← Back to The Lab
§ Pattern◆September 4, 2026◆7 min

The identity forgery pattern: why your agent's credentials need an expiry, not just a scope

Agent identity forgery moved from theoretical to funded this year. Here's the architectural fix that predates the funding round.

Share◆X◆LinkedIn◆Facebook◆

> ../patterns/credential_expiry.md

§ 01 · The problem

Most teams scope an agent's credentials carefully, read-only here, write access there, this API but not that one. Scope answers "what can this agent do." It does not answer "how long is this credential good for" or "can I tell this agent apart from a copy of itself." Both of those gaps are how identity forgery happens: a credential gets replayed, cloned into a second process, or reused long after the task it was issued for has finished.

── The standing key ──

§ 02 · Why scope alone isn't enough

A tightly scoped credential with no expiry is still a standing key. If it leaks, into a log, a prompt, a tool-output, a forked process, it stays valid until someone notices and revokes it manually. In practice, nobody notices for days. Scope limits the blast radius of a single call. It does nothing to limit the blast radius of time.

── The pattern ──

§ 03 · The pattern

Treat every agent credential as short-lived by default, not as a static secret with a scope attached.

1. Issue per-session, not per-agent. A credential is minted when a run starts and dies when it ends, not a long-lived key the agent reuses across every run.

2. Set an expiry shorter than your longest expected task. If your agent's longest normal run is 20 minutes, the credential expires at 30. A stuck or hijacked process cannot keep operating past that window even if nobody is watching.

3. Bind the credential to a run_id. Every credential carries the identifier of the specific run that issued it. If two requests arrive using the same credential from two different process contexts, that's not a scaling event, it's a forgery signal, and it should fail loud, not fail open.

4. Log every credential issuance and every use separately. Issuance tells you what should be able to act. Usage tells you what did act. The gap between those two logs is where forgery hides.

5. Revoke on completion, not on schedule. Don't wait for a cron job to clean up expired credentials, revoke the moment the run reports done, failed, or killed.

── What this catches ──

§ 04 · What this catches that scope doesn't

A well-scoped but long-lived credential still lets an attacker who steals it act indefinitely, within scope, indistinguishable from the legitimate agent. A short-lived, run-bound credential turns "stolen and replayed" into "stolen and useless within the hour", and turns "cloned into a second process" into an immediate, loud signal instead of a silent duplicate.

── The hard case ──

§ 05 · Where this gets hard

Long-running agents, the ones that legitimately operate for hours or days, break the simple "session-length expiry" rule. For those, don't extend the expiry window; rotate the credential on a fixed interval within the run instead, the same way a long-lived TLS session rotates keys without dropping the connection. The rule stays the same: no credential should outlive its usefulness by more than a few multiples of a normal task.

── Checklist ──

§ 06 · Checklist

[ ] Does every agent credential expire, independent of its scope?

[ ] Is the expiry window shorter than your longest normal task, not your longest possible one?

[ ] Is every credential bound to a specific run_id?

[ ] Do you log issuance and usage as two separate events you can diff against each other?

[ ] For long-running agents, do you rotate credentials mid-run instead of issuing one that lives for the whole duration?

── End of pattern ──

◆ If any answer is no, an attacker doesn't need to break your agent's logic, they just need to find a credential nobody thought to expire.

ORBIRESEARCH

Share◆X◆LinkedIn◆Facebook◆