# 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
