seekrit
← all posts

CrowdSec's stolen token: when source code becomes a credential inventory

Incidents

A stolen repository can become a map of the next systems to attack. The difference often comes down to whether its configuration names credentials or contains them.

CrowdSec's September 18, 2026 incident report describes a theft that happened on May 22: an attacker copied about 170 private repositories using a departing developer's OAuth token. CrowdSec traced the developer's compromise to the TanStack supply-chain attack. GitHub access had remained enabled so the developer could finish work; it was removed on May 25. The stolen archive surfaced publicly in September.

CrowdSec reported no compromise of its infrastructure or databases and no changes to its code or CI. It also reported a live AWS credential in the archive, later probed in August, whose permissions were limited to publishing to one SNS topic. Other credentials had already been rotated or were not usable from the internet, according to its investigation.

This was a developer credential theft, not an established case of an AI agent leaking a key. It belongs in an agent security discussion because agents and dependency installers often run in the same credential-rich development environments.

The first stolen token and the next stolen token

A secrets manager would not have invalidated the GitHub OAuth token used to read those repositories. That requires GitHub access management, endpoint security, and timely removal of the account's access.

Seekrit addresses a different part of the problem: the application credentials that an attacker might find after copying source code. If production passwords, provider keys, and deployment tokens are absent from the repository, copying that repository does not automatically provide those values.

The distinction gives a migration a concrete target. Inventory values in current files, reachable Git history, generated configuration, CI artifacts, and local dotenv files. Move active application secrets into Seekrit, replace repository values with names or examples, and rotate anything that was already exposed. Simply deleting the current file leaves both historical copies and the old credential's authority untouched.

Use runtime injection for trusted applications so the next deployment does not need to recreate a plaintext secrets file. Keep in mind that the receiving process can still read its environment. Malware executing inside that runtime can read what the application can read.

Make each runtime's access understandable

Create separate Seekrit identities for separate workloads. A CI publisher, a development server, and an agent's broker should not share one service token.

Seekrit service tokens bind to an application environment and its composed groups. That makes an environment a useful unit for limiting what a compromised runtime can resolve. It does not automatically make each individual secret a separate permission boundary.

For example, create a dedicated issue-triage application with an environment containing only the model key needed by that worker. After selecting the organization and creating that application and environment, an operator can mint its broker's token:

seekrit token create --name triage-broker --app issue-triage --env production

The command displays a credential once. Run it in a trusted operator session and deliver the result through the broker's protected runtime configuration. Do not paste it into an agent conversation or commit it. Review composed groups too: adding a broad shared group can defeat an otherwise narrow environment.

Then scope the underlying provider key. A vault grant decides who can obtain a credential; the provider decides what that credential can do. Both controls matter, especially when a value has already escaped.

Keep agent access outside the credential store

For code-running agents, use an isolated seekrit-proxy to hold that environment's real keys. The agent gets placeholders and permission to request selected operations. The broker checks destination, method, path, and allowed secret names before substitution.

This reduces the value of stealing the agent workspace. It requires protecting the broker's service token, process, and files from the agent, and enforcing network restrictions outside the agent's control. If malware compromises the broker host or steals its Seekrit token, the credential boundary has failed.

It also leaves a separate data-access question. A broker allowing an agent to read a private repository still allows that read. Preventing theft of the raw GitHub key does not prevent misuse of an authorized repository operation. Keep repository permissions narrow and remove access when it is no longer needed.

Close access at every layer

Offboarding and incident response both need an explicit list of authorities to remove: human sessions, OAuth grants, repository membership, machine tokens, provider keys, and any broker still serving the workload. Removing one does not imply the others were removed.

For Seekrit, revoke retired service tokens and remove obsolete key grants. Where key material may have been copied, rotate the environment's encryption key for future encrypted state. Neither step erases historical plaintext or ciphertext already taken. Rotate exposed credentials at their issuers as well, then refresh or restart trusted consumers and verify that the old credentials fail.

Keep the evidence needed to check this work. Seekrit's administrative audit trail, broker decision logs, and upstream provider logs answer different questions. Successful secret resolution is not a complete durable access ledger; do not assume the vault log records every subsequent API call.

The practical test is simple: if somebody copied this repository tomorrow, what else could they authenticate to? Seekrit can help make the answer smaller by keeping values out of the codebase and separating runtime access. Start by reviewing one application's service tokens and key grants, alongside its upstream permissions.