# 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\&#39;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\&#39;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 `<resource>:<action>` (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, <https://www.rfc-editor.org/info/rfc2119>.
* **\[RFC3986]** Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform Resource Identifier (URI): Generic Syntax", STD 66, RFC 3986, <https://www.rfc-editor.org/info/rfc3986>.
* **\[RFC6749]** Hardt, D., Ed., "The OAuth 2.0 Authorization Framework", RFC 6749, <https://www.rfc-editor.org/info/rfc6749>.
* **\[RFC6838]** Freed, N., Klensin, J., and T. Hansen, "Media Type Specifications and Registration Procedures", BCP 13, RFC 6838, <https://www.rfc-editor.org/info/rfc6838>.
* **\[RFC6901]** Bryan, P., Ed., "JavaScript Object Notation (JSON) Pointer", RFC 6901, <https://www.rfc-editor.org/info/rfc6901>.
* **\[RFC7636]** Sakimura, N., Ed., Bradley, J., and N. Agarwal, "Proof Key for Code Exchange by OAuth Public Clients", RFC 7636, <https://www.rfc-editor.org/info/rfc7636>.
* **\[RFC8126]** Cotton, M., Leiba, B., and T. Narten, "Guidelines for Writing an IANA Considerations Section in RFCs", BCP 26, RFC 8126, <https://www.rfc-editor.org/info/rfc8126>.
* **\[RFC8141]** Saint-Andre, P. and J. Klensin, "Uniform Resource Names (URNs)", RFC 8141, <https://www.rfc-editor.org/info/rfc8141>.
* **\[RFC8174]** Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, <https://www.rfc-editor.org/info/rfc8174>.
* **\[RFC8259]** Bray, T., Ed., "The JavaScript Object Notation (JSON) Data Interchange Format", STD 90, RFC 8259, <https://www.rfc-editor.org/info/rfc8259>.
* **\[RFC8615]** Nottingham, M., "Well-Known Uniform Resource Identifiers (URIs)", RFC 8615, <https://www.rfc-editor.org/info/rfc8615>.
* **\[RFC8705]** Campbell, B., Bradley, J., Sakimura, N., and T. Lodderstedt, "OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens", RFC 8705, <https://www.rfc-editor.org/info/rfc8705>.
* **\[RFC8785]** Rundgren, A., Jordan, B., and S. Erdtman, "JSON Canonicalization Scheme (JCS)", RFC 8785, <https://www.rfc-editor.org/info/rfc8785>.
* **\[RFC9449]** Fett, D., Campbell, B., Bradley, J., Lodderstedt, T., Jones, M., and D. Waite, "OAuth 2.0 Demonstrating Proof of Possession (DPoP)", RFC 9449, <https://www.rfc-editor.org/info/rfc9449>.
* **\[RFC9700]** Lodderstedt, T., Bradley, J., Labunets, A., and D. Fett, "Best Current Practice for OAuth 2.0 Security", BCP 240, RFC 9700, <https://www.rfc-editor.org/info/rfc9700>.

### 19.2 Informative References[​](#192-informative-references "Direct link to 19.2 Informative References")

* **\[A2A]** A2A Protocol Working Group, "Agent2Agent (A2A) Protocol Specification", <https://a2a-protocol.org/latest/specification/>.
* **\[CLTC-AGENTIC]** Center for Long-Term Cybersecurity (CLTC), UC Berkeley, "Agentic AI Risk-Management Standards Profile", February 2026, <https://cltc.berkeley.edu/wp-content/uploads/2026/02/Agentic-AI-Risk-Management-Standards-Profile.pdf>.
* **\[IMDA-AGENTIC]** Infocomm Media Development Authority (IMDA), "Model AI Governance Framework for Agentic AI", Version 1.5, May 2026, <https://www.imda.gov.sg/-/media/imda/files/about/emerging-tech-and-research/artificial-intelligence/mgf-for-agentic-ai.pdf>.
* **\[JSON-SCHEMA]** Wright, A., et al., "JSON Schema: A Media Type for Describing JSON Documents", <https://json-schema.org/draft/2020-12/json-schema-core>.
* **\[MCP]** Anthropic, "Model Context Protocol Specification", <https://modelcontextprotocol.io/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, <https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1>.
* **\[OPENAPI]** OpenAPI Initiative, "OpenAPI Specification", Version 3.1, <https://spec.openapis.org/oas/v3.1.0>.
* **\[OPENID-CONNECT]** Sakimura, N., Bradley, J., Jones, M., de Medeiros, B., and C. Mortimore, "OpenID Connect Core 1.0", November 2014, <https://openid.net/specs/openid-connect-core-1_0.html>.
* **\[W3C.DID]** Sporny, M., et al., "Decentralized Identifiers (DIDs) v1.0", W3C Recommendation, <https://www.w3.org/TR/did-core/>.
* **\[W3C.VC]** Sporny, M., et al., "Verifiable Credentials Data Model v2.0", W3C Recommendation, <https://www.w3.org/TR/vc-data-model-2.0/>.
* **\[ISO-22989]** ISO/IEC JTC 1/SC 42, "Information technology — Artificial intelligence — Artificial intelligence concepts and terminology", ISO/IEC 22989:2022, <https://www.iso.org/standard/74296.html>.
* **\[AI-PROTOCOLS]** Rosenberg, J., "Framework, Use Cases and Requirements for AI Agent Protocols", Internet-Draft draft-rosenberg-ai-protocols-00, 2025, <https://datatracker.ietf.org/doc/html/draft-rosenberg-ai-protocols-00>.

***

## 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       |
