Skip to content
Open
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
8 changes: 4 additions & 4 deletions docs/api/agent-discovery.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,20 +121,20 @@ A buyer agent discovers a seller through the following steps:

1. **Fetch the agent card** --- `GET https://seller.example.com/.well-known/agent.json`
2. **Inspect capabilities** --- Check supported protocols, skills, inventory types, and deal types
3. **Obtain an API key** --- `POST /auth/api-keys` with buyer identity
3. **Obtain a buyer API key** --- Ask the seller operator to mint one via `POST /auth/api-keys` (operator-gated; see [Authentication](authentication.md))
4. **Choose a protocol** --- Use [MCP](mcp.md) for structured operations ([A2A](a2a.md) is designed but not yet served)
5. **Start transacting** --- Browse products, request pricing, submit proposals, book deals

### Registry Endpoints (Operator-Facing)

Seller operators manage the agent registry through these endpoints:
Seller operators manage the agent registry through these endpoints. Mutations require an operator API key.

| Endpoint | Method | Description |
|----------|--------|-------------|
| `/registry/agents` | GET | List registered agents (filterable by type and trust status) |
| `/registry/agents/{agent_id}` | GET | Get details for a specific agent |
| `/registry/agents/{agent_id}/trust` | PUT | Update an agent's trust status |
| `/registry/agents/discover` | POST | Discover an agent by URL (fetches their agent card) |
| `/registry/agents/{agent_id}/trust` | PUT | Update an agent's trust status (operator auth required) |
| `/registry/agents/discover` | POST | Discover an agent by URL (operator auth required) |

## See Also

Expand Down
83 changes: 75 additions & 8 deletions docs/api/authentication.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Authentication

The seller agent supports authenticated and anonymous access. Authentication unlocks tiered pricing, negotiation, and richer data in responses.
The seller agent supports authenticated and anonymous access. Authentication unlocks tiered pricing, negotiation, and richer data in responses. **Operator** credentials unlock the control plane (key management, rate card, registry trust, packages, inventory sync).

## Authentication Methods

