614 lines
13 KiB
Markdown
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.
|