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

13 KiB

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:

{
  "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:

{
  "status": "healthy",
  "timestamp": "2023-01-01T00:00:00Z"
}

Readiness Check

GET /ready

Comprehensive readiness check including database connectivity.

Response:

{
  "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:

{
  "app_id": "com.example.app",
  "permissions": ["repo.read", "repo.write"],
  "redirect_uri": "https://example.com/callback"
}

Response:

{
  "redirect_url": "https://example.com/callback?token=user-token-abc123"
}

Or if no redirect_uri provided:

{
  "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:

{
  "app_id": "com.example.app",
  "type": "user",
  "user_id": "user@example.com",
  "token": "token-to-verify",
  "permissions": ["repo.read", "repo.write"]
}

Response:

{
  "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:

{
  "app_id": "com.example.app",
  "user_id": "user@example.com",
  "token": "current-token"
}

Response:

{
  "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:

{
  "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:

{
  "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:

{
  "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:

{
  "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:

{
  "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:

{
  "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:

{
  "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:

{
  "owner": {
    "type": "individual",
    "name": "API Client",
    "owner": "api-client@example.com"
  },
  "permissions": ["repo.read", "repo.write", "app.read"]
}

Response:

{
  "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:

{
  "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:
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"
    }
  }'
  1. Create Static Token:
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"]
  }'
  1. Verify Token:
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:
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"
  }'
  1. Verify User Token:
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"]
  }'
  1. Renew Token Before Expiry:
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:

docker-compose up -d

This starts PostgreSQL, the API service, and Nginx proxy with test user headers configured.