APS · Agent Passport System
Agent Passport System / action_ref v1

action_ref v1

The cross-ecosystem correlation key for agent actions. One four-field preimage, one canonicalization, one hash, frozen under the v1 label, with runnable conformance vectors in two languages.

Source of truth. The canonical version of this specification lives in the SDK repository as Markdown; this page renders it for the web and may lag the repository. Spec: docs/specs/action-ref-v1.md (raw). Vectors: conformance/action-ref-v1/vectors.json (raw).

1. Status

v1.0 · 2026-06-09 · frozen preimage

This page specifies the cross-ecosystem action_ref v1 form (derivation label action-ref-v1-jcs-sha256), the one computed by the SDK's computeExternalActionRefV1 and by independent implementations in the action-ref-v1 ecosystem. It is distinct from the APS-native action_ref of draft-pidlisnyi-aps §4.1, whose preimage uses camelCase keys, a multi-scope array, and second-precision timestamps. The two are separate primitives with intentionally different preimages.

2. Definition

action_ref is a correlation key, not an authorization claim. It joins the commitment, decision, and receipt records for a single action by a single producer. Two records carrying the same action_ref from the same producer refer to the same action; nothing more is implied.

3. Preimage

The preimage is a four-field tuple. All fields are required strings.

FieldSemantics
agent_idThe terminal executing agent DID after delegation resolution. Never the delegator, never a display label. When agent A delegates to agent B and B executes, agent_id is B.
action_typeAn opaque, producer-scoped semantic label. It enters the preimage as bytes; it is not a cross-producer semantic key.
scopeThe terminal executing agent's requested-intent scope, not the authorized or narrowed scope. Narrowing lives in the decision and commitment records. A single string.
timestampRFC 3339 UTC with exactly three fractional digits, uppercase T, uppercase Z, zero-padded: YYYY-MM-DDTHH:MM:SS.mmmZ. One valid byte sequence per instant. Producers MUST emit this form; receivers MUST treat any other representation as invalid for action_ref computation, rejected rather than coerced. Implementations holding epoch-millisecond integers convert at the serialization layer, before hashing. The string is hashed as opaque bytes and never normalized.

The accepted timestamp grammar, exactly as implemented:

^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$

4. Derivation

  1. Assemble the four-field tuple.
  2. Canonicalize with the JSON Canonicalization Scheme (RFC 8785), strict form: keys sorted by code point, no whitespace, ES2015 string escaping.
  3. SHA-256 over the UTF-8 bytes of the canonical string.
  4. Render the digest as lowercase hex (64 characters).

Because JCS sorts keys, the canonical serialized form is always, in this exact key order:

{"action_type":"...","agent_id":"...","scope":"...","timestamp":"..."}

Worked example:

agent_id    = "did:aps:zExampleAgent001"
action_type = "document.sign"
scope       = "repo:example/docs"
timestamp   = "2026-06-09T12:00:00.000Z"

action_ref = f5cc735aa740b1a5006bf4d41f6e3cacbabcab3e369043b58d924e3bb69b4988

5. Non-goals

  • Cross-producer action_type comparison. The label is producer-scoped.
  • Authorization. Holding or presenting an action_ref authorizes nothing.
  • Uniqueness across producers. Two producers can compute the same key; it is meaningful within one producer's record family.

6. What action_ref does not prove

An action_ref does not prove that the action was authorized, that it occurred, or that the scope was honored. Those claims live in the records it correlates: authorization in the decision record, occurrence in the receipt, scope conformance in the commitment and decision records. The key only joins them.

7. Relationship to the record family

Commitment, decision, and receipt records each reference action_ref as the join key for a single action. Related provenance primitives in the SDK repository: Context Provenance Attestation (CPA), which seals the context an agent reasoned over, and instruction provenance, which classifies and binds instruction sources.

8. Versioning

Any change to the preimage (field set, field semantics, timestamp grammar) or to the derivation (canonicalization, hash, encoding) is a v2 with a new derivation label. The v1 label is action-ref-v1-jcs-sha256. Implementations MUST NOT emit a changed form under the v1 label.

9. Conformance

The vector suite carries 13 vectors: 8 accept vectors (ecosystem anchors, Unicode, key-order independence, midnight rollover, .000 and .999 milliseconds, empty and long scopes) and 5 negative vectors (lowercase t, lowercase z, numeric offset, missing and six-digit fractional seconds), each rejected rather than coerced. Two verifiers run the suite: a stdlib-only Python recomputation with a vendored RFC 8785 serializer, and a Node verifier importing the shipping SDK implementation, so the vectors stay pinned to real code. See conformance/action-ref-v1/.

10. Pointers

🤖 For AI agents: If you are an agent reading this page, visit llms.txt for machine-readable documentation or llms-full.txt for the complete technical reference. This page is designed for humans.