Skip to main content
CircleCI Breach: When Static Secrets Become Skeleton KeysIncident
4 min readFor Security Engineers

CircleCI Breach: When Static Secrets Become Skeleton Keys

What Happened

On January 4, CircleCI discovered unauthorized access to their systems and immediately advised all customers to rotate their secrets. The company invalidated Personal and Project API tokens and rotated all OAuth tokens from GitHub and Bitbucket. The breach was detected by Daniel Hückmann using a CanaryToken—a honeypot credential designed to trigger alerts when accessed. This detection method revealed that an attacker had gained access to CircleCI's production environment, potentially compromising customer secrets stored within the platform.

Timeline

January 4: CircleCI publicly disclosed the security incident and issued guidance for customers to rotate all secrets stored in their platform. The company simultaneously invalidated API tokens and rotated OAuth tokens as an immediate containment measure. The timeline remains limited because CircleCI has not published a detailed post-incident report. What we know comes from their initial disclosure and subsequent customer communications.

Which Controls Failed or Were Missing

Secrets Storage Architecture: CircleCI stored customer secrets in a way that allowed an attacker who compromised their production environment to access them. This represents a failure of data isolation—customer secrets should be encrypted with keys the platform itself cannot decrypt (zero-knowledge architecture).

Detection Capabilities: The breach was discovered through a customer's CanaryToken, not CircleCI's internal monitoring. This indicates insufficient anomalous access detection for privileged credentials and production systems.

Secrets Lifecycle Management: The incident exposed the fundamental vulnerability of static secrets. Once compromised, these credentials grant persistent access until manually rotated. CircleCI's customers had no automated way to limit the blast radius through time-bounded credentials.

Principle of Least Privilege: The attacker's ability to access multiple customers' secrets suggests overly broad access permissions within CircleCI's infrastructure. Proper segmentation would have limited exposure to a subset of customers or specific secret types.

What the Standards Require

PCI DSS v4.0.1 Requirement 8.3.2 mandates that authentication credentials are protected during transmission and storage. For service providers like CircleCI, this means implementing strong cryptography and ensuring secrets are encrypted in a way that prevents unauthorized access even by platform administrators.

ISO/IEC 27001:2022 Control 8.3 requires that access to information and other associated assets is restricted in accordance with the established access control policy. This applies to both CircleCI's internal access controls and the architecture they provide to customers.

NIST 800-53 Rev 5 IA-5(7) addresses the protection of authenticators and specifically calls out the need to ensure that unencrypted static authenticators are not embedded in applications or stored in function keys. While this control focuses on preventing hardcoded secrets, the principle extends to how platforms store customer secrets.

SOC 2 Type II CC6.1 requires that the entity implements logical access security measures to protect against threats from sources outside its system boundaries. For CircleCI, this means protecting customer data even when their own perimeter is breached.

None of these standards explicitly require dynamic secrets, but they all establish principles that static secrets inherently violate: time-bounded access, least privilege, and defense in depth.

Lessons and Action Items for Your Team

Stop treating secrets rotation as incident response. If your first action after a breach is "rotate all secrets," you've already lost. Build rotation into your normal workflow. Your CI/CD pipeline should request fresh credentials for each job, not reuse the same token for months.

Implement short-lived credentials wherever possible. Instead of storing a static AWS access key in CircleCI, configure your jobs to assume an IAM role that expires after one hour. Instead of a permanent database password, use HashiCorp Vault or AWS Secrets Manager to generate credentials valid for a single deployment window.

Audit your secrets sprawl right now. You likely have the same production database password stored in: your CI/CD platform, your configuration management tool, your monitoring system, your backup scripts, and three engineers' password managers. Each copy is an attack vector. Map every location where production credentials exist, then start consolidating.

Deploy CanaryTokens in your own infrastructure. Hückmann's detection method worked because he planted a fake credential designed to trigger an alert when accessed. Create a fake API key, embed it in a config file in your repository, and configure alerts when it's used. You'll know immediately if someone is harvesting secrets from your codebase.

Evaluate your CI/CD platform's security model. Ask your vendor: How are our secrets encrypted? Who has access to the encryption keys? Can you access our secrets? If the answer to that last question is "yes," you need a different architecture. Consider using your CI/CD platform only for orchestration while fetching secrets directly from your own vault at runtime.

Build a secrets rotation runbook before you need it. Document every secret your team manages, where it's stored, what systems use it, and the exact steps to rotate it. Test this process quarterly. When CircleCI's disclosure hit, teams with runbooks rotated credentials in hours. Teams without them spent days tracking down every place a compromised token might be used.

Set credential expiration policies. If your platform supports it, configure all API tokens to expire after 90 days maximum. Force yourself to build rotation into your workflow before an incident forces you to do it under pressure.

The CircleCI incident didn't introduce a new vulnerability—it exposed an architectural problem that exists in most organizations. Static secrets are persistent privileges. When they leak, you don't know when, where, or for how long they'll be abused. Dynamic secrets with short lifespans limit the damage window to minutes or hours instead of months. Start building that capability today.

AWS Secrets Manager HashiCorp Vault

Topics:Incident

You Might Also Like