AgentEnvelope Working draft

Overview

What is the Attested Action Envelope

The eight-field schema, the canonicalization rule, and the hash chain that make a verdict verifiable offline.

Where it fits

Static agent facts describe who an agent is and what it is capable of — a claim about identity and capability that holds over time. Receipts describe what an agent did — signed after the fact, once an action is complete. The Attested Action Envelope sits between them: it records a decision taken about a specific action, at a moment in time, before the action runs.

Static agent facts say what an agent is. Receipts say what an agent did. The envelope says what an agent may do, and preserves the refusals. Together the three give a system three tenses of accountable evidence — capability, decision, and history — each independently verifiable, none requiring trust in the party that produced it. In the agent-evidence family the envelope sits alongside receipts (which record what an agent did, after the fact) as the record of what an agent may do, decided before the fact.

The eight fields

An envelope is a JSON object with exactly these eight members. A document with any additional member, any missing member, a malformed action, or an outcome outside the closed set is not an envelope and MUST fail verification.

FieldTypeRequirement
agent_idstring, non-emptyREQUIRED
actionobject {verb, resource, params}REQUIRED; exactly these three members
policy_idstringREQUIRED
outcomestring, one of authorized | denied | conditionalREQUIRED
prev_hashstring (64-char lowercase hex SHA-256) or nullREQUIRED; null only for an agent's first envelope
issued_atstring, RFC 3339 timestampREQUIRED; supplied by the issuer, validated by parsing
sigstring (128-char hex Ed25519 signature)REQUIRED
pubkeystring (64-char hex, raw 32-byte Ed25519 public key)REQUIRED

Canonicalization

The signing input is the JSON serialization of the envelope with the sig member removed, using: keys sorted lexicographically at every level; the compact separators "," and ":" (no insignificant whitespace); UTF-8 encoding. params values must be JSON-serializable. A conformant implementation produces byte-identical canonical bytes for equal envelopes — that determinism is what lets a second, independent implementation of the eight-field format verify sm-aae's envelopes, and vice versa.

Signature

sig is the Ed25519 signature (RFC 8032) over the canonical bytes, hex-encoded. pubkey is the raw 32-byte Ed25519 public key, hex-encoded. A verifier recomputes the canonical bytes and checks sig under pubkey; any mismatch yields failure, and hostile input never raises. verify_envelope is the reference implementation's single verification entry point — structural plus signature check, returning a plain boolean.

The envelope hash and the chain

The envelope hash is the lowercase-hex SHA-256 (FIPS 180-4) of the JSON serialization of the full envelope — including sig — under the same key ordering and separators. A successor envelope's prev_hash must equal the envelope hash of the agent's immediately preceding envelope. Because the hash covers sig, the chain commits to the signed artifacts themselves: swapping a signature anywhere breaks every later link.

envelope {
  agent_id
  action:     { verb, resource, params }
  policy_id                               (the authority the verdict cites)
  outcome:    authorized | denied | conditional
  prev_hash                               (SHA-256 of this agent's prior envelope, or null)
  issued_at                               (RFC 3339, caller-supplied)
  sig                                     (Ed25519 over the canonical body, sig removed)
  pubkey                                  (the signer's raw Ed25519 public key)
}

Verifying a chain

A verifier of an agent's chain — an unordered set of that agent's envelopes — recovers the unique genesis-first ordering, or rejects the set. The reference implementation's order_chain function returns that ordering, or None if the set does not form exactly one intact chain. It rejects:

  • a gap — a prev_hash naming an envelope not present in the set, i.e. a deleted or withheld interior decision;
  • a fork — two envelopes claiming the same predecessor;
  • a foreign-chain splice — a prev_hash reaching into another agent's chain (more than one agent_id present);
  • duplicates, or zero/multiple genesis envelopes (more or less than exactly one envelope with prev_hash = null).

An agent cannot quietly drop the one decision it would rather not have on record — doing so breaks the chain's reconstruction, and the break itself is the signal.

What it does not do

Policy correctness

Signs the verdict, not the judgment

sm-aae signs whatever outcome and policy_id the caller supplies. It does not evaluate policy and cannot attest that the verdict was the right one — only that it was decided, by the holder of pubkey, at issued_at, and recorded immutably.

Key pinning

Chain integrity is by hash, not by key

An envelope self-verifies against its own embedded pubkey; order_chain does not check that an agent used the same key throughout. Catching an agent that re-signs its latest envelope under a fresh key requires an external "expected key for this agent" check — an identity layer's responsibility.

Replay & timestamp truth

A record of a decision, not a clock

Presenting a valid envelope again is not forgery; consumers that derive side effects from envelopes must track which they have already acted on. issued_at is validated as well-formed RFC 3339 but is caller-asserted — sm-aae does not provide a trusted clock.

Identity & key custody

Out of the primitive's scope

Generation, storage, rotation, and revocation of the signing key, and the issuance of agent identities, are out of scope — the same boundary GOVERNANCE.md draws around the primitive: it owns the envelope, its canonicalization, and chain verification, nothing else.

Out of scope. Whether an action was correct or wise, and whether it actually happened, are both outside the envelope. The first is a policy question the caller owns; the second is the occurrence half of accountability, covered by agency receipts — see agencyreceipts.ai.