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