Module B5 — Identity and Permission Design

Identity and Permission Design

An agent is not a human. Giving an agent a human's credentials means the agent acts with the human's full privilege — and an injected agent with admin credentials is an admin compromise. Agents need their own non-human identities, scoped to the current task, exchanged per action via RFC 8693 token exchange, and isolated from the agent process entirely. The agent never holds a long-lived secret; the harness does.

60
minutes
8
artifacts
3
sub-sections
B2 built the injection defense. B4 built the tool-trust gate. Both deferred one question: who is the agent, and what is it allowed to do? The identity layer is the blast-radius floor every other defense rests on. An agent with no credentials cannot exfiltrate even if fully injected; an agent with an admin's credentials can exfiltrate the account the moment injection succeeds. This module builds that floor: non-human identities (NHIs), per-task scoped credentials via token exchange, a deterministic scope-check middleware, and credential isolation — the agent never sees the raw credential. OWASP ASI03 (Excessive Agency) and ASI10 (Broken Access Control) name the risks; DD-20 IronCurtain's credential quarantine is the reference architecture. This is the depth upgrade the course design conversation flagged as underrepresented — central in real enterprise agent deployments, where deployments fail not on injection sophistication but on the engineer who pasted their AWS keys 'to get it working.'
Key Claims
Load-Bearing Claims

An agent borrowing a human's credentials is an identity-design failure, not a convenience. The agent inherits the human's full privilege — the blast radius is the credential's scope, not the task's requirement. An injected agent with borrowed admin credentials is an admin compromise, and it looks legitimate in access logs because the credential was never stolen, it was handed over. The fix is not better injection defense (B2) or better tool provenance (B4) — it is that the agent never holds the human's credentials at all. Agents get their own non-human identities (NHIs), scoped to the task, revocable independently, and auditable as non-human. NHIs are the fastest-growing identity category in cloud security.

Least privilege for agents means per-task scoped credentials, not role-level privilege. An agent should hold exactly the permissions its current task requires, no more — not the permissions the agent's role might need across a day. The operational realization is RFC 8693 token exchange: the agent holds a short-lived session token (NHI-scoped, TTL: minutes); the harness exchanges it per action for an action token (narrower scope, specific audience, TTL: seconds). An injected agent that captures the action token gains at most one action against one audience for seconds — it cannot pivot to other APIs, scopes, or principals. The agent never holds a long-lived secret.

The load-bearing principle: credentials live in a vault the harness accesses, not in the agent process. The agent never sees the raw credential. An agent that can read its own credentials (env var, config file, system prompt) can exfiltrate them — and the system prompt is the single worst anti-pattern, because the prompt is text the model reads and can be coerced into repeating. The defense is credential isolation: the credential is never in the agent's environment; the harness retrieves it from a vault, mints the action token, makes the call, and returns only the result. This is DD-20 IronCurtain's credential quarantine (the agent holds only fake keys; the harness swaps for real) realized via a vault and token exchange without a MITM proxy. The agent cannot exfiltrate what it does not possess.

ASI03 (Excessive Agency) and ASI10 (Broken Access Control) compound into privilege-escalation chains, and the defense is the B2.3 resolution applied to the privilege boundary. Over-provisioned NHIs (ASI03) + missing scope enforcement (ASI10) = an injected agent escalates beyond its intended privilege. The defense-in-depth: per-task scoped credentials (narrow at issuance), scope-check middleware (the deterministic gate — structural, enumerable, no model in the loop, no bypass rate), credential isolation (the agent cannot steal a broader token), and API-side scope enforcement. The scope check is a compiled boolean — the agent cannot talk its way past it. This is determinism on the privilege boundary, just as B2 put determinism on the taint boundary.

After This Module
01
Explain why an agent borrowing a human's credentials (OAuth token, AWS keys) is an identity-design failure — the agent acts with the human's full privilege, and an injected agent with admin credentials is an admin compromise — and articulate why non-human identities (NHIs) are the correct model.
02
Apply least privilege at the agent layer: an agent should hold exactly the permissions its current task requires, no more — per-task scoped credentials, minted for the action, revoked after.
03
Implement delegated auth via OAuth scopes, RFC 8693 token exchange, and short-lived credentials, so the agent never holds a long-lived secret and exchanges a short-lived token for an even-more-scoped one per action.
04
Design the credential lifecycle — issuance, scoping, rotation, revocation — and locate credentials in a secrets manager the harness accesses, not the agent process (the agent never sees the raw credential).
05
Map OWASP ASI03 (Excessive Agency) and ASI10 (Broken Access Control) to the identity layer, and identify privilege-escalation chains where an injected agent acts on behalf of an under-authenticated principal.
06
Build a token-exchange and scope-check middleware that mints a scoped token per task, verifies the token covers the requested action, and quarantines credentials per DD-20 IronCurtain's credential-isolation architecture.
Artifacts
01
Teaching Document
~4,800 words; 3 sub-sections — the identity problem and non-human identities (borrowed-credential problem, NHI model, three properties), least privilege and token exchange (per-task scoped credentials, RFC 8693, OAuth scopes, SPIFFE/SPIRE workload identity), the credential lifecycle and credential isolation (issuance/scoping/rotation/revocation, credential isolation, DD-20 IronCurtain quarantine, ASI10 escalation chains, defense-in-depth); with runnable Python code (token exchange + scope-check middleware), anti-patterns, key terms, lab pointer, 13 references
READ
02
Diagrams
5 Mermaid diagrams — the borrowed-credential problem (human creds vs NHI blast radius), NHI vs human identity (three properties), per-task scoped credential flow (RFC 8693 token exchange), the credential isolation architecture (vault the harness accesses, not the agent), privilege escalation chain (ASI03 + ASI10 compound vs defense-in-depth)
READ
03
Slide Deck
15 slides — reveal.js, dark theme, design-system teal; covers what B2/B4 deferred, two OWASP risks (ASI03/ASI10), the borrowed-credential problem, the NHI model, per-task scoped credentials via token exchange, workload identity (SPIFFE/SPIRE), credential isolation, DD-20 IronCurtain, the escalation chain, the load-bearing code, lab pointer
READ
04
Teaching Script
Verbatim teaching transcript, [SLIDE N] cues
READ
05
Flashcards
Anki flashcards (TSV)
TEST
06
Exam
Exam bank, Bloom-distributed
TEST
07
Lab Spec
Build the Credential Isolation Layer — implement (a) token-exchange flow that mints a scoped action token per task (RFC 8693), (b) scope-check middleware that verifies the token covers the action, (c) credential vault the harness accesses (not the agent). Includes an injection scenario: injected agent attempts orders:delete, scope-check blocks it deterministically. Python 3.10+, no GPU, ~60-75 min.
DO
08
Module Web Page
Single-file HTML hub
HERE