diff --git a/docs/dir/ads-records.md b/docs/dir/ads-records.md index 43cd869..ba43973 100644 --- a/docs/dir/ads-records.md +++ b/docs/dir/ads-records.md @@ -11,6 +11,16 @@ The content identifier of the record is a [Content IDentifier](https://github.co - Collision-resistant - Immutable +## Verifiable Names + +Records must include a `name` field with a domain-based identifier that enables name verification. When a record uses a verifiable name: + +- The name must include a protocol prefix: `https://domain/path` or `http://domain/path`. +- The domain must host a JWKS file at `:///.well-known/jwks.json`. +- Records signed with a private key associated with a public key present in that JWKS file can be verified as authorized by the domain. + +See the [Directory CLI documentation](directory-cli.md#name-verification) for details on name verification workflows. + ## Example Email Agent You can generate your own example records using the [OASF Record Sample generator](https://schema.oasf.outshift.com/sample/0.7.0/objects/record). Below is an example OASF record for an email agent that is capable of sending and receiving emails. @@ -22,7 +32,7 @@ You can generate your own example records using the [OASF Record Sample generato ```json { "schema_version": "0.7.0", - "name": "email-agent", + "name": "https://cisco.com/agents/email-agent", "version": "v1.0.0", "authors": [ "Cisco Systems Inc." @@ -55,3 +65,7 @@ You can generate your own example records using the [OASF Record Sample generato ] } ``` + +!!! note + + The `name` field uses a verifiable domain-based format (`https://cisco.com/agents/email-agent`). When signed with a key authorized by the domain's JWKS file at `https://cisco.com/.well-known/jwks.json`, this record can be pulled using the convenient reference `cisco.com/agents/email-agent:v1.0.0` instead of its CID. diff --git a/docs/dir/directory-cli.md b/docs/dir/directory-cli.md index 0fcabf1..1224d3d 100644 --- a/docs/dir/directory-cli.md +++ b/docs/dir/directory-cli.md @@ -64,9 +64,17 @@ The following example demonstrates how to store, publish, search, and retrieve a 1. Retrieve a record ```bash + # Pull by CID dirctl pull baeareihdr6t7s6sr2q4zo456sza66eewqc7huzatyfgvoupaqyjw23ilvi + + # Or pull by name (if the record has a verifiable name) + dirctl pull cisco.com/agent:v1.0.0 ``` +!!! note "Name-based References" + + The CLI supports Docker-style name references in addition to CIDs. Records can be pulled using formats like `name`, `name:version`, or `name:version@cid` for hash-verified lookups. See [Name Verification](#name-verification) for details. + ## Directory MCP Server The Directory MCP Server provides a standardized interface for AI assistants and tools to interact with the AGNTCY Agent Directory and work with OASF agent records. @@ -248,20 +256,57 @@ Stores records in the content-addressable store. Has the following features: dirctl push agent-model.json --sign --key private.key ``` -#### `dirctl pull ` +#### `dirctl pull ` + +Retrieves records by their Content Identifier (CID) or name reference. + +**Supported Reference Formats:** -Retrieves records by their Content Identifier (CID). +| Format | Description | +|--------|-------------| +| `` | Direct lookup by CID | +| `` | Retrieves the latest version | +| `:` | Retrieves the specified version | +| `@` | Hash-verified lookup (fails if resolved CID doesn't match) | +| `:@` | Hash-verified lookup for a specific version | ??? example ```bash - # Pull record content + # Pull by CID dirctl pull baeareihdr6t7s6sr2q4zo456sza66eewqc7huzatyfgvoupaqyjw23ilvi + # Pull by name (latest version) + dirctl pull cisco.com/agent + + # Pull by name with specific version + dirctl pull cisco.com/agent:v1.0.0 + + # Pull with hash verification + dirctl pull cisco.com/agent@bafyreib... + dirctl pull cisco.com/agent:v1.0.0@bafyreib... + # Pull with signature verification dirctl pull --signature --public-key public.key ``` +**Hash Verification:** + +The `@` suffix enables hash verification. This command fails if the resolved CID doesn't match the expected digest: + +```bash +# Succeeds if cisco.com/agent:v1.0.0 resolves to bafyreib... +dirctl pull cisco.com/agent:v1.0.0@bafyreib... + +# Fails with error if CIDs don't match +dirctl pull cisco.com/agent@wrong-cid +# Error: hash verification failed: resolved CID "bafyreib..." does not match expected digest "wrong-cid" +``` + +**Version Resolution:** + +When no version is specified, commands return the most recently created record (by record's `created_at` field). This allows non-semver tags like `latest`, `dev`, or `stable`. + #### `dirctl delete ` Removes records from storage. @@ -273,15 +318,31 @@ Removes records from storage. dirctl delete baeareihdr6t7s6sr2q4zo456sza66eewqc7huzatyfgvoupaqyjw23ilvi ``` -#### `dirctl info ` +#### `dirctl info ` + +Displays metadata about stored records using CID or name reference. + +**Supported Reference Formats:** -Displays metadata about stored records. +| Format | Description | +|--------|-------------| +| `` | Direct lookup by content address | +| `` | Displays the most recently created version | +| `:` | Displays the specified version | +| `@` | Hash-verified lookup | +| `:@` | Hash-verified lookup for a specific version | ??? example ```bash - # Show record metadata + # Info by CID (existing) dirctl info baeareihdr6t7s6sr2q4zo456sza66eewqc7huzatyfgvoupaqyjw23ilvi + + # Info by name (latest version) + dirctl info cisco.com/agent --output json + + # Info by name with specific version + dirctl info cisco.com/agent:v1.0.0 --output json ``` ### Routing Operations @@ -453,9 +514,36 @@ The following flags are available: ### Security & Verification +#### Name Verification + +Record name verification proves that the signing key is authorized by the domain claimed in the record's name field. + +**Requirements:** + +- Record name must include a protocol prefix: `https://domain/path` or `http://domain/path` +- A JWKS file must be hosted at `:///.well-known/jwks.json` +- The record must be signed with the private key corresponding to a public key present in that JWKS file + +**Workflow:** + +1. Push a record with a verifiable name. + + ```bash + dirctl push record.json --output raw + # Returns: bafyreib... + ``` + +2. Sign the record (triggers automatic verification). + + ```bash + dirctl sign --key private.key + ``` + +3. Check verification status using [`dirctl naming verify`](./directory-cli.md#dirctl-naming-verify-reference). + #### `dirctl sign [flags]` -Signs records for integrity and authenticity. +Signs records for integrity and authenticity. When signing a record with a verifiable name (e.g., `https://domain/path`), the system automatically attempts to verify domain authorization via JWKS. See [Name Verification](#name-verification) for details. ??? example @@ -467,6 +555,44 @@ Signs records for integrity and authenticity. dirctl sign --oidc --fulcio-url https://fulcio.example.com ``` +#### `dirctl naming verify ` + +Verifies that a record's signing key is authorized by the domain claimed in its name field. Checks if the signing key matches a public key in the domain's JWKS file hosted at `/.well-known/jwks.json`. + +**Supported Reference Formats:** + +| Format | Description | +|--------|-------------| +| `` | Verify by content address | +| `` | Verify the most recently created version | +| `:` | Verify a specific version | + +??? example + + ```bash + # Verify by CID + dirctl naming verify bafyreib... --output json + + # Verify by name (latest version) + dirctl naming verify cisco.com/agent --output json + + # Verify by name with specific version + dirctl naming verify cisco.com/agent:v1.0.0 --output json + ``` + + Example verification response: + + ```json + { + "cid": "bafyreib...", + "verified": true, + "domain": "cisco.com", + "method": "jwks", + "key_id": "key-1", + "verified_at": "2026-01-21T10:30:00Z" + } + ``` + #### `dirctl verify [flags]` Verifies record signatures. diff --git a/docs/dir/overview.md b/docs/dir/overview.md index 519d5de..e8089f5 100644 --- a/docs/dir/overview.md +++ b/docs/dir/overview.md @@ -58,6 +58,8 @@ ADS leverages [Content Identifiers](https://github.com/multiformats/cid) for naming directory records. CIDs provide a self-describing, content-addressed naming scheme that ensures data integrity and immutability. +In addition to CID-based addressing, ADS supports verifiable domain-based names that enable human-readable references while maintaining cryptographic verification. See the [Directory CLI documentation](directory-cli.md#name-verification) for details. + ## Content Routing ADS implements capability-based record discovery through a hierarchical skill diff --git a/docs/dir/scenarios.md b/docs/dir/scenarios.md index 9848867..6ddd9a5 100644 --- a/docs/dir/scenarios.md +++ b/docs/dir/scenarios.md @@ -32,7 +32,7 @@ To start, generate an example Record that matches the data model schema defined # Generate an example data model cat << EOF > record.json { - "name": "my-record", + "name": "https://example.com/agents/my-record", "version": "v1.0.0", "description": "insert description here", "schema_version": "0.7.0", @@ -73,15 +73,30 @@ dirctl push record.json > record.cid # Set the CID as a variable for easier reference RECORD_CID=$(cat record.cid) -# Pull the record +# Pull the record by CID # Returns the same data as record.json dirctl pull $RECORD_CID -# Lookup basic metadata about the record +# Pull the record by name (if it has a verifiable name) +# Returns the same data as record.json +dirctl pull example.com/agents/my-record:v1.0.0 + +# Lookup basic metadata about the record by CID # Returns annotations, creation timestamp and OASF schema version dirctl info $RECORD_CID + +# Lookup basic metadata by name +dirctl info example.com/agents/my-record:v1.0.0 ``` +Records with verifiable names can be referenced using Docker-style formats: + +- `example.com/agents/my-record` - Latest version +- `example.com/agents/my-record:v1.0.0` - Specific version +- `example.com/agents/my-record:v1.0.0@bafyreib...` - Hash-verified lookup + +Name-based references work with `pull`, `info`, and `naming verify` commands. + ## Signing and Verification Establishing trust and authenticity is critical in distributed AI agent ecosystems, where @@ -165,6 +180,93 @@ dirctl push record.json --sign --key cosign.key dirctl verify $RECORD_CID ``` +## Name Verification + +Name verification proves that the signing key is authorized by the domain claimed in the +record's name field. This provides cryptographic proof of domain ownership and enables +human-readable references while maintaining security. + +### Requirements + +To use name verification, your record must meet these requirements: + +- Record name must include a protocol prefix: `https://domain/path` or `http://domain/path` +- A [JWKS (JSON Web Key Set)](https://datatracker.ietf.org/doc/html/rfc7517) file must be hosted at `:///.well-known/jwks.json` +- The record must be signed with the private key corresponding to a public key present in that JWKS file + +### Workflow + +```bash +# 1. Create a record with a verifiable name (already done in Build section) +# The record.json has: "name": "https://example.com/agents/my-record" + +# 2. Ensure your domain hosts a JWKS file +# Example: https://example.com/.well-known/jwks.json +# This file should contain the public key corresponding to your signing key + +# 3. Push the record +RECORD_CID=$(dirctl push record.json --output raw) +echo "Stored with CID: $RECORD_CID" + +# 4. Sign the record (triggers automatic verification) +dirctl sign $RECORD_CID --key cosign.key + +# 5. Verify the name authorization +# By CID +dirctl naming verify $RECORD_CID --output json + +# By name (latest version) +dirctl naming verify example.com/agents/my-record --output json + +# By name with specific version +dirctl naming verify example.com/agents/my-record:v1.0.0 --output json +``` + +### Verification Response + +When verification succeeds, you'll receive a response like: + +```json +{ + "cid": "bafyreib...", + "verified": true, + "domain": "example.com", + "method": "jwks", + "key_id": "key-1", + "verified_at": "2026-01-21T10:30:00Z" +} +``` + +### Using Verified Names + +Once verified, you can use convenient name-based references instead of CIDs: + +```bash +# Pull by name (latest version) +dirctl pull example.com/agents/my-record + +# Pull specific version +dirctl pull example.com/agents/my-record:v1.0.0 + +# Pull with hash verification (fails if CID doesn't match) +dirctl pull example.com/agents/my-record:v1.0.0@$RECORD_CID + +# Get info by name +dirctl info example.com/agents/my-record:v1.0.0 --output json +``` + +### Version Resolution + +When no version is specified, commands return the most recently created record (by the +record's `created_at` field). This allows non-semver tags like `latest`, `dev`, or `stable`: + +```bash +# These all pull the most recent version +dirctl pull example.com/agents/my-record +dirctl pull example.com/agents/my-record:latest +dirctl pull example.com/agents/my-record:dev +``` + ## Announce This example demonstrates how to publish records to allow content discovery across the @@ -254,6 +356,9 @@ other Directory commands like `pull`, `info`, and `verify`. # Basic search for records by name dirctl search --name "my-agent-name" +# Search for records with verifiable domain-based names +dirctl search --name "example.com/agents/my-record" + # Search for records with a specific version dirctl search --version "v1.0.0" @@ -303,6 +408,7 @@ The search functionality supports wildcard patterns for flexible matching: ```bash # Asterisk (*) wildcard - matches zero or more characters dirctl search --name "web*" # Find all web-related agents +dirctl search --name "example.com/*" # Find all agents from example.com domain dirctl search --version "v1.*" # Find all v1.x versions dirctl search --skill "audio*" # Find Audio-related skills dirctl search --locator "http*" # Find HTTP-based locators