banatie-service/docs/api/admin.md

236 lines
6.5 KiB
Markdown

# Banatie API - Administration & Authentication
## Authentication Overview
All API endpoints (except public endpoints and bootstrap) require authentication via API key in the `X-API-Key` header.
### API Key Types
**Master Keys**
- Full administrative access
- Never expire
- Can create and revoke other API keys
- Access to all admin endpoints
**Project Keys**
- Standard access for image generation
- Expire in 90 days by default
- Scoped to specific organization and project
- Rate limited (100 requests/hour)
### Header Format
```
X-API-Key: bnt_your_key_here
```
---
## Public Endpoints
### GET /health
Health check with server status.
**Authentication:** None
**Purpose:** Monitor API availability and uptime
**Returns:** Status, timestamp, uptime, environment, version
---
### GET /api/info
API information and configuration limits.
**Authentication:** Optional (returns key info if authenticated)
**Purpose:** Discover API capabilities and limits
**Returns:** API name, version, endpoints list, file size/format limits
---
## Bootstrap Endpoint
### POST /api/bootstrap/initial-key
Create the first master API key (one-time only).
**Authentication:** None (public, works only when database is empty)
**Purpose:** Initialize the API with first master key
**Notes:**
- Only works when no API keys exist in database
- Returns master key value (save securely, shown only once)
- Subsequent calls return 403 Forbidden
---
## API Key Management
All endpoints require Master Key authentication.
### POST /api/admin/keys
Create new API key (master or project).
**Authentication:** Master Key required
**Parameters:**
- `type` - "master" or "project" (required)
- `projectId` - Project identifier (required for project keys)
- `organizationId` - Organization UUID (optional, auto-created)
- `organizationSlug` - Organization slug (optional, auto-created)
- `projectSlug` - Project slug (optional, auto-created)
- `name` - Friendly name for the key (optional)
- `expiresInDays` - Expiration days (optional, default: 90 for project keys)
**Purpose:** Generate new API keys for projects or admin users
**Notes:**
- Automatically creates organization and project if they don't exist
- Returns API key value (save securely, shown only once)
- Master keys never expire, project keys expire in 90 days by default
---
### GET /api/admin/keys
List all API keys.
**Authentication:** Master Key required
**Purpose:** View all active and inactive API keys
**Returns:** Array of all keys with metadata (no sensitive key values), includes organization and project details
**Notes:**
- Shows all keys regardless of active status
- Includes last used timestamp
- Does not return actual API key values (hashed in database)
---
### DELETE /api/admin/keys/:keyId
Revoke an API key.
**Authentication:** Master Key required
**Parameters:**
- `keyId` - UUID of the key to revoke (path parameter)
**Purpose:** Deactivate an API key (soft delete)
**Notes:**
- Soft delete via `is_active` flag
- Revoked keys cannot be reactivated
- Key remains in database for audit trail
---
## Rate Limiting
### API Key Rate Limiting
Rate limits apply per API key to protected endpoints.
**Limits:**
- **Project Keys:** 100 requests per hour
- **Master Keys:** No rate limit on admin endpoints
**Affected Endpoints:**
- All `/api/v1/generations` endpoints (POST, PUT, regenerate)
- All `/api/v1/images` endpoints (POST upload, PUT)
- All `/api/v1/flows` endpoints (PUT, regenerate)
- All `/api/v1/live/scopes` endpoints (POST, PUT, regenerate, DELETE)
**Response Headers:**
- `X-RateLimit-Limit` - Maximum requests per window
- `X-RateLimit-Remaining` - Requests remaining
- `X-RateLimit-Reset` - Reset timestamp (ISO 8601)
**429 Too Many Requests:**
- Returned when limit exceeded
- Includes `Retry-After` header (seconds until reset)
---
### IP-Based Rate Limiting (Live URLs)
Separate rate limiting for public live URL generation endpoints.
**Limits:**
- **10 new generations per hour per IP address**
- Only cache MISS (new generations) count toward limit
- Cache HIT (cached images) do NOT count toward limit
**Affected Endpoints:**
- `GET /:orgSlug/:projectSlug/live/:scope` - Public live URL generation
**Purpose:**
- Prevent abuse of public live URL endpoints
- Separate from API key limits (for authenticated endpoints)
- Does not affect API key-authenticated endpoints
**Response Headers:**
- `X-RateLimit-Limit` - Maximum requests per window (10)
- `X-RateLimit-Remaining` - Requests remaining
- `X-RateLimit-Reset` - Seconds until reset
**429 Too Many Requests:**
- Returned when IP limit exceeded
- Includes `Retry-After` header (seconds until reset)
- Error code: `IP_RATE_LIMIT_EXCEEDED`
**Notes:**
- Uses in-memory store with automatic cleanup
- Supports X-Forwarded-For header for proxy/load balancer setups
- IP limit resets every hour per IP address
---
## Error Codes
### HTTP Status Codes
| Code | Description |
|------|-------------|
| 401 | Unauthorized - Missing, invalid, expired, or revoked API key |
| 403 | Forbidden - Insufficient permissions (master key required) |
| 409 | Conflict - Resource already exists (e.g., duplicate scope slug) |
| 429 | Too Many Requests - Rate limit exceeded (API key or IP) |
### Authentication Error Codes
| Error Code | HTTP Status | Description |
|------------|-------------|-------------|
| `MISSING_API_KEY` | 401 | No X-API-Key header provided |
| `INVALID_API_KEY` | 401 | Key is invalid, expired, or revoked |
| `MASTER_KEY_REQUIRED` | 403 | Endpoint requires master key, project key insufficient |
| `BOOTSTRAP_NOT_ALLOWED` | 403 | Keys already exist, cannot bootstrap again |
### Rate Limiting Error Codes
| Error Code | HTTP Status | Description |
|------------|-------------|-------------|
| `RATE_LIMIT_EXCEEDED` | 429 | API key rate limit exceeded (100/hour) |
| `IP_RATE_LIMIT_EXCEEDED` | 429 | IP rate limit exceeded for live URLs (10/hour) |
### Live Scope Error Codes
| Error Code | HTTP Status | Description |
|------------|-------------|-------------|
| `SCOPE_INVALID_FORMAT` | 400 | Scope slug format invalid (must be alphanumeric + hyphens + underscores) |
| `SCOPE_ALREADY_EXISTS` | 409 | Scope with this slug already exists in project |
| `SCOPE_NOT_FOUND` | 404 | Scope does not exist or access denied |
| `IMAGE_NOT_IN_SCOPE` | 400 | Image does not belong to specified scope |
**Notes:**
- All error responses follow the format: `{ "success": false, "error": { "message": "...", "code": "..." } }`
- Rate limit errors include `Retry-After` header with seconds until reset
- Scope management endpoints require project key authentication