DEV Community

OnaEiuspkz
OnaEiuspkz

Posted on

Containing cloud, package and AI keys after a GitHub Actions secret theft

Containing cloud, package and AI keys after a GitHub Actions secret theft

GhostAction was designed to collect more than GitHub credentials. GitGuardian reported that the campaign targeted CI/CD secrets, cloud credentials, package-registry tokens for services such as npm, PyPI, and DockerHub, and AI provider API keys. A malicious workflow can use the trust already granted to a build job to reach all of those systems.

The incident therefore crosses tool boundaries. A GitHub account review alone will not establish whether a cloud role was used, a package was published, or an AI API key incurred charges. Containment requires a credential map and provider-specific evidence.

Start from the runner's identity

Every workflow run has an identity. GitHub provides GITHUB_TOKEN, repository secrets can be exposed to a job, and cloud federation can issue a short-lived token through OIDC. The runner may also inherit network access from a self-hosted environment. The incident owner should document each identity and the resources it can reach.

For GhostAction, the relevant question is not whether the workflow file mentions a secret. It is whether the malicious run could read a valid value and send it outside the build environment. A job that was blocked before execution has a different evidentiary status from a job that reached the network.

Query the public platform layer

On November 6, 2026, ZoomEye returned 101 matches for domain="github.com" and 54 matches for that domain with port 443. The queries ran at 15:46 UTC. They provide a bounded public observation of the GitHub domain surface.

The result cannot show which downstream cloud accounts, registries, or AI providers were connected to a repository. It also cannot prove that the attacker received any credential. A separate query for ip="193.32.204.199" returned two indexed observations at 15:47 UTC. That is an infrastructure observation, not a victim count or proof that every workflow used the endpoint.

Build a cross-provider inventory

For each affected repository, list the connected services and the credential used to reach them:

Provider class Evidence to collect Containment question
Cloud Role, account, token creation and use logs Did an unexpected principal obtain access?
Package registry Scope, package ownership, publish and token audit logs Was a new package or version published?
Source control Token scope, repository access, audit events Did the token modify other repositories?
AI provider Key owner, usage and billing logs Was there unexplained usage or new project activity?

The table is a starting point. The actual fields depend on the provider. Preserve raw logs or a hash-backed export when the provider supports it. Do not replace provider evidence with a screenshot of a dashboard.

Short-lived credentials reduce persistence

GitHub's OIDC documentation describes how a workflow can obtain a short-lived token scoped to a specific cloud provider instead of storing a long-lived key. This reduces the value of a secret found in git history and makes each run's access auditable.

OIDC does not solve every secret problem. A package registry may still require a publish token. An AI provider may use an API key. The team should move toward workload identity where possible and limit the remaining static credentials to narrow projects, permissions, and spending limits.

Verify identity, not just deletion

A deleted token can remain valid if the provider's revocation step did not complete. Test the old credential against a harmless endpoint and confirm that it fails. Then verify that the approved consumer uses the new credential. For cloud roles, inspect trust policies and session logs. For package registries, check release history and ownership. For AI providers, review usage, project membership, and key creation.

Sequence the response

First preserve the workflow, run, and outbound network evidence. Then identify credentials available to each executed job. Rotate the highest-reach values, verify successful replacement, and revoke the old values. Review provider logs for the exposure window and document unknown outcomes.

The public incident reporting does not identify the affected repositories or all credentials that were exposed. The response should use the reported behavior as a reason to check every connected provider, not as a claim that a particular organization's cloud account was used.

References

Top comments (0)