Skip to content

Commit 79c3e0d

Browse files
committed
Add comprehensive docs/ with Zensical site generator
- 9 documentation pages: getting-started, verification-flow, cli-guide, trust-bundles, delegation-chains, deployment, security, troubleshooting - Zensical config (zensical.toml) and GitHub Actions workflow for Pages - Updated context7.json with docs/ folder references
1 parent e945036 commit 79c3e0d

File tree

13 files changed

+2816
-1
lines changed

13 files changed

+2816
-1
lines changed

.github/workflows/docs.yml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
name: Documentation
2+
on:
3+
push:
4+
branches:
5+
- main
6+
paths:
7+
- 'docs/**'
8+
- 'zensical.toml'
9+
permissions:
10+
contents: read
11+
pages: write
12+
id-token: write
13+
jobs:
14+
deploy:
15+
environment:
16+
name: github-pages
17+
url: ${{ steps.deployment.outputs.page_url }}
18+
runs-on: ubuntu-latest
19+
steps:
20+
- uses: actions/configure-pages@v5
21+
- uses: actions/checkout@v5
22+
- uses: actions/setup-python@v5
23+
with:
24+
python-version: 3.x
25+
- run: pip install zensical
26+
- run: zensical build --clean
27+
- uses: actions/upload-pages-artifact@v4
28+
with:
29+
path: site
30+
- uses: actions/deploy-pages@v4
31+
id: deployment

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ build/
3030
.venv/
3131
*.egg
3232

33+
# Zensical build output
34+
site/
35+
3336
# OS
3437
.DS_Store
3538
Thumbs.db

