Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion docs/dir/ads-records.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 `<scheme>://<domain>/.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.
Expand All @@ -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."
Expand Down Expand Up @@ -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.
140 changes: 133 additions & 7 deletions docs/dir/directory-cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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 <cid>`
#### `dirctl pull <reference>`

Retrieves records by their Content Identifier (CID) or name reference.

**Supported Reference Formats:**

Retrieves records by their Content Identifier (CID).
| Format | Description |
|--------|-------------|
| `<cid>` | Direct lookup by CID |
| `<name>` | Retrieves the latest version |
| `<name>:<version>` | Retrieves the specified version |
| `<name>@<cid>` | Hash-verified lookup (fails if resolved CID doesn't match) |
| `<name>:<version>@<cid>` | 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 <cid> --signature --public-key public.key
```

**Hash Verification:**

The `@<cid>` 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 <cid>`

Removes records from storage.
Expand All @@ -273,15 +318,31 @@ Removes records from storage.
dirctl delete baeareihdr6t7s6sr2q4zo456sza66eewqc7huzatyfgvoupaqyjw23ilvi
```

#### `dirctl info <cid>`
#### `dirctl info <reference>`

Displays metadata about stored records using CID or name reference.

**Supported Reference Formats:**

Displays metadata about stored records.
| Format | Description |
|--------|-------------|
| `<cid>` | Direct lookup by content address |
| `<name>` | Displays the most recently created version |
| `<name>:<version>` | Displays the specified version |
| `<name>@<cid>` | Hash-verified lookup |
| `<name>:<version>@<cid>` | 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
Expand Down Expand Up @@ -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 `<scheme>://<domain>/.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 <cid> --key private.key
```

3. Check verification status using [`dirctl naming verify`](./directory-cli.md#dirctl-naming-verify-reference).

#### `dirctl sign <cid> [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

Expand All @@ -467,6 +555,44 @@ Signs records for integrity and authenticity.
dirctl sign <cid> --oidc --fulcio-url https://fulcio.example.com
```

#### `dirctl naming verify <reference>`

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 |
|--------|-------------|
| `<cid>` | Verify by content address |
| `<name>` | Verify the most recently created version |
| `<name>:<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 <record> <signature> [flags]`

Verifies record signatures.
Expand Down
2 changes: 2 additions & 0 deletions docs/dir/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
112 changes: 109 additions & 3 deletions docs/dir/scenarios.md
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 `<scheme>://<domain>/.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
Expand Down Expand Up @@ -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"

Expand Down Expand Up @@ -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
Expand Down
Loading