diff --git a/security/agent-auth-contract.mdx b/security/agent-auth-contract.mdx new file mode 100644 index 0000000..3c702b2 --- /dev/null +++ b/security/agent-auth-contract.mdx @@ -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) +- [Error Codes](/docs/api/errors)