Documentation menu

Portable registration

Portable registration

Document shape

AHP-REG-001 — MUST. A portable registration document declares the selected snapshot as its protocolVersion and contains an ordered, non-empty hooks array.

A portable registration document is a JSON object with an ordered hooks array.

{
  "protocolVersion": "draft",
  "hooks": [
    {
      "id": "com.example.policy",
      "transport": {
        "type": "http",
        "url": "https://policy.example.com/agent-hooks"
      },
      "authentication": {
        "type": "bearer",
        "tokenEnv": "AHP_POLICY_TOKEN"
      },
      "subscriptions": [
        {
          "events": ["tool.before"],
          "mode": "intercept",
          "timeoutMs": 750,
          "failurePolicy": "fail-closed",
          "content": {"default": "metadata"}
        }
      ]
    },
    {
      "id": "com.example.local-review",
      "transport": {
        "type": "stdio",
        "command": "/usr/local/bin/local-review",
        "args": ["serve"],
        "lifecycle": "persistent"
      },
      "subscriptions": [
        {
          "events": ["tool.before"],
          "mode": "intercept",
          "timeoutMs": 500,
          "failurePolicy": "fail-open",
          "content": {"default": "metadata"}
        }
      ]
    }
  ]
}

Backend fields

Field Requirement Semantics
`id` REQUIRED Unique reverse-DNS backend identifier within the document.
`transport` REQUIRED Exactly one supported transport configuration.
`authentication` Optional endpoint authentication Credential reference; never a literal credential.
`subscriptions` REQUIRED Non-empty array of event subscriptions.
### Subscription fields
Field Requirement Semantics
`events` REQUIRED Non-empty array of exact event names, whole-family wildcards such as `tool.*`, or `*`. No arbitrary patterns.
`mode` REQUIRED `intercept` or `observe`.
`timeoutMs` Intercept only Required positive integer deadline.
`failurePolicy` Intercept only Required `fail-open` or `fail-closed`.
`content` REQUIRED Flat selection object with a required `default` and optional category-name keys, each set to `body`, `metadata`, or `omit`. See [content upload](/docs/spec/draft/content-upload/).
`includeNative` OPTIONAL Boolean; defaults to `false`.
An `intercept` subscription MUST select only events the harness advertises as interceptable, including when expanding wildcards. An `observe` subscription MUST NOT include `timeoutMs` or `failurePolicy`. ### Subscription dispatch

AHP-REG-002 — MUST. A harness sends an event to a backend only when that backend has a subscription whose events array matches the event name exactly or through a supported wildcard and whose mode matches the delivery method, except for best-effort observation of uncalled intercept subscriptions after short-circuit settlement.

For normal dispatch, hooks/intercept matches intercept mode and hooks/observe matches observe mode. After short-circuit settlement, remaining uncalled matching intercept subscriptions receive best-effort hooks/observe as defined in observation delivery. Exact selectors match only the named event; family wildcards match that event family, and * matches all supported events for the mode. Intercept wildcards select only advertised interceptable boundaries. There is no arbitrary matcher language or separate enabled subscription state. Absent a matching subscription or that short-circuit observation rule, the harness MUST NOT send that event to the backend.

stdio transport fields

A stdio transport contains:

  • type: exact value stdio
  • command: executable path or name
  • args: optional string array
  • lifecycle: persistent or per_event
  • cwd: optional backend working directory
  • env: optional object of literal string environment variables for the backend process; see process environment

HTTP transport fields

An HTTP transport contains:

  • type: exact value http
  • url: absolute endpoint URL Authentication supports the configured endpoint bindings in capabilities and authentication. Bearer authentication uses exactly one of tokenEnv or tokenRef; credentials are never literal values. Upload authentication is configured independently.

Native harness configuration

A harness MAY translate this registration model into its native configuration format. It may still claim protocol conformance if the resulting order, subscriptions, timeout, failure, transport, and credential semantics are equivalent.

Forward compatibility and local identity

Subscriptions and subscription identifiers are harness-local configuration, not wire identity. Receivers MUST ignore unknown registration/configuration fields, MUST validate recognized fields, and MAY warn about ignored fields. Unknown fields do not change dispatch, authorization, or supported effect/operation semantics.

Endpoint discovery example

This HTTP backend deliberately omits an explicit identity binding. The client attempts the endpoint and, if challenged, uses standard OAuth protected-resource discovery subject to its own trust and identity policy. The upload endpoint does so independently. Neither absence authorizes credential inheritance.

{
  "protocolVersion": "draft",
  "hooks": [{
    "id": "org.example.policy",
    "transport": {"type": "http", "url": "https://hooks.example/events"},
    "subscriptions": [{
      "id": "tool-policy",
      "events": ["tool.before"],
      "mode": "intercept",
      "timeoutMs": 1000,
      "failurePolicy": "fail-closed",
      "content": {"default": "metadata"},
      "upload": {"endpoint": "https://uploads.example/bytes", "timeoutMs": 5000, "maxBytes": 1048576}
    }]
  }]
}

For a static upload secret, explicitly set upload.auth to {"type": "bearer", "tokenRef": "secrets/policy-upload"}. This deployment-managed reference is not a URL or a secret value. Resolution failure MUST NOT switch to OAuth; an event secret is not a substitute. An explicit OAuth preset can constrain issuer, resource, client, flow, and scopes without requiring every registration to predeclare OAuth before encountering an endpoint challenge.