Expand All @@ -18,14 +18,57 @@ Authorization: Bearer <api_key>
X-Api-Key: <api_key>
```

When both headers are present, the system validates whichever is found first. Anonymous requests (no key) are allowed on most endpoints but receive public-tier access only.
When both headers are present, the system validates whichever is found first. Anonymous requests (no key) are allowed on most buyer-facing endpoints but receive public-tier access only.

## Key Roles

Every API key has a role:

| Role | Purpose |
|------|---------|
| `buyer` | Buyer-agent credential. Grants tiered data access (seat/agency/advertiser pricing). **No** control-plane rights. |
| `operator` | Publisher operator credential. Required for admin REST endpoints and admin MCP tools over HTTP. |

Pre-existing keys (stored before the role field existed) deserialize as `buyer` — they are never silently promoted to operator.

## Bootstrap: First Operator Key

Creating keys via the HTTP API itself requires an operator credential. Mint the **first** operator key out-of-band with the CLI (writes directly to storage — no network surface):

```bash
ad-seller create-operator-key --label "Primary operator"
```

Run this with the same storage config (`.env`) as the server so the key lands in the backend the server reads. The full key is printed **once** — store it securely.

Subsequent operator keys can be minted over HTTP with an existing operator credential (see below).

## Operator Surface

These routes require a valid **operator** key (anonymous → 401, buyer key → 403):

- All `/auth/api-keys` routes (create buyer, create operator, list, get, revoke)
- `/events`, `/events/{id}`
- `PUT /api/v1/rate-card`
- `POST /api/v1/inventory-sync/trigger`
- `GET /gam/orders`, `GET /gam/report`
- Registry mutations: discover, trust update, delete
- Package mutations: `POST/PUT/DELETE /packages`, `/packages/assemble`, `/packages/sync`
- `POST /api/v1/curators`, `POST /api/v1/deals/push`, `POST /api/v1/deals/distribute`

Buyer-facing reads (`GET /packages`, `GET /registry/agents`, `GET /api/v1/rate-card`, media-kit search, etc.) stay public or buyer-authenticated as before.

Admin MCP tools over HTTP (Streamable HTTP / SSE) enforce the same operator check via `Authorization` / `X-Api-Key`. Local stdio MCP access is trusted like the CLI.

## API Key Lifecycle

### Create a Key
All key-management endpoints below require an operator credential.

### Create a Buyer Key

```bash
curl -X POST http://localhost:8000/auth/api-keys \
-H "Authorization: Bearer <operator_api_key>" \
-H "Content-Type: application/json" \
-d '{
"seat_id": "seat-acme-001",
Expand All @@ -39,33 +82,52 @@ curl -X POST http://localhost:8000/auth/api-keys \
}'
```

This endpoint always creates a **buyer** key. There is no `role` field — operator keys use a separate endpoint.

The response contains the **full API key** which is shown **only once**. Store it securely --- it cannot be retrieved again.

### Create an Operator Key

```bash
curl -X POST http://localhost:8000/auth/api-keys/operator \
-H "Authorization: Bearer <operator_api_key>" \
-H "Content-Type: application/json" \
-d '{
"label": "Ops secondary key",
"expires_in_days": 365
}'
```

Operator keys carry no buyer identity (no seat/agency/advertiser fields) — only `label` and optional `expires_in_days`.

### List Keys

```bash
curl http://localhost:8000/auth/api-keys
curl http://localhost:8000/auth/api-keys \
-H "Authorization: Bearer <operator_api_key>"
```

Returns metadata for all keys (no secrets). Includes key ID, label, identity, creation date, and status.
Returns metadata for all keys (no secrets). Includes key ID, label, role, identity, creation date, and status.

### Get Key Details

```bash
curl http://localhost:8000/auth/api-keys/{key_id}
curl http://localhost:8000/auth/api-keys/{key_id} \
-H "Authorization: Bearer <operator_api_key>"
```

### Revoke a Key

```bash
curl -X DELETE http://localhost:8000/auth/api-keys/{key_id}
curl -X DELETE http://localhost:8000/auth/api-keys/{key_id} \
-H "Authorization: Bearer <operator_api_key>"
```

Revoked keys immediately return HTTP 401 on use.

## Access Tiers

Access tiers control pricing visibility, discount eligibility, and negotiation access:
Access tiers control pricing visibility, discount eligibility, and negotiation access for **buyer** keys:

| Tier | Description | Pricing Visibility | Negotiation |
|------|-------------|-------------------|-------------|
Expand All @@ -92,19 +154,24 @@ The effective tier is the **minimum** of the API key tier and the agent trust ti

### Managing Trust

Registry mutations require an operator credential:

```bash
# Discover and register an agent
curl -X POST http://localhost:8000/registry/agents/discover \
-H "Authorization: Bearer <operator_api_key>" \
-H "Content-Type: application/json" \
-d '{"agent_url": "https://buyer.example.com"}'

# Approve the agent
curl -X PUT http://localhost:8000/registry/agents/{agent_id}/trust \
-H "Authorization: Bearer <operator_api_key>" \
-H "Content-Type: application/json" \
-d '{"trust_status": "approved", "notes": "Verified by ops team"}'

