-
Notifications
You must be signed in to change notification settings - Fork 0
docs: remove * scope from agent auth contract (Phase B) #4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,189 @@ | ||
| --- | ||
| title: "Agent Authentication Contract" | ||
| description: "ASG Agent Cloud v5.2.x API Key authentication specification" | ||
| --- | ||
|
|
||
| # Agent Authentication Contract | ||
|
|
||
| This document defines the authentication contract for programmatic (agent/bot) access to ASG Agent Cloud. | ||
|
|
||
| ## Authentication Hierarchy | ||
|
|
||
| ASG Gateway supports two authentication methods, evaluated in order: | ||
|
|
||
| 1. **SIWS Session Cookie** (`asg_session`) — For console UI users | ||
| 2. **Bearer Token API Key** — For agents and programmatic access | ||
|
|
||
| ``` | ||
| Authorization: Bearer asc_sk_... | ||
| ``` | ||
|
|
||
| ## API Key Format | ||
|
|
||
| | Prefix | Environment | Example | | ||
| |--------|-------------|---------| | ||
| | `asc_sk_live_` | Production | `asc_sk_live_abc123...` | | ||
| | `asc_sk_test_` | Staging/Dev | `asc_sk_test_xyz789...` | | ||
|
|
||
| Keys are 64-character random strings prefixed with environment indicator. | ||
|
|
||
| ## Security Model | ||
|
|
||
| ### Key Storage | ||
|
|
||
| - **Plain-text key**: Shown ONCE at creation time — user must save it | ||
| - **Server stores**: BCrypt hash only (cost=10) | ||
| - **No recovery**: Lost keys cannot be retrieved; user must rotate | ||
|
|
||
| ### Scopes | ||
|
|
||
| | Scope | Description | | ||
| |-------|-------------| | ||
| | `read` | Query balance, history, usage stats (default) | | ||
| | `fund` | Initiate deposits, manage billing (requires opt-in) | | ||
|
|
||
| ### Rate Limits | ||
|
|
||
| | Tier | RPM Limit | Default | | ||
| |------|-----------|---------| | ||
| | Free | 60 | ✓ | | ||
| | Plus | 300 | | | ||
| | Pro | 1000 | | | ||
|
|
||
| Limits are per-key, not per-wallet. 429 responses include `Retry-After` header. | ||
|
|
||
| ## Endpoints (Billing Plane) | ||
|
|
||
| ### Create Key | ||
|
|
||
| ```http | ||
| POST /keys | ||
| Content-Type: application/json | ||
| Cookie: asg_session=... | ||
|
|
||
| { | ||
| "name": "My Agent Bot", | ||
| "scopes": ["read"], | ||
| "rate_limit_rpm": 60 | ||
| } | ||
| ``` | ||
|
|
||
| **Response (201):** | ||
|
|
||
| ```json | ||
| { | ||
| "key_id": "key_abc123", | ||
| "api_key": "asc_sk_live_...", // ⚠️ SHOW ONCE | ||
| "name": "My Agent Bot", | ||
| "scopes": ["read"], | ||
| "rate_limit_rpm": 60, | ||
| "created_at": "2026-02-03T12:00:00Z" | ||
| } | ||
| ``` | ||
|
|
||
| ### List Keys | ||
|
|
||
| ```http | ||
| GET /keys | ||
| Cookie: asg_session=... | ||
| ``` | ||
|
|
||
| **Response:** | ||
|
|
||
| ```json | ||
| { | ||
| "keys": [ | ||
| { | ||
| "key_id": "key_abc123", | ||
| "name": "My Agent Bot", | ||
| "prefix": "asc_sk_live_abc...", // First 16 chars only | ||
| "scopes": ["read"], | ||
| "rate_limit_rpm": 60, | ||
| "last_used_at": "2026-02-03T11:30:00Z", | ||
| "created_at": "2026-02-03T10:00:00Z" | ||
| } | ||
| ] | ||
| } | ||
| ``` | ||
|
|
||
| ### Revoke Key | ||
|
|
||
| ```http | ||
| DELETE /keys/:key_id | ||
| Cookie: asg_session=... | ||
| ``` | ||
|
|
||
| ### Rotate Key | ||
|
|
||
| ```http | ||
| POST /keys/:key_id/rotate | ||
| Cookie: asg_session=... | ||
| ``` | ||
|
|
||
| **Response:** New key object (same as Create) | ||
|
|
||
| ### Validate Key (Internal) | ||
|
|
||
| ```http | ||
| POST /keys/validate | ||
| Content-Type: application/json | ||
|
|
||
| { "api_key": "asc_sk_live_..." } | ||
| ``` | ||
|
|
||
| **Response:** | ||
|
|
||
| ```json | ||
| { | ||
| "valid": true, | ||
| "key_id": "key_abc123", | ||
| "owner_wallet": "ABC...xyz", | ||
| "scopes": ["read"], | ||
| "rate_limit_rpm": 60 | ||
| } | ||
| ``` | ||
|
|
||
| ## Gateway Auth Middleware | ||
|
|
||
| The gateway validates keys via billing-plane `/keys/validate` with 5-minute caching. | ||
|
|
||
| ```typescript | ||
| // Request gets decorated with: | ||
| interface AuthenticatedRequest extends Request { | ||
| apiKeyId?: string; // e.g., "key_abc123" | ||
| ownerWallet?: string; // Wallet that created the key | ||
| scopes?: string[]; // ["read"] or ["read", "fund"] | ||
| rateLimitRpm?: number; // Per-key rate limit | ||
| } | ||
| ``` | ||
|
|
||
| ## Error Responses | ||
|
|
||
| | Status | Code | Description | | ||
| |--------|------|-------------| | ||
| | 401 | `UNAUTHORIZED` | Missing or invalid API key | | ||
| | 403 | `FORBIDDEN` | Missing required scope | | ||
| | 429 | `RATE_LIMITED` | Rate limit exceeded | | ||
|
|
||
| ## Usage Example (Agent) | ||
|
|
||
| ```typescript | ||
| const response = await fetch('https://agent.asgcompute.com/v1/account/balance', { | ||
| headers: { | ||
| 'Authorization': 'Bearer asc_sk_live_your_key_here', | ||
| 'Content-Type': 'application/json' | ||
| } | ||
| }); | ||
|
|
||
| if (response.status === 401) { | ||
| // Re-authenticate or refresh key | ||
| } | ||
|
|
||
| const balance = await response.json(); | ||
| ``` | ||
|
|
||
| ## Related Documents | ||
|
|
||
| - [Quickstart for Agents](/docs/guide/agent-quickstart) | ||
| - [Rate Limiting](/docs/security/rate-limits) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider hyphenating “Rate‑Limiting” if used as a compound adjective. LanguageTool flags this as a potential compound adjective. If the link title is intended as an adjective, hyphenate it. 🧰 Tools🪛 LanguageTool[uncategorized] ~188-~188: If this is a compound adjective that modifies the following noun, use a hyphen. (EN_COMPOUND_ADJECTIVE_INTERNAL) 🤖 Prompt for AI Agents |
||
| - [Error Codes](/docs/api/errors) | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use the documented key prefixes in the Authorization example.
The example shows
asc_sk_..., but the format section definesasc_sk_live_/asc_sk_test_. Align the example to avoid confusion.Proposed fix
📝 Committable suggestion
🤖 Prompt for AI Agents