context7.json

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,16 @@
1010
"AGENTPIN_TECHNICAL_SPECIFICATION.md",
1111
"ROADMAP.md",
1212
"javascript/README.md",
13-
"python/README.md"
13+
"python/README.md",
14+
"docs/index.md",
15+
"docs/getting-started.md",
16+
"docs/verification-flow.md",
17+
"docs/cli-guide.md",
18+
"docs/trust-bundles.md",
19+
"docs/delegation-chains.md",
20+
"docs/deployment.md",
21+
"docs/security.md",
22+
"docs/troubleshooting.md"
1423
],
1524
"excludeFolders": [
1625
"**/target",

docs/cli-guide.md

Lines changed: 296 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,296 @@
1+
# AgentPin CLI Guide
2+
3+
The AgentPin CLI (`agentpin`) provides commands for key generation, credential issuance, credential verification, and serving discovery endpoints.
4+
5+
---
6+
7+
## Installation
8+
9+
Build from the Rust workspace:
10+
11+
```bash
12+
# Install the CLI binary
13+
cargo install --path crates/agentpin-cli
14+
15+
# Or build the full workspace
16+
cargo build --workspace --release
17+
```
18+
19+
The binary is at `target/release/agentpin`.
20+
21+
---
22+
23+
## Commands
24+
25+
### `agentpin keygen` — Generate Key Pair
26+
27+
Generate an ECDSA P-256 key pair for signing agent credentials.
28+
29+
```bash
30+
agentpin keygen \
31+
--domain example.com \
32+
--kid example-2026-01 \
33+
--output-dir ./keys
34+
```
35+
36+
**Options:**
37+
38+
| Flag | Required | Description |
39+
|------|----------|-------------|
40+
| `--domain` | Yes | Domain this key is associated with |
41+
| `--kid` | Yes | Key identifier (used in JWT headers and discovery documents) |
42+
| `--output-dir` | Yes | Directory to write key files |
43+
44+
**Output files:**
45+
46+
```
47+
keys/
48+
├── example-2026-01.private.pem # ECDSA P-256 private key (keep secret!)
49+
├── example-2026-01.public.pem # Public key in PEM format
50+
└── example-2026-01.public.jwk.json # Public key in JWK format
51+
```
52+
53+
The JWK file is ready to embed in your discovery document's `public_keys` array.
54+
55+
**Example JWK output:**
56+
57+
```json
58+
{
59+
"kid": "example-2026-01",
60+
"kty": "EC",
61+
"crv": "P-256",
62+
"x": "f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU",
63+
"y": "x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0",
64+
"use": "sig",
65+
"key_ops": ["verify"]
66+
}
67+
```
68+
69+
---
70+
71+
### `agentpin issue` — Issue a Credential
72+
73+
Issue a signed JWT credential for an agent.
74+
75+
```bash
76+
agentpin issue \
77+
--private-key ./keys/example-2026-01.private.pem \
78+
--kid example-2026-01 \
79+
--issuer example.com \
80+
--agent-id "urn:agentpin:example.com:scout" \
81+
--capabilities "read:data,write:reports" \
82+
--ttl 3600
83+
```
84+
85+
**Options:**
86+
87+
| Flag | Required | Default | Description |
88+
|------|----------|---------|-------------|
89+
| `--private-key` | Yes || Path to PEM-encoded private key |
90+
| `--kid` | Yes || Key identifier (must match a key in the discovery document) |
91+
| `--issuer` | Yes || Issuer domain (e.g., `example.com`) |
92+
| `--agent-id` | Yes || Agent identifier URN (e.g., `urn:agentpin:example.com:scout`) |
93+
| `--capabilities` | Yes || Comma-separated capability list |
94+
| `--audience` | No || Target audience domain |
95+
| `--ttl` | No | `3600` | Credential lifetime in seconds |
96+
| `--constraints` | No || JSON object of constraints |
97+
98+
**Output:**
99+
100+
The signed JWT is printed to stdout:
101+
102+
```
103+
eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImV4YW1wbGUtMjAyNi0wMSJ9.eyJpc3M...
104+
```
105+
106+
**Usage in scripts:**
107+
108+
```bash
109+
# Store credential in a variable
110+
CREDENTIAL=$(agentpin issue \
111+
--private-key ./keys/example-2026-01.private.pem \
112+
--kid example-2026-01 \
113+
--issuer example.com \
114+
--agent-id "urn:agentpin:example.com:scout" \
115+
--capabilities "read:data" \
116+
--ttl 3600)
117+
118+
# Pass to another agent via HTTP header
119+
curl -H "Authorization: Bearer $CREDENTIAL" https://api.verifier.com/endpoint
120+
121+
# Or verify it immediately
122+
agentpin verify --credential "$CREDENTIAL" --discovery ./agent-identity.json
123+
```
124+
125+
---
126+
127+
### `agentpin verify` — Verify a Credential
128+
129+
Verify a signed JWT credential against a discovery document.
130+
131+
**Offline verification (recommended):**
132+
133+
```bash
134+
agentpin verify \
135+
--credential <jwt> \
136+
--discovery ./agent-identity.json \
137+
--pin-store ./pins.json
138+
```
139+
140+
**Online verification (fetches discovery from issuer domain):**
141+
142+
```bash
143+
agentpin verify --credential <jwt>
144+
```
145+
146+
**Options:**
147+
148+
| Flag | Required | Description |
149+
|------|----------|-------------|
150+
| `--credential` | Yes | The JWT credential to verify |
151+
| `--discovery` | No | Path to local discovery document (offline mode) |
152+
| `--revocation` | No | Path to local revocation document |
153+
| `--pin-store` | No | Path to TOFU pin store file (created if missing) |
154+
| `--audience` | No | Expected audience domain |
155+
| `--bundle` | No | Path to trust bundle file |
156+
157+
**Output (JSON):**
158+
159+
```json
160+
{
161+
"valid": true,
162+
"agent_id": "urn:agentpin:example.com:scout",
163+
"issuer": "example.com",
164+
"capabilities": ["read:data", "write:reports"],
165+
"key_pinning": "first_use",
166+
"delegation_chain_valid": true,
167+
"expires_at": "2026-02-15T13:00:00Z"
168+
}
169+
```
170+
171+
**Failure output:**
172+
173+
```json
174+
{
175+
"valid": false,
176+
"error_code": "expired",
177+
"error_message": "Credential expired at 2026-02-15T12:00:00Z"
178+
}
179+
```
180+
181+
**Using with trust bundles:**
182+
183+
```bash
184+
agentpin verify \
185+
--credential <jwt> \
186+
--bundle ./trust-bundle.json \
187+
--pin-store ./pins.json
188+
```
189+
190+
---
191+
192+
### `agentpin-server` — Serve Discovery Endpoints
193+
194+
The `agentpin-server` binary serves `.well-known` discovery and revocation endpoints over HTTP.
195+
196+
```bash
197+
agentpin-server \
198+
--discovery ./agent-identity.json \
199+
--revocation ./revocations.json \
200+
--port 8080
201+
```
202+
203+
**Options:**
204+
205+
| Flag | Required | Default | Description |
206+
|------|----------|---------|-------------|
207+
| `--discovery` | Yes || Path to discovery document JSON |
208+
| `--revocation` | No || Path to revocation document JSON |
209+
| `--port` | No | `8080` | HTTP listening port |
210+
| `--host` | No | `0.0.0.0` | Bind address |
211+
212+
**Endpoints served:**
213+
214+
| Path | Cache-Control | Description |
215+
|------|---------------|-------------|
216+
| `GET /.well-known/agent-identity.json` | `max-age=3600` | Discovery document |
217+
| `GET /.well-known/agent-identity-revocations.json` | `max-age=300` | Revocation document |
218+
| `GET /health` || Health check (returns `200 OK`) |
219+
220+
**Production deployment behind a reverse proxy:**
221+
222+
```nginx
223+
# nginx configuration
224+
server {
225+
listen 443 ssl;
226+
server_name example.com;
227+
228+
location /.well-known/agent-identity.json {
229+
proxy_pass http://127.0.0.1:8080;
230+
proxy_set_header Host $host;
231+
add_header Cache-Control "public, max-age=3600";
232+
add_header Content-Type "application/json";
233+
}
234+
235+
location /.well-known/agent-identity-revocations.json {
236+
proxy_pass http://127.0.0.1:8080;
237+
proxy_set_header Host $host;
238+
add_header Cache-Control "public, max-age=300";
239+
add_header Content-Type "application/json";
240+
}
241+
}
242+
```
243+
244+
---
245+
246+
## Common Workflows
247+
248+
### Generate Keys, Issue, and Verify
249+
250+
```bash
251+
# 1. Generate keys
252+
agentpin keygen --domain example.com --kid key-01 --output-dir ./keys
253+
254+
# 2. Issue a credential
255+
JWT=$(agentpin issue \
256+
--private-key ./keys/key-01.private.pem \
257+
--kid key-01 \
258+
--issuer example.com \
259+
--agent-id "urn:agentpin:example.com:agent" \
260+
--capabilities "read:data" \
261+
--ttl 3600)
262+
263+
# 3. Verify offline with a discovery document
264+
agentpin verify \
265+
--credential "$JWT" \
266+
--discovery ./agent-identity.json \
267+
--pin-store ./pins.json
268+
```
269+
270+
### Rotate Keys
271+
272+
```bash
273+
# 1. Generate new key
274+
agentpin keygen --domain example.com --kid key-02 --output-dir ./keys
275+
276+
# 2. Add new key to discovery document (keep old key temporarily)
277+
# Edit agent-identity.json to add key-02 to public_keys array
278+
279+
# 3. Issue new credentials with the new key
280+
agentpin issue --private-key ./keys/key-02.private.pem --kid key-02 ...
281+
282+
# 4. After transition period, revoke old key
283+
# Add key-01 to revocation document
284+
285+
# 5. Remove old key from discovery document
286+
```
287+
288+
### Batch Verification
289+
290+
```bash
291+
# Verify multiple credentials from a file
292+
while IFS= read -r jwt; do
293+
result=$(agentpin verify --credential "$jwt" --discovery ./discovery.json --pin-store ./pins.json)
294+
echo "$jwt: $(echo "$result" | jq -r '.valid')"
295+
done < credentials.txt
296+
```

0 commit comments

Comments
 (0)