# The developer toolchain is now the busiest identity perimeter

Source: https://startwithidentity.com/blog/developer-toolchain-is-the-identity-perimeter/
Last updated: 2026-10-16
License: content by Start with Identity. Cite the source URL.

---

In October 2026 the developer toolchain became the busiest identity perimeter. The credentials attackers went after were not user passwords but npm publishing rights, GitHub tokens, CI secrets, OAuth client secrets and the cloud roles held by coding agents. Each of them lets the holder become a developer, a repository or an application, and most identity programs do not inventory, scope or rotate them with anything like the care they give a workforce login.

## Key takeaways

- A push to `main`, a workflow file and a repository name are all publishing credentials now, whatever they look like.
- Provenance and trusted publishing prove where a package came from, not that the right person put it there.
- A coding agent inherits every secret on the developer's disk and every permission on its execution role, and anyone who can put text in front of it can borrow them.
- Response order matters: the Shai-Hulud variant in Tensorlake punishes revoking a stolen token before its persistence is removed.
- Secrets that were exposed once and never rotated are the raw material for the next campaign.

## Who each credential lets you become

**A maintainer's push rights became a signed release.** The Tensorlake npm SDK [shipped a Shai-Hulud credential stealer in version 0.5.144](https://startwithidentity.com/blog/2026-10-08-shai-hulud-reaches-tensorlake-npm-sdk-with-a-token-revocation-wiper/). According to StepSecurity, malicious commits landed directly on `main` under a maintainer's name, and the project's own release workflow published the package, so it carried valid provenance. The payload took npm, GitHub, AWS, Kubernetes and [HashiCorp Vault](https://startwithidentity.com/vendors/machine-identity/hashicorp-vault/) credentials and republished the victim's other packages. The identity that mattered was not the npm token. It was whoever could write to the branch the pipeline trusts.

**Stolen GitHub accounts became readers of every Actions secret.** In GhostAction's October wave, [GitGuardian](https://startwithidentity.com/vendors/secrets/gitguardian/) counted [about 1,900 compromised accounts and more than 30,000 repositories](https://startwithidentity.com/blog/2026-10-15-ghostaction-returns-with-1900-hijacked-github-accounts-and-30000-repos/). The attacker committed a workflow under the victim's own identity that dumped repository secrets and scanned the full git history for keys. GitGuardian found victims hit again after earlier waves, and cases where the attacker simply edited a workflow left behind last time.

**A reclaimed repository name became an npm publisher.** Bloom Security's [SlugFest research](https://startwithidentity.com/blog/2026-10-13-npm-trusted-publishing-slugfest-let-reclaimed-repo-names-publish-packages/) showed that npm [trusted publishing](https://startwithidentity.com/glossary/trusted-publishing/) bound a package to a GitHub owner and repository name until the first publish. If that name was freed by a rename, transfer or deletion, anyone who registered it could exchange a GitHub Actions OIDC token for a publish credential. Bloom counts more than 1,500 exposed packages and reports no confirmed exploitation. GitHub now expires unvalidated configurations after 48 hours.

**A web page became the operator of a developer's session.** Adversa AI showed [GitHub Copilot CLI in autopilot mode reading a local `.env.prod` and sending it to an attacker URL](https://startwithidentity.com/blog/2026-10-06-encrypted-web-page-tricks-github-copilot-cli-into-leaking-env-secrets/) after fetching a page with encrypted instructions. GitHub validated the finding but does not treat it as a vulnerability.

