# Agent Definition Language (ADL) > The standard for trusted AI agents. ADL provides a standardized way to define agent identity, permissions, lifecycle, compliance, and governance in one auditable document. - [Agent Definition Language (ADL)](/index.md) ## spec The complete ADL v0.3.0 specification — defining agent identity, permissions, lifecycle, compliance, and governance in a machine-readable format. - [Agent Definition Language Specification](/spec.md): The complete ADL v0.3.0 specification — defining agent identity, permissions, lifecycle, compliance, and governance in a machine-readable format. ### examples Example ADL documents demonstrating minimal, intermediate, and production-ready agent definitions. - [Examples](/spec/examples.md): Example ADL documents demonstrating minimal, intermediate, and production-ready agent definitions. - [Minimal Example](/spec/examples/minimal.md): The simplest valid ADL document with only the four required fields. - [Production Agent Example](/spec/examples/production.md): A complete production-ready ADL document with identity, permissions, security, and all optional features. - [Agent with Tools Example](/spec/examples/with-tools.md): A calculator agent demonstrating ADL tool definitions with parameters and return types. ## protocol The ADL protocol layer — the normative procedures that give an agent's declarations force. Trust Protocol (counterparty procedures) and Runtime Protocol (runtime-governor procedures). - [Protocol](/protocol.md): The ADL protocol layer — the normative procedures that give an agent's declarations force. Trust Protocol (counterparty procedures) and Runtime Protocol (runtime-governor procedures). ### runtime The Runtime Protocol — normative procedures a runtime governor performs to enforce an agent's declared operational limits during execution. - [Runtime Protocol](/protocol/runtime.md): The Runtime Protocol — normative procedures a runtime governor performs to enforce an agent's declared operational limits during execution. ### trust The Trust Protocol — normative procedures for passport verification, presentation proof, and authorization enforcement in agent-to-agent trust. - [Trust Protocol](/protocol/trust.md): The Trust Protocol — normative procedures for passport verification, presentation proof, and authorization enforcement in agent-to-agent trust. ## patterns Worked deployment patterns that trace real-world agent topologies through the ADL specification end-to-end. - [Patterns](/patterns.md): Worked deployment patterns that trace real-world agent topologies through the ADL specification end-to-end. ### ai-gateway How an AI gateway (Kong AI Gateway, Cloudflare AI Gateway, Portkey, LiteLLM, Databricks Mosaic AI Gateway) mediates an agent's outbound model, tool, and agent-to-agent traffic — custodying the agent's ADL signing key, constructing presentation proofs and delegation links, and enforcing resource and data-classification policy. - [Mediating Agent Egress through an AI Gateway](/patterns/ai-gateway.md): How an AI gateway (Kong AI Gateway, Cloudflare AI Gateway, Portkey, LiteLLM, Databricks Mosaic AI Gateway) mediates an agent's outbound model, tool, and agent-to-agent traffic — custodying the agent's ADL signing key, constructing presentation proofs and delegation links, and enforcing resource and data-classification policy. ### exposing-agents How an organization exposes agents that external humans and peer agents discover and call — the provider (resource-server) side, where every inbound caller authenticates per session or per request rather than once at setup. - [Exposing Agents to External Callers](/patterns/exposing-agents.md): How an organization exposes agents that external humans and peer agents discover and call — the provider (resource-server) side, where every inbound caller authenticates per session or per request rather than once at setup. ### inbound-verification How ADL is verified and enforced on every inbound request at a Policy Enforcement Point (PEP) — a role, not a product — that can live in the agent runtime, an AI-aware gateway, a dedicated ADL verifier, or (incidentally, and not as a default) a generic API gateway. - [Verifying Inbound Callers (the Policy Enforcement Point)](/patterns/inbound-verification.md): How ADL is verified and enforced on every inbound request at a Policy Enforcement Point (PEP) — a role, not a product — that can live in the agent runtime, an AI-aware gateway, a dedicated ADL verifier, or (incidentally, and not as a default) a generic API gateway. ### multi-hop-authorization How ADL composes authentication and authorization across multiple agent hops — human OAuth 2.1, MCP token exchange, ADL passport + presentation proof, and scope composition across boundaries — illustrated with a vacation-booking scenario. - [Multi-Hop Authentication and Authorization](/patterns/multi-hop-authorization.md): How ADL composes authentication and authorization across multiple agent hops — human OAuth 2.1, MCP token exchange, ADL passport + presentation proof, and scope composition across boundaries — illustrated with a vacation-booking scenario. ## profiles ADL Profiles extend the core specification with domain-specific requirements for regulated industries. - [Profiles](/profiles.md): ADL Profiles extend the core specification with domain-specific requirements for regulated industries. ### financial - [Financial Profile Examples](/profiles/financial/1.0/examples.md): Example ADL documents using the Financial Profile across banking and brokerage compliance and AML controls. - [Financial Profile Compatibility](/profiles/financial/compatibility.md): Compatibility matrix between Financial Profile and ADL specification versions. - [Financial Profile](/profiles/financial/overview.md): The Financial Profile extends ADL for financial services with PCI-DSS, SOX, GLBA, and MiFID II compliance. - [Financial Profile Specification](/profiles/financial/specification.md): Full specification for the ADL Financial Profile including PCI-DSS, SOX, GLBA, MiFID II, and AML/KYC compliance. ### governance - [Governance Profile Examples](/profiles/governance/1.0/examples.md): Example ADL documents using the Governance Profile with conformance tiers. - [Governance Record Specification](/profiles/governance/1.0/governance-record.md): Companion specification defining the governance record schema for operational governance detail stored in agent registries. - [Governance Profile Compatibility](/profiles/governance/compatibility.md): Compatibility matrix between Governance Profile and ADL specification versions. - [Governance Profile](/profiles/governance/overview.md): The Governance Profile extends ADL for regulated enterprise environments with compliance tracking and audit trails. - [Governance Profile Specification](/profiles/governance/specification.md): Full specification for the ADL Governance Profile including compliance frameworks, AI governance, and audit trails. ### healthcare - [Healthcare Profile Examples](/profiles/healthcare/1.0/examples.md): Example ADL document using the Healthcare Profile for HIPAA compliance and clinical safety. - [Healthcare Profile Compatibility](/profiles/healthcare/compatibility.md): Compatibility matrix between Healthcare Profile and ADL specification versions. - [Healthcare Profile](/profiles/healthcare/overview.md): The Healthcare Profile extends ADL for healthcare environments with HIPAA compliance, PHI handling, and clinical safety controls. - [Healthcare Profile Specification](/profiles/healthcare/specification.md): Full specification for the ADL Healthcare Profile including HIPAA compliance, PHI handling, clinical safety, and FHIR interoperability. ### portfolio - [Portfolio Profile Examples](/profiles/portfolio/1.0/examples.md): Example ADL document using the Portfolio Profile for agent relationships and domain membership. - [Portfolio Profile Compatibility](/profiles/portfolio/compatibility.md): Compatibility matrix between Portfolio Profile and ADL specification versions. - [Portfolio Profile](/profiles/portfolio/overview.md): The Portfolio Profile extends ADL with agent relationships and domain membership for managing agent portfolios at scale. - [Portfolio Profile Specification](/profiles/portfolio/specification.md): Full specification for the ADL Portfolio Profile including agent relationships and domain membership. ### registry - [Registry Profile Examples](/profiles/registry/1.0/examples.md): Example ADL document using the Registry Profile for agent catalog and federation. - [Registry Profile Compatibility](/profiles/registry/compatibility.md): Compatibility matrix between Registry Profile and ADL specification versions. - [Registry Profile](/profiles/registry/overview.md): The Registry Profile extends ADL with agent catalog identity, classification, and multi-registry federation capabilities. - [Registry Profile Specification](/profiles/registry/specification.md): Full specification for the ADL Registry Profile including agent catalog identity, classification, and federation. ## standardization ### roadmap ADL's path toward becoming a recognized industry standard. - [Standardization](/standardization/roadmap.md): ADL's path toward becoming a recognized industry standard. ## contributing How to contribute to the ADL specification, examples, profiles, and implementations. - [Contributing](/contributing.md): How to contribute to the ADL specification, examples, profiles, and implementations. ## demo ADL solves a fundamental problem in multi-agent systems: how does one agent learn what another agent can do, and whether it should be trusted? - [Passport Discovery](/demo.md): ADL solves a fundamental problem in multi-agent systems: how does one agent learn what another agent can do, and whether it should be trusted? ## governance Governance model for the ADL specification project including roles and decision-making processes. - [Governance](/governance.md): Governance model for the ADL specification project including roles and decision-making processes. ## implementations Tools, libraries, and platforms that implement or consume ADL documents. - [Implementations](/implementations.md): Tools, libraries, and platforms that implement or consume ADL documents. ## search Agent Definition Language (ADL) — the open standard for defining AI agent identity, permissions, lifecycle, and compliance in one auditable, machine-readable document. - [Search the documentation](/search.md): Agent Definition Language (ADL) — the open standard for defining AI agent identity, permissions, lifecycle, and compliance in one auditable, machine-readable document. ## Optional - [OKF Knowledge Bundle](/okf/index.md): Open Knowledge Format (OKF v0.1) bundle: the ADL spec, protocol, profiles, patterns, and examples as agent-readable markdown. - [OKF — Specification](/okf/spec/index.md): The normative ADL specification as OKF concept pages, one per section. - [OKF — Trust & Runtime Protocol](/okf/protocol/index.md): The ADL trust and runtime protocol documents as OKF concept pages. - [OKF — Profiles](/okf/profiles/index.md): ADL domain profiles (governance, financial, healthcare, and more) as OKF concept pages. - [OKF — Patterns](/okf/patterns/index.md): ADL deployment patterns as OKF concept pages. - [OKF — Examples](/okf/examples/index.md): Worked ADL example documents with full YAML inlined, as OKF concept pages. --- # Full Documentation Content [Skip to main content](#__docusaurus_skipToContent_fallback) [![ADL Logo](/img/logo.svg)![ADL Logo](/img/logo.svg)](/index.md) [**Agent Definition Language**](/index.md) Search [agent-definition-language/specification](https://github.com/agent-definition-language/specification) Auto [](/index.md)[Specification](/spec/.md)[Profiles](/profiles/.md)[Protocol](/protocol/.md)[Patterns](/patterns/.md)[Implementations](/implementations.md)[Standardization](/standardization/roadmap.md) # Search the documentation Specification * [ADL Specification](/spec/.md) * [GitHub](https://github.com/agent-definition-language/specification) Resources * [Profiles](/profiles/.md) * [Examples](/spec/examples/.md) * [Implementations](/implementations.md) * [FAQ](/faq) Community * [Contributing](/contributing.md) * [Governance](/governance.md) * [GitHub](https://github.com/agent-definition-language/specification) * [LLMs.txt](/llms.txt) Standardization * [Roadmap](/standardization/roadmap.md) * [Get Involved](https://github.com/agent-definition-language/specification) Copyright 2026 ADL Specification Authors. Patent Pending. Licensed under Apache 2.0. --- # Patterns Worked deployment patterns that trace real-world agent topologies through the spec end-to-end. Each pattern cites specific section numbers — [§1.1](/protocol/trust.md#11-passport-verification-procedure) verification, [§1.2](/protocol/trust.md#12-presentation-proof) presentation proof, [§10.3.3](/spec/next#1033-credential-schemes) credential schemes, [§10.4](/spec/next#104-authorization-scopes) authorization scopes — so an implementer reading along can move from "I want this behavior in production" to "the normative paragraph that says how" in one lookup. This section is **non-normative**. The normative content lives in the [specification](/spec/next). Patterns illustrate composition, document failure modes, and provide regulators or auditors with reconstructable end-to-end traces — but if a pattern ever conflicts with the spec, the spec wins. ## What belongs here[​](#what-belongs-here "Direct link to What belongs here") * **Multi-hop scenarios** that exercise the cohesive Authentication structure ([§10.3](/spec/next#103-authentication)) and Authorization Scopes ([§10.4](/spec/next#104-authorization-scopes)) across both the human/external boundary ([§10.3.3](/spec/next#1033-credential-schemes) OAuth 2.1) and the agent-to-agent boundary ([§1.1](/protocol/trust.md#11-passport-verification-procedure) + [§1.2](/protocol/trust.md#12-presentation-proof)). * **Real-world deployment shapes** with concrete actors, scopes, audit chains, and failure modes — not abstract "Alice and Bob" pedagogy. * **Cross-flow composition** where the [§2.3](/protocol/trust.md#23-composition-across-boundaries-multi-hop-authorization) independent-vs-reduction patterns become operationally visible. ## What does not belong here[​](#what-does-not-belong-here "Direct link to What does not belong here") * **Standalone ADL document samples** — those go in [Examples](/spec/next/examples) (e.g. `minimal.yaml`, `production.yaml`). * **Test vectors** — those go in `core/_next/test-vectors/`, with their own SCHEMA.md and conformance runners. * **Implementer guides** that prescribe "do these steps to build X" — patterns describe how the spec composes, not how to build something. ## Index[​](#index "Direct link to Index") | Pattern | Illustrated by | Authentication paths | Authorization patterns | | ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | | [Multi-hop authentication and authorization](/patterns/multi-hop-authorization.md) | Vacation-booking scenario: human → assistant → MCP calendar / travel discovery / flight + hotel agents | OAuth 2.1, OAuth Token Exchange, ADL passport + presentation proof | Scope reduction across hops, escalated scopes for booking, sender-constrained `proof.scopes` | | [Exposing agents to external callers](/patterns/exposing-agents.md) | Fortune-50 brokerage scenario: human client website chat + well-known discovery for peer agents | OIDC per session, ADL passport + presentation proof per request | Entitlements as scopes, provider allowlist + attestation, classification gating, step-up for high-stakes | | [Verifying inbound callers (the PEP)](/patterns/inbound-verification.md) | One Policy Enforcement Point across host shapes — agent-runtime plugin, AI-aware gateway, dedicated ADL verifier, and (incidentally) a generic API gateway | OIDC (human path) + ADL passport/proof (agent path) at one PEP | Ceiling + route-required scopes, principal/delegation enforcement, classification gating, verification boundary vs internal trust domain | | [Mediating agent egress through an AI gateway](/patterns/ai-gateway.md) | Support-agent platform behind an AI gateway (Kong AI / Cloudflare / Portkey / LiteLLM): model + tool + agent-to-agent egress | Gateway custodies the agent key, constructs passport + proof + delegation per outbound call | Key custody, per-call tool/MCP credentialing, budget + classification enforcement, model routing vs declared model | ## Conventions[​](#conventions "Direct link to Conventions") * **One pattern per file**, named after the capability it demonstrates. * **Section anchors** at the end of every pattern mapping every operation to the exact `§10.x.y.z` it cites. * **Failure modes section** documenting what happens when each authentication or authorization gate rejects. * **End-to-end audit reconstruction** showing how the chain reconstructs across hops where no single hop sees the full picture. * **Unversioned living guidance**: patterns are non-normative and track the current spec; they are not snapshotted per release. --- # Mediating Agent Egress through an AI Gateway **The pattern:** an organization runs its agents behind an **AI gateway** — Kong AI Gateway, Cloudflare AI Gateway, Portkey, LiteLLM, TrueFoundry, Databricks Mosaic AI Gateway, and the like — that mediates the agents' **outbound** AI traffic: model calls (routed across providers, cached, budgeted), tool and MCP calls, and agent-to-agent calls. Because the gateway is the point where an agent's *reasoning* ("call tool X", "ask the model", "delegate to sub-agent Y") becomes an authenticated *request*, it is the natural place to custody the agent's ADL signing key, construct its presentation proofs ([§1.2](/protocol/trust.md#12-presentation-proof)) and delegation links, attach its passport ([§1.1](/protocol/trust.md#11-passport-verification-procedure)), and enforce the resource and data-handling policy the passport declares. This is a **deployment pattern**. The AI gateway sits on the agent's **egress** edge, the mirror image of the inbound enforcement edge in [Verifying Inbound Callers (the PEP)](/patterns/inbound-verification.md). One organization will often run both: an inbound PEP verifying callers arriving at its agents, and an AI gateway mediating its agents' outbound traffic. > **AI gateway vs. inbound PEP vs. OpenClaw plugin.** An *inbound PEP* ([inbound-verification](/patterns/inbound-verification.md)) verifies callers arriving at a provider. An *AI gateway* mediates an agent's outbound model/tool/agent traffic (egress + signing + tool mediation). The *OpenClaw gateway plugin* is one specific agent-runtime's ADL integration — and a natural host for the inbound PEP. The ADL primitives are the same across all three; the position and the job differ. **Illustrated through a scenario:** Helios Support runs customer-support agents on an internal platform. Every outbound call those agents make goes through the Helios AI gateway: it routes model calls across providers (with the agent's declared model as the intent and fallbacks behind it), serves some from a semantic cache, mediates internal knowledge-base tools over MCP, and brokers calls to an external shipping carrier's agent to check delivery status on a customer's behalf. The support work is incidental; what matters is that one egress layer turns the agent's reasoning into authenticated, policy-bounded requests without the reasoning layer ever holding a key. ## Cast of actors[​](#cast-of-actors "Direct link to Cast of actors") | Actor | Role | Identity | Notes | | ----------------------- | --------------------------------------- | ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Helios AI Gateway** | Egress mediation + signing layer | `did:web:helios.example:gateways:egress` (its own passport) | Custodies each agent's ADL private key in a KMS; routes model calls; mediates tools/MCP; enforces budgets + guardrails. | | **Support Agent** | Helios agent (the principal's delegate) | `https://helios.example/agents/support-bot`, `did:web:helios.example:agents:support-bot` | Declares its `model` ([§7.1](/spec/next#71-model)), `permissions.resource_limits` ([§9.6](/spec/next#96-resource-limits)), and `data_classification` ([§10.1](/spec/next#101-data-classification)) in its passport. | | **Model providers** | LLM backends | (OpenAI, Anthropic, Bedrock, …) | The gateway routes/falls back across these; provider API keys are vaulted in the gateway. | | **Knowledge MCP tools** | Internal tools | MCP servers, OAuth 2.1 resource servers | Reached via the gateway, which attaches the right credential per call. | | **Carrier Agent** | External peer agent | `https://carrier.example/agents/tracking`, `did:web:carrier.example:agents:tracking` | Called agent-to-agent; the gateway signs the proof + delegation chain. | | **Customer (Dana)** | Human principal | OIDC subject `dana@example.com` | Delegated the support interaction; rides as `sub` in outbound proofs. | ## What the AI gateway does, in ADL terms[​](#what-the-ai-gateway-does-in-adl-terms "Direct link to What the AI gateway does, in ADL terms") ### 1. Custodies the signing key and constructs the credential (the headline role)[​](#1-custodies-the-signing-key-and-constructs-the-credential-the-headline-role "Direct link to 1. Custodies the signing key and constructs the credential (the headline role)") The reasoning/LLM layer of an agent should not hold its ADL private key. The AI gateway holds it (KMS/HSM) and, for each outbound call that needs ADL credentials, constructs them on the agent's behalf: * Attaches the agent's passport ([§1.1](/protocol/trust.md#11-passport-verification-procedure)). * Builds and signs the **presentation proof** ([§1.2](/protocol/trust.md#12-presentation-proof)) bound to the specific outbound request (method + target URI), claiming the minimum scopes the counterparty requires. * Injects the **principal** (`sub`, the customer) and **mints delegation links** when the agent delegates onward to a sub-agent — the egress gateway is where the signed `act` chain is produced, because it is the holder of the agent's key. (See the multi-hop and delegation models in [Multi-Hop Authentication and Authorization](/patterns/multi-hop-authorization.md).) This concentrates a powerful capability — the gateway can sign *as* the agent — which is the central tension below. ### 2. Mediates tool and MCP calls[​](#2-mediates-tool-and-mcp-calls "Direct link to 2. Mediates tool and MCP calls") When the agent reasons that it needs a tool, the call passes through the gateway, which attaches the right credential **per call**: * For an ADL-speaking tool/agent: passport + presentation proof ([§1.1](/protocol/trust.md#11-passport-verification-procedure) / [§1.2](/protocol/trust.md#12-presentation-proof)). * For an OAuth tool/MCP server: the OAuth 2.1 token (or a token-exchanged downstream token), per the credential schemes in [§10.3.3](/spec/next#1033-credential-schemes). This is the operational answer to "the tools an agent reasons it needs have their own authN/authZ that must be obtained and presented" — the gateway is where obtaining-and-presenting happens, uniformly, instead of in each agent's prompt-driven logic. ### 3. Enforces resource, cost, and classification policy[​](#3-enforces-resource-cost-and-classification-policy "Direct link to 3. Enforces resource, cost, and classification policy") The AI gateway is the runtime enforcement point for declarations the passport only *states*: * **Budgets / token + spend caps** map onto `permissions.resource_limits` ([§9.6](/spec/next#96-resource-limits)). The gateway refuses calls that would exceed the agent's declared limits. * **Guardrails / PII redaction / content moderation** map onto `data_classification` handling ([§10.1](/spec/next#101-data-classification)) — `encryption_required`, `anonymization_required`, `logging_required` are enforced on the actual prompt and completion traffic, not just declared. ### 4. Routes model calls against the declared model[​](#4-routes-model-calls-against-the-declared-model "Direct link to 4. Routes model calls against the declared model") The agent's passport declares its intended model ([§7.1](/spec/next#71-model)). The gateway routes to that model, with provider fallbacks and semantic caching behind it. This is convenient and cost-effective — but it opens a gap between *declared* and *actually-served* model that matters for trust and audit (a request the passport says ran on a frontier model may have been silently rerouted to a cheaper one, or served from cache). Capturing runtime evidence of which model actually served a request is being specified separately as model-provenance attestation; the AI gateway is the natural place to emit it, since it sits between the agent and the model. ## Outbound request lifecycle through the gateway[​](#outbound-request-lifecycle-through-the-gateway "Direct link to Outbound request lifecycle through the gateway") The Support Agent decides to ask the Carrier Agent for a delivery status, on Dana's behalf: 1. **Reasoning emits an intent.** The agent's model output is a structured call: "ask carrier.example/tracking for order #4471 status." The reasoning layer holds no key and constructs no credential. 2. **The gateway resolves and verifies the counterparty.** It discovers / fetches the Carrier Agent's passport and runs [§1.1](/protocol/trust.md#11-passport-verification-procedure) verification, reading the carrier's declared connection requirements (auth path + per-tool scopes) off the passport. 3. **The gateway constructs the credential.** It signs a presentation proof bound to the carrier's `track_order` URL, claims the minimum scope the carrier requires, sets `sub` = Dana (with her grant), and appends any delegation link if the support agent is itself a delegate. 4. **The gateway enforces egress policy.** Token budget check ([§9.6](/spec/next#96-resource-limits)), data-classification handling on the outbound payload ([§10.1](/spec/next#101-data-classification) — strip customer PII the carrier doesn't need), and the org's egress allowlist (may this agent talk to `carrier.example` at all?). 5. **The gateway sends the request** with `ADL-Passport` + `ADL-Proof`. The carrier (or its own inbound PEP) verifies it as in the [inbound-verification](/patterns/inbound-verification.md) pattern. 6. **Model calls follow the same shape.** When the agent calls the LLM, the gateway routes to the declared model (or a fallback / cache), enforces the same budget and classification policy, and records what actually served the request. 7. **Audit.** The gateway emits one egress record per call — the agent identity, the principal/delegation it asserted, the counterparty, the scopes claimed, and (for model calls) the actual model/serving mode — correlated by request id. ## The central tension: key custody[​](#the-central-tension-key-custody "Direct link to The central tension: key custody") Putting the agent's signing key in the gateway is the whole value (no keys in the model layer, uniform credential construction, central policy) and the whole risk. **The gateway can sign proofs and mint delegation links *as* the agent.** That makes it an extraordinarily high-value target and a hard trust boundary. Mitigations an ADL deployment should insist on: * **The gateway has its own ADL identity** (its own passport/keypair), distinct from the agents it signs for, so its actions are attributable. * **Scope what the gateway may sign for** — which agents, which counterparties, which scope ceilings — and enforce it in the gateway, not just trust the model output. * **Custody the agent keys in a KMS/HSM**, not in gateway process memory; the gateway requests signatures, it doesn't export keys. * **Audit every signature** the gateway produces on an agent's behalf, so a compromised gateway leaves a trail. * **Verify, don't mint trust** — the same discipline as any gateway: the gateway authenticates the agent's *own* reasoning context and the principal's grant before signing; it does not fabricate authority the agent or principal never had. Attenuation still applies — the gateway can only sign for scopes within the agent's ceiling and the principal's grant. ## Failure modes[​](#failure-modes "Direct link to Failure modes") ### The gateway is asked to sign beyond the agent's ceiling[​](#the-gateway-is-asked-to-sign-beyond-the-agents-ceiling "Direct link to The gateway is asked to sign beyond the agent's ceiling") The agent's reasoning requests a scope the agent's passport ceiling doesn't include. The gateway refuses to sign — it cannot construct a proof claiming scopes outside the ceiling (the downstream [§2.2](/protocol/trust.md#22-authorization-in-agent-to-agent-flows) check would reject it anyway, but the egress gateway should catch it first). The agent is told the capability isn't enabled. ### Model rerouting drifts from the declared model[​](#model-rerouting-drifts-from-the-declared-model "Direct link to Model rerouting drifts from the declared model") The passport declares a frontier model; the gateway falls back to a cheaper one under load, or serves from semantic cache. Without runtime evidence, a downstream consumer trusts the declaration blindly. The mitigation is model-provenance attestation (separate specification) emitted by the gateway, recording the actual model and serving mode so drift is visible in audit. ### Compromised gateway signs rogue requests[​](#compromised-gateway-signs-rogue-requests "Direct link to Compromised gateway signs rogue requests") If the gateway is compromised, it can sign as every agent it custodies keys for — a catastrophic blast radius. This is why the gateway's own identity, per-agent signing scope, KMS-backed keys, and signature audit are not optional. Note this is distinct from passport private-key compromise of a single agent; the egress gateway concentrates many agents' signing capability and must be protected accordingly. ### Egress to a disallowed counterparty[​](#egress-to-a-disallowed-counterparty "Direct link to Egress to a disallowed counterparty") The agent reasons its way to calling an external service the org hasn't approved. The gateway's egress allowlist blocks it before any credential is constructed — the reasoning layer cannot reach the network directly. ## Spec section index[​](#spec-section-index "Direct link to Spec section index") | Gateway operation | Spec section | | -------------------------------------------- | ------------------------------------------------------------------- | | Verify the counterparty's passport | [§1.1](/protocol/trust.md#11-passport-verification-procedure) | | Construct + sign the presentation proof | [§1.2](/protocol/trust.md#12-presentation-proof) | | Attach OAuth credential for OAuth tools/MCP | [§10.3.3](/spec/next#1033-credential-schemes) | | Claim scopes within the agent ceiling | [§2.2](/protocol/trust.md#22-authorization-in-agent-to-agent-flows) | | Enforce token/spend budgets | [§9.6](/spec/next#96-resource-limits) | | Enforce data-handling on prompts/completions | [§10.1](/spec/next#101-data-classification) | | Route against the declared model | [§7.1](/spec/next#71-model) | | Discover counterparty agents | [§6.4](/spec/next#64-discovery) | ## Related material[​](#related-material "Direct link to Related material") * [Verifying Inbound Callers (the PEP)](/patterns/inbound-verification.md) — the inbound mirror; the AI gateway's outbound proofs are what an inbound PEP verifies * [Multi-Hop Authentication and Authorization](/patterns/multi-hop-authorization.md) — the proofs and delegation the AI gateway constructs * [Exposing Agents to External Callers](/patterns/exposing-agents.md) — the provider edge a mediated egress call arrives at * [Draft spec §7 (Model Configuration)](/spec/next#7-model-configuration) * [Draft spec §9 (Permissions)](/spec/next#9-permissions) * [Draft spec §10.3 (Authentication)](/spec/next#103-authentication) --- # Exposing Agents to External Callers **The pattern:** an organization exposes agents that external parties — its own human clients, and peer agents acting for others — discover and call. This is the *provider* side of the connection, and it behaves differently from a personal agent. A personal agent ([Multi-Hop Authentication and Authorization](/patterns/multi-hop-authorization.md)) is set up once by its owner and carries standing delegated authority. A provider has never met its callers: it authenticates **every inbound caller fresh** — each human session, each peer-agent request. There is no "set up once" with parties the provider didn't provision. **Illustrated through a scenario:** Meridian Capital, a Fortune-50 brokerage, exposes agents — portfolio analysis, market research, trade execution — to the outside world through two front doors: 1. **A chat interface on its authenticated client website.** A retail client signs in to `meridian.example` and talks to the portfolio agent. 2. **A well-known discovery file** that lets peer agents (a wealth-management aggregator, or a client's own personal agent) find Meridian's agents and call them directly. We trace authentication and authorization for both doors, and show why the provider side is per-session / per-request, not setup-once. ## Why the provider side is different[​](#why-the-provider-side-is-different "Direct link to Why the provider side is different") This is the question the personal-agent walkthrough leaves open: if authentication is "established once at setup," how does that work for an agent that exposes itself to the world? It doesn't — because "once at setup" describes the *client* role, not the *provider* role. | | Personal agent (client / delegate) | Agent provider (resource server) | | ---------------------------------------------- | ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Who provisions the trust | Its owner, once at setup | Nobody — callers arrive unprovisioned | | When authentication happens | Once at setup; channel-bound per message thereafter | Per human session and per agent request | | Standing authority | Holds delegated authority and spends it | Validates each caller's authority at the door | | Knows its counterparties in advance? | Yes — it set up the connections | No — anyone may show up | | Role in [§10.3](/spec/next#103-authentication) | The party *being verified* (presents passport + proof) | The *verifier* (runs [§1.1](/protocol/trust.md#11-passport-verification-procedure), [§1.2](/protocol/trust.md#12-presentation-proof), checks [§10.3.3](/spec/next#1033-credential-schemes) credentials) | **Roles are per connection, not per agent.** Meridian is a provider to its callers, but when its own trade-execution agent calls a clearing house or a market-data feed, Meridian is a *client* there — set up once, presenting credentials. The same agent is a provider on its inbound edge and a client on its outbound edge. The personal-agent pattern traced the client edge; this one traces the provider edge of the very same kind of connection. ## Cast of actors[​](#cast-of-actors "Direct link to Cast of actors") | Actor | Role | Identity | Notes | | ---------------------------- | ------------------------------------- | ---------------------------------------------------------------------------------------- | -------------------------------------------------- | | **Meridian Capital** | Agent provider (brokerage) | `https://agents.meridian.example`, IdP at `auth.meridian.example` | FINRA/SEC-regulated; did KYC at account opening | | **Portfolio Analysis Agent** | Meridian agent | `https://agents.meridian.example/portfolio`, `did:web:agents.meridian.example:portfolio` | Tools require `portfolio:read` | | **Market Research Agent** | Meridian agent | `https://agents.meridian.example/research` | Tools require `research:read` | | **Trade Execution Agent** | Meridian agent (high-stakes) | `https://agents.meridian.example/trade` | Tools require `trades:execute`; step-up required | | **Dana** | Human Meridian client | Account `dana@example.com`, signs in to `meridian.example` | Already KYC-verified at account opening | | **Wealth Aggregator** | Peer agent acting for a mutual client | `https://aggregator.example/agents/advisor`, `did:web:aggregator.example:agents:advisor` | Calls Meridian's portfolio agent to pull positions | | **Meridian Discovery** | Well-known endpoint | `https://agents.meridian.example/.well-known/adl-agents` | Lists Meridian's externally-callable agents | ## Front door 1: Authenticated website chat (human clients)[​](#front-door-1-authenticated-website-chat-human-clients "Direct link to Front door 1: Authenticated website chat (human clients)") **Authentication path:** [§10.3.3](/spec/next#1033-credential-schemes) (OIDC) — **per session, not once at setup** **Authorization path:** [§2.1](/protocol/trust.md#21-authorization-in-human-to-agent-flows) (Human-to-Agent Flows) ### What happens[​](#what-happens "Direct link to What happens") 1. Dana navigates to `meridian.example` and signs in. Meridian is an OpenID Connect provider; Dana authenticates with username + password + MFA. **This authentication is fresh every session** — when her session expires, she re-authenticates. Meridian already did identity proofing (KYC) when Dana opened her account, so the login binds to a known, proofed identity. 2. Meridian issues a session with an OIDC ID token and an access token whose `scope` reflects Dana's *entitlements*, computed by Meridian's own authorization system from her account profile: ``` scope = openid portfolio:read research:read trades:execute ``` Dana is a full-service client, so she gets trade execution. A view-only client would get `portfolio:read research:read` and no `trades:execute`. 3. Dana opens the chat and asks the portfolio agent: "How did my retirement account do this quarter?" The browser sends the message with her session token (DPoP-bound per [§10.3.3.1](/spec/next#10331-oauth-21-type-oauth2)). 4. The portfolio agent authorizes per [§2.1](/protocol/trust.md#21-authorization-in-human-to-agent-flows): * `required = ["portfolio:read"]` for the `get_performance` tool. * `presented = ["portfolio:read", "research:read", "trades:execute"]` from Dana's session token. * `required ⊆ presented` ✓ — authorized. The agent returns the quarter's performance. 5. Dana then says "sell 100 shares of ACME." This routes to the trade-execution agent, whose `place_order` tool requires `trades:execute` — a **high-stakes** scope. Meridian's policy requires a **step-up** for trade execution even within an authenticated session: the agent issues a re-authentication challenge (MFA re-prompt, or a signed confirmation), per the same step-up pattern as a server-issued nonce ([§1.2.7](/protocol/trust.md#127-server-issued-nonces) is the agent-to-agent analog). Only after Dana satisfies the challenge does the order go through. **The contrast with the personal agent:** Dana is not "set up once." Every session is a fresh OIDC authentication, sessions expire, and high-stakes actions force re-authentication mid-session. Meridian is the resource server; Dana is an unprovisioned-until-she-logs-in caller. **Audit record:** * Inbound: OIDC session, `sub=dana@example.com`, MFA satisfied, scopes from entitlements * Tools: `get_performance` (authorized), `place_order` (authorized after step-up) * Outcome per tool, with the step-up event recorded for FINRA/SEC ## Front door 2: Well-known discovery + agent-to-agent[​](#front-door-2-well-known-discovery--agent-to-agent "Direct link to Front door 2: Well-known discovery + agent-to-agent") **Authentication path:** [§1.1](/protocol/trust.md#11-passport-verification-procedure) + [§1.2](/protocol/trust.md#12-presentation-proof) — **per request, not once at setup** **Authorization path:** [§2.2](/protocol/trust.md#22-authorization-in-agent-to-agent-flows) (Agent-to-Agent Flows) A mutual client of both Meridian and a wealth-management platform has authorized the **Wealth Aggregator** agent to pull their Meridian positions into a consolidated view. The aggregator is a peer agent Meridian has never provisioned. Here is how it connects. ### Discovery[​](#discovery "Direct link to Discovery") 1. The aggregator fetches `GET https://agents.meridian.example/.well-known/adl-agents` ([§6.4](/spec/next#64-discovery)). No auth on the listing — discovery is public. It returns Meridian's externally-callable agents: ``` { "adl_discovery": "1.0", "agents": [ { "id": "https://agents.meridian.example/portfolio", "adl_document": "https://agents.meridian.example/portfolio", "name": "Meridian Portfolio Analysis", "version": "4.1.0", "status": "active" }, { "id": "https://agents.meridian.example/research", "adl_document": "https://agents.meridian.example/research", "name": "Meridian Market Research", "version": "2.0.0", "status": "active" } ] } ``` Note: the trade-execution agent is **not** listed for public discovery — Meridian only exposes read-oriented agents to unprovisioned peers. Discovery is a deliberate disclosure decision, not an automatic dump of every agent. 2. The aggregator fetches the portfolio agent's passport and runs the full [§1.1](/protocol/trust.md#11-passport-verification-procedure) verification (it is verifying *Meridian*, the same way Meridian will shortly verify *it*). It also reads Meridian's declared connection requirements from the passport: ``` security: authentication: type: oauth2 # Meridian also accepts agent-to-agent; see below scopes: ["portfolio:read"] attestation: type: third_party # Meridian requires callers to be attested, see §10.2 tools: - name: get_positions security: scopes: ["portfolio:read"] ``` ### Per-request authentication at Meridian[​](#per-request-authentication-at-meridian "Direct link to Per-request authentication at Meridian") 3. The aggregator calls `POST https://agents.meridian.example/portfolio/tools/get_positions`, presenting: * `ADL-Passport`: the aggregator's own signed passport. * `ADL-Proof`: a fresh presentation proof ([§1.2](/protocol/trust.md#12-presentation-proof)) bound to this request URI and method, claiming `scopes: ["portfolio:read"]`. 4. Meridian — now the **verifier** — authenticates the inbound caller from scratch. **It has no prior relationship with the aggregator; everything it needs arrives in this request:** * [§1.1](/protocol/trust.md#11-passport-verification-procedure): verify the aggregator's passport (resolve its `did:web`, cross-check key, verify signature, check lifecycle). * [§1.2.6](/protocol/trust.md#126-verification-procedure): verify the presentation proof (issuer match, temporal validity, request binding, signature, replay). * **Provider allowlist ([§1.1.8](/protocol/trust.md#118-provideridentity-coherence)):** because Meridian is regulated, it does not accept *any* well-formed passport. It checks the aggregator's `provider` / `id` authority against an allowlist of agents it has agreed to do business with, and requires the passport to carry a third-party attestation ([§10.2](/spec/next#102-attestation)) from an issuer Meridian trusts. An unknown but cryptographically valid agent is rejected here — verification ≠ authorization to transact. * [§2.2](/protocol/trust.md#22-authorization-in-agent-to-agent-flows): ceiling check (`proof.scopes ⊆ aggregator's passport ceiling`) and required-scope check (`get_positions` requires `portfolio:read` ⊆ `proof.scopes`). * [§1.1.9](/protocol/trust.md#119-permission-and-classification-compatibility): positions are `confidential` ([§10.1](/spec/next#101-data-classification)); Meridian checks the aggregator's declared `data_classification.sensitivity` is high enough to receive them. 5. All checks pass; Meridian returns the positions. **Every one of those checks runs again on the aggregator's next request** — there is no session that "remembers" the aggregator the way Dana's browser session remembers her. Agent-to-agent is stateless per request; the presentation proof is the per-request authenticator. **The contrast with the personal agent, restated:** Alice's personal agent was set up once and *holds* authority. The aggregator is not set up at Meridian at all — it earns authorization on each request by presenting a verifiable passport, a fresh proof, a trusted attestation, and scopes within both its own ceiling and Meridian's requirements. **Audit record:** * Inbound: passport DID `did:web:aggregator.example:agents:advisor`, attestation issuer, proof `jti`, proof.scopes `[portfolio:read]` * Allowlist + attestation check outcome * Tool: `get_positions`, classification check, outcome * Logged per request for FINRA/SEC reconstruction ## The regulated-provider overlay[​](#the-regulated-provider-overlay "Direct link to The regulated-provider overlay") A Fortune-50 brokerage adds requirements a consumer service wouldn't: * **Identity proofing.** For humans, KYC happened at account opening; the OIDC login binds to that proofed identity. For agents, Meridian requires a third-party attestation ([§10.2](/spec/next#102-attestation)) and an allowlisted provider authority — a cryptographically valid passport from an unknown party is not enough to transact. * **Entitlements as scopes.** What a caller may do (view positions vs. execute trades) is expressed as [§10.4](/spec/next#104-authorization-scopes) scopes, derived from the human's account profile or the agent's negotiated relationship — not from the caller's say-so. * **Step-up for high-stakes operations.** Trade execution forces re-authentication (humans) or a server-issued nonce / human-in-the-loop confirmation (agents, [§1.2.7](/protocol/trust.md#127-server-issued-nonces)), even within an otherwise-authenticated session. * **Data classification gating.** Positions and balances are `confidential` ([§10.1](/spec/next#101-data-classification)); Meridian enforces classification compatibility ([§1.1.9](/protocol/trust.md#119-permission-and-classification-compatibility)) so a caller cleared only for `public` data cannot receive them. * **Per-interaction audit.** Every inbound authentication and authorization decision — human or agent — is logged with enough detail to reconstruct who did what, under whose authority, when. The per-request statelessness of the agent path is an audit *advantage*: each request carries its own signed, timestamped proof. ## Where "once at setup" does and does not apply[​](#where-once-at-setup-does-and-does-not-apply "Direct link to Where \"once at setup\" does and does not apply") Putting the two patterns together: | Connection | Setup-once or per-request? | Why | | --------------------------------------- | -------------------------------------------- | ---------------------------------------------------- | | Alice → her personal agent | Once at setup (then channel-bound) | Alice provisions and delegates to *her own* agent | | Personal agent → Meridian | Per request (from Meridian's side) | Meridian never provisioned the personal agent | | Dana → Meridian website | Per session | Meridian authenticates each login fresh | | Aggregator → Meridian | Per request | Stateless agent-to-agent; proof is the authenticator | | Meridian's trade agent → clearing house | Once at setup (Meridian is the client there) | Meridian provisions its *own* upstream connections | "Once at setup" is what a principal does with an agent it *owns*. Everything an agent does toward parties it does *not* own is authenticated per session or per request. The two patterns are the two ends of the same wire. ## Failure modes[​](#failure-modes "Direct link to Failure modes") ### Dana's session expired[​](#danas-session-expired "Direct link to Dana's session expired") She comes back an hour later and sends another message. The token is past `exp`; Meridian rejects with `401` and the chat prompts her to re-authenticate. No standing authority carries her across the gap — provider sessions are deliberately finite. ### The aggregator is verifiable but not on Meridian's allowlist[​](#the-aggregator-is-verifiable-but-not-on-meridians-allowlist "Direct link to The aggregator is verifiable but not on Meridian's allowlist") The aggregator's passport verifies cleanly under [§1.1](/protocol/trust.md#11-passport-verification-procedure), and its proof is valid under [§1.2](/protocol/trust.md#12-presentation-proof) — but Meridian has no business relationship with `aggregator.example`. The allowlist / attestation check rejects it. **Verification is not authorization:** proving who you are does not entitle you to transact with a regulated provider. The aggregator gets a structured `403` distinguishing "not verified" from "verified but not authorized." ### A peer agent requests `trades:execute` over discovery[​](#a-peer-agent-requests-tradesexecute-over-discovery "Direct link to a-peer-agent-requests-tradesexecute-over-discovery") The trade-execution agent isn't even listed in the well-known file, and its tools require a step-up that the stateless agent-to-agent path doesn't satisfy on its own. A peer agent that somehow targets the trade endpoint is rejected: the scope is outside what Meridian grants to discovered peers, and high-stakes execution requires the human step-up or an explicit, separately-negotiated machine relationship. Read is open to attested peers; execute is not. ### Replayed proof against the portfolio agent[​](#replayed-proof-against-the-portfolio-agent "Direct link to Replayed proof against the portfolio agent") A captured `ADL-Proof` replayed at the same endpoint is caught by [§1.2.6.6](/protocol/trust.md#126-verification-procedure) (the `jti` is already in Meridian's recent-cache); replayed at a different endpoint, by [§1.2.6.4](/protocol/trust.md#126-verification-procedure) (request-binding mismatch). The provider's per-request verification is exactly what makes replay detectable. ### Caller's classification is too low for positions[​](#callers-classification-is-too-low-for-positions "Direct link to Caller's classification is too low for positions") The aggregator's passport declares `data_classification.sensitivity: internal`, but Meridian classifies positions as `confidential`. [§1.1.9](/protocol/trust.md#119-permission-and-classification-compatibility) rejects: the caller is not cleared to receive `confidential` data. Meridian returns a classification-mismatch error without leaking the positions. ## Spec section index[​](#spec-section-index "Direct link to Spec section index") | Provider operation | Spec section | | --------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | | Publish callable agents | [§6.4](/spec/next#64-discovery) (well-known discovery) | | Human client login (per session) | [§10.3.3.1](/spec/next#10331-oauth-21-type-oauth2) (OIDC) | | Authorize human request | [§2.1](/protocol/trust.md#21-authorization-in-human-to-agent-flows) | | Step-up for high-stakes human action | [§1.2.7](/protocol/trust.md#127-server-issued-nonces) (analog) | | Verify inbound peer agent (per request) | [§1.1](/protocol/trust.md#11-passport-verification-procedure) (all steps) | | Verify the request binding | [§1.2.6](/protocol/trust.md#126-verification-procedure) | | Require caller attestation | [§10.2](/spec/next#102-attestation) (third-party) | | Provider allowlist for transacting | [§1.1.8](/protocol/trust.md#118-provideridentity-coherence) | | Authorize peer agent request | [§2.2](/protocol/trust.md#22-authorization-in-agent-to-agent-flows) (ceiling + required scope) | | Classification gating | [§10.1](/spec/next#101-data-classification) + [§1.1.9](/protocol/trust.md#119-permission-and-classification-compatibility) | ## Related material[​](#related-material "Direct link to Related material") * [Multi-Hop Authentication and Authorization](/patterns/multi-hop-authorization.md) — the client/delegate side of the same kind of connection * [Draft spec §10.3 (Authentication)](/spec/next#103-authentication) * [Draft spec §10.4 (Authorization Scopes)](/spec/next#104-authorization-scopes) * [Draft spec §6.4 (Discovery)](/spec/next#64-discovery) * [OpenClaw passport reference example](https://github.com/adl-spec/agent-definition-language/tree/main/packages/adl-agent/examples/openclaw-passport) (GitHub) — the enterprise gateway is a small working model of this provider edge --- # Verifying Inbound Callers (the Policy Enforcement Point) **The pattern:** every inbound request to an agent — from a human (OAuth 2.1 / OIDC) or a peer agent (ADL passport + presentation proof + delegation chain) — must be authenticated and authorized *before* it reaches the agent's logic. The component that does this is a **Policy Enforcement Point (PEP)**: it runs the [§10.3](/spec/next#103-authentication) + [§10.4](/spec/next#104-authorization-scopes) procedures, holds the per-verifier state (replay cache, nonces, allowlists), and emits one consistent audit record — so the agents behind it don't each re-implement verification. The PEP is a **role, not a product.** The verification it runs is exactly the procedure defined for any verifier ([§10.3](/spec/next#103-authentication) / [§10.4](/spec/next#104-authorization-scopes)); it is not a new ADL construct. What varies between deployments is *where* the PEP lives and *how well that host understands agent traffic*. That second point matters more than it first appears: an API gateway can reverse-proxy anything, which makes it the obvious place to bolt verification onto — and is exactly why it is the wrong *default* for AI agents. The verification is necessary but not sufficient; the agent-native policy that should ride alongside it (streaming responses, token/spend budgets, per-tool-call authorization, classification on live content) wants to live where the agent semantics are. The closing section makes that case. > **PEP vs. egress gateway vs. OpenClaw plugin.** This pattern is the **inbound** edge: verifying callers *arriving* at an agent. Its mirror image is the [AI gateway](/patterns/ai-gateway.md), which mediates an agent's **outbound** traffic (egress + signing + tool mediation). The *OpenClaw gateway plugin* is one specific agent-runtime's inbound PEP. The ADL primitives are identical across all of these; the position and the job differ. ## Where the PEP can live[​](#where-the-pep-can-live "Direct link to Where the PEP can live") The same verification — passport ([§1.1](/protocol/trust.md#11-passport-verification-procedure)), proof ([§1.2](/protocol/trust.md#12-presentation-proof)), credential schemes ([§10.3.3](/spec/next#1033-credential-schemes)), scopes ([§10.4](/spec/next#104-authorization-scopes)) — can be hosted in several shapes. They differ not in *what* they verify but in how much of the agent's runtime semantics they can see and enforce alongside the identity check: | Host shape | What it is | Agent-native fit | When to reach for it | | -------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | | **Agent-runtime PEP** | Verification runs inside the agent runtime (e.g. the OpenClaw gateway plugin), in-process or as a runtime sidecar | **Highest** — sees the full agent context: streams, tool calls, token budgets, prompt/completion classification | The default for an ADL-native agent. The PEP and the agent semantics are co-located. | | **AI-aware gateway** | A gateway purpose-built for AI traffic (an AI gateway in inbound mode, or an AI-aware data plane) | **High** — understands streaming, tokens, model/tool semantics natively | Fronting a fleet where you want one edge *and* agent-native enforcement, without re-implementing it per agent. | | **Dedicated ADL verification service** | A focused verifier the host calls out to (ext\_authz sidecar, standalone service) | **Medium** — does the identity/proof/scope check cleanly; agent-native policy stays in the caller | You want verification factored out and reused, but keep budget/tool/classification policy in the runtime. | | **Generic API gateway** | A vendor-neutral gateway (Kong, Apigee, Envoy, AWS API Gateway, NGINX) running ADL verification as a plugin/filter/Lua/Wasm module | **Low** — treats traffic as opaque request/response HTTP; agent-native concerns must be bolted on | An incremental adoption path if you *already* run one — not the architecture to choose for AI agents from scratch. | The verification procedure in the lifecycle below is written for the PEP role and holds for all four. The scenario uses a single abstract enforcement edge so the steps stay host-agnostic; the closing section explains why the last row is a fallback, not a default. ## What the PEP is, and is not[​](#what-the-pep-is-and-is-not "Direct link to What the PEP is, and is not") * **It is** the verifier: it runs passport verification ([§1.1](/protocol/trust.md#11-passport-verification-procedure)), presentation-proof verification ([§1.2](/protocol/trust.md#12-presentation-proof)), the delegation/principal checks that ride in the proof ([§2.3](/protocol/trust.md#23-composition-across-boundaries-multi-hop-authorization)), credential-scheme validation for human callers ([§10.3.3](/spec/next#1033-credential-schemes)), and scope authorization ([§10.4](/spec/next#104-authorization-scopes)). It holds the replay cache ([§1.2](/protocol/trust.md#12-presentation-proof)), issues step-up nonces, applies the provider allowlist and attestation requirements, and gates on data classification ([§1.1.9](/protocol/trust.md#119-permission-and-classification-compatibility)). * **It is not** the root of trust. Proofs and delegation links are signed end-to-end by the real principals and agents; the PEP *verifies* that cryptographic chain, it does not *mint* it. The chain remains independently verifiable even if you bypass the PEP. A PEP that starts re-signing or vouching for identities it did not verify has reinvented a central authorization server — the exact thing the [passport + proof model](/spec/next#103-authentication) avoids. ## Illustrated through a scenario[​](#illustrated-through-a-scenario "Direct link to Illustrated through a scenario") Northwind Trading runs a fleet of internal agents — an Inventory Agent, a Pricing Agent, an Order Agent — none of them publicly reachable. Inbound requests are verified at a single enforcement edge before reaching any of them. Two kinds of caller arrive at that edge: a supplier's **Procurement Agent** (a peer agent, sometimes acting for a human buyer) and Northwind's own employees using an internal console. The edge authenticates both, authorizes the specific operation, and routes to the right backing agent. The trading is incidental; what matters is that one PEP handles both authentication paths and both authorization models — and that the *same* procedure would run whether Northwind hosts it in its agent runtime, an AI-aware gateway, a dedicated verifier, or (incidentally) a generic API gateway. ### Cast of actors[​](#cast-of-actors "Direct link to Cast of actors") | Actor | Role | Identity | Notes | | -------------------------------------- | ------------------------ | -------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | | **Northwind PEP** | Inbound enforcement edge | `https://api.northwind.example` | Runs ADL verification + authorization on every inbound request. Also fronts Northwind's OIDC. Host shape is deliberately abstract here. | | **Inventory / Pricing / Order Agents** | Backing agents | Internal only (e.g. `inventory.svc.northwind.internal`), `did:web:api.northwind.example:agents:inventory` etc. | Not publicly reachable; reached only via the PEP over the internal trust domain. | | **Procurement Agent** | External peer agent | `https://supply.example/agents/procurement`, `did:web:supply.example:agents:procurement` | Calls Northwind to check stock and place orders; may carry a delegation chain to a human buyer. | | **Dana** | Northwind employee | OIDC subject `dana@northwind.example` | Uses an internal console; authenticates at the PEP via OIDC. | ## Request lifecycle through the PEP[​](#request-lifecycle-through-the-pep "Direct link to Request lifecycle through the PEP") A single inbound request from the Procurement Agent — "reserve 500 units of SKU-1234" — flows through these stages at the edge. Every step is host-agnostic: it is the same whether the PEP is a runtime plugin, an AI-aware gateway, a sidecar verifier, or a generic API gateway filter. ### 1. Ingress and caller classification[​](#1-ingress-and-caller-classification "Direct link to 1. Ingress and caller classification") The PEP terminates TLS and inspects the request. It classifies the caller by what it presents: * **Human / OAuth client** → `Authorization: Bearer …` (+ `DPoP`): take the [§10.3.3](/spec/next#1033-credential-schemes) credential-scheme path. * **Peer agent** → `ADL-Passport` + `ADL-Proof` headers: take the [§1.1](/protocol/trust.md#11-passport-verification-procedure) + [§1.2](/protocol/trust.md#12-presentation-proof) path. This is the same "two front doors, one edge" idea as [Exposing Agents](/patterns/exposing-agents.md) — but here the doors are two branches of one PEP. ### 2. Authenticate (agent path)[​](#2-authenticate-agent-path "Direct link to 2. Authenticate (agent path)") The PEP runs the full [§1.1](/protocol/trust.md#11-passport-verification-procedure) verification on the Procurement Agent's passport — [retrieval integrity](/protocol/trust.md#111-retrieval-integrity), [schema](/protocol/trust.md#112-schema-validation), [`did:web` resolution](/protocol/trust.md#113-identity-resolution), [key cross-check](/protocol/trust.md#114-public-key-cross-check), [signature](/protocol/trust.md#115-signature-verification), [temporal validity](/protocol/trust.md#116-temporal-validity), [lifecycle](/protocol/trust.md#117-lifecycle-gating), [provider coherence](/protocol/trust.md#118-provideridentity-coherence) — then [§1.2 proof verification](/protocol/trust.md#126-verification-procedure): the proof must be **bound to the PEP's public URL** (`https://api.northwind.example/...`), within its temporal window, and its `jti` not in the replay cache. ### 3. Authenticate (human path)[​](#3-authenticate-human-path "Direct link to 3. Authenticate (human path)") For Dana's console request, the PEP validates the OIDC token and DPoP binding ([§10.3.3](/spec/next#1033-credential-schemes)). No ADL passport is involved; the human's identity comes from the IdP. ### 4. Principal and delegation[​](#4-principal-and-delegation "Direct link to 4. Principal and delegation") When the Procurement Agent acts on behalf of a human buyer, the principal and the chain of agents that carried the authority ride in the proof and are verified here. The PEP checks that the exercised scopes are within the principal's grant and narrow monotonically down the chain — the on-edge enforcement of the [§2.3 composition rules](/protocol/trust.md#23-composition-across-boundaries-multi-hop-authorization). The PEP is where an organization sets its policy for *requiring* a principal chain (regulated/high-value routes) versus accepting agent identity alone (low-stakes routes). ### 5. Authorize[​](#5-authorize "Direct link to 5. Authorize") The PEP computes the effective authority and checks it against the targeted route: * **Scope** ([§10.4](/spec/next#104-authorization-scopes)): the proof's requested scopes must be within the agent's [ceiling](/protocol/trust.md#22-authorization-in-agent-to-agent-flows) and cover the route's required scopes (`inventory:reserve` for the reserve endpoint). * **Classification** ([§10.1](/spec/next#101-data-classification) / [§1.1.9](/protocol/trust.md#119-permission-and-classification-compatibility)): the caller must be cleared for the data the route returns. * **Native policy**: rate limits, quotas, IP allowlists, and the [provider allowlist](/protocol/trust.md#118-provideridentity-coherence) — Northwind only does business with attested, allowlisted partners. ### 6. Route over the internal trust domain[​](#6-route-over-the-internal-trust-domain "Direct link to 6. Route over the internal trust domain") Once verified, the PEP forwards the request to the backing agent (`inventory.svc.northwind.internal`). Two consequences worth being explicit about: * **The proof is not forwarded for re-verification.** It was bound to the PEP's public URL (`https://api.northwind.example/...`), not the internal service URL, so forwarding it verbatim would fail the [request-binding check](/protocol/trust.md#126-verification-procedure). The PEP is the verification boundary; the internal hop is a separate trust domain secured by its own means (mTLS, SPIFFE/SVID, network policy). * **The PEP passes the verified context forward**, typically as signed headers (the authenticated agent id, the principal, the granted scopes, a request id) so the backing agent can make fine-grained decisions and keep its own audit without re-running verification. In a zero-trust internal network, backing agents MAY still require their own proofs — defense in depth. ### 7. Audit[​](#7-audit "Direct link to 7. Audit") The PEP emits one provenance record per request — the authenticated identity, the principal and delegation chain, the effective scopes, the route, and the outcome — correlated by request id. Because the PEP is a single chokepoint, this is the cleanest place to satisfy the audit-recording obligation that the [§2.3 composition rules](/protocol/trust.md#23-composition-across-boundaries-multi-hop-authorization) place on multi-hop authorization. ## Why a generic API gateway is the wrong default[​](#why-a-generic-api-gateway-is-the-wrong-default "Direct link to Why a generic API gateway is the wrong default") A generic API gateway *can* host the PEP: passport + proof verification slots into its request pipeline as a plugin/filter/Lua/Wasm module, right alongside the OAuth/OIDC validation, TLS termination, and routing it already does. If you already run one, that is a legitimate incremental path to enforcing ADL — the lifecycle above runs there unchanged. But "can reverse-proxy anything" is precisely the problem. A generic gateway has no opinion about agents; it treats traffic as opaque request/response HTTP. Agent traffic is not shaped like that, and the enforcement that *should* ride alongside identity verification is exactly the part a generic gateway can't see: * **Agent responses stream.** Completions arrive token-by-token over SSE / chunked transfer, and sessions are long-lived. A gateway tuned for short request/response transactions buffers, times out, or breaks the stream — degrading the very UX the agent exists to provide. * **The meaningful unit isn't the HTTP transaction.** It's a tool call, a token budget, a spend cap. Enforcing `permissions.resource_limits` ([§9.6](/spec/next#96-resource-limits)) or per-tool-call authorization means understanding agent semantics the gateway has no model of — you'd reimplement it as custom Lua/Wasm, rebuilding what AI-aware hosts do natively. * **Classification applies to live content, not just routes.** `data_classification` handling ([§10.1](/spec/next#101-data-classification)) — redaction, anonymization — needs to inspect streamed prompts and completions, not just gate a path by static policy. A generic gateway gates the route; it doesn't reason about what flows through it. * **Identity verification is necessary but not sufficient.** Verifying the passport and proof proves *who* is calling. It says nothing about budget, tool mediation, or classification on the content — which is where most of an agent's runtime risk actually lives. So the recommendation hierarchy: keep inbound verification **where the agent semantics are** — in the agent runtime ([the OpenClaw plugin pattern](/patterns/multi-hop-authorization.md)) or an AI-aware layer that understands streaming, tokens, tools, and content classification natively. Factor verification into a dedicated service if you want reuse. Use a generic API gateway as the PEP only when you already operate one and want ADL identity enforcement at that edge today — and even then, the agent-native policy belongs downstream, in the runtime, not stretched onto a gateway that was never designed for it. ## Failure modes[​](#failure-modes "Direct link to Failure modes") ### Proof bound to the wrong URL[​](#proof-bound-to-the-wrong-url "Direct link to Proof bound to the wrong URL") A client signs a proof for the backing agent's *internal* URL (or an old endpoint) instead of the PEP's public URL. The [request-binding check](/protocol/trust.md#126-verification-procedure) rejects it — the proof's `request.uri` does not match the URL the caller actually hit. The fix is client-side: bind proofs to the public PEP URL. ### Bypass attempt — calling a backing agent directly[​](#bypass-attempt--calling-a-backing-agent-directly "Direct link to Bypass attempt — calling a backing agent directly") An attacker who learns `inventory.svc.northwind.internal` tries to reach it directly, skipping the PEP. This is contained at the network layer (the internal trust domain is not externally routable) and, in a zero-trust deployment, by the backing agent still requiring a valid proof. The PEP is the *primary* enforcement point, not the *only* control. ### Replay against a different PEP node[​](#replay-against-a-different-pep-node "Direct link to Replay against a different PEP node") A captured proof is replayed against a second PEP instance. Without a shared replay cache it could slip through; with one (the recommended deployment), the `jti` is already recorded and the [replay check](/protocol/trust.md#126-verification-procedure) rejects it. This is why the replay cache MUST be shared across PEP instances, not per-node. ### Principal chain required but absent[​](#principal-chain-required-but-absent "Direct link to Principal chain required but absent") A regulated route (place-order) requires a verified principal; the caller presents only its agent identity. The PEP rejects with an insufficient-provenance error — distinct from an insufficient-scope error — so the caller knows to attach the principal/delegation, not request more scope. Low-stakes routes (check-stock) on the same PEP accept agent identity alone. ### PEP misconfigured to mint trust[​](#pep-misconfigured-to-mint-trust "Direct link to PEP misconfigured to mint trust") If the PEP is configured to re-sign requests as itself or to vouch for unverified callers, it becomes a central authorization server and the end-to-end chain breaks. The discipline: the PEP **verifies** end-to-end-signed proofs and delegation links; it never originates authority it did not receive. A PEP that genuinely re-originates calls on an agent's behalf is acting as an agent and MUST carry its own passport and appear in the delegation chain — it is no longer a transparent enforcement point. ## Spec section index[​](#spec-section-index "Direct link to Spec section index") | PEP operation | Spec section | | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | | Classify caller (human vs agent) | [§10.3](/spec/next#103-authentication) | | Verify peer-agent passport | [§1.1](/protocol/trust.md#11-passport-verification-procedure) (all steps) | | Verify presentation proof (binding, replay, nonce) | [§1.2](/protocol/trust.md#126-verification-procedure) | | Validate human credential (OIDC/OAuth/mTLS) | [§10.3.3](/spec/next#1033-credential-schemes) | | Enforce principal / multi-hop composition | [§2.3](/protocol/trust.md#23-composition-across-boundaries-multi-hop-authorization) | | Authorize scopes (ceiling + route requirement) | [§2.2](/protocol/trust.md#22-authorization-in-agent-to-agent-flows) / [§2.1](/protocol/trust.md#21-authorization-in-human-to-agent-flows) | | Enforce resource / token / spend budgets | [§9.6](/spec/next#96-resource-limits) | | Provider allowlist / attestation requirement | [§1.1.8](/protocol/trust.md#118-provideridentity-coherence) / [§10.2](/spec/next#102-attestation) | | Classification gating | [§10.1](/spec/next#101-data-classification) / [§1.1.9](/protocol/trust.md#119-permission-and-classification-compatibility) | | Discovery of the org's agents | [§6.4](/spec/next#64-discovery) | ## Related material[​](#related-material "Direct link to Related material") * [Multi-Hop Authentication and Authorization](/patterns/multi-hop-authorization.md) — the client/caller side that produces the proofs the PEP verifies, and the runtime where the agent-native PEP naturally lives * [Exposing Agents to External Callers](/patterns/exposing-agents.md) — the provider edge; this pattern is one way to *implement* that edge * [Mediating Agent Egress through an AI Gateway](/patterns/ai-gateway.md) — the outbound mirror; the proofs an AI gateway constructs are what an inbound PEP verifies * [Draft spec §10.3 (Authentication)](/spec/next#103-authentication) * [Draft spec §10.4 (Authorization Scopes)](/spec/next#104-authorization-scopes) --- # Multi-Hop Authentication and Authorization **The pattern:** an agent acting on a user's behalf calls other agents and services, and each hop must independently authenticate the caller and authorize the specific operation. This is the core capability ADL adds on top of OAuth 2.1: human-to-agent boundaries authenticate with OAuth credentials ([§10.3.3](/spec/next#1033-credential-schemes)), agent-to-agent boundaries authenticate with passports ([§1.1](/protocol/trust.md#11-passport-verification-procedure)) and presentation proofs ([§1.2](/protocol/trust.md#12-presentation-proof)), and authorization scopes ([§10.4](/spec/next#104-authorization-scopes)) compose across the chain so that no single hop sees more authority than it needs. **Illustrated through a scenario:** Alice asks her assistant to book a 5-day vacation to Ibiza in July — she might type it into a web app, DM it to her agent on Discord or Slack, send an iMessage, or email it; the entry point varies but the model is the same. The assistant checks her calendar for open dates, reaches out to travel agents — or, if Alice has a preferred airline, books with that airline directly — and arranges a hotel, searching options first and then escalating to actually book and charge her card. The assistant here is itself an AI agent (often a self-hosted OpenClaw agent) acting on Alice's behalf. The vacation booking is incidental; what matters is the authentication and authorization decision made at each hop. The protocol details behind "checks her calendar" and "reaches out to travel agents" are spelled out hop-by-hop below. A note on how to read this: the assistant does **not** start out knowing which agents it will call or which scopes those calls require. It starts with one thing — Alice's message and the standing authority she delegated when she set it up. Everything else is discovered as it works: it parses the request, uses the tools it already has, finds the agents it needs, and learns each counterparty's connection requirements *from that counterparty's passport* at the moment it connects. It then works the task to completion on its own; it does not return to Alice between hops. The walkthrough is ordered to follow that real sequence of discovery, not a pre-computed plan. This walkthrough traces every authentication and authorization decision along the way, with explicit citations to the corresponding spec sections. It is the canonical worked example for the cohesive Authentication structure ([§10.3](/spec/next#103-authentication)) and the cross-flow scope composition rules ([§2.3](/protocol/trust.md#23-composition-across-boundaries-multi-hop-authorization)). ![Infographic of the vacation-booking scenario. At the top, Alice delegates a single authority envelope S\_h — calendar, travel, travel, payments — to her Personal Assistant once via OAuth 2.1; this envelope is the ceiling for everything that follows. A banner states the rule: at each hop the assistant reads the required scopes from the counterparty\'s passport and claims only that minimum. Six numbered, color-coded steps then trace the journey: (1) the task arrives over an authenticated channel, (2) an OAuth token exchange to a Calendar MCP server claiming calendar, (3) public discovery where the assistant verifies each agent\'s passport and reads the required scopes off it, (4) an ADL passport-plus-proof call to a Flight Agent claiming flights, (5) the higher-stakes flight booking that escalates to flights plus payments while staying within the envelope, and (6) the hotel agent claiming hotels plus payments. Three takeaways close it: scopes are pulled not pushed, reduced to the minimum, and every hop authenticates independently so no hop sees the full chain.](/assets/images/multi-hop-authorization-eddf37c971bba47a6800f8257c6c7944.svg) *Figure 1 — Conceptual view: one delegated envelope, reduced to the minimum scope at each hop, across three boundary types — human→agent (OAuth 2.1), agent→MCP (OAuth token exchange), and agent→agent (ADL passport + presentation proof). Required scopes are pulled from each counterparty's passport at connect time; every hop authenticates independently.* The same multi-hop authorization, viewed as a UML sequence at the protocol level ([§2.3](/protocol/trust.md#23-composition-across-boundaries-multi-hop-authorization)) — the abstract Human → Agent A → Agent B shape behind the scenario above: ![UML sequence diagram of multi-hop authorization with three lifelines: Human, Agent A, and Agent B. Step 1, the human sends a request to Agent A carrying an OAuth token with scope S\_h. Step 2, Agent A authorizes the human per Trust Protocol section 2.1, checking that its required scopes are a subset of S\_h. Step 3, Agent A invokes upstream Agent B, presenting its passport and a presentation proof carrying scope S\_a. Step 4, Agent B authorizes Agent A per section 2.2: first a ceiling check that the proof scopes are a subset of Agent A\'s passport scopes, then that Agent B\'s required scopes are a subset of the proof scopes. Step 5, Agent B returns a result to Agent A; step 6, Agent A returns a result to the human. A closing note states the two authorizations are independent: Agent A\'s outbound scope S\_a is bounded only by Agent A\'s passport ceiling, not by S\_h, and each hop keeps its own audit record so no single hop sees the whole chain.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA5MDAgNTgwIiB3aWR0aD0iOTAwIiBoZWlnaHQ9IjU4MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsbGVkYnk9Im1oLXRpdGxlIG1oLWRlc2MiIGZvbnQtZmFtaWx5PSItYXBwbGUtc3lzdGVtLCBCbGlua01hY1N5c3RlbUZvbnQsICdTZWdvZSBVSScsIEhlbHZldGljYSwgQXJpYWwsIHNhbnMtc2VyaWYiPgogIDx0aXRsZSBpZD0ibWgtdGl0bGUiPk11bHRpLWhvcCBhdXRob3JpemF0aW9uOiB0d28gaW5kZXBlbmRlbnQgYXV0aG9yaXphdGlvbnMgYWNyb3NzIGEgaG9wIGJvdW5kYXJ5PC90aXRsZT4KICA8ZGVzYyBpZD0ibWgtZGVzYyI+QSBVTUwgc2VxdWVuY2UgZGlhZ3JhbSB3aXRoIHRocmVlIGxpZmVsaW5lczogSHVtYW4sIEFnZW50IEEsIGFuZCBBZ2VudCBCLiBTdGVwIDEsIHRoZSBodW1hbiBzZW5kcyBhIHJlcXVlc3QgdG8gQWdlbnQgQSBjYXJyeWluZyBhbiBPQXV0aCB0b2tlbiB3aXRoIHNjb3BlIFNfaC4gU3RlcCAyLCBBZ2VudCBBIGF1dGhvcml6ZXMgdGhlIGh1bWFuIHVuZGVyIMKnMi4xLCByZXF1aXJpbmcgaXRzIHJlcXVpcmVkX0Egc2NvcGVzIHRvIGJlIGEgc3Vic2V0IG9mIFNfaC4gU3RlcCAzLCBBZ2VudCBBIGludm9rZXMgdXBzdHJlYW0gQWdlbnQgQiwgcHJlc2VudGluZyBpdHMgcGFzc3BvcnQgYW5kIGEgcHJlc2VudGF0aW9uIHByb29mIGNhcnJ5aW5nIHNjb3BlIFNfYS4gU3RlcCA0LCBBZ2VudCBCIGF1dGhvcml6ZXMgQWdlbnQgQSB1bmRlciDCpzIuMjogZmlyc3QgYSBjZWlsaW5nIGNoZWNrIHRoYXQgdGhlIHByb29mIHNjb3BlcyBhcmUgYSBzdWJzZXQgb2YgQWdlbnQgQSdzIHBhc3Nwb3J0IHNjb3BlcywgdGhlbiB0aGF0IEFnZW50IEIncyByZXF1aXJlZF9CIHNjb3BlcyBhcmUgYSBzdWJzZXQgb2YgdGhlIHByb29mIHNjb3Blcy4gU3RlcCA1LCBBZ2VudCBCIHJldHVybnMgYSByZXN1bHQgdG8gQWdlbnQgQTsgc3RlcCA2LCBBZ2VudCBBIHJldHVybnMgYSByZXN1bHQgdG8gdGhlIGh1bWFuLiBBIGNsb3Npbmcgbm90ZSBzdGF0ZXMgdGhlIHR3byBhdXRob3JpemF0aW9ucyBhcmUgaW5kZXBlbmRlbnQ6IEFnZW50IEEncyBvdXRib3VuZCBzY29wZSBTX2EgaXMgYm91bmRlZCBvbmx5IGJ5IGl0cyBwYXNzcG9ydCBjZWlsaW5nLCBub3QgYnkgU19oLCBhbmQgZWFjaCBob3Aga2VlcHMgaXRzIG93biBhdWRpdCByZWNvcmQgc28gbm8gc2luZ2xlIGhvcCBzZWVzIHRoZSB3aG9sZSBjaGFpbi48L2Rlc2M+CgogIDxkZWZzPgogICAgPG1hcmtlciBpZD0ibWgtYXIiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPgogICAgICA8cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIGZpbGw9IiMzMzQxNTUiLz4KICAgIDwvbWFya2VyPgogIDwvZGVmcz4KCiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjkwMCIgaGVpZ2h0PSI1ODAiIGZpbGw9IiNmZmZmZmYiLz4KCiAgPCEtLSBUaXRsZSAtLT4KICA8dGV4dCB4PSI0NTAiIHk9IjM0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjIwIiBmb250LXdlaWdodD0iNzAwIiBmaWxsPSIjMGYxNzJhIj5NdWx0aS1Ib3AgQXV0aG9yaXphdGlvbjwvdGV4dD4KICA8dGV4dCB4PSI0NTAiIHk9IjU2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjEzIiBmb250LXN0eWxlPSJpdGFsaWMiIGZpbGw9IiM0NzU1NjkiPlR3byBpbmRlcGVuZGVudCBhdXRob3JpemF0aW9ucyBhY3Jvc3MgYSBob3AgYm91bmRhcnkgJiM4MjEyOyBIdW1hbiAmIzg1OTQ7IEFnZW50IEEgJiM4NTk0OyBBZ2VudCBCICgmIzE2NzsyLjMpPC90ZXh0PgoKICA8IS0tIGxpZmVsaW5lcyAtLT4KICA8bGluZSB4MT0iMTMwIiB5MT0iMTE2IiB4Mj0iMTMwIiB5Mj0iNDUyIiBzdHJva2U9IiNjYmQ1ZTEiIHN0cm9rZS13aWR0aD0iMS4yNSIgc3Ryb2tlLWRhc2hhcnJheT0iNCA0Ii8+CiAgPGxpbmUgeDE9IjQ1MCIgeTE9IjExNiIgeDI9IjQ1MCIgeTI9IjQ1MiIgc3Ryb2tlPSIjY2JkNWUxIiBzdHJva2Utd2lkdGg9IjEuMjUiIHN0cm9rZS1kYXNoYXJyYXk9IjQgNCIvPgogIDxsaW5lIHgxPSI3NzAiIHkxPSIxMTYiIHgyPSI3NzAiIHkyPSI0NTIiIHN0cm9rZT0iI2NiZDVlMSIgc3Ryb2tlLXdpZHRoPSIxLjI1IiBzdHJva2UtZGFzaGFycmF5PSI0IDQiLz4KCiAgPCEtLSBwYXJ0aWNpcGFudCBib3hlcyAtLT4KICA8cmVjdCB4PSI2NSIgeT0iNzgiIHdpZHRoPSIxMzAiIGhlaWdodD0iMzYiIHJ4PSI4IiBmaWxsPSIjZThmMGZlIiBzdHJva2U9IiMxYTczZTgiIHN0cm9rZS13aWR0aD0iMS41Ii8+CiAgPHRleHQgeD0iMTMwIiB5PSIxMDEiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTMiIGZvbnQtd2VpZ2h0PSI3MDAiIGZpbGw9IiMwYjU3ZDAiPkh1bWFuPC90ZXh0PgogIDxyZWN0IHg9IjM4NSIgeT0iNzgiIHdpZHRoPSIxMzAiIGhlaWdodD0iMzYiIHJ4PSI4IiBmaWxsPSIjZThmMGZlIiBzdHJva2U9IiMxYTczZTgiIHN0cm9rZS13aWR0aD0iMS41Ii8+CiAgPHRleHQgeD0iNDUwIiB5PSIxMDEiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTMiIGZvbnQtd2VpZ2h0PSI3MDAiIGZpbGw9IiMwYjU3ZDAiPkFnZW50IEE8L3RleHQ+CiAgPHJlY3QgeD0iNzA1IiB5PSI3OCIgd2lkdGg9IjEzMCIgaGVpZ2h0PSIzNiIgcng9IjgiIGZpbGw9IiNlOGYwZmUiIHN0cm9rZT0iIzFhNzNlOCIgc3Ryb2tlLXdpZHRoPSIxLjUiLz4KICA8dGV4dCB4PSI3NzAiIHk9IjEwMSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxMyIgZm9udC13ZWlnaHQ9IjcwMCIgZmlsbD0iIzBiNTdkMCI+QWdlbnQgQjwvdGV4dD4KCiAgPCEtLSBsZWdlbmQgKGluIHRoZSBjbGVhciBnYXAgYmV0d2VlbiBBZ2VudCBBIGFuZCBBZ2VudCBCIGhlYWRlcnMpIC0tPgogIDxsaW5lIHgxPSI1NDAiIHkxPSI5NiIgeDI9IjU2NiIgeTI9Ijk2IiBzdHJva2U9IiMzMzQxNTUiIHN0cm9rZS13aWR0aD0iMS41IiBtYXJrZXItZW5kPSJ1cmwoI21oLWFyKSIvPgogIDx0ZXh0IHg9IjU3MiIgeT0iMTAwIiBmb250LXNpemU9IjEwLjUiIGZpbGw9IiM2NDc0OGIiPmNhbGw8L3RleHQ+CiAgPGxpbmUgeDE9IjYxNiIgeTE9Ijk2IiB4Mj0iNjQyIiB5Mj0iOTYiIHN0cm9rZT0iIzMzNDE1NSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1kYXNoYXJyYXk9IjUgMyIgbWFya2VyLWVuZD0idXJsKCNtaC1hcikiLz4KICA8dGV4dCB4PSI2NDgiIHk9IjEwMCIgZm9udC1zaXplPSIxMC41IiBmaWxsPSIjNjQ3NDhiIj5yZXR1cm48L3RleHQ+CgogIDwhLS0gYWN0aXZhdGlvbiBiYXJzIC0tPgogIDxyZWN0IHg9IjQ0NCIgeT0iMTQ0IiB3aWR0aD0iMTIiIGhlaWdodD0iMjkyIiBmaWxsPSIjZDJlM2ZjIiBzdHJva2U9IiMxYTczZTgiIHN0cm9rZS13aWR0aD0iMC45Ii8+CiAgPHJlY3QgeD0iNzY0IiB5PSIyNTIiIHdpZHRoPSIxMiIgaGVpZ2h0PSIxMzIiIGZpbGw9IiNkMmUzZmMiIHN0cm9rZT0iIzFhNzNlOCIgc3Ryb2tlLXdpZHRoPSIwLjkiLz4KCiAgPCEtLSAoMSkgSHVtYW4gLT4gQWdlbnQgQSAtLT4KICA8dGV4dCB4PSIyODciIHk9IjE0MiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxMSIgZmlsbD0iIzFmMjkzNyI+KDEpIHJlcXVlc3QgJiMxODM7IE9BdXRoIHRva2VuLCBzY29wZSBTX2g8L3RleHQ+CiAgPGxpbmUgeDE9IjEzMCIgeTE9IjE1MCIgeDI9IjQ0MiIgeTI9IjE1MCIgc3Ryb2tlPSIjMzM0MTU1IiBzdHJva2Utd2lkdGg9IjEuNSIgbWFya2VyLWVuZD0idXJsKCNtaC1hcikiLz4KCiAgPCEtLSAoMikgwqcyLjEgYXV0aG9yaXplIGh1bWFuIChBZ2VudCBBJ3MgZGVjaXNpb24pOyBjZW50ZXJlZCBpbiB0aGUgSHVtYW48LT5BIGd1dHRlciAobWlkIHg9MjkwKSwgYmFsYW5jZWQgcGFkZGluZyAtLT4KICA8cmVjdCB4PSIxOTgiIHk9IjE2NyIgd2lkdGg9IjE4NCIgaGVpZ2h0PSI1MCIgcng9IjgiIGZpbGw9IiNmZmY3ZTYiIHN0cm9rZT0iI2Y1OWUwYiIgc3Ryb2tlLXdpZHRoPSIxLjQiLz4KICA8dGV4dCB4PSIyMTYiIHk9IjE4OCIgZm9udC1zaXplPSIxMC41IiBmb250LXdlaWdodD0iNzAwIiBmaWxsPSIjYjQ1MzA5Ij4oMikgJiMxNjc7Mi4xICYjODIxMjsgYXV0aG9yaXplIGh1bWFuPC90ZXh0PgogIDx0ZXh0IHg9IjIxNiIgeT0iMjA3IiBmb250LXNpemU9IjEwLjUiIGZpbGw9IiMxZjI5MzciPnJlcXVpcmVkX0EgJiM4ODM4OyBTX2g8L3RleHQ+CgogIDwhLS0gKDMpIEFnZW50IEEgLT4gQWdlbnQgQiAtLT4KICA8dGV4dCB4PSI2MTAiIHk9IjI1MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxMSIgZmlsbD0iIzFmMjkzNyI+KDMpIGludm9rZSB1cHN0cmVhbSAmIzE4MzsgcGFzc3BvcnQgKyBwcm9vZiwgc2NvcGUgU19hPC90ZXh0PgogIDxsaW5lIHgxPSI0NTYiIHkxPSIyNTgiIHgyPSI3NjIiIHkyPSIyNTgiIHN0cm9rZT0iIzMzNDE1NSIgc3Ryb2tlLXdpZHRoPSIxLjUiIG1hcmtlci1lbmQ9InVybCgjbWgtYXIpIi8+CgogIDwhLS0gKDQpIMKnMi4yIGF1dGhvcml6ZSBBZ2VudCBBIChBZ2VudCBCJ3MgZGVjaXNpb24pOyBjZW50ZXJlZCBpbiB0aGUgQTwtPkIgZ3V0dGVyIChtaWQgeD02MTApLCBiYWxhbmNlZCBwYWRkaW5nIC0tPgogIDxyZWN0IHg9IjQ4MyIgeT0iMjc3IiB3aWR0aD0iMjU0IiBoZWlnaHQ9IjcyIiByeD0iOCIgZmlsbD0iI2ZmZjdlNiIgc3Ryb2tlPSIjZjU5ZTBiIiBzdHJva2Utd2lkdGg9IjEuNCIvPgogIDx0ZXh0IHg9IjUwMSIgeT0iMjk3IiBmb250LXNpemU9IjEwLjUiIGZvbnQtd2VpZ2h0PSI3MDAiIGZpbGw9IiNiNDUzMDkiPig0KSAmIzE2NzsyLjIgJiM4MjEyOyBhdXRob3JpemUgQWdlbnQgQTwvdGV4dD4KICA8dGV4dCB4PSI1MDEiIHk9IjMxNiIgZm9udC1zaXplPSIxMCIgZmlsbD0iIzFmMjkzNyI+MSAmIzE4MzsgY2VpbGluZzogcHJvb2Yuc2NvcGVzICYjODgzODsgQS5wYXNzcG9ydC5zY29wZXM8L3RleHQ+CiAgPHRleHQgeD0iNTAxIiB5PSIzMzUiIGZvbnQtc2l6ZT0iMTAiIGZpbGw9IiMxZjI5MzciPjIgJiMxODM7IHJlcXVpcmVkX0IgJiM4ODM4OyBwcm9vZi5zY29wZXM8L3RleHQ+CgogIDwhLS0gKDUpIEFnZW50IEIgLS0+IEFnZW50IEEgKHJldHVybikgLS0+CiAgPHRleHQgeD0iNjEwIiB5PSIzNzYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTEiIGZpbGw9IiMxZjI5MzciPig1KSByZXN1bHQ8L3RleHQ+CiAgPGxpbmUgeDE9Ijc2NCIgeTE9IjM4NCIgeDI9IjQ1OCIgeTI9IjM4NCIgc3Ryb2tlPSIjMzM0MTU1IiBzdHJva2Utd2lkdGg9IjEuNSIgc3Ryb2tlLWRhc2hhcnJheT0iNiA0IiBtYXJrZXItZW5kPSJ1cmwoI21oLWFyKSIvPgoKICA8IS0tICg2KSBBZ2VudCBBIC0tPiBIdW1hbiAocmV0dXJuKSAtLT4KICA8dGV4dCB4PSIyODciIHk9IjQyOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxMSIgZmlsbD0iIzFmMjkzNyI+KDYpIHJlc3VsdDwvdGV4dD4KICA8bGluZSB4MT0iNDQ0IiB5MT0iNDM2IiB4Mj0iMTMyIiB5Mj0iNDM2IiBzdHJva2U9IiMzMzQxNTUiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtZGFzaGFycmF5PSI2IDQiIG1hcmtlci1lbmQ9InVybCgjbWgtYXIpIi8+CgogIDwhLS0gc3Bhbm5pbmcgdGFrZWF3YXkgbm90ZSAtLT4KICA8cmVjdCB4PSI3MCIgeT0iNDYyIiB3aWR0aD0iNzYwIiBoZWlnaHQ9IjU0IiByeD0iMTAiIGZpbGw9IiNmOGZhZmMiIHN0cm9rZT0iI2NiZDVlMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNCIvPgogIDx0ZXh0IHg9Ijg2IiB5PSI0ODQiIGZvbnQtc2l6ZT0iMTEiIGZpbGw9IiMxZjI5MzciPlR3byBpbmRlcGVuZGVudCBhdXRob3JpemF0aW9ucyAmIzgyMTI7IEFnZW50IEEncyBvdXRib3VuZCBzY29wZSBTX2EgaXMgYm91bmRlZCBvbmx5IGJ5IGl0cyBwYXNzcG9ydCBjZWlsaW5nLDwvdGV4dD4KICA8dGV4dCB4PSI4NiIgeT0iNTAyIiBmb250LXNpemU9IjExIiBmaWxsPSIjMWYyOTM3Ij5ub3QgYnkgU19oICYjODIxMjsgYW5kIGVhY2ggaG9wIGtlZXBzIGl0cyBvd24gYXVkaXQgcmVjb3JkLCBzbyBubyBzaW5nbGUgaG9wIHNlZXMgdGhlIHdob2xlIGNoYWluLjwvdGV4dD4KCiAgPCEtLSBmb290bm90ZSAtLT4KICA8dGV4dCB4PSI0NTAiIHk9IjU0NiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxMC41IiBmb250LXN0eWxlPSJpdGFsaWMiIGZpbGw9IiM0NzU1NjkiPlRoZSAmIzE2NzsyLjEgLyAmIzE2NzsyLjIgY2hlY2tzIHJ1biBpZGVudGljYWxseSBldmVyeSB0aW1lIChkZXRlcm1pbmlzdGljKTsgd2hpY2ggY291bnRlcnBhcnR5IHRoZSBhZ2VudCBkaXNjb3ZlcnMsIGFuZCBpbiB3aGF0IG9yZGVyLCBpcyBlbWVyZ2VudC48L3RleHQ+CiAgPHRleHQgeD0iNDUwIiB5PSI1NjIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTAuNSIgZm9udC1zdHlsZT0iaXRhbGljIiBmaWxsPSIjNDc1NTY5Ij5PbmUgcmVwcmVzZW50YXRpdmUgdHJhY2UuIElsbHVzdHJhdGl2ZTsgJiMxNjc7Mi4xJiM4MjExOyYjMTY3OzIuMyBhcmUgYXV0aG9yaXRhdGl2ZS48L3RleHQ+Cjwvc3ZnPgo=) *Figure 2 — Protocol view: the per-hop authorization mechanics as a UML sequence ([§2.3](/protocol/trust.md#23-composition-across-boundaries-multi-hop-authorization)). The §2.1/§2.2 checks run identically on every hop — that part is fixed and safe to draw — but this is **one representative trace**: which counterparties the assistant discovers, and in what order, is emergent (see the discovery note above), not a pre-set sequence.* ## Cast of actors[​](#cast-of-actors "Direct link to Cast of actors") | Actor | Role | Identity | Notable scopes | | ---------------------------------- | --------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | | **Alice** | Human user | Account `alice@example.com`, reaching her assistant over a linked channel (web, Discord, Slack, Teams, iMessage, or email) | What she delegated to her assistant at setup | | **Personal Assistant** (Agent A) | Alice's main AI agent (e.g. a self-hosted OpenClaw agent) | `https://assistant.example/agents/personal-bot`, `did:web:assistant.example:agents:personal-bot` | Passport ceiling: `[calendar:read, travel:search, travel:book, payments:authorize, flights:search, flights:book, hotels:search, hotels:book]` | | **Calendar MCP Server** | Provides calendar tools | `https://calendar.example/mcp` (OAuth 2.1 resource server) | Tools require `calendar:read` | | **Travel Discovery** | Public agent registry | `https://travel-agents.example/.well-known/adl-agents` | None (public) | | **Flight Booking Agent** (Agent B) | Books flights | `https://acme-flights.example/agents/booking`, `did:web:acme-flights.example:agents:booking` | Passport: `[flights:search, flights:book, payments:authorize]` | | **Hotel Booking Agent** (Agent C) | Books hotels | `https://luxury-hotels.example/agents/concierge`, `did:web:luxury-hotels.example:agents:concierge` | Passport: `[hotels:search, hotels:book, payments:authorize]` | ## What's already in place before Alice asks[​](#whats-already-in-place-before-alice-asks "Direct link to What's already in place before Alice asks") For the agent-to-agent hops to work at all, each agent has previously established cryptographic identity: * **Personal Assistant** has an Ed25519 keypair (private key in `assistant.example`'s KMS), a DID Document at `https://assistant.example/agents/personal-bot/did.json`, and a signed passport at `https://assistant.example/agents/personal-bot`. The passport's `cryptographic_identity.public_key.value` matches the DID Document's `assertionMethod` key (the [§1.1.4](/protocol/trust.md#114-public-key-cross-check) cross-check anchor). * **Flight Booking Agent** and **Hotel Booking Agent** likewise. * The well-known discovery endpoint at `https://travel-agents.example/.well-known/adl-agents` lists active travel agents. Each entry includes the agent's `id`, `adl_document` URL, name, version, and lifecycle status. This is the ambient trust state. None of it changes during Alice's session. *** ## How the agent works the task[​](#how-the-agent-works-the-task "Direct link to How the agent works the task") Before the hop-by-hop detail, here is the shape of what actually happens — and, importantly, what the agent knows at each stage: 1. **Alice sends a starting message.** "Book me a 5-day vacation to Ibiza in July." The agent does not yet know it will talk to a flight agent, a hotel agent, or anything else. It knows only the request and its **standing authority** — the delegation envelope Alice granted when she set the assistant up (Hop 1). 2. **The agent understands the request.** It parses intent: a 5-day trip, destination Ibiza, month July, requiring dates + flights + lodging. Still no knowledge of *which* downstream agents or *what* they'll require. 3. **The agent uses the tools it already has.** It has a calendar tool, so it checks Alice's calendar for open dates (Hop 2). From this point it is acting on Alice's behalf within its own granted tools. 4. **The agent plans the next leg and finds counterparties.** Now it knows it needs flights and lodging, so it discovers candidate travel agents (Hop 3). 5. **Each counterparty declares its own connection requirements.** When the agent verifies a travel agent's passport, that passport *tells the agent* what authentication and which scopes are required to connect and to invoke each tool ([§10.3.3](/spec/next#1033-credential-schemes) + [§10.4](/spec/next#104-authorization-scopes)). The agent does not guess these — it reads them off the counterparty's passport at discovery time. 6. **The agent matches each discovered requirement against its standing authority and connects.** If a required scope is within the envelope Alice delegated, the agent presents a proof claiming exactly that scope (Hops 4–6, agent-to-agent). If it is outside the envelope, that is a genuine authority gap — see [Failure modes](#failure-modes). 7. **The agent completes the task autonomously.** It searches, then books, then confirms — without returning to Alice between steps. Alice delegated the task; the agent finishes it and reports back once, with the result. The rest of this document is that sequence in full detail. The key thing the hops below make concrete: **required scopes are pulled from the counterparty's passport at connection time, not pre-computed by the assistant.** *** ## Hop 1: Alice → Personal Assistant[​](#hop-1-alice--personal-assistant "Direct link to Hop 1: Alice → Personal Assistant") **Authentication path:** [§10.3.3](/spec/next#1033-credential-schemes) (Credential Schemes) — established once at setup, presented per message by the channel **Authorization path:** [§2.1](/protocol/trust.md#21-authorization-in-human-to-agent-flows) (Human-to-Agent Flows) Alice doesn't necessarily reach her assistant through a web app. People run agents — often an OpenClaw agent they've configured on their own machine — and talk to them over whatever channel they already live in: a Discord DM, a Slack message, a Teams chat, iMessage, email, or a web UI. The authentication model has to work across all of them, and it does, because of one separation: **delegation is established once, at setup; each task message is authenticated by the channel it arrives on.** There is no consent screen popping up mid-conversation on Discord. ### Setup (happens once, before any task)[​](#setup-happens-once-before-any-task "Direct link to Setup (happens once, before any task)") When Alice first connects her assistant — installs the agent, links her calendar, authorizes payments — she performs the delegation. Concretely this is an OAuth 2.1 grant: * For a web or app setup, the Authorization Code grant with PKCE in a browser. * For a channel or device with no convenient browser, the OAuth 2.1 Device Authorization Grant (\[RFC 8628]) — the "go to this URL and enter this code" flow built exactly for input-constrained setups, which is how an OpenClaw agent on a headless box or a chat channel typically gets authorized. Either way, Alice consents **once** to a delegation envelope sized to what she wants the assistant to do, and the assistant stores the resulting tokens (with refresh tokens for longevity). This is the moment her standing authority is defined: ``` S_h = {calendar:read, travel:search, travel:book, payments:authorize} ``` The envelope is a *ceiling, not a checklist* — it bounds what the assistant may do on her behalf, and the assistant draws on whatever subset each downstream step actually requires, discovered as it goes. It is established at setup, not re-negotiated on every message. ### This message (per task)[​](#this-message-per-task "Direct link to This message (per task)") Later, Alice sends "Book me a 5-day vacation to Ibiza in July" over her channel. The agent already holds its authority, so there is no fresh login — what the agent must do now is **bind the message to Alice's identity**, and the strength of that binding depends on the channel: | Channel | Sender authentication | Assurance | | ----------------- | ----------------------------------------------------- | ------------------------------------ | | Web / app session | Authenticated session + DPoP-bound token | High | | Slack / Teams | Platform request signing + verified workspace user id | High | | Discord | Verified Discord user id of the message author | Medium | | iMessage | Sender handle (phone / Apple ID) | Medium — handle spoofing is possible | | Email | DKIM/SPF/DMARC on the sender domain + linked address | Medium with DMARC, low without | The agent maps the channel-authenticated sender to Alice's account, looks up her stored delegation `S_h`, and proceeds. In this model the [§10.3.3](/spec/next#1033-credential-schemes) "credential" is the channel-authenticated identity bound to the stored token set — not an interactive browser login per request. (On a web session it still looks like a classic bearer-token + DPoP request; on Discord it's a verified author id mapped to the same stored tokens. Same §10.3.3 outcome, different transport.) ### Channel assurance feeds the authorization decision[​](#channel-assurance-feeds-the-authorization-decision "Direct link to Channel assurance feeds the authorization decision") Because channels differ in how strongly they prove the sender, the [§10.4](/spec/next#104-authorization-scopes) authorization decision can factor channel assurance in alongside scope. A reasonable policy: * **Search / read** (`travel:search`, `calendar:read`): allow on any linked channel. * **Book / charge** (`travel:book`, `payments:authorize`): require a high-assurance channel, or a one-time step-up confirmation ("reply YES to confirm the $580 booking") when the request arrives on a medium-assurance channel like email or iMessage. This keeps a spoofed email from triggering a real charge, without weakening the autonomous flow for low-stakes actions on trusted channels. ### The agent starts working[​](#the-agent-starts-working "Direct link to The agent starts working") The assistant accepts the message and parses intent: a 5-day trip to Ibiza in July, needing dates, flights, and lodging. It sketches a rough plan — find dates, then find and engage travel agents — but it does **not** yet know which agents it will call or what they will require. Those facts get discovered in the later hops. **Alice's standing authority, the ceiling for everything the assistant does next:** ``` S_h = {calendar:read, travel:search, travel:book, payments:authorize} ``` The assistant never needs to come back to Alice as long as each step's discovered requirement falls inside this envelope — which matters even more on a chat channel, where "going back to Alice" means sending a message and waiting, possibly hours, for a reply. *** ## Hop 2: Personal Assistant → Calendar MCP Server[​](#hop-2-personal-assistant--calendar-mcp-server "Direct link to Hop 2: Personal Assistant → Calendar MCP Server") **Authentication path:** OAuth 2.1 token exchange ([§10.3.3.1](/spec/next#10331-oauth-21-type-oauth2)) **Authorization path:** [§2.1](/protocol/trust.md#21-authorization-in-human-to-agent-flows) (the MCP server is itself an OAuth 2.1 resource server) ### Why this hop is OAuth, not passport[​](#why-this-hop-is-oauth-not-passport "Direct link to Why this hop is OAuth, not passport") MCP servers in the wild are typically OAuth 2.1 resource servers. They authenticate via tokens, not via ADL passports. So even though the assistant is an ADL agent, when it calls a non-ADL MCP server, it falls back to OAuth 2.1. If the calendar MCP did speak ADL, the assistant would use [§1.1](/protocol/trust.md#11-passport-verification-procedure) + [§1.2](/protocol/trust.md#12-presentation-proof) + [§2.2](/protocol/trust.md#22-authorization-in-agent-to-agent-flows) instead — the same machinery as Hops 4–6. The choice of authentication mechanism is a property of the *server*, not the *client*. ADL agents speak OAuth 2.1 to non-ADL servers and ADL passports to ADL servers, gracefully. ### What happens[​](#what-happens "Direct link to What happens") 1. The assistant exchanges Alice's token for an MCP-bound token using OAuth 2.1 Token Exchange (\[RFC 8693]): * `POST https://auth.assistant.example/oauth/token` * `grant_type=urn:ietf:params:oauth:grant-type:token-exchange` * `subject_token=eyJ...` (Alice's access token) * `subject_token_type=urn:ietf:params:oauth:token-type:access_token` * `actor_token=` * `resource=https://calendar.example/mcp` * `scope=calendar:read` The IdP returns a new access token bound to the calendar MCP audience, with `scope=calendar:read` and an `act` claim referencing the assistant's DID. This makes the audit trail reconstruct who-on-behalf-of-whom. 2. The assistant calls the MCP server: `POST /mcp/tools/find_open_dates` with `Authorization: Bearer ` and `DPoP: ...`. 3. The MCP server's [§10.3.3](/spec/next#1033-credential-schemes) authentication validates the token, the audience, and the DPoP binding. 4. [§2.1](/protocol/trust.md#21-authorization-in-human-to-agent-flows) authorization at the MCP server: * `required = ["calendar:read"]` for the `find_open_dates` tool. * `presented = ["calendar:read"]` from the exchanged token. * `required ⊆ presented` ✓ — authorized. 5. MCP returns `["2026-07-12", "2026-07-13", ..., "2026-07-20"]`. **Audit record at this hop:** * Inbound credential: exchanged OAuth token, scopes `[calendar:read]`, `act={"sub": "did:web:assistant.example:agents:personal-bot"}`, `sub=alice@example.com` * Tool: `find_open_dates` * Outcome: authorized *** ## Hop 3: Personal Assistant → Travel Discovery[​](#hop-3-personal-assistant--travel-discovery "Direct link to Hop 3: Personal Assistant → Travel Discovery") **Authentication path:** None — public discovery endpoint **Authorization path:** None at retrieval. **[§1.1](/protocol/trust.md#11-passport-verification-procedure) verification** runs on each discovered passport before they enter the assistant's candidate list. ### What happens[​](#what-happens-1 "Direct link to What happens") 1. The assistant fetches `GET https://travel-agents.example/.well-known/adl-agents`. No auth. 2. The endpoint returns a discovery document listing travel agents: ``` { "adl_discovery": "1.0", "agents": [ { "id": "https://acme-flights.example/agents/booking", "adl_document": "https://acme-flights.example/agents/booking", "name": "Acme Flight Booking", "version": "3.2.1", "status": "active" }, { "id": "https://luxury-hotels.example/agents/concierge", "adl_document": "https://luxury-hotels.example/agents/concierge", "name": "Luxury Hotels Concierge", "version": "1.5.0", "status": "active" }, { "id": "https://budget-air.example/agents/legacy-booking", "adl_document": "https://budget-air.example/agents/legacy-booking", "name": "Budget Air Legacy", "version": "0.9.2", "status": "deprecated" } ] } ``` 3. For each candidate, the assistant fetches the passport (HTTPS GET to `adl_document`) and runs the full [§1.1](/protocol/trust.md#11-passport-verification-procedure) verification procedure: * **[§1.1.1](/protocol/trust.md#111-retrieval-integrity) Retrieval Integrity** — TLS validation against the candidate's domain. * **[§1.1.2](/protocol/trust.md#112-schema-validation) Schema Validation** — passport conforms to the ADL schema. * **[§1.1.3](/protocol/trust.md#113-identity-resolution) Identity Resolution** — resolve `did:web:acme-flights.example:agents:booking` to its DID Document at `https://acme-flights.example/agents/booking/did.json`. * **[§1.1.4](/protocol/trust.md#114-public-key-cross-check) Public Key Cross-Check** — passport's inline `cryptographic_identity.public_key.value` matches the DID Document's `assertionMethod` key. * **[§1.1.5](/protocol/trust.md#115-signature-verification) Signature Verification** — the passport signature verifies against the resolved key. * **[§1.1.6](/protocol/trust.md#116-temporal-validity) Temporal Validity** — `security.attestation.expires_at` is well in the future. * **[§1.1.7](/protocol/trust.md#117-lifecycle-gating) Lifecycle Gating** — `lifecycle.status: "active"`. (Budget Air's status is `deprecated`, which the assistant logs but doesn't filter — it's still safe to use, just with a sunset warning. If it were `retired`, the assistant would skip it entirely.) * **[§1.1.8](/protocol/trust.md#118-provideridentity-coherence) Provider–Identity Coherence** — TLS authority `acme-flights.example` matches `provider.url` host matches the `did:web` domain segment. * **[§1.1.9](/protocol/trust.md#119-permission-and-classification-compatibility) Permission/Classification Compatibility** — the assistant is invoking the agent shortly, so it pre-checks classification: assistant's `data_classification.sensitivity` (let's say `internal`) is `≥` flight agent's classification (`internal`). ✓ 4. Acme Flight Booking and Luxury Hotels Concierge both pass with no warnings. Budget Air Legacy passes with a `deprecated` warning logged for ops review. The assistant's candidate list is `[Acme Flight Booking, Luxury Hotels Concierge, Budget Air Legacy(warn)]`. ### Reading each counterparty's connection requirements[​](#reading-each-counterpartys-connection-requirements "Direct link to Reading each counterparty's connection requirements") Verification does more than establish trust — it hands the assistant the **requirements to connect**. The same passport the assistant just verified declares, in its own `security` and `tools` members, exactly what a caller must present. The assistant reads these off the passport; it does not guess them. From Acme Flight Booking's passport: ``` security: authentication: type: oauth2 # ← but Acme also accepts ADL agent-to-agent auth; see note scopes: ["flights:search", "flights:book"] # the agent's standing grant / ceiling for callers tools: - name: search_flights security: scopes: ["flights:search"] # ← required to call search_flights - name: book_flight security: scopes: ["flights:book", "payments:authorize"] # ← required to call book_flight ``` This tells the assistant three things before it sends a single request: * **Authentication path:** Acme is an ADL agent and exposes its `did:web` identity, so the assistant will authenticate agent-to-agent ([§1.1](/protocol/trust.md#11-passport-verification-procedure) + [§1.2](/protocol/trust.md#12-presentation-proof)) rather than via the human OAuth path. (A counterparty that only spoke OAuth would advertise only `security.authentication`, and the assistant would fall back to the [Hop 2](#hop-2-personal-assistant--calendar-mcp-server) pattern.) * **What `search_flights` requires:** `flights:search`. * **What `book_flight` requires:** `flights:book` + `payments:authorize`. The assistant now checks those discovered requirements against Alice's standing authority (`S_h`) and its own passport ceiling. `flights:search` and `flights:book` map from Alice's delegated `travel:search` / `travel:book`; `payments:authorize` Alice delegated directly. Every requirement Acme just declared is inside the envelope — so the assistant can proceed autonomously, with no trip back to Alice. **Audit record at this hop:** * Verification outcome per candidate (verified, public key source, lifecycle warnings) * For Budget Air specifically: verified=true, severity=warn at [§1.1.7](/protocol/trust.md#117-lifecycle-gating) * Discovered connection requirements per chosen agent (auth path + per-tool required scopes) The assistant decides to use Acme Flight Booking and Luxury Hotels Concierge. *** ## Hop 4: Personal Assistant → Flight Booking Agent (search)[​](#hop-4-personal-assistant--flight-booking-agent-search "Direct link to Hop 4: Personal Assistant → Flight Booking Agent (search)") **Authentication path:** [§1.1](/protocol/trust.md#11-passport-verification-procedure) (passport already verified in Hop 3, cached) + [§1.2](/protocol/trust.md#12-presentation-proof) (presentation proof, fresh per request) **Authorization path:** [§2.2](/protocol/trust.md#22-authorization-in-agent-to-agent-flows) (Agent-to-Agent Flows) ### Constructing the proof[​](#constructing-the-proof "Direct link to Constructing the proof") The assistant does not invent a scope set here. It already learned in Hop 3, from Acme's passport, that `search_flights` requires exactly `flights:search`. So the claim for this request is determined by the counterparty's declared requirement, then confirmed against Alice's standing authority: ``` required (from Acme's passport) = {flights:search} # discovered in Hop 3 S_h (Alice's standing authority) = {calendar:read, travel:search, travel:book, payments:authorize} map(travel:search) = {flights:search, hotels:search} # vocabulary translation assistant ceiling = {..., flights:search, flights:book, ...} required ⊆ map(S_h) ∩ ceiling ? YES → claim exactly `required` ``` This is the **reduction pattern** from [§2.3](/protocol/trust.md#23-composition-across-boundaries-multi-hop-authorization) applied per-counterparty: the requirement is pulled from the counterparty, not pushed by the assistant, and the assistant claims the minimum the counterparty asked for rather than the maximum Alice granted. For *this* search request, that minimum is `flights:search`. ``` { "adl_proof": "1.0", "iss": "https://assistant.example/agents/personal-bot", "iat": "2026-05-06T14:30:00Z", "exp": "2026-05-06T14:35:00Z", "jti": "01HXAA2K8N3M9P4Q5R6S7T8V9W", "request": { "method": "POST", "uri": "https://acme-flights.example/agents/booking/tools/search_flights" }, "scopes": ["flights:search"], "signature": { "algorithm": "Ed25519", "value": "", "signed_content": "canonical" } } ``` The signature covers the JCS-canonical form of the proof minus the `signature` object (per [§1.2.6.5](/protocol/trust.md#126-verification-procedure)). Since `scopes` is part of the canonical bytes, an attacker who scrapes the proof cannot replay it with an expanded scope set. ### Request[​](#request "Direct link to Request") ``` POST /agents/booking/tools/search_flights HTTP/1.1 Host: acme-flights.example ADL-Passport: ADL-Proof: Content-Type: application/json { "origin": "JFK", "destination": "IBZ", "depart": "2026-07-12", "return": "2026-07-17", "passengers": 1 } ``` ### Verification at Acme Flight Booking[​](#verification-at-acme-flight-booking "Direct link to Verification at Acme Flight Booking") 1. **[§1.1](/protocol/trust.md#11-passport-verification-procedure) Passport Verification** — already cached from Hop 3 (or re-run fresh if cache expired). All 9 steps pass. 2. **[§1.2.6](/protocol/trust.md#126-verification-procedure) Proof Verification:** * **[§1.2.6.1](/protocol/trust.md#126-verification-procedure) Parsing** — proof is valid JSON, all required members present. * **[§1.2.6.2](/protocol/trust.md#126-verification-procedure) Issuer Match** — proof.iss `https://assistant.example/agents/personal-bot` equals passport.id ✓. * **[§1.2.6.3](/protocol/trust.md#126-verification-procedure) Temporal Validity** — current time is between `iat - 60s` and `exp + 60s`, and `exp - iat ≤ 5min` ✓. * **[§1.2.6.4](/protocol/trust.md#126-verification-procedure) Request Binding** — proof.request.method = `POST` matches actual method ✓; proof.request.uri canonicalizes to actual URI ✓. * **[§1.2.6.5](/protocol/trust.md#126-verification-procedure) Signature Verification** — Ed25519 signature verifies against JCS canonical bytes using the verification key from [§1.1.4](/protocol/trust.md#114-public-key-cross-check) ✓. * **[§1.2.6.6](/protocol/trust.md#126-verification-procedure) Replay Prevention** — `jti` not in the verifier's recent-cache ✓; insert it. * **[§1.2.6.7](/protocol/trust.md#126-verification-procedure) Nonce Verification** — N/A (no server-issued nonce required). 3. **[§2.2](/protocol/trust.md#22-authorization-in-agent-to-agent-flows) Authorization (Agent-to-Agent):** * **Step 1:** Authentication done. * **Step 2: Establish ceiling.** Calling agent's passport `security.scopes` is `[calendar:read, travel:search, travel:book, payments:authorize, flights:search, flights:book, hotels:search, hotels:book]`. This is the ceiling. * **Step 3: Extract requested scopes.** `proof.scopes = ["flights:search"]`. * **Step 4: Verify ceiling subset.** `["flights:search"] ⊆ ceiling` ✓. * **Step 5: Determine required.** `tools[search_flights].security.scopes` is declared as `["flights:search"]`. So `required = ["flights:search"]`. * **Step 6: Authorize.** `["flights:search"] ⊆ ["flights:search"]` ✓ — authorized. 4. The flight agent runs its actual search and returns 8 candidate flights. **Audit record at this hop:** * Inbound: passport DID `did:web:assistant.example:agents:personal-bot`, proof.scopes `[flights:search]`, ceiling `[flights:search, flights:book, payments:authorize]` (the relevant subset) * Tool: `search_flights` * Required scopes: `[flights:search]` * Outcome: authorized * Note: **Alice's identity is not visible to the flight agent** — Hop 4 sees only the assistant's identity. If the flight agent needed Alice's identity (e.g., for fraud scoring), the assistant would have to include it in the request body or via a separate vouching mechanism. The protocol-level audit chain is per-hop. *** ## Hop 5: Personal Assistant → Flight Booking Agent (book)[​](#hop-5-personal-assistant--flight-booking-agent-book "Direct link to Hop 5: Personal Assistant → Flight Booking Agent (book)") **Authentication path:** [§1.1](/protocol/trust.md#11-passport-verification-procedure) (cached) + [§1.2](/protocol/trust.md#12-presentation-proof) (fresh per request) **Authorization path:** [§2.2](/protocol/trust.md#22-authorization-in-agent-to-agent-flows) with **escalated scopes** ### What's different about booking[​](#whats-different-about-booking "Direct link to What's different about booking") Alice picked a flight from the search results. Booking is a higher-stakes operation, and Acme's passport said so back in Hop 3: `book_flight` requires `flights:book` + `payments:authorize`, where search required only `flights:search`. The requirement *escalates*, and the assistant escalates the scopes it claims to match — but only as far as the counterparty asked, and only within Alice's envelope. ### Confirming authority before booking[​](#confirming-authority-before-booking "Direct link to Confirming authority before booking") The assistant re-checks the discovered requirement against Alice's standing authority — the same check as Hop 4, with the escalated requirement: ``` required (from Acme's passport) = {flights:book, payments:authorize} # discovered in Hop 3 S_h = {calendar:read, travel:search, travel:book, payments:authorize} map(travel:book) = {flights:book, hotels:book} payments:authorize delegated directly assistant ceiling = {..., flights:book, payments:authorize, ...} required ⊆ map(S_h) ∩ ceiling ? YES → claim exactly `required`, proceed autonomously ``` Because booking is within the envelope Alice already delegated, the assistant proceeds without returning to Alice. It does not pause mid-task to re-confirm — Alice asked it to book a vacation, and booking is part of that. (The case where a requirement falls *outside* the envelope is covered in [Failure modes](#failure-modes); the short version is that it's resolved when the delegation is set up, not mid-task.) ### Constructing the proof[​](#constructing-the-proof-1 "Direct link to Constructing the proof") ``` { "adl_proof": "1.0", "iss": "https://assistant.example/agents/personal-bot", "iat": "2026-05-06T14:32:00Z", "exp": "2026-05-06T14:37:00Z", "jti": "01HXAA3M9P4Q5R6S7T8V9W0X1Y", "request": { "method": "POST", "uri": "https://acme-flights.example/agents/booking/tools/book_flight" }, "scopes": ["flights:book", "payments:authorize"], "signature": { ... } } ``` Note: a different `jti` (replay prevention is per-request), a different request URI (different tool), a different scope set (escalated), but the same `iss` (same agent) and the same passport. ### Verification at Acme Flight Booking[​](#verification-at-acme-flight-booking-1 "Direct link to Verification at Acme Flight Booking") [§1.1](/protocol/trust.md#11-passport-verification-procedure) cached. [§1.2.6](/protocol/trust.md#126-verification-procedure) runs fresh on the new proof — all checks pass. [§2.2](/protocol/trust.md#22-authorization-in-agent-to-agent-flows) authorization: * Ceiling check: `[flights:book, payments:authorize] ⊆ ceiling` ✓. * Required: `tools[book_flight].security.scopes = [flights:book, payments:authorize]`. * Match: `[flights:book, payments:authorize] ⊆ [flights:book, payments:authorize]` ✓. The flight agent books the flight, charges the payment method (Alice's card on file with the assistant — pre-authorized via the OAuth grant), returns confirmation. *** ## Hop 6: Personal Assistant → Hotel Booking Agent[​](#hop-6-personal-assistant--hotel-booking-agent "Direct link to Hop 6: Personal Assistant → Hotel Booking Agent") Same pattern as Hops 4 & 5, but against `https://luxury-hotels.example/agents/concierge` with `hotels:search` then `hotels:book + payments:authorize`. The cached [§1.1](/protocol/trust.md#11-passport-verification-procedure) verification of the hotel agent's passport reused; fresh [§1.2](/protocol/trust.md#12-presentation-proof) proof per request; [§2.2](/protocol/trust.md#22-authorization-in-agent-to-agent-flows) ceiling and tool checks identical in shape. *** ## End-to-end audit reconstruction[​](#end-to-end-audit-reconstruction "Direct link to End-to-end audit reconstruction") The audit chain looks like: ``` [Hop 1] Alice → Assistant sub=alice@example.com channel=discord (author id verified, medium assurance) standing scopes=[calendar:read, travel:search, travel:book, payments:authorize] (delegated at setup) tool=chat outcome=authorized [Hop 2] Assistant → Calendar MCP token: act={did:web:assistant.example:agents:personal-bot}, sub=alice@example.com, scope=[calendar:read] tool=find_open_dates outcome=authorized [Hop 3] Assistant → Discovery (no auth, but verification of each candidate passport) outcomes: [Acme Flights: verified, Luxury Hotels: verified, Budget Air: verified+warn(deprecated)] [Hop 4] Assistant → Flight Agent passport=did:web:assistant.example:agents:personal-bot, proof.scopes=[flights:search] tool=search_flights outcome=authorized [Hop 5] Assistant → Flight Agent passport=did:web:assistant.example:agents:personal-bot, proof.scopes=[flights:book, payments:authorize] tool=book_flight outcome=authorized [Hop 6a] Assistant → Hotel Agent passport=did:web:assistant.example:agents:personal-bot, proof.scopes=[hotels:search] tool=search_hotels outcome=authorized [Hop 6b] Assistant → Hotel Agent passport=did:web:assistant.example:agents:personal-bot, proof.scopes=[hotels:book, payments:authorize] tool=book_hotel outcome=authorized ``` Each hop records its own row. No single hop sees the entire chain. End-to-end reconstruction requires correlating by request id, by Alice's session, by the assistant's actor token (which carries her sub through the calendar exchange), or by the assistant's passport DID (which is constant across all upstream hops). If a regulator later asks "did Alice authorize this booking?", the chain reconstructs: * Alice's OAuth grant included `travel:book` and `payments:authorize` (at the assistant) * The assistant's passport ceiling included `flights:book` and `payments:authorize` (at the flight agent) * Both proofs at Hop 5 declared scopes within both bounds * Therefore the booking was authorized end-to-end, with both layers of consent recorded *** ## Failure modes[​](#failure-modes "Direct link to Failure modes") ### The discovered requirement falls outside Alice's delegated envelope[​](#the-discovered-requirement-falls-outside-alices-delegated-envelope "Direct link to The discovered requirement falls outside Alice's delegated envelope") Suppose Alice's standing authority is `{calendar:read, travel:search, travel:book}` — she never delegated `payments:authorize`. When the assistant reads Acme's `book_flight` requirement in Hop 3, it discovers `payments:authorize` is required but not in the envelope: ``` required (from Acme's passport) = {flights:book, payments:authorize} S_h = {calendar:read, travel:search, travel:book} # no payments:authorize required ⊆ map(S_h) ∩ ceiling ? NO — payments:authorize is outside the envelope ``` This is a genuine authority gap, and the right place to resolve it is **at delegation time, not mid-task**. The assistant should request an envelope sized to the intent up front: a request to "book a vacation" plainly implies authority to pay, so the assistant requests `payments:authorize` in the original Hop 1 consent. A well-designed assistant catches an under-sized envelope before it starts work — by comparing the parsed intent against the granted scopes the moment Alice's message arrives — and asks for the missing grant once, at the start, rather than discovering it three hops deep. If the gap is only discovered mid-task (e.g., a counterparty requires a scope the assistant could not have anticipated from the intent), the assistant has two honest options: complete the part of the task it *is* authorized for and report what it could not do, or pause and request the additional grant. It does **not** silently claim authority it wasn't given — the upstream [§2.2](/protocol/trust.md#22-authorization-in-agent-to-agent-flows) ceiling check (next failure mode) is the backstop that makes sure of that. The design goal is that this is rare: front-loading the delegation to match the intent keeps the agent working autonomously to completion in the common case. ### The assistant's passport ceiling doesn't include `flights:book`[​](#the-assistants-passport-ceiling-doesnt-include-flightsbook "Direct link to the-assistants-passport-ceiling-doesnt-include-flightsbook") Maybe the assistant was provisioned without `flights:book` because the operator didn't enable that capability. At Hop 5, the assistant could *try* to issue the proof anyway, but the flight agent's [§2.2](/protocol/trust.md#22-authorization-in-agent-to-agent-flows) step 4 (ceiling subset check) would reject: ``` proof.scopes = [flights:book, payments:authorize] ceiling = [calendar:read, travel:search, ..., flights:search, hotels:search, hotels:book] # no flights:book [flights:book, payments:authorize] ⊆ ceiling ? NO ``` The flight agent rejects with a structured error pointing at [§2.2](/protocol/trust.md#22-authorization-in-agent-to-agent-flows) step 4. The assistant logs the misconfiguration and reports back to Alice that flight booking isn't enabled for this assistant. A well-designed assistant catches this BEFORE the request via a passport self-check (the assistant reads its own passport's ceiling), but the upstream check is the security backstop. ### Flight agent's lifecycle is `retired`[​](#flight-agents-lifecycle-is-retired "Direct link to flight-agents-lifecycle-is-retired") The discovery document at Hop 3 listed Acme Flight Booking as `active`, but between Hop 3 and Hop 4 the agent was retired. When the assistant re-runs [§1.1](/protocol/trust.md#11-passport-verification-procedure) on the cached passport (or hits a still-cached signed passport whose lifecycle changed in the document at the canonical URL), [§1.1.7](/protocol/trust.md#117-lifecycle-gating) catches it: * If the cached passport says `active` but the canonical URL now says `retired`, the [§1.1.3](/protocol/trust.md#113-identity-resolution) byte-sequence check catches the divergence (the old passport doesn't match the current canonical version). * If the assistant re-fetches and gets the new `retired` passport, [§1.1.7](/protocol/trust.md#117-lifecycle-gating) hard-blocks. Either way, the assistant falls back to the next candidate (Budget Air Legacy, with the deprecated warning) or surfaces the issue to Alice. ### Personal Assistant's proof gets replayed by an attacker[​](#personal-assistants-proof-gets-replayed-by-an-attacker "Direct link to Personal Assistant's proof gets replayed by an attacker") Someone captures the `ADL-Proof` header from Hop 4 (a search) and replays it at Hop 5 (a book). They want the *book* tool's effect using the *search* tool's proof. [§1.2.6.4](/protocol/trust.md#126-verification-procedure) catches this: the replayed proof has `request.uri = .../search_flights` but the actual request URL is `.../book_flight`. URI mismatch → reject. If the attacker also tries to replay the proof at the same URI (a duplicate search), [§1.2.6.6](/protocol/trust.md#126-verification-procedure) catches it: the `jti` is in the recent-cache → reject. If the attacker has *forged* a proof for the right URI but signed with their own key, [§1.2.6.5](/protocol/trust.md#126-verification-procedure) catches it: the signature doesn't verify against the assistant's key. If the attacker has the assistant's private key, none of this matters — the assistant has been compromised, and operational rotation (rotating the keypair, issuing a new attestation, marking the old as superseded via §5.6 lifecycle) is the answer. The presentation proof addresses replay; private key compromise is out of scope per [§1.2.1](/protocol/trust.md#121-threat-model). *** ## Spec section index[​](#spec-section-index "Direct link to Spec section index") For implementers building this scenario: | Step | Spec section | | -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | | Alice's setup-time delegation (web OAuth or device-code grant) | [§10.3.3.1](/spec/next#10331-oauth-21-type-oauth2) OAuth 2.1 + RFC 8628 | | Channel-authenticated message bound to standing delegation | [§10.3.3](/spec/next#1033-credential-schemes) | | Channel assurance factored into the authorization decision | [§10.4](/spec/next#104-authorization-scopes) | | Authorize Alice's request to assistant | [§2.1](/protocol/trust.md#21-authorization-in-human-to-agent-flows) | | Token exchange to MCP | [§10.3.3.1](/spec/next#10331-oauth-21-type-oauth2) + RFC 8693 | | MCP tool authorization | [§2.1](/protocol/trust.md#21-authorization-in-human-to-agent-flows) | | Discovery retrieval | [§6.4](/spec/next#64-discovery) | | Per-candidate verification | [§1.1](/protocol/trust.md#11-passport-verification-procedure) (all 9 steps) | | Passport caching | [§1.1](/protocol/trust.md#11-passport-verification-procedure) (implementation discretion; vector pack covers freshness) | | Proof construction | [§1.2](/protocol/trust.md#12-presentation-proof) (build) | | Proof signing | [§10.2](/spec/next#102-attestation) + [§1.2](/protocol/trust.md#12-presentation-proof) | | Proof verification at upstream | [§1.2.6](/protocol/trust.md#126-verification-procedure) (all 7 sub-steps) | | Ceiling check | [§2.2](/protocol/trust.md#22-authorization-in-agent-to-agent-flows) step 4 | | Required-scope check | [§2.2](/protocol/trust.md#22-authorization-in-agent-to-agent-flows) step 6 | | Cross-hop authorization independence | [§2.3](/protocol/trust.md#23-composition-across-boundaries-multi-hop-authorization) (independent vs. reduction patterns) | | Audit recording | [§2.3](/protocol/trust.md#23-composition-across-boundaries-multi-hop-authorization) (multi-hop record requirement) | ## Related material[​](#related-material "Direct link to Related material") * [Draft spec §10 (Security)](/spec/next#10-security) * [Draft spec §10.3 (Authentication)](/spec/next#103-authentication) * [Draft spec §10.4 (Authorization Scopes)](/spec/next#104-authorization-scopes) * [Draft spec §6.4 (Discovery)](/spec/next#64-discovery) * [Test vector pack](https://github.com/adl-spec/agent-definition-language/tree/main/core/_next/test-vectors/verify) (GitHub) * [OpenClaw passport reference example](https://github.com/adl-spec/agent-definition-language/tree/main/packages/adl-agent/examples/openclaw-passport) (GitHub) --- # Profiles Profiles extend the core ADL specification with domain-specific requirements, members, and validation rules. They enable regulated industries and specialized use cases to build on ADL without modifying the core spec. tip When to use profiles — use profiles when your agents need to comply with industry regulations (HIPAA, SOC2, PCI-DSS) or organizational governance requirements. Profiles add structured compliance tracking without changing core ADL semantics. ## Overview[​](#overview "Direct link to Overview") A **profile** is a set of additional requirements and members that extend ADL for a specific domain. When an ADL document declares a profile in its `profiles` array, it: * **MUST** satisfy all requirements of that profile * **MAY** use members defined by the profile * **SHOULD** be validated against profile-specific rules Profiles are identified by URIs (e.g., `urn:adl:profile:governance:1.0`). ## Available Profiles[​](#available-profiles "Direct link to Available Profiles") | Profile | Identifier | Status | Description | | ---------------------------------------------- | -------------------------------- | ------ | ---------------------------------------------------------------------- | | [Governance](/profiles/governance/overview.md) | `urn:adl:profile:governance:1.0` | Draft | Compliance frameworks, audit trails, enterprise governance | | [Portfolio](/profiles/portfolio/overview.md) | `urn:adl:profile:portfolio:1.0` | Draft | Agent relationships and domain membership | | [Registry](/profiles/registry/overview.md) | `urn:adl:profile:registry:1.0` | Draft | Agent catalog identity, classification, and federation | | [Financial](/profiles/financial/overview.md) | `urn:adl:profile:financial:1.0` | Draft | PCI-DSS, SOX, GLBA, MiFID II, AML/KYC compliance | | [Healthcare](/profiles/healthcare/overview.md) | `urn:adl:profile:healthcare:1.0` | Draft | HIPAA compliance, PHI handling, clinical safety, FHIR interoperability | ## Profile Versioning[​](#profile-versioning "Direct link to Profile Versioning") Profiles are versioned independently of the core ADL specification. Each profile declares which ADL versions it is compatible with in its `COMPATIBILITY.md` file. * Profile versions follow [Semantic Versioning](https://semver.org/) * A profile version remains compatible with ADL versions it declares * When ADL introduces breaking changes, profiles release new versions as needed ## Proposing a New Profile[​](#proposing-a-new-profile "Direct link to Proposing a New Profile") 1. Open an issue using the [profile proposal template](https://github.com/agent-definition-language/specification/blob/main/.github/ISSUE_TEMPLATE/profile_proposal.md) 2. Discuss scope, requirements, and target ADL compatibility 3. Create a directory under `profiles/` with: * `README.md` — Scope, status, maintainers * `COMPATIBILITY.md` — ADL version compatibility * `1.0/profile.md` — Profile specification * `1.0/examples/` — Example ADL documents using the profile 4. Submit a PR for review ## Profile Requirements[​](#profile-requirements "Direct link to Profile Requirements") Profiles **MUST NOT**: * Redefine core ADL members * Conflict with other profiles Profiles **MAY**: * Add new top-level members * Add members to existing objects * Define additional validation rules * Require specific values for optional members ## See Also[​](#see-also "Direct link to See Also") * [ADL Specification — Section 13: Profiles](/spec/.md#13-profiles) * [Contributing Guide](/contributing.md) --- # Financial Profile Examples ## Financial Compliance Monitor[​](#financial-compliance-monitor "Direct link to Financial Compliance Monitor") A compliance agent for a universal financial institution that monitors **both banking activity** (wire and ACH transfers, deposits) **and brokerage activity** (securities trading) for AML, fraud, and regulatory compliance. It spans the deposit-taking and broker-dealer sides of the house: BSA/AML and GLBA on the banking side, FINRA, SEC, and MiFID II on the brokerage side. * YAML * JSON financial-compliance-agent.adl.yaml ``` $schema: https://adl-spec.org/0.3/schema.json adl_spec: 0.3.0 name: Financial Compliance Monitor description: Monitors both banking activity (wires, deposits) and brokerage activity (securities trading) across a universal financial institution for AML, fraud, and regulatory compliance. version: 1.0.0 profiles: - urn:adl:profile:financial:1.0 lifecycle: status: active effective_date: 2026-01-01T00:00:00Z provider: name: Meridian Financial Group url: https://meridian.example contact: compliance@meridian.example model: capabilities: - function_calling tools: - name: screen_wire_transfers description: Screen banking wire and ACH transfers for BSA/AML and sanctions risk parameters: type: object properties: account_id: type: string lookback_days: type: integer default: 30 required: - account_id read_only: true - name: surveil_trades description: Surveil securities trading activity for market manipulation and insider trading parameters: type: object properties: account_id: type: string instrument: type: string required: - account_id read_only: true - name: file_sar description: File a Suspicious Activity Report with FinCEN (covers both banking and brokerage activity) parameters: type: object properties: subject_ids: type: array items: type: string activity_type: type: string enum: - banking - securities narrative: type: string required: - subject_ids - narrative requires_confirmation: true permissions: network: allowed_hosts: - core-banking.meridian.example - market-surveillance.meridian.example - fincen.gov allowed_protocols: - https deny_private: true filesystem: allowed_paths: - path: /data/banking/** access: read - path: /data/trading/** access: read - path: /data/reports/** access: read_write security: authentication: type: mtls required: true encryption: in_transit: required: true min_version: "1.3" at_rest: required: true algorithm: AES-256-GCM data_classification: sensitivity: confidential categories: - pii - financial retention: min_days: 1825 handling: encryption_required: true logging_required: true financial: data_types: - transaction_data - nonpublic_personal_info - market_data - material_nonpublic_info pci_applicable: false financial_data_handling: pci_scope: in_scope: false data_residency: - jurisdiction: US regulation: GLBA - jurisdiction: EU regulation: MIFID_II transaction_controls: transaction_limits: max_single_amount: 10000000 currency: USD pre_execution_controls: enabled: true price_tolerance_pct: 2 requires_approval_above: 1000000 kill_switch: enabled: true trigger_conditions: - error_rate_threshold - anomaly_detection notification_targets: - compliance-team@meridian.example segregation_of_duties: enabled: true restricted_actions: - file_sar approval_role: Compliance Officer regulatory_scope: applicable_regulations: - GLBA - BSA_AML - BASEL_III - FINRA - SEC_REG - MIFID_II jurisdictions: - jurisdiction: US regulation: BSA_AML - jurisdiction: EU regulation: MIFID_II record_retention: min_retention_days: 1825 tamper_proof: true financial_risk_management: model_risk: tier: tier_2 validated_by: Model Risk Committee validated_at: 2025-12-15T00:00:00Z methodology: Champion-challenger with backtesting aml_controls: screening_required: true monitoring_level: real_time kyc_refresh_days: 365 operational_risk: category: high assessed_by: Operational Risk Committee assessed_at: 2025-12-15T00:00:00Z capital_reserve: true metadata: authors: - name: Meridian Compliance Team email: compliance@meridian.example license: Proprietary tags: - financial - banking - brokerage - aml - compliance ``` financial-compliance-agent.adl.json ``` { "$schema": "https://adl-spec.org/0.3/schema.json", "adl_spec": "0.3.0", "name": "Financial Compliance Monitor", "description": "Monitors both banking activity (wires, deposits) and brokerage activity (securities trading) across a universal financial institution for AML, fraud, and regulatory compliance.", "version": "1.0.0", "profiles": [ "urn:adl:profile:financial:1.0" ], "lifecycle": { "status": "active", "effective_date": "2026-01-01T00:00:00Z" }, "provider": { "name": "Meridian Financial Group", "url": "https://meridian.example", "contact": "compliance@meridian.example" }, "model": { "capabilities": [ "function_calling" ] }, "tools": [ { "name": "screen_wire_transfers", "description": "Screen banking wire and ACH transfers for BSA/AML and sanctions risk", "parameters": { "type": "object", "properties": { "account_id": { "type": "string" }, "lookback_days": { "type": "integer", "default": 30 } }, "required": [ "account_id" ] }, "read_only": true }, { "name": "surveil_trades", "description": "Surveil securities trading activity for market manipulation and insider trading", "parameters": { "type": "object", "properties": { "account_id": { "type": "string" }, "instrument": { "type": "string" } }, "required": [ "account_id" ] }, "read_only": true }, { "name": "file_sar", "description": "File a Suspicious Activity Report with FinCEN (covers both banking and brokerage activity)", "parameters": { "type": "object", "properties": { "subject_ids": { "type": "array", "items": { "type": "string" } }, "activity_type": { "type": "string", "enum": [ "banking", "securities" ] }, "narrative": { "type": "string" } }, "required": [ "subject_ids", "narrative" ] }, "requires_confirmation": true } ], "permissions": { "network": { "allowed_hosts": [ "core-banking.meridian.example", "market-surveillance.meridian.example", "fincen.gov" ], "allowed_protocols": [ "https" ], "deny_private": true }, "filesystem": { "allowed_paths": [ { "path": "/data/banking/**", "access": "read" }, { "path": "/data/trading/**", "access": "read" }, { "path": "/data/reports/**", "access": "read_write" } ] } }, "security": { "authentication": { "type": "mtls", "required": true }, "encryption": { "in_transit": { "required": true, "min_version": "1.3" }, "at_rest": { "required": true, "algorithm": "AES-256-GCM" } } }, "data_classification": { "sensitivity": "confidential", "categories": [ "pii", "financial" ], "retention": { "min_days": 1825 }, "handling": { "encryption_required": true, "logging_required": true }, "financial": { "data_types": [ "transaction_data", "nonpublic_personal_info", "market_data", "material_nonpublic_info" ], "pci_applicable": false } }, "financial_data_handling": { "pci_scope": { "in_scope": false }, "data_residency": [ { "jurisdiction": "US", "regulation": "GLBA" }, { "jurisdiction": "EU", "regulation": "MIFID_II" } ] }, "transaction_controls": { "transaction_limits": { "max_single_amount": 10000000, "currency": "USD" }, "pre_execution_controls": { "enabled": true, "price_tolerance_pct": 2, "requires_approval_above": 1000000 }, "kill_switch": { "enabled": true, "trigger_conditions": [ "error_rate_threshold", "anomaly_detection" ], "notification_targets": [ "compliance-team@meridian.example" ] }, "segregation_of_duties": { "enabled": true, "restricted_actions": [ "file_sar" ], "approval_role": "Compliance Officer" } }, "regulatory_scope": { "applicable_regulations": [ "GLBA", "BSA_AML", "BASEL_III", "FINRA", "SEC_REG", "MIFID_II" ], "jurisdictions": [ { "jurisdiction": "US", "regulation": "BSA_AML" }, { "jurisdiction": "EU", "regulation": "MIFID_II" } ], "record_retention": { "min_retention_days": 1825, "tamper_proof": true } }, "financial_risk_management": { "model_risk": { "tier": "tier_2", "validated_by": "Model Risk Committee", "validated_at": "2025-12-15T00:00:00Z", "methodology": "Champion-challenger with backtesting" }, "aml_controls": { "screening_required": true, "monitoring_level": "real_time", "kyc_refresh_days": 365 }, "operational_risk": { "category": "high", "assessed_by": "Operational Risk Committee", "assessed_at": "2025-12-15T00:00:00Z", "capital_reserve": true } }, "metadata": { "authors": [ { "name": "Meridian Compliance Team", "email": "compliance@meridian.example" } ], "license": "Proprietary", "tags": [ "financial", "banking", "brokerage", "aml", "compliance" ] } } ``` ### Both Sides of the House[​](#both-sides-of-the-house "Direct link to Both Sides of the House") | Banking | Brokerage | | --------------------------------------------- | ------------------------------------------- | | `screen_wire_transfers` tool (wire/ACH AML) | `surveil_trades` tool (market surveillance) | | `GLBA`, `BSA_AML`, `BASEL_III` regulations | `FINRA`, `SEC_REG`, `MIFID_II` regulations | | `nonpublic_personal_info`, `transaction_data` | `market_data`, `material_nonpublic_info` | | `transaction_limits` (wire ceilings) | `pre_execution_controls` (pre-trade checks) | `file_sar` and the AML controls in `financial_risk_management` apply across both — a single FinCEN SAR pipeline and shared KYC/monitoring cadence. ### Key Financial Fields[​](#key-financial-fields "Direct link to Key Financial Fields") | Field | Purpose | | ------------------------------- | ------------------------------------------------------------------------ | | `financial_data_handling` | PCI scope assessment and multi-jurisdiction data residency | | `transaction_controls` | Transaction limits, pre-trade checks, kill switch, segregation of duties | | `regulatory_scope` | Banking + brokerage regulations and record retention | | `financial_risk_management` | Model risk tier, AML controls, operational risk capital | | `data_classification.financial` | Banking and brokerage data types | ### Compliance Highlights[​](#compliance-highlights "Direct link to Compliance Highlights") * **Authentication**: Mutual TLS (mTLS) for all connections * **Encryption**: TLS 1.3 in transit, AES-256-GCM at rest * **Kill Switch**: Triggered on error rate threshold or anomaly detection (required under MiFID II) * **Segregation of Duties**: SAR filing requires Compliance Officer approval * **Record Retention**: 5-year minimum, tamper-proof storage * **AML**: Real-time monitoring across banking and brokerage, annual KYC refresh ## Composed with the Governance Profile[​](#composed-with-the-governance-profile "Direct link to Composed with the Governance Profile") The Financial Profile is designed to compose with the [Governance Profile](/profiles/governance/overview.md). The composite example below declares both `urn:adl:profile:governance:1.0` and `urn:adl:profile:financial:1.0`, adding the governance-required `autonomy` and `compliance_framework` members on top of the financial members above. * YAML * JSON composite/governance-financial-agent.adl.yaml ``` $schema: https://adl-spec.org/0.3/schema.json adl_spec: 0.3.0 name: Financial Compliance Monitor description: Monitors both banking activity (wires, deposits) and brokerage activity (securities trading) across a universal financial institution for AML, fraud, and regulatory compliance. version: 1.0.0 profiles: - urn:adl:profile:governance:1.0 - urn:adl:profile:financial:1.0 lifecycle: status: active effective_date: 2026-01-01T00:00:00Z provider: name: Meridian Financial Group url: https://meridian.example contact: compliance@meridian.example model: capabilities: - function_calling tools: - name: screen_wire_transfers description: Screen banking wire and ACH transfers for BSA/AML and sanctions risk parameters: type: object properties: account_id: type: string lookback_days: type: integer default: 30 required: - account_id read_only: true - name: surveil_trades description: Surveil securities trading activity for market manipulation and insider trading parameters: type: object properties: account_id: type: string instrument: type: string required: - account_id read_only: true - name: file_sar description: File a Suspicious Activity Report with FinCEN (covers both banking and brokerage activity) parameters: type: object properties: subject_ids: type: array items: type: string activity_type: type: string enum: - banking - securities narrative: type: string required: - subject_ids - narrative requires_confirmation: true permissions: network: allowed_hosts: - core-banking.meridian.example - market-surveillance.meridian.example - fincen.gov allowed_protocols: - https deny_private: true filesystem: allowed_paths: - path: /data/banking/** access: read - path: /data/trading/** access: read - path: /data/reports/** access: read_write security: authentication: type: mtls required: true encryption: in_transit: required: true min_version: "1.3" at_rest: required: true algorithm: AES-256-GCM data_classification: sensitivity: confidential categories: - pii - financial retention: min_days: 1825 handling: encryption_required: true logging_required: true financial: data_types: - transaction_data - nonpublic_personal_info - market_data - material_nonpublic_info pci_applicable: false financial_data_handling: pci_scope: in_scope: false data_residency: - jurisdiction: US regulation: GLBA - jurisdiction: EU regulation: MIFID_II transaction_controls: transaction_limits: max_single_amount: 10000000 currency: USD pre_execution_controls: enabled: true price_tolerance_pct: 2 requires_approval_above: 1000000 kill_switch: enabled: true trigger_conditions: - error_rate_threshold - anomaly_detection notification_targets: - compliance-team@meridian.example segregation_of_duties: enabled: true restricted_actions: - file_sar approval_role: Compliance Officer regulatory_scope: applicable_regulations: - GLBA - BSA_AML - BASEL_III - FINRA - SEC_REG - MIFID_II jurisdictions: - jurisdiction: US regulation: BSA_AML - jurisdiction: EU regulation: MIFID_II record_retention: min_retention_days: 1825 tamper_proof: true financial_risk_management: model_risk: tier: tier_2 validated_by: Model Risk Committee validated_at: 2025-12-15T00:00:00Z methodology: Champion-challenger with backtesting aml_controls: screening_required: true monitoring_level: real_time kyc_refresh_days: 365 operational_risk: category: high assessed_by: Operational Risk Committee assessed_at: 2025-12-15T00:00:00Z capital_reserve: true autonomy: tier: 1 basis: Supervised financial-crimes monitoring; all SAR filings require human confirmation. classified_by: Meridian Compliance Team classified_at: 2026-01-01T00:00:00Z compliance_framework: primary_framework: NIST_800_53 control_mappings: - framework: NIST control_id: AU-2 status: implemented - framework: NIST control_id: AC-5 status: implemented - framework: NIST control_id: SC-13 status: implemented metadata: authors: - name: Meridian Compliance Team email: compliance@meridian.example license: Proprietary tags: - financial - banking - brokerage - aml - compliance ``` composite/governance-financial-agent.adl.json ``` { "$schema": "https://adl-spec.org/0.3/schema.json", "adl_spec": "0.3.0", "name": "Financial Compliance Monitor", "description": "Monitors both banking activity (wires, deposits) and brokerage activity (securities trading) across a universal financial institution for AML, fraud, and regulatory compliance.", "version": "1.0.0", "profiles": [ "urn:adl:profile:governance:1.0", "urn:adl:profile:financial:1.0" ], "lifecycle": { "status": "active", "effective_date": "2026-01-01T00:00:00Z" }, "provider": { "name": "Meridian Financial Group", "url": "https://meridian.example", "contact": "compliance@meridian.example" }, "model": { "capabilities": [ "function_calling" ] }, "tools": [ { "name": "screen_wire_transfers", "description": "Screen banking wire and ACH transfers for BSA/AML and sanctions risk", "parameters": { "type": "object", "properties": { "account_id": { "type": "string" }, "lookback_days": { "type": "integer", "default": 30 } }, "required": [ "account_id" ] }, "read_only": true }, { "name": "surveil_trades", "description": "Surveil securities trading activity for market manipulation and insider trading", "parameters": { "type": "object", "properties": { "account_id": { "type": "string" }, "instrument": { "type": "string" } }, "required": [ "account_id" ] }, "read_only": true }, { "name": "file_sar", "description": "File a Suspicious Activity Report with FinCEN (covers both banking and brokerage activity)", "parameters": { "type": "object", "properties": { "subject_ids": { "type": "array", "items": { "type": "string" } }, "activity_type": { "type": "string", "enum": [ "banking", "securities" ] }, "narrative": { "type": "string" } }, "required": [ "subject_ids", "narrative" ] }, "requires_confirmation": true } ], "permissions": { "network": { "allowed_hosts": [ "core-banking.meridian.example", "market-surveillance.meridian.example", "fincen.gov" ], "allowed_protocols": [ "https" ], "deny_private": true }, "filesystem": { "allowed_paths": [ { "path": "/data/banking/**", "access": "read" }, { "path": "/data/trading/**", "access": "read" }, { "path": "/data/reports/**", "access": "read_write" } ] } }, "security": { "authentication": { "type": "mtls", "required": true }, "encryption": { "in_transit": { "required": true, "min_version": "1.3" }, "at_rest": { "required": true, "algorithm": "AES-256-GCM" } } }, "data_classification": { "sensitivity": "confidential", "categories": [ "pii", "financial" ], "retention": { "min_days": 1825 }, "handling": { "encryption_required": true, "logging_required": true }, "financial": { "data_types": [ "transaction_data", "nonpublic_personal_info", "market_data", "material_nonpublic_info" ], "pci_applicable": false } }, "financial_data_handling": { "pci_scope": { "in_scope": false }, "data_residency": [ { "jurisdiction": "US", "regulation": "GLBA" }, { "jurisdiction": "EU", "regulation": "MIFID_II" } ] }, "transaction_controls": { "transaction_limits": { "max_single_amount": 10000000, "currency": "USD" }, "pre_execution_controls": { "enabled": true, "price_tolerance_pct": 2, "requires_approval_above": 1000000 }, "kill_switch": { "enabled": true, "trigger_conditions": [ "error_rate_threshold", "anomaly_detection" ], "notification_targets": [ "compliance-team@meridian.example" ] }, "segregation_of_duties": { "enabled": true, "restricted_actions": [ "file_sar" ], "approval_role": "Compliance Officer" } }, "regulatory_scope": { "applicable_regulations": [ "GLBA", "BSA_AML", "BASEL_III", "FINRA", "SEC_REG", "MIFID_II" ], "jurisdictions": [ { "jurisdiction": "US", "regulation": "BSA_AML" }, { "jurisdiction": "EU", "regulation": "MIFID_II" } ], "record_retention": { "min_retention_days": 1825, "tamper_proof": true } }, "financial_risk_management": { "model_risk": { "tier": "tier_2", "validated_by": "Model Risk Committee", "validated_at": "2025-12-15T00:00:00Z", "methodology": "Champion-challenger with backtesting" }, "aml_controls": { "screening_required": true, "monitoring_level": "real_time", "kyc_refresh_days": 365 }, "operational_risk": { "category": "high", "assessed_by": "Operational Risk Committee", "assessed_at": "2025-12-15T00:00:00Z", "capital_reserve": true } }, "autonomy": { "tier": 1, "basis": "Supervised financial-crimes monitoring; all SAR filings require human confirmation.", "classified_by": "Meridian Compliance Team", "classified_at": "2026-01-01T00:00:00Z" }, "compliance_framework": { "primary_framework": "NIST_800_53", "control_mappings": [ { "framework": "NIST", "control_id": "AU-2", "status": "implemented" }, { "framework": "NIST", "control_id": "AC-5", "status": "implemented" }, { "framework": "NIST", "control_id": "SC-13", "status": "implemented" } ] }, "metadata": { "authors": [ { "name": "Meridian Compliance Team", "email": "compliance@meridian.example" } ], "license": "Proprietary", "tags": [ "financial", "banking", "brokerage", "aml", "compliance" ] } } ``` --- # Financial Profile Compatibility This document tracks compatibility between Financial Profile versions and ADL specification versions. ## Compatibility Matrix[​](#compatibility-matrix "Direct link to Compatibility Matrix") | Profile Version | ADL Versions | Status | Notes | | --------------- | ------------ | ------ | --------------- | | 1.0 | 0.3.x | Draft | Initial release | ## Compatibility Policy[​](#compatibility-policy "Direct link to Compatibility Policy") * **Minor ADL updates** (e.g., 0.1.0 -> 0.1.1): Profile remains compatible * **Major ADL updates** (e.g., 0.1.x -> 1.0.0): Profile compatibility will be evaluated; new profile version released if needed * **Breaking profile changes**: Require new major profile version ## Migration Guides[​](#migration-guides "Direct link to Migration Guides") *No migrations yet. This section will document how to upgrade between profile versions.* --- # Financial Profile | | | | --------------------- | ------------------------------- | | **Identifier** | `urn:adl:profile:financial:1.0` | | **Status** | Draft | | **ADL Compatibility** | 0.3.x | note This profile is in draft status. The specification is stable for early adoption, but minor changes may occur before 1.0. Regulatory Disclaimer This profile does not constitute legal, regulatory, or compliance advice. It has not been reviewed or endorsed by the PCI Security Standards Council, the SEC, FINRA, the FTC, or any regulatory body. Compliance with PCI-DSS requires a Qualified Security Assessor (QSA) assessment. Compliance with SOX requires audit by a registered public accounting firm. ## Overview[​](#overview "Direct link to Overview") The Financial Profile extends ADL for financial services and banking environments. It adds members for financial data classification, transaction controls, regulatory scope declarations, and risk management. This profile addresses requirements from PCI-DSS v4.0, SOX, GLBA, Basel III/IV, FINRA, SEC regulations, DORA, MiFID II, and AML/KYC frameworks. This profile is designed to compose with the [Governance Profile](/profiles/governance/overview.md). Organizations **SHOULD** declare both profiles for full enterprise financial compliance coverage. ## Use Cases[​](#use-cases "Direct link to Use Cases") * Trade compliance monitoring agents * AML/KYC screening agents * Risk analysis and assessment agents * Fraud detection systems * Regulatory reporting agents * Customer service agents for financial institutions * Algorithmic trading oversight agents ## Quick Start[​](#quick-start "Direct link to Quick Start") Add the Financial Profile to your ADL document — minimum viable declaration: ``` { "adl_spec": "0.3.0", "name": "Transaction Monitor", "description": "Monitors transactions for compliance violations.", "version": "1.0.0", "profiles": ["urn:adl:profile:financial:1.0"], "data_classification": { "sensitivity": "confidential", "categories": ["financial"], "financial": { "data_types": ["transaction_data"] } }, "financial_data_handling": {} } ``` ## Additional Members[​](#additional-members "Direct link to Additional Members") The Financial Profile adds the following top-level members: | Member | Required | Description | | ------------------------------- | ------------ | ---------------------------------------------------------------------------- | | `data_classification.financial` | **REQUIRED** | Financial data types (composable; extends core `data_classification`) | | `financial_data_handling` | **REQUIRED** | PCI scope, data residency | | `transaction_controls` | Optional | Transaction limits, pre-execution checks, kill switch, segregation of duties | | `regulatory_scope` | Optional | Applicable regulations, jurisdictions, record retention | | `financial_risk_management` | Optional | Model risk (SR 11-7), AML controls, operational risk | See the [full specification](/profiles/financial/specification.md) for detailed member definitions. ## Regulatory Foundation[​](#regulatory-foundation "Direct link to Regulatory Foundation") This profile maps requirements from: * **PCI-DSS v4.0** — Payment card data security * **SOX** (Sarbanes-Oxley) — Internal controls, audit trails, segregation of duties * **GLBA** (Gramm-Leach-Bliley) — Financial privacy, NPI safeguards * **Basel III/IV** — Capital adequacy, operational risk * **FINRA** — Broker-dealer supervision, AI agent oversight * **SEC** — Securities regulations, MNPI controls * **DORA** — EU digital operational resilience * **MiFID II** — Algorithmic trading controls, kill switches, record retention * **BSA/AML** — Anti-money laundering, suspicious activity reporting * **FFIEC** — IT examination, model risk management (SR 11-7) --- # Financial Profile Specification | | | | --------------------- | ------------------------------- | | **Identifier** | `urn:adl:profile:financial:1.0` | | **Status** | Draft | | **ADL Compatibility** | 0.3.x | Regulatory Disclaimer This profile is provided as a technical specification in DRAFT status and does not constitute legal, regulatory, or compliance advice. It has not been reviewed or endorsed by the PCI Security Standards Council, the SEC, FINRA, the FTC, or any regulatory body. Organizations MUST NOT rely on this profile as their sole basis for regulatory compliance. Compliance with PCI-DSS, SOX, GLBA, or any other financial regulatory framework requires qualified professional assessment specific to your organization's circumstances. This profile does not substitute for a PCI-DSS assessment by a Qualified Security Assessor (QSA) or a SOX audit by a registered public accounting firm. ## 1. Introduction[​](#1-introduction "Direct link to 1. Introduction") The Financial Profile extends ADL for financial services environments. It adds members for financial data classification and handling, transaction controls, regulatory scope declarations, and financial risk management. This profile addresses requirements from PCI-DSS v4.0, SOX, GLBA, Basel III/IV, FINRA, SEC regulations, DORA, MiFID II, and AML/KYC frameworks. When this profile is declared in an ADL document's `profiles` array, the document **MUST** satisfy all requirements defined in this specification. This profile is designed to compose with the Governance Profile. Organizations **SHOULD** declare both profiles for full enterprise financial compliance coverage. *** ## 2. Additional Members[​](#2-additional-members "Direct link to 2. Additional Members") ### 2.1 financial\_data\_handling[​](#21-financial_data_handling "Direct link to 2.1 financial_data_handling") **REQUIRED** when using this profile. An object containing financial data handling configuration. | Member | Type | Required | Description | | --------------- | ------ | -------- | ------------------------------------------ | | pci\_scope | object | OPTIONAL | PCI-DSS scope declaration | | data\_residency | array | OPTIONAL | Jurisdictional data residency requirements | note Financial data types have moved to the composable member (Section 2.5). This enables consistent data classification across profiles and reuse within tools and resources. #### pci\_scope[​](#pci_scope "Direct link to pci_scope") When present, **MUST** be an object containing: | Member | Type | Required | Description | | ---------------------- | ------ | -------- | --------------------------------------------------------- | | in\_scope | bool | REQUIRED | Whether agent operates in the cardholder data environment | | saq\_type | string | OPTIONAL | Self-Assessment Questionnaire type | | tokenization\_required | bool | OPTIONAL | Whether tokenization is required for data access | #### data\_residency[​](#data_residency "Direct link to data_residency") When present, **MUST** be an array of objects containing: | Member | Type | Required | Description | | ------------ | ------ | -------- | ---------------------------------------------------- | | jurisdiction | string | REQUIRED | ISO 3166-1 country code or region (e.g., `US`, `EU`) | | regulation | string | OPTIONAL | Governing regulation (e.g., `GLBA`, `DORA`, `GDPR`) | *** ### 2.2 transaction\_controls[​](#22-transaction_controls "Direct link to 2.2 transaction_controls") **OPTIONAL.** An object containing controls for agents that execute or influence financial transactions. | Member | Type | Required | Description | | ------------------------ | ------ | -------- | ------------------------------------ | | transaction\_limits | object | OPTIONAL | Operational boundaries | | pre\_execution\_controls | object | OPTIONAL | Pre-trade/pre-transaction safeguards | | kill\_switch | object | OPTIONAL | Emergency stop configuration | | segregation\_of\_duties | object | OPTIONAL | SOX/PCI duty separation requirements | #### transaction\_limits[​](#transaction_limits "Direct link to transaction_limits") When present, **MAY** contain: | Member | Type | Description | | ------------------- | ------ | -------------------------------- | | max\_single\_amount | number | Maximum single transaction value | | max\_daily\_volume | number | Maximum daily aggregate volume | | currency | string | ISO 4217 currency code | #### pre\_execution\_controls[​](#pre_execution_controls "Direct link to pre_execution_controls") When present, **MAY** contain: | Member | Type | Description | | ------------------------- | ------ | ----------------------------------------- | | enabled | bool | Whether pre-execution checks are active | | price\_tolerance\_pct | number | Maximum price deviation percentage | | throttle\_per\_second | number | Maximum executions per second | | requires\_approval\_above | number | Amount threshold requiring human approval | #### kill\_switch[​](#kill_switch "Direct link to kill_switch") When present, **MAY** contain: | Member | Type | Description | | --------------------- | ----- | -------------------------------------- | | enabled | bool | Whether kill switch is configured | | trigger\_conditions | array | Conditions that trigger automatic halt | | notification\_targets | array | Contacts notified on trigger | #### segregation\_of\_duties[​](#segregation_of_duties "Direct link to segregation_of_duties") When present, **MAY** contain: | Member | Type | Description | | ------------------- | ------ | ------------------------------------------- | | enabled | bool | Whether segregation is enforced | | restricted\_actions | array | Actions that require separate authorization | | approval\_role | string | Role that provides secondary authorization | *** ### 2.3 regulatory\_scope[​](#23-regulatory_scope "Direct link to 2.3 regulatory_scope") **OPTIONAL.** An object declaring which financial regulations apply to this agent. | Member | Type | Required | Description | | ----------------------- | ------ | ------------------------ | --------------------------------- | | applicable\_regulations | array | REQUIRED (within member) | Financial regulations that apply | | jurisdictions | array | OPTIONAL | Regulatory jurisdictions | | reporting\_obligations | object | OPTIONAL | Regulatory reporting requirements | | record\_retention | object | OPTIONAL | Record keeping requirements | #### applicable\_regulations[​](#applicable_regulations "Direct link to applicable_regulations") **MUST** be a non-empty array. Each item **MUST** be one of: * `PCI_DSS_V4` — Payment Card Industry Data Security Standard v4.0 * `SOX` — Sarbanes-Oxley Act * `GLBA` — Gramm-Leach-Bliley Act * `BASEL_III` — Basel III Capital Framework * `FINRA` — Financial Industry Regulatory Authority rules * `SEC_REG` — SEC regulations * `DORA` — EU Digital Operational Resilience Act * `MIFID_II` — Markets in Financial Instruments Directive II * `BSA_AML` — Bank Secrecy Act / Anti-Money Laundering * `EU_AMLD` — EU Anti-Money Laundering Directive #### reporting\_obligations[​](#reporting_obligations "Direct link to reporting_obligations") When present, **MAY** contain: | Member | Type | Description | | ----------- | ------ | --------------------------------------------------------------------------- | | authorities | array | Regulatory authorities to report to | | frequency | string | Reporting frequency: `real_time`, `daily`, `monthly`, `quarterly`, `annual` | #### record\_retention[​](#record_retention "Direct link to record_retention") When present, **MAY** contain: | Member | Type | Description | | -------------------- | ------ | ---------------------------------------- | | min\_retention\_days | number | Minimum record retention in days | | tamper\_proof | bool | Whether tamper-proof storage is required | | format | string | Required record format | *** ### 2.4 financial\_risk\_management[​](#24-financial_risk_management "Direct link to 2.4 financial_risk_management") **OPTIONAL.** An object containing risk management controls for financial agents. | Member | Type | Required | Description | | ----------------- | ------ | -------- | --------------------------------------- | | model\_risk | object | OPTIONAL | Model risk management (SR 11-7 / FFIEC) | | aml\_controls | object | OPTIONAL | Anti-money laundering controls | | operational\_risk | object | OPTIONAL | Operational risk classification | #### model\_risk[​](#model_risk "Direct link to model_risk") When present, **MAY** contain: | Member | Type | Description | | ------------- | ------ | --------------------------------------------- | | tier | string | Model risk tier: `tier_1`, `tier_2`, `tier_3` | | validated\_by | string | Validation entity | | validated\_at | string | ISO 8601 timestamp | | methodology | string | Validation methodology used | #### aml\_controls[​](#aml_controls "Direct link to aml_controls") When present, **MAY** contain: | Member | Type | Description | | ------------------- | ------ | ---------------------------------- | | screening\_required | bool | Whether AML screening is required | | monitoring\_level | string | `real_time`, `daily`, `periodic` | | kyc\_refresh\_days | number | Maximum days between KYC refreshes | #### operational\_risk[​](#operational_risk "Direct link to operational_risk") When present, **MAY** contain: | Member | Type | Description | | ---------------- | ------ | --------------------------------------------- | | category | string | `low`, `medium`, `high`, `critical` | | assessed\_by | string | Entity that performed the assessment | | assessed\_at | string | ISO 8601 timestamp | | capital\_reserve | bool | Whether operational risk capital is allocated | *** ### 2.5 data\_classification Extension[​](#25-data_classification-extension "Direct link to 2.5 data_classification Extension") This profile extends the core ADL `data_classification` member (Spec §10.4) with a `financial` sub-object for financial data type classification. **REQUIRED** when using this profile. The `data_classification` member **MUST** be present with a `financial` sub-object. The `data_classification.categories` array **MUST** include `financial`. #### financial[​](#financial "Direct link to financial") An object containing financial-specific data classification. When present, **MUST** contain: | Member | Type | Required | Description | | --------------- | ----- | -------- | ---------------------------------------------------- | | data\_types | array | REQUIRED | Types of financial data handled | | pci\_applicable | bool | OPTIONAL | Whether PCI-DSS scope applies to this classification | #### data\_types[​](#data_types "Direct link to data_types") **MUST** be a non-empty array. Each item **MUST** be one of: * `cardholder_data` — Primary Account Number, cardholder name, expiration date, service code * `sensitive_auth_data` — Full track data, CAV2/CVC2/CVV2/CID, PINs (must NEVER be stored post-authorization) * `nonpublic_personal_info` — NPI under GLBA: SSNs, account numbers, income, credit history * `transaction_data` — Transaction records, trade data, order flow * `market_data` — Market prices, indices, reference data * `financial_reports` — Financial statements, regulatory filings, audit reports * `material_nonpublic_info` — MNPI under SEC insider trading regulations Example: ``` { "data_classification": { "sensitivity": "confidential", "categories": ["pii", "financial"], "retention": { "min_days": 1825 }, "handling": { "encryption_required": true, "logging_required": true }, "financial": { "data_types": ["transaction_data", "nonpublic_personal_info"], "pci_applicable": false } } } ``` *** ## 3. Compliance Mapping[​](#3-compliance-mapping "Direct link to 3. Compliance Mapping") | ADL / Profile Section | Regulatory Controls | | --------------------------------------------- | --------------------------------------------------------- | | data\_classification.financial.data\_types | PCI-DSS Req 3, 4; GLBA Safeguards Rule; NIST 800-53 SC-16 | | financial\_data\_handling.pci\_scope | PCI-DSS Req 1, 2 (CDE scoping); NIST 800-53 SC-7 | | transaction\_controls.transaction\_limits | MiFID II Art. 17; FINRA Rule 3110 | | transaction\_controls.kill\_switch | MiFID II Art. 17(1); ESMA Guidelines | | transaction\_controls.segregation\_of\_duties | SOX §302, §404; NIST 800-53 AC-5 | | regulatory\_scope.record\_retention | PCI-DSS Req 10.7; MiFID II Art. 25; SOX §802 | | financial\_risk\_management.model\_risk | SR 11-7; FFIEC IT Examination; Basel III Pillar 2 | | financial\_risk\_management.aml\_controls | BSA §5318; EU 6AMLD; FINRA Rule 3310 | | security.authentication | PCI-DSS Req 8; NIST 800-53 IA-2, IA-5 | | security.encryption | PCI-DSS Req 3.5, 4.1; NIST 800-53 SC-8, SC-13 | | governance.audit\_trail | PCI-DSS Req 10; SOX §404; NIST 800-53 AU-2, AU-6 | *** ## 4. Example[​](#4-example "Direct link to 4. Example") Complete Example This example demonstrates a complete agent definition using this profile. financial-compliance-agent.json ``` { "$schema": "https://adl-spec.org/0.3/schema.json", "adl_spec": "0.3.0", "name": "Financial Compliance Monitor", "description": "Monitors both banking activity (wires, deposits) and brokerage activity (securities trading) across a universal financial institution for AML, fraud, and regulatory compliance.", "version": "1.0.0", "profiles": [ "urn:adl:profile:financial:1.0" ], "lifecycle": { "status": "active", "effective_date": "2026-01-01T00:00:00Z" }, "provider": { "name": "Meridian Financial Group", "url": "https://meridian.example", "contact": "compliance@meridian.example" }, "model": { "capabilities": [ "function_calling" ] }, "tools": [ { "name": "screen_wire_transfers", "description": "Screen banking wire and ACH transfers for BSA/AML and sanctions risk", "parameters": { "type": "object", "properties": { "account_id": { "type": "string" }, "lookback_days": { "type": "integer", "default": 30 } }, "required": [ "account_id" ] }, "read_only": true }, { "name": "surveil_trades", "description": "Surveil securities trading activity for market manipulation and insider trading", "parameters": { "type": "object", "properties": { "account_id": { "type": "string" }, "instrument": { "type": "string" } }, "required": [ "account_id" ] }, "read_only": true }, { "name": "file_sar", "description": "File a Suspicious Activity Report with FinCEN (covers both banking and brokerage activity)", "parameters": { "type": "object", "properties": { "subject_ids": { "type": "array", "items": { "type": "string" } }, "activity_type": { "type": "string", "enum": [ "banking", "securities" ] }, "narrative": { "type": "string" } }, "required": [ "subject_ids", "narrative" ] }, "requires_confirmation": true } ], "permissions": { "network": { "allowed_hosts": [ "core-banking.meridian.example", "market-surveillance.meridian.example", "fincen.gov" ], "allowed_protocols": [ "https" ], "deny_private": true }, "filesystem": { "allowed_paths": [ { "path": "/data/banking/**", "access": "read" }, { "path": "/data/trading/**", "access": "read" }, { "path": "/data/reports/**", "access": "read_write" } ] } }, "security": { "authentication": { "type": "mtls", "required": true }, "encryption": { "in_transit": { "required": true, "min_version": "1.3" }, "at_rest": { "required": true, "algorithm": "AES-256-GCM" } } }, "data_classification": { "sensitivity": "confidential", "categories": [ "pii", "financial" ], "retention": { "min_days": 1825 }, "handling": { "encryption_required": true, "logging_required": true }, "financial": { "data_types": [ "transaction_data", "nonpublic_personal_info", "market_data", "material_nonpublic_info" ], "pci_applicable": false } }, "financial_data_handling": { "pci_scope": { "in_scope": false }, "data_residency": [ { "jurisdiction": "US", "regulation": "GLBA" }, { "jurisdiction": "EU", "regulation": "MIFID_II" } ] }, "transaction_controls": { "transaction_limits": { "max_single_amount": 10000000, "currency": "USD" }, "pre_execution_controls": { "enabled": true, "price_tolerance_pct": 2, "requires_approval_above": 1000000 }, "kill_switch": { "enabled": true, "trigger_conditions": [ "error_rate_threshold", "anomaly_detection" ], "notification_targets": [ "compliance-team@meridian.example" ] }, "segregation_of_duties": { "enabled": true, "restricted_actions": [ "file_sar" ], "approval_role": "Compliance Officer" } }, "regulatory_scope": { "applicable_regulations": [ "GLBA", "BSA_AML", "BASEL_III", "FINRA", "SEC_REG", "MIFID_II" ], "jurisdictions": [ { "jurisdiction": "US", "regulation": "BSA_AML" }, { "jurisdiction": "EU", "regulation": "MIFID_II" } ], "record_retention": { "min_retention_days": 1825, "tamper_proof": true } }, "financial_risk_management": { "model_risk": { "tier": "tier_2", "validated_by": "Model Risk Committee", "validated_at": "2025-12-15T00:00:00Z", "methodology": "Champion-challenger with backtesting" }, "aml_controls": { "screening_required": true, "monitoring_level": "real_time", "kyc_refresh_days": 365 }, "operational_risk": { "category": "high", "assessed_by": "Operational Risk Committee", "assessed_at": "2025-12-15T00:00:00Z", "capital_reserve": true } }, "metadata": { "authors": [ { "name": "Meridian Compliance Team", "email": "compliance@meridian.example" } ], "license": "Proprietary", "tags": [ "financial", "banking", "brokerage", "aml", "compliance" ] } } ``` *** ## 5. Validation Rules[​](#5-validation-rules "Direct link to 5. Validation Rules") Validation Required Implementations validating against this profile **MUST** enforce the following rules. Non-conforming documents should be rejected. | Rule | Description | | ------ | ----------------------------------------------------------------------------------------------------------------------- | | FIN-01 | `financial_data_handling` MUST be present | | FIN-02 | `data_classification.financial.data_types` MUST be a non-empty array of valid data types | | FIN-03 | If `pci_scope.in_scope` is true, `data_classification.financial.data_types` MUST include `cardholder_data` | | FIN-04 | `transaction_controls.transaction_limits.currency` MUST be valid ISO 4217 if present | | FIN-05 | `transaction_controls.pre_execution_controls.price_tolerance_pct` MUST be > 0 and <= 100 if present | | FIN-06 | `regulatory_scope.applicable_regulations` MUST contain valid regulation identifiers if present | | FIN-07 | `data_residency[*].jurisdiction` MUST be valid ISO 3166-1 code if present | | FIN-08 | All timestamps MUST be valid ISO 8601 | | FIN-09 | `financial_risk_management.model_risk.tier` MUST be a valid tier if present | | FIN-10 | `financial_risk_management.aml_controls.monitoring_level` MUST be a valid level if present | | FIN-11 | `record_retention.min_retention_days` MUST be >= 1825 (5 years) when `MIFID_II` is in `applicable_regulations` | | FIN-12 | `kill_switch.enabled` MUST be true when `MIFID_II` is in `applicable_regulations` and `transaction_controls` is present | | FIN-13 | `data_classification` MUST be present with a `financial` sub-object | | FIN-14 | `data_classification.categories` MUST include `financial` | --- # Governance Profile Examples ## Tier 2[​](#tier-2 "Direct link to Tier 2") ### Compliance Review Agent[​](#compliance-review-agent "Direct link to Compliance Review Agent") A document review agent with conditional autonomy. Requires human approval for compliance determinations affecting regulatory filings. * YAML * JSON compliance-agent.adl.yaml ``` $schema: https://adl-spec.org/profiles/governance/1.0/schema.json adl_spec: 0.3.0 name: Compliance Review Agent description: Reviews documents for regulatory compliance against SOC 2 Type II controls. Flags potential violations and recommends remediation actions. version: 2.0.0 profiles: - urn:adl:profile:governance:1.0 lifecycle: status: active effective_date: 2026-01-15T00:00:00Z data_classification: sensitivity: confidential categories: - regulatory provider: name: Acme Compliance url: https://compliance.acme.example contact: compliance@acme.example model: capabilities: - function_calling tools: - name: review_document description: Review a document against compliance controls parameters: type: object properties: document_id: type: string framework: type: string required: - document_id - framework read_only: true - name: generate_report description: Generate a compliance report parameters: type: object properties: review_id: type: string format: type: string enum: - pdf - json - html required: - review_id permissions: network: allowed_hosts: - docs.acme.example - api.acme.example allowed_protocols: - https deny_private: true filesystem: allowed_paths: - path: /data/documents/** access: read - path: /data/reports/** access: read_write security: authentication: type: oauth2 required: true scopes: - compliance:read - compliance:write encryption: in_transit: required: true min_version: "1.2" autonomy: tier: 2 basis: Agent reviews documents independently but requires human approval for compliance determinations affecting regulatory filings. classified_by: AI Ethics Committee classified_at: 2026-01-10T00:00:00Z compliance_framework: primary_framework: SOC2_TYPE_II audit_dates: last_audit: 2025-11-15T00:00:00Z next_audit: 2026-11-15T00:00:00Z risk_classification: level: medium autonomy_level: L3 assessed_by: AI Ethics Committee assessed_at: 2026-01-10T00:00:00Z rationale: Agent processes sensitive compliance data with conditional autonomy within defined review boundaries safety_reviews: required: true frequency: quarterly last_review: 2026-01-15T00:00:00Z review_board: AI Safety Board human_oversight: level: on_exception role: Compliance Officer triggers: - Compliance determination affecting regulatory filing - Document classified as restricted sensitivity - Remediation recommendation with estimated cost exceeding $50,000 response_time_minutes: 60 intervention_model: approve_reject incident_response: policy_documented: true last_tested: 2026-02-01T00:00:00Z disclosure: required: true known_limitations: - May produce inaccurate regulatory citations for jurisdictions outside the US and EU - Not trained on regulatory guidance published after 2025-12-01 prohibited_uses: - Final regulatory determination without human review - Legal advice to external parties reporting_contact: mailto:ai-issues@acme.example governance: lifecycle_governance: transition_policy: requires_approval: true approvers: - security-team - compliance-lead approval_type: all last_transition: from_status: draft to_status: active approved_by: compliance-lead approved_at: 2026-01-15T00:00:00Z reason: Passed SOC2 audit, security review, and Tier 2 governance validation ownership: owner: Compliance Team delegate: Security Team contact: compliance@acme.example user_escalation_contact: mailto:ai-support@acme.example decision_boundaries: - decision_type: regulatory_filing owner: human_only rationale: Regulatory filings require human sign-off per SOC2 CC6.1 - decision_type: document_review owner: agent rationale: Routine document reviews are within the agent's authorized scope - decision_type: remediation_recommendation owner: human_in_loop rationale: Remediation actions may have budgetary implications approval_workflow: required: true approvers: - compliance-lead - security-lead approval_type: all audit_trail: enabled: true retention_days: 730 destination: s3://acme-audit-logs/compliance-agent/ governance_record_ref: https://gorvnd.acme.example/agents/compliance-review/governance-record metadata: authors: - name: Compliance Team email: compliance@acme.example license: Proprietary documentation: https://docs.acme.example/agents/compliance-review tags: - compliance - soc2 - enterprise ``` compliance-agent.adl.json ``` { "$schema": "https://adl-spec.org/profiles/governance/1.0/schema.json", "adl_spec": "0.3.0", "name": "Compliance Review Agent", "description": "Reviews documents for regulatory compliance against SOC 2 Type II controls. Flags potential violations and recommends remediation actions.", "version": "2.0.0", "profiles": [ "urn:adl:profile:governance:1.0" ], "lifecycle": { "status": "active", "effective_date": "2026-01-15T00:00:00Z" }, "data_classification": { "sensitivity": "confidential", "categories": [ "regulatory" ] }, "provider": { "name": "Acme Compliance", "url": "https://compliance.acme.example", "contact": "compliance@acme.example" }, "model": { "capabilities": [ "function_calling" ] }, "tools": [ { "name": "review_document", "description": "Review a document against compliance controls", "parameters": { "type": "object", "properties": { "document_id": { "type": "string" }, "framework": { "type": "string" } }, "required": [ "document_id", "framework" ] }, "read_only": true }, { "name": "generate_report", "description": "Generate a compliance report", "parameters": { "type": "object", "properties": { "review_id": { "type": "string" }, "format": { "type": "string", "enum": [ "pdf", "json", "html" ] } }, "required": [ "review_id" ] } } ], "permissions": { "network": { "allowed_hosts": [ "docs.acme.example", "api.acme.example" ], "allowed_protocols": [ "https" ], "deny_private": true }, "filesystem": { "allowed_paths": [ { "path": "/data/documents/**", "access": "read" }, { "path": "/data/reports/**", "access": "read_write" } ] } }, "security": { "authentication": { "type": "oauth2", "required": true, "scopes": [ "compliance:read", "compliance:write" ] }, "encryption": { "in_transit": { "required": true, "min_version": "1.2" } } }, "autonomy": { "tier": 2, "basis": "Agent reviews documents independently but requires human approval for compliance determinations affecting regulatory filings.", "classified_by": "AI Ethics Committee", "classified_at": "2026-01-10T00:00:00Z" }, "compliance_framework": { "primary_framework": "SOC2_TYPE_II", "audit_dates": { "last_audit": "2025-11-15T00:00:00Z", "next_audit": "2026-11-15T00:00:00Z" } }, "risk_classification": { "level": "medium", "autonomy_level": "L3", "assessed_by": "AI Ethics Committee", "assessed_at": "2026-01-10T00:00:00Z", "rationale": "Agent processes sensitive compliance data with conditional autonomy within defined review boundaries" }, "safety_reviews": { "required": true, "frequency": "quarterly", "last_review": "2026-01-15T00:00:00Z", "review_board": "AI Safety Board" }, "human_oversight": { "level": "on_exception", "role": "Compliance Officer", "triggers": [ "Compliance determination affecting regulatory filing", "Document classified as restricted sensitivity", "Remediation recommendation with estimated cost exceeding $50,000" ], "response_time_minutes": 60, "intervention_model": "approve_reject" }, "incident_response": { "policy_documented": true, "last_tested": "2026-02-01T00:00:00Z" }, "disclosure": { "required": true, "known_limitations": [ "May produce inaccurate regulatory citations for jurisdictions outside the US and EU", "Not trained on regulatory guidance published after 2025-12-01" ], "prohibited_uses": [ "Final regulatory determination without human review", "Legal advice to external parties" ], "reporting_contact": "mailto:ai-issues@acme.example" }, "governance": { "lifecycle_governance": { "transition_policy": { "requires_approval": true, "approvers": [ "security-team", "compliance-lead" ], "approval_type": "all" }, "last_transition": { "from_status": "draft", "to_status": "active", "approved_by": "compliance-lead", "approved_at": "2026-01-15T00:00:00Z", "reason": "Passed SOC2 audit, security review, and Tier 2 governance validation" } }, "ownership": { "owner": "Compliance Team", "delegate": "Security Team", "contact": "compliance@acme.example", "user_escalation_contact": "mailto:ai-support@acme.example", "decision_boundaries": [ { "decision_type": "regulatory_filing", "owner": "human_only", "rationale": "Regulatory filings require human sign-off per SOC2 CC6.1" }, { "decision_type": "document_review", "owner": "agent", "rationale": "Routine document reviews are within the agent's authorized scope" }, { "decision_type": "remediation_recommendation", "owner": "human_in_loop", "rationale": "Remediation actions may have budgetary implications" } ] }, "approval_workflow": { "required": true, "approvers": [ "compliance-lead", "security-lead" ], "approval_type": "all" }, "audit_trail": { "enabled": true, "retention_days": 730, "destination": "s3://acme-audit-logs/compliance-agent/" } }, "governance_record_ref": "https://gorvnd.acme.example/agents/compliance-review/governance-record", "metadata": { "authors": [ { "name": "Compliance Team", "email": "compliance@acme.example" } ], "license": "Proprietary", "documentation": "https://docs.acme.example/agents/compliance-review", "tags": [ "compliance", "soc2", "enterprise" ] } } ``` ### Key Governance Fields[​](#key-governance-fields "Direct link to Key Governance Fields") | Field | Value | Why | | ------------------------------------- | ------------------ | ----------------------------------------------------------- | | `autonomy.tier` | `2` | Agent acts within boundaries; human oversight on exceptions | | `human_oversight.triggers` | 3 triggers defined | Required at Tier 2+ | | `incident_response.policy_documented` | `true` | Required at Tier 2+ | | `disclosure.required` | `true` | Required at Tier 2+ | | `governance_record_ref` | URI | Links to operational detail in registry | ## Tier 3[​](#tier-3 "Direct link to Tier 3") ### Autonomous Risk Assessment Agent[​](#autonomous-risk-assessment-agent "Direct link to Autonomous Risk Assessment Agent") A fully autonomous agent that continuously scans portfolios, classifies risks, and generates regulatory reports without human initiation. * YAML * JSON risk-assessment-agent.adl.yaml ``` $schema: https://adl-spec.org/profiles/governance/1.0/schema.json adl_spec: 0.3.0 name: Autonomous Risk Assessment Agent description: Performs continuous risk assessment across the enterprise portfolio. Independently identifies, classifies, and prioritizes risks. Escalates critical findings and generates regulatory reports without human initiation. version: 1.0.0 profiles: - urn:adl:profile:governance:1.0 lifecycle: status: active effective_date: 2026-02-01T00:00:00Z data_classification: sensitivity: restricted categories: - regulatory - financial provider: name: Acme Risk Management url: https://risk.acme.example contact: risk-platform@acme.example model: capabilities: - function_calling tools: - name: scan_portfolio description: Scan the enterprise portfolio for risk indicators parameters: type: object properties: scope: type: string enum: - full - incremental since: type: string format: date-time required: - scope read_only: true - name: classify_risk description: Classify an identified risk by severity and category parameters: type: object properties: finding_id: type: string evidence: type: array items: type: string required: - finding_id - name: generate_risk_report description: Generate a risk assessment report for regulatory submission parameters: type: object properties: report_type: type: string enum: - quarterly - annual - incident period_start: type: string format: date period_end: type: string format: date required: - report_type requires_confirmation: true permissions: network: allowed_hosts: - risk-api.acme.example - data.acme.example - notifications.acme.example allowed_protocols: - https deny_private: true filesystem: allowed_paths: - path: /data/risk-assessments/** access: read_write - path: /data/portfolio/** access: read - path: /data/regulatory/** access: read denied_paths: - /data/risk-assessments/**/drafts resource_limits: max_memory_mb: 2048 max_duration_sec: 3600 security: authentication: type: mtls required: true encryption: in_transit: required: true min_version: "1.3" at_rest: required: true algorithm: AES-256-GCM autonomy: tier: 3 basis: Agent operates continuously without human initiation. Independently scans portfolio, classifies risks, and generates reports. Human oversight is periodic review of outputs, not real-time approval of actions. classified_by: Chief Risk Officer classified_at: 2026-01-20T00:00:00Z compliance_framework: primary_framework: NIST_800_53 audit_dates: last_audit: 2025-12-01T00:00:00Z next_audit: 2026-06-01T00:00:00Z risk_classification: level: high autonomy_level: L4 assessed_by: Chief Risk Officer assessed_at: 2026-01-20T00:00:00Z rationale: High autonomy agent processing restricted financial and regulatory data with independent decision-making authority safety_reviews: required: true frequency: monthly last_review: 2026-02-15T00:00:00Z review_board: AI Safety Board human_oversight: level: periodic role: Risk Management Director triggers: - Risk classified as critical severity - Finding implicates a regulatory filing deadline within 30 days - Agent detects potential fraud indicators - Cumulative risk score for any business unit exceeds threshold - description: Large remediation spend when: cost_usd_over: 5000 response_time_minutes: 30 intervention_model: approve_reject incident_response: policy_documented: true last_tested: 2026-02-10T00:00:00Z evaluation_attestation: result: passed evaluator: External AI Audit Partners LLP evaluation_date: 2026-01-25T00:00:00Z methodology: third_party_audit expires_at: 2026-07-25T00:00:00Z disclosure: required: true known_limitations: - Risk classifications are probabilistic and may produce false positives - Does not assess risks in jurisdictions outside US, EU, and Singapore - Cannot evaluate risks requiring physical inspection or site visits prohibited_uses: - Sole basis for regulatory submission without human review of generated reports - Direct communication of risk findings to regulators without human approval user_responsibilities: - Review all critical risk classifications before acting on them - Validate regulatory report accuracy before submission reporting_contact: mailto:risk-ai-issues@acme.example disclosure_version: "1.0" governance: lifecycle_governance: transition_policy: requires_approval: true approvers: - cro - ciso - ai-safety-board approval_type: all notice_period_days: 30 ownership: owner: Risk Management Team delegate: Security Operations contact: risk-platform@acme.example user_escalation_contact: mailto:risk-support@acme.example decision_boundaries: - decision_type: risk_classification owner: agent rationale: Agent classifies risks independently; periodic human review validates accuracy - decision_type: regulatory_report_generation owner: human_in_loop rationale: Reports require human validation before regulatory submission - decision_type: risk_remediation_action owner: human_only rationale: Remediation actions have operational and budgetary impact requiring human authorization - decision_type: external_communication owner: human_only rationale: All external communications require human approval audit_trail: enabled: true retention_days: 2555 destination: s3://acme-audit-logs/risk-assessment-agent/ governance_record_ref: https://gorvnd.acme.example/agents/risk-assessment/governance-record anomaly_baseline: expected_tools: - name: assess_risk share: 0.5 - name: lookup_regulation share: 0.3 - name: generate_report share: 0.2 cost_per_session_usd: min: 0.05 max: 8 data_classes: - financial - regulatory metadata: authors: - name: Risk Management Team email: risk-platform@acme.example license: Proprietary documentation: https://docs.acme.example/agents/risk-assessment tags: - risk - autonomous - enterprise - restricted ``` risk-assessment-agent.adl.json ``` { "$schema": "https://adl-spec.org/profiles/governance/1.0/schema.json", "adl_spec": "0.3.0", "name": "Autonomous Risk Assessment Agent", "description": "Performs continuous risk assessment across the enterprise portfolio. Independently identifies, classifies, and prioritizes risks. Escalates critical findings and generates regulatory reports without human initiation.", "version": "1.0.0", "profiles": [ "urn:adl:profile:governance:1.0" ], "lifecycle": { "status": "active", "effective_date": "2026-02-01T00:00:00Z" }, "data_classification": { "sensitivity": "restricted", "categories": [ "regulatory", "financial" ] }, "provider": { "name": "Acme Risk Management", "url": "https://risk.acme.example", "contact": "risk-platform@acme.example" }, "model": { "capabilities": [ "function_calling" ] }, "tools": [ { "name": "scan_portfolio", "description": "Scan the enterprise portfolio for risk indicators", "parameters": { "type": "object", "properties": { "scope": { "type": "string", "enum": [ "full", "incremental" ] }, "since": { "type": "string", "format": "date-time" } }, "required": [ "scope" ] }, "read_only": true }, { "name": "classify_risk", "description": "Classify an identified risk by severity and category", "parameters": { "type": "object", "properties": { "finding_id": { "type": "string" }, "evidence": { "type": "array", "items": { "type": "string" } } }, "required": [ "finding_id" ] } }, { "name": "generate_risk_report", "description": "Generate a risk assessment report for regulatory submission", "parameters": { "type": "object", "properties": { "report_type": { "type": "string", "enum": [ "quarterly", "annual", "incident" ] }, "period_start": { "type": "string", "format": "date" }, "period_end": { "type": "string", "format": "date" } }, "required": [ "report_type" ] }, "requires_confirmation": true } ], "permissions": { "network": { "allowed_hosts": [ "risk-api.acme.example", "data.acme.example", "notifications.acme.example" ], "allowed_protocols": [ "https" ], "deny_private": true }, "filesystem": { "allowed_paths": [ { "path": "/data/risk-assessments/**", "access": "read_write" }, { "path": "/data/portfolio/**", "access": "read" }, { "path": "/data/regulatory/**", "access": "read" } ], "denied_paths": [ "/data/risk-assessments/**/drafts" ] }, "resource_limits": { "max_memory_mb": 2048, "max_duration_sec": 3600 } }, "security": { "authentication": { "type": "mtls", "required": true }, "encryption": { "in_transit": { "required": true, "min_version": "1.3" }, "at_rest": { "required": true, "algorithm": "AES-256-GCM" } } }, "autonomy": { "tier": 3, "basis": "Agent operates continuously without human initiation. Independently scans portfolio, classifies risks, and generates reports. Human oversight is periodic review of outputs, not real-time approval of actions.", "classified_by": "Chief Risk Officer", "classified_at": "2026-01-20T00:00:00Z" }, "compliance_framework": { "primary_framework": "NIST_800_53", "audit_dates": { "last_audit": "2025-12-01T00:00:00Z", "next_audit": "2026-06-01T00:00:00Z" } }, "risk_classification": { "level": "high", "autonomy_level": "L4", "assessed_by": "Chief Risk Officer", "assessed_at": "2026-01-20T00:00:00Z", "rationale": "High autonomy agent processing restricted financial and regulatory data with independent decision-making authority" }, "safety_reviews": { "required": true, "frequency": "monthly", "last_review": "2026-02-15T00:00:00Z", "review_board": "AI Safety Board" }, "human_oversight": { "level": "periodic", "role": "Risk Management Director", "triggers": [ "Risk classified as critical severity", "Finding implicates a regulatory filing deadline within 30 days", "Agent detects potential fraud indicators", "Cumulative risk score for any business unit exceeds threshold", { "description": "Large remediation spend", "when": { "cost_usd_over": 5000 } } ], "response_time_minutes": 30, "intervention_model": "approve_reject" }, "incident_response": { "policy_documented": true, "last_tested": "2026-02-10T00:00:00Z" }, "evaluation_attestation": { "result": "passed", "evaluator": "External AI Audit Partners LLP", "evaluation_date": "2026-01-25T00:00:00Z", "methodology": "third_party_audit", "expires_at": "2026-07-25T00:00:00Z" }, "disclosure": { "required": true, "known_limitations": [ "Risk classifications are probabilistic and may produce false positives", "Does not assess risks in jurisdictions outside US, EU, and Singapore", "Cannot evaluate risks requiring physical inspection or site visits" ], "prohibited_uses": [ "Sole basis for regulatory submission without human review of generated reports", "Direct communication of risk findings to regulators without human approval" ], "user_responsibilities": [ "Review all critical risk classifications before acting on them", "Validate regulatory report accuracy before submission" ], "reporting_contact": "mailto:risk-ai-issues@acme.example", "disclosure_version": "1.0" }, "governance": { "lifecycle_governance": { "transition_policy": { "requires_approval": true, "approvers": [ "cro", "ciso", "ai-safety-board" ], "approval_type": "all", "notice_period_days": 30 } }, "ownership": { "owner": "Risk Management Team", "delegate": "Security Operations", "contact": "risk-platform@acme.example", "user_escalation_contact": "mailto:risk-support@acme.example", "decision_boundaries": [ { "decision_type": "risk_classification", "owner": "agent", "rationale": "Agent classifies risks independently; periodic human review validates accuracy" }, { "decision_type": "regulatory_report_generation", "owner": "human_in_loop", "rationale": "Reports require human validation before regulatory submission" }, { "decision_type": "risk_remediation_action", "owner": "human_only", "rationale": "Remediation actions have operational and budgetary impact requiring human authorization" }, { "decision_type": "external_communication", "owner": "human_only", "rationale": "All external communications require human approval" } ] }, "audit_trail": { "enabled": true, "retention_days": 2555, "destination": "s3://acme-audit-logs/risk-assessment-agent/" } }, "governance_record_ref": "https://gorvnd.acme.example/agents/risk-assessment/governance-record", "anomaly_baseline": { "expected_tools": [ { "name": "assess_risk", "share": 0.5 }, { "name": "lookup_regulation", "share": 0.3 }, { "name": "generate_report", "share": 0.2 } ], "cost_per_session_usd": { "min": 0.05, "max": 8 }, "data_classes": [ "financial", "regulatory" ] }, "metadata": { "authors": [ { "name": "Risk Management Team", "email": "risk-platform@acme.example" } ], "license": "Proprietary", "documentation": "https://docs.acme.example/agents/risk-assessment", "tags": [ "risk", "autonomous", "enterprise", "restricted" ] } } ``` ### Additional Tier 3 Requirements[​](#additional-tier-3-requirements "Direct link to Additional Tier 3 Requirements") | Field | Value | Why | | ---------------------------------- | ---------------- | ------------------------------------------------ | | `autonomy.tier` | `3` | Agent operates independently; periodic oversight | | `evaluation_attestation.result` | `passed` | Required at Tier 3 with `passed` result | | `evaluation_attestation.evaluator` | External auditor | Third-party evaluation | | `human_oversight.level` | `periodic` | Post-hoc review model | ## Composed with the Registry Profile[​](#composed-with-the-registry-profile "Direct link to Composed with the Registry Profile") Governance composes with other profiles via `allOf`. This composite example declares both `urn:adl:profile:governance:1.0` and `urn:adl:profile:registry:1.0`, combining governance members with the registry catalog members in a single document. * YAML * JSON composite/governance-registry-agent.adl.yaml ``` $schema: https://adl-spec.org/profiles/governance/1.0/schema.json adl_spec: 0.3.0 name: Compliance Review Agent description: Reviews documents for regulatory compliance against SOC 2 Type II controls. Flags potential violations and recommends remediation actions. version: 2.0.0 profiles: - urn:adl:profile:governance:1.0 - urn:adl:profile:registry:1.0 lifecycle: status: active effective_date: 2026-01-15T00:00:00Z data_classification: sensitivity: confidential categories: - regulatory provider: name: Acme Compliance url: https://compliance.acme.example contact: compliance@acme.example model: capabilities: - function_calling tools: - name: review_document description: Review a document against compliance controls parameters: type: object properties: document_id: type: string framework: type: string required: - document_id - framework read_only: true - name: generate_report description: Generate a compliance report parameters: type: object properties: review_id: type: string format: type: string enum: - pdf - json - html required: - review_id permissions: network: allowed_hosts: - docs.acme.example - api.acme.example allowed_protocols: - https deny_private: true filesystem: allowed_paths: - path: /data/documents/** access: read - path: /data/reports/** access: read_write security: authentication: type: oauth2 required: true scopes: - compliance:read - compliance:write encryption: in_transit: required: true min_version: "1.2" autonomy: tier: 2 basis: Agent reviews documents independently but requires human approval for compliance determinations affecting regulatory filings. classified_by: AI Ethics Committee classified_at: 2026-01-10T00:00:00Z compliance_framework: primary_framework: SOC2_TYPE_II audit_dates: last_audit: 2025-11-15T00:00:00Z next_audit: 2026-11-15T00:00:00Z risk_classification: level: medium autonomy_level: L3 assessed_by: AI Ethics Committee assessed_at: 2026-01-10T00:00:00Z rationale: Agent processes sensitive compliance data with conditional autonomy within defined review boundaries safety_reviews: required: true frequency: quarterly last_review: 2026-01-15T00:00:00Z review_board: AI Safety Board human_oversight: level: on_exception role: Compliance Officer triggers: - Compliance determination affecting regulatory filing - Document classified as restricted sensitivity - Remediation recommendation with estimated cost exceeding $50,000 response_time_minutes: 60 intervention_model: approve_reject incident_response: policy_documented: true last_tested: 2026-02-01T00:00:00Z disclosure: required: true known_limitations: - May produce inaccurate regulatory citations for jurisdictions outside the US and EU - Not trained on regulatory guidance published after 2025-12-01 prohibited_uses: - Final regulatory determination without human review - Legal advice to external parties reporting_contact: mailto:ai-issues@acme.example governance: lifecycle_governance: transition_policy: requires_approval: true approvers: - security-team - compliance-lead approval_type: all last_transition: from_status: draft to_status: active approved_by: compliance-lead approved_at: 2026-01-15T00:00:00Z reason: Passed SOC2 audit, security review, and Tier 2 governance validation ownership: owner: Compliance Team delegate: Security Team contact: compliance@acme.example user_escalation_contact: mailto:ai-support@acme.example decision_boundaries: - decision_type: regulatory_filing owner: human_only rationale: Regulatory filings require human sign-off per SOC2 CC6.1 - decision_type: document_review owner: agent rationale: Routine document reviews are within the agent's authorized scope - decision_type: remediation_recommendation owner: human_in_loop rationale: Remediation actions may have budgetary implications approval_workflow: required: true approvers: - compliance-lead - security-lead approval_type: all audit_trail: enabled: true retention_days: 730 destination: s3://acme-audit-logs/compliance-agent/ governance_record_ref: https://gorvnd.acme.example/agents/compliance-review/governance-record registry: catalog_id: urn:acme:agents:compliance-review:2.0.0 catalog_classification: - domain: compliance subdomain: document-review capability: soc2-review visibility: internal federation: registries: - https://registry.acme.example - https://enterprise-agents.example primary: https://registry.acme.example metadata: authors: - name: Compliance Team email: compliance@acme.example license: Proprietary documentation: https://docs.acme.example/agents/compliance-review tags: - compliance - soc2 - enterprise ``` composite/governance-registry-agent.adl.json ``` { "$schema": "https://adl-spec.org/profiles/governance/1.0/schema.json", "adl_spec": "0.3.0", "name": "Compliance Review Agent", "description": "Reviews documents for regulatory compliance against SOC 2 Type II controls. Flags potential violations and recommends remediation actions.", "version": "2.0.0", "profiles": [ "urn:adl:profile:governance:1.0", "urn:adl:profile:registry:1.0" ], "lifecycle": { "status": "active", "effective_date": "2026-01-15T00:00:00Z" }, "data_classification": { "sensitivity": "confidential", "categories": [ "regulatory" ] }, "provider": { "name": "Acme Compliance", "url": "https://compliance.acme.example", "contact": "compliance@acme.example" }, "model": { "capabilities": [ "function_calling" ] }, "tools": [ { "name": "review_document", "description": "Review a document against compliance controls", "parameters": { "type": "object", "properties": { "document_id": { "type": "string" }, "framework": { "type": "string" } }, "required": [ "document_id", "framework" ] }, "read_only": true }, { "name": "generate_report", "description": "Generate a compliance report", "parameters": { "type": "object", "properties": { "review_id": { "type": "string" }, "format": { "type": "string", "enum": [ "pdf", "json", "html" ] } }, "required": [ "review_id" ] } } ], "permissions": { "network": { "allowed_hosts": [ "docs.acme.example", "api.acme.example" ], "allowed_protocols": [ "https" ], "deny_private": true }, "filesystem": { "allowed_paths": [ { "path": "/data/documents/**", "access": "read" }, { "path": "/data/reports/**", "access": "read_write" } ] } }, "security": { "authentication": { "type": "oauth2", "required": true, "scopes": [ "compliance:read", "compliance:write" ] }, "encryption": { "in_transit": { "required": true, "min_version": "1.2" } } }, "autonomy": { "tier": 2, "basis": "Agent reviews documents independently but requires human approval for compliance determinations affecting regulatory filings.", "classified_by": "AI Ethics Committee", "classified_at": "2026-01-10T00:00:00Z" }, "compliance_framework": { "primary_framework": "SOC2_TYPE_II", "audit_dates": { "last_audit": "2025-11-15T00:00:00Z", "next_audit": "2026-11-15T00:00:00Z" } }, "risk_classification": { "level": "medium", "autonomy_level": "L3", "assessed_by": "AI Ethics Committee", "assessed_at": "2026-01-10T00:00:00Z", "rationale": "Agent processes sensitive compliance data with conditional autonomy within defined review boundaries" }, "safety_reviews": { "required": true, "frequency": "quarterly", "last_review": "2026-01-15T00:00:00Z", "review_board": "AI Safety Board" }, "human_oversight": { "level": "on_exception", "role": "Compliance Officer", "triggers": [ "Compliance determination affecting regulatory filing", "Document classified as restricted sensitivity", "Remediation recommendation with estimated cost exceeding $50,000" ], "response_time_minutes": 60, "intervention_model": "approve_reject" }, "incident_response": { "policy_documented": true, "last_tested": "2026-02-01T00:00:00Z" }, "disclosure": { "required": true, "known_limitations": [ "May produce inaccurate regulatory citations for jurisdictions outside the US and EU", "Not trained on regulatory guidance published after 2025-12-01" ], "prohibited_uses": [ "Final regulatory determination without human review", "Legal advice to external parties" ], "reporting_contact": "mailto:ai-issues@acme.example" }, "governance": { "lifecycle_governance": { "transition_policy": { "requires_approval": true, "approvers": [ "security-team", "compliance-lead" ], "approval_type": "all" }, "last_transition": { "from_status": "draft", "to_status": "active", "approved_by": "compliance-lead", "approved_at": "2026-01-15T00:00:00Z", "reason": "Passed SOC2 audit, security review, and Tier 2 governance validation" } }, "ownership": { "owner": "Compliance Team", "delegate": "Security Team", "contact": "compliance@acme.example", "user_escalation_contact": "mailto:ai-support@acme.example", "decision_boundaries": [ { "decision_type": "regulatory_filing", "owner": "human_only", "rationale": "Regulatory filings require human sign-off per SOC2 CC6.1" }, { "decision_type": "document_review", "owner": "agent", "rationale": "Routine document reviews are within the agent's authorized scope" }, { "decision_type": "remediation_recommendation", "owner": "human_in_loop", "rationale": "Remediation actions may have budgetary implications" } ] }, "approval_workflow": { "required": true, "approvers": [ "compliance-lead", "security-lead" ], "approval_type": "all" }, "audit_trail": { "enabled": true, "retention_days": 730, "destination": "s3://acme-audit-logs/compliance-agent/" } }, "governance_record_ref": "https://gorvnd.acme.example/agents/compliance-review/governance-record", "registry": { "catalog_id": "urn:acme:agents:compliance-review:2.0.0", "catalog_classification": [ { "domain": "compliance", "subdomain": "document-review", "capability": "soc2-review" } ], "visibility": "internal", "federation": { "registries": [ "https://registry.acme.example", "https://enterprise-agents.example" ], "primary": "https://registry.acme.example" } }, "metadata": { "authors": [ { "name": "Compliance Team", "email": "compliance@acme.example" } ], "license": "Proprietary", "documentation": "https://docs.acme.example/agents/compliance-review", "tags": [ "compliance", "soc2", "enterprise" ] } } ``` --- # Governance Record Specification | | | | --------------------- | -------------------------------- | | **Companion to** | `urn:adl:profile:governance:1.0` | | **Status** | Draft | | **ADL Compatibility** | 0.3.x | ## 1. Introduction[​](#1-introduction "Direct link to 1. Introduction") A governance record is a structured document maintained by a governance registry for each registered agent. It contains operational governance detail that does not travel with the agent passport — escalation contacts, full accountability chains, audit schedules, detailed evaluation reports, and compliance control mappings. The governance record is referenced from the agent's ADL document via the `governance_record_ref` member (Section 2.10 of the Governance Profile). The passport carries trust-decision signals; the governance record carries the operational substance behind those signals. ### 1.1 Scope[​](#11-scope "Direct link to 1.1 Scope") This specification defines the schema for governance records. It is a **companion specification** to the Governance Profile, not a new ADL document type. Governance records are stored and served by governance registries (such as Gorvnd) and are not embedded in ADL documents. ### 1.2 Relationship to the Passport[​](#12-relationship-to-the-passport "Direct link to 1.2 Relationship to the Passport") | Concern | Passport (ADL Document) | Governance Record | | ----------------- | --------------------------------------------------------- | --------------------------------------------------------------------- | | Incident response | `incident_response.policy_documented: true` | Full escalation contacts, severity routing, SLAs, external reporting | | Human oversight | `triggers`, `response_time_minutes`, `intervention_model` | Escalation contact, audit cadence, review history | | Evaluation | `result`, `evaluator`, `evaluation_date`, `expires_at` | Dimensions covered, conditions, report URI, continuous testing config | | Accountability | `user_escalation_contact`, `decision_boundaries` | Full accountability chain, external dependencies | | Compliance | `compliance_framework.primary_framework` | Full `control_mappings` table, audit schedule | *** ## 2. Document Structure[​](#2-document-structure "Direct link to 2. Document Structure") A governance record **MUST** be a JSON object. It **SHOULD** be served with media type `application/json`. ### 2.1 Top-Level Members[​](#21-top-level-members "Direct link to 2.1 Top-Level Members") | Member | Type | Required | Description | | --------------------- | ------ | -------- | ----------------------------------------------- | | agent\_ref | string | REQUIRED | URI to the ADL document this record accompanies | | record\_version | string | REQUIRED | Version of this governance record | | updated\_at | string | REQUIRED | ISO 8601 timestamp of last update | | incident\_escalation | object | OPTIONAL | Full incident escalation policy | | oversight\_operations | object | OPTIONAL | Operational oversight detail | | evaluation\_detail | object | OPTIONAL | Detailed evaluation records | | accountability | object | OPTIONAL | Accountability chain and dependencies | | compliance\_detail | object | OPTIONAL | Detailed compliance control mappings | *** ### 2.2 incident\_escalation[​](#22-incident_escalation "Direct link to 2.2 incident_escalation") Operational detail for incident detection, escalation, and reporting. This content backs the passport's `incident_response.policy_documented: true` declaration. | Member | Type | Required | Description | | ----------------------------- | ------ | -------- | ------------------------------------------------------------------------------------------ | | contacts | array | REQUIRED | Escalation contact chain | | triggers | array | REQUIRED | Conditions that activate escalation | | external\_reporting\_required | bool | OPTIONAL | Whether incidents must be reported to external authorities | | reporting\_framework | string | OPTIONAL | External reporting framework (e.g., `"NIST IR-6"`, `"IMDA Incident Reporting"`) | | external\_reporting\_contact | string | OPTIONAL | URI for external reporting; **MUST** be present if `external_reporting_required` is `true` | | last\_tested | string | OPTIONAL | ISO 8601 timestamp of last escalation path test | #### contacts[​](#contacts "Direct link to contacts") **MUST** be a non-empty array of contact objects: | Member | Type | Required | Description | | ----------------------- | ------ | -------- | --------------------------------------------------------------------------------- | | role | string | REQUIRED | Role in the escalation chain (e.g., `"first_responder"`, `"incident_commander"`) | | contact | string | REQUIRED | URI for the contact (e.g., `mailto:`, PagerDuty URL, Slack webhook) | | response\_time\_minutes | number | REQUIRED | Maximum response time SLA in minutes | | severity\_threshold | string | OPTIONAL | Minimum severity that routes to this contact: `low`, `medium`, `high`, `critical` | #### triggers[​](#triggers "Direct link to triggers") **MUST** be a non-empty array of strings describing conditions that activate the escalation process. *** ### 2.3 oversight\_operations[​](#23-oversight_operations "Direct link to 2.3 oversight_operations") Operational detail for human oversight enforcement. This content backs the passport's `human_oversight.triggers` and `human_oversight.response_time_minutes` declarations. | Member | Type | Required | Description | | ------------------- | ------ | -------- | -------------------------------------------------------------------------------------------------------- | | escalation\_contact | string | OPTIONAL | URI of the person, team, or notification endpoint for oversight alerts | | audit\_cadence | string | OPTIONAL | Review frequency for oversight effectiveness (e.g., `"quarterly"`, `"monthly"`, `"after_each_incident"`) | | review\_history | array | OPTIONAL | Record of past oversight reviews | #### review\_history[​](#review_history "Direct link to review_history") When present, **MUST** be an array of review objects: | Member | Type | Required | Description | | ----------------- | ------ | -------- | -------------------------------- | | date | string | REQUIRED | ISO 8601 timestamp of review | | reviewer | string | REQUIRED | Entity that performed the review | | findings\_summary | string | OPTIONAL | Summary of review findings | *** ### 2.4 evaluation\_detail[​](#24-evaluation_detail "Direct link to 2.4 evaluation_detail") Detailed evaluation records backing the passport's `evaluation_attestation` declaration. | Member | Type | Required | Description | | ---------------------------- | ------ | -------- | ---------------------------------------------------- | | dimensions\_covered | array | OPTIONAL | Aspects of behavior that were evaluated | | conditions | array | OPTIONAL | Conditions attached to a `conditional` result | | report\_uri | string | OPTIONAL | URI to the full evaluation report document | | continuous\_testing\_enabled | bool | OPTIONAL | Whether continuous post-deployment testing is active | | evaluation\_history | array | OPTIONAL | Record of past evaluations | #### dimensions\_covered[​](#dimensions_covered "Direct link to dimensions_covered") When present, **MUST** be a non-empty array. Each item **MUST** be one of: | Value | Description | | -------------------------- | ----------------------------------------------------------------------------------------- | | `task_execution_accuracy` | Whether the agent correctly performs its intended tasks | | `policy_compliance` | Whether the agent adheres to declared policies and constraints | | `tool_calling_correctness` | Whether the agent invokes tools with correct parameters and in appropriate contexts | | `robustness` | Whether the agent handles edge cases, adversarial inputs, and unexpected conditions | | `security` | Whether the agent resists prompt injection, data exfiltration, and other security threats | | `multi_agent_behavior` | Whether the agent behaves correctly in multi-agent pipeline scenarios | #### conditions[​](#conditions "Direct link to conditions") When present, **MUST** be a non-empty array of strings. **MUST** be present when the passport's `evaluation_attestation.result` is `conditional`. #### evaluation\_history[​](#evaluation_history "Direct link to evaluation_history") When present, **MUST** be an array of evaluation record objects: | Member | Type | Required | Description | | ----------- | ------ | -------- | ------------------------------------ | | date | string | REQUIRED | ISO 8601 timestamp | | evaluator | string | REQUIRED | Entity that performed the evaluation | | result | string | REQUIRED | `passed`, `conditional`, or `failed` | | report\_uri | string | OPTIONAL | URI to the evaluation report | *** ### 2.5 accountability[​](#25-accountability "Direct link to 2.5 accountability") Full accountability chain and external dependency records. This content backs the passport's `governance.ownership.user_escalation_contact` and `governance.ownership.decision_boundaries` declarations. | Member | Type | Required | Description | | ---------------------- | ----- | -------- | ----------------------------------------- | | accountability\_chain | array | OPTIONAL | Ordered chain of accountable entities | | external\_dependencies | array | OPTIONAL | Third-party services the agent depends on | #### accountability\_chain[​](#accountability_chain "Direct link to accountability_chain") When present, **MUST** be a non-empty array of accountability objects, ordered from the deploying team to the ultimate accountable authority: | Member | Type | Required | Description | | ------- | ------ | -------- | --------------------------------------------------------------------------------------------- | | role | string | REQUIRED | Role in the accountability chain (e.g., `"deployer"`, `"product_owner"`, `"model_developer"`) | | entity | string | REQUIRED | Name of the accountable entity | | contact | string | OPTIONAL | URI for the entity | | scope | string | OPTIONAL | Description of what this entity is accountable for | #### external\_dependencies[​](#external_dependencies "Direct link to external_dependencies") When present, **MUST** be a non-empty array of dependency objects: | Member | Type | Required | Description | | ------------------- | ------ | -------- | -------------------------------------------------------- | | service | string | REQUIRED | Name of the external service | | provider | string | REQUIRED | Provider of the service | | accountability\_ref | string | OPTIONAL | URI to the provider's accountability or terms of service | | notes | string | OPTIONAL | Additional context | *** ### 2.6 compliance\_detail[​](#26-compliance_detail "Direct link to 2.6 compliance_detail") Detailed compliance control mappings and audit schedule. This content extends the passport's `compliance_framework.primary_framework` declaration. | Member | Type | Required | Description | | ----------------- | ------ | -------- | ----------------------------------- | | control\_mappings | array | OPTIONAL | Full control implementation details | | audit\_schedule | object | OPTIONAL | Audit schedule and history | #### control\_mappings[​](#control_mappings "Direct link to control_mappings") When present, **MUST** be an array of control mapping objects following the same schema as the passport's `compliance_framework.control_mappings`: | Member | Type | Required | Description | | ------------- | ------ | -------- | ----------------------------------------------------- | | framework | string | REQUIRED | Framework identifier | | control\_id | string | REQUIRED | Control identifier | | status | string | REQUIRED | `implemented`, `partial`, `planned`, `not_applicable` | | evidence\_uri | string | OPTIONAL | URI to compliance evidence | #### audit\_schedule[​](#audit_schedule "Direct link to audit_schedule") When present, **MAY** contain: | Member | Type | Description | | ----------- | ------ | ------------------------------------------ | | last\_audit | string | ISO 8601 timestamp of last audit | | next\_audit | string | ISO 8601 timestamp of next scheduled audit | | auditor | string | Entity performing the audit | *** ## 3. Tier-Conditional Record Requirements[​](#3-tier-conditional-record-requirements "Direct link to 3. Tier-Conditional Record Requirements") Governance registries **SHOULD** enforce the following requirements at agent registration time based on the passport's `autonomy.tier`: | Field | Tier 1 | Tier 2 | Tier 3 | | ------------------------------------------ | ------ | ------ | -------- | | `incident_escalation` | MAY | SHOULD | **MUST** | | `incident_escalation.contacts` (non-empty) | MAY | SHOULD | **MUST** | | `oversight_operations.escalation_contact` | MAY | MAY | **MUST** | | `oversight_operations.audit_cadence` | MAY | MAY | **MUST** | | `evaluation_detail` | MAY | MAY | SHOULD | | `accountability.accountability_chain` | MAY | MAY | SHOULD | These requirements are enforced by the governance registry, not by passport validators. The passport validator's responsibility ends at the passport schema; the registry validates the governance record at registration time. *** ## 4. Example[​](#4-example "Direct link to 4. Example") ``` { "agent_ref": "https://example.com/agents/compliance-review", "record_version": "3.1.0", "updated_at": "2026-03-01T14:00:00Z", "incident_escalation": { "contacts": [ { "role": "first_responder", "contact": "mailto:soc@example.com", "response_time_minutes": 15, "severity_threshold": "high" }, { "role": "incident_commander", "contact": "https://pagerduty.example.com/escalation/ai-incidents", "response_time_minutes": 30, "severity_threshold": "critical" } ], "triggers": [ "Agent produces output contradicting established regulatory guidance", "Agent attempts to access resources outside declared permissions", "Anomalous volume of tool invocations detected" ], "external_reporting_required": false, "last_tested": "2026-02-01T00:00:00Z" }, "oversight_operations": { "escalation_contact": "mailto:compliance-lead@example.com", "audit_cadence": "quarterly", "review_history": [ { "date": "2026-01-15T00:00:00Z", "reviewer": "AI Ethics Committee", "findings_summary": "Oversight triggers functioning as designed. Response times within SLA." } ] }, "evaluation_detail": { "dimensions_covered": [ "task_execution_accuracy", "policy_compliance", "robustness", "security" ], "report_uri": "https://gorvnd.example.com/reports/compliance-review/eval-2026-02.pdf", "continuous_testing_enabled": true, "evaluation_history": [ { "date": "2026-02-15T00:00:00Z", "evaluator": "AI Safety Review Board", "result": "passed", "report_uri": "https://gorvnd.example.com/reports/compliance-review/eval-2026-02.pdf" }, { "date": "2025-08-20T00:00:00Z", "evaluator": "External Audit Firm", "result": "conditional", "report_uri": "https://gorvnd.example.com/reports/compliance-review/eval-2025-08.pdf" } ] }, "accountability": { "accountability_chain": [ { "role": "deployer", "entity": "Compliance Team", "contact": "mailto:compliance@example.com", "scope": "Day-to-day operation and monitoring" }, { "role": "product_owner", "entity": "VP of Compliance", "contact": "mailto:vp-compliance@example.com", "scope": "Strategic direction and risk acceptance" }, { "role": "model_developer", "entity": "Acme AI", "contact": "mailto:support@acme-ai.example.com", "scope": "Underlying model behavior and updates" } ], "external_dependencies": [ { "service": "Regulatory Database API", "provider": "RegData Corp", "accountability_ref": "https://regdata.example.com/terms", "notes": "Agent queries this API for current regulatory text" } ] }, "compliance_detail": { "control_mappings": [ { "framework": "SOC2", "control_id": "CC6.1", "status": "implemented", "evidence_uri": "https://gorvnd.example.com/evidence/cc6.1" }, { "framework": "SOC2", "control_id": "CC7.2", "status": "implemented", "evidence_uri": "https://gorvnd.example.com/evidence/cc7.2" } ], "audit_schedule": { "last_audit": "2025-11-15T00:00:00Z", "next_audit": "2026-11-15T00:00:00Z", "auditor": "External Audit Partners LLP" } } } ``` --- # Governance Profile Compatibility This document tracks compatibility between Governance Profile versions and ADL specification versions. ## Compatibility Matrix[​](#compatibility-matrix "Direct link to Compatibility Matrix") | Profile Version | ADL Versions | Status | Notes | | --------------- | ------------ | ------ | --------------- | | 1.0 | 0.3.x | Draft | Initial release | ## Compatibility Policy[​](#compatibility-policy "Direct link to Compatibility Policy") * **Minor ADL updates** (e.g., 0.1.0 → 0.1.1): Profile remains compatible * **Major ADL updates** (e.g., 0.1.x → 1.0.0): Profile compatibility will be evaluated; new profile version released if needed * **Breaking profile changes**: Require new major profile version ## Migration Guides[​](#migration-guides "Direct link to Migration Guides") *No migrations yet. This section will document how to upgrade between profile versions.* --- # Governance Profile | | | | --------------------- | -------------------------------- | | **Identifier** | `urn:adl:profile:governance:1.0` | | **Status** | Draft | | **ADL Compatibility** | 0.3.x | note This profile is in draft status. The specification is stable for early adoption, but minor changes may occur before 1.0. ## Overview[​](#overview "Direct link to Overview") The Governance Profile extends ADL for regulated enterprise environments. It adds members for compliance frameworks, autonomy classification, AI governance, operational governance, and lifecycle process controls. When this profile is declared in an ADL document's `profiles` array, the document **MUST** satisfy all requirements defined in this specification. ## Use Cases[​](#use-cases "Direct link to Use Cases") * Regulatory compliance tracking * AI governance and oversight * Audit trail management * Multi-framework compliance mapping ## Quick Start[​](#quick-start "Direct link to Quick Start") Add the Governance Profile to your ADL document: ``` { "adl_spec": "0.3.0", "name": "Compliance Review Agent", "description": "Reviews documents for regulatory compliance.", "version": "1.0.0", "profiles": ["urn:adl:profile:governance:1.0"], "compliance_framework": { "primary_framework": "SOC2_TYPE_II", "control_mappings": [ { "framework": "SOC2", "control_id": "CC6.1", "status": "implemented" } ] } } ``` ## Additional Members[​](#additional-members "Direct link to Additional Members") The Governance Profile adds the following top-level members: | Member | Required | Description | | ------------------------ | ------------ | ----------------------------------------------- | | `compliance_framework` | **REQUIRED** | Compliance and regulatory framework information | | `autonomy` | **REQUIRED** | Autonomy tier classification (Tier 1, 2, or 3) | | `risk_classification` | Optional | AI risk level and assessment | | `human_oversight` | Tier 2+ | Human oversight configuration and triggers | | `incident_response` | Tier 2+ | Incident escalation policy attestation | | `disclosure` | Tier 2+ | User-facing transparency declarations | | `evaluation_attestation` | Tier 3 | Pre-deployment evaluation result | | `safety_reviews` | Optional | Safety review schedule and status | | `governance` | Optional | Operational governance information | | `governance_record_ref` | Optional | URI to governance record in registry | See the [full specification](/profiles/governance/specification.md) for detailed member definitions. ## Supported Compliance Frameworks[​](#supported-compliance-frameworks "Direct link to Supported Compliance Frameworks") The profile supports the following compliance frameworks: * `NIST_800_53` - NIST Special Publication 800-53 * `SOC2_TYPE_II` - SOC 2 Type II * `ISO_27001` - ISO/IEC 27001 Information Security * `ISO_42001` - ISO/IEC 42001 AI Management System * `GDPR` - General Data Protection Regulation * `HIPAA` - Health Insurance Portability and Accountability Act * `PCI_DSS` - Payment Card Industry Data Security Standard * `EU_AI_ACT` - EU Artificial Intelligence Act --- # Governance Profile Specification | | | | --------------------- | -------------------------------- | | **Identifier** | `urn:adl:profile:governance:1.0` | | **Status** | Draft | | **ADL Compatibility** | 0.3.x | | **Schema** | `schema.json` | | **Dependencies** | None | ## 1. Introduction[​](#1-introduction "Direct link to 1. Introduction") The Governance Profile extends ADL for regulated enterprise environments. It adds members for compliance frameworks, autonomy classification, AI governance, operational governance, and lifecycle process controls. Agent lifecycle status is defined by the core ADL `lifecycle` member (Section 5.6); this profile adds governance-specific process controls around lifecycle transitions. When this profile is declared in an ADL document's `profiles` array, the document **MUST** satisfy all requirements defined in this specification. ### 1.1 Passport Model[​](#11-passport-model "Direct link to 1.1 Passport Model") This profile applies ADL's passport model (Section 1.3 of the core specification) to governance. The ADL document carries the minimum governance declarations needed for trust decisions; operational governance detail — escalation contacts, full accountability chains, audit schedules, evaluation reports — is maintained in a separate **governance record** stored in the agent registry and linked from the passport via `governance_record_ref`. See the companion [Governance Record Specification](/profiles/governance/1.0/governance-record.md) for the governance record schema. ### 1.2 Conformance Tiers[​](#12-conformance-tiers "Direct link to 1.2 Conformance Tiers") The Governance Profile defines three conformance tiers based on agent autonomy. Tiers make governance fields **conditionally required** — fields that are OPTIONAL at Tier 1 become REQUIRED at higher tiers. This mechanism transforms optional governance declarations into enforceable constraints without making them universally required for all governed agents. | Tier | Name | Description | | ---- | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | 1 | Supervised | Human directs; agent assists. Agent operates under direct human control with limited independent action. | | 2 | Conditional Autonomy | Agent acts within defined boundaries; human oversight on exceptions. Agent may execute independently but must pause for human review under declared trigger conditions. | | 3 | Full Autonomy | Agent operates independently; human oversight is periodic or post-hoc. Agent makes and executes decisions with minimal real-time human intervention. | Tier definitions are framework-agnostic. The compliance mapping table (Section 3) provides alignment to specific framework risk classifications. *** ## 2. Additional Members[​](#2-additional-members "Direct link to 2. Additional Members") ### 2.1 compliance\_framework[​](#21-compliance_framework "Direct link to 2.1 compliance_framework") **REQUIRED** when using this profile. An object containing compliance and regulatory framework information. | Member | Type | Required | Description | | ------------------ | ------ | -------- | --------------------------------------- | | primary\_framework | string | REQUIRED | Primary compliance framework identifier | | control\_mappings | array | OPTIONAL | Control implementation details | | audit\_dates | object | OPTIONAL | Last and next audit dates | #### primary\_framework[​](#primary_framework "Direct link to primary_framework") **MUST** be one of: * `NIST_800_53` — NIST Special Publication 800-53 * `SOC2_TYPE_II` — SOC 2 Type II * `ISO_27001` — ISO/IEC 27001 Information Security * `ISO_42001` — ISO/IEC 42001 AI Management System * `GDPR` — General Data Protection Regulation * `HIPAA` — Health Insurance Portability and Accountability Act * `PCI_DSS` — Payment Card Industry Data Security Standard * `EU_AI_ACT` — EU Artificial Intelligence Act * `IMDA_AGENTIC` — IMDA Model AI Governance Framework for Agentic AI * `NIST_AI_RMF` — NIST AI Risk Management Framework #### control\_mappings[​](#control_mappings "Direct link to control_mappings") When present, **MUST** be an array of control mapping objects: | Member | Type | Required | Description | | ----------- | ------ | -------- | ---------------------------------- | | framework | string | REQUIRED | Framework identifier | | control\_id | string | REQUIRED | Control identifier (e.g., "CC6.1") | | status | string | REQUIRED | Implementation status | `status` **MUST** be one of: `implemented`, `partial`, `planned`, `not_applicable`. note For enterprise deployments with a governance registry, MAY be maintained in the governance record rather than the passport. When present in both locations, the governance record is the authoritative source. #### audit\_dates[​](#audit_dates "Direct link to audit_dates") When present, **MUST** be an object containing: | Member | Type | Required | Description | | ----------- | ------ | -------- | ------------------------------------------ | | last\_audit | string | OPTIONAL | ISO 8601 timestamp of last audit | | next\_audit | string | OPTIONAL | ISO 8601 timestamp of next scheduled audit | *** ### 2.2 autonomy[​](#22-autonomy "Direct link to 2.2 autonomy") **REQUIRED** when using this profile. Declares the agent's autonomy tier, which determines the conformance requirements for the remainder of this profile. The autonomy classification is the primary governance signal for counterparties making trust decisions about this agent. | Member | Type | Required | Description | | -------------- | ------ | -------- | ---------------------------------------- | | tier | number | REQUIRED | Conformance tier: `1`, `2`, or `3` | | basis | string | REQUIRED | Rationale for the tier classification | | classified\_by | string | REQUIRED | Entity that performed the classification | | classified\_at | string | REQUIRED | ISO 8601 timestamp of classification | `tier` **MUST** be one of `1`, `2`, or `3`. See Section 1.2 for tier definitions. `basis` **SHOULD** describe the factors that informed the classification, including the agent's scope of autonomous action, the reversibility of its decisions, and the sensitivity of data it processes. `classified_by` **SHOULD** identify a person, team, or governance body with authority to classify agents. Example: ``` { "autonomy": { "tier": 2, "basis": "Agent executes document reviews independently but requires human approval for compliance determinations that affect regulatory filings.", "classified_by": "AI Ethics Committee", "classified_at": "2026-01-15T00:00:00Z" } } ``` *** ### 2.3 risk\_classification[​](#23-risk_classification "Direct link to 2.3 risk_classification") **OPTIONAL.** AI risk level and assessment for this agent. | Member | Type | Required | Description | | --------------- | ------ | -------- | --------------------------------------------------- | | level | string | OPTIONAL | Risk level: `low`, `medium`, `high`, `critical` | | autonomy\_level | string | OPTIONAL | Fine-grained autonomy scale for framework alignment | | assessed\_by | string | OPTIONAL | Entity that performed the assessment | | assessed\_at | string | OPTIONAL | ISO 8601 timestamp | | rationale | string | OPTIONAL | Explanation of risk classification | #### autonomy\_level[​](#autonomy_level "Direct link to autonomy_level") When present, **MUST** be one of: | Value | Description | | ----- | ------------------------------------------------------------------------------------------------ | | `L0` | No autonomy — deterministic tool, no AI decision-making | | `L1` | Minimal autonomy — AI assists within tightly scoped parameters | | `L2` | Bounded autonomy — AI selects actions from a constrained set with human approval | | `L3` | Conditional autonomy — AI acts independently within defined boundaries, human override available | | `L4` | High autonomy — AI operates independently with periodic human review | | `L5` | Full autonomy — AI operates without ongoing human oversight | `autonomy_level` provides a finer-grained scale than `autonomy.tier` for organizations that require detailed risk classification. When both are present, they **SHOULD** be consistent: L0–L1 maps to Tier 1, L2–L3 maps to Tier 2, L4–L5 maps to Tier 3. *** ### 2.4 human\_oversight[​](#24-human_oversight "Direct link to 2.4 human_oversight") **OPTIONAL.** Human oversight configuration for this agent. At Tier 2+, this member **MUST** be present (GOV-12). | Member | Type | Required | Description | | ----------------------- | ------ | -------- | ----------------------------------------------------------------- | | level | string | OPTIONAL | Oversight level: `none`, `on_exception`, `periodic`, `continuous` | | role | string | OPTIONAL | Role responsible for oversight | | triggers | array | OPTIONAL | Conditions that pause agent execution for human review | | response\_time\_minutes | number | OPTIONAL | Maximum minutes before auto-halt when no reviewer responds | | intervention\_model | string | OPTIONAL | How human intervention works | #### triggers[​](#triggers "Direct link to triggers") When present, **MUST** be a non-empty array. Each entry is either a **free-text string** describing a condition (back-compatible) or a **structured predicate object** that a runtime governor can evaluate mechanically. A structured trigger **MUST** contain a `when` object with at least one predicate, and **MAY** contain a `description`. The `when` predicate vocabulary: | Predicate | Type | Fires when | | ------------------------------- | ------ | ------------------------------------------------------------------------------------------------------------ | | cost\_usd\_over | number | The session's cost exceeds this many USD. | | data\_classification\_at\_least | string | The agent touches data at or above this sensitivity (`public` < `internal` < `confidential` < `restricted`). | | tool | string | The named tool is about to be invoked. | | path\_matches | string | A target path matches this Section 4.4 pattern. | A structured trigger with multiple predicates fires when **all** are satisfied. Free-text strings remain valid and are detected by the runtime as before; structured triggers let the governor evaluate the condition without interpreting prose. The evaluation, pause-for-review, and timeout procedure is defined in [Runtime Protocol §5](/protocol/runtime.md): when a trigger fires the agent **MUST** suspend and request review, and if no reviewer responds within `response_time_minutes` the governor resolves `runtime.degradation.on_oversight_timeout`, defaulting to halt. At Tier 2+, `triggers` **MUST** be present (GOV-13). A structured trigger's `when` **MUST** contain at least one predicate (GOV-25). Example trigger values (mixed forms): ``` { "triggers": [ "Decision affecting external-facing communications", { "description": "Large spend", "when": { "cost_usd_over": 10000 } }, { "when": { "data_classification_at_least": "restricted" } }, { "when": { "tool": "wire_transfer" } } ] } ``` #### response\_time\_minutes[​](#response_time_minutes "Direct link to response_time_minutes") When present, **MUST** be a positive integer. Specifies the maximum number of minutes the agent will wait for a human reviewer to respond after a trigger condition is met. If no response is received within this period, the agent **MUST** halt execution rather than proceed without oversight. At Tier 2+, `response_time_minutes` **MUST** be present (GOV-13). #### intervention\_model[​](#intervention_model "Direct link to intervention_model") When present, **MUST** be one of: | Value | Description | | ---------------- | ----------------------------------------------------------- | | `approve_reject` | Human approves or rejects the agent's proposed action | | `plan_editing` | Human may modify the agent's proposed plan before execution | | `monitor_only` | Human observes but does not block execution | note Operational oversight detail — escalation contacts and audit cadence — is maintained in the governance record. See the Governance Record Specification. *** ### 2.5 incident\_response[​](#25-incident_response "Direct link to 2.5 incident_response") **OPTIONAL.** Declares whether an incident escalation policy is documented for this agent. At Tier 2+, this member **MUST** be present with `policy_documented: true` (GOV-14). | Member | Type | Required | Description | | ------------------ | ------ | -------- | ---------------------------------------------------------------------------- | | policy\_documented | bool | REQUIRED | Whether an incident escalation policy is documented in the governance record | | last\_tested | string | OPTIONAL | ISO 8601 timestamp of when the escalation path was last verified operational | `policy_documented` **MUST** be `true` at Tier 2+ (GOV-14). Implementations **SHOULD** warn when `last_tested` is absent or more than 90 days old. The full incident escalation policy — contacts, severity routing, response time SLAs, external reporting obligations — is maintained in the governance record. See the [Governance Record Specification](/profiles/governance/1.0/governance-record.md). Example: ``` { "incident_response": { "policy_documented": true, "last_tested": "2026-02-01T00:00:00Z" } } ``` *** ### 2.6 evaluation\_attestation[​](#26-evaluation_attestation "Direct link to 2.6 evaluation_attestation") **OPTIONAL.** Records the result of pre-deployment behavioral evaluation. At Tier 3, this member **MUST** be present with `result: passed` (GOV-16). This member is distinct from `security.attestation` (Section 10.3 of the core ADL specification), which provides cryptographic provenance for the document. `evaluation_attestation` records whether the agent's behavior was evaluated and what the outcome was. | Member | Type | Required | Description | | ---------------- | ------ | -------- | ----------------------------------------------- | | result | string | REQUIRED | Evaluation outcome | | evaluator | string | REQUIRED | Entity that performed the evaluation | | evaluation\_date | string | REQUIRED | ISO 8601 timestamp of evaluation completion | | methodology | string | OPTIONAL | Evaluation methodology class | | expires\_at | string | OPTIONAL | ISO 8601 timestamp when the attestation expires | #### result[​](#result "Direct link to result") **MUST** be one of: | Value | Description | | ------------- | ------------------------------------------------- | | `passed` | Agent met all evaluation criteria | | `conditional` | Agent passed with conditions — restrictions apply | | `failed` | Agent did not meet evaluation criteria | At Tier 3, `result` **MUST** be `passed` (GOV-16). Implementations **SHOULD** warn when `result` is `conditional` at any tier. #### methodology[​](#methodology "Direct link to methodology") When present, **MUST** be one of: `automated_benchmark`, `red_team`, `third_party_audit`, `sandbox`, `internal_review`. #### expires\_at[​](#expires_at "Direct link to expires_at") When present, implementations **SHOULD** warn when `expires_at` is in the past or within 30 days. Runtimes **SHOULD** treat an expired evaluation attestation as requiring re-evaluation before provisioning. note Detailed evaluation records — dimensions covered, conditions, full report URI, continuous testing configuration — are maintained in the governance record. See the Governance Record Specification. Example: ``` { "evaluation_attestation": { "result": "passed", "evaluator": "AI Safety Review Board", "evaluation_date": "2026-02-15T00:00:00Z", "methodology": "red_team", "expires_at": "2026-08-15T00:00:00Z" } } ``` *** ### 2.7 disclosure[​](#27-disclosure "Direct link to 2.7 disclosure") **OPTIONAL.** User-facing transparency declarations for this agent. At Tier 2+, this member **MUST** be present with `required: true` (GOV-15). Disclosure content is presented to users at interaction time. It informs anyone who interacts with the agent — including end users and peer agents — of the agent's AI identity, known limitations, prohibited uses, and reporting contact. | Member | Type | Required | Description | | ---------------------- | ------ | -------- | --------------------------------------------------------------------------- | | required | bool | REQUIRED | Whether the runtime **MUST** present disclosure to users before interaction | | known\_limitations | array | OPTIONAL | Known limitations of the agent | | prohibited\_uses | array | OPTIONAL | Uses for which the agent is not intended | | user\_responsibilities | array | OPTIONAL | Responsibilities the user accepts when using the agent | | reporting\_contact | string | OPTIONAL | URI for users to report issues or exercise data subject rights | | disclosure\_version | string | OPTIONAL | Version identifier for tracking disclosure content changes | `required` **MUST** be `true` at Tier 2+ (GOV-15). When `required` is `true`, runtimes **MUST** present the disclosure content to users before the first interaction in a session. `known_limitations`, `prohibited_uses`, and `user_responsibilities`, when present, **MUST** each be a non-empty array of strings. `reporting_contact`, when present, **MUST** be a valid URI. Example: ``` { "disclosure": { "required": true, "known_limitations": [ "May produce inaccurate regulatory citations", "Not trained on jurisdiction-specific case law after 2025" ], "prohibited_uses": [ "Final regulatory determination without human review", "Legal advice to external parties" ], "reporting_contact": "mailto:ai-issues@example.com", "disclosure_version": "1.2" } } ``` *** ### 2.8 safety\_reviews[​](#28-safety_reviews "Direct link to 2.8 safety_reviews") **OPTIONAL.** Safety review schedule and status for this agent. | Member | Type | Required | Description | | ------------- | ------ | -------- | -------------------------------------- | | required | bool | OPTIONAL | Whether safety review is required | | frequency | string | OPTIONAL | Review frequency (e.g., `"quarterly"`) | | last\_review | string | OPTIONAL | ISO 8601 timestamp | | next\_review | string | OPTIONAL | ISO 8601 timestamp | | review\_board | string | OPTIONAL | Reviewing entity | *** ### 2.9 governance[​](#29-governance "Direct link to 2.9 governance") **OPTIONAL.** An object containing operational governance information. | Member | Type | Required | Description | | --------------------- | ------ | -------- | ---------------------------------------------- | | ownership | object | OPTIONAL | Owner and delegate information | | approval\_workflow | object | OPTIONAL | Approval requirements | | audit\_trail | object | OPTIONAL | Audit logging configuration | | lifecycle\_governance | object | OPTIONAL | Governance-specific lifecycle process controls | note Agent lifecycle status (, , , ) is defined by the core ADL member (Section 5.6). The governance profile adds process controls around lifecycle transitions via , not a separate status field. #### lifecycle\_governance[​](#lifecycle_governance "Direct link to lifecycle_governance") When present, **MAY** contain: | Member | Type | Description | | ------------------ | ------ | ------------------------------------------------ | | transition\_policy | object | Rules governing lifecycle state transitions | | last\_transition | object | Record of the most recent lifecycle state change | ##### transition\_policy[​](#transition_policy "Direct link to transition_policy") When present, **MAY** contain: | Member | Type | Description | | -------------------- | ------ | ----------------------------------------------------------------------------- | | requires\_approval | bool | Whether lifecycle transitions require approval | | approvers | array | List of required approvers for transitions | | approval\_type | string | Type: `any`, `all`, `quorum` | | notice\_period\_days | number | Required notice period before deprecation/retirement | | allowed\_transitions | array | Permitted state transitions (e.g., `["draft->active", "active->deprecated"]`) | ##### last\_transition[​](#last_transition "Direct link to last_transition") When present, **MAY** contain: | Member | Type | Description | | ------------ | ------ | ----------------------------------- | | from\_status | string | Previous lifecycle status | | to\_status | string | New lifecycle status | | approved\_by | string | Entity that approved the transition | | approved\_at | string | ISO 8601 timestamp of approval | | reason | string | Reason for the transition | #### ownership[​](#ownership "Direct link to ownership") When present, **MAY** contain: | Member | Type | Description | | ------------------------- | ------ | ----------------------------------------------------------- | | owner | string | Primary owner (team or individual) | | delegate | string | Delegate owner | | contact | string | Contact email | | user\_escalation\_contact | string | URI for end users or external parties to report issues | | decision\_boundaries | array | Declarations of which decision types require human approval | ##### user\_escalation\_contact[​](#user_escalation_contact "Direct link to user_escalation_contact") When present, **MUST** be a valid URI. This is distinct from `ownership.contact` — it is the external-facing contact for end users and counterparties, not the internal governance owner. It **MAY** be a `mailto:` URI, a web form URL, or another URI scheme appropriate to the organization. ##### decision\_boundaries[​](#decision_boundaries "Direct link to decision_boundaries") When present, **MUST** be a non-empty array of objects. Each entry declares a category of decision and the authorization model for that category. | Member | Type | Required | Description | | -------------- | ------ | -------- | ---------------------------------------------------------------------------------------------------- | | decision\_type | string | REQUIRED | Category of decision (e.g., `"financial_commitment"`, `"data_deletion"`, `"external_communication"`) | | owner | string | REQUIRED | Authorization model for this decision type | | rationale | string | OPTIONAL | Explanation of why this boundary exists | `owner` **MUST** be one of: | Value | Description | | --------------- | ------------------------------------------------------------- | | `human_only` | Agent **MUST NOT** execute this decision type; human required | | `agent` | Agent may execute this decision type independently | | `human_in_loop` | Agent may propose; human must approve before execution | note The full accountability chain and external dependencies list are maintained in the governance record. See the Governance Record Specification. #### approval\_workflow[​](#approval_workflow "Direct link to approval_workflow") When present, **MAY** contain: | Member | Type | Description | | -------------- | ------ | ---------------------------------------- | | required | bool | Whether approval is required for changes | | approvers | array | List of required approvers | | approval\_type | string | Type: `any`, `all`, `quorum` | #### audit\_trail[​](#audit_trail "Direct link to audit_trail") When present, **MAY** contain: | Member | Type | Description | | --------------- | ------ | -------------------------------- | | enabled | bool | Whether audit logging is enabled | | retention\_days | number | Log retention period in days | | destination | string | Audit log destination URI | *** ### 2.10 governance\_record\_ref[​](#210-governance_record_ref "Direct link to 2.10 governance_record_ref") **OPTIONAL.** A URI that resolves to the governance record for this agent in the authoritative registry. Value **MUST** be a valid URI when present. The URI **SHOULD** be stable — it **MUST NOT** change when the governance record content is updated. The URI **MAY** require authentication to access. At Tier 3, `governance_record_ref` **SHOULD** be present (GOV-17). The governance record contains operational governance detail that does not travel with the agent passport: full incident escalation contacts, oversight escalation contacts and audit cadence, detailed evaluation reports, full accountability chains, and compliance control mappings. See the [Governance Record Specification](/profiles/governance/1.0/governance-record.md) for the record schema. Example: ``` { "governance_record_ref": "https://gorvnd.example.com/agents/compliance-review/governance-record" } ``` *** ### 2.11 anomaly\_baseline[​](#211-anomaly_baseline "Direct link to 2.11 anomaly_baseline") **OPTIONAL.** Declares the agent's expected runtime behavior so a runtime governor can detect deviation. **SHOULD** be present at Tier 2 and **MUST** be present at Tier 3 (GOV-26). | Member | Type | Description | | ----------------------- | ------ | -------------------------------------------------------------------------------------------------- | | expected\_tools | array | Expected tool-call distribution; each entry has `name` and an OPTIONAL `share` (0–1) of calls. | | cost\_per\_session\_usd | object | Expected per-session cost range: `min` / `max`. | | data\_classes | array | Data categories the agent typically touches (same vocabulary as `data_classification.categories`). | The baseline is a *declaration of normal*; the governor compares a live session against it and treats material deviation — an unexpected tool, cost outside the range, an unexpected data class — as an `on_anomaly` cause. The detection and response procedure, and how anomaly evidence binds to the governor's audit trail, is defined in [Runtime Protocol §7](/protocol/runtime.md). Because the baseline is self-declared by the agent, it is a *weak* signal on its own; its value is realized when the governor's anomaly evidence is externally verifiable ([Runtime Protocol §1.4](/protocol/runtime.md)). At Tier 3, `anomaly_baseline` is REQUIRED (GOV-26) so an autonomous agent ships with a declared envelope of normal behavior to measure against. Example: ``` { "anomaly_baseline": { "expected_tools": [ { "name": "search_invoices", "share": 0.6 }, { "name": "get_invoice_details", "share": 0.3 } ], "cost_per_session_usd": { "min": 0.01, "max": 5.00 }, "data_classes": ["financial", "pii"] } } ``` *** ## 3. Compliance Mapping[​](#3-compliance-mapping "Direct link to 3. Compliance Mapping") The Governance Profile provides mappings between ADL/profile sections and common compliance framework controls. | ADL / Profile Section | Framework Controls | | -------------------------------- | ------------------------------------------------------------------------------------------------- | | lifecycle | NIST CM-3, SA-10; ISO 42001 8.4; EU AI Act Art. 9, 72 | | permissions.network | NIST AC-4, SC-7; SOC2 CC6.6 | | permissions.filesystem | NIST AC-3, AC-6; SOC2 CC6.1 | | security.authentication | NIST IA-2, IA-5; SOC2 CC6.1 | | security.encryption | NIST SC-8, SC-13; SOC2 CC6.1 | | autonomy | IMDA §2.1; CLTC Map 5.1; CLTC Govern 1.4 | | risk\_classification | ISO 42001 6.1, 9.1; EU AI Act Art. 9; CLTC Map 5.1; IMDA §2.1.1 | | human\_oversight | ISO 42001 6.1, 9.1; EU AI Act Art. 9; IMDA §2.2.2; CLTC Govern 2.1; CLTC Map 3.5; CLTC Manage 1.3 | | incident\_response | IMDA §2.3.3; CLTC Govern 4.2; CLTC Manage 2.3 | | evaluation\_attestation | IMDA §2.3.2; CLTC Measure 1.1 | | disclosure | IMDA §2.4.2; CLTC Govern 4.2 | | governance.ownership | IMDA §2.2.1; CLTC Govern 2.1 | | governance.audit\_trail | NIST AU-2, AU-6; SOC2 CC7.2 | | governance.lifecycle\_governance | NIST CM-3, CM-4; SOC2 CC8.1 | *** ## 4. Example[​](#4-example "Direct link to 4. Example") A Tier 2 agent with conformance tier, oversight triggers, disclosure, and incident response: Complete Example This example demonstrates a complete agent definition using this profile. compliance-agent.json ``` { "$schema": "https://adl-spec.org/profiles/governance/1.0/schema.json", "adl_spec": "0.3.0", "name": "Compliance Review Agent", "description": "Reviews documents for regulatory compliance against SOC 2 Type II controls. Flags potential violations and recommends remediation actions.", "version": "2.0.0", "profiles": [ "urn:adl:profile:governance:1.0" ], "lifecycle": { "status": "active", "effective_date": "2026-01-15T00:00:00Z" }, "data_classification": { "sensitivity": "confidential", "categories": [ "regulatory" ] }, "provider": { "name": "Acme Compliance", "url": "https://compliance.acme.example", "contact": "compliance@acme.example" }, "model": { "capabilities": [ "function_calling" ] }, "tools": [ { "name": "review_document", "description": "Review a document against compliance controls", "parameters": { "type": "object", "properties": { "document_id": { "type": "string" }, "framework": { "type": "string" } }, "required": [ "document_id", "framework" ] }, "read_only": true }, { "name": "generate_report", "description": "Generate a compliance report", "parameters": { "type": "object", "properties": { "review_id": { "type": "string" }, "format": { "type": "string", "enum": [ "pdf", "json", "html" ] } }, "required": [ "review_id" ] } } ], "permissions": { "network": { "allowed_hosts": [ "docs.acme.example", "api.acme.example" ], "allowed_protocols": [ "https" ], "deny_private": true }, "filesystem": { "allowed_paths": [ { "path": "/data/documents/**", "access": "read" }, { "path": "/data/reports/**", "access": "read_write" } ] } }, "security": { "authentication": { "type": "oauth2", "required": true, "scopes": [ "compliance:read", "compliance:write" ] }, "encryption": { "in_transit": { "required": true, "min_version": "1.2" } } }, "autonomy": { "tier": 2, "basis": "Agent reviews documents independently but requires human approval for compliance determinations affecting regulatory filings.", "classified_by": "AI Ethics Committee", "classified_at": "2026-01-10T00:00:00Z" }, "compliance_framework": { "primary_framework": "SOC2_TYPE_II", "audit_dates": { "last_audit": "2025-11-15T00:00:00Z", "next_audit": "2026-11-15T00:00:00Z" } }, "risk_classification": { "level": "medium", "autonomy_level": "L3", "assessed_by": "AI Ethics Committee", "assessed_at": "2026-01-10T00:00:00Z", "rationale": "Agent processes sensitive compliance data with conditional autonomy within defined review boundaries" }, "safety_reviews": { "required": true, "frequency": "quarterly", "last_review": "2026-01-15T00:00:00Z", "review_board": "AI Safety Board" }, "human_oversight": { "level": "on_exception", "role": "Compliance Officer", "triggers": [ "Compliance determination affecting regulatory filing", "Document classified as restricted sensitivity", "Remediation recommendation with estimated cost exceeding $50,000" ], "response_time_minutes": 60, "intervention_model": "approve_reject" }, "incident_response": { "policy_documented": true, "last_tested": "2026-02-01T00:00:00Z" }, "disclosure": { "required": true, "known_limitations": [ "May produce inaccurate regulatory citations for jurisdictions outside the US and EU", "Not trained on regulatory guidance published after 2025-12-01" ], "prohibited_uses": [ "Final regulatory determination without human review", "Legal advice to external parties" ], "reporting_contact": "mailto:ai-issues@acme.example" }, "governance": { "lifecycle_governance": { "transition_policy": { "requires_approval": true, "approvers": [ "security-team", "compliance-lead" ], "approval_type": "all" }, "last_transition": { "from_status": "draft", "to_status": "active", "approved_by": "compliance-lead", "approved_at": "2026-01-15T00:00:00Z", "reason": "Passed SOC2 audit, security review, and Tier 2 governance validation" } }, "ownership": { "owner": "Compliance Team", "delegate": "Security Team", "contact": "compliance@acme.example", "user_escalation_contact": "mailto:ai-support@acme.example", "decision_boundaries": [ { "decision_type": "regulatory_filing", "owner": "human_only", "rationale": "Regulatory filings require human sign-off per SOC2 CC6.1" }, { "decision_type": "document_review", "owner": "agent", "rationale": "Routine document reviews are within the agent's authorized scope" }, { "decision_type": "remediation_recommendation", "owner": "human_in_loop", "rationale": "Remediation actions may have budgetary implications" } ] }, "approval_workflow": { "required": true, "approvers": [ "compliance-lead", "security-lead" ], "approval_type": "all" }, "audit_trail": { "enabled": true, "retention_days": 730, "destination": "s3://acme-audit-logs/compliance-agent/" } }, "governance_record_ref": "https://gorvnd.acme.example/agents/compliance-review/governance-record", "metadata": { "authors": [ { "name": "Compliance Team", "email": "compliance@acme.example" } ], "license": "Proprietary", "documentation": "https://docs.acme.example/agents/compliance-review", "tags": [ "compliance", "soc2", "enterprise" ] } } ``` *** ## 5. Validation Rules[​](#5-validation-rules "Direct link to 5. Validation Rules") Validation Required Implementations validating against this profile **MUST** enforce the following rules. Non-conforming documents should be rejected. | Rule | Description | | ------ | ----------------------------------------------------------------------------------------------------------------------- | | GOV-01 | `compliance_framework` **MUST** be present | | GOV-02 | `compliance_framework.primary_framework` **MUST** be a valid framework identifier | | GOV-03 | `control_mappings[*].status` **MUST** be a valid status value | | GOV-04 | All timestamps **MUST** be valid ISO 8601 | | GOV-05 | `risk_classification.level` **MUST** be valid if present | | GOV-06 | `lifecycle` **MUST** be present (core member, Section 5.6) | | GOV-07 | `human_oversight.level` **MUST** be valid if present | | GOV-08 | `lifecycle_governance.last_transition.from_status` and `to_status` **MUST** be valid lifecycle status values if present | | GOV-09 | `lifecycle_governance.transition_policy.approval_type` **MUST** be one of `any`, `all`, `quorum` if present | | GOV-10 | `autonomy` **MUST** be present | | GOV-11 | `autonomy.tier` **MUST** be `1`, `2`, or `3` | | GOV-12 | At Tier 2+: `human_oversight` **MUST** be present | | GOV-13 | At Tier 2+: `human_oversight.triggers` and `human_oversight.response_time_minutes` **MUST** be present | | GOV-14 | At Tier 2+: `incident_response` **MUST** be present with `policy_documented: true` | | GOV-15 | At Tier 2+: `disclosure` **MUST** be present with `required: true` | | GOV-16 | At Tier 3: `evaluation_attestation` **MUST** be present with `result: passed` | | GOV-17 | At Tier 3: `governance_record_ref` **SHOULD** be present | | GOV-18 | `autonomy.classified_at` **MUST** be valid ISO 8601 | | GOV-19 | `risk_classification.autonomy_level` **MUST** be a valid L0–L5 value if present | | GOV-20 | `human_oversight.intervention_model` **MUST** be a valid enum value if present | | GOV-21 | `evaluation_attestation.result` **MUST** be a valid enum value if present | | GOV-22 | `evaluation_attestation.methodology` **MUST** be a valid enum value if present | | GOV-23 | `governance.ownership.decision_boundaries[*].owner` **MUST** be a valid enum value if present | | GOV-24 | `governance_record_ref` **MUST** be a valid URI if present | ### 5.1 Tier-Conditional Validation[​](#51-tier-conditional-validation "Direct link to 5.1 Tier-Conditional Validation") Tier-conditional rules (GOV-12 through GOV-17, and GOV-26) are evaluated using the value of `autonomy.tier`. Validators **MUST** resolve `autonomy.tier` before evaluating tier-conditional rules. If `autonomy` is absent, validation **MUST** fail at GOV-10 before reaching tier-conditional checks. The following table summarizes field requirements by tier: | Field | Tier 1 | Tier 2 | Tier 3 | | ---------------------------------------------------- | -------- | -------- | -------- | | `compliance_framework` | **MUST** | **MUST** | **MUST** | | `autonomy` | **MUST** | **MUST** | **MUST** | | `lifecycle` | **MUST** | **MUST** | **MUST** | | `human_oversight` | MAY | **MUST** | **MUST** | | `human_oversight.triggers` | MAY | **MUST** | **MUST** | | `human_oversight.response_time_minutes` | MAY | **MUST** | **MUST** | | `incident_response` (with `policy_documented: true`) | MAY | **MUST** | **MUST** | | `disclosure` (with `required: true`) | MAY | **MUST** | **MUST** | | `evaluation_attestation` (with `result: passed`) | MAY | MAY | **MUST** | | `governance_record_ref` | MAY | MAY | SHOULD | | `anomaly_baseline` | MAY | SHOULD | **MUST** | ### 5.2 Schema Validation[​](#52-schema-validation "Direct link to 5.2 Schema Validation") The governance profile provides a JSON Schema (`schema.json`) that extends the base ADL schema via `allOf` composition per Section 13.1 of the core specification. The profile schema: 1. References the base ADL schema via `allOf` with `$ref`. 2. Declares all governance-specific members in its own `properties`. 3. Enforces tier-conditional requirements using `if`/`then` on `autonomy.tier`. 4. Is an open additive mixin: it does **not** set a root `unevaluatedProperties`, so it composes with other profiles via `allOf`. Closure (`unevaluatedProperties: false`) is applied once over the composed schema per Section 13.1 of the core specification. Validators **SHOULD** use this schema for structural validation of documents declaring the governance profile. Semantic validation rules (GOV-01 through GOV-24) that cannot be expressed in JSON Schema **MUST** be enforced programmatically. ### 5.3 Profile Dependencies[​](#53-profile-dependencies "Direct link to 5.3 Profile Dependencies") This profile has no dependencies. Profiles that depend on the governance profile (e.g., a healthcare profile) compose by referencing this profile's schema in their own `allOf` and **MAY** tighten governance constraints (e.g., require `human_oversight` at Tier 1). See Section 13.3 of the core specification for dependency rules. *** ## 6. References[​](#6-references "Direct link to 6. References") The following works informed the design of this profile's conformance tiers, compliance mappings, and governance field requirements: * **\[IMDA-AGENTIC]** Infocomm Media Development Authority (IMDA), "Model AI Governance Framework for Agentic AI", Version 1.5, May 2026, . * **\[CLTC-AGENTIC]** Center for Long-Term Cybersecurity (CLTC), UC Berkeley, "Agentic AI Risk-Management Standards Profile", February 2026, . --- # Healthcare Profile Examples ## Clinical Research Assistant[​](#clinical-research-assistant "Direct link to Clinical Research Assistant") A clinical research agent that assists with patient record analysis and clinical trial matching, with full HIPAA compliance and PHI handling controls. * YAML * JSON clinical-research-agent.adl.yaml ``` $schema: https://adl-spec.org/0.3/schema.json adl_spec: 0.3.0 name: Clinical Research Assistant description: Assists researchers with patient record analysis and clinical trial matching. version: 1.0.0 profiles: - urn:adl:profile:healthcare:1.0 lifecycle: status: active effective_date: 2026-01-15T00:00:00Z provider: name: HealthTech Corp url: https://healthtech.example contact: compliance@healthtech.example model: capabilities: - function_calling tools: - name: search_patient_records description: Search de-identified patient records for clinical trial matching parameters: type: object properties: criteria: type: string limit: type: integer default: 20 required: - criteria read_only: true - name: generate_cohort_report description: Generate a cohort analysis report from matched records parameters: type: object properties: cohort_id: type: string format: type: string enum: - pdf - json required: - cohort_id permissions: network: allowed_hosts: - ehr.healthtech.example - fhir.healthtech.example allowed_protocols: - https deny_private: true filesystem: allowed_paths: - path: /data/deidentified/** access: read - path: /data/reports/** access: read_write security: authentication: type: oauth2 required: true scopes: - patient:read - report:write encryption: in_transit: required: true min_version: "1.2" at_rest: required: true algorithm: AES-256-GCM data_classification: sensitivity: restricted categories: - pii - phi retention: min_days: 2190 handling: encryption_required: true logging_required: true healthcare: phi_types: - demographics - medical_records hipaa_applicability: true hipaa_compliance: covered_entity_type: business_associate baa_required: true minimum_necessary: scope: task_specific justification: Access limited to de-identified records for clinical trial matching review_frequency: quarterly security_rule: encryption_at_rest: AES_256 encryption_in_transit: TLS_1_2 mfa_required: true data_retention: none restoration_hours: 72 phi_handling: de_identification: method: safe_harbor re_identification_controls: true breach_notification: notification_hours: 60 contact: privacy-officer@healthtech.example threshold: 500 consent_management: required: true consent_types: - research granularity: purpose_specific revocation_supported: true clinical_safety: bias_monitoring: enabled: true protected_classes: - race - ethnicity - sex - age assessment_frequency: quarterly last_assessment: 2026-01-01T00:00:00Z human_in_the_loop: level: approval_required role: Principal Investigator escalation_path: IRB Committee interoperability: fhir_version: R4 terminology_bindings: - ICD-10 - SNOMED-CT - LOINC information_blocking: compliant: true metadata: authors: - name: HealthTech Compliance Team email: compliance@healthtech.example license: Proprietary tags: - healthcare - hipaa - clinical-research - fhir ``` clinical-research-agent.adl.json ``` { "$schema": "https://adl-spec.org/0.3/schema.json", "adl_spec": "0.3.0", "name": "Clinical Research Assistant", "description": "Assists researchers with patient record analysis and clinical trial matching.", "version": "1.0.0", "profiles": [ "urn:adl:profile:healthcare:1.0" ], "lifecycle": { "status": "active", "effective_date": "2026-01-15T00:00:00Z" }, "provider": { "name": "HealthTech Corp", "url": "https://healthtech.example", "contact": "compliance@healthtech.example" }, "model": { "capabilities": [ "function_calling" ] }, "tools": [ { "name": "search_patient_records", "description": "Search de-identified patient records for clinical trial matching", "parameters": { "type": "object", "properties": { "criteria": { "type": "string" }, "limit": { "type": "integer", "default": 20 } }, "required": [ "criteria" ] }, "read_only": true }, { "name": "generate_cohort_report", "description": "Generate a cohort analysis report from matched records", "parameters": { "type": "object", "properties": { "cohort_id": { "type": "string" }, "format": { "type": "string", "enum": [ "pdf", "json" ] } }, "required": [ "cohort_id" ] } } ], "permissions": { "network": { "allowed_hosts": [ "ehr.healthtech.example", "fhir.healthtech.example" ], "allowed_protocols": [ "https" ], "deny_private": true }, "filesystem": { "allowed_paths": [ { "path": "/data/deidentified/**", "access": "read" }, { "path": "/data/reports/**", "access": "read_write" } ] } }, "security": { "authentication": { "type": "oauth2", "required": true, "scopes": [ "patient:read", "report:write" ] }, "encryption": { "in_transit": { "required": true, "min_version": "1.2" }, "at_rest": { "required": true, "algorithm": "AES-256-GCM" } } }, "data_classification": { "sensitivity": "restricted", "categories": [ "pii", "phi" ], "retention": { "min_days": 2190 }, "handling": { "encryption_required": true, "logging_required": true }, "healthcare": { "phi_types": [ "demographics", "medical_records" ], "hipaa_applicability": true } }, "hipaa_compliance": { "covered_entity_type": "business_associate", "baa_required": true, "minimum_necessary": { "scope": "task_specific", "justification": "Access limited to de-identified records for clinical trial matching", "review_frequency": "quarterly" }, "security_rule": { "encryption_at_rest": "AES_256", "encryption_in_transit": "TLS_1_2", "mfa_required": true, "data_retention": "none", "restoration_hours": 72 } }, "phi_handling": { "de_identification": { "method": "safe_harbor", "re_identification_controls": true }, "breach_notification": { "notification_hours": 60, "contact": "privacy-officer@healthtech.example", "threshold": 500 }, "consent_management": { "required": true, "consent_types": [ "research" ], "granularity": "purpose_specific", "revocation_supported": true } }, "clinical_safety": { "bias_monitoring": { "enabled": true, "protected_classes": [ "race", "ethnicity", "sex", "age" ], "assessment_frequency": "quarterly", "last_assessment": "2026-01-01T00:00:00Z" }, "human_in_the_loop": { "level": "approval_required", "role": "Principal Investigator", "escalation_path": "IRB Committee" } }, "interoperability": { "fhir_version": "R4", "terminology_bindings": [ "ICD-10", "SNOMED-CT", "LOINC" ], "information_blocking": { "compliant": true } }, "metadata": { "authors": [ { "name": "HealthTech Compliance Team", "email": "compliance@healthtech.example" } ], "license": "Proprietary", "tags": [ "healthcare", "hipaa", "clinical-research", "fhir" ] } } ``` ### Key Healthcare Fields[​](#key-healthcare-fields "Direct link to Key Healthcare Fields") | Field | Purpose | | -------------------------------- | ------------------------------------------------------------------------ | | `hipaa_compliance` | Covered entity type, BAA requirements, minimum necessary scope | | `phi_handling` | De-identification method, breach notification, consent management | | `clinical_safety` | Bias monitoring across protected classes, human-in-the-loop requirements | | `interoperability` | FHIR version, terminology bindings (ICD-10, SNOMED-CT, LOINC) | | `data_classification.healthcare` | PHI types and HIPAA applicability flag | ### Compliance Highlights[​](#compliance-highlights "Direct link to Compliance Highlights") * **HIPAA Security Rule**: AES-256 at rest, TLS 1.2+ in transit, MFA required * **De-identification**: Safe Harbor method with re-identification controls * **Breach Notification**: 60-hour notification window, 500-record threshold * **Consent**: Purpose-specific, revocation supported * **Bias Monitoring**: Quarterly assessment across race, ethnicity, sex, and age ## Composed with the Governance Profile[​](#composed-with-the-governance-profile "Direct link to Composed with the Governance Profile") The Healthcare Profile is designed to compose with the [Governance Profile](/profiles/governance/overview.md). This composite example declares both `urn:adl:profile:governance:1.0` and `urn:adl:profile:healthcare:1.0`, adding the governance-required `autonomy` and `compliance_framework` members on top of the healthcare members above. * YAML * JSON composite/governance-healthcare-agent.adl.yaml ``` $schema: https://adl-spec.org/0.3/schema.json adl_spec: 0.3.0 name: Clinical Research Assistant description: Assists researchers with patient record analysis and clinical trial matching. version: 1.0.0 profiles: - urn:adl:profile:governance:1.0 - urn:adl:profile:healthcare:1.0 lifecycle: status: active effective_date: 2026-01-15T00:00:00Z provider: name: HealthTech Corp url: https://healthtech.example contact: compliance@healthtech.example model: capabilities: - function_calling tools: - name: search_patient_records description: Search de-identified patient records for clinical trial matching parameters: type: object properties: criteria: type: string limit: type: integer default: 20 required: - criteria read_only: true - name: generate_cohort_report description: Generate a cohort analysis report from matched records parameters: type: object properties: cohort_id: type: string format: type: string enum: - pdf - json required: - cohort_id permissions: network: allowed_hosts: - ehr.healthtech.example - fhir.healthtech.example allowed_protocols: - https deny_private: true filesystem: allowed_paths: - path: /data/deidentified/** access: read - path: /data/reports/** access: read_write security: authentication: type: oauth2 required: true scopes: - patient:read - report:write encryption: in_transit: required: true min_version: "1.2" at_rest: required: true algorithm: AES-256-GCM data_classification: sensitivity: restricted categories: - pii - phi retention: min_days: 2190 handling: encryption_required: true logging_required: true healthcare: phi_types: - demographics - medical_records hipaa_applicability: true hipaa_compliance: covered_entity_type: business_associate baa_required: true minimum_necessary: scope: task_specific justification: Access limited to de-identified records for clinical trial matching review_frequency: quarterly security_rule: encryption_at_rest: AES_256 encryption_in_transit: TLS_1_2 mfa_required: true data_retention: none restoration_hours: 72 phi_handling: de_identification: method: safe_harbor re_identification_controls: true breach_notification: notification_hours: 60 contact: privacy-officer@healthtech.example threshold: 500 consent_management: required: true consent_types: - research granularity: purpose_specific revocation_supported: true clinical_safety: bias_monitoring: enabled: true protected_classes: - race - ethnicity - sex - age assessment_frequency: quarterly last_assessment: 2026-01-01T00:00:00Z human_in_the_loop: level: approval_required role: Principal Investigator escalation_path: IRB Committee interoperability: fhir_version: R4 terminology_bindings: - ICD-10 - SNOMED-CT - LOINC information_blocking: compliant: true autonomy: tier: 1 basis: Supervised clinical research support; cohort outputs reviewed by the Principal Investigator. classified_by: HealthTech Compliance Team classified_at: 2026-01-15T00:00:00Z compliance_framework: primary_framework: HIPAA control_mappings: - framework: HIPAA control_id: §164.312(a)(1) status: implemented - framework: HIPAA control_id: §164.312(e)(1) status: implemented - framework: NIST control_id: AC-6 status: implemented metadata: authors: - name: HealthTech Compliance Team email: compliance@healthtech.example license: Proprietary tags: - healthcare - hipaa - clinical-research - fhir ``` composite/governance-healthcare-agent.adl.json ``` { "$schema": "https://adl-spec.org/0.3/schema.json", "adl_spec": "0.3.0", "name": "Clinical Research Assistant", "description": "Assists researchers with patient record analysis and clinical trial matching.", "version": "1.0.0", "profiles": [ "urn:adl:profile:governance:1.0", "urn:adl:profile:healthcare:1.0" ], "lifecycle": { "status": "active", "effective_date": "2026-01-15T00:00:00Z" }, "provider": { "name": "HealthTech Corp", "url": "https://healthtech.example", "contact": "compliance@healthtech.example" }, "model": { "capabilities": [ "function_calling" ] }, "tools": [ { "name": "search_patient_records", "description": "Search de-identified patient records for clinical trial matching", "parameters": { "type": "object", "properties": { "criteria": { "type": "string" }, "limit": { "type": "integer", "default": 20 } }, "required": [ "criteria" ] }, "read_only": true }, { "name": "generate_cohort_report", "description": "Generate a cohort analysis report from matched records", "parameters": { "type": "object", "properties": { "cohort_id": { "type": "string" }, "format": { "type": "string", "enum": [ "pdf", "json" ] } }, "required": [ "cohort_id" ] } } ], "permissions": { "network": { "allowed_hosts": [ "ehr.healthtech.example", "fhir.healthtech.example" ], "allowed_protocols": [ "https" ], "deny_private": true }, "filesystem": { "allowed_paths": [ { "path": "/data/deidentified/**", "access": "read" }, { "path": "/data/reports/**", "access": "read_write" } ] } }, "security": { "authentication": { "type": "oauth2", "required": true, "scopes": [ "patient:read", "report:write" ] }, "encryption": { "in_transit": { "required": true, "min_version": "1.2" }, "at_rest": { "required": true, "algorithm": "AES-256-GCM" } } }, "data_classification": { "sensitivity": "restricted", "categories": [ "pii", "phi" ], "retention": { "min_days": 2190 }, "handling": { "encryption_required": true, "logging_required": true }, "healthcare": { "phi_types": [ "demographics", "medical_records" ], "hipaa_applicability": true } }, "hipaa_compliance": { "covered_entity_type": "business_associate", "baa_required": true, "minimum_necessary": { "scope": "task_specific", "justification": "Access limited to de-identified records for clinical trial matching", "review_frequency": "quarterly" }, "security_rule": { "encryption_at_rest": "AES_256", "encryption_in_transit": "TLS_1_2", "mfa_required": true, "data_retention": "none", "restoration_hours": 72 } }, "phi_handling": { "de_identification": { "method": "safe_harbor", "re_identification_controls": true }, "breach_notification": { "notification_hours": 60, "contact": "privacy-officer@healthtech.example", "threshold": 500 }, "consent_management": { "required": true, "consent_types": [ "research" ], "granularity": "purpose_specific", "revocation_supported": true } }, "clinical_safety": { "bias_monitoring": { "enabled": true, "protected_classes": [ "race", "ethnicity", "sex", "age" ], "assessment_frequency": "quarterly", "last_assessment": "2026-01-01T00:00:00Z" }, "human_in_the_loop": { "level": "approval_required", "role": "Principal Investigator", "escalation_path": "IRB Committee" } }, "interoperability": { "fhir_version": "R4", "terminology_bindings": [ "ICD-10", "SNOMED-CT", "LOINC" ], "information_blocking": { "compliant": true } }, "autonomy": { "tier": 1, "basis": "Supervised clinical research support; cohort outputs reviewed by the Principal Investigator.", "classified_by": "HealthTech Compliance Team", "classified_at": "2026-01-15T00:00:00Z" }, "compliance_framework": { "primary_framework": "HIPAA", "control_mappings": [ { "framework": "HIPAA", "control_id": "§164.312(a)(1)", "status": "implemented" }, { "framework": "HIPAA", "control_id": "§164.312(e)(1)", "status": "implemented" }, { "framework": "NIST", "control_id": "AC-6", "status": "implemented" } ] }, "metadata": { "authors": [ { "name": "HealthTech Compliance Team", "email": "compliance@healthtech.example" } ], "license": "Proprietary", "tags": [ "healthcare", "hipaa", "clinical-research", "fhir" ] } } ``` --- # Healthcare Profile Compatibility This document tracks compatibility between Healthcare Profile versions and ADL specification versions. ## Compatibility Matrix[​](#compatibility-matrix "Direct link to Compatibility Matrix") | Profile Version | ADL Versions | Status | Notes | | --------------- | ------------ | ------ | --------------- | | 1.0 | 0.3.x | Draft | Initial release | ## Compatibility Policy[​](#compatibility-policy "Direct link to Compatibility Policy") * **Minor ADL updates** (e.g., 0.1.0 -> 0.1.1): Profile remains compatible * **Major ADL updates** (e.g., 0.1.x -> 1.0.0): Profile compatibility will be evaluated; new profile version released if needed * **Breaking profile changes**: Require new major profile version ## Migration Guides[​](#migration-guides "Direct link to Migration Guides") *No migrations yet. This section will document how to upgrade between profile versions.* --- # Healthcare Profile | | | | --------------------- | -------------------------------- | | **Identifier** | `urn:adl:profile:healthcare:1.0` | | **Status** | Draft | | **ADL Compatibility** | 0.3.x | note This profile is in draft status. The specification is stable for early adoption, but minor changes may occur before 1.0. Regulatory Disclaimer This profile does not constitute legal, regulatory, or compliance advice. It has not been reviewed or endorsed by HHS, OCR, the FDA, or any regulatory body. Compliance with HIPAA requires qualified professional assessment specific to your organization. This profile does not substitute for a HIPAA risk assessment as required by 45 CFR §164.308(a)(1). ## Overview[​](#overview "Direct link to Overview") The Healthcare Profile extends ADL for healthcare and medical environments. It adds members for HIPAA compliance, Protected Health Information (PHI) handling, clinical safety controls, and health data interoperability. This profile addresses requirements from HIPAA, HITECH, FDA AI/ML guidance, HL7 FHIR, and the 21st Century Cures Act. This profile is designed to compose with the [Governance Profile](/profiles/governance/overview.md). Organizations **SHOULD** declare both profiles for full enterprise healthcare compliance coverage. ## Use Cases[​](#use-cases "Direct link to Use Cases") * Electronic Health Record (EHR) integration agents * Clinical decision support systems * Clinical research and trial matching assistants * Patient communication agents * Healthcare administrative and billing agents * Medical imaging analysis agents ## Quick Start[​](#quick-start "Direct link to Quick Start") Add the Healthcare Profile to your ADL document: ``` { "adl_spec": "0.3.0", "name": "Clinical Research Assistant", "description": "Assists with patient record analysis and trial matching.", "version": "1.0.0", "profiles": ["urn:adl:profile:healthcare:1.0"], "data_classification": { "sensitivity": "restricted", "categories": ["pii", "phi"], "healthcare": { "phi_types": ["demographics", "medical_records"] } }, "hipaa_compliance": { "covered_entity_type": "business_associate", "baa_required": true, "minimum_necessary": { "scope": "task_specific" } }, "phi_handling": { "de_identification": { "method": "safe_harbor" }, "breach_notification": { "notification_hours": 60, "contact": "privacy-officer@example.com" } } } ``` ## Additional Members[​](#additional-members "Direct link to Additional Members") The Healthcare Profile adds the following top-level members: | Member | Required | Description | | -------------------------------- | ------------ | --------------------------------------------------------------------------- | | `data_classification.healthcare` | **REQUIRED** | PHI types (composable; extends core `data_classification`) | | `hipaa_compliance` | **REQUIRED** | HIPAA entity type, minimum necessary access, Security Rule settings | | `phi_handling` | **REQUIRED** | De-identification, breach notification, consent management, data provenance | | `clinical_safety` | Optional | FDA classification, PCCP change control, bias monitoring, human-in-the-loop | | `interoperability` | Optional | FHIR version, terminology bindings, information blocking, DSI transparency | See the [full specification](/profiles/healthcare/specification.md) for detailed member definitions. ## Regulatory Foundation[​](#regulatory-foundation "Direct link to Regulatory Foundation") This profile maps requirements from: * **HIPAA** (45 CFR Parts 160, 164) — Privacy, Security, and Breach Notification Rules * **HITECH Act** — Extended HIPAA to business associates * **42 CFR Part 2** — Substance use disorder record protections * **FDA AI/ML Guidance** — PCCP framework for AI model change control * **HL7 FHIR** — Health data interoperability (R4, R5) * **ONC HTI-1** — Decision Support Intervention transparency * **21st Century Cures Act** — Information blocking prohibitions * **NIST AI RMF** — AI risk management framework --- # Healthcare Profile Specification | | | | --------------------- | -------------------------------- | | **Identifier** | `urn:adl:profile:healthcare:1.0` | | **Status** | Draft | | **ADL Compatibility** | 0.3.x | Regulatory Disclaimer This profile is provided as a technical specification in DRAFT status and does not constitute legal, regulatory, or compliance advice. It has not been reviewed or endorsed by HHS, OCR, the FDA, or any regulatory body. Organizations MUST NOT rely on this profile as their sole basis for regulatory compliance. Compliance with HIPAA, HITECH, FDA regulations, or any other healthcare regulatory framework requires qualified professional assessment specific to your organization's circumstances. This profile does not substitute for a HIPAA risk assessment as required by 45 CFR §164.308(a)(1). ## 1. Introduction[​](#1-introduction "Direct link to 1. Introduction") The Healthcare Profile extends ADL for healthcare environments. It adds members for HIPAA compliance, Protected Health Information (PHI) handling, clinical safety controls, and health data interoperability. This profile addresses requirements from HIPAA (Privacy, Security, and Breach Notification Rules), HITECH, FDA AI/ML guidance, HL7 FHIR, ONC Health IT certification, and the 21st Century Cures Act. When this profile is declared in an ADL document's `profiles` array, the document **MUST** satisfy all requirements defined in this specification. This profile is designed to compose with the Governance Profile. Organizations **SHOULD** declare both profiles for full enterprise healthcare compliance coverage. *** ## 2. Additional Members[​](#2-additional-members "Direct link to 2. Additional Members") ### 2.1 hipaa\_compliance[​](#21-hipaa_compliance "Direct link to 2.1 hipaa_compliance") **REQUIRED** when using this profile. An object containing HIPAA regulatory compliance configuration. | Member | Type | Required | Description | | --------------------- | ------ | -------- | -------------------------------------------------- | | covered\_entity\_type | string | REQUIRED | Entity classification under HIPAA | | baa\_required | bool | REQUIRED | Whether a Business Associate Agreement is required | | minimum\_necessary | object | REQUIRED | Minimum necessary access configuration | | security\_rule | object | OPTIONAL | Security Rule compliance settings | note PHI categories have moved to the composable member (Section 2.5). This enables consistent data classification across profiles and reuse within tools and resources. #### covered\_entity\_type[​](#covered_entity_type "Direct link to covered_entity_type") **MUST** be one of: * `covered_entity` — Health plan, healthcare clearinghouse, or healthcare provider * `business_associate` — Entity performing functions involving PHI on behalf of a covered entity * `subcontractor` — Business associate of a business associate #### minimum\_necessary[​](#minimum_necessary "Direct link to minimum_necessary") **MUST** be an object containing: | Member | Type | Required | Description | | ----------------- | ------ | -------- | ---------------------------------- | | scope | string | REQUIRED | Access scope level | | justification | string | OPTIONAL | Reason for access level | | review\_frequency | string | OPTIONAL | How often access scope is reviewed | `scope` **MUST** be one of: `task_specific`, `role_based`, `full_record`. #### security\_rule[​](#security_rule "Direct link to security_rule") When present, **MAY** contain: | Member | Type | Description | | ----------------------- | ------ | ----------------------------------------------- | | encryption\_at\_rest | string | Required algorithm: `AES_256`, `AES_128` | | encryption\_in\_transit | string | Required protocol: `TLS_1_2`, `TLS_1_3` | | mfa\_required | bool | Whether multi-factor authentication is required | | data\_retention | string | Retention policy: `none`, `minimum`, `standard` | | restoration\_hours | number | Maximum hours to restore critical systems | *** ### 2.2 phi\_handling[​](#22-phi_handling "Direct link to 2.2 phi_handling") **REQUIRED** when using this profile. An object containing PHI data handling and de-identification controls. | Member | Type | Required | Description | | -------------------- | ------ | -------- | ------------------------------------------ | | de\_identification | object | REQUIRED | De-identification method and configuration | | breach\_notification | object | REQUIRED | Breach notification configuration | | consent\_management | object | OPTIONAL | Patient consent tracking | | data\_provenance | object | OPTIONAL | Data lineage tracking | #### de\_identification[​](#de_identification "Direct link to de_identification") **MUST** be an object containing: | Member | Type | Required | Description | | ---------------------------- | ------ | -------- | ---------------------------------------------- | | method | string | REQUIRED | De-identification method | | re\_identification\_controls | bool | OPTIONAL | Whether re-identification prevention is active | `method` **MUST** be one of: `safe_harbor`, `expert_determination`, `none`. #### breach\_notification[​](#breach_notification "Direct link to breach_notification") **MUST** be an object containing: | Member | Type | Required | Description | | ------------------- | ------ | -------- | ---------------------------------------------------------------- | | notification\_hours | number | REQUIRED | Maximum hours to notify authorities | | contact | string | REQUIRED | Breach notification contact | | threshold | number | OPTIONAL | Number of affected individuals triggering escalated notification | #### consent\_management[​](#consent_management "Direct link to consent_management") When present, **MAY** contain: | Member | Type | Description | | --------------------- | ------ | -------------------------------------------------------------------- | | required | bool | Whether explicit consent is required | | consent\_types | array | Types: `treatment`, `payment`, `operations`, `research`, `marketing` | | granularity | string | Consent granularity: `broad`, `purpose_specific`, `data_specific` | | revocation\_supported | bool | Whether consent revocation is supported | #### data\_provenance[​](#data_provenance "Direct link to data_provenance") When present, **MAY** contain: | Member | Type | Description | | --------------- | ----- | ---------------------------------------- | | tracking | bool | Whether data lineage tracking is enabled | | source\_systems | array | List of source system identifiers | *** ### 2.3 clinical\_safety[​](#23-clinical_safety "Direct link to 2.3 clinical_safety") **OPTIONAL.** An object containing clinical safety controls for agents involved in clinical decision support or patient-facing interactions. | Member | Type | Required | Description | | -------------------- | ------ | -------- | -------------------------------------- | | fda\_classification | object | OPTIONAL | FDA device/software classification | | change\_control | object | OPTIONAL | Model change management (PCCP-aligned) | | bias\_monitoring | object | OPTIONAL | Bias detection and mitigation | | human\_in\_the\_loop | object | OPTIONAL | Clinical decision oversight | #### fda\_classification[​](#fda_classification "Direct link to fda_classification") When present, **MAY** contain: | Member | Type | Description | | ----------------- | ------ | ------------------------------------------------------------- | | device\_class | string | `exempt`, `class_I`, `class_II`, `class_III`, `non_device` | | clearance\_type | string | `510k`, `de_novo`, `pma`, `not_applicable` | | clearance\_number | string | FDA clearance/approval number | | software\_level | string | `non_significant_risk`, `significant_risk`, `life_supporting` | #### change\_control[​](#change_control "Direct link to change_control") Aligned with FDA Predetermined Change Control Plan (PCCP) guidance. When present, **MAY** contain: | Member | Type | Description | | --------------------- | ------ | ------------------------------------------- | | pccp\_authorized | bool | Whether a PCCP has been FDA-authorized | | modification\_scope | array | Authorized modification types | | validation\_protocol | string | URI to validation protocol | | rollback\_plan | bool | Whether rollback capability exists | | monitoring\_frequency | string | Real-world performance monitoring frequency | #### bias\_monitoring[​](#bias_monitoring "Direct link to bias_monitoring") When present, **MAY** contain: | Member | Type | Description | | --------------------- | ------ | --------------------------------- | | enabled | bool | Whether bias monitoring is active | | protected\_classes | array | Demographics monitored for bias | | assessment\_frequency | string | How often bias is assessed | | last\_assessment | string | ISO 8601 timestamp | #### human\_in\_the\_loop[​](#human_in_the_loop "Direct link to human_in_the_loop") When present, **MAY** contain: | Member | Type | Description | | ---------------- | ------ | ------------------------------------------------------------------- | | level | string | `advisory`, `approval_required`, `continuous_oversight` | | role | string | Clinical role responsible (e.g., "Physician", "Nurse Practitioner") | | escalation\_path | string | Escalation contact or procedure | *** ### 2.4 interoperability[​](#24-interoperability "Direct link to 2.4 interoperability") **OPTIONAL.** An object containing health data interoperability standards compliance. | Member | Type | Required | Description | | --------------------- | ------ | -------- | ---------------------------------------------- | | fhir\_version | string | OPTIONAL | Supported FHIR version | | terminology\_bindings | array | OPTIONAL | Supported code systems | | tefca\_participant | bool | OPTIONAL | Whether agent participates in TEFCA | | information\_blocking | object | OPTIONAL | 21st Century Cures Act compliance | | dsi\_transparency | object | OPTIONAL | ONC Decision Support Intervention transparency | #### fhir\_version[​](#fhir_version "Direct link to fhir_version") When present, **MUST** be one of: `DSTU2`, `STU3`, `R4`, `R4B`, `R5`. #### terminology\_bindings[​](#terminology_bindings "Direct link to terminology_bindings") When present, **MUST** be an array of strings. Common values: `ICD-10`, `SNOMED-CT`, `LOINC`, `RxNorm`, `CPT`, `HCPCS`. #### information\_blocking[​](#information_blocking "Direct link to information_blocking") When present, **MAY** contain: | Member | Type | Description | | ------------------- | ----- | ----------------------------------------------- | | compliant | bool | Whether agent is information blocking compliant | | exceptions\_claimed | array | Any claimed exceptions per 45 CFR Part 171 | #### dsi\_transparency[​](#dsi_transparency "Direct link to dsi_transparency") When present, **MAY** contain: | Member | Type | Description | | ----------------------------- | ---- | ------------------------------------------------------------- | | predictive\_dsi | bool | Whether agent includes predictive DSI | | source\_attributes\_published | bool | Whether source attributes are disclosed | | irm\_practices | bool | Whether Intervention Risk Management practices are documented | *** ### 2.5 data\_classification Extension[​](#25-data_classification-extension "Direct link to 2.5 data_classification Extension") This profile extends the core ADL `data_classification` member (Spec §10.4) with a `healthcare` sub-object for PHI classification. **REQUIRED** when using this profile. The `data_classification` member **MUST** be present with a `healthcare` sub-object. The `data_classification.categories` array **MUST** include `phi`. #### healthcare[​](#healthcare "Direct link to healthcare") An object containing healthcare-specific data classification. When present, **MUST** contain: | Member | Type | Required | Description | | -------------------- | ----- | -------- | -------------------------------------------- | | phi\_types | array | REQUIRED | Categories of PHI the agent may access | | hipaa\_applicability | bool | OPTIONAL | Whether HIPAA applies to this classification | #### phi\_types[​](#phi_types "Direct link to phi_types") **MUST** be a non-empty array. Each item **MUST** be one of: * `demographics` — Patient demographic information * `medical_records` — Clinical and medical record data * `billing` — Billing and payment information * `mental_health` — Mental and behavioral health records * `substance_use` — Substance use disorder records (42 CFR Part 2) * `genetic` — Genetic information (GINA) * `reproductive` — Reproductive health information * `hiv_status` — HIV/AIDS status information Example: ``` { "data_classification": { "sensitivity": "restricted", "categories": ["pii", "phi"], "retention": { "min_days": 2190, "policy_uri": "https://healthtech.example/retention-policy" }, "handling": { "encryption_required": true, "logging_required": true }, "healthcare": { "phi_types": ["demographics", "medical_records"], "hipaa_applicability": true } } } ``` *** ## 3. Compliance Mapping[​](#3-compliance-mapping "Direct link to 3. Compliance Mapping") | ADL / Profile Section | Regulatory Controls | | ------------------------------------------ | --------------------------------------------- | | data\_classification.healthcare.phi\_types | HIPAA §164.514; NIST 800-53 SC-16 | | hipaa\_compliance.security\_rule | HIPAA §164.312; NIST 800-53 SC-8, SC-13, AC-3 | | hipaa\_compliance.minimum\_necessary | HIPAA §164.502(b); NIST 800-53 AC-6 | | phi\_handling.de\_identification | HIPAA §164.514; NIST 800-53 SI-19 | | phi\_handling.consent\_management | HIPAA §164.508; 42 CFR Part 2 | | phi\_handling.breach\_notification | HIPAA §164.400-414; HITECH §13402 | | clinical\_safety.fda\_classification | FDA 21 CFR 820; ISO 13485 | | clinical\_safety.change\_control | FDA PCCP Guidance; 21 CFR 820.30 | | clinical\_safety.bias\_monitoring | NIST AI RMF; ONC HTI-1 DSI requirements | | interoperability.fhir\_version | HL7 FHIR; ONC Cures Act Final Rule | | interoperability.information\_blocking | 21st Century Cures Act §4004; 45 CFR Part 171 | | interoperability.dsi\_transparency | ONC HTI-1 Final Rule §170.315(b)(11) | *** ## 4. Example[​](#4-example "Direct link to 4. Example") Complete Example This example demonstrates a complete agent definition using this profile. clinical-research-agent.json ``` { "$schema": "https://adl-spec.org/0.3/schema.json", "adl_spec": "0.3.0", "name": "Clinical Research Assistant", "description": "Assists researchers with patient record analysis and clinical trial matching.", "version": "1.0.0", "profiles": [ "urn:adl:profile:healthcare:1.0" ], "lifecycle": { "status": "active", "effective_date": "2026-01-15T00:00:00Z" }, "provider": { "name": "HealthTech Corp", "url": "https://healthtech.example", "contact": "compliance@healthtech.example" }, "model": { "capabilities": [ "function_calling" ] }, "tools": [ { "name": "search_patient_records", "description": "Search de-identified patient records for clinical trial matching", "parameters": { "type": "object", "properties": { "criteria": { "type": "string" }, "limit": { "type": "integer", "default": 20 } }, "required": [ "criteria" ] }, "read_only": true }, { "name": "generate_cohort_report", "description": "Generate a cohort analysis report from matched records", "parameters": { "type": "object", "properties": { "cohort_id": { "type": "string" }, "format": { "type": "string", "enum": [ "pdf", "json" ] } }, "required": [ "cohort_id" ] } } ], "permissions": { "network": { "allowed_hosts": [ "ehr.healthtech.example", "fhir.healthtech.example" ], "allowed_protocols": [ "https" ], "deny_private": true }, "filesystem": { "allowed_paths": [ { "path": "/data/deidentified/**", "access": "read" }, { "path": "/data/reports/**", "access": "read_write" } ] } }, "security": { "authentication": { "type": "oauth2", "required": true, "scopes": [ "patient:read", "report:write" ] }, "encryption": { "in_transit": { "required": true, "min_version": "1.2" }, "at_rest": { "required": true, "algorithm": "AES-256-GCM" } } }, "data_classification": { "sensitivity": "restricted", "categories": [ "pii", "phi" ], "retention": { "min_days": 2190 }, "handling": { "encryption_required": true, "logging_required": true }, "healthcare": { "phi_types": [ "demographics", "medical_records" ], "hipaa_applicability": true } }, "hipaa_compliance": { "covered_entity_type": "business_associate", "baa_required": true, "minimum_necessary": { "scope": "task_specific", "justification": "Access limited to de-identified records for clinical trial matching", "review_frequency": "quarterly" }, "security_rule": { "encryption_at_rest": "AES_256", "encryption_in_transit": "TLS_1_2", "mfa_required": true, "data_retention": "none", "restoration_hours": 72 } }, "phi_handling": { "de_identification": { "method": "safe_harbor", "re_identification_controls": true }, "breach_notification": { "notification_hours": 60, "contact": "privacy-officer@healthtech.example", "threshold": 500 }, "consent_management": { "required": true, "consent_types": [ "research" ], "granularity": "purpose_specific", "revocation_supported": true } }, "clinical_safety": { "bias_monitoring": { "enabled": true, "protected_classes": [ "race", "ethnicity", "sex", "age" ], "assessment_frequency": "quarterly", "last_assessment": "2026-01-01T00:00:00Z" }, "human_in_the_loop": { "level": "approval_required", "role": "Principal Investigator", "escalation_path": "IRB Committee" } }, "interoperability": { "fhir_version": "R4", "terminology_bindings": [ "ICD-10", "SNOMED-CT", "LOINC" ], "information_blocking": { "compliant": true } }, "metadata": { "authors": [ { "name": "HealthTech Compliance Team", "email": "compliance@healthtech.example" } ], "license": "Proprietary", "tags": [ "healthcare", "hipaa", "clinical-research", "fhir" ] } } ``` *** ## 5. Validation Rules[​](#5-validation-rules "Direct link to 5. Validation Rules") Validation Required Implementations validating against this profile **MUST** enforce the following rules. Non-conforming documents should be rejected. | Rule | Description | | ----- | ----------------------------------------------------------------------------------------------------------------------------------------- | | HC-01 | `hipaa_compliance` MUST be present | | HC-02 | `hipaa_compliance.covered_entity_type` MUST be a valid type | | HC-03 | `data_classification.healthcare.phi_types` MUST be a non-empty array of valid types | | HC-04 | `hipaa_compliance.baa_required` MUST be present | | HC-05 | `hipaa_compliance.minimum_necessary` MUST be present with valid `scope` | | HC-06 | `hipaa_compliance.security_rule.encryption_at_rest` MUST be `AES_256` or `AES_128` if present | | HC-07 | `hipaa_compliance.security_rule.encryption_in_transit` MUST be `TLS_1_2` or `TLS_1_3` if present | | HC-08 | `phi_handling` MUST be present | | HC-09 | `phi_handling.de_identification.method` MUST be a valid method | | HC-10 | `phi_handling.breach_notification` MUST be present with `notification_hours` and `contact` | | HC-11 | If `data_classification.healthcare.phi_types` includes `substance_use`, `phi_handling.consent_management` MUST be present (42 CFR Part 2) | | HC-12 | All timestamps MUST be valid ISO 8601 | | HC-13 | `interoperability.fhir_version` MUST be a valid version if present | | HC-14 | If `clinical_safety.fda_classification.device_class` is not `exempt` or `non_device`, `clinical_safety.change_control` MUST be present | | HC-15 | If `interoperability.dsi_transparency.predictive_dsi` is true, `source_attributes_published` and `irm_practices` MUST be true | | HC-16 | `data_classification` MUST be present with a `healthcare` sub-object | | HC-17 | `data_classification.categories` MUST include `phi` | --- # Portfolio Profile Examples ## Customer Service Agent[​](#customer-service-agent "Direct link to Customer Service Agent") A tier-1 support agent with defined relationships to peer agents, dependencies, and an orchestrator within the customer service domain. * YAML * JSON customer-service-agent.adl.yaml ``` $schema: https://adl-spec.org/profiles/portfolio/1.0/schema.json adl_spec: 0.3.0 name: Customer Service Agent description: Handles tier-1 customer inquiries and support requests via chat and email channels. version: 1.2.0 profiles: - urn:adl:profile:portfolio:1.0 data_classification: sensitivity: internal categories: - pii provider: name: Acme Support url: https://support.acme.example contact: support-engineering@acme.example model: capabilities: - function_calling - streaming tools: - name: search_knowledge_base description: Search the knowledge base for relevant articles parameters: type: object properties: query: type: string limit: type: integer default: 5 required: - query read_only: true - name: create_ticket description: Create a support ticket for escalation parameters: type: object properties: subject: type: string description: type: string priority: type: string enum: - low - medium - high - urgent customer_id: type: string required: - subject - description - customer_id requires_confirmation: true - name: get_customer_info description: Retrieve customer information parameters: type: object properties: customer_id: type: string required: - customer_id read_only: true permissions: network: allowed_hosts: - api.acme.example - kb.acme.example - tickets.acme.example allowed_protocols: - https deny_private: true security: authentication: type: oauth2 required: true scopes: - customers:read - tickets:write - kb:read encryption: in_transit: required: true min_version: "1.2" relationships: depends_on: - urn:adl:agent:acme:knowledge-base-agent:1.0 - urn:adl:agent:acme:ticket-api-agent:2.0 - urn:adl:agent:acme:customer-data-agent:1.5 orchestrated_by: urn:adl:agent:acme:support-orchestrator:1.0 peers: - urn:adl:agent:acme:billing-support-agent:1.0 - urn:adl:agent:acme:technical-support-agent:1.0 - urn:adl:agent:acme:returns-agent:1.0 domain: domain_id: urn:domain:customer-service subdomain: inquiries bounded_context: support-portal role: primary-handler metadata: authors: - name: Support Engineering email: support-engineering@acme.example license: Proprietary documentation: https://docs.acme.example/agents/customer-service tags: - customer-service - support - production ``` customer-service-agent.adl.json ``` { "$schema": "https://adl-spec.org/profiles/portfolio/1.0/schema.json", "adl_spec": "0.3.0", "name": "Customer Service Agent", "description": "Handles tier-1 customer inquiries and support requests via chat and email channels.", "version": "1.2.0", "profiles": [ "urn:adl:profile:portfolio:1.0" ], "data_classification": { "sensitivity": "internal", "categories": [ "pii" ] }, "provider": { "name": "Acme Support", "url": "https://support.acme.example", "contact": "support-engineering@acme.example" }, "model": { "capabilities": [ "function_calling", "streaming" ] }, "tools": [ { "name": "search_knowledge_base", "description": "Search the knowledge base for relevant articles", "parameters": { "type": "object", "properties": { "query": { "type": "string" }, "limit": { "type": "integer", "default": 5 } }, "required": [ "query" ] }, "read_only": true }, { "name": "create_ticket", "description": "Create a support ticket for escalation", "parameters": { "type": "object", "properties": { "subject": { "type": "string" }, "description": { "type": "string" }, "priority": { "type": "string", "enum": [ "low", "medium", "high", "urgent" ] }, "customer_id": { "type": "string" } }, "required": [ "subject", "description", "customer_id" ] }, "requires_confirmation": true }, { "name": "get_customer_info", "description": "Retrieve customer information", "parameters": { "type": "object", "properties": { "customer_id": { "type": "string" } }, "required": [ "customer_id" ] }, "read_only": true } ], "permissions": { "network": { "allowed_hosts": [ "api.acme.example", "kb.acme.example", "tickets.acme.example" ], "allowed_protocols": [ "https" ], "deny_private": true } }, "security": { "authentication": { "type": "oauth2", "required": true, "scopes": [ "customers:read", "tickets:write", "kb:read" ] }, "encryption": { "in_transit": { "required": true, "min_version": "1.2" } } }, "relationships": { "depends_on": [ "urn:adl:agent:acme:knowledge-base-agent:1.0", "urn:adl:agent:acme:ticket-api-agent:2.0", "urn:adl:agent:acme:customer-data-agent:1.5" ], "orchestrated_by": "urn:adl:agent:acme:support-orchestrator:1.0", "peers": [ "urn:adl:agent:acme:billing-support-agent:1.0", "urn:adl:agent:acme:technical-support-agent:1.0", "urn:adl:agent:acme:returns-agent:1.0" ] }, "domain": { "domain_id": "urn:domain:customer-service", "subdomain": "inquiries", "bounded_context": "support-portal", "role": "primary-handler" }, "metadata": { "authors": [ { "name": "Support Engineering", "email": "support-engineering@acme.example" } ], "license": "Proprietary", "documentation": "https://docs.acme.example/agents/customer-service", "tags": [ "customer-service", "support", "production" ] } } ``` ### Key Portfolio Fields[​](#key-portfolio-fields "Direct link to Key Portfolio Fields") | Field | Purpose | | ------------------------------- | ---------------------------------------------- | | `relationships.depends_on` | Agents this agent requires to function | | `relationships.orchestrated_by` | The orchestrator that coordinates this agent | | `relationships.peers` | Sibling agents in the same domain | | `domain.domain_id` | Domain membership identifier | | `domain.bounded_context` | The bounded context this agent operates within | | `domain.role` | The agent's role within the domain | ### Agent Topology[​](#agent-topology "Direct link to Agent Topology") ``` support-orchestrator (orchestrator) ├── customer-service-agent (this agent) ├── billing-support-agent (peer) ├── technical-support-agent (peer) └── returns-agent (peer) ``` Dependencies: `knowledge-base-agent`, `ticket-api-agent`, `customer-data-agent` ## Composed with the Registry Profile[​](#composed-with-the-registry-profile "Direct link to Composed with the Registry Profile") The Portfolio Profile composes with other profiles via `allOf`. This composite example declares both `urn:adl:profile:registry:1.0` and `urn:adl:profile:portfolio:1.0`, pairing catalog identity with the relationship and domain members above. * YAML * JSON composite/registry-portfolio-agent.adl.yaml ``` $schema: https://adl-spec.org/profiles/portfolio/1.0/schema.json adl_spec: 0.3.0 name: Customer Service Agent description: Handles tier-1 customer inquiries and support requests via chat and email channels. version: 1.2.0 profiles: - urn:adl:profile:registry:1.0 - urn:adl:profile:portfolio:1.0 data_classification: sensitivity: internal categories: - pii provider: name: Acme Support url: https://support.acme.example contact: support-engineering@acme.example model: capabilities: - function_calling - streaming tools: - name: search_knowledge_base description: Search the knowledge base for relevant articles parameters: type: object properties: query: type: string limit: type: integer default: 5 required: - query read_only: true - name: create_ticket description: Create a support ticket for escalation parameters: type: object properties: subject: type: string description: type: string priority: type: string enum: - low - medium - high - urgent customer_id: type: string required: - subject - description - customer_id requires_confirmation: true - name: get_customer_info description: Retrieve customer information parameters: type: object properties: customer_id: type: string required: - customer_id read_only: true permissions: network: allowed_hosts: - api.acme.example - kb.acme.example - tickets.acme.example allowed_protocols: - https deny_private: true security: authentication: type: oauth2 required: true scopes: - customers:read - tickets:write - kb:read encryption: in_transit: required: true min_version: "1.2" registry: catalog_id: cs-agent-001 catalog_classification: - domain: support subdomain: customer-service capability: conversational visibility: internal relationships: depends_on: - urn:adl:agent:acme:knowledge-base-agent:1.0 - urn:adl:agent:acme:ticket-api-agent:2.0 - urn:adl:agent:acme:customer-data-agent:1.5 orchestrated_by: urn:adl:agent:acme:support-orchestrator:1.0 peers: - urn:adl:agent:acme:billing-support-agent:1.0 - urn:adl:agent:acme:technical-support-agent:1.0 - urn:adl:agent:acme:returns-agent:1.0 domain: domain_id: urn:domain:customer-service subdomain: inquiries bounded_context: support-portal role: primary-handler metadata: authors: - name: Support Engineering email: support-engineering@acme.example license: Proprietary documentation: https://docs.acme.example/agents/customer-service tags: - customer-service - support - production ``` composite/registry-portfolio-agent.adl.json ``` { "$schema": "https://adl-spec.org/profiles/portfolio/1.0/schema.json", "adl_spec": "0.3.0", "name": "Customer Service Agent", "description": "Handles tier-1 customer inquiries and support requests via chat and email channels.", "version": "1.2.0", "profiles": [ "urn:adl:profile:registry:1.0", "urn:adl:profile:portfolio:1.0" ], "data_classification": { "sensitivity": "internal", "categories": [ "pii" ] }, "provider": { "name": "Acme Support", "url": "https://support.acme.example", "contact": "support-engineering@acme.example" }, "model": { "capabilities": [ "function_calling", "streaming" ] }, "tools": [ { "name": "search_knowledge_base", "description": "Search the knowledge base for relevant articles", "parameters": { "type": "object", "properties": { "query": { "type": "string" }, "limit": { "type": "integer", "default": 5 } }, "required": [ "query" ] }, "read_only": true }, { "name": "create_ticket", "description": "Create a support ticket for escalation", "parameters": { "type": "object", "properties": { "subject": { "type": "string" }, "description": { "type": "string" }, "priority": { "type": "string", "enum": [ "low", "medium", "high", "urgent" ] }, "customer_id": { "type": "string" } }, "required": [ "subject", "description", "customer_id" ] }, "requires_confirmation": true }, { "name": "get_customer_info", "description": "Retrieve customer information", "parameters": { "type": "object", "properties": { "customer_id": { "type": "string" } }, "required": [ "customer_id" ] }, "read_only": true } ], "permissions": { "network": { "allowed_hosts": [ "api.acme.example", "kb.acme.example", "tickets.acme.example" ], "allowed_protocols": [ "https" ], "deny_private": true } }, "security": { "authentication": { "type": "oauth2", "required": true, "scopes": [ "customers:read", "tickets:write", "kb:read" ] }, "encryption": { "in_transit": { "required": true, "min_version": "1.2" } } }, "registry": { "catalog_id": "cs-agent-001", "catalog_classification": [ { "domain": "support", "subdomain": "customer-service", "capability": "conversational" } ], "visibility": "internal" }, "relationships": { "depends_on": [ "urn:adl:agent:acme:knowledge-base-agent:1.0", "urn:adl:agent:acme:ticket-api-agent:2.0", "urn:adl:agent:acme:customer-data-agent:1.5" ], "orchestrated_by": "urn:adl:agent:acme:support-orchestrator:1.0", "peers": [ "urn:adl:agent:acme:billing-support-agent:1.0", "urn:adl:agent:acme:technical-support-agent:1.0", "urn:adl:agent:acme:returns-agent:1.0" ] }, "domain": { "domain_id": "urn:domain:customer-service", "subdomain": "inquiries", "bounded_context": "support-portal", "role": "primary-handler" }, "metadata": { "authors": [ { "name": "Support Engineering", "email": "support-engineering@acme.example" } ], "license": "Proprietary", "documentation": "https://docs.acme.example/agents/customer-service", "tags": [ "customer-service", "support", "production" ] } } ``` --- # Portfolio Profile Compatibility This document tracks compatibility between Portfolio Profile versions and ADL specification versions. ## Compatibility Matrix[​](#compatibility-matrix "Direct link to Compatibility Matrix") | Profile Version | ADL Versions | Status | Notes | | --------------- | ------------ | ------ | ------------------------------------------------------------------------- | | 1.0 | 0.3.x | Draft | Relationships and domain membership; catalog identity in Registry Profile | ## Compatibility Policy[​](#compatibility-policy "Direct link to Compatibility Policy") * **Minor ADL updates** (e.g., 0.1.0 → 0.1.1): Profile remains compatible * **Major ADL updates** (e.g., 0.1.x → 1.0.0): Profile compatibility will be evaluated; new profile version released if needed * **Breaking profile changes**: Require new major profile version ## Migration Guides[​](#migration-guides "Direct link to Migration Guides") *No migrations yet. This section will document how to upgrade between profile versions.* --- # Portfolio Profile | | | | --------------------- | ------------------------------- | | **Identifier** | `urn:adl:profile:portfolio:1.0` | | **Status** | Draft | | **ADL Compatibility** | 0.3.x | note This profile is in draft status. The specification is stable for early adoption, but minor changes may occur before 1.0. ## Overview[​](#overview "Direct link to Overview") The Portfolio Profile extends ADL with agent relationships and business domain membership capabilities. It enables organizations to track agent dependencies, composition hierarchies, and business domain alignment at scale using Domain-Driven Design (DDD) concepts. Catalog identity and classification are handled by the [Registry Profile](/profiles/registry/overview.md) — a sibling profile with no dependency. ## Use Cases[​](#use-cases "Direct link to Use Cases") * Agent dependency tracking and impact analysis * Orchestrator-to-sub-agent composition mapping * Domain-driven agent organization (bounded contexts, subdomains) * Deployment order determination * Agent relationship visualization ## Quick Start[​](#quick-start "Direct link to Quick Start") Add the Portfolio Profile to your ADL document: ``` { "adl_spec": "0.3.0", "name": "Customer Service Agent", "description": "Handles customer inquiries and support requests.", "version": "1.0.0", "profiles": ["urn:adl:profile:portfolio:1.0"], "relationships": { "depends_on": ["urn:adl:agent:acme:knowledge-base-agent:1.0"], "orchestrated_by": "urn:adl:agent:acme:support-orchestrator:1.0" }, "domain": { "domain_id": "urn:domain:customer-service", "subdomain": "inquiries", "role": "primary-handler" } } ``` ## Additional Members[​](#additional-members "Direct link to Additional Members") The Portfolio Profile adds the following top-level members: | Member | Required | Description | | --------------- | -------------- | --------------------------------------------------- | | `relationships` | At least one\* | Agent dependencies and composition relationships | | `domain` | At least one\* | Business/functional domain membership (DDD-aligned) | \* At least one of `relationships` or `domain` **MUST** be present. See the [full specification](/profiles/portfolio/specification.md) for detailed member definitions. ## Key Concepts[​](#key-concepts "Direct link to Key Concepts") ### Relationship Tracking[​](#relationship-tracking "Direct link to Relationship Tracking") The `relationships` member models agent dependencies (`depends_on`), orchestration hierarchies (`composed_of`, `orchestrated_by`), and peer collaborations (`peers`). This enables deployment ordering, impact analysis, and relationship visualization. ### Domain Alignment[​](#domain-alignment "Direct link to Domain Alignment") The `domain` member aligns agents with business capabilities using DDD concepts: domain identifiers, subdomains, bounded contexts, and roles within domains. ### Multi-Profile Composition[​](#multi-profile-composition "Direct link to Multi-Profile Composition") Organizations that need catalog identity alongside portfolio relationships declare the [Registry Profile](/profiles/registry/overview.md) as a sibling: ``` { "profiles": [ "urn:adl:profile:registry:1.0", "urn:adl:profile:portfolio:1.0" ] } ``` --- # Portfolio Profile Specification | | | | --------------------- | ------------------------------- | | **Identifier** | `urn:adl:profile:portfolio:1.0` | | **Status** | Draft | | **ADL Compatibility** | 0.3.x | | **Schema** | `schema.json` | | **Dependencies** | None | ## 1. Introduction[​](#1-introduction "Direct link to 1. Introduction") The Portfolio Profile extends ADL with agent relationships and business domain membership capabilities. It enables organizations to track agent dependencies, composition hierarchies, and business domain alignment at scale. When this profile is declared in an ADL document's `profiles` array, the document **MUST** satisfy all requirements defined in this specification. ### 1.1 Relationship to Other Profiles[​](#11-relationship-to-other-profiles "Direct link to 1.1 Relationship to Other Profiles") The Portfolio Profile is independent of other ADL profiles: * **Registry Profile** — Provides catalog identity and classification. Portfolio does not depend on registry — an enterprise may track portfolio relationships in a Git repository, CMDB, or spreadsheet without requiring formal registry integration. * **Governance Profile** — Provides compliance and governance controls. Portfolio does not depend on governance — an agent can have portfolio relationships without being governed. Organizations that need both registry and portfolio capabilities declare both profiles as siblings: ``` { "profiles": [ "urn:adl:profile:registry:1.0", "urn:adl:profile:portfolio:1.0" ] } ``` *** ## 2. Additional Members[​](#2-additional-members "Direct link to 2. Additional Members") ### 2.1 relationships[​](#21-relationships "Direct link to 2.1 relationships") **OPTIONAL.** An object containing agent dependencies and composition relationships. | Member | Type | Required | Description | | ---------------- | ------ | -------- | ---------------------------------- | | depends\_on | array | OPTIONAL | Agent URIs this agent requires | | composed\_of | array | OPTIONAL | Sub-agent URIs (for orchestrators) | | orchestrated\_by | string | OPTIONAL | Parent orchestrator URI | | peers | array | OPTIONAL | Related agents at same level | #### depends\_on[​](#depends_on "Direct link to depends_on") When present, **MUST** be an array of strings. Each string **SHOULD** be an agent URI (e.g., `urn:adl:agent:acme:shared-tools:1.0`). Lists agents that this agent requires to function correctly. #### composed\_of[​](#composed_of "Direct link to composed_of") When present, **MUST** be an array of strings. Each string **SHOULD** be an agent URI. Used when this agent is an orchestrator that manages sub-agents. #### orchestrated\_by[​](#orchestrated_by "Direct link to orchestrated_by") When present, **MUST** be a string containing the URI of the orchestrating agent. Indicates this agent operates as part of a larger orchestrated system. #### peers[​](#peers "Direct link to peers") When present, **MUST** be an array of strings. Each string **SHOULD** be an agent URI. Lists agents that operate at the same level or collaborate directly with this agent. *** ### 2.2 domain[​](#22-domain "Direct link to 2.2 domain") **OPTIONAL.** An object containing business/functional domain membership information, aligned with Domain-Driven Design (DDD) concepts. | Member | Type | Required | Description | | ---------------- | ------ | -------- | ------------------------------ | | domain\_id | string | OPTIONAL | Domain identifier | | subdomain | string | OPTIONAL | Subdomain within the domain | | bounded\_context | string | OPTIONAL | Bounded context name | | role | string | OPTIONAL | Agent's role within the domain | #### domain\_id[​](#domain_id "Direct link to domain_id") When present, **SHOULD** be a URI or URN identifying the business domain (e.g., `urn:domain:customer-service`). #### subdomain[​](#subdomain "Direct link to subdomain") When present, specifies the subdomain within the domain (e.g., "ticketing", "live-chat"). #### bounded\_context[​](#bounded_context "Direct link to bounded_context") When present, specifies the DDD bounded context this agent belongs to. #### role[​](#role "Direct link to role") When present, describes the agent's role within the domain (e.g., "primary-handler", "escalation", "specialist"). *** ## 3. Example[​](#3-example "Direct link to 3. Example") Complete Example This example demonstrates a complete agent definition using this profile. customer-service-agent.json ``` { "$schema": "https://adl-spec.org/profiles/portfolio/1.0/schema.json", "adl_spec": "0.3.0", "name": "Customer Service Agent", "description": "Handles tier-1 customer inquiries and support requests via chat and email channels.", "version": "1.2.0", "profiles": [ "urn:adl:profile:portfolio:1.0" ], "data_classification": { "sensitivity": "internal", "categories": [ "pii" ] }, "provider": { "name": "Acme Support", "url": "https://support.acme.example", "contact": "support-engineering@acme.example" }, "model": { "capabilities": [ "function_calling", "streaming" ] }, "tools": [ { "name": "search_knowledge_base", "description": "Search the knowledge base for relevant articles", "parameters": { "type": "object", "properties": { "query": { "type": "string" }, "limit": { "type": "integer", "default": 5 } }, "required": [ "query" ] }, "read_only": true }, { "name": "create_ticket", "description": "Create a support ticket for escalation", "parameters": { "type": "object", "properties": { "subject": { "type": "string" }, "description": { "type": "string" }, "priority": { "type": "string", "enum": [ "low", "medium", "high", "urgent" ] }, "customer_id": { "type": "string" } }, "required": [ "subject", "description", "customer_id" ] }, "requires_confirmation": true }, { "name": "get_customer_info", "description": "Retrieve customer information", "parameters": { "type": "object", "properties": { "customer_id": { "type": "string" } }, "required": [ "customer_id" ] }, "read_only": true } ], "permissions": { "network": { "allowed_hosts": [ "api.acme.example", "kb.acme.example", "tickets.acme.example" ], "allowed_protocols": [ "https" ], "deny_private": true } }, "security": { "authentication": { "type": "oauth2", "required": true, "scopes": [ "customers:read", "tickets:write", "kb:read" ] }, "encryption": { "in_transit": { "required": true, "min_version": "1.2" } } }, "relationships": { "depends_on": [ "urn:adl:agent:acme:knowledge-base-agent:1.0", "urn:adl:agent:acme:ticket-api-agent:2.0", "urn:adl:agent:acme:customer-data-agent:1.5" ], "orchestrated_by": "urn:adl:agent:acme:support-orchestrator:1.0", "peers": [ "urn:adl:agent:acme:billing-support-agent:1.0", "urn:adl:agent:acme:technical-support-agent:1.0", "urn:adl:agent:acme:returns-agent:1.0" ] }, "domain": { "domain_id": "urn:domain:customer-service", "subdomain": "inquiries", "bounded_context": "support-portal", "role": "primary-handler" }, "metadata": { "authors": [ { "name": "Support Engineering", "email": "support-engineering@acme.example" } ], "license": "Proprietary", "documentation": "https://docs.acme.example/agents/customer-service", "tags": [ "customer-service", "support", "production" ] } } ``` *** ## 4. Validation Rules[​](#4-validation-rules "Direct link to 4. Validation Rules") Validation Required Implementations validating against this profile **MUST** enforce the following rules. Non-conforming documents should be rejected. | Rule | Description | | ------ | ------------------------------------------------------------------- | | PFL-01 | `relationships` or `domain` **MUST** be present (at least one) | | PFL-02 | `relationships.depends_on` elements **MUST** be strings if present | | PFL-03 | `relationships.composed_of` elements **MUST** be strings if present | | PFL-04 | `relationships.orchestrated_by` **MUST** be a string if present | | PFL-05 | `relationships.peers` elements **MUST** be strings if present | ### 4.1 Schema Validation[​](#41-schema-validation "Direct link to 4.1 Schema Validation") The portfolio profile provides a JSON Schema (`schema.json`) that extends the base ADL schema via `allOf` composition per Section 13.1 of the core specification. The profile schema: 1. References the base ADL schema via `allOf` with `$ref`. 2. Declares all portfolio-specific members in its own `properties`. 3. Uses `anyOf` to enforce that at least one of `relationships` or `domain` is present. 4. Is an open additive mixin: it does **not** set a root `unevaluatedProperties`, so it composes with other profiles via `allOf`. Closure (`unevaluatedProperties: false`) is applied once over the composed schema per Section 13.1 of the core specification. Validators **SHOULD** use this schema for structural validation of documents declaring the portfolio profile. ### 4.2 Profile Dependencies[​](#42-profile-dependencies "Direct link to 4.2 Profile Dependencies") This profile has no dependencies. It **MAY** be declared alongside other profiles (e.g., registry, governance) as a sibling. See Section 13.3 of the core specification for dependency rules. *** ## 5. Use Cases[​](#5-use-cases "Direct link to 5. Use Cases") ### 5.1 Dependency Management[​](#51-dependency-management "Direct link to 5.1 Dependency Management") The `relationships` member enables: * Deployment order determination via `depends_on` * Orchestrator-to-sub-agent mapping via `composed_of` * Impact analysis when agents change * Visualization of agent relationships ### 5.2 Domain Alignment[​](#52-domain-alignment "Direct link to 5.2 Domain Alignment") The `domain` member enables: * Grouping agents by business capability * Mapping agents to bounded contexts * Understanding agent responsibilities within domains --- # Registry Profile Examples ## Registered Agent[​](#registered-agent "Direct link to Registered Agent") A compliance review agent registered in an enterprise catalog with classification and federation metadata. * YAML * JSON registered-agent.adl.yaml ``` $schema: https://adl-spec.org/profiles/registry/1.0/schema.json adl_spec: 0.3.0 name: Compliance Review Agent description: Reviews documents for regulatory compliance against SOC 2 Type II controls. Flags potential violations and recommends remediation actions. version: 2.0.0 data_classification: sensitivity: confidential categories: - regulatory profiles: - urn:adl:profile:registry:1.0 registry: catalog_id: urn:acme:agents:compliance-review:2.0.0 catalog_classification: - domain: compliance subdomain: document-review capability: soc2-review visibility: internal federation: registries: - https://registry.acme.example - https://enterprise-agents.example primary: https://registry.acme.example metadata: authors: - name: Compliance Team email: compliance@acme.example license: Proprietary documentation: https://docs.acme.example/agents/compliance-review tags: - compliance - soc2 - audit - document-review ``` registered-agent.adl.json ``` { "$schema": "https://adl-spec.org/profiles/registry/1.0/schema.json", "adl_spec": "0.3.0", "name": "Compliance Review Agent", "description": "Reviews documents for regulatory compliance against SOC 2 Type II controls. Flags potential violations and recommends remediation actions.", "version": "2.0.0", "data_classification": { "sensitivity": "confidential", "categories": [ "regulatory" ] }, "profiles": [ "urn:adl:profile:registry:1.0" ], "registry": { "catalog_id": "urn:acme:agents:compliance-review:2.0.0", "catalog_classification": [ { "domain": "compliance", "subdomain": "document-review", "capability": "soc2-review" } ], "visibility": "internal", "federation": { "registries": [ "https://registry.acme.example", "https://enterprise-agents.example" ], "primary": "https://registry.acme.example" } }, "metadata": { "authors": [ { "name": "Compliance Team", "email": "compliance@acme.example" } ], "license": "Proprietary", "documentation": "https://docs.acme.example/agents/compliance-review", "tags": [ "compliance", "soc2", "audit", "document-review" ] } } ``` ### Key Registry Fields[​](#key-registry-fields "Direct link to Key Registry Fields") | Field | Purpose | | --------------------------------- | ------------------------------------------------- | | `registry.catalog_id` | Unique identifier in the agent catalog | | `registry.catalog_classification` | Domain, subdomain, and capability taxonomy | | `registry.visibility` | Access scope (`internal`, `public`, `restricted`) | | `registry.federation` | Cross-registry discovery and sync configuration | --- # Registry Profile Compatibility This document tracks compatibility between Registry Profile versions and ADL specification versions. ## Compatibility Matrix[​](#compatibility-matrix "Direct link to Compatibility Matrix") | Profile Version | ADL Versions | Status | Notes | | --------------- | ------------ | ------ | --------------- | | 1.0 | 0.3.x | Draft | Initial release | ## Compatibility Policy[​](#compatibility-policy "Direct link to Compatibility Policy") * **Minor ADL updates** (e.g., 0.1.0 → 0.1.1): Profile remains compatible * **Major ADL updates** (e.g., 0.1.x → 1.0.0): Profile compatibility will be evaluated; new profile version released if needed * **Breaking profile changes**: Require new major profile version ## Migration Guides[​](#migration-guides "Direct link to Migration Guides") *No migrations yet. This section will document how to upgrade between profile versions.* --- # Registry Profile | | | | --------------------- | ------------------------------ | | **Identifier** | `urn:adl:profile:registry:1.0` | | **Status** | Draft | | **ADL Compatibility** | 0.3.x | note This profile is in draft status. The specification is stable for early adoption, but minor changes may occur before 1.0. ## Overview[​](#overview "Direct link to Overview") The Registry Profile extends ADL with agent catalog identity, classification, and federation capabilities. It enables organizations to manage agents across enterprise registries, support multi-path classification, and federate agent definitions across multiple registry instances. When this profile is declared in an ADL document's `profiles` array, the document **MUST** satisfy all requirements defined in this specification. ## Use Cases[​](#use-cases "Direct link to Use Cases") * Enterprise agent registries and catalogs * Multi-path agent classification by business domain * Agent discovery across organizational boundaries * Multi-registry federation and synchronization * Access control scoping (private, internal, public) ## Quick Start[​](#quick-start "Direct link to Quick Start") Add the Registry Profile to your ADL document: ``` { "adl_spec": "0.3.0", "name": "Compliance Review Agent", "description": "Reviews documents for regulatory compliance.", "version": "2.0.0", "profiles": ["urn:adl:profile:registry:1.0"], "registry": { "catalog_id": "urn:acme:agents:compliance-review:2.0.0", "catalog_classification": [ { "domain": "compliance", "subdomain": "document-review", "capability": "soc2-review" } ], "visibility": "internal" } } ``` ## Additional Members[​](#additional-members "Direct link to Additional Members") The Registry Profile adds the following top-level member: | Member | Required | Description | | ---------- | ------------ | ------------------------------------------------------------------ | | `registry` | **REQUIRED** | Agent catalog identity, classification, and federation information | ### registry[​](#registry "Direct link to registry") | Field | Type | Required | Description | | ------------------------ | ------ | ------------ | ------------------------------------------------- | | `catalog_id` | string | **REQUIRED** | Unique identifier within the registry catalog | | `catalog_classification` | array | Optional | Multi-path catalog classification entries | | `visibility` | string | Optional | Visibility scope: `private`, `internal`, `public` | | `federation` | object | Optional | Multi-registry publishing configuration | See the [full specification](/profiles/registry/specification.md) for detailed member definitions and validation rules. ## Relationship to Other Profiles[​](#relationship-to-other-profiles "Direct link to Relationship to Other Profiles") The Registry Profile is independent — it has no dependencies on other profiles. * **Portfolio Profile** — Tracks agent relationships and domain alignment. Organizations may use portfolio without a formal registry. Declare both as siblings when you need both. * **Governance Profile** — Tracks compliance and governance controls. An agent can be governed without being registered, and vice versa. ``` { "profiles": [ "urn:adl:profile:registry:1.0", "urn:adl:profile:governance:1.0", "urn:adl:profile:portfolio:1.0" ] } ``` --- # Registry Profile Specification | | | | --------------------- | ------------------------------ | | **Identifier** | `urn:adl:profile:registry:1.0` | | **Status** | Draft | | **ADL Compatibility** | 0.3.x | | **Schema** | `schema.json` | | **Dependencies** | None | ## 1. Introduction[​](#1-introduction "Direct link to 1. Introduction") The Registry Profile extends ADL with agent catalog identity, classification, and federation capabilities. It enables organizations to manage agents across enterprise registries, support multi-path classification, and federate agent definitions across multiple registry instances. When this profile is declared in an ADL document's `profiles` array, the document **MUST** satisfy all requirements defined in this specification. ### 1.1 Relationship to Other Profiles[​](#11-relationship-to-other-profiles "Direct link to 1.1 Relationship to Other Profiles") The Registry Profile is independent of other ADL profiles: * **Portfolio Profile** — Tracks agent relationships and business domain alignment. An enterprise may manage portfolio relationships without a formal registry (e.g., in a Git repository or CMDB). Registry and portfolio are siblings with no dependency. * **Governance Profile** — Tracks compliance and governance controls. An agent can be governed without being in a registry (e.g., during pre-deployment governance review). Registry and governance are siblings with no dependency. Organizations that need both registry and portfolio capabilities declare both profiles as siblings: ``` { "profiles": [ "urn:adl:profile:registry:1.0", "urn:adl:profile:portfolio:1.0" ] } ``` *** ## 2. Additional Members[​](#2-additional-members "Direct link to 2. Additional Members") ### 2.1 registry[​](#21-registry "Direct link to 2.1 registry") **REQUIRED** when using this profile. An object containing agent catalog identity, classification, and federation information. | Member | Type | Required | Description | | ----------------------- | ------ | -------- | --------------------------------------------- | | catalog\_id | string | REQUIRED | Unique identifier within the registry catalog | | catalog\_classification | array | OPTIONAL | Registry catalog classification paths | | visibility | string | OPTIONAL | Visibility scope | | federation | object | OPTIONAL | Multi-registry publishing configuration | #### catalog\_id[​](#catalog_id "Direct link to catalog_id") A unique identifier for this agent within the registry catalog. **MUST** be a non-empty string. **SHOULD** be a URN or URI that is unique across the agent registry (e.g., `urn:acme:agents:compliance-review:2.0.0`). #### catalog\_classification[​](#catalog_classification "Direct link to catalog_classification") When present, **MUST** be an array of classification path objects. Each entry represents a classification path — an agent **MAY** belong to multiple categories via multiple entries. This enables multi-path classification where a single agent serves multiple business domains or capabilities. Each classification entry **MUST** be an object containing: | Member | Type | Required | Description | | ---------- | ------ | -------- | ----------------------- | | domain | string | REQUIRED | Business domain | | subdomain | string | OPTIONAL | Subdomain within domain | | capability | string | OPTIONAL | Capability category | `domain` **MUST** be a non-empty string identifying the business domain. Values **SHOULD** be lowercase, hyphen-separated (e.g., `"compliance"`, `"risk-management"`, `"customer-service"`). The name `catalog_classification` is intentionally distinct from governance taxonomy terms (EU AI Act risk taxonomy, NIST AI taxonomy) to avoid confusion between catalog organization and regulatory classification systems. #### visibility[​](#visibility "Direct link to visibility") When present, **MUST** be one of: * `private` — Visible only to the owning team * `internal` — Visible within the organization * `public` — Visible externally #### federation[​](#federation "Direct link to federation") When present, **MUST** be an object containing multi-registry publishing configuration: | Member | Type | Required | Description | | ---------- | ------ | -------- | -------------------------------------- | | registries | array | OPTIONAL | Registry URIs where agent is published | | primary | string | OPTIONAL | Primary registry URI | `registries`, when present, **MUST** be an array of strings. Each string **MUST** be a valid URI identifying a registry where this agent is published. `primary`, when present, **MUST** be a valid URI identifying the primary registry for this agent. The primary registry is the authoritative source for the agent definition. *** ## 3. Example[​](#3-example "Direct link to 3. Example") A registered agent with multi-path classification and federation: Complete Example This example demonstrates a complete agent definition using this profile. registered-agent.json ``` { "$schema": "https://adl-spec.org/profiles/registry/1.0/schema.json", "adl_spec": "0.3.0", "name": "Compliance Review Agent", "description": "Reviews documents for regulatory compliance against SOC 2 Type II controls. Flags potential violations and recommends remediation actions.", "version": "2.0.0", "data_classification": { "sensitivity": "confidential", "categories": ["regulatory"] }, "profiles": ["urn:adl:profile:registry:1.0"], "registry": { "catalog_id": "urn:acme:agents:compliance-review:2.0.0", "catalog_classification": [ { "domain": "compliance", "subdomain": "document-review", "capability": "soc2-review" } ], "visibility": "internal", "federation": { "registries": [ "https://registry.acme.example", "https://enterprise-agents.example" ], "primary": "https://registry.acme.example" } }, "metadata": { "authors": [ { "name": "Compliance Team", "email": "compliance@acme.example" } ], "license": "Proprietary", "documentation": "https://docs.acme.example/agents/compliance-review", "tags": ["compliance", "soc2", "audit", "document-review"] } } ``` note Discovery tags are handled by the core ADL member (Section 12.5). Registry classification serves catalog organization. There is no need for separate discovery tag fields. *** ## 4. Validation Rules[​](#4-validation-rules "Direct link to 4. Validation Rules") Validation Required Implementations validating against this profile **MUST** enforce the following rules. Non-conforming documents should be rejected. | Rule | Description | | ------ | ------------------------------------------------------------------------------------------------------------ | | REG-01 | `registry` **MUST** be present | | REG-02 | `registry.catalog_id` **MUST** be present and non-empty | | REG-03 | `registry.visibility` **MUST** be a valid visibility value if present | | REG-04 | `registry.catalog_classification[*].domain` **MUST** be present and non-empty if classification entry exists | | REG-05 | `registry.federation.registries` elements **MUST** be valid URIs if present | | REG-06 | `registry.federation.primary` **MUST** be a valid URI if present | ### 4.1 Schema Validation[​](#41-schema-validation "Direct link to 4.1 Schema Validation") The registry profile provides a JSON Schema (`schema.json`) that extends the base ADL schema via `allOf` composition per Section 13.1 of the core specification. The profile schema: 1. References the base ADL schema via `allOf` with `$ref`. 2. Declares all registry-specific members in its own `properties`. 3. Is an open additive mixin: it does **not** set a root `unevaluatedProperties`, so it composes with other profiles via `allOf`. Closure (`unevaluatedProperties: false`) is applied once over the composed schema per Section 13.1 of the core specification. Validators **SHOULD** use this schema for structural validation of documents declaring the registry profile. ### 4.2 Profile Dependencies[​](#42-profile-dependencies "Direct link to 4.2 Profile Dependencies") This profile has no dependencies. It **MAY** be declared alongside other profiles (e.g., governance, portfolio) as a sibling. See Section 13.3 of the core specification for dependency rules. *** ## 5. Use Cases[​](#5-use-cases "Direct link to 5. Use Cases") ### 5.1 Agent Catalog[​](#51-agent-catalog "Direct link to 5.1 Agent Catalog") The `registry` member enables catalog systems to: * Index agents by `catalog_id` for unique lookup * Organize agents by `catalog_classification` domain, subdomain, and capability * Control access based on `visibility` ### 5.2 Multi-Registry Federation[​](#52-multi-registry-federation "Direct link to 5.2 Multi-Registry Federation") The `federation` member enables: * Publishing agent definitions to multiple registries * Identifying the authoritative registry via `primary` * Synchronizing agent metadata across registry instances ### 5.3 Multi-Path Classification[​](#53-multi-path-classification "Direct link to 5.3 Multi-Path Classification") The `catalog_classification` array enables: * Classifying a single agent under multiple business domains * Supporting matrix organizational structures where agents serve multiple teams * Enabling cross-domain discovery without duplicating agent definitions --- # Protocol ADL is specified as a **family of documents** built around one signed passport. The [ADL Core specification](/spec/.md) is the single *declarative* document: it describes what an agent **is** and the limits it **declares**. Around it sits a **protocol layer** — an open set of *procedural* documents that define what an actor **MUST do** with those declarations, the layer that gives an agent's declarations force. Core declares; the protocols enforce. A declared limit has force only when a protocol procedure acts on it. ![Component diagram of the ADL document family. A DECLARE region at the top holds the ADL Core (identity, capabilities, limits, lifecycle), which derives the Agent Passport, a declared and signed artifact. A dashed declare-versus-enforce boundary separates it from the ENFORCE region (the protocol layer) below, holding the Trust Protocol (admission-time verification and authorization), the Runtime Protocol (a continuous governor performing enforcement and evidence), and a dashed open-layer slot for future protocols such as discovery, reputation, and settlement. The passport is consumed by the Trust Protocol at admission and by the Runtime Protocol at runtime, and is available to the open-layer slot in future. The Runtime Protocol produces an Enforcement Evidence hash-chained record.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA4MjAgNzQwIiB3aWR0aD0iODIwIiBoZWlnaHQ9Ijc0MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsbGVkYnk9ImRmYS10aXRsZSBkZmEtZGVzYyIgZm9udC1mYW1pbHk9Ii1hcHBsZS1zeXN0ZW0sIEJsaW5rTWFjU3lzdGVtRm9udCwgJ1NlZ29lIFVJJywgSGVsdmV0aWNhLCBBcmlhbCwgc2Fucy1zZXJpZiI+CiAgPHRpdGxlIGlkPSJkZmEtdGl0bGUiPkFETCBkb2N1bWVudCBmYW1pbHk6IENvcmUgZGVjbGFyZXM7IHRoZSBwcm90b2NvbHMgZW5mb3JjZTwvdGl0bGU+CiAgPGRlc2MgaWQ9ImRmYS1kZXNjIj5BIHR3by1yZWdpb24gY29tcG9uZW50IGRpYWdyYW0uIEEgREVDTEFSRSByZWdpb24gYXQgdGhlIHRvcCBjb250YWlucyB0aGUgQURMIENvcmUgKGlkZW50aXR5LCBjYXBhYmlsaXRpZXMsIGxpbWl0cywgbGlmZWN5Y2xlKSwgd2hpY2ggZGVyaXZlcyB0aGUgQWdlbnQgUGFzc3BvcnQsIGEgZGVjbGFyZWQgYW5kIHNpZ25lZCBhcnRpZmFjdCBzdGFja2VkIGRpcmVjdGx5IGJlbmVhdGggaXQuIEEgZGFzaGVkIGRlY2xhcmUtdmVyc3VzLWVuZm9yY2UgYm91bmRhcnkgc2VwYXJhdGVzIGl0IGZyb20gdGhlIEVORk9SQ0UgcmVnaW9uICh0aGUgcHJvdG9jb2wgbGF5ZXIpIGJlbG93LCB3aGljaCBjb250YWlucyB0aGUgVHJ1c3QgUHJvdG9jb2wgKGFkbWlzc2lvbi10aW1lIHZlcmlmaWNhdGlvbiBhbmQgYXV0aG9yaXphdGlvbiksIHRoZSBSdW50aW1lIFByb3RvY29sIChhIGNvbnRpbnVvdXMgZ292ZXJub3IgcGVyZm9ybWluZyBlbmZvcmNlbWVudCBhbmQgZXZpZGVuY2UpLCBhbmQgYSBkYXNoZWQgb3Blbi1sYXllciBzbG90IGZvciBmdXR1cmUgcHJvdG9jb2xzIHN1Y2ggYXMgZGlzY292ZXJ5LCByZXB1dGF0aW9uLCBhbmQgc2V0dGxlbWVudC4gRnJvbSBhIHNpbmdsZSBodWIgcG9pbnQsIHRoZSBwYXNzcG9ydCBmYW5zIG91dCBhcyBldmVubHkgc3BhY2VkIHNwb2tlczogY29uc3VtZWQgYnkgdGhlIFRydXN0IFByb3RvY29sIGF0IGFkbWlzc2lvbiwgYnkgdGhlIFJ1bnRpbWUgUHJvdG9jb2wgYXQgcnVudGltZSwgYW5kIGF2YWlsYWJsZSB0byB0aGUgb3Blbi1sYXllciBzbG90IGluIGZ1dHVyZS4gVGhlIFJ1bnRpbWUgUHJvdG9jb2wgcHJvZHVjZXMgYW4gRW5mb3JjZW1lbnQgRXZpZGVuY2UgaGFzaC1jaGFpbmVkIHJlY29yZC48L2Rlc2M+CgogIDxkZWZzPgogICAgPG1hcmtlciBpZD0iZGZhLWFycm93IiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj4KICAgICAgPHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBmaWxsPSIjMzM0MTU1Ii8+CiAgICA8L21hcmtlcj4KICAgIDxtYXJrZXIgaWQ9ImRmYS1hcnJvdy1vcGVuIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj4KICAgICAgPHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBmaWxsPSIjOTRhM2I4Ii8+CiAgICA8L21hcmtlcj4KICA8L2RlZnM+CgogIDxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSI4MjAiIGhlaWdodD0iNzQwIiBmaWxsPSIjZmZmZmZmIi8+CgogIDwhLS0gVGl0bGUgLS0+CiAgPHRleHQgeD0iNDEwIiB5PSIzOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIyMCIgZm9udC13ZWlnaHQ9IjcwMCIgZmlsbD0iIzBmMTcyYSI+QURMIERvY3VtZW50IEZhbWlseTwvdGV4dD4KICA8dGV4dCB4PSI0MTAiIHk9IjYwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjEzIiBmb250LXN0eWxlPSJpdGFsaWMiIGZpbGw9IiM0NzU1NjkiPkNvcmUgZGVjbGFyZXM7IHRoZSBwcm90b2NvbHMgZW5mb3JjZTwvdGV4dD4KCiAgPCEtLSBERUNMQVJFIHJlZ2lvbiAtLT4KICA8cmVjdCB4PSIzMCIgeT0iODIiIHdpZHRoPSI3NjAiIGhlaWdodD0iMjY4IiByeD0iMTAiIGZpbGw9IiNmOGZhZmMiIHN0cm9rZT0iI2NiZDVlMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNCIvPgogIDx0ZXh0IHg9IjUwIiB5PSIxMDQiIGZvbnQtc2l6ZT0iMTIiIGZvbnQtd2VpZ2h0PSI3MDAiIGZpbGw9IiM0NzU1NjkiIGxldHRlci1zcGFjaW5nPSIxIj5ERUNMQVJFPC90ZXh0PgoKICA8IS0tIEFETCBDb3JlIGJveCAodG9wIG9mIHN0YWNrLCBjZW50ZXJlZCBvbiB4PTQxMCkgLS0+CiAgPHJlY3QgeD0iMjgwIiB5PSIxMDAiIHdpZHRoPSIyNjAiIGhlaWdodD0iODYiIHJ4PSI4IiBmaWxsPSIjZThmMGZlIiBzdHJva2U9IiMxYTczZTgiIHN0cm9rZS13aWR0aD0iMS41Ii8+CiAgPHRleHQgeD0iNDEwIiB5PSIxMzIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTUiIGZvbnQtd2VpZ2h0PSI3MDAiIGZpbGw9IiMwYjU3ZDAiPkFETCBDb3JlPC90ZXh0PgogIDx0ZXh0IHg9IjQxMCIgeT0iMTU0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjExLjUiIGZpbGw9IiMxZjI5MzciPmlkZW50aXR5ICYjMTgzOyBjYXBhYmlsaXRpZXM8L3RleHQ+CiAgPHRleHQgeD0iNDEwIiB5PSIxNzEiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTEuNSIgZmlsbD0iIzFmMjkzNyI+bGltaXRzICYjMTgzOyBsaWZlY3ljbGU8L3RleHQ+CgogIDwhLS0gZGVyaXZlIGFycm93IENvcmUgLT4gUGFzc3BvcnQgKHZlcnRpY2FsKTsgd2lkZXIgZ3V0dGVyIHNvIHRoZSBsaW5lIGFuZCBhcnJvd2hlYWQgcmVhZCBjbGVhcmx5IGFyb3VuZCB0aGUgbGFiZWwgLS0+CiAgPGxpbmUgeDE9IjQxMCIgeTE9IjE4NiIgeDI9IjQxMCIgeTI9IjI0MCIgc3Ryb2tlPSIjMzM0MTU1IiBzdHJva2Utd2lkdGg9IjEuNSIgc3Ryb2tlLWRhc2hhcnJheT0iNSA0IiBtYXJrZXItZW5kPSJ1cmwoI2RmYS1hcnJvdykiLz4KICA8cmVjdCB4PSIzNzgiIHk9IjIwNSIgd2lkdGg9IjY0IiBoZWlnaHQ9IjE2IiBmaWxsPSIjZjhmYWZjIi8+CiAgPHRleHQgeD0iNDEwIiB5PSIyMTYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTAuNSIgZm9udC1zdHlsZT0iaXRhbGljIiBmaWxsPSIjNDc1NTY5Ij4mIzE3MTtkZXJpdmUmIzE4Nzs8L3RleHQ+CgogIDwhLS0gQWdlbnQgUGFzc3BvcnQgYm94IChib3R0b20gb2Ygc3RhY2ssIGNlbnRlcmVkIG9uIHg9NDEwID0gdGhlIGh1YikgLS0+CiAgPHJlY3QgeD0iMjgwIiB5PSIyNDAiIHdpZHRoPSIyNjAiIGhlaWdodD0iODYiIHJ4PSI4IiBmaWxsPSIjZmZmN2U2IiBzdHJva2U9IiNmNTllMGIiIHN0cm9rZS13aWR0aD0iMS41Ii8+CiAgPHRleHQgeD0iNDEwIiB5PSIyNzIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTUiIGZvbnQtd2VpZ2h0PSI3MDAiIGZpbGw9IiNiNDUzMDkiPkFnZW50IFBhc3Nwb3J0PC90ZXh0PgogIDx0ZXh0IHg9IjQxMCIgeT0iMjk0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjExLjUiIGZpbGw9IiMxZjI5MzciPmRlY2xhcmVkIGxpbWl0cywgc2lnbmVkPC90ZXh0PgogIDx0ZXh0IHg9IjQxMCIgeT0iMzExIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjEwLjUiIGZvbnQtc3R5bGU9Iml0YWxpYyIgZmlsbD0iIzZiNzI4MCI+dGhlIGRlY2xhcmVkIGFydGlmYWN0PC90ZXh0PgoKICA8IS0tIGRlY2xhcmUvZW5mb3JjZSBib3VuZGFyeTsgdGhlIGxpbmUgY2FycmllcyAiZW5mb3JjZWQiIHBsdXMgdGhlIHRocmVlIGNyb3NzaW5nIGxhYmVscywgYWxsIGNlbnRlcmVkIG9uIGl0IC0tPgogIDxsaW5lIHgxPSIzMCIgeTE9IjM3MiIgeDI9Ijc5MCIgeTI9IjM3MiIgc3Ryb2tlPSIjNjQ3NDhiIiBzdHJva2Utd2lkdGg9IjEuNzUiIHN0cm9rZS1kYXNoYXJyYXk9IjcgNSIvPgogIDxyZWN0IHg9IjExMiIgeT0iMzYzIiB3aWR0aD0iNzYiIGhlaWdodD0iMTgiIHJ4PSI5IiBmaWxsPSIjZmZmZmZmIiBzdHJva2U9IiM2NDc0OGIiIHN0cm9rZS13aWR0aD0iMSIvPgogIDx0ZXh0IHg9IjE1MCIgeT0iMzc2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjExIiBmb250LXdlaWdodD0iNzAwIiBmaWxsPSIjMzM0MTU1Ij5lbmZvcmNlZDwvdGV4dD4KCiAgPCEtLSBFTkZPUkNFIHJlZ2lvbiAtLT4KICA8cmVjdCB4PSIzMCIgeT0iMzk0IiB3aWR0aD0iNzYwIiBoZWlnaHQ9IjMyMCIgcng9IjEwIiBmaWxsPSIjZjhmYWZjIiBzdHJva2U9IiNjYmQ1ZTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtZGFzaGFycmF5PSI1IDQiLz4KCiAgPCEtLSBUcnVzdCBQcm90b2NvbCAtLT4KICA8cmVjdCB4PSI2MiIgeT0iNDIwIiB3aWR0aD0iMjEwIiBoZWlnaHQ9IjExOCIgcng9IjgiIGZpbGw9IiNlNmY0ZWEiIHN0cm9rZT0iIzEzNzMzMyIgc3Ryb2tlLXdpZHRoPSIxLjUiLz4KICA8dGV4dCB4PSIxNjciIHk9IjQ1MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxNCIgZm9udC13ZWlnaHQ9IjcwMCIgZmlsbD0iIzBkNjUyZCI+VHJ1c3QgUHJvdG9jb2w8L3RleHQ+CiAgPHRleHQgeD0iMTY3IiB5PSI0NzQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTEiIGZpbGw9IiMxZjI5MzciPmFkbWlzc2lvbi10aW1lPC90ZXh0PgogIDx0ZXh0IHg9IjE2NyIgeT0iNDkwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjExIiBmaWxsPSIjMWYyOTM3Ij52ZXJpZmljYXRpb24gJmFtcDs8L3RleHQ+CiAgPHRleHQgeD0iMTY3IiB5PSI1MDYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTEiIGZpbGw9IiMxZjI5MzciPmF1dGhvcml6YXRpb248L3RleHQ+CgogIDwhLS0gUnVudGltZSBQcm90b2NvbCAtLT4KICA8cmVjdCB4PSIzMDUiIHk9IjQyMCIgd2lkdGg9IjIxMCIgaGVpZ2h0PSIxMTgiIHJ4PSI4IiBmaWxsPSIjZmNlOGU2IiBzdHJva2U9IiNjNTIyMWYiIHN0cm9rZS13aWR0aD0iMS41Ii8+CiAgPHRleHQgeD0iNDEwIiB5PSI0NTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTQiIGZvbnQtd2VpZ2h0PSI3MDAiIGZpbGw9IiNhNTBlMGUiPlJ1bnRpbWUgUHJvdG9jb2w8L3RleHQ+CiAgPHRleHQgeD0iNDEwIiB5PSI0NzQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTEiIGZpbGw9IiMxZjI5MzciPmNvbnRpbnVvdXMgZ292ZXJub3I6PC90ZXh0PgogIDx0ZXh0IHg9IjQxMCIgeT0iNDkwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjExIiBmaWxsPSIjMWYyOTM3Ij5lbmZvcmNlbWVudCAmYW1wOzwvdGV4dD4KICA8dGV4dCB4PSI0MTAiIHk9IjUwNiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxMSIgZmlsbD0iIzFmMjkzNyI+ZXZpZGVuY2U8L3RleHQ+CgogIDwhLS0gT3Blbi1sYXllciBzbG90IC0tPgogIDxyZWN0IHg9IjU0OCIgeT0iNDIwIiB3aWR0aD0iMjEwIiBoZWlnaHQ9IjExOCIgcng9IjgiIGZpbGw9IiNmMWYzZjQiIHN0cm9rZT0iIzlhYTBhNiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1kYXNoYXJyYXk9IjYgNCIvPgogIDx0ZXh0IHg9IjY1MyIgeT0iNDUwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjE0IiBmb250LXdlaWdodD0iNzAwIiBmaWxsPSIjNWY2MzY4Ij5PcGVuLWxheWVyIHNsb3Q8L3RleHQ+CiAgPHRleHQgeD0iNjUzIiB5PSI0NzQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTEiIGZpbGw9IiM1ZjYzNjgiPmRpc2NvdmVyeSAmIzE4MzsgcmVwdXRhdGlvbjwvdGV4dD4KICA8dGV4dCB4PSI2NTMiIHk9IjQ5MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxMSIgZmlsbD0iIzVmNjM2OCI+JiMxODM7IHNldHRsZW1lbnQ8L3RleHQ+CiAgPHRleHQgeD0iNjUzIiB5PSI1MTIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTAiIGZvbnQtc3R5bGU9Iml0YWxpYyIgZmlsbD0iIzgwODY4YiI+KGZ1dHVyZSk8L3RleHQ+CgogIDwhLS0gaHViLWFuZC1zcG9rZTogdGhyZWUgZXZlbmx5IGZhbm5lZCBhcnJvd3MgZnJvbSB0aGUgcGFzc3BvcnQgaHViICg0MTAsMzI2KTsgZWFjaCBjcm9zc2luZyBsYWJlbCBpcyBjZW50ZXJlZCBvbiB0aGUgYm91bmRhcnkgbGluZSB3aGVyZSBpdHMgc3Bva2UgcGllcmNlcyBpdCAoeCA9IDI5MSAvIDQxMCAvIDUyOSkgLS0+CiAgPCEtLSBzcG9rZSAtPiBUcnVzdCAoYXQgYWRtaXNzaW9uKSAtLT4KICA8bGluZSB4MT0iNDEwIiB5MT0iMzI2IiB4Mj0iMTY3IiB5Mj0iNDIwIiBzdHJva2U9IiMzMzQxNTUiIHN0cm9rZS13aWR0aD0iMS41IiBtYXJrZXItZW5kPSJ1cmwoI2RmYS1hcnJvdykiLz4KICA8cmVjdCB4PSIyNDUiIHk9IjM2NCIgd2lkdGg9IjkyIiBoZWlnaHQ9IjE2IiBmaWxsPSIjZmZmZmZmIi8+CiAgPHRleHQgeD0iMjkxIiB5PSIzNzYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTAuNSIgZmlsbD0iIzMzNDE1NSI+YXQgYWRtaXNzaW9uPC90ZXh0PgogIDwhLS0gc3Bva2UgLT4gUnVudGltZSAoYXQgcnVudGltZSkgLS0+CiAgPGxpbmUgeDE9IjQxMCIgeTE9IjMyNiIgeDI9IjQxMCIgeTI9IjQyMCIgc3Ryb2tlPSIjMzM0MTU1IiBzdHJva2Utd2lkdGg9IjEuNSIgbWFya2VyLWVuZD0idXJsKCNkZmEtYXJyb3cpIi8+CiAgPHJlY3QgeD0iMzcxIiB5PSIzNjQiIHdpZHRoPSI3OCIgaGVpZ2h0PSIxNiIgZmlsbD0iI2ZmZmZmZiIvPgogIDx0ZXh0IHg9IjQxMCIgeT0iMzc2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjEwLjUiIGZpbGw9IiMzMzQxNTUiPmF0IHJ1bnRpbWU8L3RleHQ+CiAgPCEtLSBzcG9rZSAtPiBPcGVuIChmdXR1cmUpIC0tPgogIDxsaW5lIHgxPSI0MTAiIHkxPSIzMjYiIHgyPSI2NTMiIHkyPSI0MjAiIHN0cm9rZT0iIzk0YTNiOCIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNCIgbWFya2VyLWVuZD0idXJsKCNkZmEtYXJyb3ctb3BlbikiLz4KICA8cmVjdCB4PSI1MDMiIHk9IjM2NCIgd2lkdGg9IjUyIiBoZWlnaHQ9IjE2IiBmaWxsPSIjZmZmZmZmIi8+CiAgPHRleHQgeD0iNTI5IiB5PSIzNzYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTAuNSIgZm9udC1zdHlsZT0iaXRhbGljIiBmaWxsPSIjNjQ3NDhiIj5mdXR1cmU8L3RleHQ+CgogIDwhLS0gUnVudGltZSAtPiBFdmlkZW5jZSAocHJvZHVjZSwgdmVydGljYWwpIC0tPgogIDxsaW5lIHgxPSI0MTAiIHkxPSI1MzgiIHgyPSI0MTAiIHkyPSI1ODAiIHN0cm9rZT0iIzMzNDE1NSIgc3Ryb2tlLXdpZHRoPSIxLjUiIG1hcmtlci1lbmQ9InVybCgjZGZhLWFycm93KSIvPgogIDxyZWN0IHg9IjM3OCIgeT0iNTUxIiB3aWR0aD0iNjQiIGhlaWdodD0iMTUiIGZpbGw9IiNmOGZhZmMiLz4KICA8dGV4dCB4PSI0MTAiIHk9IjU2MiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxMCIgZm9udC1zdHlsZT0iaXRhbGljIiBmaWxsPSIjNDc1NTY5Ij4mIzE3MTtwcm9kdWNlJiMxODc7PC90ZXh0PgoKICA8IS0tIEVuZm9yY2VtZW50IEV2aWRlbmNlIC0tPgogIDxyZWN0IHg9IjMwNSIgeT0iNTgwIiB3aWR0aD0iMjEwIiBoZWlnaHQ9IjgwIiByeD0iOCIgZmlsbD0iI2YzZThmZCIgc3Ryb2tlPSIjODQzMGNlIiBzdHJva2Utd2lkdGg9IjEuNSIvPgogIDx0ZXh0IHg9IjQxMCIgeT0iNjE0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjEzIiBmb250LXdlaWdodD0iNzAwIiBmaWxsPSIjNmIyMWE4Ij5FbmZvcmNlbWVudCBFdmlkZW5jZTwvdGV4dD4KICA8dGV4dCB4PSI0MTAiIHk9IjYzNSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxMSIgZmlsbD0iIzFmMjkzNyI+aGFzaC1jaGFpbmVkIHJlY29yZDwvdGV4dD4KCiAgPCEtLSBPcGVuLWxheWVyIG5vdGUgLS0+CiAgPHRleHQgeD0iNjUzIiB5PSI2MDAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTAiIGZvbnQtc3R5bGU9Iml0YWxpYyIgZmlsbD0iIzgwODY4YiI+YnVpbGRzIG9uIHRoZSBzYW1lIHBhc3Nwb3J0OzwvdGV4dD4KICA8dGV4dCB4PSI2NTMiIHk9IjYxNCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxMCIgZm9udC1zdHlsZT0iaXRhbGljIiBmaWxsPSIjODA4NjhiIj5ubyBjaGFuZ2UgdG8gdGhlIENvcmU8L3RleHQ+CgogIDwhLS0gRU5GT1JDRSByZWdpb24gbGFiZWwgbW92ZWQgdG8gdGhlIGJvdHRvbSBzbyB0aGUgaW5ib3VuZCBzcG9rZXMgbmV2ZXIgY3Jvc3MgaXQgLS0+CiAgPHRleHQgeD0iNTAiIHk9IjcwMiIgZm9udC1zaXplPSIxMiIgZm9udC13ZWlnaHQ9IjcwMCIgZmlsbD0iIzQ3NTU2OSIgbGV0dGVyLXNwYWNpbmc9IjEiPkVORk9SQ0UgJiMxODM7IFBST1RPQ09MIExBWUVSPC90ZXh0Pgo8L3N2Zz4K) *Figure 1 (informative): The ADL document family — Core declares the agent passport; the protocols enforce it (Trust at admission, Runtime continuously), with an open slot for future protocols. Illustrative only; the normative requirements live in the Core and protocol documents.* ## The protocol layer[​](#the-protocol-layer "Direct link to The protocol layer") Two protocols are defined today. The layer is open: further protocols may join it as new enforcement boundaries emerge. | Document | Actor | When it acts | What it does | | -------------------------------------------- | ---------------------------------------------- | --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **[Trust Protocol](/protocol/trust.md)** | A counterparty (peer agent, gateway, registry) | Once, at **admission** | Verifies a passport, binds a request to a presentation proof, and authorizes agent-to-agent calls. | | **[Runtime Protocol](/protocol/runtime.md)** | A runtime governor | Continuously, **after admission** | Enforces an agent's declared operational limits while it executes — budgets, iteration limits, sub-agent admission, oversight triggers, degradation, and anomaly detection. | The split mirrors the two questions governance has to answer about an agent that wasn't fully specified in advance: *can I trust this agent before I let it act?* (Trust) and *is it still behaving within its declared limits while it acts?* (Runtime). ## Status[​](#status "Direct link to Status") * The **[Trust Protocol](/protocol/trust.md)** is drafted: authentication (§1) and authorization (§2) procedures, with conformance test vectors tracking its section numbers. * The **[Runtime Protocol](/protocol/runtime.md)** is an early draft — the runtime governor (§1), the enforcement procedures (§2–§7: budgets, iteration, sub-agent admission, oversight, degradation, anomaly), and the signed enforcement-evidence format (§8) are drafted; the completeness/witness tier (§8.8) is reserved. The protocol layer is cut on the same cadence as ADL Core and shares its version number: a spec release freezes the protocols at the same version. Section references outside a protocol's own range refer to the [ADL Core specification](/spec/.md). --- # Runtime Protocol | | | | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Version** | 0.3.0 | | **Status** | Posted — the runtime governor (§1), the enforcement procedures (§2–§7), and the enforcement-evidence format (§8) are drafted; the completeness/witness tier (§8.8) is reserved. | The **Runtime Protocol** defines the normative procedures a *runtime governor* performs to enforce an ADL agent's declared operational limits while the agent executes: budgets, iteration limits, sub-agent admission, human-oversight triggers, degradation, and anomaly detection. It sits in the ADL document family alongside the [ADL Core specification](/spec/.md), which declares what an agent **is** and the limits it advertises, and the [Trust Protocol](/protocol/trust.md), which defines what a *counterparty* does to verify and authorize it; it is one document in ADL's open protocol layer. Where the Trust Protocol acts **once, at admission**, the Runtime Protocol acts **continuously, after admission**: it is the layer that gives an agent's declared operational limits force at runtime. The declarative members these procedures operate on — `permissions.resource_limits`, `runtime.tool_invocation`, `permissions.sub_agents`, `permissions.delegation`, `human_oversight`, `runtime.degradation`, and `anomaly_baseline` — are defined by [ADL Core](/spec/.md) and the governance profiles, which are authoritative for their syntax and constraints. This document references them but does not redefine them; it defines what a governor **MUST** do with them. The Runtime Protocol is numbered independently as a standalone document: the runtime governor is §1, the enforcement procedures are §2–§7, and the enforcement-evidence format is §8. Section references outside §1–§8 — for example §9.6, §11.3, or §10.1 — refer to the [ADL Core specification](/spec/.md). The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 \[RFC2119] \[RFC8174] when, and only when, they appear in all capitals, as shown here. ## 1 The Runtime Governor[​](#1-the-runtime-governor "Direct link to 1 The Runtime Governor") The Trust Protocol's §1 defines the *counterparty* — the actor that decides, once, whether to admit an agent. This protocol defines a second actor, the **runtime governor**: the actor that holds an admitted agent to its declared operational limits on every step thereafter. Authentication asks *should this agent act?*; runtime governance asks *is it still acting within the limits it declared?* The two are complementary and independently conformant. ![Consumption-versus-time chart of the runtime governor. The vertical axis is cumulative consumption (tokens, cost, wall-clock); the horizontal axis is session progress. A bold red horizontal line near the top is the declared budget ceiling, fixed at admission — the deterministic boundary the governor enforces, with a GOVERNOR marker stationed on it. Rising from the session-start origin is a fan of blue curves, each a possible run of the agent; four level off below the ceiling and complete within budget, while one keeps climbing and is halted at the moment it would cross the ceiling, marked with a red cross labelled fail-closed. A caption notes the fan is one representative set of runs and the next run differs — the conduct is emergent; only the ceiling and the governor are fixed. To the right, a deterministic activity diagram shows the governor\'s decision loop: observe (the PDP projects usage), decide whether projected usage exceeds the cap, permit and loop if not, otherwise enforce (the PEP resolves the section 6 degradation response) and either apply the declared response or, if none is declared, HALT as the fail-closed default. A footnote states the governor is the control authority over the runtime, not the runtime itself and not the admission-time counterparty, and that the boundary and decision loop are fixed while the trajectories are not.](/assets/images/runtime-governor-envelope-59e37d597a3eaea58df709677961e37d.svg) *Figure 1 (informative): The runtime governor holds an admitted agent to its declared limits. A declared limit is a fixed boundary — here a budget ceiling (`permissions.resource_limits.budget`), fixed at admission (§1.3) — while the agent's consumption is emergent: a fan of possible runs, most completing under budget while one is halted at the boundary, fail-closed by default (§2, §6). The inset is the governor's deterministic observe → decide → enforce loop (§1.2). This figure is illustrative; the normative requirements are stated in the text.* ### 1.1 Role[​](#11-role "Direct link to 1.1 Role") The runtime governor is a **logical role**, not a prescribed component. Any element of a deployment with the authority to observe and intercept an agent's execution **MAY** act as the governor: the agent's own runtime, an AI gateway, a sidecar proxy, or an orchestrator. This protocol specifies the governor's responsibilities and authority, not its deployment shape. Two distinctions matter: * The governor is not **the runtime**. The runtime is the execution environment that runs the agent; the governor is the control authority *over* that environment. A single process **MAY** play both roles, but the responsibilities are separate — and §1.4 addresses the trust consequences when it does. * The governor is not the **counterparty** (Trust Protocol §1). The counterparty makes a one-time admission decision from the passport and hands off; the governor acts continuously, for the lifetime of the session, against the passport the counterparty admitted (§1.3). ### 1.2 Decision and Enforcement[​](#12-decision-and-enforcement "Direct link to 1.2 Decision and Enforcement") The governor operates a continuous **observe → decide → enforce** loop, decomposed into two functions adopted from the access-control model of \[XACML] / \[NIST.SP.800-162]: * A **policy decision point (PDP)** evaluates the agent's declared limits (the members enumerated in §2–§7) against the observed state of the running session and returns a decision. * A **policy enforcement point (PEP)** acts on that decision, with the authority to **observe**, **throttle**, **pause** (for oversight, §5), **halt**, or **escalate** execution. §2–§7 define the *decisions* the PDP makes for each class of limit. §6 (Degradation) defines the *enforcement responses* the PEP applies when a limit is reached. This section defines only the actor that hosts both. A conforming governor **MUST** be able to enforce, not merely observe, to claim any tier above R1 (Conformance Tiers). ### 1.3 Binding to the Passport[​](#13-binding-to-the-passport "Direct link to 1.3 Binding to the Passport") The governor enforces against the **passport admitted for the session**. It does **not** re-authenticate the agent: passport verification is the counterparty's procedure (Trust Protocol §1.1), and the governor consumes its result. The separation is deliberate — authentication establishes *identity and integrity*; runtime governance establishes *conformance to declared limits*. Two invariants bind the governor to that passport: 1. **Version pinning.** The governor **MUST** enforce against the exact passport version admitted at the start of the session — the same canonical bytes whose signature the counterparty verified (Trust Protocol §1.1.5). 2. **Anti-swap.** If the agent's declared limits change mid-session — a different passport, a re-signed passport, or any mutation of the members governed by §2–§7 — the governor **MUST NOT** silently adopt the new limits. It **MUST** treat the change as a session-integrity fault and apply the configured degradation response (§6), defaulting to fail-closed. An agent's declared limits are therefore not advisory inputs to the runtime; they are the governor's enforcement contract for the session, fixed at admission. ![State machine of the governor\'s binding to the passport. At session start the admitted passport is pinned to its exact canonical bytes — the version whose signature the counterparty verified — moving the governor into a governing state where it enforces against those pinned bytes on every step; while the bytes are unchanged it loops and continues. If the declared limits change mid-session — a different passport, a re-signed passport, or any mutation of the members governed by sections 2 to 7 — the governor must not silently adopt them; it transitions to a session-integrity fault state and applies the configured degradation response, defaulting to fail-closed (halt), so the swapped limits are never adopted.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA5MDAgNTIwIiB3aWR0aD0iOTAwIiBoZWlnaHQ9IjUyMCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsbGVkYnk9ImFzLXRpdGxlIGFzLWRlc2MiIGZvbnQtZmFtaWx5PSItYXBwbGUtc3lzdGVtLCBCbGlua01hY1N5c3RlbUZvbnQsICdTZWdvZSBVSScsIEhlbHZldGljYSwgQXJpYWwsIHNhbnMtc2VyaWYiPgogIDx0aXRsZSBpZD0iYXMtdGl0bGUiPkFudGktc3dhcCBhbmQgdmVyc2lvbiBwaW5uaW5nOiBkZWNsYXJlZCBsaW1pdHMgYXJlIGZpeGVkIGF0IGFkbWlzc2lvbiBhbmQgY2Fubm90IGJlIHNpbGVudGx5IHN3YXBwZWQgbWlkLXNlc3Npb248L3RpdGxlPgogIDxkZXNjIGlkPSJhcy1kZXNjIj5BIHN0YXRlIG1hY2hpbmUgZm9yIHRoZSBnb3Zlcm5vcidzIGJpbmRpbmcgdG8gdGhlIHBhc3Nwb3J0LiBBdCBzZXNzaW9uIHN0YXJ0IHRoZSBhZG1pdHRlZCBwYXNzcG9ydCBpcyBwaW5uZWQgdG8gaXRzIGV4YWN0IGNhbm9uaWNhbCBieXRlcyDigJQgdGhlIHZlcnNpb24gd2hvc2Ugc2lnbmF0dXJlIHRoZSBjb3VudGVycGFydHkgdmVyaWZpZWQg4oCUIG1vdmluZyB0aGUgZ292ZXJub3IgaW50byBhIGdvdmVybmluZyBzdGF0ZSwgd2hlcmUgaXQgZW5mb3JjZXMgYWdhaW5zdCB0aG9zZSBwaW5uZWQgYnl0ZXMgb24gZXZlcnkgc3RlcC4gV2hpbGUgZ292ZXJuaW5nLCBlYWNoIHN0ZXAgaXMgY2hlY2tlZCBhZ2FpbnN0IHRoZSBwaW46IGlmIHRoZSBjYW5vbmljYWwgYnl0ZXMgYXJlIHVuY2hhbmdlZCwgdGhlIGdvdmVybm9yIHN0YXlzIGluIHRoZSBnb3Zlcm5pbmcgc3RhdGUgYW5kIGNvbnRpbnVlcy4gSWYgdGhlIGRlY2xhcmVkIGxpbWl0cyBjaGFuZ2UgbWlkLXNlc3Npb24g4oCUIGEgZGlmZmVyZW50IHBhc3Nwb3J0LCBhIHJlLXNpZ25lZCBwYXNzcG9ydCwgb3IgYW55IG11dGF0aW9uIG9mIHRoZSBtZW1iZXJzIGdvdmVybmVkIGJ5IHNlY3Rpb25zIDIgdG8gNyDigJQgdGhlIGdvdmVybm9yIE1VU1QgTk9UIHNpbGVudGx5IGFkb3B0IHRoZSBuZXcgbGltaXRzOyBpdCB0cmFuc2l0aW9ucyB0byBhIHNlc3Npb24taW50ZWdyaXR5IGZhdWx0IHN0YXRlLiBGcm9tIHRoZSBmYXVsdCBzdGF0ZSBpdCBhcHBsaWVzIHRoZSBjb25maWd1cmVkIGRlZ3JhZGF0aW9uIHJlc3BvbnNlLCBkZWZhdWx0aW5nIHRvIGZhaWwtY2xvc2VkIChoYWx0KSwgYW5kIHRoZSBuZXcgbGltaXRzIGFyZSBuZXZlciBhZG9wdGVkLiBBIG5vdGUgc3RhdGVzIHRoZSBkZWNsYXJlZCBsaW1pdHMgYXJlIHRoZSBnb3Zlcm5vcidzIGVuZm9yY2VtZW50IGNvbnRyYWN0IGZvciB0aGUgc2Vzc2lvbiwgbm90IGFkdmlzb3J5IGlucHV0cy48L2Rlc2M+CgogIDxkZWZzPgogICAgPG1hcmtlciBpZD0iYXMtYXIiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPgogICAgICA8cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIGZpbGw9IiMzMzQxNTUiLz4KICAgIDwvbWFya2VyPgogICAgPG1hcmtlciBpZD0iYXMtYXItcmVkIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj4KICAgICAgPHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBmaWxsPSIjYzUyMjFmIi8+CiAgICA8L21hcmtlcj4KICA8L2RlZnM+CgogIDxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSI5MDAiIGhlaWdodD0iNTIwIiBmaWxsPSIjZmZmZmZmIi8+CgogIDwhLS0gVGl0bGUgLS0+CiAgPHRleHQgeD0iNDUwIiB5PSIzNCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIyMCIgZm9udC13ZWlnaHQ9IjcwMCIgZmlsbD0iIzBmMTcyYSI+QW50aS1Td2FwICZhbXA7IFZlcnNpb24gUGlubmluZzwvdGV4dD4KICA8dGV4dCB4PSI0NTAiIHk9IjU2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjEzIiBmb250LXN0eWxlPSJpdGFsaWMiIGZpbGw9IiM0NzU1NjkiPkRlY2xhcmVkIGxpbWl0cyBhcmUgZml4ZWQgYXQgYWRtaXNzaW9uICYjODIxMjsgdGhleSBjYW5ub3QgYmUgc2lsZW50bHkgc3dhcHBlZCBtaWQtc2Vzc2lvbiAoJiMxNjc7MS4zKTwvdGV4dD4KCiAgPCEtLSBpbml0aWFsIGRvdCAtLT4KICA8Y2lyY2xlIGN4PSI5MCIgY3k9IjE5MCIgcj0iNyIgZmlsbD0iIzMzNDE1NSIvPgogIDx0ZXh0IHg9IjkwIiB5PSIxNzAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iOS41IiBmaWxsPSIjNDc1NTY5Ij5zZXNzaW9uIHN0YXJ0PC90ZXh0PgoKICA8IS0tIEFETUlUVEVEIC8gcGlubmVkIHN0YXRlIC0tPgogIDxyZWN0IHg9IjE1MCIgeT0iMTU4IiB3aWR0aD0iMjAwIiBoZWlnaHQ9IjY0IiByeD0iMTIiIGZpbGw9IiNlOGYwZmUiIHN0cm9rZT0iIzFhNzNlOCIgc3Ryb2tlLXdpZHRoPSIxLjc1Ii8+CiAgPHRleHQgeD0iMjUwIiB5PSIxODQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTMiIGZvbnQtd2VpZ2h0PSI3MDAiIGZpbGw9IiMwYjU3ZDAiPmFkbWl0dGVkICYjMTgzOyBwaW5uZWQ8L3RleHQ+CiAgPHRleHQgeD0iMjUwIiB5PSIyMDEiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iOS41IiBmaWxsPSIjMWYyOTM3Ij5jYW5vbmljYWwgYnl0ZXMgZml4ZWQ8L3RleHQ+CiAgPHRleHQgeD0iMjUwIiB5PSIyMTQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iOS41IiBmaWxsPSIjMWYyOTM3Ij4odGhlICYjMTY3OzEuMS41IHZlcmlmaWVkIHZlcnNpb24pPC90ZXh0PgoKICA8bGluZSB4MT0iOTciIHkxPSIxOTAiIHgyPSIxNDgiIHkyPSIxOTAiIHN0cm9rZT0iIzMzNDE1NSIgc3Ryb2tlLXdpZHRoPSIxLjQiIG1hcmtlci1lbmQ9InVybCgjYXMtYXIpIi8+CgogIDwhLS0gR09WRVJOSU5HIHN0YXRlIC0tPgogIDxyZWN0IHg9IjQ1MCIgeT0iMTU4IiB3aWR0aD0iMjAwIiBoZWlnaHQ9IjY0IiByeD0iMTIiIGZpbGw9IiNlNmY0ZWEiIHN0cm9rZT0iIzEzNzMzMyIgc3Ryb2tlLXdpZHRoPSIxLjc1Ii8+CiAgPHRleHQgeD0iNTUwIiB5PSIxODQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTMiIGZvbnQtd2VpZ2h0PSI3MDAiIGZpbGw9IiMwZDY1MmQiPmdvdmVybmluZzwvdGV4dD4KICA8dGV4dCB4PSI1NTAiIHk9IjIwMSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSI5LjUiIGZpbGw9IiMxZjI5MzciPmVuZm9yY2UgYWdhaW5zdCB0aGUgcGluPC90ZXh0PgogIDx0ZXh0IHg9IjU1MCIgeT0iMjE0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjkuNSIgZmlsbD0iIzFmMjkzNyI+b24gZXZlcnkgc3RlcDwvdGV4dD4KCiAgPGxpbmUgeDE9IjM1MCIgeTE9IjE5MCIgeDI9IjQ0OCIgeTI9IjE5MCIgc3Ryb2tlPSIjMzM0MTU1IiBzdHJva2Utd2lkdGg9IjEuNCIgbWFya2VyLWVuZD0idXJsKCNhcy1hcikiLz4KICA8cmVjdCB4PSIzNjQiIHk9IjE3OSIgd2lkdGg9IjcyIiBoZWlnaHQ9IjE2IiBmaWxsPSIjZmZmZmZmIi8+CiAgPHRleHQgeD0iNDAwIiB5PSIxOTEiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iOS41IiBmaWxsPSIjNDc1NTY5Ij5hZG1pdDwvdGV4dD4KCiAgPCEtLSBzZWxmLWxvb3A6IGJ5dGVzIHVuY2hhbmdlZCAtPiBjb250aW51ZSAtLT4KICA8cGF0aCBkPSJNNTIwLDE1OCBDIDUwNSwxMjAgNTk1LDEyMCA1ODAsMTU4IiBmaWxsPSJub25lIiBzdHJva2U9IiMxMzczMzMiIHN0cm9rZS13aWR0aD0iMS40IiBtYXJrZXItZW5kPSJ1cmwoI2FzLWFyKSIvPgogIDx0ZXh0IHg9IjU1MCIgeT0iMTIwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjkuNSIgZmlsbD0iIzBkNjUyZCI+Ynl0ZXMgdW5jaGFuZ2VkICYjODU5NDsgY29udGludWU8L3RleHQ+CgogIDwhLS0gY2hlY2sgc3RlcCAoZGVjaXNpb24pIGJlbG93IGdvdmVybmluZyAtLT4KICA8dGV4dCB4PSI1NTAiIHk9IjI1MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxMCIgZm9udC1zdHlsZT0iaXRhbGljIiBmaWxsPSIjNDc1NTY5Ij5lYWNoIHN0ZXA6IGRvIHRoZSBjYW5vbmljYWwgYnl0ZXMgc3RpbGwgbWF0Y2ggdGhlIHBpbj88L3RleHQ+CgogIDwhLS0gdHJhbnNpdGlvbiB0byBGQVVMVCAoZG93bikgb24gbXV0YXRpb24gLS0+CiAgPGxpbmUgeDE9IjU1MCIgeTE9IjIyMiIgeDI9IjU1MCIgeTI9IjMwMCIgc3Ryb2tlPSIjYzUyMjFmIiBzdHJva2Utd2lkdGg9IjEuNiIgbWFya2VyLWVuZD0idXJsKCNhcy1hci1yZWQpIi8+CiAgPHJlY3QgeD0iMzcyIiB5PSIyNjIiIHdpZHRoPSIzNTYiIGhlaWdodD0iMzIiIGZpbGw9IiNmZmZmZmYiLz4KICA8dGV4dCB4PSI1NTAiIHk9IjI3NiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxMCIgZm9udC13ZWlnaHQ9IjcwMCIgZmlsbD0iI2E1MGUwZSI+bGltaXRzIGNoYW5nZSBtaWQtc2Vzc2lvbjwvdGV4dD4KICA8dGV4dCB4PSI1NTAiIHk9IjI4OSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSI5IiBmaWxsPSIjYTUwZTBlIj5kaWZmZXJlbnQgLyByZS1zaWduZWQgcGFzc3BvcnQgJiMxODM7IGFueSAmIzE2NzsyJiM4MjExOyYjMTY3OzcgbXV0YXRpb248L3RleHQ+CgogIDwhLS0gRkFVTFQgc3RhdGUgLS0+CiAgPHJlY3QgeD0iNDMwIiB5PSIzMDAiIHdpZHRoPSIyNDAiIGhlaWdodD0iNjAiIHJ4PSIxMiIgZmlsbD0iI2ZjZThlNiIgc3Ryb2tlPSIjYzUyMjFmIiBzdHJva2Utd2lkdGg9IjEuNzUiLz4KICA8dGV4dCB4PSI1NTAiIHk9IjMyNSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxMyIgZm9udC13ZWlnaHQ9IjcwMCIgZmlsbD0iI2E1MGUwZSI+c2Vzc2lvbi1pbnRlZ3JpdHkgZmF1bHQ8L3RleHQ+CiAgPHRleHQgeD0iNTUwIiB5PSIzNDMiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iOS41IiBmaWxsPSIjMWYyOTM3Ij5uZXcgbGltaXRzIE1VU1QgTk9UIGJlIHNpbGVudGx5IGFkb3B0ZWQ8L3RleHQ+CgogIDwhLS0gdHJhbnNpdGlvbiB0byBkZWdyYWRhdGlvbiAvIGZhaWwtY2xvc2VkIChkb3duKSAtLT4KICA8bGluZSB4MT0iNTUwIiB5MT0iMzYwIiB4Mj0iNTUwIiB5Mj0iNDA0IiBzdHJva2U9IiNjNTIyMWYiIHN0cm9rZS13aWR0aD0iMS42IiBtYXJrZXItZW5kPSJ1cmwoI2FzLWFyLXJlZCkiLz4KICA8cmVjdCB4PSI1NTYiIHk9IjM3MiIgd2lkdGg9IjEyMCIgaGVpZ2h0PSIxNiIgZmlsbD0iI2ZmZmZmZiIvPgogIDx0ZXh0IHg9IjU2MCIgeT0iMzg0IiB0ZXh0LWFuY2hvcj0ic3RhcnQiIGZvbnQtc2l6ZT0iOS41IiBmaWxsPSIjYTUwZTBlIj5hcHBseSBkZWdyYWRhdGlvbiAoJiMxNjc7Nik8L3RleHQ+CgogIDwhLS0gRkFJTC1DTE9TRUQgdGVybWluYWwgLS0+CiAgPHJlY3QgeD0iNDMwIiB5PSI0MDQiIHdpZHRoPSIyNDAiIGhlaWdodD0iNjAiIHJ4PSIxMiIgZmlsbD0iI2ZkZThlOCIgc3Ryb2tlPSIjYzUyMjFmIiBzdHJva2Utd2lkdGg9IjIiLz4KICA8dGV4dCB4PSI1NTAiIHk9IjQyOSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxMyIgZm9udC13ZWlnaHQ9IjcwMCIgZmlsbD0iI2E1MGUwZSI+ZmFpbC1jbG9zZWQgKGhhbHQpIGJ5IGRlZmF1bHQ8L3RleHQ+CiAgPHRleHQgeD0iNTUwIiB5PSI0NDciIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iOS41IiBmaWxsPSIjMWYyOTM3Ij50aGUgc3dhcHBlZCBsaW1pdHMgYXJlIG5ldmVyIGFkb3B0ZWQ8L3RleHQ+CgogIDwhLS0gbm90ZSAobGVmdCwgdW5kZXIgYWRtaXR0ZWQpIC0tPgogIDxyZWN0IHg9IjgwIiB5PSIzMjAiIHdpZHRoPSIzMDAiIGhlaWdodD0iOTYiIHJ4PSIxMCIgZmlsbD0iI2Y4ZmFmYyIgc3Ryb2tlPSIjY2JkNWUxIiBzdHJva2Utd2lkdGg9IjEuNSIgc3Ryb2tlLWRhc2hhcnJheT0iNSA0Ii8+CiAgPHRleHQgeD0iOTYiIHk9IjM0NCIgZm9udC1zaXplPSIxMSIgZm9udC13ZWlnaHQ9IjcwMCIgZmlsbD0iIzMzNDE1NSI+VGhlIHBpbiBpcyB0aGUgZW5mb3JjZW1lbnQgY29udHJhY3Q8L3RleHQ+CiAgPHRleHQgeD0iOTYiIHk9IjM2NCIgZm9udC1zaXplPSIxMCIgZmlsbD0iIzFmMjkzNyI+RGVjbGFyZWQgbGltaXRzIGFyZSBmaXhlZCBhdCBhZG1pc3Npb24sPC90ZXh0PgogIDx0ZXh0IHg9Ijk2IiB5PSIzNzkiIGZvbnQtc2l6ZT0iMTAiIGZpbGw9IiMxZjI5MzciPm5vdCBhZHZpc29yeSBpbnB1dHMgdGhlIHJ1bnRpbWUgY2FuIHJldmlzZS48L3RleHQ+CiAgPHRleHQgeD0iOTYiIHk9IjM5OSIgZm9udC1zaXplPSIxMCIgZmlsbD0iIzFmMjkzNyI+QSBtaWQtc2Vzc2lvbiBzd2FwIGlzIGEgZmF1bHQsIG5vdCBhbjwvdGV4dD4KICA8dGV4dCB4PSI5NiIgeT0iNDE0IiBmb250LXNpemU9IjEwIiBmaWxsPSIjMWYyOTM3Ij51cGRhdGUgJiM4MjEyOyB0aGUgc2Vzc2lvbiBoYWx0cyByYXRoZXIgdGhhbiBkcmlmdC48L3RleHQ+CgogIDwhLS0gZm9vdG5vdGUgLS0+CiAgPHRleHQgeD0iNDUwIiB5PSI0OTgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTEiIGZvbnQtc3R5bGU9Iml0YWxpYyIgZmlsbD0iIzQ3NTU2OSI+U2Vzc2lvbi1pbnRlZ3JpdHkgbG9naWMgaXMgZGV0ZXJtaW5pc3RpYzogYSBzd2FwcGVkIG9yIG11dGF0ZWQgcGFzc3BvcnQgYWx3YXlzIGZhdWx0cyB0byB0aGUgc2FtZSBmYWlsLWNsb3NlZCBkZWZhdWx0LiBJbGx1c3RyYXRpdmU7ICYjMTY3OzEuMyBpcyBhdXRob3JpdGF0aXZlLjwvdGV4dD4KPC9zdmc+Cg==) *Figure 2 (informative): The admitted passport is pinned at session start; every step is checked against the pin. A mid-session change is treated as a session-integrity fault and fails closed by default — a swap is a fault, not an update. This figure is illustrative; §1.3 is authoritative.* ### 1.4 Trust in the Governor[​](#14-trust-in-the-governor "Direct link to 1.4 Trust in the Governor") Because the governor **MAY** be operated by the same party that operates the agent (§1.1), its enforcement cannot be taken on faith: a party that benefits from an agent exceeding its limits could also operate a governor that declines to stop it. This is the **self-governance** problem, and this protocol does not pretend it away. It is addressed by tiered evidence rather than by mandating separation: * At **R1 (Observing)**, the governor's contribution is the **audit trail** — a record of the agent's resource use and limit boundaries that a third party can inspect after the fact. This is "document it," not "stop it." * At **R2 (Enforcing)** and **R3 (Adaptive)**, a governor's enforcement **SHOULD** be **externally evidenced**: the governor produces verifiable evidence, bound to the admitted passport and session, that lets a counterparty distinguish a governor that *actually* enforced at a tier from one that merely *claimed* it. The concrete evidence format — what an enforcement record attests, how it binds to the passport and session, and how a counterparty verifies it — is specified in **§8 (Enforcement Evidence)**. That mechanism provides tamper-evidence and freshness but **not** completeness; detecting omission by a self-interested operator is the reserved witness tier (§8.8). **Status:** §1.1–§1.3 are stable framing. §1.4's evidence mechanism is specified in §8; the per-tier normative requirements continue to firm up. ## 2 Budget Enforcement[​](#2-budget-enforcement "Direct link to 2 Budget Enforcement") This section defines how the governor (§1) enforces the budget envelope declared in [ADL Core §9.6](/spec/next#96-resource-limits): `permissions.resource_limits.budget`, capping `tokens`, `cost_usd`, and `wall_clock_sec` per session and per day. The governor's PDP (§1.2) **MUST** maintain cumulative counters for each declared `budget` dimension, scoped per session (§1.3) and per rolling 24-hour day. Before the PEP admits a step that consumes a budgeted resource — a model call (tokens, cost) or any execution (wall-clock) — the PDP **MUST**: 1. **Project usage.** Compute projected cumulative usage as the current counter plus the step's expected consumption, for each declared dimension and scope. 2. **Compare to caps.** For each declared cap, if projected usage would exceed it, the dimension is **exhausted** for that scope. 3. **Decide.** If no declared cap would be exceeded, return *permit*. If any would, return *budget-exhausted*, identifying the dimension (`tokens` / `cost_usd` / `wall_clock_sec`) and scope (`per_session` / `per_day`). 4. **Enforce.** On *budget-exhausted*, the PEP **MUST** apply the degradation response keyed `on_budget_exhausted` (§6), **defaulting to fail-closed** (halt the session) when no response is declared. 5. **Record.** The governor **MUST** record the boundary event (which cap, which scope, observed versus limit) in its audit trail (§1.4), regardless of tier. Cost accounting — mapping token counts and tool calls to `cost_usd` — is governor-specific. A governor claiming R2 or above on the `cost_usd` dimension **MUST** document its cost model. **Sub-agent personas draw down the parent's envelope.** When the agent spawns subordinate personas ([Core §9.7.1](/spec/next#971-sub-agents-personas)), their consumption is **not** metered separately: a persona acts under the parent's identity, so the governor **MUST** count persona tokens, cost, and wall-clock against the parent's `budget` counters in **aggregate** (parent plus all personas), and **MUST** additionally enforce a persona's `budget_share` against that persona's own consumption when declared. The parent's caps are therefore the ceiling for the whole persona fan-out, not per-persona. (A separately-identified *peer*, by contrast, carries its own `budget` and is governed under §4.2.) **Conformance.** At **R1** the governor tracks usage against caps and records boundary events but does not block. At **R2** it **MUST** block any step that would exceed a declared cap and apply §6 degradation. At **R3** the boundary events additionally feed the anomaly substrate (§7). ## 3 Iteration Control[​](#3-iteration-control "Direct link to 3 Iteration Control") This section defines how the governor enforces the iteration limits declared in [ADL Core §11.3](/spec/next#113-tool-invocation): `max_iterations`, `max_tool_calls_per_session`, and `loop_detection`. The governor's PDP (§1.2) **MUST** maintain, per session (§1.3), a count of reason→act iterations and a count of tool invocations, and **MUST** retain a sliding window of the most recent steps when `loop_detection` is declared. Before the PEP admits a step, the PDP **MUST**: 1. **Count.** Increment the projected iteration and tool-call counts for the step. 2. **Check hard limits.** If the projected count would exceed `max_iterations` or `max_tool_calls_per_session`, the limit is reached. 3. **Detect loops.** When `loop_detection` is declared, examine the last `window` steps; if the step would repeat a prior step's signature (same tool and equivalent arguments) beyond a governor-defined repetition threshold, a loop is detected. How signatures are computed is governor-specific and **MUST** be documented when claiming R2+ on loop detection. 4. **Decide and enforce.** On a reached limit or detected loop, resolve the degradation response (§6): for a detected loop, `loop_detection.on_detected` if present, otherwise `runtime.degradation.on_iteration_limit`; for a hard limit, `runtime.degradation.on_iteration_limit`. Absent either, **fail closed** (halt). 5. **Record.** Record the boundary or loop event in the audit trail (§1.4). **Conformance.** At **R1** the governor counts iterations and tool calls and flags loops without blocking. At **R2** it **MUST** block on a reached limit or detected loop and apply §6. At **R3** loop and limit events feed the anomaly substrate (§7). ## 4 Sub-Agent Spawning and Peer Delegation[​](#4-sub-agent-spawning-and-peer-delegation "Direct link to 4 Sub-Agent Spawning and Peer Delegation") ADL Core §9.7 declares two ways an agent brings other agents into its work, distinguished by identity, and the governor treats them differently because only one crosses a trust boundary: * **Sub-agents** ([Core §9.7.1](/spec/next#971-sub-agents-personas)) are subordinate **personas** spawned under the parent's own identity. There is no passport to verify and no counterparty — the governor *caps* them, it does not *admit* them. * **Delegation** ([Core §9.7.2](/spec/next#972-delegation-external-peers)) engages a separately-identified **peer**. This crosses a trust boundary and is the case that requires admission. ### 4.1 Sub-agent (persona) capping[​](#41-sub-agent-persona-capping "Direct link to 4.1 Sub-agent (persona) capping") When the agent attempts to spawn a persona declared in `permissions.sub_agents`, the governor's PDP (§1.2) **MUST**, before the PEP admits the spawn: 1. **Match the persona.** The persona **MUST** correspond to a declared `sub_agents[]` entry by `name`; a spawn naming no declared persona is **not** permitted (deny-by-default). The governor **MUST NOT** grant the persona any tool outside its declared `tools` subset (or the parent's tools when `tools` is omitted), and never a tool the parent itself lacks. 2. **Check concurrency.** Reject the spawn if it would exceed the persona's `max_parallel` or the parent's `resource_limits.max_concurrent` (§9.6). 3. **Account against the parent.** Persona consumption draws down the parent's envelope: the governor **MUST** count a persona's tokens, cost, and wall-clock against the parent's `budget` (§2) in **aggregate**, and against the persona's `budget_share` when declared. A persona does **not** receive a fresh budget. 4. **Decide and enforce.** If any check fails, the spawn is denied; the PEP resolves `runtime.degradation.on_sub_agent_denied` (§6), defaulting to fail-closed (do not spawn). 5. **Record.** Record the spawn decision (persona `name`, matched rule, aggregate draw-down) in the audit trail (§1.4). A persona is **never** admitted as a counterparty: there is no passport, no delegation chain, and no attenuation to verify, because the persona acts under the parent's identity and its authority is a subset of the parent's by construction. ### 4.2 Peer (external) admission[​](#42-peer-external-admission "Direct link to 4.2 Peer (external) admission") When the agent attempts to delegate to a separately-identified peer, the governor's PDP (§1.2) **MUST**, before the PEP admits the delegation, evaluate the peer against `permissions.delegation`: 1. **Match identity.** Resolve the prospective peer's identifier and evaluate it against `match` and `deny` per §4.4 patterns. `deny` overrides `match`; an identifier matching no `match` pattern is **not** permitted (deny-by-default). 2. **Check depth.** Reject the delegation if it would exceed `max_depth` relative to the root of the current delegation chain. 3. **Check attenuation.** When `attenuation.scopes_subset` is set, the peer's passport `security.scopes` **MUST** be a subset of this agent's ceiling; when `attenuation.budget_subset` is set, its `budget` caps **MUST** be ≤ this agent's. This composes with — and does not replace — the Trust Protocol's delegation-chain verification, which establishes the peer's identity and the chain's integrity. 4. **Decide and enforce.** If any check fails, the delegation is denied; the PEP resolves `runtime.degradation.on_delegation_denied` (§6), defaulting to fail-closed (do not delegate). 5. **Record.** Record the admission decision (peer identity, matched rule, attenuation result) in the audit trail (§1.4). **Conformance.** At **R1** the governor records prospective spawns and delegations and what the decision *would* be; it does not block. At **R2** it **MUST** enforce persona caps (§4.1) and peer admission (§4.2) and apply §6 on denial. At **R3** spawn and delegation patterns feed the anomaly substrate (§7). ## 5 Oversight Triggers[​](#5-oversight-triggers "Direct link to 5 Oversight Triggers") This section defines how the governor evaluates the human-oversight triggers declared in the [Governance Profile](/profiles/governance/specification.md) (`human_oversight.triggers`), including the structured predicate form, and the pause/timeout behavior they impose. For each declared trigger, the governor's PDP (§1.2) **MUST**, before the PEP admits a step: 1. **Evaluate predicates.** For a structured trigger, evaluate its `when` predicates against the step and session state: `cost_usd_over` against the §2 cost counter, `data_classification_at_least` against the step's data classification, `tool` against the tool about to be invoked, and `path_matches` against the target path (§4.4 patterns). The trigger fires when **all** its predicates hold. Free-text triggers are evaluated by governor-specific detection. 2. **Pause on fire.** When a trigger fires, the PEP **MUST** pause execution (degradation action `pause`, §6) and request human review through the declared `intervention_model`. 3. **Time out.** If no reviewer responds within `human_oversight.response_time_minutes`, the governor resolves `runtime.degradation.on_oversight_timeout` (§6), defaulting to fail-closed (halt). The agent **MUST NOT** proceed unreviewed. 4. **Resume.** Execution resumes only on explicit approval per the `intervention_model` (`approve_reject` or `plan_editing`); `monitor_only` does not gate execution. 5. **Record.** Record the trigger firing, the review outcome, and any timeout in the audit trail (§1.4). Independently of the Governance Profile, a governor **MUST** treat any tool declaring `requires_confirmation: true` ([ADL Core §8.1](/spec/next#81-tools)) as an always-on oversight trigger: the governor **MUST** obtain explicit human approval before such a tool is invoked and **MUST NOT** invoke it autonomously, regardless of whether `human_oversight` is declared. This is a Core-level control and applies even when no Governance Profile is present. Structured triggers let the governor evaluate oversight conditions mechanically. Free-text triggers require governor-specific interpretation and are best treated as R1 signals unless the governor can detect them reliably. **Conformance.** At **R1** the governor records trigger evaluations without pausing. At **R2** it **MUST** pause on a fired trigger and enforce the response-time timeout. At **R3** trigger firings feed the anomaly substrate (§7). ## 6 Degradation[​](#6-degradation "Direct link to 6 Degradation") This section defines how the governor responds when a limit fires or a fault occurs. Responses are declared in [ADL Core §11.5](/spec/next#115-degradation) as `runtime.degradation`, a map from *cause* (`on_budget_exhausted`, `on_iteration_limit`, `on_sub_agent_denied`, `on_delegation_denied`, `on_oversight_timeout`, `on_tool_error`, `on_anomaly`, …) to a *response* whose `action` is one of `halt`, `pause`, `fallback`, or `continue`. ![Activity diagram of the degradation procedure. A cause fires — budget exhausted, iteration limit, sub-agent denied, oversight timeout, tool error, or anomaly. The governor looks up the cause in the declared runtime.degradation map. If a response is declared, it applies the declared action: halt terminates the session, pause suspends and escalates for human oversight, fallback substitutes a declared value and continues, or continue proceeds despite the cause — continue is fail-open and must be explicitly declared and recorded with the cause it overrode. If no response is declared, the governor must halt the session: absence of a declared response is not consent to continue; this fail-closed default is the core of teeth at runtime. Every degradation event, including whether the fail-closed default applied, is recorded in the audit trail.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA5MDAgNTQwIiB3aWR0aD0iOTAwIiBoZWlnaHQ9IjU0MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsbGVkYnk9ImRnLXRpdGxlIGRnLWRlc2MiIGZvbnQtZmFtaWx5PSItYXBwbGUtc3lzdGVtLCBCbGlua01hY1N5c3RlbUZvbnQsICdTZWdvZSBVSScsIEhlbHZldGljYSwgQXJpYWwsIHNhbnMtc2VyaWYiPgogIDx0aXRsZSBpZD0iZGctdGl0bGUiPkRlZ3JhZGF0aW9uOiBhIGZpcmVkIGNhdXNlIHJlc29sdmVzIHRvIGEgZGVjbGFyZWQgcmVzcG9uc2UsIG9yIGZhaWxzIGNsb3NlZCBieSBkZWZhdWx0PC90aXRsZT4KICA8ZGVzYyBpZD0iZGctZGVzYyI+QW4gYWN0aXZpdHkgZGlhZ3JhbSBvZiB0aGUgZ292ZXJub3IncyBkZWdyYWRhdGlvbiBwcm9jZWR1cmUuIEEgY2F1c2UgZmlyZXMg4oCUIGZvciBleGFtcGxlIGJ1ZGdldCBleGhhdXN0ZWQsIGl0ZXJhdGlvbiBsaW1pdCwgc3ViLWFnZW50IGRlbmllZCwgb3ZlcnNpZ2h0IHRpbWVvdXQsIHRvb2wgZXJyb3IsIG9yIGFub21hbHkuIFRoZSBnb3Zlcm5vciBsb29rcyB1cCB0aGUgY2F1c2UgaW4gdGhlIGRlY2xhcmVkIHJ1bnRpbWUuZGVncmFkYXRpb24gbWFwLiBJZiBhIHJlc3BvbnNlIGlzIGRlY2xhcmVkLCBpdCBhcHBsaWVzIHRoZSBkZWNsYXJlZCBhY3Rpb246IGhhbHQgdGVybWluYXRlcyB0aGUgc2Vzc2lvbiwgcGF1c2Ugc3VzcGVuZHMgYW5kIGVzY2FsYXRlcyBmb3IgaHVtYW4gb3ZlcnNpZ2h0LCBmYWxsYmFjayBzdWJzdGl0dXRlcyBhIGRlY2xhcmVkIHZhbHVlIGFuZCBjb250aW51ZXMsIG9yIGNvbnRpbnVlIHByb2NlZWRzIGRlc3BpdGUgdGhlIGNhdXNlLiBDb250aW51ZSBpcyBmYWlsLW9wZW4gYW5kIG11c3QgYmUgZXhwbGljaXRseSBkZWNsYXJlZCBhbmQgcmVjb3JkZWQgaW4gdGhlIGF1ZGl0IHRyYWlsIHRvZ2V0aGVyIHdpdGggdGhlIGNhdXNlIGl0IG92ZXJyb2RlLiBJZiBubyByZXNwb25zZSBpcyBkZWNsYXJlZCBmb3IgdGhlIGNhdXNlLCB0aGUgZ292ZXJub3IgbXVzdCBoYWx0IHRoZSBzZXNzaW9uIOKAlCBhYnNlbmNlIG9mIGEgZGVjbGFyZWQgcmVzcG9uc2UgaXMgbm90IGNvbnNlbnQgdG8gY29udGludWU7IHRoaXMgZmFpbC1jbG9zZWQgZGVmYXVsdCBpcyB0aGUgY29yZSBvZiB0ZWV0aCBhdCBydW50aW1lLiBFdmVyeSBkZWdyYWRhdGlvbiBldmVudCwgaW5jbHVkaW5nIHdoZXRoZXIgdGhlIGZhaWwtY2xvc2VkIGRlZmF1bHQgYXBwbGllZCwgaXMgcmVjb3JkZWQgaW4gdGhlIGF1ZGl0IHRyYWlsLjwvZGVzYz4KCiAgPGRlZnM+CiAgICA8bWFya2VyIGlkPSJkZy1hciIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI5IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+CiAgICAgIDxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgZmlsbD0iIzMzNDE1NSIvPgogICAgPC9tYXJrZXI+CiAgICA8bWFya2VyIGlkPSJkZy1hci1yZWQiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPgogICAgICA8cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIGZpbGw9IiNjNTIyMWYiLz4KICAgIDwvbWFya2VyPgogIDwvZGVmcz4KCiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjkwMCIgaGVpZ2h0PSI1NDAiIGZpbGw9IiNmZmZmZmYiLz4KCiAgPCEtLSBUaXRsZSAtLT4KICA8dGV4dCB4PSI0NTAiIHk9IjM0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjIwIiBmb250LXdlaWdodD0iNzAwIiBmaWxsPSIjMGYxNzJhIj5EZWdyYWRhdGlvbiAmYW1wOyB0aGUgRmFpbC1DbG9zZWQgRGVmYXVsdDwvdGV4dD4KICA8dGV4dCB4PSI0NTAiIHk9IjU2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjEzIiBmb250LXN0eWxlPSJpdGFsaWMiIGZpbGw9IiM0NzU1NjkiPkEgZmlyZWQgY2F1c2UgcmVzb2x2ZXMgdG8gYSBkZWNsYXJlZCByZXNwb25zZSAmIzgyMTI7IG9yIHRoZSBzZXNzaW9uIGhhbHRzICgmIzE2Nzs2KTwvdGV4dD4KCiAgPCEtLSBjYXVzZSBmaXJlcyAtLT4KICA8cmVjdCB4PSIzMjAiIHk9IjgwIiB3aWR0aD0iMjYwIiBoZWlnaHQ9IjQ4IiByeD0iMTAiIGZpbGw9IiNmZmY3ZTYiIHN0cm9rZT0iI2Y1OWUwYiIgc3Ryb2tlLXdpZHRoPSIxLjUiLz4KICA8dGV4dCB4PSI0NTAiIHk9IjEwMCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxMiIgZm9udC13ZWlnaHQ9IjcwMCIgZmlsbD0iI2I0NTMwOSI+YSBjYXVzZSBmaXJlczwvdGV4dD4KICA8dGV4dCB4PSI0NTAiIHk9IjExNiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSI4IiBmaWxsPSIjMWYyOTM3Ij5idWRnZXQgJiMxODM7IGl0ZXJhdGlvbiAmIzE4Mzsgc3ViLWFnZW50ICYjMTgzOyBvdmVyc2lnaHQgJiMxODM7IHRvb2wtZXJyb3IgJiMxODM7IGFub21hbHk8L3RleHQ+CgogIDxsaW5lIHgxPSI0NTAiIHkxPSIxMjgiIHgyPSI0NTAiIHkyPSIxNTAiIHN0cm9rZT0iIzMzNDE1NSIgc3Ryb2tlLXdpZHRoPSIxLjQiIG1hcmtlci1lbmQ9InVybCgjZGctYXIpIi8+CgogIDwhLS0gZGVjaXNpb246IGRlY2xhcmVkPyAtLT4KICA8cG9seWdvbiBwb2ludHM9IjQ1MCwxNTAgNTgwLDE5MiA0NTAsMjM0IDMyMCwxOTIiIGZpbGw9IiNmZmZmZmYiIHN0cm9rZT0iI2Y1OWUwYiIgc3Ryb2tlLXdpZHRoPSIxLjYiLz4KICA8dGV4dCB4PSI0NTAiIHk9IjE4OCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxMSIgZm9udC13ZWlnaHQ9IjcwMCIgZmlsbD0iIzFmMjkzNyI+cmVzcG9uc2UgZGVjbGFyZWQgaW48L3RleHQ+CiAgPHRleHQgeD0iNDUwIiB5PSIyMDIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTAiIGZpbGw9IiMxZjI5MzciPnJ1bnRpbWUuZGVncmFkYXRpb24/PC90ZXh0PgoKICA8IS0tIFlFUyBicmFuY2ggKGxlZnQvZG93biB0byBhY3Rpb25zKSAtLT4KICA8bGluZSB4MT0iMzIwIiB5MT0iMTkyIiB4Mj0iMTUwIiB5Mj0iMTkyIiBzdHJva2U9IiMzMzQxNTUiIHN0cm9rZS13aWR0aD0iMS40Ii8+CiAgPGxpbmUgeDE9IjE1MCIgeTE9IjE5MiIgeDI9IjE1MCIgeTI9IjI1MCIgc3Ryb2tlPSIjMzM0MTU1IiBzdHJva2Utd2lkdGg9IjEuNCIgbWFya2VyLWVuZD0idXJsKCNkZy1hcikiLz4KICA8cmVjdCB4PSIxMjAiIHk9IjIwMCIgd2lkdGg9IjYwIiBoZWlnaHQ9IjE2IiBmaWxsPSIjZmZmZmZmIi8+CiAgPHRleHQgeD0iMTUwIiB5PSIyMTIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTAiIGZvbnQtd2VpZ2h0PSI3MDAiIGZpbGw9IiMxMzczMzMiPnllczwvdGV4dD4KCiAgPCEtLSBOTyBicmFuY2ggKHJpZ2h0L2Rvd24gdG8gSEFMVCkgLS0+CiAgPGxpbmUgeDE9IjU4MCIgeTE9IjE5MiIgeDI9Ijc1MCIgeTI9IjE5MiIgc3Ryb2tlPSIjYzUyMjFmIiBzdHJva2Utd2lkdGg9IjEuNSIvPgogIDxsaW5lIHgxPSI3NTAiIHkxPSIxOTIiIHgyPSI3NTAiIHkyPSIyNTAiIHN0cm9rZT0iI2M1MjIxZiIgc3Ryb2tlLXdpZHRoPSIxLjUiIG1hcmtlci1lbmQ9InVybCgjZGctYXItcmVkKSIvPgogIDxyZWN0IHg9IjcwMCIgeT0iMTg0IiB3aWR0aD0iMTUwIiBoZWlnaHQ9IjE2IiBmaWxsPSIjZmZmZmZmIi8+CiAgPHRleHQgeD0iNzc1IiB5PSIxOTYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTAiIGZvbnQtd2VpZ2h0PSI3MDAiIGZpbGw9IiNhNTBlMGUiPm5vIGRlY2xhcmVkIHJlc3BvbnNlPC90ZXh0PgoKICA8IS0tIGFwcGx5LXRoZS1hY3Rpb24gY29udGFpbmVyIC0tPgogIDxyZWN0IHg9IjQwIiB5PSIyNTAiIHdpZHRoPSI1NjAiIGhlaWdodD0iMTcwIiByeD0iMTAiIGZpbGw9IiNmOGZhZmMiIHN0cm9rZT0iI2NiZDVlMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNCIvPgogIDx0ZXh0IHg9IjYwIiB5PSIyNzIiIGZvbnQtc2l6ZT0iMTEiIGZvbnQtd2VpZ2h0PSI3MDAiIGZpbGw9IiMzMzQxNTUiPmFwcGx5IHRoZSBkZWNsYXJlZCBhY3Rpb248L3RleHQ+CgogIDwhLS0gZm91ciBhY3Rpb24gY2hpcHMgLS0+CiAgPHJlY3QgeD0iNjAiIHk9IjI4NiIgd2lkdGg9IjEyMCIgaGVpZ2h0PSI1OCIgcng9IjgiIGZpbGw9IiNlNmY0ZWEiIHN0cm9rZT0iIzEzNzMzMyIgc3Ryb2tlLXdpZHRoPSIxLjQiLz4KICA8dGV4dCB4PSIxMjAiIHk9IjMwNyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxMSIgZm9udC13ZWlnaHQ9IjcwMCIgZmlsbD0iIzBkNjUyZCI+aGFsdDwvdGV4dD4KICA8dGV4dCB4PSIxMjAiIHk9IjMyNCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSI4LjUiIGZpbGw9IiMxZjI5MzciPnRlcm1pbmF0ZSB0aGU8L3RleHQ+CiAgPHRleHQgeD0iMTIwIiB5PSIzMzUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iOC41IiBmaWxsPSIjMWYyOTM3Ij5zZXNzaW9uPC90ZXh0PgoKICA8cmVjdCB4PSIxOTIiIHk9IjI4NiIgd2lkdGg9IjEyMCIgaGVpZ2h0PSI1OCIgcng9IjgiIGZpbGw9IiNlOGYwZmUiIHN0cm9rZT0iIzFhNzNlOCIgc3Ryb2tlLXdpZHRoPSIxLjQiLz4KICA8dGV4dCB4PSIyNTIiIHk9IjMwNyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxMSIgZm9udC13ZWlnaHQ9IjcwMCIgZmlsbD0iIzBiNTdkMCI+cGF1c2U8L3RleHQ+CiAgPHRleHQgeD0iMjUyIiB5PSIzMjQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iOC41IiBmaWxsPSIjMWYyOTM3Ij5lc2NhbGF0ZSB0byBodW1hbjwvdGV4dD4KICA8dGV4dCB4PSIyNTIiIHk9IjMzNSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSI4LjUiIGZpbGw9IiMxZjI5MzciPm92ZXJzaWdodCAoJiMxNjc7NSk8L3RleHQ+CgogIDxyZWN0IHg9IjMyNCIgeT0iMjg2IiB3aWR0aD0iMTIwIiBoZWlnaHQ9IjU4IiByeD0iOCIgZmlsbD0iI2U4ZjBmZSIgc3Ryb2tlPSIjMWE3M2U4IiBzdHJva2Utd2lkdGg9IjEuNCIvPgogIDx0ZXh0IHg9IjM4NCIgeT0iMzA3IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjExIiBmb250LXdlaWdodD0iNzAwIiBmaWxsPSIjMGI1N2QwIj5mYWxsYmFjazwvdGV4dD4KICA8dGV4dCB4PSIzODQiIHk9IjMyNCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSI4LjUiIGZpbGw9IiMxZjI5MzciPnN1YnN0aXR1dGUgdmFsdWUsPC90ZXh0PgogIDx0ZXh0IHg9IjM4NCIgeT0iMzM1IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjguNSIgZmlsbD0iIzFmMjkzNyI+Y29udGludWU8L3RleHQ+CgogIDxyZWN0IHg9IjQ1NiIgeT0iMjg2IiB3aWR0aD0iMTIwIiBoZWlnaHQ9IjU4IiByeD0iOCIgZmlsbD0iI2ZlZjNjNyIgc3Ryb2tlPSIjZDk3NzA2IiBzdHJva2Utd2lkdGg9IjEuNCIvPgogIDx0ZXh0IHg9IjUxNiIgeT0iMzA3IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjExIiBmb250LXdlaWdodD0iNzAwIiBmaWxsPSIjOTI0MDBlIj5jb250aW51ZTwvdGV4dD4KICA8dGV4dCB4PSI1MTYiIHk9IjMyNCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSI4LjUiIGZpbGw9IiM5MjQwMGUiPmZhaWwtb3BlbiAmIzgyMTI7IGV4cGxpY2l0PC90ZXh0PgogIDx0ZXh0IHg9IjUxNiIgeT0iMzM1IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjguNSIgZmlsbD0iIzkyNDAwZSI+JmFtcDsgcmVjb3JkZWQ8L3RleHQ+CgogIDx0ZXh0IHg9IjMyMCIgeT0iMzcyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjkuNSIgZm9udC1zdHlsZT0iaXRhbGljIiBmaWxsPSIjNDc1NTY5Ij4mIzgyMjA7Y29udGludWUmIzgyMjE7IGlzIHRoZSBvbmx5IHBhdGggdGhhdCBkb2VzIG5vdCBzdG9wIG9yIHN1YnN0aXR1dGUgJiM4MjEyOyBpdCBtdXN0IGJlIGRlY2xhcmVkIG9uIHB1cnBvc2UgYW5kIGxvZ2dlZC48L3RleHQ+CiAgPHRleHQgeD0iMzIwIiB5PSI0MDIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iOS41IiBmaWxsPSIjNDc1NTY5Ij5FdmVyeSBkZWdyYWRhdGlvbiBldmVudCAmIzgyMTI7IGNhdXNlLCByZXNvbHZlZCBhY3Rpb24sIGFuZCB3aGV0aGVyIGZhaWwtY2xvc2VkIGFwcGxpZWQgJiM4MjEyOyBpcyByZWNvcmRlZCBpbiB0aGUgYXVkaXQgdHJhaWwuPC90ZXh0PgoKICA8IS0tIEhBTFQgKGZhaWwtY2xvc2VkKSB0ZXJtaW5hbCAtLT4KICA8cmVjdCB4PSI2NjAiIHk9IjI1MCIgd2lkdGg9IjIwMCIgaGVpZ2h0PSI4NCIgcng9IjEwIiBmaWxsPSIjZmRlOGU4IiBzdHJva2U9IiNjNTIyMWYiIHN0cm9rZS13aWR0aD0iMiIvPgogIDx0ZXh0IHg9Ijc2MCIgeT0iMjgwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjE0IiBmb250LXdlaWdodD0iNzAwIiBmaWxsPSIjYTUwZTBlIj5IQUxUPC90ZXh0PgogIDx0ZXh0IHg9Ijc2MCIgeT0iMzAwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjEwIiBmb250LXdlaWdodD0iNzAwIiBmaWxsPSIjYTUwZTBlIj5mYWlsLWNsb3NlZCBkZWZhdWx0PC90ZXh0PgogIDx0ZXh0IHg9Ijc2MCIgeT0iMzE2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjguNSIgZmlsbD0iIzFmMjkzNyI+YWJzZW5jZSBvZiBhIHJlc3BvbnNlIGlzPC90ZXh0PgogIDx0ZXh0IHg9Ijc2MCIgeT0iMzI3IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjguNSIgZmlsbD0iIzFmMjkzNyI+bm90IGNvbnNlbnQgdG8gY29udGludWU8L3RleHQ+CgogIDwhLS0gdGhlc2lzIGNhbGxvdXQgdW5kZXIgSEFMVCAtLT4KICA8cmVjdCB4PSI2NjAiIHk9IjM2MCIgd2lkdGg9IjIwMCIgaGVpZ2h0PSI2MCIgcng9IjEwIiBmaWxsPSIjZjhmYWZjIiBzdHJva2U9IiNjNTIyMWYiIHN0cm9rZS13aWR0aD0iMS4zIiBzdHJva2UtZGFzaGFycmF5PSI1IDQiLz4KICA8dGV4dCB4PSI3NjAiIHk9IjM4MiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSI5LjUiIGZvbnQtd2VpZ2h0PSI3MDAiIGZpbGw9IiNhNTBlMGUiPnRlZXRoIGF0IHJ1bnRpbWU8L3RleHQ+CiAgPHRleHQgeD0iNzYwIiB5PSIzOTgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iOC41IiBmaWxsPSIjMWYyOTM3Ij5hIGxpbWl0IHdpdGggbm8gZGVjbGFyZWQ8L3RleHQ+CiAgPHRleHQgeD0iNzYwIiB5PSI0MDkiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iOC41IiBmaWxsPSIjMWYyOTM3Ij5oYW5kbGluZyBzdG9wcyB0aGUgYWdlbnQ8L3RleHQ+CgogIDwhLS0gZm9vdG5vdGUgLS0+CiAgPHRleHQgeD0iNDUwIiB5PSI1MDAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTEiIGZvbnQtc3R5bGU9Iml0YWxpYyIgZmlsbD0iIzQ3NTU2OSI+VGhlIGdvdmVybm9yJ3MgcmVzb2x1dGlvbiBsb2dpYyBpcyBkZXRlcm1pbmlzdGljOiB0aGUgc2FtZSBjYXVzZSBhbmQgdGhlIHNhbWUgZGVjbGFyYXRpb24gYWx3YXlzIHJlc29sdmUgdGhlIHNhbWUgd2F5LjwvdGV4dD4KICA8dGV4dCB4PSI0NTAiIHk9IjUxOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxMSIgZm9udC1zdHlsZT0iaXRhbGljIiBmaWxsPSIjNDc1NTY5Ij5JbGx1c3RyYXRpdmU7ICYjMTY3OzYgKGFuZCBDb3JlICYjMTY3OzExLjUpIGFyZSBhdXRob3JpdGF0aXZlLjwvdGV4dD4KPC9zdmc+Cg==) *Figure (informative): A fired cause either resolves to a declared response (halt, pause, fallback, or the explicit fail-open continue) or, when no response is declared, halts the session — the fail-closed default. This figure is illustrative; the procedure below (and Core §11.5) is authoritative.* This is the shared response procedure that §2–§5 and §7 invoke. When a cause fires, the governor's PEP (§1.2) **MUST** resolve the response as follows: 1. **Look up the cause.** If `runtime.degradation` declares a response for the fired cause, apply it (step 3). 2. **Fail closed on absence.** If no response is declared for the cause, the governor **MUST** halt the session. Absence of a degradation response is **not** consent to continue — this default is the core of "teeth at runtime": a limit with no declared handling stops the agent rather than waving it through. 3. **Apply the action.** * `halt` — terminate the session; no further steps execute. * `pause` — suspend execution and escalate for human oversight (§5); resume only on explicit approval. * `fallback` — substitute the declared `value` / `message` for the blocked step and continue. * `continue` — proceed despite the cause. This is **fail-open** and **MUST** be explicit; the governor **MUST** record every `continue` in the audit trail (§1.4) together with the cause it overrode. 4. **Record.** Every degradation event — the cause, the resolved action, and whether the fail-closed default applied — is recorded in the audit trail (§1.4). The Core `runtime.error_handling.fallback_behavior` member (§11.4) is treated as the `on_tool_error` cause; when both are present, `runtime.degradation.on_tool_error` governs. **Conformance.** At **R1** the governor records which cause fired and what response *would* apply, but does not alter execution. At **R2** and above it **MUST** apply the resolved response, including the fail-closed default. ## 7 Anomaly Detection[​](#7-anomaly-detection "Direct link to 7 Anomaly Detection") This section defines how the governor monitors a session against the agent's declared [`anomaly_baseline`](/profiles/governance/specification.md) (Governance Profile) — expected tool-call distribution, per-session cost range, and the data classes the agent typically touches — and how it responds to deviation. The governor's PDP (§1.2) **MUST**, over the course of a session, compare observed behavior against the declared baseline: 1. **Track.** Accumulate the session's tool-call distribution, cost (reusing the §2 counters), and the data classes touched. 2. **Compare.** Flag deviation when the session invokes a tool outside `expected_tools`, its cost falls outside `cost_per_session_usd`, or it touches a data class outside `data_classes`. How far a session may drift before it is "material" is governor-defined and **MUST** be documented when claiming R3. 3. **Respond.** On material deviation, the governor resolves `runtime.degradation.on_anomaly` (§6), defaulting to fail-closed (halt). Because anomaly is a softer signal than a hard limit, a `pause` (escalate to §5 oversight) is often the appropriate declared response. 4. **Evidence.** The governor **MUST** record the deviation as an enforcement event in the signed record of **§8**, so a counterparty can distinguish a governor that *actually* monitors (R3) from one that merely claims it. An anomaly is the `on_anomaly` cause; the record's tamper-evidence and freshness properties (§8.1) apply, and completeness remains subject to the reserved witness tier (§8.8). Because the baseline is self-declared by the agent, anomaly detection against it is only as strong as the baseline is honest; its governance value depends on the §8 evidence being externally verifiable. **Conformance.** Anomaly detection is **R3**. At **R1**/**R2** a governor **MAY** record baseline deviation but is not required to act on it; at **R3** it **MUST** monitor against a declared baseline and apply §6 on material deviation. ## 8 Enforcement Evidence[​](#8-enforcement-evidence "Direct link to 8 Enforcement Evidence") §1.4 requires that, at R2 and above, a governor's enforcement be *externally evidenced* so a counterparty can distinguish a governor that actually enforced from one that merely claims a tier. This section specifies that evidence: a signed, per-session **enforcement record**. ![Data-structure diagram of an ADL enforcement record. At the top is the record header, binding the record to a governor identity, the subject agent by passport digest (the version pin), the session and tier, the time window, and an optional counterparty nonce for freshness. Below it is an ordered chain of enforcement events, each carrying a sequence number, the cause that fired, the section 6 action applied, a timestamp, and a prev\_hash field; an arrow from each event\'s prev\_hash points back to the previous block — event zero\'s prev\_hash is the SHA-256 of the header, each later event\'s is the SHA-256 of the prior event — so any alteration, reordering, or deletion breaks a link. At the bottom, the governor\'s signature seals the whole chain. A callout states what the evidence proves (tamper-evidence, and freshness with a nonce) and what it does not (completeness — the reserved witness tier).](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA5MDAgNjYwIiB3aWR0aD0iOTAwIiBoZWlnaHQ9IjY2MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsbGVkYnk9ImVlLXRpdGxlIGVlLWRlc2MiIGZvbnQtZmFtaWx5PSItYXBwbGUtc3lzdGVtLCBCbGlua01hY1N5c3RlbUZvbnQsICdTZWdvZSBVSScsIEhlbHZldGljYSwgQXJpYWwsIHNhbnMtc2VyaWYiPgogIDx0aXRsZSBpZD0iZWUtdGl0bGUiPkVuZm9yY2VtZW50IGV2aWRlbmNlOiBhIHNpZ25lZCwgaGFzaC1jaGFpbmVkIHJlY29yZCBvZiB3aGF0IHRoZSBnb3Zlcm5vciBlbmZvcmNlZDwvdGl0bGU+CiAgPGRlc2MgaWQ9ImVlLWRlc2MiPkEgZGF0YS1zdHJ1Y3R1cmUgZGlhZ3JhbSBvZiBhbiBBREwgZW5mb3JjZW1lbnQgcmVjb3JkLiBBdCB0aGUgdG9wIGlzIHRoZSByZWNvcmQgaGVhZGVyLCBiaW5kaW5nIHRoZSByZWNvcmQgdG8gYSBnb3Zlcm5vciBpZGVudGl0eSwgdGhlIHN1YmplY3QgYWdlbnQgYnkgcGFzc3BvcnQgZGlnZXN0ICh0aGUgdmVyc2lvbiBwaW4pLCB0aGUgc2Vzc2lvbiBhbmQgdGllciwgdGhlIHRpbWUgd2luZG93LCBhbmQgYW4gb3B0aW9uYWwgY291bnRlcnBhcnR5IG5vbmNlIGZvciBmcmVzaG5lc3MuIEJlbG93IHRoZSBoZWFkZXIgaXMgYW4gb3JkZXJlZCBjaGFpbiBvZiBlbmZvcmNlbWVudCBldmVudHMsIGVhY2ggY2FycnlpbmcgYSBzZXF1ZW5jZSBudW1iZXIsIHRoZSBjYXVzZSB0aGF0IGZpcmVkLCB0aGUgc2VjdGlvbiA2IGFjdGlvbiBhcHBsaWVkLCBhIHRpbWVzdGFtcCwgYW5kIGEgcHJldl9oYXNoIGZpZWxkLiBBbiBhcnJvdyBmcm9tIGVhY2ggZXZlbnQncyBwcmV2X2hhc2ggcG9pbnRzIGJhY2sgdG8gdGhlIHByZXZpb3VzIGV2ZW50OiBldmVudCB6ZXJvJ3MgcHJldl9oYXNoIGlzIHRoZSBTSEEtMjU2IG9mIHRoZSByZWNvcmQgaGVhZGVyLCBhbmQgZWFjaCBsYXRlciBldmVudCdzIHByZXZfaGFzaCBpcyB0aGUgU0hBLTI1NiBvZiB0aGUgcHJldmlvdXMgZXZlbnQsIHNvIGFueSBhbHRlcmF0aW9uLCByZW9yZGVyaW5nLCBvciBkZWxldGlvbiBicmVha3MgYSBsaW5rLiBBdCB0aGUgYm90dG9tLCB0aGUgZ292ZXJub3IncyBzaWduYXR1cmUgc2VhbHMgdGhlIHdob2xlIGNoYWluLiBBIGNhbGxvdXQgc3RhdGVzIHdoYXQgdGhlIGV2aWRlbmNlIHByb3ZlcyDigJQgdGFtcGVyLWV2aWRlbmNlIGFuZCwgd2l0aCBhIG5vbmNlLCBmcmVzaG5lc3Mg4oCUIGFuZCB3aGF0IGl0IGRvZXMgbm90IHByb3ZlOiBjb21wbGV0ZW5lc3MsIHdoaWNoIGlzIHRoZSByZXNlcnZlZCB3aXRuZXNzIHRpZXIuPC9kZXNjPgoKICA8ZGVmcz4KICAgIDxtYXJrZXIgaWQ9ImVlLWFycm93IiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj4KICAgICAgPHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBmaWxsPSIjODQzMGNlIi8+CiAgICA8L21hcmtlcj4KICAgIDxtYXJrZXIgaWQ9ImVlLXNlYWwiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPgogICAgICA8cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIGZpbGw9IiMzMzQxNTUiLz4KICAgIDwvbWFya2VyPgogIDwvZGVmcz4KCiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjkwMCIgaGVpZ2h0PSI2NjAiIGZpbGw9IiNmZmZmZmYiLz4KCiAgPCEtLSBUaXRsZSAtLT4KICA8dGV4dCB4PSI0NTAiIHk9IjM0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjIwIiBmb250LXdlaWdodD0iNzAwIiBmaWxsPSIjMGYxNzJhIj5FbmZvcmNlbWVudCBFdmlkZW5jZTwvdGV4dD4KICA8dGV4dCB4PSI0NTAiIHk9IjU2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjEzIiBmb250LXN0eWxlPSJpdGFsaWMiIGZpbGw9IiM0NzU1NjkiPkEgc2lnbmVkLCBoYXNoLWNoYWluZWQgcmVjb3JkIG9mIHdoYXQgdGhlIGdvdmVybm9yIGVuZm9yY2VkICYjODIxMjsgdGFtcGVyLWV2aWRlbnQsIG5vdCBjb21wbGV0ZTwvdGV4dD4KCiAgPCEtLSA9PT09PT09PT09PT09PT09PT09PT0gSEVBREVSID09PT09PT09PT09PT09PT09PT09PSAtLT4KICA8cmVjdCB4PSI3MCIgeT0iODQiIHdpZHRoPSI0NzAiIGhlaWdodD0iMTM2IiByeD0iMTAiIGZpbGw9IiNlZWYyZmYiIHN0cm9rZT0iIzRmNDZlNSIgc3Ryb2tlLXdpZHRoPSIxLjUiLz4KICA8dGV4dCB4PSI4NiIgeT0iMTA2IiBmb250LXNpemU9IjEyLjUiIGZvbnQtd2VpZ2h0PSI3MDAiIGZpbGw9IiMzNzMwYTMiPlJlY29yZCBoZWFkZXI8L3RleHQ+CiAgPGcgZm9udC1zaXplPSIxMC41IiBmaWxsPSIjMWYyOTM3Ij4KICAgIDx0ZXh0IHg9Ijg2IiB5PSIxMjgiPjx0c3BhbiBmb250LXdlaWdodD0iNzAwIj5nb3Zlcm5vcjwvdHNwYW4+ICYjODIxMjsgaWRlbnRpdHkgKEhUVFBTIC8gZGlkOndlYiksIHJlc29sdmVkIHRvIGEga2V5PC90ZXh0PgogICAgPHRleHQgeD0iODYiIHk9IjE0NiI+PHRzcGFuIGZvbnQtd2VpZ2h0PSI3MDAiPnN1YmplY3QucGFzc3BvcnRfZGlnZXN0PC90c3Bhbj4gJiM4MjEyOyBiaW5kcyB0byB0aGUgYWRtaXR0ZWQgcGFzc3BvcnQgKHZlcnNpb24gcGluKTwvdGV4dD4KICAgIDx0ZXh0IHg9Ijg2IiB5PSIxNjQiPjx0c3BhbiBmb250LXdlaWdodD0iNzAwIj5zZXNzaW9uICYjMTgzOyB0aWVyPC90c3Bhbj4gKFIxIC8gUjIgLyBSMykgJiMxODM7IDx0c3BhbiBmb250LXdlaWdodD0iNzAwIj53aW5kb3c8L3RzcGFuPiAoc3RhcnQgJiM4MjExOyBlbmQpPC90ZXh0PgogICAgPHRleHQgeD0iODYiIHk9IjE4MiI+PHRzcGFuIGZvbnQtd2VpZ2h0PSI3MDAiPm5vbmNlPC90c3Bhbj4gJiM4MjEyOyBvcHRpb25hbCBjb3VudGVycGFydHkgY2hhbGxlbmdlIChmcmVzaG5lc3MsICYjMTY3OzguNSk8L3RleHQ+CiAgICA8dGV4dCB4PSI4NiIgeT0iMTk4IiBmaWxsPSIjNjQ3NDhiIiBmb250LXN0eWxlPSJpdGFsaWMiPiYjODIzMDsgcGx1cyBhZGxfZW5mb3JjZW1lbnRfcmVjb3JkLCBpYXQsIG91dGNvbWUgKGZ1bGwgY2Fub25pY2FsIGhlYWRlciBpcyBoYXNoZWQpPC90ZXh0PgogIDwvZz4KCiAgPCEtLSBoZWFkZXIgLT4gZXZlbnQwIGNoYWluIGFuY2hvciAtLT4KICA8bGluZSB4MT0iMzA1IiB5MT0iMjIwIiB4Mj0iMzA1IiB5Mj0iMjMyIiBzdHJva2U9IiMzMzQxNTUiIHN0cm9rZS13aWR0aD0iMS40IiBtYXJrZXItZW5kPSJ1cmwoI2VlLXNlYWwpIi8+CiAgPHRleHQgeD0iMzEzIiB5PSIyMzAiIHRleHQtYW5jaG9yPSJzdGFydCIgZm9udC1zaXplPSI5IiBmb250LXN0eWxlPSJpdGFsaWMiIGZpbGw9IiM2NDc0OGIiPlNIQS0yNTYoaGVhZGVyKSA9IGV2ZW50c1swXS5wcmV2X2hhc2g8L3RleHQ+CgogIDwhLS0gPT09PT09PT09PT09PT09PT09PT09IEVWRU5UIENIQUlOID09PT09PT09PT09PT09PT09PT09PSAtLT4KICA8IS0tIGV2ZW50IDAgLS0+CiAgPHJlY3QgeD0iMTIwIiB5PSIyMzQiIHdpZHRoPSIzNzAiIGhlaWdodD0iNTYiIHJ4PSI4IiBmaWxsPSIjZjNlOGZkIiBzdHJva2U9IiM4NDMwY2UiIHN0cm9rZS13aWR0aD0iMS41Ii8+CiAgPHRleHQgeD0iMTM0IiB5PSIyNTQiIGZvbnQtc2l6ZT0iMTEiIGZvbnQtd2VpZ2h0PSI3MDAiIGZpbGw9IiM2YjIxYTgiPmV2ZW50c1swXTwvdGV4dD4KICA8dGV4dCB4PSIxMzQiIHk9IjI3MiIgZm9udC1zaXplPSIxMCIgZmlsbD0iIzFmMjkzNyI+c2VxIDAgJiMxODM7IGNhdXNlIG9uX2J1ZGdldF9leGhhdXN0ZWQgJiMxODM7IGFjdGlvbiBoYWx0PC90ZXh0PgogIDx0ZXh0IHg9IjEzNCIgeT0iMjg1IiBmb250LXNpemU9IjkuNSIgZmlsbD0iIzQ3NTU2OSI+YXQgJiMxODM7IDx0c3BhbiBmb250LXdlaWdodD0iNzAwIiBmaWxsPSIjNmIyMWE4Ij5wcmV2X2hhc2g8L3RzcGFuPiAmIzg1OTQ7IGhlYWRlcjwvdGV4dD4KCiAgPCEtLSBldmVudCAxIC0tPgogIDxyZWN0IHg9IjEyMCIgeT0iMzIwIiB3aWR0aD0iMzcwIiBoZWlnaHQ9IjU2IiByeD0iOCIgZmlsbD0iI2YzZThmZCIgc3Ryb2tlPSIjODQzMGNlIiBzdHJva2Utd2lkdGg9IjEuNSIvPgogIDx0ZXh0IHg9IjEzNCIgeT0iMzQwIiBmb250LXNpemU9IjExIiBmb250LXdlaWdodD0iNzAwIiBmaWxsPSIjNmIyMWE4Ij5ldmVudHNbMV08L3RleHQ+CiAgPHRleHQgeD0iMTM0IiB5PSIzNTgiIGZvbnQtc2l6ZT0iMTAiIGZpbGw9IiMxZjI5MzciPnNlcSAxICYjMTgzOyBjYXVzZSBvbl9hbm9tYWx5ICYjMTgzOyBhY3Rpb24gcGF1c2U8L3RleHQ+CiAgPHRleHQgeD0iMTM0IiB5PSIzNzEiIGZvbnQtc2l6ZT0iOS41IiBmaWxsPSIjNDc1NTY5Ij5hdCAmIzE4MzsgPHRzcGFuIGZvbnQtd2VpZ2h0PSI3MDAiIGZpbGw9IiM2YjIxYTgiPnByZXZfaGFzaDwvdHNwYW4+ICYjODU5NDsgU0hBLTI1NihldmVudHNbMF0pPC90ZXh0PgoKICA8IS0tIGV2ZW50IDIgLS0+CiAgPHJlY3QgeD0iMTIwIiB5PSI0MDYiIHdpZHRoPSIzNzAiIGhlaWdodD0iNTYiIHJ4PSI4IiBmaWxsPSIjZjNlOGZkIiBzdHJva2U9IiM4NDMwY2UiIHN0cm9rZS13aWR0aD0iMS41Ii8+CiAgPHRleHQgeD0iMTM0IiB5PSI0MjYiIGZvbnQtc2l6ZT0iMTEiIGZvbnQtd2VpZ2h0PSI3MDAiIGZpbGw9IiM2YjIxYTgiPmV2ZW50c1syXTwvdGV4dD4KICA8dGV4dCB4PSIxMzQiIHk9IjQ0NCIgZm9udC1zaXplPSIxMCIgZmlsbD0iIzFmMjkzNyI+c2VxIDIgJiMxODM7IGNhdXNlIG9uX292ZXJzaWdodF90aW1lb3V0ICYjMTgzOyBhY3Rpb24gaGFsdDwvdGV4dD4KICA8dGV4dCB4PSIxMzQiIHk9IjQ1NyIgZm9udC1zaXplPSI5LjUiIGZpbGw9IiM0NzU1NjkiPmF0ICYjMTgzOyA8dHNwYW4gZm9udC13ZWlnaHQ9IjcwMCIgZmlsbD0iIzZiMjFhOCI+cHJldl9oYXNoPC90c3Bhbj4gJiM4NTk0OyBTSEEtMjU2KGV2ZW50c1sxXSk8L3RleHQ+CgogIDwhLS0gYmFjay1wb2ludGluZyBjaGFpbiBhcnJvd3MgKGVhY2ggcHJldl9oYXNoIHBvaW50cyB0byB0aGUgcHJpb3IgYmxvY2spIC0tPgogIDwhLS0gZXZlbnQxIC0+IGV2ZW50MCAtLT4KICA8cGF0aCBkPSJNNTA0LDM0OCBDIDUyNCwzNDggNTI0LDI2MiA1MDQsMjYyIiBmaWxsPSJub25lIiBzdHJva2U9IiM4NDMwY2UiIHN0cm9rZS13aWR0aD0iMS41IiBtYXJrZXItZW5kPSJ1cmwoI2VlLWFycm93KSIvPgogIDwhLS0gZXZlbnQyIC0+IGV2ZW50MSAtLT4KICA8cGF0aCBkPSJNNTA0LDQzNCBDIDUyNCw0MzQgNTI0LDM0OCA1MDQsMzQ4IiBmaWxsPSJub25lIiBzdHJva2U9IiM4NDMwY2UiIHN0cm9rZS13aWR0aD0iMS41IiBtYXJrZXItZW5kPSJ1cmwoI2VlLWFycm93KSIvPgogIDx0ZXh0IHRyYW5zZm9ybT0icm90YXRlKC05MCA1NDMgMzU1KSIgeD0iNTQzIiB5PSIzNTUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iOSIgZm9udC1zdHlsZT0iaXRhbGljIiBmaWxsPSIjODQzMGNlIj5lYWNoIGxpbmsgdmVyaWZpZXMgdGhlIHByaW9yIGJsb2NrPC90ZXh0PgoKICA8IS0tIGNoYWluIC0+IHNpZ25hdHVyZSAtLT4KICA8bGluZSB4MT0iMzA1IiB5MT0iNDYyIiB4Mj0iMzA1IiB5Mj0iNDkwIiBzdHJva2U9IiMzMzQxNTUiIHN0cm9rZS13aWR0aD0iMS40IiBtYXJrZXItZW5kPSJ1cmwoI2VlLXNlYWwpIi8+CgogIDwhLS0gPT09PT09PT09PT09PT09PT09PT09IFNJR05BVFVSRSA9PT09PT09PT09PT09PT09PT09PT0gLS0+CiAgPHJlY3QgeD0iMTIwIiB5PSI0OTIiIHdpZHRoPSIzNzAiIGhlaWdodD0iNTYiIHJ4PSI4IiBmaWxsPSIjZTZmNGVhIiBzdHJva2U9IiMxMzczMzMiIHN0cm9rZS13aWR0aD0iMS43NSIvPgogIDx0ZXh0IHg9IjMwNSIgeT0iNTE1IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjEyIiBmb250LXdlaWdodD0iNzAwIiBmaWxsPSIjMGQ2NTJkIj5nb3Zlcm5vciBzaWduYXR1cmU8L3RleHQ+CiAgPHRleHQgeD0iMzA1IiB5PSI1MzMiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iOS41IiBmaWxsPSIjMWYyOTM3Ij5zZWFscyB0aGUgZnVsbCByZWNvcmQgKGhlYWRlciArIGNoYWluKSAmIzE4MzsgRWQyNTUxOSBSRUNPTU1FTkRFRDwvdGV4dD4KCiAgPCEtLSA9PT09PT09PT09PT09PT09PT09PT0gQ0FMTE9VVDogcHJvdmVzIC8gZG9lcyBub3QgcHJvdmUgPT09PT09PT09PT09PT09PT09PT09IC0tPgogIDxyZWN0IHg9IjU2NiIgeT0iMjM0IiB3aWR0aD0iMjg0IiBoZWlnaHQ9IjMxNCIgcng9IjEwIiBmaWxsPSIjZjhmYWZjIiBzdHJva2U9IiNjYmQ1ZTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtZGFzaGFycmF5PSI1IDQiLz4KICA8dGV4dCB4PSI3MDgiIHk9IjI2MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxMyIgZm9udC13ZWlnaHQ9IjcwMCIgZmlsbD0iIzMzNDE1NSI+V2hhdCBpdCBwcm92ZXMgJiM4MjEyOyBhbmQgZG9lcyBub3Q8L3RleHQ+CgogIDx0ZXh0IHg9IjU4NCIgeT0iMjg4IiBmb250LXNpemU9IjExIiBmb250LXdlaWdodD0iNzAwIiBmaWxsPSIjMGQ2NTJkIj4mIzEwMDAzOyBUYW1wZXItZXZpZGVuY2U8L3RleHQ+CiAgPHRleHQgeD0iNTg0IiB5PSIzMDUiIGZvbnQtc2l6ZT0iMTAiIGZpbGw9IiMxZjI5MzciPmFsdGVyZWQsIHJlb3JkZXJlZCwgb3IgZGVsZXRlZDwvdGV4dD4KICA8dGV4dCB4PSI1ODQiIHk9IjMxOSIgZm9udC1zaXplPSIxMCIgZmlsbD0iIzFmMjkzNyI+ZXZlbnRzIGJyZWFrIGEgcHJldl9oYXNoIGxpbmsuPC90ZXh0PgoKICA8dGV4dCB4PSI1ODQiIHk9IjM0NiIgZm9udC1zaXplPSIxMSIgZm9udC13ZWlnaHQ9IjcwMCIgZmlsbD0iIzBkNjUyZCI+JiMxMDAwMzsgRnJlc2huZXNzICh3aXRoIG5vbmNlKTwvdGV4dD4KICA8dGV4dCB4PSI1ODQiIHk9IjM2MyIgZm9udC1zaXplPSIxMCIgZmlsbD0iIzFmMjkzNyI+YSByZWNvcmQgY2FycnlpbmcgdGhlIGNoYWxsZW5nZTwvdGV4dD4KICA8dGV4dCB4PSI1ODQiIHk9IjM3NyIgZm9udC1zaXplPSIxMCIgZmlsbD0iIzFmMjkzNyI+cG9zdC1kYXRlcyBpdCAmIzgyMTI7IG5vdCBwcmUtZmFicmljYXRlZC48L3RleHQ+CgogIDxsaW5lIHgxPSI1ODQiIHkxPSIzOTgiIHgyPSI4MzIiIHkyPSIzOTgiIHN0cm9rZT0iI2NiZDVlMSIgc3Ryb2tlLXdpZHRoPSIxIi8+CgogIDx0ZXh0IHg9IjU4NCIgeT0iNDIyIiBmb250LXNpemU9IjExIiBmb250LXdlaWdodD0iNzAwIiBmaWxsPSIjYTUwZTBlIj4mIzEwMDA3OyBOT1QgY29tcGxldGVuZXNzPC90ZXh0PgogIDx0ZXh0IHg9IjU4NCIgeT0iNDM5IiBmb250LXNpemU9IjEwIiBmaWxsPSIjMWYyOTM3Ij5hIHZhbGlkIHJlY29yZCBwcm92ZXMgd2hhdCB0aGU8L3RleHQ+CiAgPHRleHQgeD0iNTg0IiB5PSI0NTMiIGZvbnQtc2l6ZT0iMTAiIGZpbGw9IiMxZjI5MzciPmdvdmVybm9yIDx0c3BhbiBmb250LXN0eWxlPSJpdGFsaWMiPnJlY29yZGVkPC90c3Bhbj4sIG5vdCB0aGF0IG5vPC90ZXh0PgogIDx0ZXh0IHg9IjU4NCIgeT0iNDY3IiBmb250LXNpemU9IjEwIiBmaWxsPSIjMWYyOTM3Ij51bnJlY29yZGVkIHZpb2xhdGlvbiBvY2N1cnJlZC48L3RleHQ+CiAgPHRleHQgeD0iNTg0IiB5PSI0ODciIGZvbnQtc2l6ZT0iOS41IiBmb250LXN0eWxlPSJpdGFsaWMiIGZpbGw9IiM2NDc0OGIiPkRldGVjdGluZyBvbWlzc2lvbiBpcyB0aGUgcmVzZXJ2ZWQ8L3RleHQ+CiAgPHRleHQgeD0iNTg0IiB5PSI1MDAiIGZvbnQtc2l6ZT0iOS41IiBmb250LXN0eWxlPSJpdGFsaWMiIGZpbGw9IiM2NDc0OGIiPndpdG5lc3MgdGllciAoJiMxNjc7OC44KS48L3RleHQ+CgogIDwhLS0gPT09PT09PT09PT09PT09PT09PT09IGZvb3Rub3RlID09PT09PT09PT09PT09PT09PT09PSAtLT4KICA8dGV4dCB4PSI0NTAiIHk9IjYwMCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxMSIgZm9udC1zdHlsZT0iaXRhbGljIiBmaWxsPSIjNDc1NTY5Ij5BIGNvdW50ZXJwYXJ0eSByZXNvbHZlcyB0aGUgZ292ZXJub3Iga2V5LCB2ZXJpZmllcyB0aGUgc2lnbmF0dXJlLCByZS1jaGVja3MgdGhlIGhhc2gtY2hhaW4sIGFuZCBjb25maXJtcyB0aGUgcGFzc3BvcnQgZGlnZXN0LjwvdGV4dD4KICA8dGV4dCB4PSI0NTAiIHk9IjYxNyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxMSIgZm9udC1zdHlsZT0iaXRhbGljIiBmaWxsPSIjNDc1NTY5Ij5UaGUgc3RydWN0dXJlIGFuZCB2ZXJpZmljYXRpb24gYXJlIGRldGVybWluaXN0aWM7IHRoZSByZWNvcmQncyBjb250ZW50IGlzIGEgcGVyLXJ1biBhY2NvdW50IG9mIGNvbmR1Y3QuPC90ZXh0Pgo8L3N2Zz4K) *Figure 1 (informative): An enforcement record binds a governor's signature over a hash-chained event sequence to the admitted passport (by digest) and, optionally, a counterparty nonce. The structure and its verification (§8.6) are deterministic; what the record proves — tamper-evidence and freshness, but not completeness (§8.1) — is fixed by that structure. This figure is illustrative; the normative structure is the table in §8.3.* ### 8.1 Trust model — what the evidence proves, and what it does not[​](#81-trust-model--what-the-evidence-proves-and-what-it-does-not "Direct link to 8.1 Trust model — what the evidence proves, and what it does not") Because a governor **MAY** be operated by the same party as the agent (§1.1), evidence must be read with a clear understanding of its guarantees: * **Tamper-evidence (provided).** The record is signed by the governor and its events are hash-chained, so a counterparty can detect any *alteration, reordering, or deletion* of recorded events. * **Freshness and interaction-binding (provided).** A counterparty **MAY** seed the record with a nonce (§8.5); a record carrying that nonce could only have been produced after the challenge, so a governor cannot satisfy the counterparty with a stale or pre-fabricated record. * **Completeness (NOT provided at this tier).** Signing and chaining cannot prove that an event the governor *never recorded* did not occur. A self-interested operator can still under-report. Detecting omission requires third-party witnessing; that is the reserved higher-assurance tier in §8.8. The evidence in this section is honest about stopping short of it. ### 8.2 The governor's identity[​](#82-the-governors-identity "Direct link to 8.2 The governor's identity") The governor is a first-class identified actor. The record's `governor` field is an identifier — an HTTPS URI or `did:web` — that resolves to a verification key exactly as a passport `id` does (Trust Protocol §1.1.3). The governor's identity **MAY** itself be an ADL passport. A counterparty resolves and pins the governor key the same way it resolves an agent's, reusing the §10.2 attestation and §1.1.5 signature machinery. ### 8.3 Enforcement record structure[​](#83-enforcement-record-structure "Direct link to 8.3 Enforcement record structure") An enforcement record **MUST** be a JSON object with the following members: | Member | Type | Required | Description | | ------------------------ | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | | `adl_enforcement_record` | string | REQUIRED | Format version. **MUST** be `"1.0"`. | | `governor` | string | REQUIRED | The governor's identifier (HTTPS URI or `did:web`), resolved to its key per §8.2. | | `subject` | object | REQUIRED | The admitted agent: `id` (the passport `id`) and `passport_digest` (the digest of the JCS-canonical admitted passport bytes, per the §1.3 version pin). | | `session` | string | REQUIRED | Identifier of the governed session (§1.3). | | `tier` | string | REQUIRED | The tier the governor enforced for this session: `"R1"`, `"R2"`, or `"R3"`. | | `window` | object | REQUIRED | `start` / `end` ISO 8601 timestamps spanning the session. | | `iat` | string | REQUIRED | ISO 8601 time the record was issued. | | `nonce` | string | OPTIONAL | A counterparty-issued nonce (§8.5), when freshness binding is required. | | `limits` | object | OPTIONAL | Summary of the declared limits in force (the §2–§7 members the governor enforced). | | `events` | array | REQUIRED | Ordered, hash-chained enforcement events (§8.4). MAY be empty when no limit fired. | | `outcome` | string | REQUIRED | Session outcome: `"completed"`, `"halted"`, or `"paused"`. | | `signature` | object | REQUIRED | Signature over the JCS-canonical record minus `signature`, by the governor's key. Same shape as §10.2 attestation signatures (Ed25519 RECOMMENDED). | Each `events[]` entry **MUST** contain `seq` (0-based index), `cause` (`on_budget_exhausted`, `on_iteration_limit`, `on_sub_agent_denied`, `on_delegation_denied`, `on_oversight_timeout`, `on_tool_error`, `on_anomaly`), `action` (the §6 action applied), `at` (ISO 8601), and `prev_hash` (§8.4); it **MAY** contain `detail`. When the event was produced by a subordinate persona ([Core §9.7.1](/spec/next#971-sub-agents-personas)), the governor **SHOULD** record the persona's `name` in `detail` (e.g. `"persona": "doc-reviewer"`), so the account can attribute conduct to the persona that produced it — without implying the persona was a separately-admitted party. The record's `subject` remains the parent agent, since the persona acts under the parent's identity. ### 8.4 Event hash-chaining[​](#84-event-hash-chaining "Direct link to 8.4 Event hash-chaining") Events are chained so their order and integrity are self-checking and to provide the anchor points the §8.8 witness tier attests: * `events[0].prev_hash` **MUST** be the SHA-256, base64url-encoded, of the JCS-canonical record *header* (the record minus `events` and `signature`). * `events[i].prev_hash` (i > 0) **MUST** be the SHA-256, base64url-encoded, of the JCS-canonical bytes of `events[i-1]`. A verifier recomputes the chain; any altered, reordered, or removed event breaks a `prev_hash` link. The governor's `signature` over the full record (including `events`) seals the chain at session end. ### 8.5 Counterparty-seeded binding[​](#85-counterparty-seeded-binding "Direct link to 8.5 Counterparty-seeded binding") A counterparty **MAY** require a fresh record bound to its own challenge, using the nonce mechanism of Trust Protocol §1.2.7: the counterparty issues a nonce (e.g. `WWW-Authenticate: ADL nonce="…"`), and the governor **MUST** include it as the record's `nonce` so it is covered by the signature. A record carrying the counterparty's nonce demonstrably post-dates the challenge, defeating stale or pre-fabricated evidence for that interaction. Deployments handling `restricted` data (§10.1) **SHOULD** require it. ### 8.6 Verification procedure[​](#86-verification-procedure "Direct link to 8.6 Verification procedure") A counterparty verifying an enforcement record **MUST**: 1. **Schema-validate** the record against `schema-enforcement-record.json`. 2. **Resolve the governor key** from `governor` per §8.2 (Trust Protocol §1.1.3 identity resolution). 3. **Verify the signature** over the JCS-canonical record minus `signature` (Trust Protocol §1.1.5). 4. **Bind to the passport.** Confirm `subject.passport_digest` matches the digest of the passport admitted for the session (§1.3 version pin); a mismatch means the evidence is for a different passport version and **MUST** be rejected. 5. **Verify the nonce** (when the counterparty issued one): it **MUST** equal the issued value and be within its TTL (§1.2.7 semantics). 6. **Verify the hash-chain** per §8.4; a broken link **MUST** cause rejection. 7. **Interpret honestly.** A valid record is tamper-evidence of *what the governor recorded* at the stated tier — not proof of completeness (§8.1). A counterparty **MUST NOT** treat a valid record as proof that no unrecorded violation occurred. ### 8.7 Conveyance[​](#87-conveyance "Direct link to 8.7 Conveyance") A governor **MAY** convey the record inline to a counterparty on request (the agent-to-agent analog of returning a presentation proof) and **MAY** publish it to the agent's governance record (the `governance_record_ref` of the Governance Profile), where operational evidence is expected to live. The record is self-contained: its signature and `subject.passport_digest` make it verifiable wherever it is obtained. ### 8.8 Completeness and the witness tier (reserved)[​](#88-completeness-and-the-witness-tier-reserved "Direct link to 8.8 Completeness and the witness tier (reserved)") Detecting *omission* — not just alteration — requires a third party that sees records independently of the operator. A future higher-assurance tier anchors each record (or its event-chain checkpoints, §8.4) in an append-only, third-party-witnessed transparency log, so a gap in an agent's record sequence is itself detectable. The log protocol, witness model, and the conformance tier that requires it are **reserved**; the record format in §8.3 is designed to anchor into such a log without change. ## Conformance Tiers[​](#conformance-tiers "Direct link to Conformance Tiers") A runtime governor advertises the tier of enforcement it implements. Tiers are cumulative. | Tier | Name | A governor at this tier… | | ------ | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **R1** | Observing | Observes and records the agent's resource use, tool calls, and limit boundaries; does not block. Provides the audit trail. | | **R2** | Enforcing | Blocks on declared hard limits (budgets §2, iteration caps §3, sub-agent admission §4) and applies `runtime.degradation` (§6), fail-closed on absence; **SHOULD** produce signed enforcement evidence (§8). | | **R3** | Adaptive | R2 plus continuous anomaly-baseline monitoring (§7) and structured oversight-trigger escalation (§5); enforcement evidence (§8) is expected. | **Status:** Tier definitions are provisional; their normative conformance requirements continue to firm up. ## IANA Considerations[​](#iana-considerations "Direct link to IANA Considerations") This document requests no IANA registrations. The enforcement record (§8) is a JSON document whose format version is carried in-band in its `adl_enforcement_record` member (`"1.0"`) and whose structure is validated by `schema-enforcement-record.json` (§8.3); it is conveyed inline on request or published to the agent's governance record (§8.7) without a dedicated HTTP field or media type. Should a media type for the enforcement record be desired in a future revision (for example `application/adl-enforcement-record+json`), it would be registered through the IANA media-types registry at that time; no such registration is requested here. ## Security Considerations[​](#security-considerations "Direct link to Security Considerations") The runtime governor's security model is developed normatively in §1.4 (Trust in the Governor) and §8.1 (what the evidence proves); this section consolidates it for review. **Self-governance is the central limitation.** The governor **MAY** be operated by the same party as the agent (§1.1), so its enforcement cannot be taken on faith. The protocol addresses this with tiered, externally-verifiable evidence (§8) rather than by mandating separation: an enforcement record lets a counterparty distinguish a governor that *actually* enforced at a tier from one that merely claims it. **The evidence proves tamper-evidence and freshness, not completeness.** A signed, hash-chained record (§8.4) detects alteration, reordering, or deletion of recorded events, and a counterparty-issued nonce (§8.5) defeats stale or pre-fabricated records — but a valid record does **not** prove that no *unrecorded* violation occurred. Detecting omission by a self-interested operator requires an independent witness and is the reserved tier of §8.8 (the \[RFC6962] transparency-log model); counterparties **MUST NOT** read a valid record as proof of completeness (§8.1). **Fail-closed is a security property.** Absence of a declared degradation response halts the session (§6): a limit with no declared handling stops the agent rather than waving it through. Implementations **MUST** preserve this default and **MUST** record any explicit `continue` (fail-open) override together with the cause it overrode (§6). **The admitted passport is pinned.** The governor enforces against the exact canonical passport bytes admitted at session start (§1.3); any mid-session change to the governed members is a session-integrity fault that fails closed, preventing silent limit-swapping during a session. **Governor key trust.** The governor is a first-class identified actor whose key is resolved and verified with the same machinery as a passport (§8.2, Trust Protocol §1.1.3/§1.1.5); the did:web and TLS trust-anchor considerations in the Trust Protocol's Security Considerations apply equally to the governor's identity. ## References[​](#references "Direct link to References") ### Normative References[​](#normative-references "Direct link to Normative References") * **\[RFC2119]** Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, . * **\[RFC8174]** Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, . * **\[RFC8785]** Rundgren, A., Jordan, B., and S. Erdtman, "JSON Canonicalization Scheme (JCS)", RFC 8785, . Used to canonicalize an enforcement record before signing and verifying (§8.3–§8.6). * **\[ADL-CORE]** Nederveld, T., "Agent Definition Language (ADL)", the Core document of this specification family; see [/spec](/spec/.md). * **\[ADL-TRUST]** Nederveld, T., "ADL Trust Protocol", the companion authentication and authorization document; the governor resolves and verifies its own key with the Trust Protocol's §1.1.3/§1.1.5 machinery; see [/protocol/trust](/protocol/trust.md). ### Informative References[​](#informative-references "Direct link to Informative References") * **\[XACML]** OASIS, "eXtensible Access Control Markup Language (XACML) Version 3.0", OASIS Standard, January 2013. The policy decision point / policy enforcement point (PDP/PEP) model adopted in §1.2. * **\[NIST.SP.800-162]** Hu, V., et al., "Guide to Attribute Based Access Control (ABAC) Definition and Considerations", NIST Special Publication 800-162, . * **\[RFC6962]** Laurie, B., Langley, A., and E. Kasper, "Certificate Transparency", RFC 6962, . The witness model the reserved completeness tier (§8.8) draws on. --- # Trust Protocol | | | | ----------- | ------ | | **Version** | 0.3.0 | | **Status** | Posted | The **Trust Protocol** defines the normative procedures a counterparty performs to establish trust in an ADL agent: verifying a passport, binding a request to a presentation proof, and authorizing agent-to-agent calls. It is the *protocol* layer that sits on top of the *description* layer defined by the [ADL Core specification](/spec/.md). ADL Core declares what an agent is and which credential schemes and scopes it advertises; ADL Trust defines what a verifier **MUST** do with those declarations. The Trust Protocol is numbered independently as a standalone document: Authentication is §1 and Authorization is §2. Section references outside this range — for example §6.4, §9, §10.1, or §10.2 — refer to the [ADL Core specification](/spec/.md). Conformance test vectors and verification-outcome step identifiers track these Trust Protocol section numbers (e.g., §1.1.5, §1.2.6.6). The declarative members these procedures operate on — `security.attestation` (Core §10.2), the credential schemes (Core §10.3.3), and the scope declarations (Core §10.4.1–§10.4.2) — are defined in [ADL Core](/spec/.md). This document references them but does not redefine them. The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 \[RFC2119] \[RFC8174] when, and only when, they appear in all capitals, as shown here. ## The Passport[​](#the-passport "Direct link to The Passport") A **passport** is a compact **identity document** for an agent — smaller than the agent's full [ADL Core](/spec/.md) document — that the agent presents to establish trust with other agents. Where the full ADL document describes everything about an agent (identity, capabilities, tools, resources, model configuration, permissions, and runtime behavior), the passport carries only what a counterparty needs to answer two questions: *who is this agent?* and *can I trust this document?* The members it carries are defined by [ADL Core](/spec/.md), which is authoritative for their syntax and constraints. ![Left-to-right class diagram of passport distillation. On the left, the full ADL Document lists all its member groups; the identity-and-trust members (adl\_spec, id and provider, cryptographic\_identity, security attestation and scopes, lifecycle status, permissions, and data\_classification) are highlighted as the distilled subset, while the operational members (capabilities, tools, resources, model, runtime behaviour and degradation, human\_oversight, anomaly\_baseline) are greyed as staying behind. A derive arrow crosses to the middle column, the Agent Passport — a compact signed box carrying only that subset, the members a counterparty needs to answer who is this agent and can I trust this document. A present arrow then carries the passport to a counterparty on the right, attached to a request or dereferenced by URL. The passport is a typed projection of the document: identity and trust travel; capabilities and runtime stay behind, resolved separately when needed.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA5MDAgNjQwIiB3aWR0aD0iOTAwIiBoZWlnaHQ9IjY0MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsbGVkYnk9InBkLXRpdGxlIHBkLWRlc2MiIGZvbnQtZmFtaWx5PSItYXBwbGUtc3lzdGVtLCBCbGlua01hY1N5c3RlbUZvbnQsICdTZWdvZSBVSScsIEhlbHZldGljYSwgQXJpYWwsIHNhbnMtc2VyaWYiPgogIDx0aXRsZSBpZD0icGQtdGl0bGUiPlBhc3Nwb3J0IGRpc3RpbGxhdGlvbjogYSBjb21wYWN0LCBzZXBhcmF0ZWx5LXZlcmlmaWFibGUgY3JlZGVudGlhbCBkZXJpdmVkIGZyb20gdGhlIGZ1bGwgQURMIGRvY3VtZW50PC90aXRsZT4KICA8ZGVzYyBpZD0icGQtZGVzYyI+QSBsZWZ0LXRvLXJpZ2h0IGNsYXNzL29iamVjdCBkaWFncmFtIGluIHRocmVlIGNvbHVtbnMuIE9uIHRoZSBsZWZ0LCB0aGUgZnVsbCBBREwgRG9jdW1lbnQgbGlzdHMgYWxsIG9mIGl0cyBtZW1iZXIgZ3JvdXBzOyB0aGUgaWRlbnRpdHktYW5kLXRydXN0IG1lbWJlcnMgKGFkbF9zcGVjLCBpZCBhbmQgcHJvdmlkZXIsIGNyeXB0b2dyYXBoaWNfaWRlbnRpdHksIHNlY3VyaXR5IGF0dGVzdGF0aW9uIGFuZCBzY29wZXMsIGxpZmVjeWNsZSBzdGF0dXMsIHBlcm1pc3Npb25zLCBhbmQgZGF0YV9jbGFzc2lmaWNhdGlvbikgYXJlIGhpZ2hsaWdodGVkIGFzIHRoZSBkaXN0aWxsZWQgc3Vic2V0LCB3aGlsZSB0aGUgb3BlcmF0aW9uYWwgbWVtYmVycyAoY2FwYWJpbGl0aWVzLCB0b29scywgcmVzb3VyY2VzLCBtb2RlbCwgcnVudGltZSBiZWhhdmlvdXIgYW5kIGRlZ3JhZGF0aW9uLCBodW1hbl9vdmVyc2lnaHQsIGFub21hbHlfYmFzZWxpbmUpIGFyZSBncmV5ZWQgYXMgc3RheWluZyBiZWhpbmQgaW4gdGhlIGZ1bGwgZG9jdW1lbnQuIEEgc2luZ2xlIGRlcml2ZSBhcnJvdyBjcm9zc2VzIHRvIHRoZSBtaWRkbGUgY29sdW1uLCB0aGUgQWdlbnQgUGFzc3BvcnQsIGEgY29tcGFjdCBib3ggY2Fycnlpbmcgb25seSB0aGF0IGRpc3RpbGxlZCBzdWJzZXQg4oCUIHRoZSBtZW1iZXJzIGEgY291bnRlcnBhcnR5IG5lZWRzIHRvIGFuc3dlciB3aG8gaXMgdGhpcyBhZ2VudCBhbmQgY2FuIEkgdHJ1c3QgdGhpcyBkb2N1bWVudC4gQSBwcmVzZW50IGFycm93IHRoZW4gY2FycmllcyB0aGUgcGFzc3BvcnQgdG8gdGhlIHJpZ2h0IGNvbHVtbiwgYSBjb3VudGVycGFydHksIGF0dGFjaGVkIHRvIGEgcmVxdWVzdCBvciBkZXJlZmVyZW5jZWQgYnkgVVJMLiBBIG5vdGUgc3RhdGVzIHRoZSBwYXNzcG9ydCBpcyBhIHR5cGVkIHByb2plY3Rpb24gb2YgdGhlIGRvY3VtZW50OiBpZGVudGl0eSBhbmQgdHJ1c3QgdHJhdmVsOyBjYXBhYmlsaXRpZXMgYW5kIHJ1bnRpbWUgc3RheSBiZWhpbmQsIGFuZCB0aGUgZnVsbCBkb2N1bWVudCBpcyByZXNvbHZlZCBzZXBhcmF0ZWx5IHdoZW4gbmVlZGVkLjwvZGVzYz4KCiAgPGRlZnM+CiAgICA8bWFya2VyIGlkPSJwZC1hcnJvdyIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI5IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+CiAgICAgIDxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgZmlsbD0iIzMzNDE1NSIvPgogICAgPC9tYXJrZXI+CiAgPC9kZWZzPgoKICA8cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iOTAwIiBoZWlnaHQ9IjY0MCIgZmlsbD0iI2ZmZmZmZiIvPgoKICA8IS0tIFRpdGxlIC0tPgogIDx0ZXh0IHg9IjQ1MCIgeT0iMzQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMjAiIGZvbnQtd2VpZ2h0PSI3MDAiIGZpbGw9IiMwZjE3MmEiPlBhc3Nwb3J0IERpc3RpbGxhdGlvbjwvdGV4dD4KICA8dGV4dCB4PSI0NTAiIHk9IjU2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjEzIiBmb250LXN0eWxlPSJpdGFsaWMiIGZpbGw9IiM0NzU1NjkiPkEgY29tcGFjdCwgc2VwYXJhdGVseS12ZXJpZmlhYmxlIGNyZWRlbnRpYWwgZGVyaXZlZCBmcm9tIHRoZSBmdWxsIEFETCBkb2N1bWVudDwvdGV4dD4KCiAgPCEtLSA9PT09PT09PT09PT09PT09PT09PT0gTEVGVDogZnVsbCBBREwgZG9jdW1lbnQgPT09PT09PT09PT09PT09PT09PT09IC0tPgogIDxyZWN0IHg9IjQwIiB5PSI5MiIgd2lkdGg9IjMwMCIgaGVpZ2h0PSI0NzYiIHJ4PSIxMCIgZmlsbD0iI2Y4ZmFmYyIgc3Ryb2tlPSIjMWE3M2U4IiBzdHJva2Utd2lkdGg9IjEuNSIvPgogIDx0ZXh0IHg9IjE5MCIgeT0iMTE2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjE0IiBmb250LXdlaWdodD0iNzAwIiBmaWxsPSIjMGI1N2QwIj5BREwgRG9jdW1lbnQ8L3RleHQ+CiAgPHRleHQgeD0iMTkwIiB5PSIxMzIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTAiIGZvbnQtc3R5bGU9Iml0YWxpYyIgZmlsbD0iIzY0NzQ4YiI+dGhlIGZ1bGwgYWdlbnQgZGVmaW5pdGlvbiAoQ29yZSk8L3RleHQ+CgogIDwhLS0gZGlzdGlsbGVkIHN1YnNldCBoZWFkZXIgLS0+CiAgPHRleHQgeD0iNjAiIHk9IjE1OCIgZm9udC1zaXplPSI5LjUiIGZvbnQtd2VpZ2h0PSI3MDAiIGZpbGw9IiMwYjU3ZDAiIGxldHRlci1zcGFjaW5nPSIwLjYiPkRJU1RJTExFRCBJTlRPIFRIRSBQQVNTUE9SVDwvdGV4dD4KICA8IS0tIElOIHJvd3MgLS0+CiAgPGcgZm9udC1zaXplPSIxMSIgZmlsbD0iIzBmMTcyYSI+CiAgICA8cmVjdCB4PSI1NiIgeT0iMTY0IiB3aWR0aD0iMjY4IiBoZWlnaHQ9IjIyIiByeD0iNCIgZmlsbD0iI2U4ZjBmZSIvPgogICAgPHRleHQgeD0iNjYiIHk9IjE3OSI+YWRsX3NwZWMgJiM4MjEyOyBzcGVjIHZlcnNpb248L3RleHQ+CiAgICA8cmVjdCB4PSI1NiIgeT0iMTkwIiB3aWR0aD0iMjY4IiBoZWlnaHQ9IjIyIiByeD0iNCIgZmlsbD0iI2U4ZjBmZSIvPgogICAgPHRleHQgeD0iNjYiIHk9IjIwNSI+aWQgJiMxODM7IHByb3ZpZGVyICYjODIxMjsgaWRlbnRpdHk8L3RleHQ+CiAgICA8cmVjdCB4PSI1NiIgeT0iMjE2IiB3aWR0aD0iMjY4IiBoZWlnaHQ9IjIyIiByeD0iNCIgZmlsbD0iI2U4ZjBmZSIvPgogICAgPHRleHQgeD0iNjYiIHk9IjIzMSI+Y3J5cHRvZ3JhcGhpY19pZGVudGl0eTwvdGV4dD4KICAgIDxyZWN0IHg9IjU2IiB5PSIyNDIiIHdpZHRoPSIyNjgiIGhlaWdodD0iMjIiIHJ4PSI0IiBmaWxsPSIjZThmMGZlIi8+CiAgICA8dGV4dCB4PSI2NiIgeT0iMjU3Ij5zZWN1cml0eSAmIzgyMTI7IGF0dGVzdGF0aW9uICYjMTgzOyBzY29wZXM8L3RleHQ+CiAgICA8cmVjdCB4PSI1NiIgeT0iMjY4IiB3aWR0aD0iMjY4IiBoZWlnaHQ9IjIyIiByeD0iNCIgZmlsbD0iI2U4ZjBmZSIvPgogICAgPHRleHQgeD0iNjYiIHk9IjI4MyI+bGlmZWN5Y2xlLnN0YXR1czwvdGV4dD4KICAgIDxyZWN0IHg9IjU2IiB5PSIyOTQiIHdpZHRoPSIyNjgiIGhlaWdodD0iMjIiIHJ4PSI0IiBmaWxsPSIjZThmMGZlIi8+CiAgICA8dGV4dCB4PSI2NiIgeT0iMzA5Ij5wZXJtaXNzaW9uczwvdGV4dD4KICAgIDxyZWN0IHg9IjU2IiB5PSIzMjAiIHdpZHRoPSIyNjgiIGhlaWdodD0iMjIiIHJ4PSI0IiBmaWxsPSIjZThmMGZlIi8+CiAgICA8dGV4dCB4PSI2NiIgeT0iMzM1Ij5kYXRhX2NsYXNzaWZpY2F0aW9uPC90ZXh0PgogIDwvZz4KCiAgPCEtLSBzdGF5cy1iZWhpbmQgaGVhZGVyIC0tPgogIDx0ZXh0IHg9IjYwIiB5PSIzNjQiIGZvbnQtc2l6ZT0iOS41IiBmb250LXdlaWdodD0iNzAwIiBmaWxsPSIjOTRhM2I4IiBsZXR0ZXItc3BhY2luZz0iMC42Ij5TVEFZUyBJTiBUSEUgRlVMTCBET0NVTUVOVDwvdGV4dD4KICA8IS0tIE9VVCByb3dzIC0tPgogIDxnIGZvbnQtc2l6ZT0iMTEiIGZpbGw9IiM5NGEzYjgiPgogICAgPHJlY3QgeD0iNTYiIHk9IjM3MCIgd2lkdGg9IjI2OCIgaGVpZ2h0PSIyMCIgcng9IjQiIGZpbGw9IiNmMWY1ZjkiLz4KICAgIDx0ZXh0IHg9IjY2IiB5PSIzODQiPmNhcGFiaWxpdGllczwvdGV4dD4KICAgIDxyZWN0IHg9IjU2IiB5PSIzOTQiIHdpZHRoPSIyNjgiIGhlaWdodD0iMjAiIHJ4PSI0IiBmaWxsPSIjZjFmNWY5Ii8+CiAgICA8dGV4dCB4PSI2NiIgeT0iNDA4Ij50b29sczwvdGV4dD4KICAgIDxyZWN0IHg9IjU2IiB5PSI0MTgiIHdpZHRoPSIyNjgiIGhlaWdodD0iMjAiIHJ4PSI0IiBmaWxsPSIjZjFmNWY5Ii8+CiAgICA8dGV4dCB4PSI2NiIgeT0iNDMyIj5yZXNvdXJjZXM8L3RleHQ+CiAgICA8cmVjdCB4PSI1NiIgeT0iNDQyIiB3aWR0aD0iMjY4IiBoZWlnaHQ9IjIwIiByeD0iNCIgZmlsbD0iI2YxZjVmOSIvPgogICAgPHRleHQgeD0iNjYiIHk9IjQ1NiI+bW9kZWw8L3RleHQ+CiAgICA8cmVjdCB4PSI1NiIgeT0iNDY2IiB3aWR0aD0iMjY4IiBoZWlnaHQ9IjIwIiByeD0iNCIgZmlsbD0iI2YxZjVmOSIvPgogICAgPHRleHQgeD0iNjYiIHk9IjQ4MCI+cnVudGltZSAmIzgyMTI7IGJlaGF2aW91ciAmIzE4MzsgZGVncmFkYXRpb248L3RleHQ+CiAgICA8cmVjdCB4PSI1NiIgeT0iNDkwIiB3aWR0aD0iMjY4IiBoZWlnaHQ9IjIwIiByeD0iNCIgZmlsbD0iI2YxZjVmOSIvPgogICAgPHRleHQgeD0iNjYiIHk9IjUwNCI+aHVtYW5fb3ZlcnNpZ2h0PC90ZXh0PgogICAgPHJlY3QgeD0iNTYiIHk9IjUxNCIgd2lkdGg9IjI2OCIgaGVpZ2h0PSIyMCIgcng9IjQiIGZpbGw9IiNmMWY1ZjkiLz4KICAgIDx0ZXh0IHg9IjY2IiB5PSI1MjgiPmFub21hbHlfYmFzZWxpbmU8L3RleHQ+CiAgPC9nPgoKICA8IS0tID09PT09PT09PT09PT09PT09PT09PSBkZXJpdmUgYXJyb3cgKGZyb20gSU4gZ3JvdXAgdG8gcGFzc3BvcnQpID09PT09PT09PT09PT09PT09PT09PSAtLT4KICA8bGluZSB4MT0iMzQwIiB5MT0iMjQ5IiB4Mj0iNDQ4IiB5Mj0iMjQ5IiBzdHJva2U9IiMzMzQxNTUiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtZGFzaGFycmF5PSI1IDQiIG1hcmtlci1lbmQ9InVybCgjcGQtYXJyb3cpIi8+CiAgPHJlY3QgeD0iMzU2IiB5PSIyMjciIHdpZHRoPSI3NiIgaGVpZ2h0PSIxNiIgZmlsbD0iI2ZmZmZmZiIvPgogIDx0ZXh0IHg9IjM5NCIgeT0iMjM5IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjEwLjUiIGZvbnQtc3R5bGU9Iml0YWxpYyIgZmlsbD0iIzQ3NTU2OSI+JiMxNzE7ZGVyaXZlJiMxODc7PC90ZXh0PgogIDx0ZXh0IHg9IjM5NCIgeT0iMjYzIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjkiIGZpbGw9IiM2NDc0OGIiPnR5cGVkIHByb2plY3Rpb248L3RleHQ+CgogIDwhLS0gPT09PT09PT09PT09PT09PT09PT09IE1JRERMRTogdGhlIHBhc3Nwb3J0ID09PT09PT09PT09PT09PT09PT09PSAtLT4KICA8cmVjdCB4PSI0NTAiIHk9IjE1MCIgd2lkdGg9IjI1MCIgaGVpZ2h0PSIyOTAiIHJ4PSIxMCIgZmlsbD0iI2ZmZjdlNiIgc3Ryb2tlPSIjZjU5ZTBiIiBzdHJva2Utd2lkdGg9IjEuNzUiLz4KICA8dGV4dCB4PSI1NzUiIHk9IjE3NiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxNCIgZm9udC13ZWlnaHQ9IjcwMCIgZmlsbD0iI2I0NTMwOSI+QWdlbnQgUGFzc3BvcnQ8L3RleHQ+CiAgPHRleHQgeD0iNTc1IiB5PSIxOTIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iOS41IiBmb250LXN0eWxlPSJpdGFsaWMiIGZpbGw9IiM5MjcyMmYiPmNvbXBhY3QgJiMxODM7IHNpZ25lZCAmIzE4MzsgcmUtdmVyaWZpZWQgZWFjaCBleGNoYW5nZTwvdGV4dD4KCiAgPGcgZm9udC1zaXplPSIxMSIgZmlsbD0iIzBmMTcyYSI+CiAgICA8dGV4dCB4PSI0NzAiIHk9IjIxOCI+YWRsX3NwZWM8L3RleHQ+CiAgICA8dGV4dCB4PSI0NzAiIHk9IjI0MCI+aWQ8L3RleHQ+CiAgICA8dGV4dCB4PSI0NzAiIHk9IjI2MiI+Y3J5cHRvZ3JhcGhpY19pZGVudGl0eTwvdGV4dD4KICAgIDx0ZXh0IHg9IjQ3MCIgeT0iMjg0Ij5zZWN1cml0eS5hdHRlc3RhdGlvbiAoKyBzaWduYXR1cmUpPC90ZXh0PgogICAgPHRleHQgeD0iNDcwIiB5PSIzMDYiPmxpZmVjeWNsZS5zdGF0dXM8L3RleHQ+CiAgICA8dGV4dCB4PSI0NzAiIHk9IjMyOCI+cHJvdmlkZXI8L3RleHQ+CiAgICA8dGV4dCB4PSI0NzAiIHk9IjM1MCI+cGVybWlzc2lvbnMgJiMxODM7IGRhdGFfY2xhc3NpZmljYXRpb248L3RleHQ+CiAgICA8dGV4dCB4PSI0NzAiIHk9IjM3MiI+c2VjdXJpdHkuc2NvcGVzPC90ZXh0PgogIDwvZz4KICA8bGluZSB4MT0iNDY2IiB5MT0iMzg2IiB4Mj0iNjg0IiB5Mj0iMzg2IiBzdHJva2U9IiNmM2Q4YTgiIHN0cm9rZS13aWR0aD0iMSIvPgogIDx0ZXh0IHg9IjU3NSIgeT0iNDA2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjkuNSIgZmlsbD0iIzkyNzIyZiI+YW5zd2Vyczogd2hvIGlzIHRoaXMgYWdlbnQ/PC90ZXh0PgogIDx0ZXh0IHg9IjU3NSIgeT0iNDIxIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjkuNSIgZmlsbD0iIzkyNzIyZiI+YW5kIGNhbiBJIHRydXN0IHRoaXMgZG9jdW1lbnQ/PC90ZXh0PgoKICA8IS0tID09PT09PT09PT09PT09PT09PT09PSBwcmVzZW50IGFycm93IChwYXNzcG9ydCB0byBjb3VudGVycGFydHkpID09PT09PT09PT09PT09PT09PT09PSAtLT4KICA8bGluZSB4MT0iNzAwIiB5MT0iMjQ5IiB4Mj0iNzg4IiB5Mj0iMjQ5IiBzdHJva2U9IiMzMzQxNTUiIHN0cm9rZS13aWR0aD0iMS41IiBtYXJrZXItZW5kPSJ1cmwoI3BkLWFycm93KSIvPgogIDxyZWN0IHg9IjcxMiIgeT0iMjI3IiB3aWR0aD0iNjQiIGhlaWdodD0iMTYiIGZpbGw9IiNmZmZmZmYiLz4KICA8dGV4dCB4PSI3NDQiIHk9IjIzOSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxMC41IiBmb250LXN0eWxlPSJpdGFsaWMiIGZpbGw9IiM0NzU1NjkiPiYjMTcxO3ByZXNlbnQmIzE4Nzs8L3RleHQ+CiAgPHRleHQgeD0iNzQ0IiB5PSIyNjMiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iOSIgZmlsbD0iIzY0NzQ4YiI+YXR0YWNoZWQgb3I8L3RleHQ+CiAgPHRleHQgeD0iNzQ0IiB5PSIyNzUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iOSIgZmlsbD0iIzY0NzQ4YiI+ZGVyZWZlcmVuY2VkPC90ZXh0PgoKICA8IS0tID09PT09PT09PT09PT09PT09PT09PSBSSUdIVDogY291bnRlcnBhcnR5ID09PT09PT09PT09PT09PT09PT09PSAtLT4KICA8cmVjdCB4PSI3OTAiIHk9IjIwNiIgd2lkdGg9IjkyIiBoZWlnaHQ9Ijg2IiByeD0iMTAiIGZpbGw9IiNlNmY0ZWEiIHN0cm9rZT0iIzEzNzMzMyIgc3Ryb2tlLXdpZHRoPSIxLjUiLz4KICA8dGV4dCB4PSI4MzYiIHk9IjI0NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxMiIgZm9udC13ZWlnaHQ9IjcwMCIgZmlsbD0iIzBkNjUyZCI+Y291bnRlci08L3RleHQ+CiAgPHRleHQgeD0iODM2IiB5PSIyNjAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTIiIGZvbnQtd2VpZ2h0PSI3MDAiIGZpbGw9IiMwZDY1MmQiPnBhcnR5PC90ZXh0PgoKICA8IS0tID09PT09PT09PT09PT09PT09PT09PSBmb290bm90ZSA9PT09PT09PT09PT09PT09PT09PT0gLS0+CiAgPHRleHQgeD0iNDUwIiB5PSI2MDAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTEiIGZvbnQtc3R5bGU9Iml0YWxpYyIgZmlsbD0iIzQ3NTU2OSI+VGhlIHBhc3Nwb3J0IGlzIGEgdHlwZWQgcHJvamVjdGlvbiBvZiB0aGUgZG9jdW1lbnQ6IGlkZW50aXR5IGFuZCB0cnVzdCB0cmF2ZWw7IGNhcGFiaWxpdGllcyBhbmQgcnVudGltZSBzdGF5IGJlaGluZC48L3RleHQ+CiAgPHRleHQgeD0iNDUwIiB5PSI2MTciIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTEiIGZvbnQtc3R5bGU9Iml0YWxpYyIgZmlsbD0iIzQ3NTU2OSI+QSBjb3VudGVycGFydHkgdGhhdCBuZWVkcyB0aGUgYWdlbnQncyBjb21wbGV0ZSBkZWZpbml0aW9uIHJlc29sdmVzIHRoZSBmdWxsIEFETCBkb2N1bWVudCBzZXBhcmF0ZWx5LjwvdGV4dD4KPC9zdmc+Cg==) *Figure 1 (informative): The passport is a typed projection of the full ADL document — the identity-and-trust subset a counterparty needs, distilled into a compact signed credential, while the operational members stay in the full document and are resolved separately. This figure is illustrative; the member list below is authoritative.* Keeping the passport small matters because it travels on agent-to-agent interactions — attached to a request or dereferenced by URL (§1.2.5) — and is verified on every exchange. A counterparty that needs the agent's complete definition resolves the full ADL document separately. Note that `permissions` and `data_classification` are carried in full rather than as a digest; an agent with large permission sets (up to the Core §18.5 limits) therefore trades passport compactness for self-containment, which implementers sizing a passport header (e.g., `ADL-Passport`) should anticipate. The passport carries the following members: | Member | ADL Core | Role in trust | | ------------------------------------ | --------- | ---------------------------------------------------------------------------------------------------------------------------------- | | `adl_spec` | §4 | Spec version; selects the JSON Schema used for validation (§1.1.2). | | `id` | §6 | The agent's stable identifier — an HTTPS URI or URN — resolved to an authoritative key (§1.1.3). | | `cryptographic_identity.did` | §6.3 | A `did:web` identifier resolved to a DID Document that supplies the verification key (§1.1.3). | | `cryptographic_identity.public_key` | §6.3 | Inline public key (`algorithm`, `value`), cross-checked against the resolved key (§1.1.4). | | `security.attestation` | §10.2 | Attestation envelope (`type`, `issuer`, `issued_at`, `expires_at`) carrying the signature and its validity window (§1.1.5–§1.1.6). | | `security.attestation.signature` | §10.2 | The cryptographic signature over the JCS-canonical document, verified in §1.1.5 (`algorithm`, `value`, `signed_content`). | | `lifecycle.status` | §5.6 | `active` / `deprecated` / `retired` / `draft`; gates whether the agent may be provisioned (§1.1.7). | | `provider` | §6 | The publisher's identity, checked for coherence with the signing authority (§1.1.8). | | `permissions`, `data_classification` | §9, §10.1 | The agent's declared access surface and sensitivity, applied when it is invoked (§1.1.9). | | `security.scopes` | §10.4.1 | The agent's standing authorization ceiling for agent-to-agent calls (§2.2). | A passport is **verifiable** when it carries a resolvable `id` (or `cryptographic_identity.did`) together with a `security.attestation.signature`. An ADL document that lacks these can still be consumed as a description, but cannot be cryptographically verified as a passport — §1.1.3 treats a URN-only, unsigned document as Trust-On-First-Use. ## 1 Authentication (Agent-to-Agent)[​](#1-authentication-agent-to-agent "Direct link to 1 Authentication (Agent-to-Agent)") This section defines the agent-to-agent authentication path: how a counterparty verifies an ADL passport (§1.1) and binds it to a specific request via a presentation proof (§1.2). The complementary human/external-service path — the declarative credential schemes carried in `security.authentication` — is defined in [ADL Core §10.3.3](/spec/next#1033-credential-schemes). The procedures in §1.1 and §1.2 are procedural rather than declarative: they describe what counterparties **MUST** do when receiving an ADL passport, and apply regardless of whether the passport declares `security.authentication`. ### 1.1 Passport Verification Procedure[​](#11-passport-verification-procedure "Direct link to 1.1 Passport Verification Procedure") When a counterparty receives an ADL document — whether through peer exchange, a discovery endpoint (§6.4), a registry, or any other channel — and intends to act on its declarations (provision the agent, route requests to it, grant access, or treat it as authoritative), the counterparty **MUST** perform the verification procedure defined in this section before relying on any declaration in the document. The procedure is layered: each step gates the next. An implementation **MUST NOT** skip earlier steps to reach later ones, and **MUST NOT** treat a partial verification as sufficient unless this section explicitly allows it. ![Top-to-bottom activity diagram of the ten-gate passport verification procedure. An incoming ADL passport enters a vertical sequence of gates, each of which must pass before the next runs: retrieval integrity, schema validation, identity resolution, public-key cross-check, signature verification, temporal validity, lifecycle gating, provider-identity coherence, and permission and classification compatibility, ending in the verification outcome. A reject rail down the right side catches any gate that fails and sends the document to a single rejected outcome whose declarations must not be acted upon. Two branch callouts on the left show that a URN-only or unsigned document drops to Trust-On-First-Use rather than failing, and a deprecated lifecycle status warns but may continue. Passing all ten gates yields a verified outcome at the bottom.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA5MDAgNzIwIiB3aWR0aD0iOTAwIiBoZWlnaHQ9IjcyMCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsbGVkYnk9InZwLXRpdGxlIHZwLWRlc2MiIGZvbnQtZmFtaWx5PSItYXBwbGUtc3lzdGVtLCBCbGlua01hY1N5c3RlbUZvbnQsICdTZWdvZSBVSScsIEhlbHZldGljYSwgQXJpYWwsIHNhbnMtc2VyaWYiPgogIDx0aXRsZSBpZD0idnAtdGl0bGUiPlBhc3Nwb3J0IHZlcmlmaWNhdGlvbiBwaXBlbGluZTogdGVuIGdhdGVkIHN0ZXBzLCBlYWNoIGdhdGluZyB0aGUgbmV4dDwvdGl0bGU+CiAgPGRlc2MgaWQ9InZwLWRlc2MiPkEgdG9wLXRvLWJvdHRvbSBhY3Rpdml0eSBkaWFncmFtIG9mIHRoZSBwYXNzcG9ydCB2ZXJpZmljYXRpb24gcHJvY2VkdXJlLiBBbiBpbmNvbWluZyBBREwgcGFzc3BvcnQgZW50ZXJzIGEgdmVydGljYWwgc2VxdWVuY2Ugb2YgdGVuIGdhdGVzLCBlYWNoIG9mIHdoaWNoIG11c3QgcGFzcyBiZWZvcmUgdGhlIG5leHQgcnVuczogcmV0cmlldmFsIGludGVncml0eSwgc2NoZW1hIHZhbGlkYXRpb24sIGlkZW50aXR5IHJlc29sdXRpb24sIHB1YmxpYy1rZXkgY3Jvc3MtY2hlY2ssIHNpZ25hdHVyZSB2ZXJpZmljYXRpb24sIHRlbXBvcmFsIHZhbGlkaXR5LCBsaWZlY3ljbGUgZ2F0aW5nLCBwcm92aWRlci1pZGVudGl0eSBjb2hlcmVuY2UsIGFuZCBwZXJtaXNzaW9uIGFuZCBjbGFzc2lmaWNhdGlvbiBjb21wYXRpYmlsaXR5LCBlbmRpbmcgaW4gdGhlIHZlcmlmaWNhdGlvbiBvdXRjb21lLiBUaGUgcHJvY2VkdXJlIGlzIGxheWVyZWQ6IGFuIGltcGxlbWVudGF0aW9uIG11c3Qgbm90IHNraXAgYW4gZWFybGllciBzdGVwIHRvIHJlYWNoIGEgbGF0ZXIgb25lLiBUd28gYnJhbmNoIHBvaW50cyBhcmUgc2hvd246IGF0IGlkZW50aXR5IHJlc29sdXRpb24sIGEgVVJOLW9ubHkgb3IgdW5zaWduZWQgZG9jdW1lbnQgZHJvcHMgdG8gVHJ1c3QtT24tRmlyc3QtVXNlIHJhdGhlciB0aGFuIGZhaWxpbmc7IGF0IGxpZmVjeWNsZSBnYXRpbmcsIGEgZGVwcmVjYXRlZCBzdGF0dXMgd2FybnMgYnV0IG1heSBjb250aW51ZSB3aGlsZSByZXRpcmVkIG9yIGRyYWZ0IGlzIHJlamVjdGVkLiBBIHJlamVjdCByYWlsIHJ1bnMgZG93biB0aGUgcmlnaHQgc2lkZTogYW55IGdhdGUgdGhhdCBmYWlscyBzZW5kcyB0aGUgZG9jdW1lbnQgdG8gYSBzaW5nbGUgcmVqZWN0ZWQgb3V0Y29tZSBvbiB0aGUgcmlnaHQsIGFuZCBpdHMgZGVjbGFyYXRpb25zIG11c3Qgbm90IGJlIGFjdGVkIHVwb24uIFBhc3NpbmcgYWxsIHRlbiBnYXRlcyB5aWVsZHMgYSB2ZXJpZmllZCBvdXRjb21lIGF0IHRoZSBib3R0b20uPC9kZXNjPgoKICA8ZGVmcz4KICAgIDxtYXJrZXIgaWQ9InZwLWFyIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj4KICAgICAgPHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBmaWxsPSIjMzM0MTU1Ii8+CiAgICA8L21hcmtlcj4KICAgIDxtYXJrZXIgaWQ9InZwLWFyLXJlZCIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI5IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+CiAgICAgIDxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgZmlsbD0iI2M1MjIxZiIvPgogICAgPC9tYXJrZXI+CiAgICA8bWFya2VyIGlkPSJ2cC1hci1hbWJlciIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI5IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+CiAgICAgIDxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgZmlsbD0iI2Y1OWUwYiIvPgogICAgPC9tYXJrZXI+CiAgPC9kZWZzPgoKICA8cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iOTAwIiBoZWlnaHQ9IjcyMCIgZmlsbD0iI2ZmZmZmZiIvPgoKICA8IS0tIFRpdGxlIC0tPgogIDx0ZXh0IHg9IjQ1MCIgeT0iMzQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMjAiIGZvbnQtd2VpZ2h0PSI3MDAiIGZpbGw9IiMwZjE3MmEiPlBhc3Nwb3J0IFZlcmlmaWNhdGlvbiBQaXBlbGluZTwvdGV4dD4KICA8dGV4dCB4PSI0NTAiIHk9IjU2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjEzIiBmb250LXN0eWxlPSJpdGFsaWMiIGZpbGw9IiM0NzU1NjkiPlRlbiBnYXRlZCBzdGVwcyAoJiMxNjc7MS4xLjEmIzgyMTE7JiMxNjc7MS4xLjEwKSAmIzgyMTI7IGVhY2ggZ2F0ZSBnYXRlcyB0aGUgbmV4dDsgbm8gc3RlcCBtYXkgYmUgc2tpcHBlZDwvdGV4dD4KCiAgPCEtLSBpbmNvbWluZyAtLT4KICA8cmVjdCB4PSIyNTAiIHk9Ijc4IiB3aWR0aD0iMjAwIiBoZWlnaHQ9IjM0IiByeD0iMTciIGZpbGw9IiNlOGYwZmUiIHN0cm9rZT0iIzFhNzNlOCIgc3Ryb2tlLXdpZHRoPSIxLjUiLz4KICA8dGV4dCB4PSIzNTAiIHk9IjEwMCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxMiIgZm9udC13ZWlnaHQ9IjcwMCIgZmlsbD0iIzBiNTdkMCI+aW5jb21pbmcgQURMIHBhc3Nwb3J0PC90ZXh0PgoKICA8IS0tIHJlamVjdCByYWlsIHRhcmdldCAocmlnaHQpIC0tPgogIDxyZWN0IHg9IjY5MCIgeT0iMzMyIiB3aWR0aD0iMTUwIiBoZWlnaHQ9IjU2IiByeD0iMTAiIGZpbGw9IiNmY2U4ZTYiIHN0cm9rZT0iI2M1MjIxZiIgc3Ryb2tlLXdpZHRoPSIxLjc1Ii8+CiAgPHRleHQgeD0iNzY1IiB5PSIzNTYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTMiIGZvbnQtd2VpZ2h0PSI3MDAiIGZpbGw9IiNhNTBlMGUiPlJFSkVDVEVEPC90ZXh0PgogIDx0ZXh0IHg9Ijc2NSIgeT0iMzc0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjkuNSIgZmlsbD0iIzFmMjkzNyI+ZGVjbGFyYXRpb25zIG5vdCBhY3RlZCB1cG9uPC90ZXh0PgoKICA8IS0tIHZlcnRpY2FsIGdhdGVzOiB4IGNlbnRlciAzNTAsIGVhY2ggMjAwIHdpZGUsIDQwIHRhbGwsIHNwYWNlZCA1NCAtLT4KICA8IS0tIGhlbHBlcjogZ2F0ZSByb3dzIC0tPgogIDwhLS0gMSAtLT4KICA8cmVjdCB4PSIyNTAiIHk9IjEyNCIgd2lkdGg9IjIwMCIgaGVpZ2h0PSI0MCIgcng9IjgiIGZpbGw9IiNmOGZhZmMiIHN0cm9rZT0iIzY0NzQ4YiIgc3Ryb2tlLXdpZHRoPSIxLjQiLz4KICA8dGV4dCB4PSIzNTAiIHk9IjE0MyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxMS41IiBmb250LXdlaWdodD0iNzAwIiBmaWxsPSIjMGYxNzJhIj4xICYjMTgzOyBSZXRyaWV2YWwgaW50ZWdyaXR5PC90ZXh0PgogIDx0ZXh0IHg9IjM1MCIgeT0iMTU3IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjkiIGZpbGw9IiM0NzU1NjkiPkhUVFBTICsgVExTICYjMTgzOyBwcm92ZW5hbmNlPC90ZXh0PgoKICA8cmVjdCB4PSIyNTAiIHk9IjE3OCIgd2lkdGg9IjIwMCIgaGVpZ2h0PSI0MCIgcng9IjgiIGZpbGw9IiNmOGZhZmMiIHN0cm9rZT0iIzY0NzQ4YiIgc3Ryb2tlLXdpZHRoPSIxLjQiLz4KICA8dGV4dCB4PSIzNTAiIHk9IjE5NyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxMS41IiBmb250LXdlaWdodD0iNzAwIiBmaWxsPSIjMGYxNzJhIj4yICYjMTgzOyBTY2hlbWEgdmFsaWRhdGlvbjwvdGV4dD4KICA8dGV4dCB4PSIzNTAiIHk9IjIxMSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSI5IiBmaWxsPSIjNDc1NTY5Ij5hZ2FpbnN0IHRoZSBhZGxfc3BlYyBzY2hlbWE8L3RleHQ+CgogIDxyZWN0IHg9IjI1MCIgeT0iMjMyIiB3aWR0aD0iMjAwIiBoZWlnaHQ9IjQwIiByeD0iOCIgZmlsbD0iI2Y4ZmFmYyIgc3Ryb2tlPSIjNjQ3NDhiIiBzdHJva2Utd2lkdGg9IjEuNCIvPgogIDx0ZXh0IHg9IjM1MCIgeT0iMjUxIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjExLjUiIGZvbnQtd2VpZ2h0PSI3MDAiIGZpbGw9IiMwZjE3MmEiPjMgJiMxODM7IElkZW50aXR5IHJlc29sdXRpb248L3RleHQ+CiAgPHRleHQgeD0iMzUwIiB5PSIyNjUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iOSIgZmlsbD0iIzQ3NTU2OSI+aWQgLyBkaWQ6d2ViICYjODU5NDsgYXV0aG9yaXRhdGl2ZSBrZXk8L3RleHQ+CgogIDxyZWN0IHg9IjI1MCIgeT0iMjg2IiB3aWR0aD0iMjAwIiBoZWlnaHQ9IjQwIiByeD0iOCIgZmlsbD0iI2Y4ZmFmYyIgc3Ryb2tlPSIjNjQ3NDhiIiBzdHJva2Utd2lkdGg9IjEuNCIvPgogIDx0ZXh0IHg9IjM1MCIgeT0iMzA1IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjExLjUiIGZvbnQtd2VpZ2h0PSI3MDAiIGZpbGw9IiMwZjE3MmEiPjQgJiMxODM7IFB1YmxpYy1rZXkgY3Jvc3MtY2hlY2s8L3RleHQ+CiAgPHRleHQgeD0iMzUwIiB5PSIzMTkiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iOSIgZmlsbD0iIzQ3NTU2OSI+aW5saW5lIGtleSA9PSByZXNvbHZlZCBrZXk8L3RleHQ+CgogIDxyZWN0IHg9IjI1MCIgeT0iMzQwIiB3aWR0aD0iMjAwIiBoZWlnaHQ9IjQwIiByeD0iOCIgZmlsbD0iI2Y4ZmFmYyIgc3Ryb2tlPSIjNjQ3NDhiIiBzdHJva2Utd2lkdGg9IjEuNCIvPgogIDx0ZXh0IHg9IjM1MCIgeT0iMzU5IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjExLjUiIGZvbnQtd2VpZ2h0PSI3MDAiIGZpbGw9IiMwZjE3MmEiPjUgJiMxODM7IFNpZ25hdHVyZSB2ZXJpZmljYXRpb248L3RleHQ+CiAgPHRleHQgeD0iMzUwIiB5PSIzNzMiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iOSIgZmlsbD0iIzQ3NTU2OSI+SkNTLWNhbm9uaWNhbCAmIzE4MzsgJiMxNjc7MTAuMjwvdGV4dD4KCiAgPHJlY3QgeD0iMjUwIiB5PSIzOTQiIHdpZHRoPSIyMDAiIGhlaWdodD0iNDAiIHJ4PSI4IiBmaWxsPSIjZjhmYWZjIiBzdHJva2U9IiM2NDc0OGIiIHN0cm9rZS13aWR0aD0iMS40Ii8+CiAgPHRleHQgeD0iMzUwIiB5PSI0MTMiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTEuNSIgZm9udC13ZWlnaHQ9IjcwMCIgZmlsbD0iIzBmMTcyYSI+NiAmIzE4MzsgVGVtcG9yYWwgdmFsaWRpdHk8L3RleHQ+CiAgPHRleHQgeD0iMzUwIiB5PSI0MjciIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iOSIgZmlsbD0iIzQ3NTU2OSI+YXR0ZXN0YXRpb24gbm90IGV4cGlyZWQ8L3RleHQ+CgogIDxyZWN0IHg9IjI1MCIgeT0iNDQ4IiB3aWR0aD0iMjAwIiBoZWlnaHQ9IjQwIiByeD0iOCIgZmlsbD0iI2Y4ZmFmYyIgc3Ryb2tlPSIjNjQ3NDhiIiBzdHJva2Utd2lkdGg9IjEuNCIvPgogIDx0ZXh0IHg9IjM1MCIgeT0iNDY3IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjExLjUiIGZvbnQtd2VpZ2h0PSI3MDAiIGZpbGw9IiMwZjE3MmEiPjcgJiMxODM7IExpZmVjeWNsZSBnYXRpbmc8L3RleHQ+CiAgPHRleHQgeD0iMzUwIiB5PSI0ODEiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iOSIgZmlsbD0iIzQ3NTU2OSI+YWN0aXZlIC8gZGVwcmVjYXRlZCAvIHJldGlyZWQgLyBkcmFmdDwvdGV4dD4KCiAgPHJlY3QgeD0iMjUwIiB5PSI1MDIiIHdpZHRoPSIyMDAiIGhlaWdodD0iNDAiIHJ4PSI4IiBmaWxsPSIjZjhmYWZjIiBzdHJva2U9IiM2NDc0OGIiIHN0cm9rZS13aWR0aD0iMS40Ii8+CiAgPHRleHQgeD0iMzUwIiB5PSI1MjEiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTEuNSIgZm9udC13ZWlnaHQ9IjcwMCIgZmlsbD0iIzBmMTcyYSI+OCAmIzE4MzsgUHJvdmlkZXIgY29oZXJlbmNlPC90ZXh0PgogIDx0ZXh0IHg9IjM1MCIgeT0iNTM1IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjkiIGZpbGw9IiM0NzU1NjkiPnNpZ25lciBhbGlnbnMgd2l0aCBwcm92aWRlcjwvdGV4dD4KCiAgPHJlY3QgeD0iMjUwIiB5PSI1NTYiIHdpZHRoPSIyMDAiIGhlaWdodD0iNDAiIHJ4PSI4IiBmaWxsPSIjZjhmYWZjIiBzdHJva2U9IiM2NDc0OGIiIHN0cm9rZS13aWR0aD0iMS40Ii8+CiAgPHRleHQgeD0iMzUwIiB5PSI1NzUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTEuNSIgZm9udC13ZWlnaHQ9IjcwMCIgZmlsbD0iIzBmMTcyYSI+OSAmIzE4MzsgUGVybWlzc2lvbiAmYW1wOyBjbGFzcy48L3RleHQ+CiAgPHRleHQgeD0iMzUwIiB5PSI1ODkiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iOSIgZmlsbD0iIzQ3NTU2OSI+ZGVueS1ieS1kZWZhdWx0ICYjMTgzOyBkYXRhIGNsYXNzPC90ZXh0PgoKICA8IS0tIDEwIG91dGNvbWUgLS0+CiAgPHJlY3QgeD0iMjUwIiB5PSI2MjQiIHdpZHRoPSIyMDAiIGhlaWdodD0iNDQiIHJ4PSIxMCIgZmlsbD0iI2U2ZjRlYSIgc3Ryb2tlPSIjMTM3MzMzIiBzdHJva2Utd2lkdGg9IjEuNzUiLz4KICA8dGV4dCB4PSIzNTAiIHk9IjY0MyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxMi41IiBmb250LXdlaWdodD0iNzAwIiBmaWxsPSIjMGQ2NTJkIj4xMCAmIzE4MzsgVkVSSUZJRUQ8L3RleHQ+CiAgPHRleHQgeD0iMzUwIiB5PSI2NTkiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iOSIgZmlsbD0iIzFmMjkzNyI+b3V0Y29tZSByZWNvcmRlZDsgZGVjbGFyYXRpb25zIHRydXN0ZWQ8L3RleHQ+CgogIDwhLS0gdmVydGljYWwgZ2F0aW5nIGFycm93cyBiZXR3ZWVuIHN0ZXBzICh4PTM1MCkgLS0+CiAgPGxpbmUgeDE9IjM1MCIgeTE9IjExMiIgeDI9IjM1MCIgeTI9IjEyNCIgc3Ryb2tlPSIjMzM0MTU1IiBzdHJva2Utd2lkdGg9IjEuNCIgbWFya2VyLWVuZD0idXJsKCN2cC1hcikiLz4KICA8bGluZSB4MT0iMzUwIiB5MT0iMTY0IiB4Mj0iMzUwIiB5Mj0iMTc4IiBzdHJva2U9IiMzMzQxNTUiIHN0cm9rZS13aWR0aD0iMS40IiBtYXJrZXItZW5kPSJ1cmwoI3ZwLWFyKSIvPgogIDxsaW5lIHgxPSIzNTAiIHkxPSIyMTgiIHgyPSIzNTAiIHkyPSIyMzIiIHN0cm9rZT0iIzMzNDE1NSIgc3Ryb2tlLXdpZHRoPSIxLjQiIG1hcmtlci1lbmQ9InVybCgjdnAtYXIpIi8+CiAgPGxpbmUgeDE9IjM1MCIgeTE9IjI3MiIgeDI9IjM1MCIgeTI9IjI4NiIgc3Ryb2tlPSIjMzM0MTU1IiBzdHJva2Utd2lkdGg9IjEuNCIgbWFya2VyLWVuZD0idXJsKCN2cC1hcikiLz4KICA8bGluZSB4MT0iMzUwIiB5MT0iMzI2IiB4Mj0iMzUwIiB5Mj0iMzQwIiBzdHJva2U9IiMzMzQxNTUiIHN0cm9rZS13aWR0aD0iMS40IiBtYXJrZXItZW5kPSJ1cmwoI3ZwLWFyKSIvPgogIDxsaW5lIHgxPSIzNTAiIHkxPSIzODAiIHgyPSIzNTAiIHkyPSIzOTQiIHN0cm9rZT0iIzMzNDE1NSIgc3Ryb2tlLXdpZHRoPSIxLjQiIG1hcmtlci1lbmQ9InVybCgjdnAtYXIpIi8+CiAgPGxpbmUgeDE9IjM1MCIgeTE9IjQzNCIgeDI9IjM1MCIgeTI9IjQ0OCIgc3Ryb2tlPSIjMzM0MTU1IiBzdHJva2Utd2lkdGg9IjEuNCIgbWFya2VyLWVuZD0idXJsKCN2cC1hcikiLz4KICA8bGluZSB4MT0iMzUwIiB5MT0iNDg4IiB4Mj0iMzUwIiB5Mj0iNTAyIiBzdHJva2U9IiMzMzQxNTUiIHN0cm9rZS13aWR0aD0iMS40IiBtYXJrZXItZW5kPSJ1cmwoI3ZwLWFyKSIvPgogIDxsaW5lIHgxPSIzNTAiIHkxPSI1NDIiIHgyPSIzNTAiIHkyPSI1NTYiIHN0cm9rZT0iIzMzNDE1NSIgc3Ryb2tlLXdpZHRoPSIxLjQiIG1hcmtlci1lbmQ9InVybCgjdnAtYXIpIi8+CiAgPGxpbmUgeDE9IjM1MCIgeTE9IjU5NiIgeDI9IjM1MCIgeTI9IjYyNCIgc3Ryb2tlPSIjMzM0MTU1IiBzdHJva2Utd2lkdGg9IjEuNCIgbWFya2VyLWVuZD0idXJsKCN2cC1hcikiLz4KICA8dGV4dCB4PSIzNTgiIHk9IjYxMyIgdGV4dC1hbmNob3I9InN0YXJ0IiBmb250LXNpemU9IjkiIGZpbGw9IiMxMzczMzMiPmFsbCBnYXRlcyBwYXNzPC90ZXh0PgoKICA8IS0tIHJlamVjdCByYWlsOiBvbmUgY29udGludW91cyBzb2xpZCBicmFja2V0IGVtYnJhY2luZyBhbGwgbmluZSBnYXRlcyAtPiBhbnkgZ2F0ZSBmYWlscyAtPiBSRUpFQ1RFRCAtLT4KICA8bGluZSB4MT0iNDU1IiB5MT0iMTQ0IiB4Mj0iNjAwIiB5Mj0iMTQ0IiBzdHJva2U9IiNjNTIyMWYiIHN0cm9rZS13aWR0aD0iMS41Ii8+CiAgPGxpbmUgeDE9IjYwMCIgeTE9IjE0NCIgeDI9IjYwMCIgeTI9IjU3NiIgc3Ryb2tlPSIjYzUyMjFmIiBzdHJva2Utd2lkdGg9IjEuNSIvPgogIDxsaW5lIHgxPSI0NTUiIHkxPSI1NzYiIHgyPSI2MDAiIHkyPSI1NzYiIHN0cm9rZT0iI2M1MjIxZiIgc3Ryb2tlLXdpZHRoPSIxLjUiLz4KICA8bGluZSB4MT0iNjAwIiB5MT0iMzYwIiB4Mj0iNjg4IiB5Mj0iMzYwIiBzdHJva2U9IiNjNTIyMWYiIHN0cm9rZS13aWR0aD0iMS42IiBtYXJrZXItZW5kPSJ1cmwoI3ZwLWFyLXJlZCkiLz4KICA8cmVjdCB4PSI2MDYiIHk9IjM0MCIgd2lkdGg9Ijc2IiBoZWlnaHQ9IjE0IiBmaWxsPSIjZmZmZmZmIi8+CiAgPHRleHQgeD0iNjQ0IiB5PSIzNTEiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iOS41IiBmb250LXdlaWdodD0iNzAwIiBmaWxsPSIjYTUwZTBlIj5hbnkgZ2F0ZSBmYWlsczwvdGV4dD4KCiAgPCEtLSBicmFuY2ggY2FsbG91dHMgKGxlZnQgc2lkZSkgLS0+CiAgPCEtLSBVUk4tb25seSAtPiBUT0ZVIGF0IHN0ZXAgMyAtLT4KICA8cmVjdCB4PSI0MCIgeT0iMjM1IiB3aWR0aD0iMTkwIiBoZWlnaHQ9IjM0IiByeD0iOCIgZmlsbD0iI2ZmZjdlNiIgc3Ryb2tlPSIjZjU5ZTBiIiBzdHJva2Utd2lkdGg9IjEuMyIvPgogIDx0ZXh0IHg9IjEzNSIgeT0iMjQ5IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjkuNSIgZm9udC13ZWlnaHQ9IjcwMCIgZmlsbD0iI2I0NTMwOSI+VVJOLW9ubHkgLyB1bnNpZ25lZDwvdGV4dD4KICA8dGV4dCB4PSIxMzUiIHk9IjI2MiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSI5IiBmaWxsPSIjOTI3MjJmIj4mIzg1OTQ7IFRydXN0LU9uLUZpcnN0LVVzZSAobm90IHJlamVjdCk8L3RleHQ+CiAgPGxpbmUgeDE9IjIzMCIgeTE9IjI1MiIgeDI9IjI0OCIgeTI9IjI1MiIgc3Ryb2tlPSIjZjU5ZTBiIiBzdHJva2Utd2lkdGg9IjEuMyIgbWFya2VyLWVuZD0idXJsKCN2cC1hci1hbWJlcikiLz4KCiAgPCEtLSBkZXByZWNhdGVkIC0+IHdhcm4gYXQgc3RlcCA3IC0tPgogIDxyZWN0IHg9IjQwIiB5PSI0NTEiIHdpZHRoPSIxOTAiIGhlaWdodD0iMzQiIHJ4PSI4IiBmaWxsPSIjZmZmN2U2IiBzdHJva2U9IiNmNTllMGIiIHN0cm9rZS13aWR0aD0iMS4zIi8+CiAgPHRleHQgeD0iMTM1IiB5PSI0NjUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iOS41IiBmb250LXdlaWdodD0iNzAwIiBmaWxsPSIjYjQ1MzA5Ij5kZXByZWNhdGVkPC90ZXh0PgogIDx0ZXh0IHg9IjEzNSIgeT0iNDc4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjkiIGZpbGw9IiM5MjcyMmYiPiYjODU5NDsgd2FybiwgTUFZIGNvbnRpbnVlPC90ZXh0PgogIDxsaW5lIHgxPSIyMzAiIHkxPSI0NjgiIHgyPSIyNDgiIHkyPSI0NjgiIHN0cm9rZT0iI2Y1OWUwYiIgc3Ryb2tlLXdpZHRoPSIxLjMiIG1hcmtlci1lbmQ9InVybCgjdnAtYXItYW1iZXIpIi8+CgogIDwhLS0gZm9vdG5vdGUgLS0+CiAgPHRleHQgeD0iNDUwIiB5PSI3MDAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTEiIGZvbnQtc3R5bGU9Iml0YWxpYyIgZmlsbD0iIzQ3NTU2OSI+VGhlIHByb2NlZHVyZSBpcyBsYXllcmVkIGFuZCBkZXRlcm1pbmlzdGljOiB0aGUgc2FtZSBwYXNzcG9ydCB5aWVsZHMgdGhlIHNhbWUgb3V0Y29tZSBldmVyeSB0aW1lLiBJbGx1c3RyYXRpdmU7ICYjMTY3OzEuMSBpcyBhdXRob3JpdGF0aXZlLjwvdGV4dD4KPC9zdmc+Cg==) *Figure 2 (informative): The verification procedure is a layered pipeline — each gate gates the next, any failure rejects, and the same passport yields the same outcome every time. This figure is illustrative; the normative steps are §1.1.1–§1.1.10 below.* #### 1.1.1 Retrieval Integrity[​](#111-retrieval-integrity "Direct link to 1.1.1 Retrieval Integrity") Before any document-level verification, the counterparty **MUST** establish retrieval integrity: * If the document was retrieved over the network, retrieval **MUST** use HTTPS with full TLS certificate validation per \[RFC9110]. Implementations **MUST NOT** accept ADL documents over plain HTTP from untrusted sources. * If the document was retrieved from a discovery endpoint (§6.4), the discovery endpoint's TLS authority establishes a starting trust anchor for the listed agents. Implementations **SHOULD** record this authority for use in §1.1.3. * If the document was retrieved from local storage, an internal registry, or an air-gapped channel, the counterparty **MUST** record the provenance (path, registry name, channel identifier) for downstream auditing. Such documents **SHOULD** still be cryptographically verified per the remaining steps in this section. #### 1.1.2 Schema Validation[​](#112-schema-validation "Direct link to 1.1.2 Schema Validation") The counterparty **MUST** validate the document against the ADL JSON Schema for the version declared in `adl_spec`. Documents that fail schema validation **MUST** be rejected; their declarations **MUST NOT** be acted upon. This step gates all subsequent verification because subsequent steps assume the document's structure conforms to the schema. #### 1.1.3 Identity Resolution[​](#113-identity-resolution "Direct link to 1.1.3 Identity Resolution") If the document declares an `id` or `cryptographic_identity.did`, the counterparty **MUST** resolve it to an authoritative public key using the procedure appropriate for the identifier scheme: * **HTTPS URI `id`** — The counterparty **MUST** dereference the `id` URL over HTTPS. The fetched document **MUST** match the document being verified by canonical byte sequence (per §10.2 / \[RFC8785]). If the canonical byte sequences do not match, the document being verified is not the authoritative version published at the canonical URL and **MUST** be rejected unless the counterparty has out-of-band reason to accept it (e.g., a known mirror with an integrity record). * **`did:web` `cryptographic_identity.did`** — The counterparty **MUST** resolve the DID by fetching `https://{domain}/.well-known/did.json` for top-level identifiers, or `https://{domain}/{path-segments}/did.json` for path-based identifiers, per the `did:web` method specification \[W3C.DID-WEB]. The fetched DID Document **MUST** be served over HTTPS with full certificate validation. The counterparty **MUST** extract the public key designated by the DID Document's `assertionMethod` verification relationship. If `assertionMethod` is absent or unresolvable, verification **MUST** fail. * **URN `id`** — URN identifiers do not resolve. If the document declares only a URN identifier, the counterparty **MUST NOT** rely on the URN for identity verification. The counterparty **MAY** still perform §1.1.5 (signature verification) using the inline `cryptographic_identity.public_key`, but **MUST** treat the result as Trust-On-First-Use and **MUST NOT** elevate the document's declarations to a higher trust tier than the channel that delivered it. #### 1.1.4 Public Key Cross-Check[​](#114-public-key-cross-check "Direct link to 1.1.4 Public Key Cross-Check") When both an inline `cryptographic_identity.public_key` and a resolved authoritative public key (from §1.1.3) are available, the counterparty **MUST** cross-check them: * The `algorithm` values **MUST** match. * The `value` byte sequences (after base64 decoding) **MUST** be identical. If the cross-check fails, the document **MUST** be rejected. A mismatch indicates either document tampering after signing or a misconfigured publisher; in either case, the document cannot be trusted. When only one public key source is available (e.g., URN-only identifier with inline key, or DID-only identifier without inline key), the counterparty **MUST** record which source was used and **MAY** apply additional policy (such as requiring human review) before acting on the document's declarations. #### 1.1.5 Signature Verification[​](#115-signature-verification "Direct link to 1.1.5 Signature Verification") If the document contains `security.attestation.signature`, the counterparty **MUST** verify it per §10.2: 1. Construct the verification payload by removing the `signature` object from `security.attestation` (preserving all other fields). 2. Serialize the resulting document using JCS \[RFC8785]. 3. If `signed_content` is `"digest"`, compute the digest using `digest_algorithm` and compare to `digest_value`; reject on mismatch. 4. Verify the signature `value` against the canonical byte sequence (or its digest) using the algorithm in `signature.algorithm` and the public key established in §1.1.3 / §1.1.4. A document that claims a signature but fails verification **MUST** be rejected. A document with no signature **MAY** be accepted only if the counterparty's policy permits unsigned documents from the document's retrieval channel. #### 1.1.6 Temporal Validity[​](#116-temporal-validity "Direct link to 1.1.6 Temporal Validity") The counterparty **MUST** check the attestation's temporal validity: * If `security.attestation.expires_at` is in the past, the document **MUST** be rejected unless the counterparty's policy explicitly permits expired attestations (e.g., for offline forensic analysis). * Implementations **SHOULD** warn when `expires_at` is within 30 days of the current time, per §10.2. #### 1.1.7 Lifecycle Gating[​](#117-lifecycle-gating "Direct link to 1.1.7 Lifecycle Gating") The counterparty **MUST** check `lifecycle.status` per §5.6: * `retired` — The counterparty **MUST NOT** provision, route to, or otherwise rely on the agent. Verification fails at this step. * `deprecated` — The counterparty **SHOULD** warn (including `sunset_date` and `successor` if present) and **MAY** continue. Counterparties **SHOULD NOT** onboard new dependencies on deprecated agents. * `draft` — The counterparty **MUST NOT** provision in production. In development environments, the counterparty **MAY** continue. * `active` — The counterparty **MAY** continue. #### 1.1.8 Provider–Identity Coherence[​](#118-provideridentity-coherence "Direct link to 1.1.8 Provider–Identity Coherence") The counterparty **SHOULD** verify that the signing identity is coherent with the document's declared `provider`: * The TLS authority used in §1.1.1 (for retrieval) and §1.1.3 (for identity resolution) **SHOULD** align with the domain of `provider.url` and the authority component of an HTTPS `id` or the domain segment of a `did:web` identifier. * When the counterparty maintains a provider allowlist (per §18), the signing identity **MUST** match an entry on that allowlist before the document's declarations are acted upon. #### 1.1.9 Permission and Classification Compatibility[​](#119-permission-and-classification-compatibility "Direct link to 1.1.9 Permission and Classification Compatibility") When the counterparty is invoking the agent (rather than merely cataloging it), the counterparty **MUST** apply the deny-by-default permission model (§9) and the data classification rules (§10.1) before completing verification. In particular: * The agent's declared `permissions.network`, `permissions.filesystem`, `permissions.environment`, and `permissions.execution` **MUST** be applied to subsequent tool invocations. * When the counterparty is itself an agent, its own `data_classification.sensitivity` **MUST** be at least as high as the data classification of any tool or resource it invokes on the verified agent. This prevents a `public`-classified agent from accessing `confidential` data exposed by a verified peer. #### 1.1.10 Verification Outcome[​](#1110-verification-outcome "Direct link to 1.1.10 Verification Outcome") A verification result **MUST** record, at minimum: * A boolean overall outcome (`verified` or `not_verified`) * The result of each step (1.1.1 through 1.1.9), including which step failed (if any) * The retrieval channel and trust anchor used * The public key source(s) used (inline, DID-resolved, or both) Implementations that operate in `audit` or `permissive` modes (allowing failed verifications to proceed with logging) **MUST** still record the same structure; the outcome is informational rather than gating in those modes. ### 1.2 Presentation Proof[​](#12-presentation-proof "Direct link to 1.2 Presentation Proof") §1.1 authenticates a passport — does this document genuinely belong to the agent it names? It does not, however, bind the passport to a specific request. A passport that is published at a discoverable URL, shared in a registry, or transmitted over an authenticated channel is replayable: any party that obtains the passport bytes can re-present them as their own for the document's entire validity window. This subsection closes that gap by defining a per-request **presentation proof**, signed by the passport's private key, that binds the passport to a specific request URI, method, and timestamp. The presentation proof is conceptually equivalent to OAuth 2.1's sender-constrained-token mechanism (DPoP, \[RFC9449]) but uses ADL-native primitives (JCS canonicalization per §10.2 + Ed25519 signing) so that ports across languages do not need a JWT toolchain. When an agent acts as the *presenter* of an ADL passport — when it submits its passport in support of a request to a counterparty — it **MUST**, unless §1.2.10 explicitly waives the requirement, produce a presentation proof. When a counterparty acts as the *verifier* of a presentation, it **MUST**, after completing §1.1 verification of the passport, perform the procedure in §1.2.6 before treating the request as authenticated. #### 1.2.1 Threat Model[​](#121-threat-model "Direct link to 1.2.1 Threat Model") The presentation proof addresses a single threat: replay of a previously observed or scraped passport. It assumes: * Passports are not secret. The threat model is that an attacker may obtain a complete, valid, signed passport (from a discovery endpoint, registry, network capture, or copy-pasted disclosure). * The attacker does **not** have access to the corresponding private key. * The verifier and presenter have synchronized clocks within a tolerance specified by §1.2.8. The presentation proof does **not** address private key compromise; that is a key-rotation concern handled at the attestation level (§10.2 `expires_at`) and by operational rotation policies. #### 1.2.2 Proof Document Structure[​](#122-proof-document-structure "Direct link to 1.2.2 Proof Document Structure") A presentation proof **MUST** be a JSON object with the following members: | Member | Type | Required | Description | | ----------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `adl_proof` | string | REQUIRED | Proof format version. **MUST** be `"1.0"` for this specification. | | `iss` | string | REQUIRED | The passport's `id` value. The verifier **MUST** confirm this matches the `id` of the accompanying passport. | | `iat` | string | REQUIRED | ISO 8601 timestamp when the proof was issued. | | `exp` | string | REQUIRED | ISO 8601 timestamp when the proof expires. **MUST NOT** be more than 5 minutes after `iat`. | | `jti` | string | REQUIRED | Globally unique proof identifier (recommended: ULID, UUIDv7, or 128-bit base32 random). Used by verifiers for replay prevention. | | `request` | object | REQUIRED | The request the proof binds to. See §1.2.3. | | `scopes` | array of strings | OPTIONAL | Per-request requested authorization scopes. When present, the verifier **MUST** check that the array is a subset of the presenter's passport-declared ceiling per §2.2. Sender-constrained scope binding analogous to DPoP-bound access tokens. | | `nonce` | string | OPTIONAL | A nonce previously issued by the verifier per §1.2.7. | | `signature` | object | REQUIRED | Ed25519 signature over the JCS-canonical bytes of the proof minus the signature object. Same shape as §10.2 attestation signatures. | #### 1.2.3 Request Binding Object[​](#123-request-binding-object "Direct link to 1.2.3 Request Binding Object") The `request` member binds the proof to a specific request: | Member | Type | Required | Description | | -------- | ------ | ---------------------------- | ------------------------------------------------------------------------------------------------------ | | `method` | string | REQUIRED for HTTP transports | Uppercase HTTP method (`GET`, `POST`, etc.). For non-HTTP transports, **MAY** be the literal `"NONE"`. | | `uri` | string | REQUIRED | The canonical request URI per §1.2.4. | For non-HTTP transports (e.g., A2A over message queues, MCP over stdio), `uri` **MUST** be a stable transport-specific identifier — a topic name, a fully-qualified RPC method, or an A2A skill URI — and `method` **MUST** be `"NONE"`. The intent is that two requests with the same logical target produce the same binding. #### 1.2.4 URI Canonicalization[​](#124-uri-canonicalization "Direct link to 1.2.4 URI Canonicalization") Before producing or verifying a proof, the `request.uri` value **MUST** be canonicalized: 1. The scheme **MUST** be lowercased. 2. The host (if present) **MUST** be lowercased and **MUST NOT** carry a trailing dot. 3. Default ports **MUST** be stripped (port 80 for `http`, 443 for `https`). 4. The path **MUST** be percent-encoding-normalized: unreserved characters (per \[RFC3986]) **MUST** be unencoded, and reserved characters **MUST** use uppercase hex (`%2F`, not `%2f`). 5. The query string, if present, **MUST** be preserved verbatim (order-significant). 6. The fragment **MUST** be omitted (fragments are not transmitted; including one in a proof is a defect). These rules match DPoP §4.2 (`htu`) \[RFC9449] for cross-implementation consistency. #### 1.2.5 Presentation[​](#125-presentation "Direct link to 1.2.5 Presentation") Two presentation modes are defined: **Pull (verifier-initiated retrieval).** The verifier dereferences the passport's `id` URL or `adl_document` URL via HTTPS. No presentation proof is required: the TLS authority that served the document at its canonical URL is the binding, and §1.1.3's URL-equals-document check is sufficient. **Push (presenter-initiated request).** The presenter attaches the passport and a presentation proof to its outgoing request. The proof **MUST** cover the request being made. For HTTP-based push, the presenter **SHOULD** use the following header convention: * `ADL-Passport`: Base64-encoded passport bytes (YAML or JSON). * `ADL-Passport-URL`: Alternative to `ADL-Passport`. Canonical URL the verifier may dereference to retrieve the passport. When both are present, the verifier **MUST** prefer dereferencing. * `ADL-Proof`: Base64-encoded presentation proof JSON. For non-HTTP transports, the presentation proof **MUST** be carried in a transport-appropriate analog (for example, an A2A `proof` field alongside the `passport` field). #### 1.2.6 Verification Procedure[​](#126-verification-procedure "Direct link to 1.2.6 Verification Procedure") ![Two-path comparison converging on one verifier. On the left, an attacker replays a scraped, valid, signed passport alone; because the attacker lacks the agent\'s private key the replay carries no per-request proof, and the verifier rejects it — replay defeated. On the right, the legitimate agent presents the same passport together with a presentation proof: a per-request object binding the passport id (iss) to the request method and canonical URI, an issued-at and short expiry, and a unique jti, all signed by the agent\'s private key. The verifier\'s §1.2.6 checks — issuer match, temporal validity within five minutes, request binding, signature against the passport key, and replay prevention via the jti cache — accept the bound request. The proof binds the passport to one request URI, method, timestamp, and jti, signed by the key the attacker does not have.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA5MDAgNTYwIiB3aWR0aD0iOTAwIiBoZWlnaHQ9IjU2MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsbGVkYnk9InBwLXRpdGxlIHBwLWRlc2MiIGZvbnQtZmFtaWx5PSItYXBwbGUtc3lzdGVtLCBCbGlua01hY1N5c3RlbUZvbnQsICdTZWdvZSBVSScsIEhlbHZldGljYSwgQXJpYWwsIHNhbnMtc2VyaWYiPgogIDx0aXRsZSBpZD0icHAtdGl0bGUiPlByZXNlbnRhdGlvbiBwcm9vZjogYSBwZXItcmVxdWVzdCBzaWduYXR1cmUgYmluZHMgdGhlIHBhc3Nwb3J0IHRvIG9uZSByZXF1ZXN0LCBkZWZlYXRpbmcgcmVwbGF5PC90aXRsZT4KICA8ZGVzYyBpZD0icHAtZGVzYyI+QSB0d28tcGF0aCBjb21wYXJpc29uIGNvbnZlcmdpbmcgb24gb25lIHZlcmlmaWVyLiBQYXNzcG9ydHMgYXJlIG5vdCBzZWNyZXQsIHNvIGFuIGF0dGFja2VyIGNhbiBvYnRhaW4gYSBjb21wbGV0ZSwgdmFsaWQsIHNpZ25lZCBwYXNzcG9ydC4gT24gdGhlIGxlZnQsIHRoZSBhdHRhY2tlciByZXBsYXlzIGEgc2NyYXBlZCBwYXNzcG9ydCBhbG9uZTogaXQgY2FycmllcyBubyBwZXItcmVxdWVzdCBwcm9vZiBiZWNhdXNlIHRoZSBhdHRhY2tlciBsYWNrcyB0aGUgYWdlbnQncyBwcml2YXRlIGtleS4gVGhlIHZlcmlmaWVyIHJlamVjdHMgaXQuIE9uIHRoZSByaWdodCwgdGhlIGxlZ2l0aW1hdGUgYWdlbnQgcHJlc2VudHMgdGhlIHNhbWUgcGFzc3BvcnQgdG9nZXRoZXIgd2l0aCBhIHByZXNlbnRhdGlvbiBwcm9vZiDigJQgYSBwZXItcmVxdWVzdCBvYmplY3QgYmluZGluZyB0aGUgcGFzc3BvcnQgaWQgKGlzcykgdG8gdGhlIHJlcXVlc3QgbWV0aG9kIGFuZCBjYW5vbmljYWwgVVJJLCBhbiBpc3N1ZWQtYXQgYW5kIHNob3J0IGV4cGlyeSwgYW5kIGEgdW5pcXVlIGp0aSwgYWxsIHNpZ25lZCBieSB0aGUgYWdlbnQncyBwcml2YXRlIGtleS4gVGhlIHZlcmlmaWVyIGNoZWNrcyBpc3N1ZXIgbWF0Y2gsIHRlbXBvcmFsIHZhbGlkaXR5IHdpdGhpbiBmaXZlIG1pbnV0ZXMsIHJlcXVlc3QgYmluZGluZywgdGhlIHNpZ25hdHVyZSBhZ2FpbnN0IHRoZSBwYXNzcG9ydCBrZXksIGFuZCByZXBsYXkgcHJldmVudGlvbiB2aWEgdGhlIGp0aSBjYWNoZSwgYW5kIGFjY2VwdHMgdGhlIHJlcXVlc3QuIFRoZSBwcm9vZiBiaW5kcyBwYXNzcG9ydCB0byBhIHNwZWNpZmljIHJlcXVlc3QgVVJJLCBtZXRob2QsIHRpbWVzdGFtcCwgYW5kIGp0aSwgc2lnbmVkIGJ5IHRoZSBwcml2YXRlIGtleSB0aGUgYXR0YWNrZXIgZG9lcyBub3QgaGF2ZS48L2Rlc2M+CgogIDxkZWZzPgogICAgPG1hcmtlciBpZD0icHAtYXIiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPgogICAgICA8cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIGZpbGw9IiMzMzQxNTUiLz4KICAgIDwvbWFya2VyPgogICAgPG1hcmtlciBpZD0icHAtYXItcmVkIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj4KICAgICAgPHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBmaWxsPSIjYzUyMjFmIi8+CiAgICA8L21hcmtlcj4KICAgIDxtYXJrZXIgaWQ9InBwLWFyLWdyZWVuIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj4KICAgICAgPHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBmaWxsPSIjMTM3MzMzIi8+CiAgICA8L21hcmtlcj4KICA8L2RlZnM+CgogIDxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSI5MDAiIGhlaWdodD0iNTYwIiBmaWxsPSIjZmZmZmZmIi8+CgogIDwhLS0gVGl0bGUgLS0+CiAgPHRleHQgeD0iNDUwIiB5PSIzNCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIyMCIgZm9udC13ZWlnaHQ9IjcwMCIgZmlsbD0iIzBmMTcyYSI+UHJlc2VudGF0aW9uIFByb29mICYjODIxMjsgUmVwbGF5IEJpbmRpbmc8L3RleHQ+CiAgPHRleHQgeD0iNDUwIiB5PSI1NiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxMyIgZm9udC1zdHlsZT0iaXRhbGljIiBmaWxsPSIjNDc1NTY5Ij5BIHBlci1yZXF1ZXN0IHNpZ25hdHVyZSBiaW5kcyB0aGUgcGFzc3BvcnQgdG8gb25lIHJlcXVlc3Q7IGEgc2NyYXBlZCBwYXNzcG9ydCBhbG9uZSBpcyByZWplY3RlZCAoJiMxNjc7MS4yKTwvdGV4dD4KCiAgPCEtLSBjb2x1bW4gaGVhZGVycyAtLT4KICA8dGV4dCB4PSIyMTAiIHk9IjkyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjEyLjUiIGZvbnQtd2VpZ2h0PSI3MDAiIGZpbGw9IiNhNTBlMGUiPlRocmVhdDogcmVwbGF5ZWQgcGFzc3BvcnQ8L3RleHQ+CiAgPHRleHQgeD0iNjkwIiB5PSI5MiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxMi41IiBmb250LXdlaWdodD0iNzAwIiBmaWxsPSIjMGQ2NTJkIj5MZWdpdGltYXRlOiBwYXNzcG9ydCArIHByb29mPC90ZXh0PgoKICA8IS0tID09PT09PT09PT09PT09PT09PT09PSBMRUZUOiBhdHRhY2tlciA9PT09PT09PT09PT09PT09PT09PT0gLS0+CiAgPHJlY3QgeD0iNzAiIHk9IjEwOCIgd2lkdGg9IjI4MCIgaGVpZ2h0PSI2MCIgcng9IjEwIiBmaWxsPSIjZmNlOGU2IiBzdHJva2U9IiNjNTIyMWYiIHN0cm9rZS13aWR0aD0iMS41Ii8+CiAgPHRleHQgeD0iMjEwIiB5PSIxMzIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTIiIGZvbnQtd2VpZ2h0PSI3MDAiIGZpbGw9IiNhNTBlMGUiPmF0dGFja2VyPC90ZXh0PgogIDx0ZXh0IHg9IjIxMCIgeT0iMTUwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjkuNSIgZmlsbD0iIzFmMjkzNyI+aG9sZHMgYSBzY3JhcGVkLCB2YWxpZCwgc2lnbmVkIHBhc3Nwb3J0PC90ZXh0PgogIDx0ZXh0IHg9IjIxMCIgeT0iMTYyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjkuNSIgZm9udC1zdHlsZT0iaXRhbGljIiBmaWxsPSIjYTUwZTBlIj5idXQgbm90IHRoZSBwcml2YXRlIGtleTwvdGV4dD4KCiAgPCEtLSBzY3JhcGVkIHBhc3Nwb3J0IHRva2VuIC0tPgogIDxyZWN0IHg9IjEyMCIgeT0iMjA2IiB3aWR0aD0iMTgwIiBoZWlnaHQ9IjU4IiByeD0iOCIgZmlsbD0iI2ZmZjdlNiIgc3Ryb2tlPSIjZjU5ZTBiIiBzdHJva2Utd2lkdGg9IjEuNSIvPgogIDx0ZXh0IHg9IjIxMCIgeT0iMjI4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjExIiBmb250LXdlaWdodD0iNzAwIiBmaWxsPSIjYjQ1MzA5Ij5wYXNzcG9ydCAoY29waWVkKTwvdGV4dD4KICA8dGV4dCB4PSIyMTAiIHk9IjI0NiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSI5IiBmaWxsPSIjMWYyOTM3Ij52YWxpZCBieXRlcywgdmFsaWQgc2lnbmF0dXJlPC90ZXh0PgogIDx0ZXh0IHg9IjIxMCIgeT0iMjU4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjkiIGZvbnQtc3R5bGU9Iml0YWxpYyIgZmlsbD0iI2E1MGUwZSI+bm8gcGVyLXJlcXVlc3QgcHJvb2Y8L3RleHQ+CgogIDxsaW5lIHgxPSIyMTAiIHkxPSIxNjgiIHgyPSIyMTAiIHkyPSIyMDQiIHN0cm9rZT0iIzMzNDE1NSIgc3Ryb2tlLXdpZHRoPSIxLjQiIG1hcmtlci1lbmQ9InVybCgjcHAtYXIpIi8+CiAgPGxpbmUgeDE9IjIxMCIgeTE9IjI2NCIgeDI9IjIxMCIgeTI9IjMxOCIgc3Ryb2tlPSIjYzUyMjFmIiBzdHJva2Utd2lkdGg9IjEuNSIgbWFya2VyLWVuZD0idXJsKCNwcC1hci1yZWQpIi8+CiAgPHJlY3QgeD0iMTYwIiB5PSIyODQiIHdpZHRoPSIxMDAiIGhlaWdodD0iMTUiIGZpbGw9IiNmZmZmZmYiLz4KICA8dGV4dCB4PSIyMTAiIHk9IjI5NiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSI5LjUiIGZpbGw9IiNhNTBlMGUiPnJlcGxheSBhdHRlbXB0PC90ZXh0PgoKICA8IS0tID09PT09PT09PT09PT09PT09PT09PSBSSUdIVDogbGVnaXRpbWF0ZSBhZ2VudCA9PT09PT09PT09PT09PT09PT09PT0gLS0+CiAgPHJlY3QgeD0iNTUwIiB5PSIxMDgiIHdpZHRoPSIyODAiIGhlaWdodD0iNjAiIHJ4PSIxMCIgZmlsbD0iI2U2ZjRlYSIgc3Ryb2tlPSIjMTM3MzMzIiBzdHJva2Utd2lkdGg9IjEuNSIvPgogIDx0ZXh0IHg9IjY5MCIgeT0iMTMyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjEyIiBmb250LXdlaWdodD0iNzAwIiBmaWxsPSIjMGQ2NTJkIj50aGUgYWdlbnQ8L3RleHQ+CiAgPHRleHQgeD0iNjkwIiB5PSIxNTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iOS41IiBmaWxsPSIjMWYyOTM3Ij5ob2xkcyB0aGUgcGFzc3BvcnQgYW5kIGl0cyBwcml2YXRlIGtleTwvdGV4dD4KICA8dGV4dCB4PSI2OTAiIHk9IjE2MiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSI5LjUiIGZvbnQtc3R5bGU9Iml0YWxpYyIgZmlsbD0iIzBkNjUyZCI+c2lnbnMgYSBmcmVzaCBwcm9vZiBwZXIgcmVxdWVzdDwvdGV4dD4KCiAgPCEtLSBwYXNzcG9ydCArIHByb29mIHRva2VuIC0tPgogIDxyZWN0IHg9IjU2MCIgeT0iMTkwIiB3aWR0aD0iMjYwIiBoZWlnaHQ9IjkyIiByeD0iOCIgZmlsbD0iI2ZmZjdlNiIgc3Ryb2tlPSIjZjU5ZTBiIiBzdHJva2Utd2lkdGg9IjEuNSIvPgogIDx0ZXh0IHg9IjY5MCIgeT0iMjEwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjExIiBmb250LXdlaWdodD0iNzAwIiBmaWxsPSIjYjQ1MzA5Ij5wYXNzcG9ydCArIHByZXNlbnRhdGlvbiBwcm9vZjwvdGV4dD4KICA8bGluZSB4MT0iNTcyIiB5MT0iMjE4IiB4Mj0iODA4IiB5Mj0iMjE4IiBzdHJva2U9IiNmM2Q4YTgiIHN0cm9rZS13aWR0aD0iMSIvPgogIDxnIGZvbnQtc2l6ZT0iOSIgZmlsbD0iIzFmMjkzNyI+CiAgICA8dGV4dCB4PSI1NzIiIHk9IjIzNCI+aXNzID0gcGFzc3BvcnQgaWQgJiMxODM7IHJlcXVlc3Q6IG1ldGhvZCArIFVSSTwvdGV4dD4KICAgIDx0ZXh0IHg9IjU3MiIgeT0iMjQ4Ij5pYXQgJiMxODM7IGV4cCAoJiM4ODA0OyA1IG1pbikgJiMxODM7IGp0aSAodW5pcXVlKTwvdGV4dD4KICAgIDx0ZXh0IHg9IjU3MiIgeT0iMjYyIiBmb250LXdlaWdodD0iNzAwIiBmaWxsPSIjMGQ2NTJkIj5zaWduYXR1cmUgYnkgdGhlIGFnZW50J3MgcHJpdmF0ZSBrZXk8L3RleHQ+CiAgICA8dGV4dCB4PSI1NzIiIHk9IjI3NiIgZm9udC1zdHlsZT0iaXRhbGljIiBmaWxsPSIjNDc1NTY5Ij5iaW5kcyB0aGlzIHBhc3Nwb3J0IHRvIHRoaXMgb25lIHJlcXVlc3Q8L3RleHQ+CiAgPC9nPgoKICA8bGluZSB4MT0iNjkwIiB5MT0iMTY4IiB4Mj0iNjkwIiB5Mj0iMTg4IiBzdHJva2U9IiMzMzQxNTUiIHN0cm9rZS13aWR0aD0iMS40IiBtYXJrZXItZW5kPSJ1cmwoI3BwLWFyKSIvPgogIDxsaW5lIHgxPSI2OTAiIHkxPSIyODIiIHgyPSI2OTAiIHkyPSIzMTgiIHN0cm9rZT0iIzEzNzMzMyIgc3Ryb2tlLXdpZHRoPSIxLjUiIG1hcmtlci1lbmQ9InVybCgjcHAtYXItZ3JlZW4pIi8+CiAgPHJlY3QgeD0iNjQ4IiB5PSIyOTEiIHdpZHRoPSI4NCIgaGVpZ2h0PSIxNSIgZmlsbD0iI2ZmZmZmZiIvPgogIDx0ZXh0IHg9IjY5MCIgeT0iMzAzIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjkuNSIgZmlsbD0iIzBkNjUyZCI+Ym91bmQgcmVxdWVzdDwvdGV4dD4KCiAgPCEtLSA9PT09PT09PT09PT09PT09PT09PT0gVkVSSUZJRVIgKGNlbnRlciBib3R0b20pID09PT09PT09PT09PT09PT09PT09PSAtLT4KICA8cmVjdCB4PSIzMDAiIHk9IjMyMCIgd2lkdGg9IjMwMCIgaGVpZ2h0PSIxMTgiIHJ4PSIxMCIgZmlsbD0iI2Y4ZmFmYyIgc3Ryb2tlPSIjMWE3M2U4IiBzdHJva2Utd2lkdGg9IjEuNzUiLz4KICA8dGV4dCB4PSI0NTAiIHk9IjM0NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxMyIgZm9udC13ZWlnaHQ9IjcwMCIgZmlsbD0iIzBiNTdkMCI+dmVyaWZpZXIgJiMxODM7ICYjMTY3OzEuMi42IGNoZWNrczwvdGV4dD4KICA8ZyBmb250LXNpemU9IjkuNSIgZmlsbD0iIzFmMjkzNyI+CiAgICA8dGV4dCB4PSIzMTgiIHk9IjM2NiI+aXNzdWVyIG1hdGNoIChpc3MgPSBpZCkgJiMxODM7IHRlbXBvcmFsICgmIzg4MDQ7IDUgbWluKTwvdGV4dD4KICAgIDx0ZXh0IHg9IjMxOCIgeT0iMzgyIj5yZXF1ZXN0IGJpbmRpbmcgKG1ldGhvZCArIFVSSSkgJiMxODM7IHNpZ25hdHVyZSAocGFzc3BvcnQga2V5KTwvdGV4dD4KICAgIDx0ZXh0IHg9IjMxOCIgeT0iMzk4Ij5yZXBsYXkgcHJldmVudGlvbiAmIzgyMTI7IGp0aSBzZWVuIGJlZm9yZT8gcmVqZWN0PC90ZXh0PgogIDwvZz4KICA8bGluZSB4MT0iMzE4IiB5MT0iNDA4IiB4Mj0iNTgyIiB5Mj0iNDA4IiBzdHJva2U9IiNjYmQ1ZTEiIHN0cm9rZS13aWR0aD0iMSIvPgogIDx0ZXh0IHg9IjQ1MCIgeT0iNDI2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjkuNSIgZm9udC1zdHlsZT0iaXRhbGljIiBmaWxsPSIjNDc1NTY5Ij5ubyB2YWxpZCBwcm9vZiAmIzg2NTg7IG5vIGF1dGhlbnRpY2F0ZWQgcmVxdWVzdDwvdGV4dD4KCiAgPCEtLSBsZWZ0IHBhdGggaW50byB2ZXJpZmllciAtLT4KICA8bGluZSB4MT0iMjEwIiB5MT0iMzE4IiB4Mj0iMjEwIiB5Mj0iMzYwIiBzdHJva2U9IiNjNTIyMWYiIHN0cm9rZS13aWR0aD0iMS41Ii8+CiAgPGxpbmUgeDE9IjIxMCIgeTE9IjM2MCIgeDI9IjI5OCIgeTI9IjM2MCIgc3Ryb2tlPSIjYzUyMjFmIiBzdHJva2Utd2lkdGg9IjEuNSIgbWFya2VyLWVuZD0idXJsKCNwcC1hci1yZWQpIi8+CiAgPCEtLSByaWdodCBwYXRoIGludG8gdmVyaWZpZXIgLS0+CiAgPGxpbmUgeDE9IjY5MCIgeTE9IjMxOCIgeDI9IjY5MCIgeTI9IjM4MCIgc3Ryb2tlPSIjMTM3MzMzIiBzdHJva2Utd2lkdGg9IjEuNSIvPgogIDxsaW5lIHgxPSI2OTAiIHkxPSIzODAiIHgyPSI2MDIiIHkyPSIzODAiIHN0cm9rZT0iIzEzNzMzMyIgc3Ryb2tlLXdpZHRoPSIxLjUiIG1hcmtlci1lbmQ9InVybCgjcHAtYXItZ3JlZW4pIi8+CgogIDwhLS0gb3V0Y29tZXMgLS0+CiAgPHJlY3QgeD0iMTIwIiB5PSI0NzAiIHdpZHRoPSIxODAiIGhlaWdodD0iNDQiIHJ4PSIxMCIgZmlsbD0iI2ZjZThlNiIgc3Ryb2tlPSIjYzUyMjFmIiBzdHJva2Utd2lkdGg9IjEuNzUiLz4KICA8dGV4dCB4PSIyMTAiIHk9IjQ5MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxMiIgZm9udC13ZWlnaHQ9IjcwMCIgZmlsbD0iI2E1MGUwZSI+UkVKRUNURUQ8L3RleHQ+CiAgPHRleHQgeD0iMjEwIiB5PSI1MDUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iOSIgZmlsbD0iIzFmMjkzNyI+cmVwbGF5IGRlZmVhdGVkPC90ZXh0PgogIDxsaW5lIHgxPSIzMjAiIHkxPSI0MzgiIHgyPSIyNDgiIHkyPSI0NjgiIHN0cm9rZT0iI2M1MjIxZiIgc3Ryb2tlLXdpZHRoPSIxLjUiIG1hcmtlci1lbmQ9InVybCgjcHAtYXItcmVkKSIvPgoKICA8cmVjdCB4PSI2MDAiIHk9IjQ3MCIgd2lkdGg9IjE4MCIgaGVpZ2h0PSI0NCIgcng9IjEwIiBmaWxsPSIjZTZmNGVhIiBzdHJva2U9IiMxMzczMzMiIHN0cm9rZS13aWR0aD0iMS43NSIvPgogIDx0ZXh0IHg9IjY5MCIgeT0iNDkwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjEyIiBmb250LXdlaWdodD0iNzAwIiBmaWxsPSIjMGQ2NTJkIj5BQ0NFUFRFRDwvdGV4dD4KICA8dGV4dCB4PSI2OTAiIHk9IjUwNSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSI5IiBmaWxsPSIjMWYyOTM3Ij5yZXF1ZXN0IGF1dGhlbnRpY2F0ZWQ8L3RleHQ+CiAgPGxpbmUgeDE9IjU4MCIgeTE9IjQzOCIgeDI9IjY1MiIgeTI9IjQ2OCIgc3Ryb2tlPSIjMTM3MzMzIiBzdHJva2Utd2lkdGg9IjEuNSIgbWFya2VyLWVuZD0idXJsKCNwcC1hci1ncmVlbikiLz4KCiAgPCEtLSBmb290bm90ZSAtLT4KICA8dGV4dCB4PSI0NTAiIHk9IjU0NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxMSIgZm9udC1zdHlsZT0iaXRhbGljIiBmaWxsPSIjNDc1NTY5Ij5UaGUgcHJvb2YgYmluZHMgcGFzc3BvcnQgJiM4NTk0OyByZXF1ZXN0IFVSSSArIG1ldGhvZCArIHRpbWVzdGFtcCArIGp0aSwgc2lnbmVkIGJ5IHRoZSBrZXkgdGhlIGF0dGFja2VyIGxhY2tzLiBJbGx1c3RyYXRpdmU7ICYjMTY3OzEuMiBpcyBhdXRob3JpdGF0aXZlLjwvdGV4dD4KPC9zdmc+Cg==) *Figure (informative): A scraped passport is replayable; a passport bound to a per-request proof is not. The proof binds the passport to a specific request and is signed by the private key an attacker lacks, so a replayed passport without a fresh proof is rejected. This figure is illustrative; the §1.2.6 steps below are authoritative.* After §1.1 succeeds, the verifier **MUST** perform the following checks. They are gated: failure of an earlier check halts the procedure. **§1.2.6.1 Proof Document Parsing.** Decode and parse the proof. A document that is not valid JSON, or that is missing any REQUIRED member from §1.2.2, **MUST** be rejected. **§1.2.6.2 Issuer Match.** The proof's `iss` **MUST** equal the passport's `id`. A mismatch indicates the proof was constructed for a different passport and **MUST** result in rejection. **§1.2.6.3 Temporal Validity.** The current time **MUST** lie between `iat - skew` and `exp + skew`, where `skew` is the value defined in §1.2.8. Additionally, `exp - iat` **MUST NOT** exceed 5 minutes; proofs that declare longer lifetimes **MUST** be rejected. **§1.2.6.4 Request Binding.** The proof's `request.method` **MUST** equal the actual request's HTTP method (compared case-insensitively, normalized to uppercase). The proof's `request.uri`, after the canonicalization in §1.2.4, **MUST** equal the canonicalized form of the actual request URI. Mismatch **MUST** result in rejection. **§1.2.6.5 Signature Verification.** The signature **MUST** verify against the JCS-canonical bytes of the proof with its `signature` object removed, using the verification key established by §1.1.4 / §1.1.5 (the same key used to verify the passport itself). Signature failure **MUST** result in rejection. **§1.2.6.6 Replay Prevention.** The verifier **MUST** maintain a cache of recently observed `jti` values, scoped to the verifier instance, with a TTL no shorter than the maximum proof lifetime (5 minutes). If the proof's `jti` is found in the cache, the proof **MUST** be rejected. Otherwise, the verifier **MUST** insert the `jti` into the cache before treating the request as authenticated. **§1.2.6.7 Nonce Verification (when applicable).** If the verifier has issued a nonce per §1.2.7 and the proof includes a `nonce` member, the value **MUST** match the issued nonce. If the verifier requires a nonce (high-security mode) and the proof omits it, the proof **MUST** be rejected. #### 1.2.7 Server-Issued Nonces[​](#127-server-issued-nonces "Direct link to 1.2.7 Server-Issued Nonces") A verifier **MAY** require that proofs include a server-issued nonce, providing stronger guarantees than time-based replay prevention alone. When this mode is enabled: * The verifier issues a nonce via a `WWW-Authenticate: ADL nonce="…"` challenge on a `401 Unauthorized` response, or via a separate challenge endpoint. * The presenter retrieves the nonce, includes it in the next proof's `nonce` member, and re-issues the request. * The verifier accepts the nonce only once and only within a configured TTL. Nonces are **OPTIONAL** in the base specification. Deployments handling `restricted` data classification (§10.1) **SHOULD** require nonces. #### 1.2.8 Clock Skew Tolerance[​](#128-clock-skew-tolerance "Direct link to 1.2.8 Clock Skew Tolerance") The default skew tolerance **MUST** be 60 seconds. Implementations **MAY** make this configurable but **MUST NOT** default to a value greater than 5 minutes. #### 1.2.9 Outcome Recording[​](#129-outcome-recording "Direct link to 1.2.9 Outcome Recording") The §1.1.10 verification outcome **MUST** be extended to record the result of each §1.2.6 step using the same step-result shape, with section values `"1.2.6.1"` through `"1.2.6.7"`. The aggregate outcome's `verified` flag **MUST** require all §1.1 and §1.2 block-severity steps to pass. #### 1.2.10 Backward Compatibility and Optional Enforcement[​](#1210-backward-compatibility-and-optional-enforcement "Direct link to 1.2.10 Backward Compatibility and Optional Enforcement") To allow incremental adoption: * Implementations **MAY** provide a `require_proof` configuration flag (default: `false` for backward compatibility, **RECOMMENDED**: `true` for production). * When `require_proof` is `false` and a proof is absent, §1.2 step results **MUST** be recorded with `severity: "warn"` and `passed: true` carrying the detail `"presentation proof not provided"`. The aggregate outcome remains `verified` based on §1.1 alone. * When `require_proof` is `true` and a proof is absent, the verifier **MUST** reject the request with a missing-proof step at §1.2.6.1, severity `"block"`. ## 2 Authorization (Enforcement Procedures)[​](#2-authorization-enforcement-procedures "Direct link to 2 Authorization (Enforcement Procedures)") Authentication (§1) establishes *who* a counterparty is. Authorization establishes *what they may do*. The scope *declarations* an agent advertises — `security.scopes` and `tools[*].security.scopes`, together with their inheritance and override rules — are defined in [ADL Core §10.4.1–§10.4.2](/spec/next#104-authorization-scopes). This section defines the *enforcement procedures* a verifier applies to those declarations, uniformly across both authentication paths defined in §1. ### 2.1 Authorization in Human-to-Agent Flows[​](#21-authorization-in-human-to-agent-flows "Direct link to 2.1 Authorization in Human-to-Agent Flows") When the calling party authenticates via §10.3.3 (OAuth 2.1, OIDC, mTLS, or API key), the agent **MUST** authorize the request as follows: 1. **Authenticate first.** §10.3.3 credential validation **MUST** succeed before scope evaluation. Authentication failure short-circuits with a `401 Unauthorized` response (or transport-equivalent) and **MUST NOT** leak which scopes the request was missing. 2. **Extract presented scopes.** For OAuth 2.1 / OIDC, parse the `scope` claim of the access token. For API keys with an out-of-band scope binding, look up the scope set associated with the key. For mTLS, extract scopes from the client certificate (e.g., from a Subject Alternative Name extension or an external attribute store). 3. **Determine required scopes for the requested operation.** * For requests that target a specific tool, required = `tools[i].security.scopes` if declared, else `security.scopes`. * For requests that target the agent in general (e.g., capability discovery, status), required = `security.scopes`. 4. **Authorize.** The request is authorized iff every member of the required set is present in the presented set. Implementations **MAY** evaluate scope membership case-sensitively (recommended) or per the deployment's OAuth 2.1 server policy. 5. **Reject with structured error.** When authorization fails, respond with HTTP `403 Forbidden` and a `WWW-Authenticate: Bearer error="insufficient_scope", scope=""` header per \[RFC6750] §3, and **MUST NOT** leak any data the client was attempting to access. This procedure is unchanged from standard OAuth 2.1 resource-server behavior; ADL's contribution is only the declarative `tools[*].security.scopes` override semantics. ### 2.2 Authorization in Agent-to-Agent Flows[​](#22-authorization-in-agent-to-agent-flows "Direct link to 2.2 Authorization in Agent-to-Agent Flows") When the calling party is itself an ADL agent authenticating via §1.1 (passport) and §1.2 (presentation proof), the agent **MUST** authorize the request as follows: 1. **Authenticate first.** §1.1 verification and §1.2.6 proof verification **MUST** succeed before scope evaluation. Authentication failure short-circuits per §1.1.10 / §1.2.9. 2. **Establish the presenter's scope ceiling.** The ceiling is the calling agent's passport `security.scopes`. The ceiling represents the maximum capability the calling agent can ever assert, signed by the calling agent's key as part of the passport (§10.2 attestation). 3. **Extract requested scopes from the proof.** Read the `scopes` member of the presentation proof (§1.2.2). When omitted, the requested scope set is empty. 4. **Verify ceiling subset.** The proof's `scopes` array **MUST** be a subset of the calling agent's passport `security.scopes` ceiling. A request whose proof asserts a scope outside the ceiling **MUST** be rejected at this step. This is the agent-to-agent analog of OAuth 2.1's authorization-server-issued scope: the passport-attested ceiling is the agent's standing grant, and the proof is its per-request attestation of which slice of that grant it is exercising. 5. **Determine required scopes for the requested operation.** Identical to §2.1 step 3 — tool override or root default. 6. **Authorize.** The request is authorized iff every member of the required set is present in the proof's `scopes` set. 7. **Reject with structured error.** When authorization fails, the rejection **MUST** identify the missing scopes in the structured outcome (§1.1.10 + §1.2.9) and **MAY** include them in a transport-level error response, scoped to information the calling agent already has the right to see. The proof's signature (§1.2.6.5) covers the `scopes` array as part of the canonical bytes, so the requested scope set is sender-constrained: a third party that intercepts the proof cannot replay it with an expanded scope set. ### 2.3 Composition Across Boundaries (Multi-Hop Authorization)[​](#23-composition-across-boundaries-multi-hop-authorization "Direct link to 2.3 Composition Across Boundaries (Multi-Hop Authorization)") When a human-authenticated request arrives at Agent A and Agent A subsequently calls upstream Agent B on the human's behalf, two independent authorizations occur: ![UML sequence diagram of multi-hop authorization with three lifelines: Human, Agent A, and Agent B. Step 1, the human sends a request to Agent A carrying an OAuth token with scope S\_h. Step 2, Agent A authorizes the human under §2.1, requiring its required\_A scopes to be a subset of S\_h. Step 3, Agent A invokes upstream Agent B, presenting its passport and a presentation proof carrying scope S\_a. Step 4, Agent B authorizes Agent A under §2.2: first a ceiling check that the proof scopes are a subset of Agent A\'s passport scopes, then that Agent B\'s required\_B scopes are a subset of the proof scopes. Step 5, Agent B returns a result to Agent A; step 6, Agent A returns a result to the human. A closing note states the two authorizations are independent: Agent A\'s outbound scope S\_a is bounded only by its passport ceiling, not by S\_h, and each hop keeps its own audit record so no single hop sees the whole chain.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA5MDAgNTgwIiB3aWR0aD0iOTAwIiBoZWlnaHQ9IjU4MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsbGVkYnk9Im1oLXRpdGxlIG1oLWRlc2MiIGZvbnQtZmFtaWx5PSItYXBwbGUtc3lzdGVtLCBCbGlua01hY1N5c3RlbUZvbnQsICdTZWdvZSBVSScsIEhlbHZldGljYSwgQXJpYWwsIHNhbnMtc2VyaWYiPgogIDx0aXRsZSBpZD0ibWgtdGl0bGUiPk11bHRpLWhvcCBhdXRob3JpemF0aW9uOiB0d28gaW5kZXBlbmRlbnQgYXV0aG9yaXphdGlvbnMgYWNyb3NzIGEgaG9wIGJvdW5kYXJ5PC90aXRsZT4KICA8ZGVzYyBpZD0ibWgtZGVzYyI+QSBVTUwgc2VxdWVuY2UgZGlhZ3JhbSB3aXRoIHRocmVlIGxpZmVsaW5lczogSHVtYW4sIEFnZW50IEEsIGFuZCBBZ2VudCBCLiBTdGVwIDEsIHRoZSBodW1hbiBzZW5kcyBhIHJlcXVlc3QgdG8gQWdlbnQgQSBjYXJyeWluZyBhbiBPQXV0aCB0b2tlbiB3aXRoIHNjb3BlIFNfaC4gU3RlcCAyLCBBZ2VudCBBIGF1dGhvcml6ZXMgdGhlIGh1bWFuIHVuZGVyIMKnMi4xLCByZXF1aXJpbmcgaXRzIHJlcXVpcmVkX0Egc2NvcGVzIHRvIGJlIGEgc3Vic2V0IG9mIFNfaC4gU3RlcCAzLCBBZ2VudCBBIGludm9rZXMgdXBzdHJlYW0gQWdlbnQgQiwgcHJlc2VudGluZyBpdHMgcGFzc3BvcnQgYW5kIGEgcHJlc2VudGF0aW9uIHByb29mIGNhcnJ5aW5nIHNjb3BlIFNfYS4gU3RlcCA0LCBBZ2VudCBCIGF1dGhvcml6ZXMgQWdlbnQgQSB1bmRlciDCpzIuMjogZmlyc3QgYSBjZWlsaW5nIGNoZWNrIHRoYXQgdGhlIHByb29mIHNjb3BlcyBhcmUgYSBzdWJzZXQgb2YgQWdlbnQgQSdzIHBhc3Nwb3J0IHNjb3BlcywgdGhlbiB0aGF0IEFnZW50IEIncyByZXF1aXJlZF9CIHNjb3BlcyBhcmUgYSBzdWJzZXQgb2YgdGhlIHByb29mIHNjb3Blcy4gU3RlcCA1LCBBZ2VudCBCIHJldHVybnMgYSByZXN1bHQgdG8gQWdlbnQgQTsgc3RlcCA2LCBBZ2VudCBBIHJldHVybnMgYSByZXN1bHQgdG8gdGhlIGh1bWFuLiBBIGNsb3Npbmcgbm90ZSBzdGF0ZXMgdGhlIHR3byBhdXRob3JpemF0aW9ucyBhcmUgaW5kZXBlbmRlbnQ6IEFnZW50IEEncyBvdXRib3VuZCBzY29wZSBTX2EgaXMgYm91bmRlZCBvbmx5IGJ5IGl0cyBwYXNzcG9ydCBjZWlsaW5nLCBub3QgYnkgU19oLCBhbmQgZWFjaCBob3Aga2VlcHMgaXRzIG93biBhdWRpdCByZWNvcmQgc28gbm8gc2luZ2xlIGhvcCBzZWVzIHRoZSB3aG9sZSBjaGFpbi48L2Rlc2M+CgogIDxkZWZzPgogICAgPG1hcmtlciBpZD0ibWgtYXIiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPgogICAgICA8cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIGZpbGw9IiMzMzQxNTUiLz4KICAgIDwvbWFya2VyPgogIDwvZGVmcz4KCiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjkwMCIgaGVpZ2h0PSI1ODAiIGZpbGw9IiNmZmZmZmYiLz4KCiAgPCEtLSBUaXRsZSAtLT4KICA8dGV4dCB4PSI0NTAiIHk9IjM0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjIwIiBmb250LXdlaWdodD0iNzAwIiBmaWxsPSIjMGYxNzJhIj5NdWx0aS1Ib3AgQXV0aG9yaXphdGlvbjwvdGV4dD4KICA8dGV4dCB4PSI0NTAiIHk9IjU2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjEzIiBmb250LXN0eWxlPSJpdGFsaWMiIGZpbGw9IiM0NzU1NjkiPlR3byBpbmRlcGVuZGVudCBhdXRob3JpemF0aW9ucyBhY3Jvc3MgYSBob3AgYm91bmRhcnkgJiM4MjEyOyBIdW1hbiAmIzg1OTQ7IEFnZW50IEEgJiM4NTk0OyBBZ2VudCBCICgmIzE2NzsyLjMpPC90ZXh0PgoKICA8IS0tIGxpZmVsaW5lcyAtLT4KICA8bGluZSB4MT0iMTMwIiB5MT0iMTE2IiB4Mj0iMTMwIiB5Mj0iNDUyIiBzdHJva2U9IiNjYmQ1ZTEiIHN0cm9rZS13aWR0aD0iMS4yNSIgc3Ryb2tlLWRhc2hhcnJheT0iNCA0Ii8+CiAgPGxpbmUgeDE9IjQ1MCIgeTE9IjExNiIgeDI9IjQ1MCIgeTI9IjQ1MiIgc3Ryb2tlPSIjY2JkNWUxIiBzdHJva2Utd2lkdGg9IjEuMjUiIHN0cm9rZS1kYXNoYXJyYXk9IjQgNCIvPgogIDxsaW5lIHgxPSI3NzAiIHkxPSIxMTYiIHgyPSI3NzAiIHkyPSI0NTIiIHN0cm9rZT0iI2NiZDVlMSIgc3Ryb2tlLXdpZHRoPSIxLjI1IiBzdHJva2UtZGFzaGFycmF5PSI0IDQiLz4KCiAgPCEtLSBwYXJ0aWNpcGFudCBib3hlcyAtLT4KICA8cmVjdCB4PSI2NSIgeT0iNzgiIHdpZHRoPSIxMzAiIGhlaWdodD0iMzYiIHJ4PSI4IiBmaWxsPSIjZThmMGZlIiBzdHJva2U9IiMxYTczZTgiIHN0cm9rZS13aWR0aD0iMS41Ii8+CiAgPHRleHQgeD0iMTMwIiB5PSIxMDEiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTMiIGZvbnQtd2VpZ2h0PSI3MDAiIGZpbGw9IiMwYjU3ZDAiPkh1bWFuPC90ZXh0PgogIDxyZWN0IHg9IjM4NSIgeT0iNzgiIHdpZHRoPSIxMzAiIGhlaWdodD0iMzYiIHJ4PSI4IiBmaWxsPSIjZThmMGZlIiBzdHJva2U9IiMxYTczZTgiIHN0cm9rZS13aWR0aD0iMS41Ii8+CiAgPHRleHQgeD0iNDUwIiB5PSIxMDEiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTMiIGZvbnQtd2VpZ2h0PSI3MDAiIGZpbGw9IiMwYjU3ZDAiPkFnZW50IEE8L3RleHQ+CiAgPHJlY3QgeD0iNzA1IiB5PSI3OCIgd2lkdGg9IjEzMCIgaGVpZ2h0PSIzNiIgcng9IjgiIGZpbGw9IiNlOGYwZmUiIHN0cm9rZT0iIzFhNzNlOCIgc3Ryb2tlLXdpZHRoPSIxLjUiLz4KICA8dGV4dCB4PSI3NzAiIHk9IjEwMSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxMyIgZm9udC13ZWlnaHQ9IjcwMCIgZmlsbD0iIzBiNTdkMCI+QWdlbnQgQjwvdGV4dD4KCiAgPCEtLSBsZWdlbmQgKGluIHRoZSBjbGVhciBnYXAgYmV0d2VlbiBBZ2VudCBBIGFuZCBBZ2VudCBCIGhlYWRlcnMpIC0tPgogIDxsaW5lIHgxPSI1NDAiIHkxPSI5NiIgeDI9IjU2NiIgeTI9Ijk2IiBzdHJva2U9IiMzMzQxNTUiIHN0cm9rZS13aWR0aD0iMS41IiBtYXJrZXItZW5kPSJ1cmwoI21oLWFyKSIvPgogIDx0ZXh0IHg9IjU3MiIgeT0iMTAwIiBmb250LXNpemU9IjEwLjUiIGZpbGw9IiM2NDc0OGIiPmNhbGw8L3RleHQ+CiAgPGxpbmUgeDE9IjYxNiIgeTE9Ijk2IiB4Mj0iNjQyIiB5Mj0iOTYiIHN0cm9rZT0iIzMzNDE1NSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1kYXNoYXJyYXk9IjUgMyIgbWFya2VyLWVuZD0idXJsKCNtaC1hcikiLz4KICA8dGV4dCB4PSI2NDgiIHk9IjEwMCIgZm9udC1zaXplPSIxMC41IiBmaWxsPSIjNjQ3NDhiIj5yZXR1cm48L3RleHQ+CgogIDwhLS0gYWN0aXZhdGlvbiBiYXJzIC0tPgogIDxyZWN0IHg9IjQ0NCIgeT0iMTQ0IiB3aWR0aD0iMTIiIGhlaWdodD0iMjkyIiBmaWxsPSIjZDJlM2ZjIiBzdHJva2U9IiMxYTczZTgiIHN0cm9rZS13aWR0aD0iMC45Ii8+CiAgPHJlY3QgeD0iNzY0IiB5PSIyNTIiIHdpZHRoPSIxMiIgaGVpZ2h0PSIxMzIiIGZpbGw9IiNkMmUzZmMiIHN0cm9rZT0iIzFhNzNlOCIgc3Ryb2tlLXdpZHRoPSIwLjkiLz4KCiAgPCEtLSAoMSkgSHVtYW4gLT4gQWdlbnQgQSAtLT4KICA8dGV4dCB4PSIyODciIHk9IjE0MiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxMSIgZmlsbD0iIzFmMjkzNyI+KDEpIHJlcXVlc3QgJiMxODM7IE9BdXRoIHRva2VuLCBzY29wZSBTX2g8L3RleHQ+CiAgPGxpbmUgeDE9IjEzMCIgeTE9IjE1MCIgeDI9IjQ0MiIgeTI9IjE1MCIgc3Ryb2tlPSIjMzM0MTU1IiBzdHJva2Utd2lkdGg9IjEuNSIgbWFya2VyLWVuZD0idXJsKCNtaC1hcikiLz4KCiAgPCEtLSAoMikgwqcyLjEgYXV0aG9yaXplIGh1bWFuIChBZ2VudCBBJ3MgZGVjaXNpb24pOyBjZW50ZXJlZCBpbiB0aGUgSHVtYW48LT5BIGd1dHRlciAobWlkIHg9MjkwKSwgYmFsYW5jZWQgcGFkZGluZyAtLT4KICA8cmVjdCB4PSIxOTgiIHk9IjE2NyIgd2lkdGg9IjE4NCIgaGVpZ2h0PSI1MCIgcng9IjgiIGZpbGw9IiNmZmY3ZTYiIHN0cm9rZT0iI2Y1OWUwYiIgc3Ryb2tlLXdpZHRoPSIxLjQiLz4KICA8dGV4dCB4PSIyMTYiIHk9IjE4OCIgZm9udC1zaXplPSIxMC41IiBmb250LXdlaWdodD0iNzAwIiBmaWxsPSIjYjQ1MzA5Ij4oMikgJiMxNjc7Mi4xICYjODIxMjsgYXV0aG9yaXplIGh1bWFuPC90ZXh0PgogIDx0ZXh0IHg9IjIxNiIgeT0iMjA3IiBmb250LXNpemU9IjEwLjUiIGZpbGw9IiMxZjI5MzciPnJlcXVpcmVkX0EgJiM4ODM4OyBTX2g8L3RleHQ+CgogIDwhLS0gKDMpIEFnZW50IEEgLT4gQWdlbnQgQiAtLT4KICA8dGV4dCB4PSI2MTAiIHk9IjI1MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxMSIgZmlsbD0iIzFmMjkzNyI+KDMpIGludm9rZSB1cHN0cmVhbSAmIzE4MzsgcGFzc3BvcnQgKyBwcm9vZiwgc2NvcGUgU19hPC90ZXh0PgogIDxsaW5lIHgxPSI0NTYiIHkxPSIyNTgiIHgyPSI3NjIiIHkyPSIyNTgiIHN0cm9rZT0iIzMzNDE1NSIgc3Ryb2tlLXdpZHRoPSIxLjUiIG1hcmtlci1lbmQ9InVybCgjbWgtYXIpIi8+CgogIDwhLS0gKDQpIMKnMi4yIGF1dGhvcml6ZSBBZ2VudCBBIChBZ2VudCBCJ3MgZGVjaXNpb24pOyBjZW50ZXJlZCBpbiB0aGUgQTwtPkIgZ3V0dGVyIChtaWQgeD02MTApLCBiYWxhbmNlZCBwYWRkaW5nIC0tPgogIDxyZWN0IHg9IjQ4MyIgeT0iMjc3IiB3aWR0aD0iMjU0IiBoZWlnaHQ9IjcyIiByeD0iOCIgZmlsbD0iI2ZmZjdlNiIgc3Ryb2tlPSIjZjU5ZTBiIiBzdHJva2Utd2lkdGg9IjEuNCIvPgogIDx0ZXh0IHg9IjUwMSIgeT0iMjk3IiBmb250LXNpemU9IjEwLjUiIGZvbnQtd2VpZ2h0PSI3MDAiIGZpbGw9IiNiNDUzMDkiPig0KSAmIzE2NzsyLjIgJiM4MjEyOyBhdXRob3JpemUgQWdlbnQgQTwvdGV4dD4KICA8dGV4dCB4PSI1MDEiIHk9IjMxNiIgZm9udC1zaXplPSIxMCIgZmlsbD0iIzFmMjkzNyI+MSAmIzE4MzsgY2VpbGluZzogcHJvb2Yuc2NvcGVzICYjODgzODsgQS5wYXNzcG9ydC5zY29wZXM8L3RleHQ+CiAgPHRleHQgeD0iNTAxIiB5PSIzMzUiIGZvbnQtc2l6ZT0iMTAiIGZpbGw9IiMxZjI5MzciPjIgJiMxODM7IHJlcXVpcmVkX0IgJiM4ODM4OyBwcm9vZi5zY29wZXM8L3RleHQ+CgogIDwhLS0gKDUpIEFnZW50IEIgLS0+IEFnZW50IEEgKHJldHVybikgLS0+CiAgPHRleHQgeD0iNjEwIiB5PSIzNzYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTEiIGZpbGw9IiMxZjI5MzciPig1KSByZXN1bHQ8L3RleHQ+CiAgPGxpbmUgeDE9Ijc2NCIgeTE9IjM4NCIgeDI9IjQ1OCIgeTI9IjM4NCIgc3Ryb2tlPSIjMzM0MTU1IiBzdHJva2Utd2lkdGg9IjEuNSIgc3Ryb2tlLWRhc2hhcnJheT0iNiA0IiBtYXJrZXItZW5kPSJ1cmwoI21oLWFyKSIvPgoKICA8IS0tICg2KSBBZ2VudCBBIC0tPiBIdW1hbiAocmV0dXJuKSAtLT4KICA8dGV4dCB4PSIyODciIHk9IjQyOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxMSIgZmlsbD0iIzFmMjkzNyI+KDYpIHJlc3VsdDwvdGV4dD4KICA8bGluZSB4MT0iNDQ0IiB5MT0iNDM2IiB4Mj0iMTMyIiB5Mj0iNDM2IiBzdHJva2U9IiMzMzQxNTUiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtZGFzaGFycmF5PSI2IDQiIG1hcmtlci1lbmQ9InVybCgjbWgtYXIpIi8+CgogIDwhLS0gc3Bhbm5pbmcgdGFrZWF3YXkgbm90ZSAtLT4KICA8cmVjdCB4PSI3MCIgeT0iNDYyIiB3aWR0aD0iNzYwIiBoZWlnaHQ9IjU0IiByeD0iMTAiIGZpbGw9IiNmOGZhZmMiIHN0cm9rZT0iI2NiZDVlMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNCIvPgogIDx0ZXh0IHg9Ijg2IiB5PSI0ODQiIGZvbnQtc2l6ZT0iMTEiIGZpbGw9IiMxZjI5MzciPlR3byBpbmRlcGVuZGVudCBhdXRob3JpemF0aW9ucyAmIzgyMTI7IEFnZW50IEEncyBvdXRib3VuZCBzY29wZSBTX2EgaXMgYm91bmRlZCBvbmx5IGJ5IGl0cyBwYXNzcG9ydCBjZWlsaW5nLDwvdGV4dD4KICA8dGV4dCB4PSI4NiIgeT0iNTAyIiBmb250LXNpemU9IjExIiBmaWxsPSIjMWYyOTM3Ij5ub3QgYnkgU19oICYjODIxMjsgYW5kIGVhY2ggaG9wIGtlZXBzIGl0cyBvd24gYXVkaXQgcmVjb3JkLCBzbyBubyBzaW5nbGUgaG9wIHNlZXMgdGhlIHdob2xlIGNoYWluLjwvdGV4dD4KCiAgPCEtLSBmb290bm90ZSAtLT4KICA8dGV4dCB4PSI0NTAiIHk9IjU0NiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxMC41IiBmb250LXN0eWxlPSJpdGFsaWMiIGZpbGw9IiM0NzU1NjkiPlRoZSAmIzE2NzsyLjEgLyAmIzE2NzsyLjIgY2hlY2tzIHJ1biBpZGVudGljYWxseSBldmVyeSB0aW1lIChkZXRlcm1pbmlzdGljKTsgd2hpY2ggY291bnRlcnBhcnR5IHRoZSBhZ2VudCBkaXNjb3ZlcnMsIGFuZCBpbiB3aGF0IG9yZGVyLCBpcyBlbWVyZ2VudC48L3RleHQ+CiAgPHRleHQgeD0iNDUwIiB5PSI1NjIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTAuNSIgZm9udC1zdHlsZT0iaXRhbGljIiBmaWxsPSIjNDc1NTY5Ij5PbmUgcmVwcmVzZW50YXRpdmUgdHJhY2UuIElsbHVzdHJhdGl2ZTsgJiMxNjc7Mi4xJiM4MjExOyYjMTY3OzIuMyBhcmUgYXV0aG9yaXRhdGl2ZS48L3RleHQ+Cjwvc3ZnPgo=) *Figure: The two independent authorizations across the hop boundary — §2.1 (human → Agent A) and §2.2 (Agent A → Agent B). This is one representative trace: the §2.1/§2.2 checks run identically every time, while the agent's discovery of which counterparty to call is emergent.* The two authorizations are **independent**: * The human's scope set `S_h` authorizes the request *to* Agent A. It is not, by default, propagated upstream. * Agent A's outbound scope set `S_a` is constrained only by Agent A's own passport ceiling — not by `S_h`. * Agent B authorizes Agent A purely on the basis of `S_a` and `required_B`. Agent B does not (and cannot, without additional mechanism) see `S_h`. Implementations **MAY** apply additional per-hop policy. The two common patterns: * **Independent (default).** Each hop's authorization is its own decision. Recommended for most deployments. Audit MUST record both authorizations. * **Reduction (delegated).** Agent A computes `S_a = S_a_max ∩ map(S_h)` where `S_a_max` is its passport ceiling and `map(...)` projects human-scope vocabulary to upstream-scope vocabulary. This is conceptually equivalent to OAuth 2.1 Token Exchange \[RFC8693] with `actor_token` set to Agent A's passport. Implementations that adopt this pattern **MUST** document the mapping and **MUST** record the source human scopes in the audit trail. In all cases, implementations **MUST** maintain an audit record per hop containing: the inbound credential's scopes, the tool invoked, the required scopes, and the outcome. The audit chain reconstructs end-to-end authority even though no single hop sees the entire chain. ### 2.4 Effective Scope Computation[​](#24-effective-scope-computation "Direct link to 2.4 Effective Scope Computation") For a single authorization decision at any hop: ``` required = tools[i].security.scopes if declared, else security.scopes presented = OAuth token scopes ∪ proof.scopes ∪ out-of-band binding for key/cert (whichever applies) effective = required ∩ presented authorized = (required ⊆ presented) ``` When `authorized` is false, `(required \ presented)` (set difference) gives the missing-scope list returned in the structured error. For agent-to-agent specifically, the additional ceiling check is: ``` ceiling = caller_passport.security.scopes ceiling_satisfied = (proof.scopes ⊆ ceiling) ``` A request fails authorization if `ceiling_satisfied` is false, even when `authorized` would be true. The ceiling check **MUST** run before the required-scope check; an out-of-ceiling request is a misbehavior that the verifier **MUST** distinguish from an insufficient-scope request in audit logs. ### 2.5 Composition with §1 Authentication[​](#25-composition-with-1-authentication "Direct link to 2.5 Composition with §1 Authentication") Authorization (§2) **MUST** be evaluated only after authentication (§1) succeeds. The relationship is strictly layered: | Step | What it establishes | | --------------------------- | ------------------------------------------------------------------------------ | | §1.1 Verification Procedure | The passport is authentic and the calling identity is who it claims | | §1.2 Presentation Proof | The current request is bound to that identity right now | | §10.3.3 Credential Schemes | An OAuth 2.1 / OIDC / mTLS / API-key bearer is present (for non-agent callers) | | §2 Authorization Scopes | The authenticated party may perform this specific operation | A failure at any §1 step **MUST** prevent §2 evaluation. Conversely, §2 success without §1 success is a defect — implementations **MUST NOT** authorize requests against unauthenticated identities, even when the requested scope set looks sufficient. This is the OAuth 2.1 `unauthenticated → no scope decision` invariant carried into the agent-to-agent path. ### 2.6 Examples[​](#26-examples "Direct link to 2.6 Examples") **Root + per-tool override:** ``` { "security": { "scopes": ["invoices:read", "invoices:write"] }, "tools": [ { "name": "list_invoices", "security": { "scopes": ["invoices:read"] } }, { "name": "approve_invoice", "security": { "scopes": ["invoices:write", "invoices:approve"] } }, { "name": "search_help", "security": { "scopes": [] } } ] } ``` `list_invoices` narrows the root requirement to read-only. `approve_invoice` adds a tool-specific `invoices:approve` scope beyond the root. `search_help` explicitly requires no scopes (e.g., a public help search). **Agent-to-agent presentation proof carrying scopes:** ``` { "adl_proof": "1.0", "iss": "https://agents.acme.example/finance-bot", "iat": "2026-05-06T14:30:00Z", "exp": "2026-05-06T14:35:00Z", "jti": "01HW8YQ7K9X2N3T4M5R6S7V8W9", "request": { "method": "POST", "uri": "https://agents.acme.example/invoice-processor/tools/approve_invoice" }, "scopes": ["invoices:write", "invoices:approve"], "signature": { "algorithm": "Ed25519", "value": "...", "signed_content": "canonical" } } ``` The verifier (`invoice-processor`) checks that `["invoices:write", "invoices:approve"]` is a subset of `finance-bot`'s passport ceiling, then checks that the `approve_invoice` tool's required scopes are a subset of those, then proxies the call. *** ## IANA Considerations[​](#iana-considerations "Direct link to IANA Considerations") This document requests the registrations below, following \[RFC8126] and the HTTP registration procedures of \[RFC9110]. ### HTTP Authentication Scheme[​](#http-authentication-scheme "Direct link to HTTP Authentication Scheme") IANA is requested to add the following entry to the "Hypertext Transfer Protocol (HTTP) Authentication Scheme Registry" (\[RFC9110] §16.4.1): | Authentication Scheme Name | Reference | | -------------------------- | --------------------- | | `ADL` | This document, §1.2.7 | The `ADL` scheme appears only in a `WWW-Authenticate` challenge, carrying a single verifier-issued `nonce` auth-param (`WWW-Authenticate: ADL nonce="…"`) on a `401 Unauthorized` response; the presenter echoes the value in the presentation proof's `nonce` member (§1.2.7). It does not define an `Authorization`-header credential. ### HTTP Field Names[​](#http-field-names "Direct link to HTTP Field Names") IANA is requested to add the following entries to the "Hypertext Transfer Protocol (HTTP) Field Name Registry" (\[RFC9110] §16.3.1): | Field Name | Status | Reference | | ------------------ | --------- | --------------------- | | `ADL-Passport` | permanent | This document, §1.2.5 | | `ADL-Passport-URL` | permanent | This document, §1.2.5 | | `ADL-Proof` | permanent | This document, §1.2.5 | > **Note (\[RFC6648]).** These field names omit the deprecated `X-` prefix, per \[RFC6648]. ADL has no deployed base that used `X-`-prefixed forms, so the unprefixed names are registered directly and no `X-` aliases are defined. No media type is registered by this document. The passport is conveyed base64-encoded in `ADL-Passport` (or dereferenced via `ADL-Passport-URL`) and validated against the ADL JSON Schema; the presentation proof is conveyed base64-encoded in `ADL-Proof` and validated against the structure in §1.2.2. ## Security Considerations[​](#security-considerations "Direct link to Security Considerations") This section consolidates the security properties and residual risks of the §1 authentication and §2 authorization procedures. The presentation-proof threat model (§1.2.1) and the no-leak authorization rules (§2.1) are normative where stated; this section summarizes them and adds operational guidance. **Passports are public; presentation proofs are not optional.** A passport is not secret (§1.2.1): an attacker may obtain a complete, valid, signed passport from a discovery endpoint, a registry, or network capture. Authentication of a *request* therefore **MUST** rely on the per-request presentation proof (§1.2), which binds the passport to the request method, URI, time window, and `jti` under a signature the attacker cannot produce. Accepting a passport without a fresh proof (outside the §1.2.10 waivers) re-opens the replay vector the proof exists to close. **did:web trust anchor.** When identity is resolved via `did:web` (§1.1.3, \[W3C.DID-WEB]), the verification key is only as trustworthy as the TLS and DNS for the DID's domain: whoever controls `https://{domain}/.well-known/did.json` controls the key. Compromise of the domain, its TLS certificate, or its DNS permits key substitution. Verifiers **SHOULD** pin or monitor did:web keys for high-value counterparties and **MUST** apply the §1.1.8 provider-coherence checks. An unsigned or URN-only document remains Trust-On-First-Use (§1.1.3) and **MUST NOT** be elevated above the trust of the channel that delivered it. **Replay-cache integrity and exhaustion.** Replay prevention (§1.2.6.6) requires a `jti` cache with a TTL at least the maximum proof lifetime. Two operational hazards follow. (1) *Distribution:* the cache is scoped to the verifier instance; a horizontally-scaled verifier whose instances do not share the cache can accept the same `jti` once per instance within the window. Deployments that scale a logical verifier across instances **SHOULD** use a shared or replicated `jti` store, or restrict the freshness guarantee to single-instance verifiers and rely on server-issued nonces (§1.2.7) for stronger binding. (2) *Exhaustion:* an attacker can flood the cache with distinct `jti` values; verifiers **SHOULD** bound cache size, rate-limit unauthenticated presentations, and use the proof's short `exp` (≤ 5 minutes, §1.2.3) as the eviction horizon. **Clock skew.** The bounded skew tolerance (§1.2.8; default 60 s, maximum 5 min) limits the window in which a captured proof could be replayed before the `jti` cache is consulted; deployments **MUST NOT** widen it beyond the §1.2.8 maximum. **No information leakage on failure.** Authorization failures **MUST** return only the structured outcome and **MUST NOT** leak data the caller was attempting to access (§2.1); the `WWW-Authenticate: Bearer error="insufficient_scope"` response (\[RFC6750]) names missing scopes only to the extent the caller is already entitled to know them. **Algorithm agility.** Signatures are verified over the JCS canonicalization of \[RFC8785] with Ed25519 RECOMMENDED; verifiers **MUST** reject weak or unknown signature algorithms (per the ADL Core cryptographic floors) rather than downgrading. ## References[​](#references "Direct link to References") ### Normative References[​](#normative-references "Direct link to Normative References") * **\[RFC2119]** Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, . * **\[RFC3986]** Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform Resource Identifier (URI): Generic Syntax", STD 66, RFC 3986, . * **\[RFC6648]** Saint-Andre, P., Crocker, D., and M. Nottingham, "Deprecating the 'X-' Prefix and Similar Constructs in Application Protocols", BCP 178, RFC 6648, . * **\[RFC6750]** Jones, M. and D. Hardt, "The OAuth 2.0 Authorization Framework: Bearer Token Usage", RFC 6750, . * **\[RFC8126]** Cotton, M., Leiba, B., and T. Narten, "Guidelines for Writing an IANA Considerations Section in RFCs", BCP 26, RFC 8126, . * **\[RFC8174]** Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, . * **\[RFC8785]** Rundgren, A., Jordan, B., and S. Erdtman, "JSON Canonicalization Scheme (JCS)", RFC 8785, . * **\[RFC9110]** Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., "HTTP Semantics", STD 97, RFC 9110, . * **\[W3C.DID-WEB]** Guy, A., et al., "did:web Method Specification", W3C Credentials Community Group, . * **\[ADL-CORE]** Nederveld, T., "Agent Definition Language (ADL)", the Core document of this specification family; see [/spec](/spec/.md). ### Informative References[​](#informative-references "Direct link to Informative References") * **\[RFC8693]** Jones, M., Nadalin, A., Campbell, B., Ed., Bradley, J., and C. Mortimore, "OAuth 2.0 Token Exchange", RFC 8693, . * **\[RFC9449]** Fett, D., Campbell, B., Bradley, J., Lodderstedt, T., Jones, M., and D. Waite, "OAuth 2.0 Demonstrating Proof of Possession (DPoP)", RFC 9449, . --- # Agent Definition Language Specification | | | | ----------------- | ---------------------------------------------------------------------------- | | **Version** | 0.3.0 | | **Status** | Posted | | **Patent Status** | Patent Pending (US Provisional Application No. 63/985,186, filed 2026-02-18) | ## 1. Introduction[​](#1-introduction "Direct link to 1. Introduction") ### 1.1 Purpose[​](#11-purpose "Direct link to 1.1 Purpose") The Agent Definition Language (ADL) provides a standard format for describing AI agents. ADL documents are JSON objects that describe an agent's identity, capabilities, tools, permissions, and runtime requirements. This specification describes the structure of ADL documents, the semantics of their members, and conformance requirements for implementations. ADL serves a similar role for AI agents that OpenAPI serves for REST APIs, AsyncAPI for event-driven architectures, and WSDL for web services. It enables: * **Discovery:** Agents can find other agents and assess their fit for the task at hand. * **Interoperability:** Agents can interact with tools, resources, and other agents using a common description format. * **Deployment:** Runtime environments can provision and configure agents based on declared requirements. * **Security:** Permission boundaries and security requirements are explicitly declared, and given force at admission and at runtime by the protocol layer (see the Trust and Runtime Protocols). * **Lifecycle:** Agents can be versioned, tracked through operational states, and managed across their entire lifecycle from draft to retirement. * **Accountability:** A runtime governor enforces declared limits — budgets, iteration, sub-agent admission, oversight, and degradation — and can produce verifiable evidence that it did (see the Runtime Protocol). ### 1.2 Goals[​](#12-goals "Direct link to 1.2 Goals") * **Portable:** ADL documents describe agents independent of any specific runtime, platform, or provider. * **Interoperable:** ADL documents can be transformed into other formats (A2A Agent Cards, MCP configurations) and consumed by diverse tooling. * **Extensible:** ADL supports profiles that add domain-specific requirements without changing the core specification. * **Secure:** Permission boundaries, authentication, and security constraints are first-class concepts. * **Machine-readable:** ADL documents are validated against JSON Schema and can be processed programmatically. * **Human-friendly:** Clear naming conventions and structures that are easy to read and author. ### 1.3 Design Model[​](#13-design-model "Direct link to 1.3 Design Model") An ADL document **describes** an AI agent — its identity, capabilities, permissions, security posture, and governance signals. From that description an agent distills a **passport**: the compact credential it carries and presents so a counterparty — peer agent, gateway, orchestrator, registry, or human operator — can make a trust decision without first resolving the full document. The passport model establishes two principles: 1. **Self-contained trust signals.** The passport **MUST** carry enough information for a counterparty to decide whether to interact with the agent and whether to act on its requests, without requiring access to external systems. 2. **Separation of declaration from operations.** Operational detail that changes independently of the agent's declared behavior — escalation contacts, audit schedules, evaluation reports, deployment logs — belongs in external records (e.g., a governance record in a registry), not in the passport. Profiles **MAY** define linking members (e.g., `governance_record_ref`) that reference such records by stable URI. This separation ensures that: * The passport remains compact, so it can travel on every agent-to-agent and agent-to-gateway exchange. * Operational changes (personnel rotation, policy updates) do not require re-issuing the passport. * Internal operational detail is not exposed to external counterparties. ADL separates declaration from procedure across a family of documents built around this passport: * **ADL Core** (this document) is the single declarative document — what an agent *is* and the limits it declares. * The **protocol layer** is an open set of procedural documents, each defining what an actor **MUST** do with those declarations. Two are defined today: the **ADL Trust Protocol** (a *counterparty* verifying a passport and authorizing agent-to-agent calls) and the **ADL Runtime Protocol** (a *runtime governor* enforcing declared operational limits during execution). Core declares; the protocols enforce. A declared limit has force only when a protocol procedure acts on it. The protocol layer admits further documents as new enforcement boundaries emerge. ![Component diagram of the ADL document family. A DECLARE region at the top holds the ADL Core (identity, capabilities, limits, lifecycle), which derives the Agent Passport, a declared and signed artifact. A dashed declare-versus-enforce boundary separates it from the ENFORCE region (the protocol layer) below, holding the Trust Protocol (admission-time verification and authorization), the Runtime Protocol (a continuous governor performing enforcement and evidence), and a dashed open-layer slot for future protocols such as discovery, reputation, and settlement. The passport is consumed by the Trust Protocol at admission and by the Runtime Protocol at runtime, and is available to the open-layer slot in future. The Runtime Protocol produces an Enforcement Evidence hash-chained record.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA4MjAgNzQwIiB3aWR0aD0iODIwIiBoZWlnaHQ9Ijc0MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsbGVkYnk9ImRmYS10aXRsZSBkZmEtZGVzYyIgZm9udC1mYW1pbHk9Ii1hcHBsZS1zeXN0ZW0sIEJsaW5rTWFjU3lzdGVtRm9udCwgJ1NlZ29lIFVJJywgSGVsdmV0aWNhLCBBcmlhbCwgc2Fucy1zZXJpZiI+CiAgPHRpdGxlIGlkPSJkZmEtdGl0bGUiPkFETCBkb2N1bWVudCBmYW1pbHk6IENvcmUgZGVjbGFyZXM7IHRoZSBwcm90b2NvbHMgZW5mb3JjZTwvdGl0bGU+CiAgPGRlc2MgaWQ9ImRmYS1kZXNjIj5BIHR3by1yZWdpb24gY29tcG9uZW50IGRpYWdyYW0uIEEgREVDTEFSRSByZWdpb24gYXQgdGhlIHRvcCBjb250YWlucyB0aGUgQURMIENvcmUgKGlkZW50aXR5LCBjYXBhYmlsaXRpZXMsIGxpbWl0cywgbGlmZWN5Y2xlKSwgd2hpY2ggZGVyaXZlcyB0aGUgQWdlbnQgUGFzc3BvcnQsIGEgZGVjbGFyZWQgYW5kIHNpZ25lZCBhcnRpZmFjdCBzdGFja2VkIGRpcmVjdGx5IGJlbmVhdGggaXQuIEEgZGFzaGVkIGRlY2xhcmUtdmVyc3VzLWVuZm9yY2UgYm91bmRhcnkgc2VwYXJhdGVzIGl0IGZyb20gdGhlIEVORk9SQ0UgcmVnaW9uICh0aGUgcHJvdG9jb2wgbGF5ZXIpIGJlbG93LCB3aGljaCBjb250YWlucyB0aGUgVHJ1c3QgUHJvdG9jb2wgKGFkbWlzc2lvbi10aW1lIHZlcmlmaWNhdGlvbiBhbmQgYXV0aG9yaXphdGlvbiksIHRoZSBSdW50aW1lIFByb3RvY29sIChhIGNvbnRpbnVvdXMgZ292ZXJub3IgcGVyZm9ybWluZyBlbmZvcmNlbWVudCBhbmQgZXZpZGVuY2UpLCBhbmQgYSBkYXNoZWQgb3Blbi1sYXllciBzbG90IGZvciBmdXR1cmUgcHJvdG9jb2xzIHN1Y2ggYXMgZGlzY292ZXJ5LCByZXB1dGF0aW9uLCBhbmQgc2V0dGxlbWVudC4gRnJvbSBhIHNpbmdsZSBodWIgcG9pbnQsIHRoZSBwYXNzcG9ydCBmYW5zIG91dCBhcyBldmVubHkgc3BhY2VkIHNwb2tlczogY29uc3VtZWQgYnkgdGhlIFRydXN0IFByb3RvY29sIGF0IGFkbWlzc2lvbiwgYnkgdGhlIFJ1bnRpbWUgUHJvdG9jb2wgYXQgcnVudGltZSwgYW5kIGF2YWlsYWJsZSB0byB0aGUgb3Blbi1sYXllciBzbG90IGluIGZ1dHVyZS4gVGhlIFJ1bnRpbWUgUHJvdG9jb2wgcHJvZHVjZXMgYW4gRW5mb3JjZW1lbnQgRXZpZGVuY2UgaGFzaC1jaGFpbmVkIHJlY29yZC48L2Rlc2M+CgogIDxkZWZzPgogICAgPG1hcmtlciBpZD0iZGZhLWFycm93IiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj4KICAgICAgPHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBmaWxsPSIjMzM0MTU1Ii8+CiAgICA8L21hcmtlcj4KICAgIDxtYXJrZXIgaWQ9ImRmYS1hcnJvdy1vcGVuIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj4KICAgICAgPHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBmaWxsPSIjOTRhM2I4Ii8+CiAgICA8L21hcmtlcj4KICA8L2RlZnM+CgogIDxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSI4MjAiIGhlaWdodD0iNzQwIiBmaWxsPSIjZmZmZmZmIi8+CgogIDwhLS0gVGl0bGUgLS0+CiAgPHRleHQgeD0iNDEwIiB5PSIzOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIyMCIgZm9udC13ZWlnaHQ9IjcwMCIgZmlsbD0iIzBmMTcyYSI+QURMIERvY3VtZW50IEZhbWlseTwvdGV4dD4KICA8dGV4dCB4PSI0MTAiIHk9IjYwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjEzIiBmb250LXN0eWxlPSJpdGFsaWMiIGZpbGw9IiM0NzU1NjkiPkNvcmUgZGVjbGFyZXM7IHRoZSBwcm90b2NvbHMgZW5mb3JjZTwvdGV4dD4KCiAgPCEtLSBERUNMQVJFIHJlZ2lvbiAtLT4KICA8cmVjdCB4PSIzMCIgeT0iODIiIHdpZHRoPSI3NjAiIGhlaWdodD0iMjY4IiByeD0iMTAiIGZpbGw9IiNmOGZhZmMiIHN0cm9rZT0iI2NiZDVlMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNCIvPgogIDx0ZXh0IHg9IjUwIiB5PSIxMDQiIGZvbnQtc2l6ZT0iMTIiIGZvbnQtd2VpZ2h0PSI3MDAiIGZpbGw9IiM0NzU1NjkiIGxldHRlci1zcGFjaW5nPSIxIj5ERUNMQVJFPC90ZXh0PgoKICA8IS0tIEFETCBDb3JlIGJveCAodG9wIG9mIHN0YWNrLCBjZW50ZXJlZCBvbiB4PTQxMCkgLS0+CiAgPHJlY3QgeD0iMjgwIiB5PSIxMDAiIHdpZHRoPSIyNjAiIGhlaWdodD0iODYiIHJ4PSI4IiBmaWxsPSIjZThmMGZlIiBzdHJva2U9IiMxYTczZTgiIHN0cm9rZS13aWR0aD0iMS41Ii8+CiAgPHRleHQgeD0iNDEwIiB5PSIxMzIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTUiIGZvbnQtd2VpZ2h0PSI3MDAiIGZpbGw9IiMwYjU3ZDAiPkFETCBDb3JlPC90ZXh0PgogIDx0ZXh0IHg9IjQxMCIgeT0iMTU0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjExLjUiIGZpbGw9IiMxZjI5MzciPmlkZW50aXR5ICYjMTgzOyBjYXBhYmlsaXRpZXM8L3RleHQ+CiAgPHRleHQgeD0iNDEwIiB5PSIxNzEiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTEuNSIgZmlsbD0iIzFmMjkzNyI+bGltaXRzICYjMTgzOyBsaWZlY3ljbGU8L3RleHQ+CgogIDwhLS0gZGVyaXZlIGFycm93IENvcmUgLT4gUGFzc3BvcnQgKHZlcnRpY2FsKTsgd2lkZXIgZ3V0dGVyIHNvIHRoZSBsaW5lIGFuZCBhcnJvd2hlYWQgcmVhZCBjbGVhcmx5IGFyb3VuZCB0aGUgbGFiZWwgLS0+CiAgPGxpbmUgeDE9IjQxMCIgeTE9IjE4NiIgeDI9IjQxMCIgeTI9IjI0MCIgc3Ryb2tlPSIjMzM0MTU1IiBzdHJva2Utd2lkdGg9IjEuNSIgc3Ryb2tlLWRhc2hhcnJheT0iNSA0IiBtYXJrZXItZW5kPSJ1cmwoI2RmYS1hcnJvdykiLz4KICA8cmVjdCB4PSIzNzgiIHk9IjIwNSIgd2lkdGg9IjY0IiBoZWlnaHQ9IjE2IiBmaWxsPSIjZjhmYWZjIi8+CiAgPHRleHQgeD0iNDEwIiB5PSIyMTYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTAuNSIgZm9udC1zdHlsZT0iaXRhbGljIiBmaWxsPSIjNDc1NTY5Ij4mIzE3MTtkZXJpdmUmIzE4Nzs8L3RleHQ+CgogIDwhLS0gQWdlbnQgUGFzc3BvcnQgYm94IChib3R0b20gb2Ygc3RhY2ssIGNlbnRlcmVkIG9uIHg9NDEwID0gdGhlIGh1YikgLS0+CiAgPHJlY3QgeD0iMjgwIiB5PSIyNDAiIHdpZHRoPSIyNjAiIGhlaWdodD0iODYiIHJ4PSI4IiBmaWxsPSIjZmZmN2U2IiBzdHJva2U9IiNmNTllMGIiIHN0cm9rZS13aWR0aD0iMS41Ii8+CiAgPHRleHQgeD0iNDEwIiB5PSIyNzIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTUiIGZvbnQtd2VpZ2h0PSI3MDAiIGZpbGw9IiNiNDUzMDkiPkFnZW50IFBhc3Nwb3J0PC90ZXh0PgogIDx0ZXh0IHg9IjQxMCIgeT0iMjk0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjExLjUiIGZpbGw9IiMxZjI5MzciPmRlY2xhcmVkIGxpbWl0cywgc2lnbmVkPC90ZXh0PgogIDx0ZXh0IHg9IjQxMCIgeT0iMzExIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjEwLjUiIGZvbnQtc3R5bGU9Iml0YWxpYyIgZmlsbD0iIzZiNzI4MCI+dGhlIGRlY2xhcmVkIGFydGlmYWN0PC90ZXh0PgoKICA8IS0tIGRlY2xhcmUvZW5mb3JjZSBib3VuZGFyeTsgdGhlIGxpbmUgY2FycmllcyAiZW5mb3JjZWQiIHBsdXMgdGhlIHRocmVlIGNyb3NzaW5nIGxhYmVscywgYWxsIGNlbnRlcmVkIG9uIGl0IC0tPgogIDxsaW5lIHgxPSIzMCIgeTE9IjM3MiIgeDI9Ijc5MCIgeTI9IjM3MiIgc3Ryb2tlPSIjNjQ3NDhiIiBzdHJva2Utd2lkdGg9IjEuNzUiIHN0cm9rZS1kYXNoYXJyYXk9IjcgNSIvPgogIDxyZWN0IHg9IjExMiIgeT0iMzYzIiB3aWR0aD0iNzYiIGhlaWdodD0iMTgiIHJ4PSI5IiBmaWxsPSIjZmZmZmZmIiBzdHJva2U9IiM2NDc0OGIiIHN0cm9rZS13aWR0aD0iMSIvPgogIDx0ZXh0IHg9IjE1MCIgeT0iMzc2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjExIiBmb250LXdlaWdodD0iNzAwIiBmaWxsPSIjMzM0MTU1Ij5lbmZvcmNlZDwvdGV4dD4KCiAgPCEtLSBFTkZPUkNFIHJlZ2lvbiAtLT4KICA8cmVjdCB4PSIzMCIgeT0iMzk0IiB3aWR0aD0iNzYwIiBoZWlnaHQ9IjMyMCIgcng9IjEwIiBmaWxsPSIjZjhmYWZjIiBzdHJva2U9IiNjYmQ1ZTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtZGFzaGFycmF5PSI1IDQiLz4KCiAgPCEtLSBUcnVzdCBQcm90b2NvbCAtLT4KICA8cmVjdCB4PSI2MiIgeT0iNDIwIiB3aWR0aD0iMjEwIiBoZWlnaHQ9IjExOCIgcng9IjgiIGZpbGw9IiNlNmY0ZWEiIHN0cm9rZT0iIzEzNzMzMyIgc3Ryb2tlLXdpZHRoPSIxLjUiLz4KICA8dGV4dCB4PSIxNjciIHk9IjQ1MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxNCIgZm9udC13ZWlnaHQ9IjcwMCIgZmlsbD0iIzBkNjUyZCI+VHJ1c3QgUHJvdG9jb2w8L3RleHQ+CiAgPHRleHQgeD0iMTY3IiB5PSI0NzQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTEiIGZpbGw9IiMxZjI5MzciPmFkbWlzc2lvbi10aW1lPC90ZXh0PgogIDx0ZXh0IHg9IjE2NyIgeT0iNDkwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjExIiBmaWxsPSIjMWYyOTM3Ij52ZXJpZmljYXRpb24gJmFtcDs8L3RleHQ+CiAgPHRleHQgeD0iMTY3IiB5PSI1MDYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTEiIGZpbGw9IiMxZjI5MzciPmF1dGhvcml6YXRpb248L3RleHQ+CgogIDwhLS0gUnVudGltZSBQcm90b2NvbCAtLT4KICA8cmVjdCB4PSIzMDUiIHk9IjQyMCIgd2lkdGg9IjIxMCIgaGVpZ2h0PSIxMTgiIHJ4PSI4IiBmaWxsPSIjZmNlOGU2IiBzdHJva2U9IiNjNTIyMWYiIHN0cm9rZS13aWR0aD0iMS41Ii8+CiAgPHRleHQgeD0iNDEwIiB5PSI0NTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTQiIGZvbnQtd2VpZ2h0PSI3MDAiIGZpbGw9IiNhNTBlMGUiPlJ1bnRpbWUgUHJvdG9jb2w8L3RleHQ+CiAgPHRleHQgeD0iNDEwIiB5PSI0NzQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTEiIGZpbGw9IiMxZjI5MzciPmNvbnRpbnVvdXMgZ292ZXJub3I6PC90ZXh0PgogIDx0ZXh0IHg9IjQxMCIgeT0iNDkwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjExIiBmaWxsPSIjMWYyOTM3Ij5lbmZvcmNlbWVudCAmYW1wOzwvdGV4dD4KICA8dGV4dCB4PSI0MTAiIHk9IjUwNiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxMSIgZmlsbD0iIzFmMjkzNyI+ZXZpZGVuY2U8L3RleHQ+CgogIDwhLS0gT3Blbi1sYXllciBzbG90IC0tPgogIDxyZWN0IHg9IjU0OCIgeT0iNDIwIiB3aWR0aD0iMjEwIiBoZWlnaHQ9IjExOCIgcng9IjgiIGZpbGw9IiNmMWYzZjQiIHN0cm9rZT0iIzlhYTBhNiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1kYXNoYXJyYXk9IjYgNCIvPgogIDx0ZXh0IHg9IjY1MyIgeT0iNDUwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjE0IiBmb250LXdlaWdodD0iNzAwIiBmaWxsPSIjNWY2MzY4Ij5PcGVuLWxheWVyIHNsb3Q8L3RleHQ+CiAgPHRleHQgeD0iNjUzIiB5PSI0NzQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTEiIGZpbGw9IiM1ZjYzNjgiPmRpc2NvdmVyeSAmIzE4MzsgcmVwdXRhdGlvbjwvdGV4dD4KICA8dGV4dCB4PSI2NTMiIHk9IjQ5MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxMSIgZmlsbD0iIzVmNjM2OCI+JiMxODM7IHNldHRsZW1lbnQ8L3RleHQ+CiAgPHRleHQgeD0iNjUzIiB5PSI1MTIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTAiIGZvbnQtc3R5bGU9Iml0YWxpYyIgZmlsbD0iIzgwODY4YiI+KGZ1dHVyZSk8L3RleHQ+CgogIDwhLS0gaHViLWFuZC1zcG9rZTogdGhyZWUgZXZlbmx5IGZhbm5lZCBhcnJvd3MgZnJvbSB0aGUgcGFzc3BvcnQgaHViICg0MTAsMzI2KTsgZWFjaCBjcm9zc2luZyBsYWJlbCBpcyBjZW50ZXJlZCBvbiB0aGUgYm91bmRhcnkgbGluZSB3aGVyZSBpdHMgc3Bva2UgcGllcmNlcyBpdCAoeCA9IDI5MSAvIDQxMCAvIDUyOSkgLS0+CiAgPCEtLSBzcG9rZSAtPiBUcnVzdCAoYXQgYWRtaXNzaW9uKSAtLT4KICA8bGluZSB4MT0iNDEwIiB5MT0iMzI2IiB4Mj0iMTY3IiB5Mj0iNDIwIiBzdHJva2U9IiMzMzQxNTUiIHN0cm9rZS13aWR0aD0iMS41IiBtYXJrZXItZW5kPSJ1cmwoI2RmYS1hcnJvdykiLz4KICA8cmVjdCB4PSIyNDUiIHk9IjM2NCIgd2lkdGg9IjkyIiBoZWlnaHQ9IjE2IiBmaWxsPSIjZmZmZmZmIi8+CiAgPHRleHQgeD0iMjkxIiB5PSIzNzYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTAuNSIgZmlsbD0iIzMzNDE1NSI+YXQgYWRtaXNzaW9uPC90ZXh0PgogIDwhLS0gc3Bva2UgLT4gUnVudGltZSAoYXQgcnVudGltZSkgLS0+CiAgPGxpbmUgeDE9IjQxMCIgeTE9IjMyNiIgeDI9IjQxMCIgeTI9IjQyMCIgc3Ryb2tlPSIjMzM0MTU1IiBzdHJva2Utd2lkdGg9IjEuNSIgbWFya2VyLWVuZD0idXJsKCNkZmEtYXJyb3cpIi8+CiAgPHJlY3QgeD0iMzcxIiB5PSIzNjQiIHdpZHRoPSI3OCIgaGVpZ2h0PSIxNiIgZmlsbD0iI2ZmZmZmZiIvPgogIDx0ZXh0IHg9IjQxMCIgeT0iMzc2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjEwLjUiIGZpbGw9IiMzMzQxNTUiPmF0IHJ1bnRpbWU8L3RleHQ+CiAgPCEtLSBzcG9rZSAtPiBPcGVuIChmdXR1cmUpIC0tPgogIDxsaW5lIHgxPSI0MTAiIHkxPSIzMjYiIHgyPSI2NTMiIHkyPSI0MjAiIHN0cm9rZT0iIzk0YTNiOCIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNCIgbWFya2VyLWVuZD0idXJsKCNkZmEtYXJyb3ctb3BlbikiLz4KICA8cmVjdCB4PSI1MDMiIHk9IjM2NCIgd2lkdGg9IjUyIiBoZWlnaHQ9IjE2IiBmaWxsPSIjZmZmZmZmIi8+CiAgPHRleHQgeD0iNTI5IiB5PSIzNzYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTAuNSIgZm9udC1zdHlsZT0iaXRhbGljIiBmaWxsPSIjNjQ3NDhiIj5mdXR1cmU8L3RleHQ+CgogIDwhLS0gUnVudGltZSAtPiBFdmlkZW5jZSAocHJvZHVjZSwgdmVydGljYWwpIC0tPgogIDxsaW5lIHgxPSI0MTAiIHkxPSI1MzgiIHgyPSI0MTAiIHkyPSI1ODAiIHN0cm9rZT0iIzMzNDE1NSIgc3Ryb2tlLXdpZHRoPSIxLjUiIG1hcmtlci1lbmQ9InVybCgjZGZhLWFycm93KSIvPgogIDxyZWN0IHg9IjM3OCIgeT0iNTUxIiB3aWR0aD0iNjQiIGhlaWdodD0iMTUiIGZpbGw9IiNmOGZhZmMiLz4KICA8dGV4dCB4PSI0MTAiIHk9IjU2MiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxMCIgZm9udC1zdHlsZT0iaXRhbGljIiBmaWxsPSIjNDc1NTY5Ij4mIzE3MTtwcm9kdWNlJiMxODc7PC90ZXh0PgoKICA8IS0tIEVuZm9yY2VtZW50IEV2aWRlbmNlIC0tPgogIDxyZWN0IHg9IjMwNSIgeT0iNTgwIiB3aWR0aD0iMjEwIiBoZWlnaHQ9IjgwIiByeD0iOCIgZmlsbD0iI2YzZThmZCIgc3Ryb2tlPSIjODQzMGNlIiBzdHJva2Utd2lkdGg9IjEuNSIvPgogIDx0ZXh0IHg9IjQxMCIgeT0iNjE0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXNpemU9IjEzIiBmb250LXdlaWdodD0iNzAwIiBmaWxsPSIjNmIyMWE4Ij5FbmZvcmNlbWVudCBFdmlkZW5jZTwvdGV4dD4KICA8dGV4dCB4PSI0MTAiIHk9IjYzNSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxMSIgZmlsbD0iIzFmMjkzNyI+aGFzaC1jaGFpbmVkIHJlY29yZDwvdGV4dD4KCiAgPCEtLSBPcGVuLWxheWVyIG5vdGUgLS0+CiAgPHRleHQgeD0iNjUzIiB5PSI2MDAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTAiIGZvbnQtc3R5bGU9Iml0YWxpYyIgZmlsbD0iIzgwODY4YiI+YnVpbGRzIG9uIHRoZSBzYW1lIHBhc3Nwb3J0OzwvdGV4dD4KICA8dGV4dCB4PSI2NTMiIHk9IjYxNCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxMCIgZm9udC1zdHlsZT0iaXRhbGljIiBmaWxsPSIjODA4NjhiIj5ubyBjaGFuZ2UgdG8gdGhlIENvcmU8L3RleHQ+CgogIDwhLS0gRU5GT1JDRSByZWdpb24gbGFiZWwgbW92ZWQgdG8gdGhlIGJvdHRvbSBzbyB0aGUgaW5ib3VuZCBzcG9rZXMgbmV2ZXIgY3Jvc3MgaXQgLS0+CiAgPHRleHQgeD0iNTAiIHk9IjcwMiIgZm9udC1zaXplPSIxMiIgZm9udC13ZWlnaHQ9IjcwMCIgZmlsbD0iIzQ3NTU2OSIgbGV0dGVyLXNwYWNpbmc9IjEiPkVORk9SQ0UgJiMxODM7IFBST1RPQ09MIExBWUVSPC90ZXh0Pgo8L3N2Zz4K) *Figure 1 (informative): The ADL document family. The Core declares the agent passport; the protocol layer enforces it — Trust at admission, Runtime continuously — and is open to future protocols. This figure is illustrative; the normative requirements are stated in the text of this section and the protocol documents.* ### 1.4 Relationship to Other Specifications[​](#14-relationship-to-other-specifications "Direct link to 1.4 Relationship to Other Specifications") ADL builds upon, interoperates with, and draws on: * **JSON \[RFC8259]** — ADL documents are valid JSON. * **JSON Schema \[JSON-SCHEMA]** — ADL documents are validated against JSON Schema; tool parameters use JSON Schema for types. * **A2A Protocol \[A2A]** — ADL documents can generate A2A Agent Cards. * **Model Context Protocol \[MCP]** — ADL documents can generate MCP server configurations; tools, resources, and prompts align with MCP primitives. * **OpenAPI \[OPENAPI]** — ADL can reference OpenAPI specifications for HTTP-based tools. * **W3C Decentralized Identifiers \[W3C.DID] and Verifiable Credentials \[W3C.VC]** — ADL supports DIDs for cryptographic identity and VCs for attestations. * **AI agent protocols \[AI-PROTOCOLS]** — ADL's declarative model complements the framework, use cases, and requirements for AI agent protocols developed in the IETF. * **Agentic-AI governance frameworks \[IMDA-AGENTIC], \[CLTC-AGENTIC]** — ADL's governance signals, accountability model, and runtime enforcement draw on emerging agentic-AI governance and risk-management guidance. *** ## 2. Requirements Language[​](#2-requirements-language "Direct link to 2. Requirements Language") The key words **MUST**, **MUST NOT**, **REQUIRED**, **SHALL**, **SHALL NOT**, **SHOULD**, **SHOULD NOT**, **RECOMMENDED**, **NOT RECOMMENDED**, **MAY**, and **OPTIONAL** in this document are to be interpreted as described in BCP 14 \[RFC2119] \[RFC8174] when, and only when, they appear in all capitals, as shown here. *** ## 3. Terminology[​](#3-terminology "Direct link to 3. Terminology") The terms "AI agent", "AI system", "autonomy", and "automation" are used in this document consistent with their definitions in \[ISO-22989]. Where this specification narrows an ISO/IEC 22989 term, the narrower definition below takes precedence. | Term | Definition | | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **ADL document** | A JSON object that conforms to this specification. | | **agent** | An AI agent \[ISO-22989] further scoped as an AI system \[ISO-22989] that operates within boundaries declared by an ADL document. An agent senses and responds to its environment and takes actions to achieve its goals, subject to the permissions and constraints expressed in its ADL document. | | **sub-agent** | A **subordinate** agent: a persona an agent spawns that runs under the **parent agent's own identity**, sharing its passport, permissions, and accountability rather than holding its own. It is *sub*-ordinate in the literal sense — part of the parent, not a separate party — typically a distinct context with a focused prompt and a tool subset. Declared in `permissions.sub_agents` (§9.7). Engaging a *separately-identified* agent is **delegation** to a peer, not a sub-agent relationship. | | **delegation** | An agent engaging a **separate, independently-identified agent** — one with its own ADL document and agent passport — to act with or for it. The engaged agent is a **peer**, not a subordinate: it is discovered (§6.4) and admitted across a trust boundary via the Trust Protocol, and bounded by the calling agent's `permissions.delegation` envelope (§9.7). | | **AI system** | An engineered system that generates outputs such as content, forecasts, recommendations, or decisions for a given set of human-defined objectives \[ISO-22989]. | | **model** | The AI model (e.g., large language model) that powers an agent's reasoning. In \[ISO-22989] terms, a model is the learned computational artifact within an AI system. | | **tool** | A function or capability that an agent can invoke to perform an action or retrieve information (equivalent to "function" in function-calling and "tool" in \[MCP]). | | **resource** | A data source that an agent can read from (e.g., vector store, knowledge base, file system). | | **prompt** | A predefined prompt template that an agent can use. | | **profile** | A set of additional requirements and members that extend the core ADL specification for specific domains. | | **permission domain** | A category of system access (network, filesystem, etc.) that defines operational boundaries for an agent. | | **runtime** | The system or environment that executes an agent based on its ADL definition. | | **autonomy** | The characteristic of a system that is capable of modifying its intended domain of use or goal without external intervention, control, or oversight \[ISO-22989]. ADL expresses the degree of permitted autonomy through governance profile tiers. | | **agent passport** | A compact, verifiable credential derived from an agent's ADL document, carried during agent-to-agent interactions and verified on every exchange (§1.3). Its verification procedures are defined by the Trust Protocol. | | **counterparty** | An actor — a human, service, or other agent — that interacts with an agent and decides whether to verify, admit, and act on its requests. Counterparty procedures performed at admission are defined by the Trust Protocol. | | **runtime governor** | The actor that holds an admitted agent to its declared operational limits during execution, enforcing them on every step. It is a logical role, not a prescribed component; its procedures are defined by the Runtime Protocol. | | **enforcement record** | A verifiable record produced by a runtime governor attesting that it enforced an agent's declared limits. Its format is specified by the Runtime Protocol (Enforcement Evidence). | *** ## 4. Document Structure[​](#4-document-structure "Direct link to 4. Document Structure") ### 4.1 Media Type[​](#41-media-type "Direct link to 4.1 Media Type") * ADL documents use the media type **`application/adl+json`**. * ADL documents **MUST** be encoded in UTF-8. * ADL documents **MUST** be valid JSON \[RFC8259]. * Member names **MUST** use **snake\_case** (lowercase with underscores). * All timestamps **MUST** be ISO 8601 strings with timezone (e.g., `"2026-02-15T14:30:00Z"`). * All URIs **MUST** conform to \[RFC3986]. * **YAML authoring and JSON canonical form:** YAML is an authoring convenience; JSON is the canonical wire format. When an ADL document is authored in YAML, implementations **MUST** convert it to JSON for processing and validation. The media type `application/adl+json` applies to the JSON canonical form. ### 4.2 Top-Level Object[​](#42-top-level-object "Direct link to 4.2 Top-Level Object") An ADL document **MUST** be a single JSON object. **Required members:** * `adl_spec` (Section 5.1) * `name` (Section 5.3) * `description` (Section 5.4) * `version` (Section 5.5) * `data_classification` (Section 10.1) **Optional members:** * `$schema`, `id`, `provider`, `cryptographic_identity`, `lifecycle`, `model`, `system_prompt`, `tools`, `resources`, `prompts`, `permissions`, `security`, `runtime`, `metadata`, `profiles` An ADL document **MUST NOT** contain members not defined by this specification, a declared profile, or the extension mechanism. ### 4.3 Extension Mechanism[​](#43-extension-mechanism "Direct link to 4.3 Extension Mechanism") * **Profiles:** Add domain-specific requirements and members; declared in `profiles`. See Section 13. * **Extensions object:** Custom vendor data without a full profile. An `extensions` member **MAY** appear at any object level within an ADL document. Within `extensions`, vendor data is grouped under reverse-domain namespace keys. Vendor namespace keys **MUST** use reverse-domain notation with at least two dot-separated segments (e.g., `com.acme`, `io.anthropic`, `org.example.research`). Keys **MUST** conform to the `vendor-key` production in Appendix D. Single-segment keys (e.g., `acme`) and uppercase keys (e.g., `COM.ACME`) are invalid. Implementations **MUST** preserve `extensions` members when round-tripping ADL documents. Implementations **MAY** ignore the contents of `extensions`. Implementations **MUST NOT** reject documents containing `extensions` with unknown vendor namespaces. The member name `extensions` is reserved at every object level in an ADL document. Implementations **MUST NOT** define non-extension semantics for the `extensions` member. Example: ``` { "adl_spec": "0.3.0", "name": "Invoice Processor", "version": "2.0.0", "description": "Processes and routes invoices.", "data_classification": { "sensitivity": "confidential", "extensions": { "com.acme": { "data_tier": "gold", "retention_override_approved": true } } }, "model": { "name": "acme-large-2024", "extensions": { "com.acme": { "model_tier": "premium", "cost_per_1k_tokens": 0.03 } } }, "extensions": { "com.acme": { "internal_id": "inv-proc-007", "cost_center": "engineering" } } } ``` ### 4.4 Pattern Matching[​](#44-pattern-matching "Direct link to 4.4 Pattern Matching") Several ADL members use patterns to specify allowed or denied values. ADL defines a minimal pattern syntax based on a subset of glob matching rules. The following constructs are supported: 1. **Literal match.** A string with no wildcard characters matches only itself. Matching is case-sensitive unless the underlying system is case-insensitive (e.g., Windows filesystem paths). 2. **Single-segment wildcard (`*`).** The `*` character matches zero or more characters within a single segment. The segment boundary depends on context: * **Host patterns** (Section 9.2): segments are separated by `.` (dot). `*` does not match dots. `*.example.com` matches `api.example.com` but does not match `deep.sub.example.com`. * **Environment variable patterns** (Section 9.4): `*` matches any characters in the variable name. `APP_*` matches `APP_PORT` and `APP_HOST`. * **Command patterns** (Section 9.5): `*` matches any characters in the command name. 3. **Multi-segment wildcard (`**`).** The `**` sequence matches zero or more path segments including separators. Valid only in filesystem path patterns (Section 9.3). `/data/**` matches `/data/`, `/data/foo`, and `/data/foo/bar/baz`. `**` **MUST NOT** appear in host patterns, environment variable patterns, or command patterns. 4. **Restrictions.** Patterns **MUST** contain wildcards only in the positions described above. Mid-string wildcards (e.g., `foo*bar`) are **NOT RECOMMENDED**; implementations **MAY** reject them. A bare `*` as an entire pattern (matching everything) is valid but **NOT RECOMMENDED** for security-sensitive domains (`allowed_hosts`, `allowed_variables`). Implementations **SHOULD** warn when a bare `*` wildcard is used in permission patterns. Implementations **MUST** apply patterns using the rules defined in this section. Implementations **MUST NOT** interpret patterns as regular expressions. Formal grammar productions for pattern elements are defined in Appendix D. *** ## 5. Core Members[​](#5-core-members "Direct link to 5. Core Members") ### 5.1 ADL Specification[​](#51-adl-specification "Direct link to 5.1 ADL Specification") Specifies the ADL specification version the document conforms to. * **REQUIRED.** Value **MUST** be a string in semantic versioning format (MAJOR.MINOR.PATCH). The format **MUST** conform to the `semver` production in Appendix D. * An implementation implements one or more ADL versions. An `adl_spec` value is **supported** when its MAJOR component equals the MAJOR of a version the implementation implements *and* its MINOR component is less than or equal to the highest MINOR the implementation implements for that MAJOR; any other value is **unsupported**. A different MAJOR version, or a higher MINOR than the implementation implements, is therefore unsupported. * Implementations **MUST** reject documents whose `adl_spec` version is unsupported (error `ADL-2001`, Section 16.2). * Within a supported MAJOR, implementations **SHOULD** accept documents with a lower or equal MINOR version (forward compatibility within a MAJOR) and **MAY** reject a higher MINOR they do not implement. * Pre-release suffixes (e.g., `"0.2.0-draft"`) **MUST NOT** appear in `adl_spec` values. Only release versions are valid for conformance. Pre-release identifiers **MAY** appear in the agent's own `version` member (Section 5.5). Example: `"adl_spec": "0.3.0"` ### 5.2 $schema[​](#52-schema "Direct link to 5.2 $schema") Optional. URI reference to the JSON Schema for validation. **RECOMMENDED** for JSON documents (enables IDE validation). Canonical schema URI for ADL 0.3: `https://adl-spec.org/0.3/schema.json`. ### 5.3 Name[​](#53-name "Direct link to 5.3 Name") Human-readable name for the agent. **REQUIRED.** Value **MUST** be a non-empty string. For machine identifiers, use `id` (Section 6.1). ### 5.4 Description[​](#54-description "Direct link to 5.4 Description") Human-readable description of the agent's purpose and capabilities. **REQUIRED.** Value **MUST** be a non-empty string. **SHOULD** be sufficient for users to understand what the agent does without examining tool definitions. ### 5.5 Version[​](#55-version "Direct link to 5.5 Version") Agent's version. **REQUIRED.** Value **MUST** be a string in semantic versioning format (MAJOR.MINOR.PATCH); the format **MUST** conform to the `semver` production in Appendix D. Agent version changes **SHOULD** follow SemVer (MAJOR: breaking; MINOR: new capabilities; PATCH: fixes, docs). ### 5.6 Lifecycle[​](#56-lifecycle "Direct link to 5.6 Lifecycle") Operational lifecycle status of the agent. **OPTIONAL.** When present, value **MUST** be an object containing at minimum a `status` member. | Member | Type | Required | Description | | --------------- | ------ | -------- | --------------------------------------------------- | | status | string | REQUIRED | Lifecycle state of the agent | | effective\_date | string | OPTIONAL | ISO 8601 timestamp when current status took effect | | sunset\_date | string | OPTIONAL | ISO 8601 timestamp for planned or actual retirement | | successor | string | OPTIONAL | URI or URN of the replacement agent | #### status[​](#status "Direct link to status") **REQUIRED** when `lifecycle` is present. Value **MUST** be one of: | Status | Meaning | | ------------ | --------------------------------------------------- | | `draft` | Under development; not ready for production use | | `active` | Operational and available for use | | `deprecated` | Superseded; discouraged for new use; may be removed | | `retired` | End-of-life; no longer operational | When `lifecycle` is omitted, no lifecycle assertion is made. Implementations **MUST NOT** assume a default status. Runtimes **SHOULD** check `lifecycle.status` before provisioning agents. Runtimes **SHOULD NOT** provision agents with status `draft` in production environments. Runtimes **SHOULD** warn users when provisioning agents with status `deprecated`. Runtimes **MUST NOT** provision or execute agents with status `retired`. note "Provision" and "execute" refer to instantiating an agent for operation. Reading, parsing, validating, analyzing, or migrating from an agent definition is unrestricted regardless of lifecycle status. #### effective\_date[​](#effective_date "Direct link to effective_date") When present, value **MUST** be a valid ISO 8601 string with timezone. Indicates when the current `status` took effect. #### sunset\_date[​](#sunset_date "Direct link to sunset_date") When present, value **MUST** be a valid ISO 8601 string with timezone. Indicates when the agent will be or was retired. Implementations **SHOULD** warn when `sunset_date` is in the future and within 30 days. When `sunset_date` is in the past and `status` is `deprecated`, runtimes **SHOULD** treat the agent as `retired`. #### successor[​](#successor "Direct link to successor") When present, value **MUST** be a string; **SHOULD** be a URI or URN identifying the replacement agent (see Section 6.1 for identifier formats). **SHOULD** be present when `status` is `deprecated` or `retired`. Implementations **SHOULD** warn if `successor` is present when `status` is `active` or `draft`. Example: ``` { "lifecycle": { "status": "deprecated", "effective_date": "2026-01-15T00:00:00Z", "sunset_date": "2026-08-01T00:00:00Z", "successor": "https://acme.example.com/agents/research-assistant" } } ``` *** ## 6. Agent Identity[​](#6-agent-identity "Direct link to 6. Agent Identity") ### 6.1 Id[​](#61-id "Direct link to 6.1 Id") Unique identifier for the agent. **OPTIONAL.** When present, value **MUST** be a string and **MUST** be a valid URI \[RFC3986] or URN \[RFC8141]. Identifier formats, in order of preference: 1. **HTTPS URI (RECOMMENDED):** `https://{domain}/agents/{name}` — Provides ownership verification via TLS, direct resolution to the agent's ADL document, and natural integration with `.well-known` discovery (Section 6.4). The domain authority **SHOULD** serve the ADL document at the identifier URL with media type `application/adl+json`. 2. **Decentralized Identifier:** `did:web:{domain}:agents:{name}` — Provides cryptographic identity binding via the DID Document. Resolution follows the `did:web` method specification \[W3C.DID]. **RECOMMENDED** when cryptographic verification of agent identity is required independent of transport. 3. **URN (offline/catalog use):** `urn:adl:agent:{namespace}:{name}:{version}` — Location-independent identifier suitable for air-gapped environments, offline catalogs, and internal registries where network resolution is unavailable. The `{type}` segment is `agent` for an agent identifier; the full namespace syntax (`urn:adl:{type}:…`) is defined in Section 17.3 and Appendix D, and an `id` using this scheme **MUST** conform to the `adl-urn` production (VAL-37). URN identifiers provide naming only; they do not support ownership verification or discovery without an external resolver. When an agent has both a resolvable identifier (HTTPS URI or DID) and a URN, the resolvable identifier **SHOULD** be used as the primary `id` value. The URN **MAY** be recorded in `metadata` for catalog interoperability. note The namespace identifier is used as a convention in this specification but is not yet a registered URN namespace per \[RFC8141]. Formal registration with IANA will be pursued in a future revision. Implementations SHOULD NOT assume that URNs are globally resolvable. ### 6.2 Provider[​](#62-provider "Direct link to 6.2 Provider") Identifies the organization or entity that provides the agent. **OPTIONAL.** When present, value **MUST** be an object: | Member | Type | Required | Description | | ------- | ------ | -------- | ---------------- | | name | string | REQUIRED | Provider name | | url | string | OPTIONAL | Provider website | | contact | string | OPTIONAL | Contact email | ### 6.3 Cryptographic Identity[​](#63-cryptographic-identity "Direct link to 6.3 Cryptographic Identity") Cryptographic identification for the agent. **OPTIONAL.** When present, value **MUST** be an object: | Member | Type | Required | Description | | ----------- | ------ | -------- | ------------------------------------- | | did | string | OPTIONAL | Decentralized Identifier \[W3C.DID] | | public\_key | object | OPTIONAL | Public key for signature verification | At least one of `did` or `public_key` **SHOULD** be present. The `public_key` object, when present, **MUST** contain `algorithm` (string, REQUIRED) and `value` (string, Base64-encoded, REQUIRED). Implementations **SHOULD** reject weak algorithms (e.g., RSA below 2048 bits, DSA, ECDSA below P-256). EdDSA (Ed25519, Ed448) is **RECOMMENDED**. Example (agent identity with DID and public key): ``` { "id": "https://acme.example.com/agents/invoice-processor", "provider": { "name": "Acme Corp", "url": "https://acme.example.com", "contact": "ai-platform@acme.example.com" }, "cryptographic_identity": { "did": "did:web:acme.example.com:agents:invoice-processor", "public_key": { "algorithm": "Ed25519", "value": "MCowBQYDK2VwAyEAGb9ECWmEzf6FQbrBZ9w7lshQhqowtrbLDFw4rXAxZuE=" } } } ``` ### 6.4 Discovery[​](#64-discovery "Direct link to 6.4 Discovery") Agent discovery enables clients to locate agents published by a domain without prior knowledge of individual agent identifiers. It is the **front-end of delegation**: an agent does its work with its own tools, resources, and model, and turns to discovery only when a task exceeds its own reach and it needs to engage another agent. What it finds is then bounded by the agent's declared `permissions.delegation` envelope (§9.7.2) and admitted via the Trust Protocol — so discovery widens reach without widening authority. ![A two-region figure of governed discovery. On the left is the agent\'s own reach: a task arrives, and in the common case the agent handles it itself with its own tools, resources, and model, completing with no delegation — whether a task exceeds its reach is judged emergently per run. Only on a capability gap (the exception, drawn at the bottom) does the agent reach out, an arrow crossing into the right region. There a deterministic flow runs top to bottom: a registry served at the well-known adl-agents URL (the directory; publishing invites connection); triage by description and keywords, fetching only the few candidates that fit (emergent — which it picks varies); the delegation envelope of match and deny patterns that permits only peers within the declared boundary (§9.7.2); and Trust Protocol admission verifying the peer\'s passport and attenuation. Only an admitted peer is engaged, as a separate party. The agent does the work itself whenever it can and reaches a discovered peer only when a task exceeds its own reach, within its declared delegation envelope.](/assets/images/governed-discovery-56d665b049ee528337c5c9a7dce8700e.svg) *Figure (informative): Discovery is the governed front-end of delegation. The agent acts on its own by default and reaches a discovered peer only when a task exceeds its own reach — bounded by the `permissions.delegation` envelope (§9.7.2) and admitted via the Trust Protocol. Whether it needs help and which peer it selects are emergent per run; the envelope gate and admission are deterministic. This figure is illustrative; this section and §9.7.2 are authoritative.* Domains hosting ADL agents **MAY** publish a discovery document at the well-known URI \[RFC8615]: ``` https://{domain}/.well-known/adl-agents ``` The discovery document, when present, **MUST** be a JSON object served with media type `application/json`, **MUST** contain `adl_discovery` with the value `"1.0"`, and **MUST** contain an `agents` array. Each entry in the array **MUST** be an object containing: | Member | Type | Required | Description | | -------------- | ------ | ----------- | ------------------------------------------------------------------------------------------------------ | | `id` | string | REQUIRED | The agent's identifier per Section 6.1. | | `adl_document` | string | REQUIRED | URL to the full ADL document. | | `description` | string | RECOMMENDED | A concise, capability-focused summary of what the agent does and when to engage it (see below). | | `name` | string | OPTIONAL | Human-readable agent name. | | `version` | string | OPTIONAL | Agent version (Section 5.5). | | `status` | string | OPTIONAL | Lifecycle status (Section 5.6). Permitted values mirror §5.6 and **MUST** be kept in lockstep with it. | | `keywords` | array | OPTIONAL | Short strings naming the agent's domains, tasks, or capabilities, to support programmatic matching. | A domain that publishes a discovery document is, in effect, inviting other agents to connect. The `description` exists so a discovering agent can triage the list — deciding which agents merit retrieving the full document — **without** fetching every agent's document first. Publishers **SHOULD** include it; a discovery document whose entries omit it forces every consumer to fetch each full ADL document just to learn what each agent does. When present, `description` **MUST** be a summary of the agent's overall purpose and capabilities, written so another agent can assess fit for a task, and **MUST NOT** exceed 256 characters. It **SHOULD** be the agent's top-level `description` (Section 5.4), or a purpose-focused summary derived from it. The `description` is a triage aid, not a substitute for the full document: the authoritative capability declarations (tools, resources, permissions) remain in the ADL document at `adl_document`. Example discovery document: ``` { "adl_discovery": "1.0", "agents": [ { "id": "https://acme.example.com/agents/invoice-processor", "adl_document": "https://acme.example.com/agents/invoice-processor/adl.json", "name": "Invoice Processor", "description": "Processes vendor invoices: extracts line items, validates against purchase orders, and flags discrepancies for human review. Handles PDF and structured formats; does not issue payments.", "keywords": ["invoicing", "accounts-payable", "document-extraction"], "version": "2.0.0", "status": "active" }, { "id": "https://acme.example.com/agents/research-assistant", "adl_document": "https://acme.example.com/agents/research-assistant/adl.json", "name": "Research Assistant", "description": "Answers research questions by searching internal knowledge bases and the public web, then synthesizing cited summaries. Read-only; does not modify records or take external actions.", "keywords": ["research", "search", "summarization"], "version": "2.1.0", "status": "active" } ] } ``` The discovery document format is defined by the JSON Schema `schema-discovery.json`, a standalone artifact verified independently of any individual ADL document. Clients performing discovery **MUST** fetch the discovery document over HTTPS. Clients **SHOULD** validate the TLS certificate chain. The discovery document **SHOULD** be cacheable; servers **SHOULD** set appropriate `Cache-Control` headers. note Registration of with IANA per \[RFC8615] will be pursued alongside the IETF Internet-Draft submission. *** ## 7. Model Configuration[​](#7-model-configuration "Direct link to 7. Model Configuration") ### 7.1 Model[​](#71-model "Direct link to 7.1 Model") AI model configuration. **OPTIONAL.** When omitted, the runtime determines the model. When present, value **MUST** be an object: | Member | Type | Required | Description | | --------------- | ------ | -------- | ------------------------------ | | provider | string | OPTIONAL | Model provider identifier | | name | string | OPTIONAL | Model identifier | | version | string | OPTIONAL | Model version | | context\_window | number | OPTIONAL | Max context window (tokens) | | temperature | number | OPTIONAL | Sampling temperature (0.0–2.0) | | max\_tokens | number | OPTIONAL | Max output tokens | | capabilities | array | OPTIONAL | Required model capabilities | `capabilities` values may include: `function_calling`, `vision`, `code_execution`, `streaming`. ### 7.2 System Prompt[​](#72-system-prompt "Direct link to 7.2 System Prompt") System prompt for the agent. **OPTIONAL.** Value **MUST** be a string or an object. When an object, it **MUST** contain `template` (string, REQUIRED) and **MAY** contain `variables` (object). #### Template Variable Syntax[​](#template-variable-syntax "Direct link to Template Variable Syntax") Variables in templates use the `{{variable_name}}` syntax and **MUST** conform to the `template-var` production in Appendix D. Variable names **MUST** begin with a letter (`A`–`Z` or `a`–`z`) and **MAY** contain letters, digits, and underscores. **Escaping:** To include a literal `{{` in template text without triggering variable substitution, implementations **MUST** support the escape sequence `\{{`. A `\{{` in the template string is rendered as `{{` and is not treated as a variable reference. **Undefined variables:** When a template references a variable name not present in `variables`, the implementation **MUST** treat this as an error (error code ADL-2024) and **MUST NOT** silently substitute an empty string. Implementations **SHOULD** include the undefined variable name in the error detail. Example: ``` { "model": { "provider": "acme-ai", "name": "acme-large-2024", "context_window": 200000, "temperature": 0.7, "max_tokens": 4096, "capabilities": ["function_calling", "vision"] }, "system_prompt": { "template": "You are a helpful assistant for {{company_name}}. Today is {{current_date}}.", "variables": { "company_name": "Acme Corp", "current_date": "2026-02-18" } } } ``` *** ## 8. Capabilities[​](#8-capabilities "Direct link to 8. Capabilities") ### 8.1 Tools[​](#81-tools "Direct link to 8.1 Tools") Array of tool objects (functions the agent can invoke). **OPTIONAL.** Each tool **MUST** contain `name` (string, REQUIRED) and `description` (string, REQUIRED). Each tool **MAY** contain: `parameters` (JSON Schema), `returns` (JSON Schema), `examples`, `requires_confirmation` (bool), `idempotent` (bool), `read_only` (bool), `annotations`, `data_classification` (Section 10.1). Tool names **MUST** be unique, **MUST** match `^[a-z][a-z0-9_]*$`, and **MUST** conform to the `tool-name` production in Appendix D. The `parameters` and `returns` objects, when present, **MUST** be valid JSON Schema. The `read_only` and `idempotent` members are behavioral hints, each a boolean defaulting to `false` when absent. `read_only: true` declares that invoking the tool does not modify any state observable outside the agent (a pure query). `idempotent: true` declares that invoking the tool more than once with the same arguments has the same observable effect as invoking it once. A runtime **MAY** use these hints to decide whether a tool is safe to retry (Section 11.3) or to invoke in parallel, but **MUST NOT** treat them as a security control: state-changing boundaries are governed by `permissions` (Section 9), not by these hints. The `examples` member, when present, **MUST** be an array of example objects. Each example object **MAY** contain: | Member | Type | Required | Description | | ------ | ------ | -------- | ----------------------------------- | | name | string | OPTIONAL | Human-readable name for the example | | input | object | OPTIONAL | Example input parameters | | output | any | OPTIONAL | Expected output value | The `annotations` member, when present, **MUST** be an object containing implementation hints and metadata. Annotations is an open object — implementations **MAY** add custom keys. Standard annotation members include: | Member | Type | Required | Description | | ------------- | ------ | -------- | ------------------------------- | | openapi\_ref | string | OPTIONAL | URI to an OpenAPI specification | | operation\_id | string | OPTIONAL | OpenAPI operation identifier | See Section 15.3 for OpenAPI integration details. Implementations **MUST** preserve all annotation members when processing, including unrecognized keys. Example: ``` { "tools": [ { "name": "search_invoices", "description": "Search for invoices by vendor name, date range, or amount.", "parameters": { "type": "object", "properties": { "vendor": { "type": "string", "description": "Vendor name to search" }, "date_from": { "type": "string", "format": "date" }, "date_to": { "type": "string", "format": "date" } }, "required": [] }, "returns": { "type": "array", "items": { "type": "object" } }, "examples": [ { "name": "Search by vendor", "input": { "vendor": "Acme Supplies" }, "output": [{ "id": "INV-001", "amount": 1500.00 }] } ], "idempotent": true, "read_only": true, "annotations": { "openapi_ref": "https://api.acme.example.com/openapi.json", "operation_id": "searchInvoices" }, "data_classification": { "sensitivity": "confidential" } } ] } ``` ### 8.2 Resources[​](#82-resources "Direct link to 8.2 Resources") Array of resource objects (data sources the agent can access). **OPTIONAL.** Each resource **MUST** contain `name` (string, REQUIRED) and `type` (string, REQUIRED). `type` **MUST** be one of: `vector_store`, `knowledge_base`, `file`, `api`, `database`. Each resource **MAY** contain: `description`, `uri`, `mime_types`, `schema`, `annotations`, `data_classification` (Section 10.1). Resource names **MUST** be unique. The `mime_types` member, when present, **MUST** be an array of strings. Each value **MUST** be a valid MIME type (e.g., `"application/json"`, `"text/plain"`). The `schema` member, when present, **MUST** be a valid JSON Schema describing the structure of the resource's data. The `annotations` member, when present, **MUST** be an object. Same semantics as `tool.annotations` — an open object for implementation hints that **MUST** be preserved when processing. Example: ``` { "resources": [ { "name": "invoice_store", "type": "vector_store", "description": "Vector store containing indexed invoice documents for semantic search.", "uri": "https://store.acme.example.com/invoices", "mime_types": ["application/pdf", "application/json"], "data_classification": { "sensitivity": "confidential" } } ] } ``` ### 8.3 Prompts[​](#83-prompts "Direct link to 8.3 Prompts") Array of prompt objects (reusable prompt templates). **OPTIONAL.** Each prompt **MUST** contain `name` (string, REQUIRED) and `template` (string, REQUIRED). Each prompt **MAY** contain `description`, `arguments` (JSON Schema). Template arguments use `{{argument_name}}` and **MUST** conform to the `template-var` production in Appendix D. Prompt names **MUST** be unique. Example: ``` { "prompts": [ { "name": "summarize_invoice", "description": "Summarizes an invoice for a reviewer.", "template": "Summarize the following invoice for {{reviewer_role}}:\n\n{{invoice_text}}\n\nHighlight amounts over {{threshold}}.", "arguments": { "type": "object", "properties": { "reviewer_role": { "type": "string" }, "invoice_text": { "type": "string" }, "threshold": { "type": "number" } }, "required": ["reviewer_role", "invoice_text"] } } ] } ``` *** ## 9. Permissions[​](#9-permissions "Direct link to 9. Permissions") The `permissions` member defines the agent's operational boundaries. **OPTIONAL.** When present, value **MUST** be an object containing one or more permission domain members. ### 9.1 Permissions Model[​](#91-permissions-model "Direct link to 9.1 Permissions Model") | Domain | Description | | ---------------- | --------------------------------------------- | | network | Network access boundaries | | filesystem | Filesystem access boundaries | | environment | Environment variable access | | execution | Process execution boundaries | | resource\_limits | Resource consumption limits | | sub\_agents | Subordinate personas this agent may spawn | | delegation | Separate-identity peers this agent may engage | The first five domains govern the agent's access to **system resources**. The last two govern **delegation**, and they differ by identity: `sub_agents` (§9.7) bounds which **subordinate personas** the agent may spawn under its *own* identity (a static list), while `delegation` (§9.7) bounds which **separately-identified peers** it may engage across a trust boundary (an envelope over agents it discovers at runtime, §6.4). All are members of `permissions` and follow the same deny-by-default model below. Permissions operate on a **deny-by-default** model. Runtimes **MUST** deny any capability not explicitly granted in the `permissions` member. Runtimes **MUST** enforce declared permissions. Runtimes that cannot enforce a specific permission domain **MUST** warn users before execution and **SHOULD** refuse to execute the agent unless the user explicitly acknowledges the limitation. When the `permissions` member is omitted from an ADL document, no permissions are granted to the agent. Runtimes **MUST** treat the absence of `permissions` as equivalent to an empty `permissions` object — the agent has no granted capabilities. When a specific permission domain (e.g., `network`, `filesystem`) is omitted from the `permissions` object, all operations in that domain are denied. For example, if `permissions` is present but does not contain `network`, the agent **MUST** have no network access. Runtimes **MUST NOT** infer, assume, or provide default permissions when `permissions` or a permission domain is absent. #### Conflict Resolution[​](#conflict-resolution "Direct link to Conflict Resolution") When a value matches both an `allowed_*` pattern and a `denied_*` pattern within the same permission domain, the `denied_*` pattern **MUST** take precedence. The agent **MUST NOT** be granted access to any value matched by a `denied_*` pattern, regardless of whether it also matches an `allowed_*` pattern. This deny-takes-precedence rule ensures that explicit exclusions cannot be overridden by broad allow patterns. Example: If `allowed_variables` is `["APP_*"]` and `denied_variables` is `["APP_SECRET_*"]`, the variable `APP_SECRET_KEY` is **denied** even though it matches `APP_*`. ### 9.2 Network[​](#92-network "Direct link to 9.2 Network") Optional members: `allowed_hosts` (array of host patterns), `allowed_ports`, `allowed_protocols`, `deny_private` (bool). Host patterns support exact match and `*.example.com`. Host patterns in `allowed_hosts` **MUST** conform to the pattern syntax defined in Section 4.4. ### 9.3 Filesystem[​](#93-filesystem "Direct link to 9.3 Filesystem") Optional members: `allowed_paths` (array of `{ path, access }` where access is `read`, `write`, or `read_write`), `denied_paths`. Path patterns in `allowed_paths[*].path` and `denied_paths` **MUST** conform to the pattern syntax defined in Section 4.4. The `**` multi-segment wildcard is valid in filesystem path patterns. ### 9.4 Environment[​](#94-environment "Direct link to 9.4 Environment") Optional members: `allowed_variables`, `denied_variables` (patterns with wildcards, e.g., `APP_*`). Variable patterns in `allowed_variables` and `denied_variables` **MUST** conform to the pattern syntax defined in Section 4.4. ### 9.5 Execution[​](#95-execution "Direct link to 9.5 Execution") Optional members: `allowed_commands`, `denied_commands`, `allow_shell` (bool). Command patterns in `allowed_commands` and `denied_commands` **MUST** conform to the pattern syntax defined in Section 4.4. ### 9.6 Resource Limits[​](#96-resource-limits "Direct link to 9.6 Resource Limits") Optional members: `max_memory_mb`, `max_cpu_percent`, `max_duration_sec`, `max_concurrent`, `budget`. The `budget` member, when present, **MUST** be an object declaring cumulative consumption ceilings. It **MAY** contain `tokens`, `cost_usd`, and `wall_clock_sec`; each, when present, **MUST** be an object that **MAY** contain `per_session` and `per_day` caps. | Member | Unit | Description | | ------------------------------------------------ | ------- | --------------------------------------------------------------------------------------- | | `budget.tokens.per_session` / `.per_day` | tokens | Maximum model tokens (input + output) consumed in one session / rolling 24-hour window. | | `budget.cost_usd.per_session` / `.per_day` | USD | Maximum monetary cost incurred in one session / rolling day. | | `budget.wall_clock_sec.per_session` / `.per_day` | seconds | Maximum cumulative wall-clock run time in one session / rolling day. | Whereas `max_duration_sec` bounds a single execution, `budget.wall_clock_sec` bounds cumulative wall-clock across a session or day; the two compose. Each cap **MUST** be a number greater than `0`, and within a dimension `per_session` **MUST** be less than or equal to `per_day` when both are present. These are declarations; the procedure a runtime governor applies to enforce them is defined in the [Runtime Protocol](/protocol/runtime.md). Example (complete permissions object): ``` { "permissions": { "network": { "allowed_hosts": ["api.acme.example.com", "*.storage.example.com"], "allowed_ports": [443], "allowed_protocols": ["https"], "deny_private": true }, "filesystem": { "allowed_paths": [ { "path": "/data/invoices/**", "access": "read" }, { "path": "/tmp/processing/**", "access": "read_write" } ], "denied_paths": ["/tmp/processing/**/secrets"] }, "environment": { "allowed_variables": ["APP_*", "INVOICE_*"], "denied_variables": ["APP_SECRET_*"] }, "execution": { "allowed_commands": ["python3", "jq"], "allow_shell": false }, "resource_limits": { "max_memory_mb": 512, "max_cpu_percent": 25, "max_duration_sec": 300, "budget": { "tokens": { "per_session": 1000000, "per_day": 10000000 }, "cost_usd": { "per_session": 5.00, "per_day": 50.00 }, "wall_clock_sec": { "per_session": 1800, "per_day": 14400 } } } } } ``` ### 9.7 Sub-Agents and Delegation[​](#97-sub-agents-and-delegation "Direct link to 9.7 Sub-Agents and Delegation") An agent may bring other agents into its work in two structurally different ways, distinguished by **identity**. ADL declares them as two separate permission domains: * **Sub-agents** (§9.7.1) are **subordinate personas** the agent spawns under its *own* identity — no separate passport. They are statically enumerated and governed as part of the parent. * **Delegation** (§9.7.2) is engaging a **separately-identified peer** — an agent with its own ADL document and passport — across a trust boundary. Peers are discovered at runtime (§6.4) and admitted via the Trust Protocol. #### 9.7.1 Sub-Agents (personas)[​](#971-sub-agents-personas "Direct link to 9.7.1 Sub-Agents (personas)") The `sub_agents` member declares the **subordinate personas** this agent may spawn: distinct contexts, each with a focused prompt and a tool subset, that run under the **parent's own identity** (§3). A sub-agent has no agent passport and crosses no trust boundary — it *is* the parent, acting in a narrower role — so its authority is a subset of the parent's by construction. **OPTIONAL.** When present, **MUST** be an array of persona objects. Deny-by-default applies (§9.1): a runtime **MUST NOT** spawn a persona not declared here. Each entry **MAY** contain: | Member | Type | Required | Description | | ----------------- | ------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `name` | string | REQUIRED | Local persona/role name (not an agent identifier). **MUST** be unique within the array. | | `description` | string | OPTIONAL | What the persona is for. | | `prompt_resource` | string | OPTIONAL | Identifier of a `resources` entry (§8.2) holding the persona's prompt/instructions — keeps the persona's *content* in `resources` (versioned and signed-over) and its *declaration* here. | | `tools` | array | OPTIONAL | Subset of the parent's `tools` the persona may use. Omitted ⇒ the parent's full tool set. A persona **MUST NOT** be granted a tool the parent lacks. | | `max_parallel` | integer | OPTIONAL | Maximum instances of this persona running concurrently. Composes with `resource_limits.max_concurrent` (§9.6). | | `budget_share` | object | OPTIONAL | Per-instance sub-cap within the parent's `resource_limits.budget` (same shape as §9.6 `budget`), so one persona cannot exhaust the whole envelope. | A persona's authority is always a subset of the parent's; there is no attenuation chain to verify, because there is no separate grant. The parent's declared envelope is the ceiling for the parent **and all its personas in aggregate** — personas draw down the parent's budget rather than receiving fresh envelopes. The procedure a runtime governor applies to cap personas at spawn time is defined in the [Runtime Protocol](/protocol/runtime.md); a spawn that no entry permits is denied, and the governor resolves `runtime.degradation.on_sub_agent_denied` (§11.5), defaulting to fail-closed. #### 9.7.2 Delegation (external peers)[​](#972-delegation-external-peers "Direct link to 9.7.2 Delegation (external peers)") The `delegation` member declares the **envelope** of separately-identified agents this agent may engage as peers. Unlike sub-agents, a delegated peer is a distinct party with its own ADL document and agent passport, and engagement crosses a trust boundary. Because peers are **discovered at runtime** (§6.4 / the Registry Profile / a trusted directory) rather than enumerated at design time, this domain declares which discovered agents are *permitted*, not a fixed roster. **OPTIONAL.** When present, **MUST** be an object. Deny-by-default applies (§9.1): a delegation to an agent matched by no `match` pattern is denied. It **MAY** contain: | Member | Type | Description | | ------------- | ------- | --------------------------------------------------------------------------------------------------------- | | `match` | array | Agent-identifier patterns this agent MAY delegate to. Patterns follow §4.4. | | `deny` | array | Agent-identifier patterns this agent MUST NOT delegate to. `deny` overrides `match` (§9.1). | | `max_depth` | integer | Maximum delegation depth rooted at this agent. | | `attenuation` | object | Constraints a delegated peer MUST satisfy; MAY contain `scopes_subset` (bool) and `budget_subset` (bool). | `attenuation.scopes_subset: true` requires a peer's `security.scopes` to be a subset of this agent's ceiling; `budget_subset: true` requires its `permissions.resource_limits.budget` caps to be less than or equal to this agent's. These compose with the delegation-chain verification defined in the [Trust Protocol](/protocol/trust.md). These are declarations; the admission procedure a runtime governor applies when this agent attempts to delegate to a peer is defined in the [Runtime Protocol](/protocol/runtime.md). A delegation that no rule permits is denied; the governor resolves `runtime.degradation.on_delegation_denied` (§11.5), defaulting to fail-closed. *** ## 10. Security[​](#10-security "Direct link to 10. Security") The `security` member defines security requirements. **OPTIONAL.** When present, value **MUST** be an object that **MAY** contain `authentication`, `encryption`, and `attestation`. Section 10 spans two ADL layers. The **declarative** members defined here in ADL Core — `data_classification` (§10.1), `attestation` (§10.2), the credential schemes (§10.3.3), and the scope declarations (§10.4.1–§10.4.2) — describe what an agent handles and what it advertises. The **procedural** members — passport verification (§10.3.1), presentation proof (§10.3.2), and authorization enforcement (§10.4.3) — define what a counterparty **MUST** do with those declarations and are specified in the companion [**ADL Trust Protocol**](/protocol/trust.md), where they are numbered independently as §1 (Authentication) and §2 (Authorization). Section 10 is ordered to follow the dependency stack of the security model. Data Classification (§10.1) declares what the agent handles. Attestation (§10.2) signs the passport. Authentication (§10.3) defines how parties prove identity at runtime — agent-to-agent via passport verification (§10.3.1) and presentation proof (§10.3.2), and human or external services via OAuth 2.1, OIDC, mTLS, or API keys (§10.3.3). Authorization (§10.4) covers scope-based AuthZ. Encryption (§10.5) covers channel security. ### 10.1 Data Classification[​](#101-data-classification "Direct link to 10.1 Data Classification") The `data_classification` member declares the sensitivity and categories of data the agent may access, process, or produce. **REQUIRED.** Value **MUST** be an object. Data classification is required by NIST FIPS 199, NIST SP 800-60, ISO 27001:2022 Annex A.5.12, FedRAMP, SOC 2, and CMMC. It is the foundational step of security categorization across all major compliance frameworks. This member is a **reusable composable attribute**. In addition to the required top-level declaration, it **MAY** also appear within individual `tools[*]` or `resources[*]` objects to classify specific capabilities. When present on both the top level and a tool or resource, the tool/resource-level classification applies to that capability. #### High-Water Mark Rule[​](#high-water-mark-rule "Direct link to High-Water Mark Rule") The top-level `data_classification.sensitivity` **MUST** be greater than or equal to the highest `sensitivity` value declared in any tool-level or resource-level `data_classification` within the same document. This follows the FIPS 199 high-water mark principle: a system's overall security categorization is the highest value among its constituent information types. The sensitivity ordering from lowest to highest is: `public` < `internal` < `confidential` < `restricted`. Sensitivity levels align with NIST FIPS 199 impact categorization and ISO 27001:2022 Annex A.5.12 information classification. | Member | Type | Required | Description | | ----------- | ------ | -------- | ------------------------------------ | | sensitivity | string | REQUIRED | Information sensitivity level | | categories | array | OPTIONAL | Broad information categories handled | | retention | object | OPTIONAL | Data retention requirements | | handling | object | OPTIONAL | Data handling constraints | #### sensitivity[​](#sensitivity "Direct link to sensitivity") **REQUIRED** when `data_classification` is present. Value **MUST** be one of: | Value | Definition | | -------------- | ------------------------------------------------------------------------------------------------------ | | `public` | Information approved for unrestricted disclosure | | `internal` | Information limited to organizational use | | `confidential` | Information requiring protection; unauthorized disclosure could cause harm | | `restricted` | Information requiring the highest level of protection; unauthorized disclosure could cause severe harm | #### categories[​](#categories "Direct link to categories") When present, **MUST** be a non-empty array. Each item **MUST** be one of: | Value | Definition | | ----------------------- | -------------------------------------------------------------- | | `pii` | Personally Identifiable Information | | `phi` | Protected Health Information (HIPAA) | | `financial` | Financial data (PCI-DSS, GLBA, SOX scope) | | `credentials` | Authentication credentials, secrets, keys | | `intellectual_property` | Trade secrets, proprietary algorithms, business-sensitive data | | `regulatory` | Data subject to specific regulatory requirements | Profiles **MAY** define additional category values. #### retention[​](#retention "Direct link to retention") When present, **MUST** be an object. **MAY** contain: | Member | Type | Description | | ----------- | ------ | ------------------------------------- | | min\_days | number | Minimum retention period in days | | max\_days | number | Maximum retention period in days | | policy\_uri | string | URI to the governing retention policy | When both `min_days` and `max_days` are present, `min_days` **MUST** be less than or equal to `max_days`. #### handling[​](#handling "Direct link to handling") When present, **MUST** be an object. **MAY** contain: | Member | Type | Description | | ------------------------- | ---- | ---------------------------------------------------- | | encryption\_required | bool | Whether data must be encrypted at rest | | anonymization\_required | bool | Whether data must be anonymized before processing | | cross\_border\_restricted | bool | Whether data may not leave jurisdictional boundaries | | logging\_required | bool | Whether all access must be logged | #### Profile Extensions[​](#profile-extensions "Direct link to Profile Extensions") Profiles **MAY** add domain-specific sub-objects within `data_classification` to provide granular classification vocabularies. For example, a healthcare profile may add a `healthcare` sub-object with PHI type enumerations, and a financial profile may add a `financial` sub-object with financial data type enumerations. Multiple profile extensions compose naturally within the same `data_classification` object. See Section 13 for profile composition rules. Example (top-level and tool-level data classification demonstrating the high-water mark rule): ``` { "data_classification": { "sensitivity": "confidential", "categories": ["financial", "pii"], "retention": { "max_days": 2555, "policy_uri": "https://acme.example.com/data-retention" }, "handling": { "encryption_required": true, "logging_required": true } }, "tools": [ { "name": "get_invoice_details", "description": "Returns detailed invoice data including PII.", "data_classification": { "sensitivity": "confidential", "categories": ["financial", "pii"] } }, { "name": "get_invoice_summary", "description": "Returns anonymized invoice summary.", "data_classification": { "sensitivity": "internal" } } ] } ``` The top-level `sensitivity` of `"confidential"` satisfies the high-water mark rule: it equals the highest tool-level value (`"confidential"` for `get_invoice_details`). ### 10.2 Attestation[​](#102-attestation "Direct link to 10.2 Attestation") The `security.attestation` member declares cryptographic attestation of the passport. **OPTIONAL.** When present, value **MUST** be an object that **MAY** contain `type` (one of `self`, `third_party`, `verifiable_credential`), `issuer`, `issued_at`, `expires_at` (ISO 8601), and `signature` (object). Implementations **SHOULD** warn when `expires_at` is in the past or within 30 days. **Signature object:** When present, **MUST** contain `algorithm`, `value` (Base64url-encoded), `signed_content` (`"canonical"` or `"digest"`). When `signed_content` is `"digest"`, **MUST** also include `digest_algorithm` and `digest_value`. Supported algorithms include Ed25519 (RECOMMENDED), Ed448, ES256/384/512, RS256, PS256 (RSA ≥ 2048). Verification: remove signature, serialize with JCS \[RFC8785], verify digest if applicable, resolve public key from `cryptographic_identity`, verify signature. Example: ``` { "security": { "attestation": { "type": "third_party", "issuer": "https://trust.acme.example.com", "issued_at": "2026-01-01T00:00:00Z", "expires_at": "2027-01-01T00:00:00Z" } } } ``` ### 10.3 Authentication[​](#103-authentication "Direct link to 10.3 Authentication") ADL defines authentication at two complementary boundaries: 1. **Agent-to-agent.** When one ADL agent calls another, both sides authenticate using cryptographically signed passports (§10.3.1) and per-request presentation proofs (§10.3.2). This path establishes identity for autonomous agent meshes where no shared OAuth 2.1 authorization server exists. 2. **Human or external service to agent.** When a human user, an OAuth 2.1 client, or an external service calls an ADL agent, the agent authenticates that party using standard credential schemes — OAuth 2.1 \[OAUTH2.1], OIDC \[OPENID-CONNECT], mTLS \[RFC8705], or API keys (§10.3.3). The two paths compose. A human's OAuth 2.1 access token authenticates their session at the agent boundary; the receiving agent then presents its own passport plus proof to upstream agents it calls on the human's behalf. ADL does not replace OAuth 2.1 — it adds the agent-identity layer that OAuth 2.1's resource-server protocol does not specify, and integrates cleanly with OAuth 2.1 at the human and external-service boundary. The `security.authentication` member of an ADL document is declarative: it advertises which credential scheme (§10.3.3) external clients use to reach the agent. The procedures in §10.3.1 (Passport Verification) and §10.3.2 (Presentation Proof) are procedural rather than declarative — they describe what counterparties **MUST** do when receiving an ADL passport, and apply regardless of whether `security.authentication` is present. #### 10.3.1 Passport Verification & 10.3.2 Presentation Proof[​](#1031-passport-verification--1032-presentation-proof "Direct link to 10.3.1 Passport Verification & 10.3.2 Presentation Proof") The agent-to-agent authentication procedures — **passport verification** and **presentation proof** — are normatively defined in the companion [**ADL Trust Protocol**](/protocol/trust.md) as §1.1 and §1.2. They specify what a counterparty **MUST** do when receiving and acting on an ADL passport, and what a presenter **MUST** do to bind a passport to a specific request. The credential schemes below (§10.3.3) cover the complementary human and external-service boundary. #### 10.3.3 Credential Schemes[​](#1033-credential-schemes "Direct link to 10.3.3 Credential Schemes") The `security.authentication` member declares the credential scheme that human users, OAuth 2.1 clients, or external services use when calling the agent. It is the OAuth-2.1-aligned (and OAuth-2.1-adjacent) surface of ADL — the `did:web`-and-passport machinery in §10.3.1 and §10.3.2 covers agent-to-agent identity, while §10.3.3 covers the human-and-external-service boundary. `security.authentication` is **OPTIONAL**. When present, value **MUST** be an object that **MAY** contain `type` (one of `none`, `api_key`, `oauth2`, `oidc`, `mtls`) and `required` (bool). Type-specific members **MAY** be present. When `type` is `"none"`, the agent declares that it requires no credential at its request boundary: requests are accepted without authentication at this layer, and `required` **SHOULD** be omitted or `false`. `type: "none"` **MUST NOT** be used by agents handling `confidential` or `restricted` data (§10.1) without compensating network-layer controls. This setting governs only the human-and-external-service credential layer (§10.3.3); agent-to-agent passport verification (§10.3.1) and presentation proof (§10.3.2) still apply when the caller is another ADL agent, regardless of `type`. ##### 10.3.3.1 OAuth 2.1 (`type: "oauth2"`)[​](#10331-oauth-21-type-oauth2 "Direct link to 10331-oauth-21-type-oauth2") When `type` is `"oauth2"`, the agent acts as an OAuth 2.1 \[OAUTH2.1] resource server and **SHOULD** follow the OAuth 2.0 security best current practice \[RFC9700]. The following members **SHOULD** be declared so clients can integrate without out-of-band configuration: | Member | Type | Description | | ------------------------ | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `token_endpoint` | string (HTTPS URI) | OAuth 2.1 token endpoint URL | | `authorization_endpoint` | string (HTTPS URI) | OAuth 2.1 authorization endpoint URL (for grant types that require user interaction) | | `scopes` | array of strings | Scopes the agent recognizes; clients **MUST** request only declared scopes | | `grant_types_supported` | array of strings | Subset of `["authorization_code", "client_credentials", "refresh_token"]` (the grant types OAuth 2.1 recommends) | | `pkce_required` | boolean | Whether the agent requires PKCE \[RFC7636] for the authorization-code grant. **SHOULD** be `true`; OAuth 2.1 mandates PKCE for public clients and **RECOMMENDS** it for confidential clients | | `dpop_required` | boolean | Whether the agent requires DPoP \[RFC9449] sender-constrained tokens. **SHOULD** be `true` for deployments handling `confidential` or `restricted` data classification (§10.1) | Agents **SHOULD NOT** issue or accept OAuth 2.0 implicit-grant or password-grant tokens; OAuth 2.1 deprecates both. ##### 10.3.3.2 OpenID Connect (`type: "oidc"`)[​](#10332-openid-connect-type-oidc "Direct link to 10332-openid-connect-type-oidc") When `type` is `"oidc"`, the agent acts as an OpenID Connect relying party for end-user authentication on top of OAuth 2.1. The following members **SHOULD** be declared: | Member | Type | Description | | ------------------- | ------------------ | ------------------------------------------------------------------------------------------------------ | | `issuer` | string (HTTPS URI) | OIDC issuer identifier (the `iss` value in ID tokens) | | `audience` | string | The agent's audience identifier (the `aud` value clients **MUST** request) | | `scopes` | array of strings | OIDC scopes the agent requires (typically includes `openid`; **MAY** include `profile`, `email`, etc.) | | `userinfo_endpoint` | string (HTTPS URI) | UserInfo endpoint (when the agent fetches additional claims) | OIDC inherits OAuth 2.1's PKCE and DPoP requirements; the same recommendations from §10.3.3.1 apply. ##### 10.3.3.3 Mutual TLS (`type: "mtls"`)[​](#10333-mutual-tls-type-mtls "Direct link to 10333-mutual-tls-type-mtls") When `type` is `"mtls"`, the agent requires X.509 client certificates per \[RFC8705]. The following members **SHOULD** be declared: | Member | Type | Description | | ------------------ | ---------------- | -------------------------------------------------------------------------- | | `accepted_issuers` | array of strings | DNs (Distinguished Names) or URIs of CAs the agent accepts | | `required_san` | string | Required Subject Alternative Name pattern (e.g., URI form) when applicable | mTLS is **RECOMMENDED** for service-to-service deployments where a client-credential OAuth 2.1 flow would require unnecessary token-exchange machinery. ##### 10.3.3.4 API Key (`type: "api_key"`)[​](#10334-api-key-type-api_key "Direct link to 10334-api-key-type-api_key") When `type` is `"api_key"`, the agent accepts a static or rotating shared secret. The following members **SHOULD** be declared: | Member | Type | Description | | --------------------- | ------------------ | -------------------------------------------------------------------------------------------------------------- | | `header_name` | string | HTTP header carrying the key (default: `Authorization` with `Bearer` prefix; common alternatives: `X-API-Key`) | | `rotation_policy_uri` | string (HTTPS URI) | Reference to the operational rotation policy for the key | API keys **SHOULD NOT** be used for `confidential` or `restricted` data classification (§10.1) without compensating controls (mTLS at the network layer, IP allowlisting, per-request HMAC). OAuth 2.1 with DPoP is the **RECOMMENDED** alternative. ##### 10.3.3.5 Composition with §10.3.1 / §10.3.2[​](#10335-composition-with-1031--1032 "Direct link to 10.3.3.5 Composition with §10.3.1 / §10.3.2") When an agent that declares `security.authentication` (§10.3.3) calls a peer agent, two authentications happen end-to-end: 1. The **calling client** (human, OAuth 2.1 client, or external service) presents a §10.3.3 credential to authenticate at the agent's request boundary. 2. The **agent itself** presents its own ADL passport (§10.3.1) plus presentation proof (§10.3.2) to the peer agent it calls upstream. These are independent authentications. A failed §10.3.3 check **MUST NOT** bypass §10.3.1 verification of any upstream agent the request reaches; conversely, a successful §10.3.1 verification **MUST NOT** be treated as authentication of a non-agent caller. Implementations **MUST** record both authentications in the audit trail when both apply. Example: ``` { "security": { "authentication": { "type": "oauth2", "required": true, "token_endpoint": "https://auth.acme.example.com/oauth/token", "authorization_endpoint": "https://auth.acme.example.com/oauth/authorize", "scopes": ["invoices:read", "invoices:write"], "grant_types_supported": ["authorization_code", "client_credentials"], "pkce_required": true, "dpop_required": true } } } ``` ### 10.4 Authorization Scopes[​](#104-authorization-scopes "Direct link to 10.4 Authorization Scopes") Authentication (§10.3) establishes *who* a counterparty is. Authorization (§10.4) establishes *what they may do*. ADL adopts scope-based authorization aligned with OAuth 2.1 \[OAUTH2.1]: the agent declares scope requirements at the root level and per-tool, and a counterparty's request is authorized only if its presented scope set covers every scope the targeted resource requires. Scopes apply uniformly across both authentication paths defined in §10.3: * **Human or external service to agent** (§10.3.3): scopes are presented in the OAuth 2.1 access token, OIDC ID token, or equivalent credential. * **Agent to agent** (§10.3.1 + §10.3.2): scopes are presented in the presentation proof's `scopes` member (Trust Protocol §1.2.2), bound cryptographically to the request. The two paths use the same scope vocabulary, the same inheritance and override rules, and the same effective-scope computation. They diverge only in *how* the requesting scope set arrives at the verifier. #### 10.4.1 Scope Declaration[​](#1041-scope-declaration "Direct link to 10.4.1 Scope Declaration") ADL adds two scope-declaration members: | Member | Location | Type | Required | Description | | -------------------------- | -------- | ---------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | | `security.scopes` | root | array of strings | OPTIONAL | Default required scopes for the agent. Acts as the agent's scope **ceiling** when the agent itself is making upstream calls (see Trust Protocol §2.4). | | `tools[*].security.scopes` | per tool | array of strings | OPTIONAL | Required scopes to invoke this specific tool. Overrides the root default for this tool. | Each scope value **MUST** be a non-empty string matching the OAuth 2.1 scope grammar: visible ASCII characters excluding double-quote and backslash, separated where needed by single space characters per \[RFC6749] §3.3. The recommended convention is `:` (e.g., `invoices:read`, `documents:write`), and ADL validators **SHOULD** warn on values that do not follow the convention. Scopes prefixed with `adl:` are reserved for future spec-defined values. Scope declarations are meaningful when the authentication path supports scope assertion: OAuth 2.1, OIDC, and presentation proofs (§10.3.2). For non-scope-bearing credentials (`api_key`, `mtls`), implementations **MUST** treat scope declarations as advisory unless the credential is augmented out-of-band (e.g., an API key bound to a server-side scope record). #### 10.4.2 Inheritance and Override[​](#1042-inheritance-and-override "Direct link to 10.4.2 Inheritance and Override") The inheritance rule is **override-on-presence**, not augment: * If a tool **omits** `tools[*].security.scopes`, the root `security.scopes` applies for that tool. * If a tool **declares** `tools[*].security.scopes` (including an empty array), that declaration **completely replaces** the root scope set for that tool. * An empty array (`"scopes": []`) at tool level explicitly means "this tool requires no scopes" and **MUST** be treated as a deliberate downgrade, not an oversight. Validators **SHOULD** warn when a tool's declared scope set introduces values not present in the root `security.scopes`, since this expands the agent's stated capability surface beyond what the root advertises. Validators **MAY** support a strict mode that rejects such expansions. #### 10.4.3 Authorization Enforcement[​](#1043-authorization-enforcement "Direct link to 10.4.3 Authorization Enforcement") The procedures for enforcing these scope declarations — human-to-agent authorization, agent-to-agent authorization (including the passport-ceiling subset check), multi-hop composition, and effective-scope computation — are normatively defined in the companion [**ADL Trust Protocol**](/protocol/trust.md#2-authorization-enforcement-procedures) as §2.1–§2.6. Scope *declaration* and *inheritance* (§10.4.1–§10.4.2) are part of ADL Core; their *enforcement* is part of ADL Trust. ### 10.5 Encryption[​](#105-encryption "Direct link to 10.5 Encryption") The `security.encryption` member declares channel and at-rest encryption requirements. **OPTIONAL.** When present, value **MUST** be an object that **MAY** contain `in_transit` (`required`, `min_version`) and `at_rest` (`required`, `algorithm`). Example: ``` { "security": { "encryption": { "in_transit": { "required": true, "min_version": "TLS1.3" }, "at_rest": { "required": true, "algorithm": "AES-256-GCM" } } } } ``` *** ## 11. Runtime Behavior[​](#11-runtime-behavior "Direct link to 11. Runtime Behavior") The `runtime` member configures agent runtime behavior. **OPTIONAL.** When present, value **MUST** be an object. ### 11.1 Input Handling[​](#111-input-handling "Direct link to 11.1 Input Handling") The `input_handling` member, when present, **MUST** be an object. Optional members: `max_input_length`, `content_types`, `sanitization`. The `sanitization` member, when present, **MUST** be an object describing input sanitization rules. It **MAY** contain: | Member | Type | Required | Description | | ------------------ | ------- | -------- | ------------------------------------- | | enabled | boolean | OPTIONAL | Whether input sanitization is active | | strip\_html | boolean | OPTIONAL | Whether to strip HTML tags from input | | max\_input\_length | number | OPTIONAL | Maximum input length in characters | The `content_types` member, when present, **MUST** be an array of strings. Each value **MUST** be a valid MIME type specifying an accepted input content type. ### 11.2 Output Handling[​](#112-output-handling "Direct link to 11.2 Output Handling") The `output_handling` member, when present, **MUST** be an object. Optional members: `max_output_length`, `format`, `streaming` (bool). The `format` member, when present, **MUST** be a string specifying the default output format. Value **MUST** be one of: `"text"`, `"json"`, `"markdown"`, `"html"`. ### 11.3 Tool Invocation[​](#113-tool-invocation "Direct link to 11.3 Tool Invocation") The `tool_invocation` member, when present, **MUST** be an object. Optional members: `parallel` (bool), `max_concurrent`, `timeout_ms`, `retry_policy`, `max_iterations`, `max_tool_calls_per_session`, `loop_detection`. The `retry_policy` member, when present, **MUST** be an object describing retry behavior for tool invocations. It **MAY** contain: | Member | Type | Required | Description | | ------------------ | ------ | -------- | ---------------------------------------------- | | max\_retries | number | OPTIONAL | Maximum number of retry attempts | | backoff\_strategy | string | OPTIONAL | One of: `"fixed"`, `"exponential"`, `"linear"` | | initial\_delay\_ms | number | OPTIONAL | Initial delay between retries in milliseconds | | max\_delay\_ms | number | OPTIONAL | Maximum delay between retries in milliseconds | The `max_iterations`, `max_tool_calls_per_session`, and `loop_detection` members bound an agent's reasoning loop: | Member | Type | Description | | ------------------------------ | ------- | ---------------------------------------------------------------- | | max\_iterations | integer | Maximum reason→act iterations the agent may take in one session. | | max\_tool\_calls\_per\_session | integer | Maximum total tool invocations in one session. | | loop\_detection | object | Detection of repetitive behavior; see below. | `loop_detection`, when present, **MUST** be an object that **MAY** contain `window` (integer; number of most-recent steps examined for repetition) and `on_detected` (a degradation response object per §11.5, applied when a loop is detected and overriding `degradation.on_iteration_limit` for the loop case). These are declarations; the procedure a runtime governor applies — counting iterations and tool calls, detecting loops, and the fail-closed default — is defined in the [Runtime Protocol](/protocol/runtime.md). When a limit or loop fires with no specific response declared, the governor resolves `runtime.degradation.on_iteration_limit` (§11.5), defaulting to fail-closed. ### 11.4 Error Handling[​](#114-error-handling "Direct link to 11.4 Error Handling") The `error_handling` member, when present, **MUST** be an object. Optional members: `on_tool_error` (`abort`, `continue`, or `retry`), `max_retries`, `fallback_behavior`. The `fallback_behavior` member, when present, **MUST** be an object describing behavior when errors occur and `on_tool_error` does not resolve the situation. It **MAY** contain: | Member | Type | Required | Description | | ------- | ------ | -------- | -------------------------------------------------------- | | action | string | OPTIONAL | One of: `"return_error"`, `"use_default"`, `"skip"` | | default | any | OPTIONAL | Default value to return when `action` is `"use_default"` | | message | string | OPTIONAL | User-facing message on fallback | `runtime.degradation` (§11.5) generalizes `fallback_behavior` across all limit causes; this member is equivalent to `degradation.on_tool_error`, and `degradation` takes precedence when both are present. Example: ``` { "runtime": { "input_handling": { "max_input_length": 32768, "content_types": ["text/plain", "application/json"], "sanitization": { "enabled": true, "strip_html": true } }, "output_handling": { "format": "json", "max_output_length": 8192, "streaming": false }, "tool_invocation": { "parallel": true, "max_concurrent": 3, "timeout_ms": 30000, "retry_policy": { "max_retries": 2, "backoff_strategy": "exponential", "initial_delay_ms": 500, "max_delay_ms": 5000 } }, "error_handling": { "on_tool_error": "retry", "max_retries": 2, "fallback_behavior": { "action": "return_error", "message": "Invoice processing temporarily unavailable." } } } } ``` ### 11.5 Degradation[​](#115-degradation "Direct link to 11.5 Degradation") The `degradation` member declares how the agent behaves when an operational limit is reached or a fault occurs. **OPTIONAL.** When present, **MUST** be an object whose keys are *cause* identifiers matching `^on_[a-z0-9_]+$` and whose values are *response* objects. Recognized causes include `on_budget_exhausted` (§9.6), `on_iteration_limit` (§11.3), `on_sub_agent_denied` (a subordinate-persona spawn was denied, §9.7.1), `on_delegation_denied` (an external-peer delegation was denied, §9.7.2), `on_oversight_timeout` (Governance Profile), `on_tool_error`, and `on_anomaly`. Causes are an open set: this list is not exhaustive, and profiles **MAY** define additional causes (for example, `on_oversight_timeout` and `on_anomaly` are defined by the Governance Profile). Each response object **MUST** contain `action` and **MAY** contain the rest: | Member | Type | Required | Description | | ------- | ------- | -------- | ------------------------------------------------------------------ | | action | string | REQUIRED | One of: `"halt"`, `"pause"`, `"fallback"`, `"continue"`. | | value | any | OPTIONAL | Value to return when `action` is `"fallback"`. | | message | string | OPTIONAL | User-facing message. | | notify | boolean | OPTIONAL | Whether to emit an out-of-band notification when this cause fires. | `degradation` generalizes the per-tool `runtime.error_handling.fallback_behavior` (§11.4), which is retained for backward compatibility and is equivalent to `degradation.on_tool_error`; when both address that cause, `degradation` takes precedence. These are declarations. The procedure a runtime governor applies — and the **fail-closed default** when a cause fires with no declared response — is defined in the [Runtime Protocol](/protocol/runtime.md). Absence of a degradation response does not mean "continue": a conforming governor halts. *** ## 12. Metadata[​](#12-metadata "Direct link to 12. Metadata") The `metadata` member provides additional information. **OPTIONAL.** When present, value **MUST** be an object. ### 12.1 Authors[​](#121-authors "Direct link to 12.1 Authors") Array of author objects. Each **MAY** contain `name`, `email`, `url`. ### 12.2 License[​](#122-license "Direct link to 12.2 License") String: SPDX license identifier or URI to license document. ### 12.3 Documentation[​](#123-documentation "Direct link to 12.3 Documentation") String: URI to documentation. ### 12.4 Repository[​](#124-repository "Direct link to 12.4 Repository") String: URI to source repository. ### 12.5 Tags[​](#125-tags "Direct link to 12.5 Tags") Array of strings. **SHOULD** be lowercase, alphanumeric and hyphens only. Tags **SHOULD** conform to the `tag` production in Appendix D. ### 12.6 Example[​](#126-example "Direct link to 12.6 Example") ``` { "metadata": { "authors": [ { "name": "Platform Team", "email": "platform@example.com", "url": "https://example.com/team/platform" } ], "license": "Apache-2.0", "documentation": "https://docs.example.com/agents/invoice-processor", "repository": "https://github.com/example/invoice-processor", "tags": ["finance", "invoice", "production"] } } ``` *** ## 13. Profiles[​](#13-profiles "Direct link to 13. Profiles") The `profiles` member declares which profiles the document conforms to. **OPTIONAL.** Value **MUST** be an array of profile identifiers (URIs or registered names). When a profile is declared: the document **MUST** satisfy all profile requirements, **MAY** use profile-defined members, and validators **SHOULD** check profile-specific rules. ADL defines two categories of profiles: * **Standard profiles** define domain-specific top-level members and validation rules. Standard profiles use the `urn:adl:profile:*` namespace and **SHOULD** be registered with the IANA profile registry (Section 13.5) to prevent naming conflicts. Examples: Governance (`urn:adl:profile:governance:1.0`), Healthcare, Financial. * **Vendor profiles** declare vendor-specific extensions with schema validation, targeting the `extensions` namespace rather than defining new top-level members. Vendor profiles use URI identifiers controlled by the vendor (e.g., `https://acme.com/adl/extensions/v1`) and do not require registration — the reverse-domain namespace provides collision prevention through DNS ownership. See Section 13.4. Both categories use the same `allOf` composition mechanism (Section 13.1) and **MAY** appear together in a document's `profiles` array. ### 13.1 Profile Schema Composition[​](#131-profile-schema-composition "Direct link to 13.1 Profile Schema Composition") Profiles extend the base ADL schema using the JSON Schema 2020-12 `allOf` composition mechanism. Each profile publishes a JSON Schema that: 1. References the base ADL schema via `allOf` with `$ref`. 2. Declares the profile's additional top-level members in its own `properties`. 3. Adds `unevaluatedProperties: false` to close the composed schema, ensuring only base ADL members, profile-defined members, and `extensions` members are accepted. The base ADL schema (Appendix A) does not restrict unknown top-level properties — it declares `properties` and `patternProperties` but omits `additionalProperties` and `unevaluatedProperties`. This allows profile schemas to add members via composition without conflict. For documents that do not declare any profiles, validators **SHOULD** use the strict schema (`schema-strict.json`), which adds `unevaluatedProperties: false` to reject unknown top-level members. Profile schemas **MUST NOT** redefine core ADL members with incompatible types. Profiles **MAY**: * Add top-level members. * Add members to existing objects (e.g., extending `data_classification` with domain-specific sub-objects). * Define validation rules. * Require specific values for optional core members. * Use conditional validation (`if`/`then`) to enforce tier-based or context-dependent requirements. ### 13.2 Multi-Profile Composition[​](#132-multi-profile-composition "Direct link to 13.2 Multi-Profile Composition") When a document declares multiple profiles, the document **MUST** satisfy all declared profile requirements. Validators compose profile schemas using `allOf` — each profile's schema is included as an element. JSON Schema `allOf` uses "strictest wins" semantics: if any profile requires a member, the composed result requires it. Profiles **MUST** be designed for independent composition. A profile's validation rules **MUST NOT** assume the absence of members defined by other profiles. For standard profiles, the IANA profile registry designated expert review (see Section 13.5) prevents cross-profile field naming conflicts. Vendor profiles avoid conflicts through their reverse-domain namespace isolation. ### 13.3 Profile Dependencies[​](#133-profile-dependencies "Direct link to 13.3 Profile Dependencies") A profile **MAY** declare dependencies on other profiles. When a profile declares a dependency, documents using that profile **MUST** also satisfy the dependency profile's requirements. The `profiles` array **MUST** include all transitive dependencies. At the schema level, a dependent profile composes its parent via `allOf`: ``` { "allOf": [ { "$ref": "https://adl-spec.org/0.3/schema.json" }, { "$ref": "https://adl-spec.org/profiles/governance/1.0/schema.json" } ], "properties": { "hipaa_data_handling": { "type": "object" } }, "unevaluatedProperties": false } ``` A dependent profile **MAY** tighten constraints from its parent (e.g., make an optional parent field required, narrow an enum). A dependent profile **MUST NOT** loosen constraints from its parent (e.g., make a required parent field optional). This follows from `allOf` semantics — the parent's constraints remain in force. If a dependent profile needs a parent field to not be required, this indicates a design issue. Resolutions include: refactoring the parent into a base profile with looser constraints, changing the relationship from dependency to sibling, or revising the parent profile in a new major version. ### 13.4 Vendor Profiles[​](#134-vendor-profiles "Direct link to 13.4 Vendor Profiles") A **vendor profile** is a profile published by an organization to declare vendor-specific extensions with schema validation. Vendor profiles use the same `allOf` composition mechanism as standard profiles (Section 13.1) but target the `extensions` namespace rather than defining new top-level members. See Section 13 for an overview of the standard/vendor profile taxonomy. Vendor profiles use URI identifiers controlled by the vendor (e.g., `https://acme.com/adl/extensions/v1`). The `urn:adl:profile:*` namespace is reserved for standard profiles. Vendor profiles **MUST NOT** use this namespace. A vendor profile **MAY** add schema constraints to the `extensions` object at any level, validating that its reverse-domain namespace contains the expected structure. The profile schema references the base ADL schema via `allOf` and declares `properties` for `extensions` within the relevant objects. A vendor profile **MAY** declare a dependency on a standard profile and add schema constraints to `extensions` within that profile's objects. The vendor profile composes its dependency via `allOf` and adds `extensions` constraints inside the profile-defined objects. This enables vendors to extend profile-defined objects without redefining them. Vendor profiles are subject to the following constraints: * Vendor profiles **MUST NOT** redefine core ADL members or standard profile members with incompatible types. * Vendor profiles **MUST** only add schema constraints within their own reverse-domain namespace under `extensions`. * A vendor profile's `extensions` schema applies only when the vendor profile is declared in the document's `profiles` array. * Documents **MAY** include `extensions` data for a vendor without declaring the vendor's profile. In this case, the data is preserved but unvalidated — implementations treat it as opaque. * Multiple vendor profiles compose independently. Each vendor's `extensions` constraints apply only within its own namespace. Vendor profiles do not require IANA registration. The reverse-domain namespace provides collision prevention through DNS ownership. Vendors **SHOULD**: * Publish their profile schema at a stable, dereferenceable URI. * Version their profile schemas (e.g., `/v1/`, `/v2/`). * Document the semantics of their extension fields. ### 13.5 Standard Profile Registration[​](#135-standard-profile-registration "Direct link to 13.5 Standard Profile Registration") Standard profile identifiers **SHOULD** be registered to prevent naming conflicts. Only standard profiles — those using the `urn:adl:profile:*` namespace — are subject to registration. Vendor profiles rely on reverse-domain namespace isolation and do not require registration (see Section 13.4). The registration authority (e.g., IANA profile registry) **MUST** employ designated expert review to ensure: 1. New standard profiles do not redefine members from existing profiles with incompatible semantics. 2. New standard profiles do not introduce field names that conflict with existing profiles. 3. Dependencies between profiles are explicitly declared and acyclic. If a member becomes cross-cutting (needed by multiple standard profiles), the registration authority **MAY** recommend promoting it to the core ADL specification. ### 13.6 Example[​](#136-example "Direct link to 13.6 Example") ``` { "adl_spec": "0.3.0", "name": "Invoice Processor", "version": "2.0.0", "description": "Processes invoices with governance and financial compliance.", "data_classification": { "sensitivity": "confidential", "categories": ["financial"] }, "profiles": [ "urn:adl:profile:governance:1.0", "urn:adl:profile:financial:1.0" ] } ``` *** ## 14. Processing ADL Documents[​](#14-processing-adl-documents "Direct link to 14. Processing ADL Documents") ### 14.1 Parsing[​](#141-parsing "Direct link to 14.1 Parsing") Implementations **MUST** parse ADL as JSON \[RFC8259], **MUST** reject invalid JSON, and **MUST** reject documents where the top-level value is not a JSON object. ### 14.2 Validation[​](#142-validation "Direct link to 14.2 Validation") Implementations **MUST** validate ADL documents against the JSON Schema defined in Appendix A. Implementations **MUST** validate the following semantic rules: | Rule | Description | | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | | VAL-01 | `adl_spec` MUST match a supported version | | VAL-02 | Tool names MUST be unique | | VAL-03 | Resource names MUST be unique | | VAL-04 | Prompt names MUST be unique | | VAL-05 | Timestamps MUST be valid ISO 8601 | | VAL-06 | URIs MUST be valid per RFC 3986 | | VAL-07 | JSON Schema in parameters/returns MUST be valid | | VAL-08 | Profile requirements MUST be satisfied | | VAL-09 | `lifecycle.status` MUST be a valid status value if present | | VAL-10 | `lifecycle.effective_date` MUST be valid ISO 8601 if present | | VAL-11 | `lifecycle.sunset_date` MUST be valid ISO 8601 if present | | VAL-12 | `lifecycle.successor` MUST be a valid URI if present | | VAL-13 | Tool names MUST match `^[a-z][a-z0-9_]*$` | | VAL-14 | Resource `type` MUST be a valid resource type value | | VAL-15 | `model.temperature` MUST be between 0.0 and 2.0 if present | | VAL-16 | `security.authentication.type` MUST be a valid authentication type if present | | VAL-17 | `security.attestation.type` MUST be a valid attestation type if present | | VAL-18 | `runtime.error_handling.on_tool_error` MUST be a valid error action if present | | VAL-19 | `runtime.output_handling.format` MUST be a valid format value if present | | VAL-20 | `model.capabilities` items MUST be valid capability values if present | | VAL-21 | Host patterns MUST conform to Section 4.4 pattern syntax | | VAL-22 | Filesystem path patterns MUST conform to Section 4.4 pattern syntax | | VAL-23 | Environment variable patterns MUST conform to Section 4.4 pattern syntax | | VAL-24 | Attestation `signature.signed_content` value `"digest"` MUST have `digest_algorithm` and `digest_value` present | | VAL-25 | `data_classification.sensitivity` MUST be a valid sensitivity level if present | | VAL-26 | `data_classification.categories` items MUST be valid category values if present | | VAL-27 | `data_classification.retention.min_days` MUST be less than or equal to `max_days` when both are present | | VAL-28 | Top-level `data_classification.sensitivity` MUST be >= the highest `sensitivity` in any tool or resource `data_classification` (high-water mark) | | VAL-29 | Every `permissions.resource_limits.budget` cap MUST be a number greater than `0` | | VAL-30 | Within any `budget` dimension, `per_session` MUST be <= `per_day` when both are present | | VAL-31 | Each `runtime.degradation` response `action` MUST be one of `halt`, `pause`, `fallback`, `continue` | | VAL-32 | `runtime.tool_invocation.max_iterations` and `max_tool_calls_per_session`, when present, MUST be integers >= 1 | | VAL-33 | `runtime.tool_invocation.loop_detection.window`, when present, MUST be an integer >= 2 | | VAL-34 | `permissions.delegation.match` and `deny` patterns MUST conform to Section 4.4 pattern syntax | | VAL-35 | `permissions.delegation.max_depth`, when present, MUST be an integer >= 1 | | VAL-35a | Each `permissions.sub_agents[]` entry MUST have a `name`, unique within the array; a persona's `tools` MUST be a subset of the parent's `tools` | | VAL-36 | Each `runtime.degradation` cause key MUST match `^on_[a-z0-9_]+$` | | VAL-37 | Any value using the `urn:adl:` URN scheme MUST conform to the `adl-urn` production (Appendix D), including a `{type}` segment of `agent` or `profile` | Implementations **MAY** perform additional validation based on declared profiles. ### 14.3 Unknown Members[​](#143-unknown-members "Direct link to 14.3 Unknown Members") Implementations **MUST** preserve unrecognized members when round-tripping. Implementations **MUST NOT** reject documents containing `extensions` with unknown vendor namespaces. Implementations **MAY** warn on unknown non-extension, non-profile members. *** ## 15. Interoperability[​](#15-interoperability "Direct link to 15. Interoperability") ### 15.1 A2A Agent Card Generation[​](#151-a2a-agent-card-generation "Direct link to 15.1 A2A Agent Card Generation") Implementations **SHOULD** support generating A2A Agent Cards from ADL (e.g., name, description, version, tools→skills, cryptographic\_identity.did→id, security.authentication→authentication). ### 15.2 MCP Server Configuration[​](#152-mcp-server-configuration "Direct link to 15.2 MCP Server Configuration") Implementations **SHOULD** support generating MCP server configurations (name, description, version, tools, resources, prompts). ### 15.3 OpenAPI Integration[​](#153-openapi-integration "Direct link to 15.3 OpenAPI Integration") Tools that invoke HTTP APIs **MAY** reference OpenAPI specs. The tool `annotations` object **MAY** contain `openapi_ref` (URI) and `operation_id`. *** ## 16. Errors[​](#16-errors "Direct link to 16. Errors") ### 16.1 Error Format[​](#161-error-format "Direct link to 16.1 Error Format") Implementations **SHOULD** return errors in a consistent format, e.g.: ``` { "errors": [ { "code": "ADL-1001", "title": "Invalid JSON", "detail": "Unexpected token at line 42, column 15", "source": { "pointer": "/tools/0/name" } } ] } ``` The `source` object **MAY** contain: `pointer` (JSON Pointer to the error location), `line` (1-indexed), `column` (1-indexed). ### 16.2 Error Codes[​](#162-error-codes "Direct link to 16.2 Error Codes") | Code | Category | Description | | -------- | --------- | ------------------------------------------------------------------------------------------------------------------------------- | | ADL-1001 | Parse | Invalid JSON syntax | | ADL-1002 | Parse | Document is not a JSON object | | ADL-1003 | Schema | Missing required member | | ADL-1004 | Schema | Invalid member type | | ADL-1005 | Schema | Invalid enum value | | ADL-1006 | Schema | Value does not match pattern | | ADL-2001 | Semantic | Unsupported ADL version | | ADL-2002 | Semantic | Duplicate tool name | | ADL-2003 | Semantic | Duplicate resource name | | ADL-2004 | Semantic | Duplicate prompt name | | ADL-2005 | Semantic | Invalid timestamp format | | ADL-2006 | Semantic | Invalid URI format | | ADL-2007 | Semantic | Invalid JSON Schema | | ADL-2008 | Semantic | Invalid tool name pattern | | ADL-2009 | Semantic | Invalid resource type value | | ADL-2010 | Semantic | Temperature out of range | | ADL-2011 | Semantic | Invalid authentication type | | ADL-2012 | Semantic | Invalid attestation type | | ADL-2013 | Semantic | Invalid error handling action | | ADL-2014 | Semantic | Invalid output format | | ADL-2015 | Semantic | Invalid model capability | | ADL-2016 | Semantic | Invalid host pattern syntax | | ADL-2017 | Semantic | Invalid filesystem path pattern | | ADL-2018 | Semantic | Invalid environment variable pattern | | ADL-2019 | Semantic | Missing digest fields for digest-mode signature | | ADL-2020 | Semantic | Invalid data classification sensitivity level | | ADL-2021 | Semantic | Invalid data classification category | | ADL-2022 | Semantic | Retention min\_days exceeds max\_days | | ADL-2023 | Semantic | Top-level sensitivity below tool/resource sensitivity (high-water mark violation) | | ADL-2024 | Semantic | Undefined template variable | | ADL-2025 | Semantic | Invalid ADL URN: a `urn:adl:` value does not conform to the `adl-urn` production (missing or invalid `{type}` segment) (VAL-37) | | ADL-3001 | Profile | Profile requirements not satisfied | | ADL-3002 | Profile | Unknown profile | | ADL-4001 | Security | Weak key algorithm | | ADL-4002 | Security | Invalid signature | | ADL-4003 | Security | Expired attestation | | ADL-5001 | Lifecycle | Invalid lifecycle status value | | ADL-5002 | Lifecycle | Successor present on active/draft agent | | ADL-5003 | Lifecycle | Sunset date in the past with non-retired status | | ADL-6001 | Runtime | Resource-limit budget cap not greater than zero (VAL-29) | | ADL-6002 | Runtime | Budget `per_session` exceeds `per_day` (VAL-30) | | ADL-6003 | Runtime | Invalid degradation response action (VAL-31) | | ADL-6004 | Runtime | Invalid tool-invocation iteration limit (VAL-32) | | ADL-6005 | Runtime | Invalid loop-detection window (VAL-33) | | ADL-6006 | Runtime | Invalid sub-agent pattern syntax (VAL-34) | | ADL-6007 | Runtime | Invalid sub-agent `max_depth` (VAL-35) | | ADL-6008 | Runtime | Invalid degradation cause key (VAL-36) | | ADL-6009 | Runtime | Invalid sub-agent declaration: missing or duplicate `name`, or `tools` not a subset of the parent's (VAL-35a) | ### 16.3 Error Source Examples[​](#163-error-source-examples "Direct link to 16.3 Error Source Examples") The `source.pointer` member uses JSON Pointer \[RFC6901] to identify the location of the error within the ADL document. The following examples illustrate `source` values for representative error codes from each category: ``` // ADL-1003 (Schema): Missing required member "data_classification" { "code": "ADL-1003", "title": "Missing required member", "detail": "Required member 'data_classification' is missing", "source": { "pointer": "" } } ``` ``` // ADL-2002 (Semantic): Duplicate tool name at index 2 { "code": "ADL-2002", "title": "Duplicate tool name", "detail": "Tool name 'search_documents' already defined at index 0", "source": { "pointer": "/tools/2/name" } } ``` ``` // ADL-2016 (Semantic): Invalid host pattern in permissions { "code": "ADL-2016", "title": "Invalid host pattern syntax", "detail": "Pattern '**' is not a valid host pattern", "source": { "pointer": "/permissions/network/allowed_hosts/1" } } ``` ``` // ADL-2023 (Semantic): High-water mark violation on a tool { "code": "ADL-2023", "title": "High-water mark violation", "detail": "Tool 'query_records' has sensitivity 'confidential' which exceeds top-level 'internal'", "source": { "pointer": "/tools/1/data_classification/sensitivity" } } ``` ``` // ADL-3001 (Profile): Profile requirement not satisfied { "code": "ADL-3001", "title": "Profile requirements not satisfied", "detail": "Governance profile requires 'compliance' member", "source": { "pointer": "/profiles/0" } } ``` ``` // ADL-4001 (Security): Weak key algorithm { "code": "ADL-4001", "title": "Weak key algorithm", "detail": "Algorithm 'RS256' with 1024-bit key does not meet minimum strength requirements", "source": { "pointer": "/cryptographic_identity/public_key" } } ``` ``` // ADL-5002 (Lifecycle): Successor on active agent { "code": "ADL-5002", "title": "Successor present on non-retired agent", "detail": "Member 'successor' is only valid when lifecycle.status is 'retired'", "source": { "pointer": "/lifecycle/successor" } } ``` *** ## 17. IANA Considerations[​](#17-iana-considerations "Direct link to 17. IANA Considerations") ### 17.1 Media Type[​](#171-media-type "Direct link to 17.1 Media Type") This document requests IANA to register the `application/adl+json` media type in the "Media Types" registry in accordance with \[RFC6838]. * **Type name:** application * **Subtype name:** adl+json * **Required parameters:** None * **Optional parameters:** * `profile` — A comma-separated list of ADL profile identifiers (URIs or registered names from the ADL Profile Registry defined in Section 17.2) that the document conforms to. Each identifier **MUST** be a URI conforming to \[RFC3986]. Consumers that do not recognize a profile identifier **MAY** ignore the parameter and **MUST** preserve it when retransmitting the document. * **Encoding considerations:** binary — ADL documents are JSON text sequences encoded in UTF-8 \[RFC8259]. No other character encoding is permitted. Consistent with \[RFC8259], UTF-8 without a byte-order mark (BOM) is **RECOMMENDED**. * **Security considerations:** ADL documents declare agent behavior including permission grants, system prompt templates, tool invocation configuration, and cryptographic identity. Processors **MUST** treat content from untrusted sources with appropriate caution. Template variables in `system_prompt` and prompt templates use a `{{variable_name}}` substitution syntax; processors **MUST** sanitize variable values before substitution to prevent prompt injection attacks that could alter agent behavior. ADL documents include URI references in fields such as `$schema`, `openapi_ref`, `documentation`, and `repository`; processors **MUST NOT** automatically dereference these URIs from untrusted documents, as doing so may target internal network resources and enable Server-Side Request Forgery (SSRF). Documents that declare broad permissions (e.g., a bare `*` wildcard in `allowed_hosts`) represent elevated risk and **SHOULD** require explicit human review before deployment. Processors **SHOULD** impose limits on document size, JSON nesting depth, and array lengths to prevent resource exhaustion from adversarially crafted documents. For a comprehensive treatment of all security considerations applicable to this media type, see Section 18. * **Interoperability considerations:** ADL documents **MUST** be processed as JSON \[RFC8259] regardless of authoring format. YAML is a common authoring convenience, but processors **MUST** operate on the JSON form; documents intended to be signed using JCS \[RFC8785] **MUST** be serialized as JSON before signing. Profile declarations — whether via the `profile` optional parameter or the `profiles` document member — allow multiple profiles to compose within a single document; consumers that partially implement profile requirements **SHOULD** process the members they recognize and preserve unrecognized members per Section 14.3. Validation against the JSON Schema defined in Appendix A provides a baseline interoperability check. Implementations that generate A2A Agent Cards or MCP server configurations from ADL documents **SHOULD** follow the mappings defined in Section 15. Producers **SHOULD** include the `$schema` member to enable tooling-assisted validation. * **Published specification:** \[this document] * **Applications that use this media type:** AI agent platforms, agent registries, development tools, orchestration frameworks, and runtime environments that provision and manage AI agents. * **Fragment identifier considerations:** Fragment identifiers for resources of this type **SHOULD** be interpreted as JSON Pointer expressions \[RFC6901] identifying a location within the ADL document object. * **Additional information:** * Deprecated alias names for this type: N/A * Magic number(s): N/A * File extension(s): `.adl.json`, `.adl` * Macintosh file type code(s): N/A * Object Identifiers: N/A * **Person and email address to contact for further information:** See the Author's Address section of this document. * **Intended usage:** COMMON * **Restrictions on usage:** None * **Author:** See the Author's Address section of this document. * **Change controller:** IETF ### 17.2 Profile Registry[​](#172-profile-registry "Direct link to 17.2 Profile Registry") IANA is requested to create and maintain a new registry titled **"ADL Profile Registry"** within a new "Agent Definition Language (ADL)" registry group. **Registration Policy:** Specification Required \[RFC8126]. The designated expert reviews registration requests to verify that the profile is documented in a publicly available, stable specification and that all required registration template fields are complete. **Registration Template:** Parties wishing to register a profile **MUST** provide all of the following fields: | Field | Description | | ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Identifier (URI) | A URI that uniquely identifies the profile, conforming to \[RFC3986]. The URI **SHOULD** be dereferenceable and return a human-readable description of the profile. | | Name | A short human-readable name for the profile (e.g., "ADL Governance Profile"). | | Version | The profile version string in MAJOR.MINOR form (optionally MAJOR.MINOR.PATCH), matching the `{version}` segment of the profile URN (Section 17.3). | | Specification Reference | A stable, publicly accessible URI or document reference for the profile specification. The specification **MUST** define all profile-required members, validation rules, and any additional semantics added by the profile. | | ADL Version Compatibility | The ADL specification version(s) with which the profile is designed to operate (e.g., "0.2.x"). | | Contact | Name and email address of the person or group responsible for the profile registration. | | Status | One of: `active` (currently maintained) or `deprecated` (superseded or abandoned). | **Initial Registry Contents:** | Identifier (URI) | Name | Version | | -------------------------------- | ---------------------- | ------- | | `urn:adl:profile:governance:1.0` | ADL Governance Profile | 1.0.0 | | `urn:adl:profile:portfolio:1.0` | ADL Portfolio Profile | 1.0.0 | | `urn:adl:profile:healthcare:1.0` | ADL Healthcare Profile | 1.0.0 | | `urn:adl:profile:financial:1.0` | ADL Financial Profile | 1.0.0 | All initial entries reference Appendix C of this document, target ADL compatibility 0.2.x, are `active`, and list the Author's Address as contact. **Designated Expert Criteria:** The designated expert **SHOULD** evaluate requests against the following criteria: 1. **Publicly available specification:** The profile specification **MUST** be accessible at a stable, public URI. Specifications behind paywalls or access controls are not acceptable for registration. 2. **Non-conflict with core ADL:** The profile **MUST NOT** redefine or contradict normative requirements of the core ADL specification. Profiles **MAY** add new members, constrain optional members to a subset of permitted values, or require that optional core members be present. 3. **Complete registration template:** All required template fields **MUST** be present and non-empty. Incomplete registrations **MUST** be returned to the submitter. 4. **Stable identifier:** The profile URI **SHOULD** be dereferenceable and **SHOULD** remain stable over time. Ephemeral or frequently changing URIs are not acceptable. 5. **Legitimate purpose:** The profile **SHOULD** address a genuine domain or deployment need not already covered by an existing active registered profile. ### 17.3 URN Namespace[​](#173-urn-namespace "Direct link to 17.3 URN Namespace") IANA is requested to register the `adl` URN namespace identifier in the "Formal URN Namespaces" registry in accordance with \[RFC8141]. * **Namespace Identifier:** `adl` * **Version:** 1 * **Date:** \[date of publication] * **Registrant:** See the Author's Address section of this document. * **Purpose:** The `urn:adl:` namespace provides persistent, location-independent identifiers for ADL agents, profiles, and related artifacts. These identifiers are intended for use in offline catalogs, air-gapped environments, and internal registries where network resolution is unavailable. For connected environments, HTTPS URIs (Section 6.1) are the **RECOMMENDED** identifier format. * **Syntax:** URNs in this namespace take one of two type-discriminated forms. **Agent URNs** are `urn:adl:agent:{namespace}:{name}:{version}`, where `{namespace}` is a lowercase alphanumeric organization identifier and `{name}` is a lowercase alphanumeric resource name (which may contain hyphens). **Profile URNs** are `urn:adl:profile:{name}:{version}`, where `{name}` is the registry-assigned profile name; profile URNs carry no organization namespace. `{version}` is a semantic version (MAJOR.MINOR.PATCH) for agent URNs and a MAJOR.MINOR (optionally MAJOR.MINOR.PATCH) version for profile URNs. The formal syntax is defined by the `adl-urn` production in Appendix D. A `urn:adl:` value that does not conform to `adl-urn` — for example, an agent URN omitting the `{namespace}` segment, or any URN whose type segment is neither `agent` nor `profile` — **MUST** be rejected (VAL-37, error `ADL-2025`). * **Assignment:** Sub-namespace assignment under `urn:adl:profile:` is governed by the ADL Profile Registry (Section 17.2). Sub-namespace assignment under `urn:adl:agent:` is at the discretion of the namespace holder; no central registry is required for agent URNs. * **Security and Privacy:** URN identifiers in this namespace are opaque strings and carry no inherent security properties. Implementations **MUST NOT** infer ownership, trust, or authorization from a `urn:adl:` identifier alone. Verification of agent identity **MUST** rely on the mechanisms described in Section 6.3 (Cryptographic Identity) and Section 10.2 (Attestation). See Section 18 for comprehensive security considerations. ### 17.4 Well-Known URI[​](#174-well-known-uri "Direct link to 17.4 Well-Known URI") IANA is requested to register the `adl-agents` well-known URI suffix in the "Well-Known URIs" registry in accordance with \[RFC8615]. * **URI suffix:** adl-agents * **Change controller:** IETF * **Specification document:** Section 6.4 of \[this document] * **Status:** permanent * **Related information:** The well-known URI `https://{domain}/.well-known/adl-agents` returns a JSON document listing all ADL agents published by the domain authority. The document format is defined in Section 6.4. The resource **MUST** be served over HTTPS. *** ## 18. Security Considerations[​](#18-security-considerations "Direct link to 18. Security Considerations") ### 18.1 Document Integrity[​](#181-document-integrity "Direct link to 18.1 Document Integrity") ADL documents define agent behavior, permission grants, and security requirements. The trust model for an ADL document depends on its provenance and the integrity mechanisms applied to it. Unsigned ADL documents from untrusted or unverified sources **MUST** be treated as potentially malicious. When a document includes a cryptographic signature in `security.attestation.signature`, implementations **MUST** verify the signature before acting on the document's permission or security declarations. Signature verification requires serializing the document (with the signature object removed) using JCS \[RFC8785] to produce a canonical byte sequence, then verifying the resulting digest using the algorithm and public key declared in `cryptographic_identity`. Implementations **MUST** reject documents that claim to be signed but whose signature does not verify. Implementations **SHOULD** warn when processing signed documents whose attestation has expired (`expires_at` is in the past). An ADL document whose permissions or capabilities have been modified after signing will produce a different canonical byte sequence and fail signature verification; this is the intended behavior and provides protection against privilege escalation via document tampering. ### 18.2 Sensitive Data in ADL Documents[​](#182-sensitive-data-in-adl-documents "Direct link to 18.2 Sensitive Data in ADL Documents") ADL documents **SHOULD NOT** contain secrets, credentials, or other sensitive data in plaintext. Fields such as `system_prompt`, `provider.contact`, `metadata.authors`, and tool parameter examples may inadvertently expose confidential information if documents are logged, cached, or transmitted without adequate access controls. API keys, passwords, private keys, bearer tokens, and other authentication material **MUST NOT** appear as literal string values in ADL documents. Where agent configuration requires secret values at runtime, implementations **SHOULD** use environment variable references or external secret manager URIs rather than embedding values directly. Implementations **SHOULD** warn when string values match patterns commonly associated with credentials (e.g., values matching the format of known API key prefixes). Organizations **SHOULD** subject ADL documents to the same secret-scanning controls applied to source code repositories before storage or distribution. ### 18.3 Template Injection[​](#183-template-injection "Direct link to 18.3 Template Injection") The `system_prompt` member (Section 7.2) and `prompts[*].template` members (Section 8.3) support a template substitution syntax using `{{variable_name}}` placeholders. If variable values are derived from untrusted user input and substituted without sanitization, an attacker may be able to alter agent behavior by injecting malicious instructions into the rendered prompt — including instructions that override the intended agent behavior or cause the agent to exfiltrate information. Implementations **MUST** sanitize template variable values before substitution. At minimum, implementations **SHOULD** escape or reject values that contain the template delimiter sequence `{{` or `}}`, and **SHOULD** apply length limits to variable values. Applications that allow end users to supply template variable values **SHOULD** treat such values as untrusted and apply content validation appropriate to the deployment context. Runtimes operating on agents with `data_classification.sensitivity` of `confidential` or `restricted` **SHOULD** log rendered prompts (after variable substitution) to enable post-incident review, subject to applicable privacy constraints. ### 18.4 Information Disclosure[​](#184-information-disclosure "Direct link to 18.4 Information Disclosure") ADL documents may reveal infrastructure details that are useful to attackers. The `name`, `description`, and tool `description` fields may disclose the existence of internal services or system architecture. The `permissions.network.allowed_hosts` list may reveal internal hostname patterns, private IP ranges, or internal service naming conventions. The `permissions.filesystem.allowed_paths` list may reveal sensitive directory structures. The `provider.url`, `metadata.documentation`, and `metadata.repository` fields may reference internal systems not intended for public visibility. ADL documents intended for public distribution **SHOULD** be reviewed to remove or generalize infrastructure-specific information. Host patterns **SHOULD** use registered domain names rather than IP addresses or internal hostnames. Path patterns **SHOULD** avoid exposing sensitive directory names. Documents with `data_classification.sensitivity` of `confidential` or `restricted` **SHOULD** only be distributed to parties with appropriate access authorization and **SHOULD NOT** be published to public registries without thorough review. ### 18.5 Resource Exhaustion[​](#185-resource-exhaustion "Direct link to 18.5 Resource Exhaustion") Implementations that parse and validate ADL documents are susceptible to resource exhaustion from adversarially crafted inputs. Specific attack vectors include: deeply nested JSON Schema in `parameters` and `returns` members (including circular `$ref` chains or exponentially expanding `allOf`/`anyOf` combinators); documents with very large numbers of tools, resources, or prompts; and documents with excessively long string values in `system_prompt`, description fields, or pattern arrays. Implementations **SHOULD** enforce and document limits on: total document size (recommended maximum: 1 MB); JSON nesting depth (recommended maximum: 32 levels); number of entries in `tools`, `resources`, and `prompts` arrays (recommended maximum: 1000 each); string length for `system_prompt` and description fields (recommended maximum: 1 MB per field); and number of entries in any permission pattern array (recommended maximum: 500 patterns per domain). Implementations **SHOULD** terminate processing with an appropriate error code when any of these limits is exceeded rather than continuing to consume resources. ### 18.6 Pattern Matching Abuse[​](#186-pattern-matching-abuse "Direct link to 18.6 Pattern Matching Abuse") The permission pattern syntax (Section 4.4) governs access grants across network, filesystem, environment variable, and execution domains. Overly permissive patterns undermine the deny-by-default permission model; patterns that are expensive to evaluate can enable denial-of-service. A bare `*` as the sole value of an entry in `allowed_hosts` grants access to all hostnames and effectively disables network permission enforcement. Implementations **MUST** warn when a bare `*` wildcard is used in any security-sensitive permission pattern, including `allowed_hosts` and `allowed_variables`. Implementations **SHOULD** require explicit user acknowledgment — or refuse to deploy — agents that use bare `*` patterns in these domains. Pattern evaluation **SHOULD** be bounded in time and space: implementations that use backtracking pattern matchers **SHOULD** reject or normalize patterns that would require exponential backtracking (e.g., consecutive wildcards such as `***`). The `**` multi-segment wildcard **MUST NOT** appear in host, environment, or command patterns, and implementations **MUST** reject documents in which it does. ### 18.7 URI Reference Attacks (SSRF)[​](#187-uri-reference-attacks-ssrf "Direct link to 18.7 URI Reference Attacks (SSRF)") Multiple ADL fields accept URI values: `$schema`, `id`, `provider.url`, `metadata.documentation`, `metadata.repository`, `resource.uri`, `tool.annotations.openapi_ref`, `lifecycle.successor`, `security.attestation.issuer`, and others defined by profiles. If an implementation automatically dereferences these URIs when processing a document from an untrusted source, an attacker may cause the implementation to issue requests to arbitrary endpoints, including internal services not reachable from the public internet — a class of vulnerability known as Server-Side Request Forgery (SSRF). Implementations **MUST NOT** automatically dereference URI values from ADL documents received from untrusted sources without explicit operator or user consent. Implementations that fetch external schema documents (e.g., via `$schema`) for validation purposes **SHOULD** use an allowlist of trusted schema hosts and **MUST NOT** follow redirects that leave the trusted set. When fetching `openapi_ref` documents for tool description or validation, implementations **SHOULD** verify that the target URI matches a pre-approved allowlist. Implementations **SHOULD** validate that URI values in ADL documents conform to \[RFC3986] and **SHOULD** reject URIs with schemes other than `https`, `http`, or `urn` unless the deployment context explicitly allows them. ### 18.8 Canonicalization Attacks[​](#188-canonicalization-attacks "Direct link to 18.8 Canonicalization Attacks") ADL supports document integrity verification via cryptographic signatures using JCS canonicalization \[RFC8785]. The security of this mechanism depends on all conforming implementations producing identical canonical byte sequences for the same logical document. Subtle differences in JCS implementations — such as incorrect handling of Unicode escape sequences, floating-point number serialization, or object member ordering — could cause a legitimate signature to fail verification, or, more critically, allow an attacker to construct a document where different implementations produce different canonical forms, potentially enabling a signature verification bypass. Implementations **MUST** use a conformant JCS \[RFC8785] implementation for both signing and verification. Implementations **SHOULD** validate their JCS implementation against the test vectors provided in RFC 8785 before use in a production environment. Implementations **MUST NOT** verify signatures against non-canonical serializations such as pretty-printed JSON or YAML. Implementations that process ADL documents containing IEEE 754 floating-point values in signed content **SHOULD** be aware that platform-specific floating-point representation differences may affect canonicalization and **SHOULD** avoid floating-point values in fields that will be signed when possible. ### 18.9 Privacy Considerations[​](#189-privacy-considerations "Direct link to 18.9 Privacy Considerations") ADL documents may contain personal information subject to applicable privacy regulations. The `provider.contact` field (Section 6.2) contains a contact email address. The `metadata.authors` array (Section 12.1) may contain author names, email addresses, and URLs. The `system_prompt` member may contain information about intended user roles, user populations, or organizational context. When ADL documents are published to public registries or shared broadly, this information becomes publicly accessible. Publishers **SHOULD** review ADL documents for personally identifiable information (PII) before public distribution and **SHOULD** use organizational or role-based contact addresses rather than personal email addresses. Implementations that log ADL document contents for debugging or auditing **SHOULD** redact or omit `provider.contact`, `metadata.authors`, and `system_prompt` fields from logs unless there is a documented operational requirement to retain them. Users **SHOULD** be informed when their ADL documents are transmitted to third-party services for validation, indexing, or registry queries. ### 18.10 Privilege Escalation[​](#1810-privilege-escalation "Direct link to 18.10 Privilege Escalation") An ADL document that has been modified — whether by a malicious actor during transmission or by a compromised storage or distribution system — could grant an agent permissions or capabilities beyond those that were reviewed and approved for deployment. This risk is the primary motivator for the integrity mechanisms described in Section 10.2. Implementations **SHOULD** verify document integrity (Section 10.2) before enforcing the permissions declared in a document, particularly when documents are retrieved from network locations, shared storage systems, or public registries. Runtimes that cannot verify document integrity **SHOULD** apply compensating controls — such as mandatory human review — before deploying agents that declare elevated permissions or sensitive data access. When a document's `data_classification.sensitivity` is `confidential` or `restricted`, runtimes **SHOULD** require a verified signature or a verified supply chain (e.g., document retrieved from a trusted registry over an authenticated and integrity-protected channel) before provisioning. Organizations **SHOULD** maintain an inventory of approved ADL documents along with their expected signatures or cryptographic digests, and **SHOULD** treat any discrepancy between the recorded and observed document as a potential security incident. ### 18.11 Cross-Origin and Supply Chain Concerns[​](#1811-cross-origin-and-supply-chain-concerns "Direct link to 18.11 Cross-Origin and Supply Chain Concerns") ADL documents may be fetched from remote sources: registries, source control systems, artifact stores, or agent marketplaces. A document tampered with in transit or at the origin could cause a runtime to provision a malicious agent without the operator's knowledge. ADL documents **SHOULD** be fetched over authenticated, integrity-protected channels (HTTPS with full certificate validation). Implementations **SHOULD** verify document signatures (Section 10.2) when documents are retrieved from remote or third-party sources. Implementations **SHOULD** validate that the signing identity declared in `cryptographic_identity` matches an expected, trusted identity for the document's declared `provider`. Supply chain integrity requires attention at every reference boundary: the ADL document itself, referenced OpenAPI specifications (`openapi_ref`), and external JSON Schemas (`$schema`). Implementations that automatically resolve external references during provisioning **SHOULD** pin or verify all such references. When accepting ADL documents from third-party sources, implementations **SHOULD** apply an allowlist of trusted providers (based on `provider.name` or `id` URI authority), verify attestation signatures from trusted issuers, and treat documents from unverified sources with the same caution applied to untrusted executable code. ### 18.12 Permission Model and Defense in Depth[​](#1812-permission-model-and-defense-in-depth "Direct link to 18.12 Permission Model and Defense in Depth") The deny-by-default permission model (Section 9.1) is a foundational security property of ADL: an agent can only access resources and capabilities that its ADL document explicitly permits. However, the effectiveness of this model depends entirely on the runtime correctly enforcing declared permissions. No permission model is a substitute for defense in depth. Runtimes **MUST** enforce declared permissions and **MUST NOT** allow agents to exceed those permissions under any circumstances, including error conditions or fallback behaviors. Runtimes that cannot enforce a specific permission domain (e.g., because the underlying platform lacks the required isolation primitives) **MUST** warn users before execution and **SHOULD** refuse to execute the agent unless the user explicitly acknowledges the limitation. Beyond permission enforcement, runtimes **SHOULD** monitor agent behavior during execution: logging tool invocations, recording network destinations contacted, and alerting on anomalous activity such as repeated attempts to access resources outside declared permissions. The ADL document represents intended access boundaries at definition time; runtime monitoring ensures actual behavior remains within those boundaries in production. Runtimes **SHOULD** validate tool inputs and outputs against the declared JSON Schema (Section 8.1) before passing them to or from the agent. Malformed responses from external tool implementations could inject unexpected data into agent reasoning; runtime-level schema validation provides a defense against malfunctioning or malicious tool backends. Tools annotated with `requires_confirmation: true` **MUST** receive explicit user confirmation before invocation; runtimes **MUST NOT** invoke such tools autonomously regardless of other configuration. Lifecycle status **MUST** be enforced as a security boundary. Runtimes **MUST NOT** provision or execute agents with `lifecycle.status` of `retired`. Retired agents may have revoked credentials, unpatched vulnerabilities, or stale permission configurations. Agents with `lifecycle.status` of `deprecated` **SHOULD** trigger warnings to operators, who **SHOULD** migrate to the agent identified by `lifecycle.successor` before the `sunset_date` is reached. *** ## 19. References[​](#19-references "Direct link to 19. References") ### 19.1 Normative References[​](#191-normative-references "Direct link to 19.1 Normative References") * **\[RFC2119]** Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, . * **\[RFC3986]** Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform Resource Identifier (URI): Generic Syntax", STD 66, RFC 3986, . * **\[RFC6749]** Hardt, D., Ed., "The OAuth 2.0 Authorization Framework", RFC 6749, . * **\[RFC6838]** Freed, N., Klensin, J., and T. Hansen, "Media Type Specifications and Registration Procedures", BCP 13, RFC 6838, . * **\[RFC6901]** Bryan, P., Ed., "JavaScript Object Notation (JSON) Pointer", RFC 6901, . * **\[RFC7636]** Sakimura, N., Ed., Bradley, J., and N. Agarwal, "Proof Key for Code Exchange by OAuth Public Clients", RFC 7636, . * **\[RFC8126]** Cotton, M., Leiba, B., and T. Narten, "Guidelines for Writing an IANA Considerations Section in RFCs", BCP 26, RFC 8126, . * **\[RFC8141]** Saint-Andre, P. and J. Klensin, "Uniform Resource Names (URNs)", RFC 8141, . * **\[RFC8174]** Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, . * **\[RFC8259]** Bray, T., Ed., "The JavaScript Object Notation (JSON) Data Interchange Format", STD 90, RFC 8259, . * **\[RFC8615]** Nottingham, M., "Well-Known Uniform Resource Identifiers (URIs)", RFC 8615, . * **\[RFC8705]** Campbell, B., Bradley, J., Sakimura, N., and T. Lodderstedt, "OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens", RFC 8705, . * **\[RFC8785]** Rundgren, A., Jordan, B., and S. Erdtman, "JSON Canonicalization Scheme (JCS)", RFC 8785, . * **\[RFC9449]** Fett, D., Campbell, B., Bradley, J., Lodderstedt, T., Jones, M., and D. Waite, "OAuth 2.0 Demonstrating Proof of Possession (DPoP)", RFC 9449, . * **\[RFC9700]** Lodderstedt, T., Bradley, J., Labunets, A., and D. Fett, "Best Current Practice for OAuth 2.0 Security", BCP 240, RFC 9700, . ### 19.2 Informative References[​](#192-informative-references "Direct link to 19.2 Informative References") * **\[A2A]** A2A Protocol Working Group, "Agent2Agent (A2A) Protocol Specification", . * **\[CLTC-AGENTIC]** Center for Long-Term Cybersecurity (CLTC), UC Berkeley, "Agentic AI Risk-Management Standards Profile", February 2026, . * **\[IMDA-AGENTIC]** Infocomm Media Development Authority (IMDA), "Model AI Governance Framework for Agentic AI", Version 1.5, May 2026, . * **\[JSON-SCHEMA]** Wright, A., et al., "JSON Schema: A Media Type for Describing JSON Documents", . * **\[MCP]** Anthropic, "Model Context Protocol Specification", . * **\[OAUTH2.1]** Parecki, A., Hardt, D., and T. Lodderstedt, "The OAuth 2.1 Authorization Framework", Work in Progress, Internet-Draft, draft-ietf-oauth-v2-1, . * **\[OPENAPI]** OpenAPI Initiative, "OpenAPI Specification", Version 3.1, . * **\[OPENID-CONNECT]** Sakimura, N., Bradley, J., Jones, M., de Medeiros, B., and C. Mortimore, "OpenID Connect Core 1.0", November 2014, . * **\[W3C.DID]** Sporny, M., et al., "Decentralized Identifiers (DIDs) v1.0", W3C Recommendation, . * **\[W3C.VC]** Sporny, M., et al., "Verifiable Credentials Data Model v2.0", W3C Recommendation, . * **\[ISO-22989]** ISO/IEC JTC 1/SC 42, "Information technology — Artificial intelligence — Artificial intelligence concepts and terminology", ISO/IEC 22989:2022, . * **\[AI-PROTOCOLS]** Rosenberg, J., "Framework, Use Cases and Requirements for AI Agent Protocols", Internet-Draft draft-rosenberg-ai-protocols-00, 2025, . *** ## Appendix A. JSON Schema[​](#appendix-a-json-schema "Direct link to Appendix A. JSON Schema") The normative JSON Schema for ADL is available at `https://adl-spec.org/0.3/schema.json` (JSON Schema Draft 2020-12). A minimal required-fields schema is provided in [schema.json](/assets/files/schema-474255af4acc442d9cfd5bafab7a9930.json) in this directory. *** ## Appendix B. Examples[​](#appendix-b-examples "Direct link to Appendix B. Examples") See the [examples/](/spec/examples/.md) directory: * **Minimal:** [minimal.yaml](undefined) * **Agent with tools:** [with-tools.yaml](undefined) * **Production agent:** [production.yaml](undefined) *** ## Appendix C. Profiles[​](#appendix-c-profiles "Direct link to Appendix C. Profiles") ADL profiles are maintained in the [profiles/](/profiles/.md) directory. Each profile is versioned independently and declares compatibility with ADL versions. ### Available Profiles[​](#available-profiles "Direct link to Available Profiles") | Profile | Identifier | Status | | ---------------------------------------------- | -------------------------------- | ------ | | [Governance](/profiles/governance/overview.md) | `urn:adl:profile:governance:1.0` | Draft | | [Portfolio](/profiles/portfolio/overview.md) | `urn:adl:profile:portfolio:1.0` | Draft | | [Healthcare](/profiles/healthcare/overview.md) | `urn:adl:profile:healthcare:1.0` | Draft | | [Financial](/profiles/financial/overview.md) | `urn:adl:profile:financial:1.0` | Draft | See the [profiles/](/profiles/.md) directory for the full profile index and contribution guidelines. *** ## Appendix D. ABNF Grammar[​](#appendix-d-abnf-grammar "Direct link to Appendix D. ABNF Grammar") This appendix defines formal ABNF grammar productions (RFC 5234 / RFC 7405) for syntactic constructs specified in this document. All productions use ASCII character references consistent with RFC 5234, Appendix B. The core ABNF rules `ALPHA` (letters), `DIGIT` (decimal digits), and `VCHAR` (visible ASCII characters) are defined in RFC 5234 Section 6 (B.1). ``` ; Semantic Versioning format (Sections 5.1, 5.5) semver = 1*DIGIT "." 1*DIGIT "." 1*DIGIT ; Tool name (Section 8.1) ; All alpha characters MUST be lowercase; satisfies ^[a-z][a-z0-9_]*$ tool-name = lc-alpha *( lc-alpha / DIGIT / "_" ) lc-alpha = %x61-7A ; a-z (lowercase letters only) ; Vendor extension namespace key (Section 4.3) ; Reverse-domain notation, minimum two segments vendor-key = domain-segment 1*("." domain-segment) domain-segment = lc-alpha *(lc-alpha / DIGIT / "-") ; Template variable (Sections 7.2, 8.3) ; Used in system_prompt templates and prompt templates template-var = "{{" var-name "}}" var-name = ALPHA *( ALPHA / DIGIT / "_" ) ; First character MUST be a letter (upper or lowercase) ; Tag (Section 12.5) ; Lowercase alphanumeric characters and hyphens tag = 1*( lc-alpha / DIGIT / "-" ) ; Pattern syntax (Section 4.4) ; An ADL pattern consists of literal characters and optional wildcard tokens pattern = 1*pattern-element pattern-element = multi-wildcard / single-wildcard / literal-chars multi-wildcard = "**" ; Valid only in filesystem path patterns (Section 9.3) ; MUST NOT appear in host, env-variable, or command patterns single-wildcard = "*" ; Matches within one segment; does not cross "." in host ; patterns or "/" in filesystem path patterns literal-chars = 1*literal-char literal-char = %x21-29 / %x2B-7E ; Printable ASCII except "*" (%x2A) ; "/" (%x2F) carries segment-boundary meaning in path patterns ; "." (%x2E) carries segment-boundary meaning in host patterns ; ADL URN namespace (Section 17.3) ; Agent URNs carry an organization namespace; profile URNs do not. ; urn:adl:agent:{namespace}:{name}:{version} ; urn:adl:profile:{name}:{version} adl-urn = agent-urn / profile-urn agent-urn = "urn:adl:agent:" urn-namespace ":" urn-name ":" semver profile-urn = "urn:adl:profile:" urn-name ":" profile-version profile-version = 1*DIGIT "." 1*DIGIT [ "." 1*DIGIT ] ; MAJOR.MINOR, optionally MAJOR.MINOR.PATCH urn-namespace = 1*( lc-alpha / DIGIT ) ; Lowercase alphanumeric organization identifier (agent URNs only) urn-name = ( lc-alpha / DIGIT ) *( lc-alpha / DIGIT / "-" ) ; Lowercase alphanumeric resource name, may contain hyphens ``` ### Cross-Reference Summary[​](#cross-reference-summary "Direct link to Cross-Reference Summary") | Production | Normative Section | Usage | | -------------- | ----------------- | -------------------------------------- | | `semver` | 5.1, 5.5 | `adl_spec` and `version` values | | `tool-name` | 8.1 | Tool `name` values | | `vendor-key` | 4.3 | Vendor extension namespace keys | | `template-var` | 7.2, 8.3 | `{{variable}}` references in templates | | `tag` | 12.5 | `metadata.tags` array items | | `pattern` | 4.4, 9.2–9.5 | Permission domain pattern strings | | `adl-urn` | 17.3 | `urn:adl:` namespace identifiers | --- # Examples This section contains example Agent Definition Language (ADL) documents. They illustrate the specification and can be used to validate tooling. :::tip Start Here New to ADL? Start with the [Minimal Example](/spec/examples/minimal.md) to understand the required fields, then explore the [Production Example](/spec/examples/production.md) for a complete implementation. ::: ## Example Index[​](#example-index "Direct link to Example Index") | Example | Description | | ------------------------------------------ | ---------------------------------------------------- | | [Minimal](/spec/examples/minimal.md) | Minimal valid ADL document with only required fields | | [With Tools](/spec/examples/with-tools.md) | Calculator agent demonstrating tool definitions | | [Production](/spec/examples/production.md) | Full production-style agent with all features | ## Conventions[​](#conventions "Direct link to Conventions") * Examples are valid against the ADL version they target * **Format:** YAML or JSON; must be valid JSON (RFC 8259) when processed * **Encoding:** UTF-8 * **Member names:** `snake_case` (lowercase with underscores) * **Required members:** `adl_spec`, `name`, `description`, `version`, `data_classification` * **Versioning:** `adl_spec` and `version` use semantic versioning (`MAJOR.MINOR.PATCH`) * **Timestamps:** ISO 8601 with timezone (e.g., `2026-02-15T14:30:00Z`) * **Extensions:** Use the `extensions` object with vendor-namespaced keys ## Quick Reference[​](#quick-reference "Direct link to Quick Reference") The minimal valid ADL document: minimal.adl.yaml ``` adl_spec: "0.3.0" name: Hello Agent description: A simple greeting agent. version: "1.0.0" data_classification: sensitivity: public ``` :::info File Extension ADL documents use the `.adl.yaml`, `.adl.json`, or `.adl` file extension. The media type is `application/adl+json`. ::: ## Contributing Examples[​](#contributing-examples "Direct link to Contributing Examples") New examples are welcome! To contribute: 1. Ensure the example conforms to the target spec version 2. Add clear comments explaining the example's purpose 3. Submit a PR with the example See the [Contributing Guide](/contributing.md) for more information. --- # Minimal Example This is the simplest valid ADL document, containing only the required fields. :::info Validation This document validates against the [ADL JSON Schema](/spec/.md#appendix-a-json-schema). ::: ## Document[​](#document "Direct link to Document") * YAML * JSON hello-agent.adl.yaml ``` adl_spec: "0.3.0" name: Hello Agent description: A simple greeting agent. version: "1.0.0" data_classification: sensitivity: public ``` hello-agent.adl.json ``` { "adl_spec": "0.3.0", "name": "Hello Agent", "description": "A simple greeting agent.", "version": "1.0.0", "data_classification": { "sensitivity": "public" } } ``` ## Required Fields[​](#required-fields "Direct link to Required Fields") | Field | Description | | ------------- | ----------------------------------------------------------- | | `adl_spec` | ADL specification version (must be semantic version format) | | `name` | Human-readable name for the agent | | `description` | Description of the agent's purpose and capabilities | | `version` | Agent's version (must be semantic version format) | ## Notes[​](#notes "Direct link to Notes") :::note Key Points * This document declares conformance to ADL version 0.1.0 * The agent has no tools, resources, prompts, or permissions defined * The runtime will determine the model to use * All fields use `snake_case` naming convention ::: ## Next Steps[​](#next-steps "Direct link to Next Steps") Ready to add more functionality? See: * [Agent with Tools](/spec/examples/with-tools.md) - Add tool definitions * [Production Agent](/spec/examples/production.md) - Full-featured example --- # Production Agent Example This example demonstrates a full production-style agent with identity, model configuration, tools, resources, prompts, permissions, security, runtime settings, and metadata. :::info Complete Reference This example uses all major ADL features. Use it as a reference when building production agents. ::: ## Document[​](#document "Direct link to Document") * YAML * JSON research-assistant.adl.yaml ``` $schema: https://adl-spec.org/0.2/schema.json adl_spec: "0.3.0" name: Research Assistant description: An AI assistant that helps researchers find, summarize, and analyze academic papers. version: "2.1.0" id: urn:adl:agent:acme:research-assistant:2.1.0 data_classification: sensitivity: internal categories: - intellectual_property lifecycle: status: active effective_date: "2026-01-15T00:00:00Z" provider: name: Acme AI url: https://acme.ai contact: support@acme.ai cryptographic_identity: did: did:web:acme.ai:agents:research-assistant public_key: algorithm: Ed25519 value: base64-encoded-public-key model: provider: anthropic name: claude-sonnet-4-20250514 context_window: 200000 temperature: 0.5 capabilities: - function_calling system_prompt: >- You are a research assistant that helps users find and analyze academic papers. Be thorough, accurate, and cite your sources. tools: - name: search_papers description: Search for academic papers parameters: type: object properties: query: type: string limit: type: integer default: 10 required: - query read_only: true - name: get_paper description: Get full paper details parameters: type: object properties: paper_id: type: string required: - paper_id read_only: true - name: save_note description: Save a research note parameters: type: object properties: title: type: string content: type: string required: - title - content resources: - name: paper_index type: vector_store description: Vector index of paper embeddings uri: s3://research-data/papers/ prompts: - name: summarize description: Summarize a paper template: | Summarize the following paper: {{content}} permissions: network: allowed_hosts: - api.semanticscholar.org - arxiv.org allowed_protocols: - https deny_private: true filesystem: allowed_paths: - path: /data/papers/** access: read - path: /data/notes/** access: read_write resource_limits: max_memory_mb: 2048 max_duration_sec: 300 security: authentication: type: oauth2 required: true scopes: - read:papers - write:notes encryption: in_transit: required: true min_version: "1.2" attestation: type: self issued_at: "2026-02-01T00:00:00Z" expires_at: "2027-02-01T00:00:00Z" runtime: tool_invocation: parallel: true max_concurrent: 3 timeout_ms: 30000 error_handling: on_tool_error: retry max_retries: 2 metadata: authors: - name: Research Team email: research@acme.ai license: Apache-2.0 documentation: https://docs.acme.ai/research-assistant repository: https://github.com/acme/research-assistant tags: - research - academic - papers - summarization ``` research-assistant.adl.json ``` { "$schema": "https://adl-spec.org/0.2/schema.json", "adl_spec": "0.3.0", "name": "Research Assistant", "description": "An AI assistant that helps researchers find, summarize, and analyze academic papers.", "version": "2.1.0", "id": "urn:adl:agent:acme:research-assistant:2.1.0", "data_classification": { "sensitivity": "internal", "categories": [ "intellectual_property" ] }, "lifecycle": { "status": "active", "effective_date": "2026-01-15T00:00:00Z" }, "provider": { "name": "Acme AI", "url": "https://acme.ai", "contact": "support@acme.ai" }, "cryptographic_identity": { "did": "did:web:acme.ai:agents:research-assistant", "public_key": { "algorithm": "Ed25519", "value": "base64-encoded-public-key" } }, "model": { "provider": "anthropic", "name": "claude-sonnet-4-20250514", "context_window": 200000, "temperature": 0.5, "capabilities": [ "function_calling" ] }, "system_prompt": "You are a research assistant that helps users find and analyze academic papers. Be thorough, accurate, and cite your sources.", "tools": [ { "name": "search_papers", "description": "Search for academic papers", "parameters": { "type": "object", "properties": { "query": { "type": "string" }, "limit": { "type": "integer", "default": 10 } }, "required": [ "query" ] }, "read_only": true }, { "name": "get_paper", "description": "Get full paper details", "parameters": { "type": "object", "properties": { "paper_id": { "type": "string" } }, "required": [ "paper_id" ] }, "read_only": true }, { "name": "save_note", "description": "Save a research note", "parameters": { "type": "object", "properties": { "title": { "type": "string" }, "content": { "type": "string" } }, "required": [ "title", "content" ] } } ], "resources": [ { "name": "paper_index", "type": "vector_store", "description": "Vector index of paper embeddings", "uri": "s3://research-data/papers/" } ], "prompts": [ { "name": "summarize", "description": "Summarize a paper", "template": "Summarize the following paper:\n\n{{content}}\n" } ], "permissions": { "network": { "allowed_hosts": [ "api.semanticscholar.org", "arxiv.org" ], "allowed_protocols": [ "https" ], "deny_private": true }, "filesystem": { "allowed_paths": [ { "path": "/data/papers/**", "access": "read" }, { "path": "/data/notes/**", "access": "read_write" } ] }, "resource_limits": { "max_memory_mb": 2048, "max_duration_sec": 300 } }, "security": { "authentication": { "type": "oauth2", "required": true, "scopes": [ "read:papers", "write:notes" ] }, "encryption": { "in_transit": { "required": true, "min_version": "1.2" } }, "attestation": { "type": "self", "issued_at": "2026-02-01T00:00:00Z", "expires_at": "2027-02-01T00:00:00Z" } }, "runtime": { "tool_invocation": { "parallel": true, "max_concurrent": 3, "timeout_ms": 30000 }, "error_handling": { "on_tool_error": "retry", "max_retries": 2 } }, "metadata": { "authors": [ { "name": "Research Team", "email": "research@acme.ai" } ], "license": "Apache-2.0", "documentation": "https://docs.acme.ai/research-assistant", "repository": "https://github.com/acme/research-assistant", "tags": [ "research", "academic", "papers", "summarization" ] } } ``` ## Sections Breakdown[​](#sections-breakdown "Direct link to Sections Breakdown") ### Identity[​](#identity "Direct link to Identity") The agent has a unique identifier and provider information: * YAML * JSON ``` id: urn:adl:agent:acme:research-assistant:2.1.0 provider: name: Acme AI url: https://acme.ai contact: support@acme.ai ``` ``` { "id": "urn:adl:agent:acme:research-assistant:2.1.0", "provider": { "name": "Acme AI", "url": "https://acme.ai", "contact": "support@acme.ai" } } ``` ### Cryptographic Identity[​](#cryptographic-identity "Direct link to Cryptographic Identity") For secure agent identification: * YAML * JSON ``` cryptographic_identity: did: did:web:acme.ai:agents:research-assistant public_key: algorithm: Ed25519 value: base64-encoded-public-key ``` ``` { "cryptographic_identity": { "did": "did:web:acme.ai:agents:research-assistant", "public_key": { "algorithm": "Ed25519", "value": "base64-encoded-public-key" } } } ``` ### Permissions (Deny-by-Default)[​](#permissions-deny-by-default "Direct link to Permissions (Deny-by-Default)") :::warning Security Model Network and filesystem access is explicitly defined. Any access not explicitly granted is **denied**. ::: * YAML * JSON ``` permissions: network: allowed_hosts: - api.semanticscholar.org - arxiv.org allowed_protocols: - https deny_private: true ``` ``` { "permissions": { "network": { "allowed_hosts": [ "api.semanticscholar.org", "arxiv.org" ], "allowed_protocols": [ "https" ], "deny_private": true } } } ``` ### Security[​](#security "Direct link to Security") Authentication and encryption requirements: * YAML * JSON ``` security: authentication: type: oauth2 required: true scopes: - read:papers - write:notes ``` ``` { "security": { "authentication": { "type": "oauth2", "required": true, "scopes": [ "read:papers", "write:notes" ] } } } ``` ### Runtime Configuration[​](#runtime-configuration "Direct link to Runtime Configuration") How the agent should execute: * YAML * JSON ``` runtime: tool_invocation: parallel: true max_concurrent: 3 timeout_ms: 30000 ``` ``` { "runtime": { "tool_invocation": { "parallel": true, "max_concurrent": 3, "timeout_ms": 30000 } } } ``` ## Notes[​](#notes "Direct link to Notes") :::tip Production Checklist * Use `$schema` to enable IDE validation and autocomplete * Define explicit permissions (deny-by-default) * Configure security requirements (authentication, encryption) * Set attestation with appropriate expiration dates * Include comprehensive metadata for discovery ::: --- # Agent with Tools Example This example demonstrates an agent with tool definitions - a calculator that can perform math operations. :::tip Tool Design Tools should be atomic, well-documented, and have clear parameter schemas. Mark read-only tools appropriately to enable safer execution. ::: ## Document[​](#document "Direct link to Document") * YAML * JSON calculator.adl.yaml ``` adl_spec: "0.3.0" name: Calculator description: A calculator agent that performs math operations. version: "0.1.0" data_classification: sensitivity: public model: capabilities: - function_calling tools: - name: add description: Add two numbers parameters: type: object properties: a: type: number b: type: number required: - a - b returns: type: number read_only: true idempotent: true - name: multiply description: Multiply two numbers parameters: type: object properties: a: type: number b: type: number required: - a - b returns: type: number read_only: true idempotent: true metadata: license: MIT tags: - calculator - math ``` calculator.adl.json ``` { "adl_spec": "0.3.0", "name": "Calculator", "description": "A calculator agent that performs math operations.", "version": "0.1.0", "data_classification": { "sensitivity": "public" }, "model": { "capabilities": [ "function_calling" ] }, "tools": [ { "name": "add", "description": "Add two numbers", "parameters": { "type": "object", "properties": { "a": { "type": "number" }, "b": { "type": "number" } }, "required": [ "a", "b" ] }, "returns": { "type": "number" }, "read_only": true, "idempotent": true }, { "name": "multiply", "description": "Multiply two numbers", "parameters": { "type": "object", "properties": { "a": { "type": "number" }, "b": { "type": "number" } }, "required": [ "a", "b" ] }, "returns": { "type": "number" }, "read_only": true, "idempotent": true } ], "metadata": { "license": "MIT", "tags": [ "calculator", "math" ] } } ``` ## Key Features[​](#key-features "Direct link to Key Features") ### Model Configuration[​](#model-configuration "Direct link to Model Configuration") * YAML * JSON ``` model: capabilities: - function_calling ``` ``` { "model": { "capabilities": [ "function_calling" ] } } ``` This declares that the agent requires a model with function calling capability. ### Tool Definitions[​](#tool-definitions "Direct link to Tool Definitions") Each tool includes: | Field | Purpose | | ------------- | --------------------------------------------------------------- | | `name` | Unique identifier for the tool (must match `^[a-z][a-z0-9_]*$`) | | `description` | Human-readable description of what the tool does | | `parameters` | JSON Schema defining the input parameters | | `returns` | JSON Schema defining the return value | | `read_only` | Indicates the tool doesn't modify state | | `idempotent` | Indicates the tool can be safely retried | ### Metadata[​](#metadata "Direct link to Metadata") * YAML * JSON ``` metadata: license: MIT tags: - calculator - math ``` ``` { "metadata": { "license": "MIT", "tags": [ "calculator", "math" ] } } ``` Provides additional context about the agent for discovery and licensing. ## Notes[​](#notes "Direct link to Notes") :::note Implementation Guidance * Tool names must be unique within the document * The `parameters` and `returns` fields use JSON Schema * `read_only` tools are generally safer and can be executed without confirmation * `idempotent` tools can be safely retried on failure ::: ## Next Steps[​](#next-steps "Direct link to Next Steps") Ready to build a production-ready agent? See [Production Agent](/spec/examples/production.md) for a complete example with identity, permissions, security, and more. --- # Contributing Thank you for your interest in contributing to the Agent Definition Language (ADL) specification! :::tip Ways to Get Involved * Report issues or suggest improvements * Submit example ADL documents * Contribute to profile specifications * Build tools and implementations ::: ## Ways to Contribute[​](#ways-to-contribute "Direct link to Ways to Contribute") ### Specification Feedback[​](#specification-feedback "Direct link to Specification Feedback") * Open issues for clarification requests * Propose changes via pull requests * Participate in discussions ### Examples[​](#examples "Direct link to Examples") * Submit new example ADL documents * Improve existing examples with better documentation * Add examples for specific use cases ### Profiles[​](#profiles "Direct link to Profiles") * Propose new domain-specific profiles * Contribute to existing profile specifications * Provide feedback on profile requirements ### Implementations[​](#implementations "Direct link to Implementations") * Build tools that consume or produce ADL * Create validators, linters, or converters * Develop integrations with existing platforms ## Contribution Process[​](#contribution-process "Direct link to Contribution Process") ### 1. Open an Issue[​](#1-open-an-issue "Direct link to 1. Open an Issue") Before making significant changes, open an issue to discuss: * The problem you're solving * Your proposed approach * Any questions or concerns ### 2. Fork and Branch[​](#2-fork-and-branch "Direct link to 2. Fork and Branch") ``` git clone https://github.com/agent-definition-language/specification.git cd specification git checkout -b feature/your-feature-name ``` ### 3. Make Changes[​](#3-make-changes "Direct link to 3. Make Changes") * Follow existing code style and conventions * Update documentation as needed * Add tests if applicable ### 4. Commit with Conventional Commits[​](#4-commit-with-conventional-commits "Direct link to 4. Commit with Conventional Commits") Use [Conventional Commits](https://www.conventionalcommits.org/) format: ``` feat(spec): add support for conditional permissions fix(examples): correct JSON syntax in production example docs(profiles): clarify governance profile requirements ``` Types: * `feat`: New feature * `fix`: Bug fix * `docs`: Documentation changes * `refactor`: Code refactoring * `test`: Test additions/updates * `chore`: Maintenance tasks ### 5. Submit Pull Request[​](#5-submit-pull-request "Direct link to 5. Submit Pull Request") * Reference related issues * Describe your changes clearly * Be responsive to review feedback ## Code of Conduct[​](#code-of-conduct "Direct link to Code of Conduct") This project follows a code of conduct. By participating, you agree to uphold respectful and inclusive behavior. ## License[​](#license "Direct link to License") Contributions are licensed under Apache 2.0, consistent with the project license. ## Questions?[​](#questions "Direct link to Questions?") Open an issue or start a discussion. We're happy to help! --- # Passport Discovery ADL solves a fundamental problem in multi-agent systems: **how does one agent learn what another agent can do, and whether it should be trusted?** Today, agent integrations are hardcoded. If Agent A wants to use Agent B, a developer has to read B's documentation, write glue code, and manually configure credentials. This doesn't scale when you have hundreds of agents across organizations. ADL changes this. Every agent carries a **passport** — a machine-readable document that declares its identity, capabilities, permissions, data sensitivity, and security requirements. Another agent can read this passport, understand what's available, verify trust, and start communicating — automatically. The demo below walks through this flow step by step. Step through the flow below to see how one agent discovers another, reads its passport, evaluates trust, and starts communicating — without any prior configuration or hardcoded integrations. Discovery Validate Trust Communicate 🔍 Discovery Agent 🤖 Service Agent Run DemoStepReset8 steps Click **Run Demo** to start the discovery flow, or **Step** to advance one step at a time. This simulates the real [A2A discovery demo](https://github.com/agent-definition-language/implementations/tree/main/packages/adl-agent/examples/a2a-discovery) that runs locally with `bun run examples/a2a-discovery/run-demo.ts` Find agents on a domainRead the agent’s passportVerify the passport is legitimateTranslate to A2A formatDecide whether to trust this agentInvoke: Explain the passport modelInvoke: Validate a documentInvoke: Compare ADL with A2A ## What you just saw[​](#what-you-just-saw "Direct link to What you just saw") This demo illustrates four core ideas from the ADL specification: ### 1. Discovery without prior knowledge[​](#1-discovery-without-prior-knowledge "Direct link to 1. Discovery without prior knowledge") The discovery agent didn't know anything about the service agent in advance. It queried a standard URL (`/.well-known/adl-agents`) and received a directory of available agents. Any domain can publish this directory — it's how agents find each other across organizations. ### 2. Passports are self-describing[​](#2-passports-are-self-describing "Direct link to 2. Passports are self-describing") The ADL passport contained everything the discovery agent needed: the agent's name, what tools it offers, what data sensitivity level it operates at, and what authentication it requires. No separate API docs, no out-of-band configuration. ### 3. Trust is evaluated, not assumed[​](#3-trust-is-evaluated-not-assumed "Direct link to 3. Trust is evaluated, not assumed") Before sending a single request, the discovery agent checked the passport's trust signals. Is the data public or restricted? Are the tools read-only? Is authentication required? These aren't just metadata — they're machine-enforceable constraints that let agents make autonomous trust decisions. ### 4. Format interoperability[​](#4-format-interoperability "Direct link to 4. Format interoperability") The passport was converted to an A2A Agent Card with a single function call. ADL tools became A2A skills. Authentication mapped directly. An agent described in ADL can participate in the A2A ecosystem, the MCP ecosystem, or both — from one source document. ## Try it locally[​](#try-it-locally "Direct link to Try it locally") The demo above is a simulation. To run the real thing with actual HTTP requests between two processes: ``` cd packages/adl-agent bun run examples/a2a-discovery/run-demo.ts ``` No API keys needed — it runs entirely locally using the agent's built-in tools. --- # Governance This document describes the governance model for the Agent Definition Language (ADL) specification project. :::info Open Development ADL is developed openly. All decisions are documented, and consensus is sought among contributors. ::: ## Principles[​](#principles "Direct link to Principles") 1. **Openness:** Development happens in public; all decisions are documented 2. **Consensus:** Major decisions seek rough consensus among contributors 3. **Meritocracy:** Influence is earned through contribution 4. **Stability:** Breaking changes require strong justification ## Roles[​](#roles "Direct link to Roles") ### Contributors[​](#contributors "Direct link to Contributors") Anyone who contributes to the project: * Submit issues and pull requests * Participate in discussions * Provide feedback on specifications ### Maintainers[​](#maintainers "Direct link to Maintainers") Trusted contributors with merge permissions: * Review and merge pull requests * Triage issues * Guide specification development * Enforce contribution guidelines ### Specification Editors[​](#specification-editors "Direct link to Specification Editors") Responsible for specification text quality: * Ensure consistency and clarity * Resolve editorial disputes * Maintain specification style ## Decision Making[​](#decision-making "Direct link to Decision Making") ### Routine Decisions[​](#routine-decisions "Direct link to Routine Decisions") Made by maintainers through pull request review: * Bug fixes * Documentation improvements * Minor clarifications ### Significant Decisions[​](#significant-decisions "Direct link to Significant Decisions") Require broader input and discussion: * New specification features * Breaking changes * Profile additions * Governance changes Process: 1. Open an issue describing the proposal 2. Allow time for community feedback (minimum 2 weeks) 3. Seek consensus among maintainers 4. Document the decision ### Dispute Resolution[​](#dispute-resolution "Direct link to Dispute Resolution") If consensus cannot be reached: 1. Extend discussion period 2. Seek additional perspectives 3. Maintainers vote (majority wins) 4. Decision is documented with rationale ## Specification Versioning[​](#specification-versioning "Direct link to Specification Versioning") ### Semantic Versioning[​](#semantic-versioning "Direct link to Semantic Versioning") ADL follows [Semantic Versioning](https://semver.org/): * **MAJOR:** Breaking changes * **MINOR:** New features, backward compatible * **PATCH:** Bug fixes, clarifications ### Draft Versions[​](#draft-versions "Direct link to Draft Versions") Versions with `-draft` suffix are unstable: * Subject to breaking changes * Not recommended for production ### Stable Versions[​](#stable-versions "Direct link to Stable Versions") Versions without `-draft` suffix: * Backward compatibility guaranteed within major version * Breaking changes require major version bump ## Standardization Governance[​](#standardization-governance "Direct link to Standardization Governance") When ADL is submitted to standards bodies: * Project governance continues for open-source version * Standards body governance applies to formal standard * Effort to keep versions aligned ## Changes to Governance[​](#changes-to-governance "Direct link to Changes to Governance") This governance document may be updated: 1. Propose changes via pull request 2. Allow 4-week comment period 3. Require maintainer consensus 4. Document rationale for changes --- # Implementations Tools, libraries, and integrations for working with ADL documents. Lint your agents like code. ## Official Tools[​](#official-tools "Direct link to Official Tools") ### [@adl-spec/core](https://www.npmjs.com/package/@adl-spec/core)[​](#adl-speccore "Direct link to adl-speccore") Reference implementation and SDK for ADL. Parse, validate, and convert agent definitions programmatically. Includes full TypeScript types, JSON Schema validation, and converters to A2A Agent Cards and MCP server configurations. * **Type:** SDK / Library * **ADL Version:** 0.3.0+ * **License:** Apache-2.0 * **Language:** TypeScript (Bun runtime) * **Source:** [packages/adl-core](https://github.com/agent-definition-language/implementations/tree/main/packages/adl-core) ``` import { parseADL, validateDocument, convertToA2A } from "@adl-spec/core"; const { document } = parseADL(yamlString); const result = validateDocument(document); const agentCard = convertToA2A(document); ``` ### [@adl-spec/cli](https://www.npmjs.com/package/@adl-spec/cli)[​](#adl-speccli "Direct link to adl-speccli") The official command-line tool for ADL. Validate agent definitions against the spec, convert them to A2A Agent Cards or MCP configurations, and scaffold new documents from templates. * **Type:** Validator / Converter / Scaffolder * **ADL Version:** 0.3.0+ * **License:** Apache-2.0 * **Language:** TypeScript (Bun runtime) * **Source:** [packages/adl-cli](https://github.com/agent-definition-language/implementations/tree/main/packages/adl-cli) ``` # Validate an agent definition npx @adl-spec/cli validate agent.adl.yaml # Convert to A2A Agent Card npx @adl-spec/cli convert agent.adl.yaml --to a2a # Scaffold a governance-ready definition npx @adl-spec/cli init --template governance ``` ### [@adl-spec/generator](https://www.npmjs.com/package/@adl-spec/generator)[​](#adl-specgenerator "Direct link to adl-specgenerator") Generate agent code from ADL documents for multiple target frameworks. Transforms ADL definitions into an intermediate representation, then renders deployable code with a pluggable target system. * **Type:** Code Generator * **ADL Version:** 0.3.0+ * **License:** Apache-2.0 * **Language:** TypeScript (Bun runtime) * **Source:** [packages/adl-generator](https://github.com/agent-definition-language/implementations/tree/main/packages/adl-generator) * **Built-in targets:** `claude-sdk-ts`, `vanilla-ts` ``` import { generateAgent, listTargets } from "@adl-spec/generator"; const result = generateAgent(document, { target: "claude-sdk-ts" }); for (const file of result.files) { // file.path, file.content — ready to write to disk } ``` ### [@adl-spec/agent](https://www.npmjs.com/package/@adl-spec/agent)[​](#adl-specagent "Direct link to adl-specagent") An interactive AI agent that explains ADL concepts through conversation. Built with the ADL core SDK, it validates its own ADL passport on startup — a practical demonstration of ADL in action. * **Type:** Agent / Demo * **ADL Version:** 0.3.0+ * **License:** Apache-2.0 * **Language:** TypeScript (Bun runtime) * **Source:** [packages/adl-agent](https://github.com/agent-definition-language/implementations/tree/main/packages/adl-agent) ### [ADL JSON Schema](https://adl-spec.org/0.3/schema.json)[​](#adl-json-schema "Direct link to adl-json-schema") The official JSON Schema for ADL 0.3.0. Use it for validation in any language with a JSON Schema library, or wire it into your editor for autocomplete and inline diagnostics. * **Type:** Schema * **ADL Version:** 0.3.0 * **License:** Apache-2.0 * **Source:** [core/0.3.0/schema.json](https://github.com/agent-definition-language/specification/blob/main/core/0.3.0/schema.json) ## IDE Support[​](#ide-support "Direct link to IDE Support") ### VS Code — JSON Schema Validation[​](#vs-code--json-schema-validation "Direct link to VS Code — JSON Schema Validation") Get autocomplete, inline errors, and hover docs for ADL documents in VS Code with zero extensions. Add this to your workspace `.vscode/settings.json`: ``` { "json.schemas": [ { "url": "https://adl-spec.org/0.3/schema.json", "fileMatch": ["*.adl.json"] } ], "yaml.schemas": { "https://adl-spec.org/0.3/schema.json": "*.adl.yaml" } } ``` * **Type:** IDE Integration * **ADL Version:** 0.3.0 * **Prerequisites:** For YAML support, install the [YAML extension](https://marketplace.visualstudio.com/items?itemName=redhat.vscode-yaml) ### JetBrains IDEs — JSON Schema Validation[​](#jetbrains-ides--json-schema-validation "Direct link to JetBrains IDEs — JSON Schema Validation") IntelliJ IDEA, WebStorm, and other JetBrains IDEs support JSON Schema mapping natively. Go to **Settings > Languages & Frameworks > Schemas and DTDs > JSON Schema Mappings**, add a new mapping with the schema URL `https://adl-spec.org/0.3/schema.json`, and map it to your `*.adl.json` files. * **Type:** IDE Integration * **ADL Version:** 0.3.0 ## Adding Your Implementation[​](#adding-your-implementation "Direct link to Adding Your Implementation") Built something with ADL? We want to list it here. ### Requirements[​](#requirements "Direct link to Requirements") 1. Supports ADL 0.3.0 or later 2. Publicly available (open source preferred) 3. Includes documentation for users 4. Actively maintained ### How to Submit[​](#how-to-submit "Direct link to How to Submit") Open a [pull request](https://github.com/agent-definition-language/implementations/pulls) adding your implementation to this page. Use this template: ``` ### [Tool Name](https://github.com/org/repo) Brief description of what the tool does. - **Type:** Validator / Converter / IDE Extension / Runtime / Other - **ADL Version:** 0.3.0+ - **License:** MIT / Apache-2.0 / etc. - **Language:** TypeScript / Python / Go / etc. ``` --- # Standardization The Agent Definition Language (ADL) is being developed as an open specification with the goal of becoming a recognized industry standard for describing AI agents. :::info Current Status ADL is currently in **Community Draft** phase. We are stabilizing the specification and gathering feedback from implementers. ::: ## Our Approach[​](#our-approach "Direct link to Our Approach") ADL follows a community-first development model: 1. **Open Development** - The specification is developed in the open with public feedback and contributions welcome 2. **Reference Implementations** - We prioritize working implementations over theoretical completeness 3. **Real-World Validation** - The spec evolves based on actual deployment experience ## Current Focus[​](#current-focus "Direct link to Current Focus") * Stabilizing the core specification (v0.1.0) * Building reference tooling (validators, converters) * Gathering feedback from early adopters * Documenting interoperability with existing standards (A2A, MCP, OpenAPI) ## Future Direction[​](#future-direction "Direct link to Future Direction") As the specification matures and gains adoption, we intend to pursue formal standardization through appropriate industry bodies. This will help ensure long-term stability, broad interoperability, and vendor-neutral governance. The specific standardization path will be determined based on community input and the needs of adopters. ## Get Involved[​](#get-involved "Direct link to Get Involved") * Review the [specification](/spec/.md) * Try the [examples](/spec/examples/.md) * Contribute on [GitHub](https://github.com/agent-definition-language/specification) * Share feedback through issues or discussions ---