# Block a malicious agent
curl -X PUT http://localhost:8000/registry/agents/{agent_id}/trust \
-H "Authorization: Bearer <operator_api_key>" \
-H "Content-Type: application/json" \
-d '{"trust_status": "blocked", "notes": "Abuse detected"}'
```
15 changes: 14 additions & 1 deletion docs/api/mcp.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,16 @@ bearer_token_env_var = "SELLER_AGENT_API_KEY"

See full setup guides: [Claude](../guides/claude-desktop-setup.md) | [ChatGPT, Codex & AI IDEs](../guides/chatgpt-setup.md)

### Operator credentials for admin tools

Admin MCP tools (API key management, trust updates, package/rate-card writes,
inventory sync, deal push/distribute, GAM reporting, etc.) require an
**operator** API key over HTTP transports. Pass it as
`Authorization: Bearer <key>` or `X-Api-Key: <key>` (see Cursor/Codex examples
above). Bootstrap the first key with `ad-seller create-operator-key` —
[Authentication](authentication.md). Local stdio MCP access is trusted like
the CLI and does not require a header.

## Available Tools (41)

### Setup & Status
Expand Down Expand Up @@ -114,9 +124,12 @@ See full setup guides: [Claude](../guides/claude-desktop-setup.md) | [ChatGPT, C

### API Keys

Operator auth required over HTTP. Buyer keys only via MCP — mint additional
operator keys with `POST /auth/api-keys/operator` or the CLI.

| Tool | Description |
|------|-------------|
| `create_api_key` | Create an API key for a buyer or agent |
| `create_api_key` | Create a **buyer** API key |
| `list_api_keys` | List active keys |
| `revoke_api_key` | Revoke a key |

Expand Down
25 changes: 16 additions & 9 deletions docs/api/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,35 +90,42 @@ The Ad Seller System API exposes **59 endpoints** across **19 tags**. All endpoi

## Packages

Package reads are public / tier-gated; mutations require an operator credential.

| Method | Path | Summary |
|--------|------|---------|
| GET | `/packages` | List packages with tier-gated view |
| GET | `/packages/{package_id}` | Get a single package with tier-gated view |
| POST | `/packages` | Create a curated package (Layer 2) |
| PUT | `/packages/{package_id}` | Update an existing package |
| DELETE | `/packages/{package_id}` | Archive a package (soft delete) |
| POST | `/packages/assemble` | Assemble a dynamic package (Layer 3) from product IDs |
| POST | `/packages/sync` | Trigger ad server inventory sync (Layer 1) |
| POST | `/packages` | Create a curated package (Layer 2; operator auth required) |
| PUT | `/packages/{package_id}` | Update an existing package (operator auth required) |
| DELETE | `/packages/{package_id}` | Archive a package (soft delete; operator auth required) |
| POST | `/packages/assemble` | Assemble a dynamic package (Layer 3; operator auth required) |
| POST | `/packages/sync` | Trigger ad server inventory sync (Layer 1; operator auth required) |

## Authentication

All `/auth/api-keys*` routes require an **operator** credential. Bootstrap the first operator key with `ad-seller create-operator-key` (see [Authentication](authentication.md)).

| Method | Path | Summary |
|--------|------|---------|
| POST | `/auth/api-keys` | Create a new API key for a buyer |
| POST | `/auth/api-keys` | Create a new **buyer** API key (operator auth required) |
| POST | `/auth/api-keys/operator` | Create a new **operator** API key (operator auth required) |
| GET | `/auth/api-keys` | List all API keys (metadata only, no secrets) |
| GET | `/auth/api-keys/{key_id}` | Get details for a specific API key |
| DELETE | `/auth/api-keys/{key_id}` | Revoke an API key |

## Agent Registry

Registry reads are public; mutations require an operator credential.

| Method | Path | Summary |
|--------|------|---------|
| GET | `/.well-known/agent.json` | Serve this seller agent's card for A2A discovery |
| GET | `/registry/agents` | List agents in the local registry |
| GET | `/registry/agents/{agent_id}` | Get details for a specific registered agent |
| POST | `/registry/agents/discover` | Discover an agent by URL |
| PUT | `/registry/agents/{agent_id}/trust` | Update an agent's trust status |
| DELETE | `/registry/agents/{agent_id}` | Remove an agent from the local registry |
| POST | `/registry/agents/discover` | Discover an agent by URL (operator auth required) |
| PUT | `/registry/agents/{agent_id}/trust` | Update an agent's trust status (operator auth required) |
| DELETE | `/registry/agents/{agent_id}` | Remove an agent from the local registry (operator auth required) |

## Quotes

Expand Down
2 changes: 1 addition & 1 deletion docs/architecture/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ graph LR
end

BA -->|"1. Discover (GET /.well-known/agent.json)"| SA
BA -->|"2. Get API Key (POST /auth/api-keys)"| SA
BA -->|"2. Receive buyer API key (operator mints via POST /auth/api-keys)"| SA
BA -->|"3. MCP: Structured tool calls (/mcp/ Streamable HTTP)"| SA
BA -->|"4. A2A: Natural language (/a2a/seller/jsonrpc)"| SA
BA -->|"5. REST: Browse, quote, book, negotiate"| SA
Expand Down
Loading
Loading