**A chat prompt became an AWS role.** Zenity Labs showed that a prompt could make an Amazon Bedrock AgentCore agent [fetch its execution role credentials](https://startwithidentity.com/blog/2026-10-08-one-prompt-pulled-aws-agentcore-role-credentials-from-imds/) from the [instance metadata service](https://startwithidentity.com/glossary/instance-metadata-service/). The default role could invoke other agents, read their conversations, write to their memory and read [AWS Secrets Manager](https://startwithidentity.com/vendors/secrets/aws-secrets-manager/). AWS has since moved AgentCore to IMDSv2-only and narrowed the role.

**A dependency decided where an application's secret went.** In the SAP Cloud SDK for Python, [CVE-2026-89111](https://startwithidentity.com/blog/2026-10-13-sap-cloud-sdk-python-flaw-sends-oauth-client-secrets-to-attackers/) let whoever controlled a tenant subdomain redirect the OAuth token request and capture the [client credentials](https://startwithidentity.com/glossary/client-credentials/). In that flow the client secret is the application.

September had already shown the shape. Mandiant described a [hijacked AI coding assistant session](https://startwithidentity.com/blog/2026-09-16-hijacked-ai-coding-assistant-session-spread-shai-hulud-to-100-repos/) that led to stolen GitHub OAuth tokens and Shai-Hulud in about 100 internal repositories, and Aikido showed that [GitLab's incoming email address](https://startwithidentity.com/blog/2026-09-23-gitlab-incoming-email-token-lets-anyone-commit-and-run-ci-as-you/) can commit code and start CI jobs as the user.

## Why existing controls missed them

**They are credentials that do not look like credentials.** A repository name, a workflow filename, a branch, an email address and a default execution role are not in any token inventory. Yet each one, in these incidents, was the thing a downstream system trusted to decide who could publish, read secrets or run code.

**Provenance answers the wrong question.** Tensorlake's malicious release was built by the real workflow in the real repository. SlugFest's forged publisher would have passed an OIDC exchange. Both controls verify the pipeline. Neither verifies that the change entering the pipeline came from someone entitled to make it.

**Agents run with the developer's identity and none of the developer's judgment.** Copilot CLI could read every file the developer could and make outbound requests in the same session. The AgentCore role was reachable by any tool that could make an HTTP request, so its permissions were effectively granted to everyone who could talk to the agent. This is [prompt injection](https://startwithidentity.com/glossary/prompt-injection/) used as credential access, covered in [agent instruction injection](https://startwithidentity.com/techniques/agent-instruction-injection/).

**Static secrets accumulate faster than they are rotated.** GhostAction works because Actions secrets and git history hold long-lived keys, and because some victims never rotated after the last wave. That is [secrets in repositories and CI](https://startwithidentity.com/techniques/secrets-in-repositories-and-ci/) and [static API key abuse](https://startwithidentity.com/techniques/static-api-key-abuse/) at campaign scale.

## Controls, in priority order

**1. Remove static publishing and cloud credentials.** Move package publishing to trusted publishing and CI cloud access to [workload identity federation](https://startwithidentity.com/glossary/workload-identity-federation/), so there is no long-lived token to dump. Then fix the binding: run `npm trust list`, confirm every bound repository still exists under your control, publish once right after creating a binding so it locks to the numeric repository ID, and check cloud trust policies that match on repository name for the same flaw. [Workload identity 101](https://startwithidentity.com/guides/machine-identity/workload-identity-101/) covers the migration.

**2. Treat write access to release branches as a publishing credential.** Require reviewed merge requests on any branch a release workflow builds from, and review who can modify workflow files. A pipeline that publishes whatever reaches `main` gives publishing rights to everyone who can push there.

**3. Rotate in a revoke-safe order.** On a host that ran a Shai-Hulud install, the malware checks the stolen GitHub token every 60 seconds and, per StepSecurity, deletes the home directory once it is revoked. Remove the persistence first, then revoke and [rotate](https://startwithidentity.com/glossary/secrets-rotation/) GitHub, npm, cloud, Vault and SSH credentials, then rebuild the host. For GhostAction, revoke the token that made the malicious commit, rotate every repository secret and anything in git history, and remove the workflow from all branches and forks. The [API key rotation automation guide](https://startwithidentity.com/guides/machine-identity/api-key-rotation-automation-guide/) helps make rotation routine rather than an emergency.

**4. Scope agent identities and close the metadata path.** Enforce IMDSv2, give each agent its own role scoped to its own resources and the specific secrets it needs, and do not assume agents in one account are isolated from each other. Keep production `.env` files off machines where coding agents run, pull short-lived credentials from a [secrets manager](https://startwithidentity.com/glossary/secrets-management/) at runtime, and do not combine autopilot modes with fetching arbitrary URLs. See [securing AI agent identities](https://startwithidentity.com/guides/machine-identity/securing-ai-agent-identities/).

**5. Scan for exposed secrets, including history.** Secret scanning on commits and across full git history finds what GhostAction harvests before it does. Pair it with an owner for each finding, because detection without rotation is what made GhostAction's repeat victims possible. [Secrets management vendors](https://startwithidentity.com/vendors/secrets/) differ mainly on how far they go from detection to remediation.

**6. Gate first publishes and new namespaces.** A first publish, a new trusted publishing binding, or a publish to an internal namespace is a high-impact identity event. Watch for publishes you did not start, verify AI-recommended dependencies against allowlists as Mandiant advises, and never let tenant or user input decide where a credential is sent, which is the SAP lesson.

## What this does not mean

It does not mean trusted publishing or provenance were mistakes. Short-lived OIDC exchanges are the right replacement for long-lived npm tokens, and SlugFest was a binding bug that GitHub has narrowed. The point is that they move the identity question upstream, to branches, workflows and repository names, and those need the same governance a token would.

It also does not mean the coding agent is the attacker. In each agent case the damage came from what the agent could already reach. Shrink that, and the next injected instruction has nothing worth taking. For the broader inventory problem, see [non-human identity security](https://startwithidentity.com/guides/machine-identity/non-human-identity-security/) and our September analysis of [credentials nobody owns](https://startwithidentity.com/blog/credentials-nobody-owns/).

## Related reading

- [Secrets in repositories and CI](https://startwithidentity.com/techniques/secrets-in-repositories-and-ci/), [static API key abuse](https://startwithidentity.com/techniques/static-api-key-abuse/) and [agent instruction injection](https://startwithidentity.com/techniques/agent-instruction-injection/)
- [Non-human identity](https://startwithidentity.com/glossary/nhi/), [least privilege](https://startwithidentity.com/glossary/least-privilege/) and [token theft](https://startwithidentity.com/glossary/token-theft/) in the glossary
- [Machine identity management guide](https://startwithidentity.com/guides/machine-identity/machine-identity-management-guide/)
- [CVE-2026-89111 brief](https://startwithidentity.com/cves/cve-2026-89111/)
- [Secrets management vendors](https://startwithidentity.com/vendors/secrets/) and [machine identity vendors](https://startwithidentity.com/vendors/machine-identity/)
