# 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.