# ACT (Agent Compact Token) — Medium Blog Post Series ## Series Title: "Securing the Agentic Web" Target audience: Backend/platform engineers, AI practitioners, security-minded architects building multi-agent systems. --- ## Post 1: "Why OAuth Isn't Enough for AI Agents" **Hook**: OAuth was built for humans clicking "Allow." Autonomous agents don't click buttons — they chain tasks, delegate to sub-agents, and need cryptographic proof of what they did, not just what they were allowed to do. **Key points**: - OAuth assumes a human in the loop (consent screens, redirect flows) - Agents need machine-to-machine auth that works without an Authorization Server - The missing piece: **accountability** — OAuth proves authorization, but not execution - Agents operate across organizational boundaries; federated trust is essential - Existing alternatives and their gaps: - **SPIFFE/SPIRE**: Workload identity, but no capability scoping or execution records - **ZCAP-LD**: Capability delegation, but JSON-LD complexity and no execution phase - **Macaroons**: Contextual caveats, but no standardized structure for agent workflows - **OPA/Cedar**: Policy engines, but no portable token format **Diagram idea**: Side-by-side comparison — OAuth flow vs. ACT flow for an agent task **Call to action**: Introduce ACT as "authorization + accountability in a single token" --- ## Post 2: "One Token, Two Lives — The ACT Lifecycle" **Hook**: What if your authorization token could *grow up* — transforming from a permission slip into a receipt? **Key points**: - **Phase 1 — Authorization Mandate**: Signed by the issuing agent - "Agent A authorizes Agent B to do X, with these constraints, until time T" - JOSE header: `typ: "act+jwt"`, `alg: "EdDSA"`, `kid` - Claims: `iss`, `sub`, `aud`, `exp`, `jti` (UUID v4), `task`, `cap` - The `task` object: purpose, data sensitivity, created_by - The `cap` array: fine-grained actions with constraints - **Phase 2 — Execution Record**: Re-signed by the executing agent - Same token, new claims added: `exec_act`, `par`, `exec_ts`, `status` - Critical: header `kid` switches from issuer's key to executor's key - Optional: `inp_hash` and `out_hash` (SHA-256 of actual I/O data) - The `err` object for failure cases **Code example**: Show a Phase 1 JWT payload, then the same payload with Phase 2 claims added **Why it matters**: One token = complete audit trail. No separate logging system needed. The token *is* the evidence. **Analogy**: A signed work order (Phase 1) that becomes a signed completion certificate (Phase 2) --- ## Post 3: "Zero to PKI — ACT's Trust Tier Progression" **Hook**: Most security specs start with "first, set up your PKI infrastructure." ACT starts with "first, share a key over Signal." **Key points**: - **Tier 1 — Pre-Shared Keys** (mandatory to implement) - Ed25519 key pairs shared out-of-band - `kid` is just an opaque string both parties agree on - Zero infrastructure. Works on day one. Perfect for prototyping and internal agents - Key registry: simple dict mapping `kid → public_key_bytes` - **Tier 2 — PKI / X.509** - `kid` = SHA-256 thumbprint of DER-encoded certificate - `x5c` JOSE header carries the certificate chain - Standard X.509 chain validation against trusted CA store - For enterprises with existing PKI - **Tier 3 — Decentralized Identifiers (DIDs)** - `did:key` — self-contained, no resolution needed (Ed25519 public key in the DID itself) - `did:web` — HTTP-resolvable, cacheable with TTL - For cross-organizational federation without shared CA **Diagram idea**: Three-rung ladder — each tier adds infrastructure but also adds trust guarantees **Why it matters**: You can start using ACT in 10 minutes with pre-shared keys, then upgrade to PKI or DIDs as your deployment matures. No rip-and-replace. --- ## Post 4: "Delegation Without Escalation — How ACT Prevents Rogue Sub-Agents" **Hook**: When Agent A delegates to Agent B who delegates to Agent C... how do you ensure C can't do more than A originally allowed? **Key points**: - The `del` claim: `{ depth, max_depth, chain[] }` - `chain` is ordered root → immediate parent - Each entry: `{ delegator, jti, sig }` - **Capability attenuation**: child's `cap` MUST be a subset of parent's `cap` - Constraints can only get MORE restrictive, never less - Example: parent allows `data.read` with `max_rows: 1000` → child can set `max_rows: 100` but not `max_rows: 5000` - **Chain verification**: - `sig = Sign(delegator.private_key, SHA-256(parent_act_compact_bytes))` - Each chain entry verified against delegator's public key - **Rejection conditions** (5 ways delegation fails): 1. `depth > max_depth` 2. `chain.length != depth` 3. Any chain signature fails 4. `cap` contains actions not in parent's `cap` 5. Any constraint is less restrictive than parent's **Code example**: Three-agent delegation chain with progressively narrower capabilities **Analogy**: Power of attorney — you can give someone authority to act on your behalf, and they can sub-delegate, but each level can only narrow the scope, never widen it --- ## Post 5: "Following the Thread — DAG-Based Execution Tracking" **Hook**: In a world where agents spawn agents that spawn agents, how do you answer "what happened and in what order?" **Key points**: - Every Phase 2 ACT has a `par` (parents) array — JTIs of predecessor tasks - `[]` for root tasks (no parents) - Multiple parents = fan-in (joining parallel branches) - The `jti` itself serves as the task ID - **DAG validation rules**: 1. `jti` uniqueness within `wid` (workflow) scope 2. Every parent `jti` must exist as a verified Phase 2 ACT in the ledger 3. Temporal ordering: `parent.exec_ts < child.exec_ts + 30s` (clock skew tolerance) 4. Acyclicity: max 10,000-node traversal limit 5. `exec_act` must match one of the `cap[].action` values - **Workflow grouping**: Optional `wid` (workflow ID) groups related ACTs **Diagram idea**: A DAG of 6-8 tasks showing fan-out (parallel dispatch) and fan-in (result aggregation) **Real-world example**: ML pipeline — data fetch → preprocess (fan-out to 3 shards) → train (fan-in) → evaluate → deploy **Why it matters**: Compliance, debugging, incident response. "Show me every action taken in workflow X, in causal order, with cryptographic proof." --- ## Post 6: "Humans in the Loop — ACT's Oversight Mechanism" **Hook**: Full autonomy is terrifying. Full control is impractical. ACT's oversight mechanism is the middle ground. **Key points**: - The `oversight` claim: - `requires_approval_for`: array of action strings that need human sign-off - `approval_ref`: reference to the approval record - How it works in practice: - Agent receives mandate with `oversight.requires_approval_for: ["data.delete"]` - Before executing `data.delete`, agent must obtain approval - Approval reference stored in `oversight.approval_ref` - Selective oversight: Only specific high-risk actions require approval, not everything - Composable with delegation: oversight requirements propagate down the chain **Why it matters**: Regulatory compliance (GDPR right-to-delete, financial transactions), enterprise risk management, building trust in agent systems incrementally --- ## Post 7: "Threat Model Deep Dive — What ACT Defends Against" **Hook**: Every security spec claims to be secure. Here's exactly what ACT protects against — and what it doesn't. **Key points**: - **Defended threats**: - Token forgery (Ed25519 signatures, no symmetric algs, no "alg: none") - Privilege escalation (capability attenuation in delegation chains) - Replay attacks (jti uniqueness, exp enforcement, clock skew tolerance ≤300s) - Execution fabrication (Phase 2 re-signature by sub's key, not iss's key) - Audit trail tampering (hash-chained append-only ledger) - Man-in-the-middle on delegation (chain signatures bind to parent token bytes) - **Security constraints in implementation**: - Algorithm allowlist: EdDSA (Ed25519), ES256 only. No HS*, no "none" - Key material zeroed on deletion - iat must not be unreasonably future (≤30s) - aud verification mandatory - **Out of scope** (honest about limitations): - Token revocation (not in v00 — mentioned as future work) - Confidentiality of token contents (JWS, not JWE) - Compromised agent keys (standard key management applies) **Table**: Threat → ACT mitigation → Residual risk --- ## Post 8: "ACT Meets the IETF — Why Standardization Matters for Agent Interop" **Hook**: Your agents and my agents need to talk. Without a standard, we're back to building custom integrations for every partner. **Key points**: - The IETF process: Internet-Draft → RFC pathway - `draft-nennemann-act-00` is the first submission - Building on existing standards: RFC 7519 (JWT), RFC 7515 (JWS), RFC 7518 (JWA) - ABNF notation for action names, formal CDDL-style structures - Why an IETF RFC vs. a blog post or GitHub repo: - Interoperability testing with multiple implementations - Formal security review - Stable reference for contracts and regulations - Media type registration: `application/act+jwt` - **Interoperability requirements**: - MUST implement Tier 1 (pre-shared keys) - MUST support EdDSA (Ed25519) - MUST verify delegation chains - MUST enforce DAG validation - Comparison with other agent-related standards efforts **Why it matters**: As AI agents become infrastructure, we need the same rigor we applied to HTTP, TLS, and OAuth --- ## Post 9: "Building Your First ACT Agent — A Hands-On Tutorial" **Hook**: Enough theory. Let's build two agents that authorize, execute, and audit a task using ACT. **Key points** (step-by-step tutorial): 1. Install the `act` Python package 2. Generate Ed25519 key pairs for two agents 3. Create a Phase 1 mandate (Agent A → Agent B: "read customer data") 4. Agent B validates the mandate 5. Agent B executes and creates Phase 2 record (with inp_hash/out_hash) 6. Append to audit ledger 7. Verify the complete chain 8. Add delegation: Agent B delegates subset to Agent C 9. Verify Agent C's execution in the DAG **Code examples**: Complete working Python code for each step, using the reference implementation **Real-world scenario**: E-commerce — order service authorizes inventory agent to check stock, inventory agent delegates to warehouse-specific sub-agents --- ## Post 10: "The Road Ahead — ACT's Evolution and the Agentic Future" **Hook**: ACT v00 is a foundation. Here's what's coming and how you can shape it. **Key points**: - **Future work mentioned in the draft**: - Token revocation mechanisms - Formal capability algebra (lattice-based constraint reasoning) - Performance benchmarks across implementations - Integration patterns with existing auth infrastructure - Privacy-preserving execution records (selective disclosure) - **Community and contribution**: - Reference implementation as the interoperability baseline - Test vectors (Appendix B) as the conformance suite - How to write a second implementation (in Rust, Go, etc.) - **The bigger picture**: - Agent-to-agent economy needs trust primitives - ACT as one layer in the agentic stack - Composability with other standards (OpenID for agents, SCIM, etc.) --- ## Cross-Series Themes 1. **Progressive complexity**: Each post builds on the previous, but each can stand alone 2. **Code-first**: Every concept illustrated with real Python snippets from the reference implementation 3. **Honest trade-offs**: Acknowledge what ACT doesn't solve (yet) 4. **Standards matter**: Thread the IETF standardization story throughout 5. **Real-world grounding**: Each post connects to concrete use cases ## Publication Strategy - **Cadence**: 1 post per week, 10-week series - **Length**: 1,500-2,500 words per post (8-12 min read) - **Tags**: AI, Security, Authentication, Distributed Systems, IETF - **Series landing page**: Link all posts, provide a "start here" guide - **Code repo**: Link to the reference implementation throughout - **Post 9** can be published on dev.to / Hashnode in addition to Medium for developer reach