A token has no session and no declared purpose. It has a scope, and a scope can't tell you a command is safe.
A CI/CD pipeline holds a token that doesn't wait on a human. That part is normal and sane. What varies is how wide the token's scope is, and it drifts wide for the ordinary reason: a build runner that needs reach across a fleet gets scoped once, at creation, and nobody narrows it later. That's exactly the setup that makes one dangerous command catastrophic, because most access-control models answer whether a command is on a list, not whether this specific command is dangerous in this context—a rule list can't express the second question.
That gap—the difference between "may this caller attempt this" and "is this specific command dangerous"—is what a two-layer governance model has to close for tokens. The 2026 incidents below are not examples of that exact gap; they show the stakes and reach once a broad-scope token ends up in the wrong hands.
The gap: a token has no session to judge intent against
A human operator working through a session has a declared purpose behind the work—the reason a Work Session was opened in the first place. A token has none of that. It has a scope, set once at creation time, and nothing else for a judgment layer to weigh a command against. Say a service token's command allow-list is scoped to *—not unusual for a build runner that needs broad reach across a fleet. The ACL (access-control list) check passes. The command runs. If that command happens to be a sudo rm -rf /, nothing in an ACL-only model stops it, because the ACL was never designed to evaluate command content—only whether the caller is allowed to attempt something in that category at all. "Governed by its ACL at creation time" sounds like a safeguard until the ACL itself is broad, at which point it stops meaning anything.
This isn't a hypothetical. Three cases from the past several months show what a broad-scope token is actually worth to an attacker:
- A flaw in Claude Code's GitHub Actions integration let an attacker register a GitHub App of their own—which takes no special permissions—and use its installation token to open an issue whose text the agent treated as instructions: enough to read the runner's environment, steal its OIDC (OpenID Connect) credentials, and mint a token with write access to the repo. Anthropic closed the permission-check bypass within four days of the January 2026 report and shipped further hardening through April; the finding went public in June. The underlying pattern—an agent conflating trusted workflow context with untrusted input—is bigger than the one bug that got patched. (flatt.tech)
- The other two show how far a stolen or leaked build token reaches once it's out of your hands. The March 2026 LiteLLM supply-chain attack, attributed to TeamPCP, started upstream: the threat actor compromised Trivy, a security scanner, and the poisoned build flowed into LiteLLM's own pipeline. CloudSEK's reconstructed exposure dataset put more than 2,500 companies and roughly 434,000 CI/CD pipelines in range, with poisoned releases built to harvest SSH keys, cloud credentials, Kubernetes tokens, and AI provider keys off build runners. (CloudSEK)
- In August 2026, GitGuardian found 4,576 exposed n8n credentials across 1,255 hostnames in public GitHub commits. Of 896 reachable instances they tested, 36% accepted at least one leaked token—enough to read workflow definitions, reuse stored credentials, and, through crafted workflows, extract the underlying credential values. (The Hacker News)
None of the three is a clean instance of a broad-scope token running a command that a risk check waved through—that specific failure hasn't made headlines yet, which is exactly why access-control models keep shipping without a check for it. What the three actually show is reach: once a token ends up in the wrong hands, or gets tricked into acting on attacker-authored input, the blast radius is whatever that token's scope allows. Claude Code's case is the closest: an authorization check—which actor counts as trusted—failed, and the January fix was another authorization check: GitHub Apps no longer trigger the workflow by default. LiteLLM and n8n are pure reach: a leaked or stolen token doing whatever its scope allows, no judgment layer in the picture at all. The obvious response to the reach problem is narrower scoping: give the coding agent's token GitHub and Linear access, give the ops agent's token AWS access, and nothing more. That's the right instinct, and it still doesn't touch the wildcard-ACL scenario above—a narrower ACL is still an ACL. It answers "may this caller attempt this," never "is this specific command dangerous."
The fix: authorization and risk are two different questions
We split this into two checks in our own product: authorization and risk, and every principal that reaches it—an agent inside a Work Session, or a service token running a build—passes through both.
Authorization asks whether execution sits inside an approved scope: an admin-approved service-token ACL, or an active Work Session. Risk—also called command risk judgment—asks whether this specific command is dangerous, evaluated against the command's own content rather than the caller's identity. Where that judgment is enabled, it runs regardless of who or what issued it. A broad ACL doesn't shrink that second check—it just leaves the command's own risk as the only question left, and an ACL was never going to answer it.
| Check | Question it answers | When it runs |
|---|---|---|
| Authorization | Does this caller's scope cover this action? | Once, at creation |
| Command risk judgment | Is this specific command dangerous? | Every time, per command |
We also treat two kinds of tokens differently, on purpose. A service token's scope is admin-approved ahead of time—someone other than the token holder decided what it's allowed to do. A personal API token is self-scoped: the person holding it approved themselves. Personal tokens aren't the intended path for privileged execution; service tokens and Work Sessions are. Non-privileged personal-token use is untouched.
A service token satisfies authorization through its admin-approved ACL rather than a Work Session, and that matters for anyone running a pipeline: in-scope token commands auto-approve instead of routing to a human—they're still judged, just not held up waiting for one. A CI/CD job doesn't hang because a human has to review a routine deploy step.
Command risk judgment is principal-agnostic: it evaluates the command itself, not who is running it. Where Alpacon's command judgment is enabled, the same risk check runs against the command whether the caller is an agent inside a Work Session or a service token running a build—broad ACL included. A wildcard-scoped token no longer gets a free pass on command content just because its ACL was broad.
The takeaway
A token that can reach your API is an authorization decision. Whether the command it's about to run is safe is a different decision, and no ACL—however carefully scoped—answers it. If your access model treats "the token was allowed to call this" as the end of the check, you're trusting scope to do a job it was never built for—and the incidents above show what that costs once a token ends up in the wrong hands or acting on the wrong instructions. Command-level risk judgment has to run on every caller, including the ones that never see a login prompt.
