Files
skybridge/kms/docs/API.md
2025-08-26 19:16:41 -04:00

614 lines
13 KiB
Markdown

# API Key Management Service - API Documentation
This document describes the REST API endpoints for the API Key Management Service.
## Base URL
```
http://localhost:8080
```
## Authentication
All protected endpoints require authentication via the `X-User-Email` header (when using the HeaderAuthenticationProvider).
```
X-User-Email: user@example.com
```
## Content Type
All endpoints accept and return JSON data:
```
Content-Type: application/json
```
## Error Response Format
All error responses follow this format:
```json
{
"error": "Error Type",
"message": "Detailed error message"
}
```
Common HTTP status codes:
- `400` - Bad Request (invalid input)
- `401` - Unauthorized (authentication required)
- `404` - Not Found (resource not found)
- `500` - Internal Server Error
## Health Check Endpoints
### Health Check
```
GET /health
```
Basic health check for load balancers.
**Response:**
```json
{
"status": "healthy",
"timestamp": "2023-01-01T00:00:00Z"
}
```
### Readiness Check
```
GET /ready
```
Comprehensive readiness check including database connectivity.
**Response:**
```json
{
"status": "ready",
"timestamp": "2023-01-01T00:00:00Z",
"checks": {
"database": "healthy"
}
}
```
## Authentication Endpoints
### User Login
```
POST /api/login
```
Initiates user authentication flow.
**Headers:**
- `X-User-Email: user@example.com` (required for HeaderAuthenticationProvider)
**Request Body:**
```json
{
"app_id": "com.example.app",
"permissions": ["repo.read", "repo.write"],
"redirect_uri": "https://example.com/callback"
}
```
**Response:**
```json
{
"redirect_url": "https://example.com/callback?token=user-token-abc123"
}
```
Or if no redirect_uri provided:
```json
{
"token": "user-token-abc123",
"user_id": "user@example.com",
"app_id": "com.example.app",
"expires_in": 604800
}
```
### Token Verification
```
POST /api/verify
```
Verifies a token and returns its permissions.
**Request Body:**
```json
{
"app_id": "com.example.app",
"type": "user",
"user_id": "user@example.com",
"token": "token-to-verify",
"permissions": ["repo.read", "repo.write"]
}
```
**Response:**
```json
{
"valid": true,
"user_id": "user@example.com",
"permissions": ["repo.read", "repo.write"],
"permission_results": {
"repo.read": true,
"repo.write": true
},
"expires_at": "2023-01-08T00:00:00Z",
"max_valid_at": "2023-01-31T00:00:00Z",
"token_type": "user"
}
```
### Token Renewal
```
POST /api/renew
```
Renews a user token with extended expiration.
**Request Body:**
```json
{
"app_id": "com.example.app",
"user_id": "user@example.com",
"token": "current-token"
}
```
**Response:**
```json
{
"token": "new-renewed-token",
"expires_at": "2023-01-15T00:00:00Z",
"max_valid_at": "2023-01-31T00:00:00Z"
}
```
## Application Management
### List Applications
```
GET /api/applications?limit=50&offset=0
```
Retrieves a paginated list of applications.
**Query Parameters:**
- `limit` (optional): Number of results to return (default: 50, max: 100)
- `offset` (optional): Number of results to skip (default: 0)
**Headers:**
- `X-User-Email: user@example.com` (required)
**Response:**
```json
{
"data": [
{
"app_id": "com.example.app",
"app_link": "https://example.com",
"type": ["static", "user"],
"callback_url": "https://example.com/callback",
"hmac_key": "hmac-key-hidden-in-responses",
"token_renewal_duration": 604800000000000,
"max_token_duration": 2592000000000000,
"owner": {
"type": "team",
"name": "Example Team",
"owner": "example-org"
},
"created_at": "2023-01-01T00:00:00Z",
"updated_at": "2023-01-01T00:00:00Z"
}
],
"limit": 50,
"offset": 0,
"count": 1
}
```
### Create Application
```
POST /api/applications
```
Creates a new application.
**Headers:**
- `X-User-Email: user@example.com` (required)
**Request Body:**
```json
{
"app_id": "com.example.newapp",
"app_link": "https://newapp.example.com",
"type": ["static", "user"],
"callback_url": "https://newapp.example.com/callback",
"token_renewal_duration": "168h",
"max_token_duration": "720h",
"owner": {
"type": "team",
"name": "Development Team",
"owner": "example-org"
}
}
```
**Response:**
```json
{
"app_id": "com.example.newapp",
"app_link": "https://newapp.example.com",
"type": ["static", "user"],
"callback_url": "https://newapp.example.com/callback",
"hmac_key": "generated-hmac-key",
"token_renewal_duration": 604800000000000,
"max_token_duration": 2592000000000000,
"owner": {
"type": "team",
"name": "Development Team",
"owner": "example-org"
},
"created_at": "2023-01-01T00:00:00Z",
"updated_at": "2023-01-01T00:00:00Z"
}
```
### Get Application
```
GET /api/applications/{app_id}
```
Retrieves a specific application by ID.
**Headers:**
- `X-User-Email: user@example.com` (required)
**Response:**
```json
{
"app_id": "com.example.app",
"app_link": "https://example.com",
"type": ["static", "user"],
"callback_url": "https://example.com/callback",
"hmac_key": "hmac-key-value",
"token_renewal_duration": 604800000000000,
"max_token_duration": 2592000000000000,
"owner": {
"type": "team",
"name": "Example Team",
"owner": "example-org"
},
"created_at": "2023-01-01T00:00:00Z",
"updated_at": "2023-01-01T00:00:00Z"
}
```
### Update Application
```
PUT /api/applications/{app_id}
```
Updates an existing application. Only provided fields will be updated.
**Headers:**
- `X-User-Email: user@example.com` (required)
**Request Body:**
```json
{
"app_link": "https://updated.example.com",
"callback_url": "https://updated.example.com/callback",
"owner": {
"type": "individual",
"name": "John Doe",
"owner": "john.doe@example.com"
}
}
```
**Response:**
```json
{
"app_id": "com.example.app",
"app_link": "https://updated.example.com",
"type": ["static", "user"],
"callback_url": "https://updated.example.com/callback",
"hmac_key": "existing-hmac-key",
"token_renewal_duration": 604800000000000,
"max_token_duration": 2592000000000000,
"owner": {
"type": "individual",
"name": "John Doe",
"owner": "john.doe@example.com"
},
"created_at": "2023-01-01T00:00:00Z",
"updated_at": "2023-01-01T12:00:00Z"
}
```
### Delete Application
```
DELETE /api/applications/{app_id}
```
Deletes an application and all associated tokens.
**Headers:**
- `X-User-Email: user@example.com` (required)
**Response:**
```
HTTP 204 No Content
```
## Static Token Management
### List Tokens for Application
```
GET /api/applications/{app_id}/tokens?limit=50&offset=0
```
Retrieves all static tokens for a specific application.
**Query Parameters:**
- `limit` (optional): Number of results to return (default: 50, max: 100)
- `offset` (optional): Number of results to skip (default: 0)
**Headers:**
- `X-User-Email: user@example.com` (required)
**Response:**
```json
{
"data": [
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"app_id": "com.example.app",
"owner": {
"type": "individual",
"name": "John Doe",
"owner": "john.doe@example.com"
},
"type": "hmac",
"created_at": "2023-01-01T00:00:00Z",
"updated_at": "2023-01-01T00:00:00Z"
}
],
"limit": 50,
"offset": 0,
"count": 1
}
```
### Create Static Token
```
POST /api/applications/{app_id}/tokens
```
Creates a new static token for an application.
**Headers:**
- `X-User-Email: user@example.com` (required)
**Request Body:**
```json
{
"owner": {
"type": "individual",
"name": "API Client",
"owner": "api-client@example.com"
},
"permissions": ["repo.read", "repo.write", "app.read"]
}
```
**Response:**
```json
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"token": "static-token-abc123xyz789",
"permissions": ["repo.read", "repo.write", "app.read"],
"created_at": "2023-01-01T00:00:00Z"
}
```
**Note:** The `token` field is only returned once during creation for security reasons.
### Delete Static Token
```
DELETE /api/tokens/{token_id}
```
Deletes a static token and revokes all its permissions.
**Headers:**
- `X-User-Email: user@example.com` (required)
**Response:**
```
HTTP 204 No Content
```
## Permission Scopes
The following permission scopes are available:
### System Permissions
- `internal` - Full access to internal system operations (system only)
- `internal.read` - Read access to internal system data (system only)
- `internal.write` - Write access to internal system data (system only)
- `internal.admin` - Administrative access to internal system (system only)
### Application Management
- `app` - Access to application management
- `app.read` - Read application information
- `app.write` - Create and update applications
- `app.delete` - Delete applications
### Token Management
- `token` - Access to token management
- `token.read` - Read token information
- `token.create` - Create new tokens
- `token.revoke` - Revoke existing tokens
### Permission Management
- `permission` - Access to permission management
- `permission.read` - Read permission information
- `permission.write` - Create and update permissions
- `permission.grant` - Grant permissions to tokens
- `permission.revoke` - Revoke permissions from tokens
### Repository Access (Example)
- `repo` - Access to repository operations
- `repo.read` - Read repository data
- `repo.write` - Write to repositories
- `repo.admin` - Administrative access to repositories
## Rate Limiting
The API implements rate limiting with the following limits:
- **General API endpoints**: 100 requests per minute with burst of 20
- **Authentication endpoints** (`/login`, `/verify`, `/renew`): 10 requests per minute with burst of 5
Rate limit headers are included in responses:
- `X-RateLimit-Limit`: Request limit per window
- `X-RateLimit-Remaining`: Remaining requests in current window
- `X-RateLimit-Reset`: Unix timestamp when the window resets
When rate limited:
```json
{
"error": "Rate limit exceeded",
"message": "Too many requests. Please try again later."
}
```
## Testing Endpoints
For testing purposes, different user scenarios are available through different ports:
- **Port 80**: Regular user (`test@example.com`)
- **Port 8081**: Admin user (`admin@example.com`) with higher rate limits
- **Port 8082**: Limited user (`limited@example.com`) with lower rate limits
## Example Workflows
### Creating an Application and Static Token
1. **Create Application:**
```bash
curl -X POST http://localhost/api/applications \
-H "Content-Type: application/json" \
-H "X-User-Email: admin@example.com" \
-d '{
"app_id": "com.mycompany.api",
"app_link": "https://api.mycompany.com",
"type": ["static", "user"],
"callback_url": "https://api.mycompany.com/callback",
"token_renewal_duration": "168h",
"max_token_duration": "720h",
"owner": {
"type": "team",
"name": "API Team",
"owner": "api-team@mycompany.com"
}
}'
```
2. **Create Static Token:**
```bash
curl -X POST http://localhost/api/applications/com.mycompany.api/tokens \
-H "Content-Type: application/json" \
-H "X-User-Email: admin@example.com" \
-d '{
"owner": {
"type": "individual",
"name": "Service Account",
"owner": "service@mycompany.com"
},
"permissions": ["repo.read", "repo.write"]
}'
```
3. **Verify Token:**
```bash
curl -X POST http://localhost/api/verify \
-H "Content-Type: application/json" \
-d '{
"app_id": "com.mycompany.api",
"type": "static",
"token": "static-token-abc123xyz789",
"permissions": ["repo.read"]
}'
```
### User Authentication Flow
1. **Initiate Login:**
```bash
curl -X POST http://localhost/api/login \
-H "Content-Type: application/json" \
-H "X-User-Email: user@example.com" \
-d '{
"app_id": "com.mycompany.api",
"permissions": ["repo.read"],
"redirect_uri": "https://myapp.com/callback"
}'
```
2. **Verify User Token:**
```bash
curl -X POST http://localhost/api/verify \
-H "Content-Type: application/json" \
-d '{
"app_id": "com.mycompany.api",
"type": "user",
"user_id": "user@example.com",
"token": "user-token-from-login",
"permissions": ["repo.read"]
}'
```
3. **Renew Token Before Expiry:**
```bash
curl -X POST http://localhost/api/renew \
-H "Content-Type: application/json" \
-d '{
"app_id": "com.mycompany.api",
"user_id": "user@example.com",
"token": "current-user-token"
}'
```
## Security Considerations
- All tokens should be transmitted over HTTPS in production
- Static tokens are returned only once during creation - store them securely
- User tokens have both renewal and maximum validity periods
- HMAC keys are used for token signing and should be rotated regularly
- Rate limiting helps prevent abuse
- Permission scopes follow hierarchical structure
- All operations are logged with user attribution
## Development and Testing
The service includes comprehensive health checks, detailed logging, and metrics collection. When running with `LOG_LEVEL=debug`, additional debugging information is available in the logs.
For local development, the service can be started with:
```bash
docker-compose up -d
```
This starts PostgreSQL, the API service, and Nginx proxy with test user headers configured.