-
This commit is contained in:
677
docs/ARCHITECTURE.md
Normal file
677
docs/ARCHITECTURE.md
Normal file
@ -0,0 +1,677 @@
|
|||||||
|
# API Key Management Service (KMS) - System Architecture
|
||||||
|
|
||||||
|
## Table of Contents
|
||||||
|
1. [System Overview](#system-overview)
|
||||||
|
2. [Architecture Principles](#architecture-principles)
|
||||||
|
3. [Component Architecture](#component-architecture)
|
||||||
|
4. [System Architecture Diagram](#system-architecture-diagram)
|
||||||
|
5. [Request Flow Pipeline](#request-flow-pipeline)
|
||||||
|
6. [Authentication Flow](#authentication-flow)
|
||||||
|
7. [API Design](#api-design)
|
||||||
|
8. [Technology Stack](#technology-stack)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## System Overview
|
||||||
|
|
||||||
|
The API Key Management Service (KMS) is a secure, scalable platform for managing API authentication tokens across applications. Built with Go backend and React TypeScript frontend, it provides centralized token lifecycle management with enterprise-grade security features.
|
||||||
|
|
||||||
|
### Key Capabilities
|
||||||
|
- **Multi-Provider Authentication**: Header, JWT, OAuth2, SAML support
|
||||||
|
- **Dual Token System**: Static HMAC tokens and renewable JWT user tokens
|
||||||
|
- **Hierarchical Permissions**: Role-based access control with inheritance
|
||||||
|
- **Enterprise Security**: Rate limiting, brute force protection, audit logging
|
||||||
|
- **High Availability**: Containerized deployment with load balancing
|
||||||
|
|
||||||
|
### Core Features
|
||||||
|
- **Token Lifecycle Management**: Create, verify, renew, and revoke tokens
|
||||||
|
- **Application Management**: Multi-tenant application configuration
|
||||||
|
- **User Session Tracking**: Comprehensive session management
|
||||||
|
- **Audit Logging**: Complete audit trail of all operations
|
||||||
|
- **Health Monitoring**: Built-in health checks and metrics
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Architecture Principles
|
||||||
|
|
||||||
|
### Clean Architecture
|
||||||
|
The system follows clean architecture principles with clear separation of concerns:
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────┐
|
||||||
|
│ Handlers │ ← HTTP request handling
|
||||||
|
├─────────────────┤
|
||||||
|
│ Services │ ← Business logic
|
||||||
|
├─────────────────┤
|
||||||
|
│ Repositories │ ← Data access
|
||||||
|
├─────────────────┤
|
||||||
|
│ Database │ ← Data persistence
|
||||||
|
└─────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### Design Principles
|
||||||
|
- **Dependency Injection**: All services receive dependencies through constructors
|
||||||
|
- **Interface Segregation**: Repository interfaces enable testing and flexibility
|
||||||
|
- **Single Responsibility**: Each component has one clear purpose
|
||||||
|
- **Fail-Safe Defaults**: Security-first configuration with safe fallbacks
|
||||||
|
- **Immutable Operations**: Database transactions and audit logging
|
||||||
|
- **Defense in Depth**: Multiple security layers throughout the stack
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Component Architecture
|
||||||
|
|
||||||
|
### Backend Components (`internal/`)
|
||||||
|
|
||||||
|
#### **Handlers Layer** (`internal/handlers/`)
|
||||||
|
HTTP request processors implementing REST API endpoints:
|
||||||
|
|
||||||
|
- **`application.go`**: Application CRUD operations
|
||||||
|
- Create, read, update, delete applications
|
||||||
|
- HMAC key management
|
||||||
|
- Ownership validation
|
||||||
|
|
||||||
|
- **`auth.go`**: Authentication workflows
|
||||||
|
- User login and logout
|
||||||
|
- Token renewal and validation
|
||||||
|
- Multi-provider authentication
|
||||||
|
|
||||||
|
- **`token.go`**: Token operations
|
||||||
|
- Static token creation
|
||||||
|
- Token verification
|
||||||
|
- Token revocation
|
||||||
|
|
||||||
|
- **`health.go`**: System health checks
|
||||||
|
- Database connectivity
|
||||||
|
- Cache availability
|
||||||
|
- Service status
|
||||||
|
|
||||||
|
- **`oauth2.go`, `saml.go`**: External authentication providers
|
||||||
|
- OAuth2 authorization code flow
|
||||||
|
- SAML assertion validation
|
||||||
|
- Provider callback handling
|
||||||
|
|
||||||
|
#### **Services Layer** (`internal/services/`)
|
||||||
|
Business logic implementation with transaction management:
|
||||||
|
|
||||||
|
- **`auth_service.go`**: Authentication provider orchestration
|
||||||
|
- Multi-provider authentication
|
||||||
|
- Session management
|
||||||
|
- User context creation
|
||||||
|
|
||||||
|
- **`token_service.go`**: Token lifecycle management
|
||||||
|
- Static token generation and validation
|
||||||
|
- JWT user token management
|
||||||
|
- Permission assignment
|
||||||
|
|
||||||
|
- **`application_service.go`**: Application configuration management
|
||||||
|
- Application CRUD operations
|
||||||
|
- Configuration validation
|
||||||
|
- HMAC key rotation
|
||||||
|
|
||||||
|
- **`session_service.go`**: User session tracking
|
||||||
|
- Session creation and validation
|
||||||
|
- Session timeout handling
|
||||||
|
- Cross-provider session management
|
||||||
|
|
||||||
|
#### **Repository Layer** (`internal/repository/postgres/`)
|
||||||
|
Data access with ACID transaction support:
|
||||||
|
|
||||||
|
- **`application_repository.go`**: Application persistence
|
||||||
|
- Secure dynamic query building
|
||||||
|
- Parameterized queries
|
||||||
|
- Ownership validation
|
||||||
|
|
||||||
|
- **`token_repository.go`**: Static token management
|
||||||
|
- BCrypt token hashing
|
||||||
|
- Token lookup and validation
|
||||||
|
- Permission relationship management
|
||||||
|
|
||||||
|
- **`permission_repository.go`**: Permission catalog
|
||||||
|
- Hierarchical permission structure
|
||||||
|
- Permission validation
|
||||||
|
- Bulk permission operations
|
||||||
|
|
||||||
|
- **`session_repository.go`**: User session storage
|
||||||
|
- Session persistence
|
||||||
|
- Expiration management
|
||||||
|
- Provider metadata storage
|
||||||
|
|
||||||
|
#### **Authentication Providers** (`internal/auth/`)
|
||||||
|
Pluggable authentication system:
|
||||||
|
|
||||||
|
- **`header_validator.go`**: HMAC signature validation
|
||||||
|
- Timestamp-based replay protection
|
||||||
|
- Constant-time signature comparison
|
||||||
|
- Email format validation
|
||||||
|
|
||||||
|
- **`jwt.go`**: JWT token management
|
||||||
|
- Token generation with secure JTI
|
||||||
|
- Signature validation
|
||||||
|
- Revocation list management
|
||||||
|
|
||||||
|
- **`oauth2.go`**: OAuth2 authorization code flow
|
||||||
|
- State management
|
||||||
|
- Token exchange
|
||||||
|
- Provider integration
|
||||||
|
|
||||||
|
- **`saml.go`**: SAML assertion validation
|
||||||
|
- XML signature validation
|
||||||
|
- Attribute extraction
|
||||||
|
- Provider configuration
|
||||||
|
|
||||||
|
- **`permissions.go`**: Hierarchical permission evaluation
|
||||||
|
- Role-based access control
|
||||||
|
- Permission inheritance
|
||||||
|
- Bulk permission evaluation
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## System Architecture Diagram
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
graph TB
|
||||||
|
%% External Components
|
||||||
|
Client[Client Applications]
|
||||||
|
Browser[Web Browser]
|
||||||
|
AuthProvider[OAuth2/SAML Provider]
|
||||||
|
|
||||||
|
%% Load Balancer & Proxy
|
||||||
|
subgraph "Load Balancer Layer"
|
||||||
|
Nginx[Nginx Proxy<br/>:80, :8081]
|
||||||
|
end
|
||||||
|
|
||||||
|
%% Frontend Layer
|
||||||
|
subgraph "Frontend Layer"
|
||||||
|
React[React TypeScript SPA<br/>Ant Design UI<br/>:3000]
|
||||||
|
AuthContext[Authentication Context]
|
||||||
|
APIService[API Service Client]
|
||||||
|
end
|
||||||
|
|
||||||
|
%% API Gateway & Middleware
|
||||||
|
subgraph "API Layer"
|
||||||
|
API[Go API Server<br/>:8080]
|
||||||
|
|
||||||
|
subgraph "Middleware Chain"
|
||||||
|
Logger[Request Logger]
|
||||||
|
Security[Security Headers<br/>CORS, CSRF]
|
||||||
|
RateLimit[Rate Limiter<br/>100 RPS]
|
||||||
|
Auth[Authentication<br/>Header/JWT/OAuth2/SAML]
|
||||||
|
Validation[Request Validator]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
%% Business Logic Layer
|
||||||
|
subgraph "Service Layer"
|
||||||
|
AuthService[Authentication Service]
|
||||||
|
TokenService[Token Service]
|
||||||
|
AppService[Application Service]
|
||||||
|
SessionService[Session Service]
|
||||||
|
PermService[Permission Service]
|
||||||
|
end
|
||||||
|
|
||||||
|
%% Data Access Layer
|
||||||
|
subgraph "Repository Layer"
|
||||||
|
AppRepo[Application Repository]
|
||||||
|
TokenRepo[Token Repository]
|
||||||
|
PermRepo[Permission Repository]
|
||||||
|
SessionRepo[Session Repository]
|
||||||
|
end
|
||||||
|
|
||||||
|
%% Infrastructure Layer
|
||||||
|
subgraph "Infrastructure"
|
||||||
|
PostgreSQL[(PostgreSQL 15<br/>:5432)]
|
||||||
|
Redis[(Redis Cache<br/>Optional)]
|
||||||
|
Metrics[Prometheus Metrics<br/>:9090]
|
||||||
|
end
|
||||||
|
|
||||||
|
%% External Security
|
||||||
|
subgraph "Security & Crypto"
|
||||||
|
HMAC[HMAC Signature<br/>Validation]
|
||||||
|
BCrypt[BCrypt Hashing<br/>Cost 14]
|
||||||
|
JWT[JWT Token<br/>Generation]
|
||||||
|
end
|
||||||
|
|
||||||
|
%% Flow Connections
|
||||||
|
Client -->|API Requests| Nginx
|
||||||
|
Browser -->|HTTPS| Nginx
|
||||||
|
AuthProvider -->|OAuth2/SAML| API
|
||||||
|
|
||||||
|
Nginx -->|Proxy| React
|
||||||
|
Nginx -->|API Proxy| API
|
||||||
|
|
||||||
|
React --> AuthContext
|
||||||
|
React --> APIService
|
||||||
|
APIService -->|REST API| API
|
||||||
|
|
||||||
|
API --> Logger
|
||||||
|
Logger --> Security
|
||||||
|
Security --> RateLimit
|
||||||
|
RateLimit --> Auth
|
||||||
|
Auth --> Validation
|
||||||
|
Validation --> AuthService
|
||||||
|
Validation --> TokenService
|
||||||
|
Validation --> AppService
|
||||||
|
Validation --> SessionService
|
||||||
|
Validation --> PermService
|
||||||
|
|
||||||
|
AuthService --> AppRepo
|
||||||
|
TokenService --> TokenRepo
|
||||||
|
AppService --> AppRepo
|
||||||
|
SessionService --> SessionRepo
|
||||||
|
PermService --> PermRepo
|
||||||
|
|
||||||
|
AppRepo --> PostgreSQL
|
||||||
|
TokenRepo --> PostgreSQL
|
||||||
|
PermRepo --> PostgreSQL
|
||||||
|
SessionRepo --> PostgreSQL
|
||||||
|
|
||||||
|
TokenService --> HMAC
|
||||||
|
TokenService --> BCrypt
|
||||||
|
TokenService --> JWT
|
||||||
|
AuthService --> Redis
|
||||||
|
|
||||||
|
API --> Metrics
|
||||||
|
|
||||||
|
%% Styling
|
||||||
|
classDef frontend fill:#e1f5fe,stroke:#0277bd,stroke-width:2px
|
||||||
|
classDef api fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
|
||||||
|
classDef service fill:#e8f5e8,stroke:#2e7d32,stroke-width:2px
|
||||||
|
classDef data fill:#fff3e0,stroke:#ef6c00,stroke-width:2px
|
||||||
|
classDef security fill:#ffebee,stroke:#c62828,stroke-width:2px
|
||||||
|
|
||||||
|
class React,AuthContext,APIService frontend
|
||||||
|
class API,Logger,Security,RateLimit,Auth,Validation api
|
||||||
|
class AuthService,TokenService,AppService,SessionService,PermService service
|
||||||
|
class PostgreSQL,Redis,Metrics,AppRepo,TokenRepo,PermRepo,SessionRepo data
|
||||||
|
class HMAC,BCrypt,JWT security
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Request Flow Pipeline
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart TD
|
||||||
|
Start([HTTP Request]) --> Nginx{Nginx Proxy<br/>Load Balancer}
|
||||||
|
|
||||||
|
Nginx -->|Static Assets| Frontend[React SPA<br/>Port 3000]
|
||||||
|
Nginx -->|API Routes| API[Go API Server<br/>Port 8080]
|
||||||
|
|
||||||
|
API --> Logger[Request Logger<br/>Structured Logging]
|
||||||
|
Logger --> Security[Security Middleware<br/>Headers, CORS, CSRF]
|
||||||
|
Security --> RateLimit{Rate Limiter<br/>100 RPS, 200 Burst}
|
||||||
|
|
||||||
|
RateLimit -->|Exceeded| RateResponse[429 Too Many Requests]
|
||||||
|
RateLimit -->|Within Limits| Auth[Authentication<br/>Middleware]
|
||||||
|
|
||||||
|
Auth --> AuthHeader{Auth Provider}
|
||||||
|
AuthHeader -->|header| HeaderAuth[Header Validator<br/>X-User-Email]
|
||||||
|
AuthHeader -->|jwt| JWTAuth[JWT Validator<br/>Signature + Claims]
|
||||||
|
AuthHeader -->|oauth2| OAuth2Auth[OAuth2 Flow<br/>Authorization Code]
|
||||||
|
AuthHeader -->|saml| SAMLAuth[SAML Assertion<br/>XML Validation]
|
||||||
|
|
||||||
|
HeaderAuth --> AuthCache{Check Cache<br/>Redis 5min TTL}
|
||||||
|
JWTAuth --> JWTValidation[Signature Validation<br/>Expiry Check]
|
||||||
|
OAuth2Auth --> OAuth2Exchange[Token Exchange<br/>User Info Retrieval]
|
||||||
|
SAMLAuth --> SAMLValidation[Assertion Validation<br/>Signature Check]
|
||||||
|
|
||||||
|
AuthCache -->|Hit| AuthContext[Create AuthContext]
|
||||||
|
AuthCache -->|Miss| DBAuth[Database Lookup<br/>User Permissions]
|
||||||
|
JWTValidation --> RevocationCheck[Check Revocation List<br/>Redis Cache]
|
||||||
|
OAuth2Exchange --> SessionStore[Store User Session<br/>PostgreSQL]
|
||||||
|
SAMLValidation --> SessionStore
|
||||||
|
|
||||||
|
DBAuth --> CacheStore[Store in Cache<br/>5min TTL]
|
||||||
|
RevocationCheck --> AuthContext
|
||||||
|
SessionStore --> AuthContext
|
||||||
|
CacheStore --> AuthContext
|
||||||
|
|
||||||
|
AuthContext --> Validation[Request Validator<br/>JSON Schema]
|
||||||
|
Validation -->|Invalid| ValidationError[400 Bad Request]
|
||||||
|
Validation -->|Valid| Router{Route Handler}
|
||||||
|
|
||||||
|
Router -->|/health| HealthHandler[Health Check<br/>DB + Cache Status]
|
||||||
|
Router -->|/api/applications| AppHandler[Application CRUD<br/>HMAC Key Management]
|
||||||
|
Router -->|/api/tokens| TokenHandler[Token Operations<br/>Create, Verify, Revoke]
|
||||||
|
Router -->|/api/login| AuthHandler[Authentication<br/>Login, Renewal]
|
||||||
|
Router -->|/api/oauth2| OAuth2Handler[OAuth2 Callbacks<br/>State Management]
|
||||||
|
Router -->|/api/saml| SAMLHandler[SAML Callbacks<br/>Assertion Processing]
|
||||||
|
|
||||||
|
HealthHandler --> Service[Service Layer]
|
||||||
|
AppHandler --> Service
|
||||||
|
TokenHandler --> Service
|
||||||
|
AuthHandler --> Service
|
||||||
|
OAuth2Handler --> Service
|
||||||
|
SAMLHandler --> Service
|
||||||
|
|
||||||
|
Service --> Repository[Repository Layer<br/>Database Operations]
|
||||||
|
Repository --> PostgreSQL[(PostgreSQL<br/>ACID Transactions)]
|
||||||
|
|
||||||
|
Service --> CryptoOps[Cryptographic Operations]
|
||||||
|
CryptoOps --> HMAC[HMAC Signature<br/>Timestamp Validation]
|
||||||
|
CryptoOps --> BCrypt[BCrypt Hashing<br/>Cost 14]
|
||||||
|
CryptoOps --> JWT[JWT Generation<br/>RS256 Signing]
|
||||||
|
|
||||||
|
Repository --> AuditLog[Audit Logging<br/>All Operations]
|
||||||
|
AuditLog --> AuditTable[(audit_logs table)]
|
||||||
|
|
||||||
|
Service --> Response[HTTP Response]
|
||||||
|
Response --> Metrics[Prometheus Metrics<br/>Port 9090]
|
||||||
|
Response --> End([Response Sent])
|
||||||
|
|
||||||
|
%% Error Paths
|
||||||
|
RateResponse --> End
|
||||||
|
ValidationError --> End
|
||||||
|
|
||||||
|
%% Styling
|
||||||
|
classDef middleware fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
|
||||||
|
classDef auth fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
|
||||||
|
classDef handler fill:#e8f5e8,stroke:#2e7d32,stroke-width:2px
|
||||||
|
classDef data fill:#fff3e0,stroke:#ef6c00,stroke-width:2px
|
||||||
|
classDef crypto fill:#ffebee,stroke:#c62828,stroke-width:2px
|
||||||
|
classDef error fill:#fce4ec,stroke:#ad1457,stroke-width:2px
|
||||||
|
|
||||||
|
class Logger,Security,RateLimit,Validation middleware
|
||||||
|
class Auth,HeaderAuth,JWTAuth,OAuth2Auth,SAMLAuth,AuthContext auth
|
||||||
|
class HealthHandler,AppHandler,TokenHandler,AuthHandler,OAuth2Handler,SAMLHandler,Service handler
|
||||||
|
class Repository,PostgreSQL,AuditTable,AuthCache data
|
||||||
|
class CryptoOps,HMAC,BCrypt,JWT crypto
|
||||||
|
class RateResponse,ValidationError error
|
||||||
|
```
|
||||||
|
|
||||||
|
### Request Processing Pipeline
|
||||||
|
|
||||||
|
1. **Load Balancer**: Nginx receives and routes requests
|
||||||
|
2. **Static Assets**: React SPA served directly by Nginx
|
||||||
|
3. **API Gateway**: Go server handles API requests
|
||||||
|
4. **Middleware Chain**: Security, rate limiting, authentication
|
||||||
|
5. **Route Handler**: Business logic processing
|
||||||
|
6. **Service Layer**: Transaction management and orchestration
|
||||||
|
7. **Repository Layer**: Database operations with audit logging
|
||||||
|
8. **Response**: JSON response with metrics collection
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Authentication Flow
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
sequenceDiagram
|
||||||
|
participant Client as Client App
|
||||||
|
participant API as API Gateway
|
||||||
|
participant Auth as Auth Service
|
||||||
|
participant DB as PostgreSQL
|
||||||
|
participant Provider as OAuth2/SAML
|
||||||
|
participant Cache as Redis Cache
|
||||||
|
|
||||||
|
%% Header-based Authentication
|
||||||
|
rect rgb(240, 248, 255)
|
||||||
|
Note over Client, Cache: Header-based Authentication Flow
|
||||||
|
Client->>API: Request with X-User-Email header
|
||||||
|
API->>Auth: Validate header auth
|
||||||
|
Auth->>DB: Check user permissions
|
||||||
|
DB-->>Auth: Return user context
|
||||||
|
Auth->>Cache: Cache auth result (5min TTL)
|
||||||
|
Auth-->>API: AuthContext{UserID, Permissions}
|
||||||
|
API-->>Client: Authenticated response
|
||||||
|
end
|
||||||
|
|
||||||
|
%% JWT Authentication Flow
|
||||||
|
rect rgb(245, 255, 245)
|
||||||
|
Note over Client, Cache: JWT Authentication Flow
|
||||||
|
Client->>API: Login request {app_id, permissions}
|
||||||
|
API->>Auth: Generate JWT token
|
||||||
|
Auth->>DB: Validate app_id and permissions
|
||||||
|
DB-->>Auth: Application config
|
||||||
|
Auth->>Auth: Create JWT with claims<br/>{user_id, permissions, exp, iat}
|
||||||
|
Auth-->>API: JWT token + expires_at
|
||||||
|
API-->>Client: LoginResponse{token, expires_at}
|
||||||
|
|
||||||
|
Note over Client, API: Subsequent requests with JWT
|
||||||
|
Client->>API: Request with Bearer JWT
|
||||||
|
API->>Auth: Verify JWT signature
|
||||||
|
Auth->>Auth: Check expiration & claims
|
||||||
|
Auth->>Cache: Check revocation list
|
||||||
|
Cache-->>Auth: Token status
|
||||||
|
Auth-->>API: Valid AuthContext
|
||||||
|
API-->>Client: Authorized response
|
||||||
|
end
|
||||||
|
|
||||||
|
%% OAuth2/SAML Flow
|
||||||
|
rect rgb(255, 248, 240)
|
||||||
|
Note over Client, Provider: OAuth2/SAML Authentication Flow
|
||||||
|
Client->>API: POST /api/login {app_id, redirect_uri}
|
||||||
|
API->>Auth: Generate OAuth2 state
|
||||||
|
Auth->>DB: Store state + app context
|
||||||
|
Auth-->>API: Redirect URL + state
|
||||||
|
API-->>Client: {redirect_url, state}
|
||||||
|
|
||||||
|
Client->>Provider: Redirect to OAuth2 provider
|
||||||
|
Provider-->>Client: Authorization code + state
|
||||||
|
|
||||||
|
Client->>API: GET /api/oauth2/callback?code=xxx&state=yyy
|
||||||
|
API->>Auth: Validate state and exchange code
|
||||||
|
Auth->>Provider: Exchange code for tokens
|
||||||
|
Provider-->>Auth: Access token + ID token
|
||||||
|
Auth->>Provider: Get user info
|
||||||
|
Provider-->>Auth: User profile
|
||||||
|
Auth->>DB: Create/update user session
|
||||||
|
Auth->>Auth: Generate internal JWT
|
||||||
|
Auth-->>API: JWT token + user context
|
||||||
|
API-->>Client: Set-Cookie with JWT + redirect
|
||||||
|
end
|
||||||
|
|
||||||
|
%% Token Renewal Flow
|
||||||
|
rect rgb(248, 245, 255)
|
||||||
|
Note over Client, DB: Token Renewal Flow
|
||||||
|
Client->>API: POST /api/renew {app_id, user_id, token}
|
||||||
|
API->>Auth: Validate current token
|
||||||
|
Auth->>Auth: Check token expiration<br/>and max_valid_at
|
||||||
|
Auth->>DB: Get application config
|
||||||
|
DB-->>Auth: TokenRenewalDuration, MaxTokenDuration
|
||||||
|
Auth->>Auth: Generate new JWT<br/>with extended expiry
|
||||||
|
Auth->>Cache: Invalidate old token
|
||||||
|
Auth-->>API: New token + expires_at
|
||||||
|
API-->>Client: RenewResponse{token, expires_at}
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
### Authentication Methods
|
||||||
|
|
||||||
|
#### **Header-based Authentication**
|
||||||
|
- **Use Case**: Service-to-service authentication
|
||||||
|
- **Security**: HMAC-SHA256 signatures with timestamp validation
|
||||||
|
- **Replay Protection**: 5-minute timestamp window
|
||||||
|
- **Caching**: 5-minute Redis cache for performance
|
||||||
|
|
||||||
|
#### **JWT Authentication**
|
||||||
|
- **Use Case**: User authentication with session management
|
||||||
|
- **Security**: RSA signatures with revocation checking
|
||||||
|
- **Token Lifecycle**: Configurable expiration with renewal
|
||||||
|
- **Claims**: User ID, permissions, application scope
|
||||||
|
|
||||||
|
#### **OAuth2/SAML Authentication**
|
||||||
|
- **Use Case**: External identity provider integration
|
||||||
|
- **Security**: Authorization code flow with state validation
|
||||||
|
- **Session Management**: Database-backed session storage
|
||||||
|
- **Provider Support**: Configurable provider endpoints
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## API Design
|
||||||
|
|
||||||
|
### RESTful Endpoints
|
||||||
|
|
||||||
|
#### **Authentication Endpoints**
|
||||||
|
```
|
||||||
|
POST /api/login - Authenticate user, issue JWT
|
||||||
|
POST /api/renew - Renew JWT token
|
||||||
|
POST /api/logout - Revoke JWT token
|
||||||
|
GET /api/verify - Verify token and permissions
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **Application Management**
|
||||||
|
```
|
||||||
|
GET /api/applications - List applications (paginated)
|
||||||
|
POST /api/applications - Create application
|
||||||
|
GET /api/applications/:id - Get application details
|
||||||
|
PUT /api/applications/:id - Update application
|
||||||
|
DELETE /api/applications/:id - Delete application
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **Token Management**
|
||||||
|
```
|
||||||
|
GET /api/applications/:id/tokens - List application tokens
|
||||||
|
POST /api/applications/:id/tokens - Create new token
|
||||||
|
DELETE /api/tokens/:id - Revoke token
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **OAuth2/SAML Integration**
|
||||||
|
```
|
||||||
|
POST /api/oauth2/login - Initiate OAuth2 flow
|
||||||
|
GET /api/oauth2/callback - OAuth2 callback handler
|
||||||
|
POST /api/saml/login - Initiate SAML flow
|
||||||
|
POST /api/saml/callback - SAML assertion handler
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **System Endpoints**
|
||||||
|
```
|
||||||
|
GET /health - System health check
|
||||||
|
GET /ready - Readiness probe
|
||||||
|
GET /metrics - Prometheus metrics
|
||||||
|
```
|
||||||
|
|
||||||
|
### Request/Response Patterns
|
||||||
|
|
||||||
|
#### **Authentication Headers**
|
||||||
|
```http
|
||||||
|
X-User-Email: user@example.com
|
||||||
|
X-Auth-Timestamp: 2024-01-15T10:30:00Z
|
||||||
|
X-Auth-Signature: sha256=abc123...
|
||||||
|
Authorization: Bearer eyJhbGciOiJSUzI1NiIs...
|
||||||
|
Content-Type: application/json
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **Error Response Format**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"error": "validation_failed",
|
||||||
|
"message": "Request validation failed",
|
||||||
|
"details": [
|
||||||
|
{
|
||||||
|
"field": "permissions",
|
||||||
|
"message": "Invalid permission format",
|
||||||
|
"value": "invalid.perm"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **Success Response Format**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"id": "550e8400-e29b-41d4-a716-446655440000",
|
||||||
|
"token": "ABC123_xyz789...",
|
||||||
|
"permissions": ["app.read", "token.create"],
|
||||||
|
"created_at": "2024-01-15T10:30:00Z"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Technology Stack
|
||||||
|
|
||||||
|
### Backend Technologies
|
||||||
|
- **Language**: Go 1.21+ with modules
|
||||||
|
- **Web Framework**: Gin HTTP framework
|
||||||
|
- **Database**: PostgreSQL 15 with connection pooling
|
||||||
|
- **Authentication**: JWT-Go library with RSA signing
|
||||||
|
- **Cryptography**: Go standard crypto libraries
|
||||||
|
- **Caching**: Redis for session and revocation storage
|
||||||
|
- **Logging**: Zap structured logging
|
||||||
|
- **Metrics**: Prometheus metrics collection
|
||||||
|
|
||||||
|
### Frontend Technologies
|
||||||
|
- **Framework**: React 18 with TypeScript
|
||||||
|
- **UI Library**: Ant Design components
|
||||||
|
- **State Management**: React Context API
|
||||||
|
- **HTTP Client**: Axios with interceptors
|
||||||
|
- **Routing**: React Router with protected routes
|
||||||
|
- **Build Tool**: Create React App with TypeScript
|
||||||
|
|
||||||
|
### Infrastructure
|
||||||
|
- **Containerization**: Docker with multi-stage builds
|
||||||
|
- **Orchestration**: Docker Compose for local development
|
||||||
|
- **Reverse Proxy**: Nginx with load balancing
|
||||||
|
- **Database Migrations**: Custom Go migration system
|
||||||
|
- **Health Monitoring**: Built-in health check endpoints
|
||||||
|
|
||||||
|
### Security Stack
|
||||||
|
- **TLS**: TLS 1.3 for all communications
|
||||||
|
- **Hashing**: BCrypt with cost 14 for production
|
||||||
|
- **Signatures**: HMAC-SHA256 and RSA signatures
|
||||||
|
- **Rate Limiting**: Token bucket algorithm
|
||||||
|
- **CSRF**: Double-submit cookie pattern
|
||||||
|
- **Headers**: Comprehensive security headers
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Deployment Considerations
|
||||||
|
|
||||||
|
### Container Configuration
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
kms-api:
|
||||||
|
image: kms-api:latest
|
||||||
|
ports:
|
||||||
|
- "8080:8080"
|
||||||
|
environment:
|
||||||
|
- DB_HOST=postgres
|
||||||
|
- DB_PORT=5432
|
||||||
|
- JWT_SECRET=${JWT_SECRET}
|
||||||
|
- HMAC_KEY=${HMAC_KEY}
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
```
|
||||||
|
|
||||||
|
### Environment Variables
|
||||||
|
```bash
|
||||||
|
# Database Configuration
|
||||||
|
DB_HOST=localhost
|
||||||
|
DB_PORT=5432
|
||||||
|
DB_NAME=kms
|
||||||
|
DB_USER=postgres
|
||||||
|
DB_PASSWORD=postgres
|
||||||
|
|
||||||
|
# Server Configuration
|
||||||
|
SERVER_HOST=0.0.0.0
|
||||||
|
SERVER_PORT=8080
|
||||||
|
|
||||||
|
# Authentication
|
||||||
|
AUTH_PROVIDER=header
|
||||||
|
JWT_SECRET=your-jwt-secret
|
||||||
|
HMAC_KEY=your-hmac-key
|
||||||
|
|
||||||
|
# Security
|
||||||
|
RATE_LIMIT_ENABLED=true
|
||||||
|
RATE_LIMIT_RPS=100
|
||||||
|
RATE_LIMIT_BURST=200
|
||||||
|
```
|
||||||
|
|
||||||
|
### Monitoring Setup
|
||||||
|
```yaml
|
||||||
|
prometheus:
|
||||||
|
scrape_configs:
|
||||||
|
- job_name: 'kms-api'
|
||||||
|
static_configs:
|
||||||
|
- targets: ['kms-api:9090']
|
||||||
|
scrape_interval: 15s
|
||||||
|
metrics_path: /metrics
|
||||||
|
```
|
||||||
|
|
||||||
|
This architecture documentation provides a comprehensive technical overview of the KMS system, suitable for development teams, system architects, and operations personnel who need to understand, deploy, or maintain the system.
|
||||||
852
docs/DATABASE_SCHEMA.md
Normal file
852
docs/DATABASE_SCHEMA.md
Normal file
@ -0,0 +1,852 @@
|
|||||||
|
# KMS Database Schema Documentation
|
||||||
|
|
||||||
|
## Table of Contents
|
||||||
|
1. [Schema Overview](#schema-overview)
|
||||||
|
2. [Entity Relationship Diagram](#entity-relationship-diagram)
|
||||||
|
3. [Table Definitions](#table-definitions)
|
||||||
|
4. [Relationships and Constraints](#relationships-and-constraints)
|
||||||
|
5. [Indexes and Performance](#indexes-and-performance)
|
||||||
|
6. [Security Considerations](#security-considerations)
|
||||||
|
7. [Migration Strategy](#migration-strategy)
|
||||||
|
8. [Query Patterns](#query-patterns)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Schema Overview
|
||||||
|
|
||||||
|
The KMS database schema is designed around core entities that manage applications, tokens, permissions, and user sessions. The schema follows PostgreSQL best practices with proper normalization, constraints, and indexing strategies.
|
||||||
|
|
||||||
|
### Core Entities
|
||||||
|
- **Applications**: Central configuration for API key management
|
||||||
|
- **Static Tokens**: Long-lived API tokens with HMAC signatures
|
||||||
|
- **User Sessions**: JWT token tracking with metadata
|
||||||
|
- **Available Permissions**: Hierarchical permission catalog
|
||||||
|
- **Granted Permissions**: Token-permission relationships
|
||||||
|
- **Audit Logs**: Complete audit trail of all operations
|
||||||
|
|
||||||
|
### Design Principles
|
||||||
|
- **Normalized Design**: Reduces data redundancy
|
||||||
|
- **Referential Integrity**: Foreign key constraints ensure consistency
|
||||||
|
- **Audit Trail**: Complete history of all operations
|
||||||
|
- **Performance Optimized**: Strategic indexing for common queries
|
||||||
|
- **Security First**: Sensitive data protection and access controls
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Entity Relationship Diagram
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
erDiagram
|
||||||
|
%% Core Application Entity
|
||||||
|
applications {
|
||||||
|
string app_id PK "Application identifier"
|
||||||
|
string app_link "Application URL"
|
||||||
|
text[] type "static|user application types"
|
||||||
|
string callback_url "OAuth2 callback URL"
|
||||||
|
string hmac_key "HMAC signing key"
|
||||||
|
string token_prefix "Custom token prefix"
|
||||||
|
bigint token_renewal_duration "Token renewal window (ns)"
|
||||||
|
bigint max_token_duration "Max token lifetime (ns)"
|
||||||
|
string owner_type "individual|team"
|
||||||
|
string owner_name "Owner display name"
|
||||||
|
string owner_owner "Owner identifier"
|
||||||
|
timestamp created_at
|
||||||
|
timestamp updated_at
|
||||||
|
}
|
||||||
|
|
||||||
|
%% Static Token Management
|
||||||
|
static_tokens {
|
||||||
|
uuid id PK
|
||||||
|
string app_id FK "References applications.app_id"
|
||||||
|
string owner_type "individual|team"
|
||||||
|
string owner_name "Token owner name"
|
||||||
|
string owner_owner "Token owner identifier"
|
||||||
|
string key_hash "BCrypt hashed token (cost 14)"
|
||||||
|
string type "Always 'hmac'"
|
||||||
|
timestamp created_at
|
||||||
|
timestamp updated_at
|
||||||
|
}
|
||||||
|
|
||||||
|
%% User Session Tracking
|
||||||
|
user_sessions {
|
||||||
|
uuid id PK
|
||||||
|
string user_id "User identifier"
|
||||||
|
string app_id FK "References applications.app_id"
|
||||||
|
string session_token "Hashed session identifier"
|
||||||
|
text permissions "JSON array of permissions"
|
||||||
|
timestamp expires_at "Session expiration"
|
||||||
|
timestamp max_valid_at "Maximum validity window"
|
||||||
|
string provider "header|jwt|oauth2|saml"
|
||||||
|
json metadata "Provider-specific data"
|
||||||
|
boolean active "Session status"
|
||||||
|
timestamp created_at
|
||||||
|
timestamp updated_at
|
||||||
|
timestamp last_used_at
|
||||||
|
}
|
||||||
|
|
||||||
|
%% Permission Catalog
|
||||||
|
available_permissions {
|
||||||
|
uuid id PK
|
||||||
|
string scope UK "Unique permission scope"
|
||||||
|
string name "Human-readable name"
|
||||||
|
text description "Permission description"
|
||||||
|
string category "Permission category"
|
||||||
|
string parent_scope FK "References available_permissions.scope"
|
||||||
|
boolean is_system "System permission flag"
|
||||||
|
timestamp created_at
|
||||||
|
string created_by "Creator identifier"
|
||||||
|
timestamp updated_at
|
||||||
|
string updated_by "Last updater"
|
||||||
|
}
|
||||||
|
|
||||||
|
%% Token-Permission Relationships
|
||||||
|
granted_permissions {
|
||||||
|
uuid id PK
|
||||||
|
string token_type "static|user"
|
||||||
|
uuid token_id FK "References static_tokens.id"
|
||||||
|
uuid permission_id FK "References available_permissions.id"
|
||||||
|
string scope "Denormalized permission scope"
|
||||||
|
timestamp created_at
|
||||||
|
string created_by "Grant creator"
|
||||||
|
boolean revoked "Permission revocation status"
|
||||||
|
timestamp revoked_at "Revocation timestamp"
|
||||||
|
string revoked_by "Revoker identifier"
|
||||||
|
}
|
||||||
|
|
||||||
|
%% Audit Trail
|
||||||
|
audit_logs {
|
||||||
|
uuid id PK
|
||||||
|
timestamp timestamp "Event timestamp"
|
||||||
|
string user_id "Acting user"
|
||||||
|
string action "Action performed"
|
||||||
|
string resource_type "Resource type affected"
|
||||||
|
string resource_id "Resource identifier"
|
||||||
|
json old_values "Previous values"
|
||||||
|
json new_values "New values"
|
||||||
|
string ip_address "Client IP"
|
||||||
|
string user_agent "Client user agent"
|
||||||
|
json metadata "Additional context"
|
||||||
|
}
|
||||||
|
|
||||||
|
%% Relationships
|
||||||
|
applications ||--o{ static_tokens : "app_id"
|
||||||
|
applications ||--o{ user_sessions : "app_id"
|
||||||
|
available_permissions ||--o{ available_permissions : "parent_scope"
|
||||||
|
available_permissions ||--o{ granted_permissions : "permission_id"
|
||||||
|
static_tokens ||--o{ granted_permissions : "token_id"
|
||||||
|
|
||||||
|
%% Indexes and Constraints
|
||||||
|
applications {
|
||||||
|
index idx_applications_owner_type "owner_type"
|
||||||
|
index idx_applications_created_at "created_at"
|
||||||
|
check owner_type_valid "owner_type IN ('individual', 'team')"
|
||||||
|
check type_not_empty "array_length(type, 1) > 0"
|
||||||
|
}
|
||||||
|
|
||||||
|
static_tokens {
|
||||||
|
index idx_static_tokens_app_id "app_id"
|
||||||
|
index idx_static_tokens_key_hash "key_hash"
|
||||||
|
unique key_hash_unique "key_hash"
|
||||||
|
check type_hmac "type = 'hmac'"
|
||||||
|
}
|
||||||
|
|
||||||
|
user_sessions {
|
||||||
|
index idx_user_sessions_user_id "user_id"
|
||||||
|
index idx_user_sessions_app_id "app_id"
|
||||||
|
index idx_user_sessions_token "session_token"
|
||||||
|
index idx_user_sessions_expires_at "expires_at"
|
||||||
|
index idx_user_sessions_active "active"
|
||||||
|
}
|
||||||
|
|
||||||
|
available_permissions {
|
||||||
|
index idx_available_permissions_scope "scope"
|
||||||
|
index idx_available_permissions_category "category"
|
||||||
|
index idx_available_permissions_parent_scope "parent_scope"
|
||||||
|
index idx_available_permissions_is_system "is_system"
|
||||||
|
}
|
||||||
|
|
||||||
|
granted_permissions {
|
||||||
|
index idx_granted_permissions_token "token_type, token_id"
|
||||||
|
index idx_granted_permissions_permission_id "permission_id"
|
||||||
|
index idx_granted_permissions_scope "scope"
|
||||||
|
index idx_granted_permissions_revoked "revoked"
|
||||||
|
unique token_permission_unique "token_type, token_id, permission_id"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Table Definitions
|
||||||
|
|
||||||
|
### Applications Table
|
||||||
|
|
||||||
|
The central configuration table for all applications in the system.
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE applications (
|
||||||
|
app_id VARCHAR(100) PRIMARY KEY,
|
||||||
|
app_link TEXT NOT NULL,
|
||||||
|
type TEXT[] NOT NULL DEFAULT '{}',
|
||||||
|
callback_url TEXT,
|
||||||
|
hmac_key TEXT NOT NULL,
|
||||||
|
token_prefix VARCHAR(10),
|
||||||
|
token_renewal_duration BIGINT NOT NULL DEFAULT 3600000000000, -- 1 hour in nanoseconds
|
||||||
|
max_token_duration BIGINT NOT NULL DEFAULT 86400000000000, -- 24 hours in nanoseconds
|
||||||
|
owner_type VARCHAR(20) NOT NULL CHECK (owner_type IN ('individual', 'team')),
|
||||||
|
owner_name VARCHAR(255) NOT NULL,
|
||||||
|
owner_owner VARCHAR(255) NOT NULL,
|
||||||
|
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
||||||
|
|
||||||
|
-- Constraints
|
||||||
|
CONSTRAINT app_id_format CHECK (app_id ~ '^[a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9]$'),
|
||||||
|
CONSTRAINT type_not_empty CHECK (array_length(type, 1) > 0),
|
||||||
|
CONSTRAINT token_prefix_format CHECK (token_prefix IS NULL OR token_prefix ~ '^[A-Z]{2,4}$'),
|
||||||
|
CONSTRAINT valid_durations CHECK (
|
||||||
|
token_renewal_duration > 0 AND
|
||||||
|
max_token_duration > 0 AND
|
||||||
|
max_token_duration > token_renewal_duration
|
||||||
|
)
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Field Descriptions
|
||||||
|
- **`app_id`**: Unique application identifier, must follow naming conventions
|
||||||
|
- **`app_link`**: URL to the application for reference
|
||||||
|
- **`type`**: Array of supported token types (`static`, `user`)
|
||||||
|
- **`callback_url`**: OAuth2/SAML callback URL for authentication flows
|
||||||
|
- **`hmac_key`**: HMAC signing key for static token validation
|
||||||
|
- **`token_prefix`**: Custom prefix for generated tokens (2-4 uppercase letters)
|
||||||
|
- **`token_renewal_duration`**: How long tokens can be renewed (nanoseconds)
|
||||||
|
- **`max_token_duration`**: Maximum token lifetime (nanoseconds)
|
||||||
|
- **`owner_type`**: Individual or team ownership
|
||||||
|
- **`owner_name`**: Display name of the owner
|
||||||
|
- **`owner_owner`**: Identifier of the owner (email for individual, team ID for team)
|
||||||
|
|
||||||
|
### Static Tokens Table
|
||||||
|
|
||||||
|
Long-lived API tokens with HMAC-based authentication.
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE static_tokens (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
app_id VARCHAR(100) NOT NULL REFERENCES applications(app_id) ON DELETE CASCADE,
|
||||||
|
owner_type VARCHAR(20) NOT NULL CHECK (owner_type IN ('individual', 'team')),
|
||||||
|
owner_name VARCHAR(255) NOT NULL,
|
||||||
|
owner_owner VARCHAR(255) NOT NULL,
|
||||||
|
key_hash TEXT NOT NULL UNIQUE,
|
||||||
|
type VARCHAR(10) NOT NULL DEFAULT 'hmac' CHECK (type = 'hmac'),
|
||||||
|
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Security Features
|
||||||
|
- **`key_hash`**: BCrypt hash of the actual token (cost 14)
|
||||||
|
- **Unique constraint**: Prevents token duplication
|
||||||
|
- **Cascade deletion**: Tokens deleted when application is removed
|
||||||
|
- **Owner tracking**: Links tokens to their creators
|
||||||
|
|
||||||
|
### User Sessions Table
|
||||||
|
|
||||||
|
JWT token session tracking with comprehensive metadata.
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE user_sessions (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
user_id VARCHAR(255) NOT NULL,
|
||||||
|
app_id VARCHAR(100) NOT NULL REFERENCES applications(app_id) ON DELETE CASCADE,
|
||||||
|
session_token VARCHAR(255) NOT NULL,
|
||||||
|
permissions TEXT NOT NULL DEFAULT '[]', -- JSON array
|
||||||
|
expires_at TIMESTAMP WITH TIME ZONE NOT NULL,
|
||||||
|
max_valid_at TIMESTAMP WITH TIME ZONE NOT NULL,
|
||||||
|
provider VARCHAR(20) NOT NULL CHECK (provider IN ('header', 'jwt', 'oauth2', 'saml')),
|
||||||
|
metadata JSONB DEFAULT '{}',
|
||||||
|
active BOOLEAN NOT NULL DEFAULT true,
|
||||||
|
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
||||||
|
last_used_at TIMESTAMP WITH TIME ZONE,
|
||||||
|
|
||||||
|
-- Constraints
|
||||||
|
CONSTRAINT valid_session_times CHECK (max_valid_at >= expires_at),
|
||||||
|
CONSTRAINT valid_permissions CHECK (permissions::json IS NOT NULL)
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Session Management Features
|
||||||
|
- **Session tracking**: Complete session lifecycle management
|
||||||
|
- **Multi-provider support**: Tracks authentication method
|
||||||
|
- **Permission storage**: JSON array of granted permissions
|
||||||
|
- **Activity tracking**: Last used timestamp for session cleanup
|
||||||
|
- **Flexible metadata**: Provider-specific data storage
|
||||||
|
|
||||||
|
### Available Permissions Table
|
||||||
|
|
||||||
|
Hierarchical permission catalog with system and custom permissions.
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE available_permissions (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
scope VARCHAR(255) NOT NULL UNIQUE,
|
||||||
|
name VARCHAR(255) NOT NULL,
|
||||||
|
description TEXT,
|
||||||
|
category VARCHAR(100) NOT NULL DEFAULT 'custom',
|
||||||
|
parent_scope VARCHAR(255) REFERENCES available_permissions(scope) ON DELETE SET NULL,
|
||||||
|
is_system BOOLEAN NOT NULL DEFAULT false,
|
||||||
|
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
||||||
|
created_by VARCHAR(255) NOT NULL,
|
||||||
|
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
||||||
|
updated_by VARCHAR(255) NOT NULL,
|
||||||
|
|
||||||
|
-- Constraints
|
||||||
|
CONSTRAINT scope_format CHECK (scope ~ '^[a-zA-Z][a-zA-Z0-9._]*[a-zA-Z0-9]$'),
|
||||||
|
CONSTRAINT no_self_reference CHECK (scope != parent_scope)
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Permission Hierarchy Features
|
||||||
|
- **Hierarchical structure**: Parent-child permission relationships
|
||||||
|
- **System permissions**: Built-in permissions that cannot be deleted
|
||||||
|
- **Flexible scoping**: Dot-notation permission scopes
|
||||||
|
- **Audit tracking**: Creation and modification history
|
||||||
|
|
||||||
|
### Granted Permissions Table
|
||||||
|
|
||||||
|
Token-permission relationship management with revocation support.
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE granted_permissions (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
token_type VARCHAR(10) NOT NULL CHECK (token_type IN ('static', 'user')),
|
||||||
|
token_id UUID NOT NULL,
|
||||||
|
permission_id UUID NOT NULL REFERENCES available_permissions(id) ON DELETE CASCADE,
|
||||||
|
scope VARCHAR(255) NOT NULL, -- Denormalized for performance
|
||||||
|
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
||||||
|
created_by VARCHAR(255) NOT NULL,
|
||||||
|
revoked BOOLEAN NOT NULL DEFAULT false,
|
||||||
|
revoked_at TIMESTAMP WITH TIME ZONE,
|
||||||
|
revoked_by VARCHAR(255),
|
||||||
|
|
||||||
|
-- Constraints
|
||||||
|
CONSTRAINT unique_token_permission UNIQUE (token_type, token_id, permission_id),
|
||||||
|
CONSTRAINT valid_revocation CHECK (
|
||||||
|
(revoked = false AND revoked_at IS NULL AND revoked_by IS NULL) OR
|
||||||
|
(revoked = true AND revoked_at IS NOT NULL AND revoked_by IS NOT NULL)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Permission Grant Features
|
||||||
|
- **Multi-token support**: Works with both static and user tokens
|
||||||
|
- **Denormalized scope**: Performance optimization for common queries
|
||||||
|
- **Revocation tracking**: Complete audit trail of permission changes
|
||||||
|
- **Referential integrity**: Maintains consistency with permission catalog
|
||||||
|
|
||||||
|
### Audit Logs Table
|
||||||
|
|
||||||
|
Complete audit trail of all system operations.
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE audit_logs (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
timestamp TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
||||||
|
user_id VARCHAR(255) NOT NULL,
|
||||||
|
action VARCHAR(100) NOT NULL,
|
||||||
|
resource_type VARCHAR(50) NOT NULL,
|
||||||
|
resource_id VARCHAR(255),
|
||||||
|
old_values JSONB,
|
||||||
|
new_values JSONB,
|
||||||
|
ip_address INET,
|
||||||
|
user_agent TEXT,
|
||||||
|
metadata JSONB DEFAULT '{}',
|
||||||
|
|
||||||
|
-- Constraints
|
||||||
|
CONSTRAINT valid_action CHECK (action ~ '^[a-z][a-z_]*[a-z]$'),
|
||||||
|
CONSTRAINT valid_resource_type CHECK (resource_type ~ '^[a-z][a-z_]*[a-z]$')
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Audit Features
|
||||||
|
- **Complete coverage**: All operations logged
|
||||||
|
- **Before/after values**: Full change tracking
|
||||||
|
- **Client context**: IP address and user agent
|
||||||
|
- **Flexible metadata**: Additional context storage
|
||||||
|
- **Time-series data**: Ordered by timestamp for analysis
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Relationships and Constraints
|
||||||
|
|
||||||
|
### Primary Relationships
|
||||||
|
|
||||||
|
#### **Application → Static Tokens (1:N)**
|
||||||
|
```sql
|
||||||
|
ALTER TABLE static_tokens
|
||||||
|
ADD CONSTRAINT fk_static_tokens_app_id
|
||||||
|
FOREIGN KEY (app_id) REFERENCES applications(app_id) ON DELETE CASCADE;
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **Application → User Sessions (1:N)**
|
||||||
|
```sql
|
||||||
|
ALTER TABLE user_sessions
|
||||||
|
ADD CONSTRAINT fk_user_sessions_app_id
|
||||||
|
FOREIGN KEY (app_id) REFERENCES applications(app_id) ON DELETE CASCADE;
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **Available Permissions → Self (Hierarchy)**
|
||||||
|
```sql
|
||||||
|
ALTER TABLE available_permissions
|
||||||
|
ADD CONSTRAINT fk_available_permissions_parent
|
||||||
|
FOREIGN KEY (parent_scope) REFERENCES available_permissions(scope) ON DELETE SET NULL;
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **Granted Permissions → Available Permissions (N:1)**
|
||||||
|
```sql
|
||||||
|
ALTER TABLE granted_permissions
|
||||||
|
ADD CONSTRAINT fk_granted_permissions_permission
|
||||||
|
FOREIGN KEY (permission_id) REFERENCES available_permissions(id) ON DELETE CASCADE;
|
||||||
|
```
|
||||||
|
|
||||||
|
### Data Integrity Constraints
|
||||||
|
|
||||||
|
#### **Check Constraints**
|
||||||
|
```sql
|
||||||
|
-- Application ID format validation
|
||||||
|
ALTER TABLE applications
|
||||||
|
ADD CONSTRAINT app_id_format
|
||||||
|
CHECK (app_id ~ '^[a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9]$');
|
||||||
|
|
||||||
|
-- Owner type validation
|
||||||
|
ALTER TABLE applications
|
||||||
|
ADD CONSTRAINT owner_type_valid
|
||||||
|
CHECK (owner_type IN ('individual', 'team'));
|
||||||
|
|
||||||
|
-- Token type validation
|
||||||
|
ALTER TABLE static_tokens
|
||||||
|
ADD CONSTRAINT type_hmac
|
||||||
|
CHECK (type = 'hmac');
|
||||||
|
|
||||||
|
-- Permission scope format
|
||||||
|
ALTER TABLE available_permissions
|
||||||
|
ADD CONSTRAINT scope_format
|
||||||
|
CHECK (scope ~ '^[a-zA-Z][a-zA-Z0-9._]*[a-zA-Z0-9]$');
|
||||||
|
|
||||||
|
-- Session time validation
|
||||||
|
ALTER TABLE user_sessions
|
||||||
|
ADD CONSTRAINT valid_session_times
|
||||||
|
CHECK (max_valid_at >= expires_at);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **Unique Constraints**
|
||||||
|
```sql
|
||||||
|
-- Unique token hashes
|
||||||
|
ALTER TABLE static_tokens
|
||||||
|
ADD CONSTRAINT key_hash_unique UNIQUE (key_hash);
|
||||||
|
|
||||||
|
-- Unique permission scopes
|
||||||
|
ALTER TABLE available_permissions
|
||||||
|
ADD CONSTRAINT scope_unique UNIQUE (scope);
|
||||||
|
|
||||||
|
-- Unique token-permission relationships
|
||||||
|
ALTER TABLE granted_permissions
|
||||||
|
ADD CONSTRAINT unique_token_permission
|
||||||
|
UNIQUE (token_type, token_id, permission_id);
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Indexes and Performance
|
||||||
|
|
||||||
|
### Primary Indexes
|
||||||
|
|
||||||
|
#### **Applications Table**
|
||||||
|
```sql
|
||||||
|
-- Primary key index (automatic)
|
||||||
|
CREATE INDEX idx_applications_owner_type ON applications(owner_type);
|
||||||
|
CREATE INDEX idx_applications_created_at ON applications(created_at);
|
||||||
|
CREATE INDEX idx_applications_owner_owner ON applications(owner_owner);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **Static Tokens Table**
|
||||||
|
```sql
|
||||||
|
-- Foreign key and lookup indexes
|
||||||
|
CREATE INDEX idx_static_tokens_app_id ON static_tokens(app_id);
|
||||||
|
CREATE INDEX idx_static_tokens_key_hash ON static_tokens(key_hash); -- For token verification
|
||||||
|
CREATE INDEX idx_static_tokens_created_at ON static_tokens(created_at);
|
||||||
|
CREATE INDEX idx_static_tokens_owner_owner ON static_tokens(owner_owner);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **User Sessions Table**
|
||||||
|
```sql
|
||||||
|
-- Session lookup indexes
|
||||||
|
CREATE INDEX idx_user_sessions_user_id ON user_sessions(user_id);
|
||||||
|
CREATE INDEX idx_user_sessions_app_id ON user_sessions(app_id);
|
||||||
|
CREATE INDEX idx_user_sessions_token ON user_sessions(session_token);
|
||||||
|
CREATE INDEX idx_user_sessions_expires_at ON user_sessions(expires_at);
|
||||||
|
CREATE INDEX idx_user_sessions_active ON user_sessions(active);
|
||||||
|
|
||||||
|
-- Composite index for active session lookup
|
||||||
|
CREATE INDEX idx_user_sessions_active_lookup
|
||||||
|
ON user_sessions(user_id, app_id, active) WHERE active = true;
|
||||||
|
|
||||||
|
-- Cleanup index for expired sessions
|
||||||
|
CREATE INDEX idx_user_sessions_cleanup
|
||||||
|
ON user_sessions(expires_at) WHERE active = true;
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **Available Permissions Table**
|
||||||
|
```sql
|
||||||
|
-- Permission lookup indexes
|
||||||
|
CREATE INDEX idx_available_permissions_scope ON available_permissions(scope);
|
||||||
|
CREATE INDEX idx_available_permissions_category ON available_permissions(category);
|
||||||
|
CREATE INDEX idx_available_permissions_parent_scope ON available_permissions(parent_scope);
|
||||||
|
CREATE INDEX idx_available_permissions_is_system ON available_permissions(is_system);
|
||||||
|
|
||||||
|
-- Hierarchy traversal index
|
||||||
|
CREATE INDEX idx_available_permissions_hierarchy
|
||||||
|
ON available_permissions(parent_scope, scope);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **Granted Permissions Table**
|
||||||
|
```sql
|
||||||
|
-- Token permission lookup
|
||||||
|
CREATE INDEX idx_granted_permissions_token ON granted_permissions(token_type, token_id);
|
||||||
|
CREATE INDEX idx_granted_permissions_permission_id ON granted_permissions(permission_id);
|
||||||
|
CREATE INDEX idx_granted_permissions_scope ON granted_permissions(scope);
|
||||||
|
CREATE INDEX idx_granted_permissions_revoked ON granted_permissions(revoked);
|
||||||
|
|
||||||
|
-- Active permissions index
|
||||||
|
CREATE INDEX idx_granted_permissions_active
|
||||||
|
ON granted_permissions(token_type, token_id, scope) WHERE revoked = false;
|
||||||
|
|
||||||
|
-- Permission cleanup index
|
||||||
|
CREATE INDEX idx_granted_permissions_revoked_at ON granted_permissions(revoked_at);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **Audit Logs Table**
|
||||||
|
```sql
|
||||||
|
-- Audit query indexes
|
||||||
|
CREATE INDEX idx_audit_logs_timestamp ON audit_logs(timestamp);
|
||||||
|
CREATE INDEX idx_audit_logs_user_id ON audit_logs(user_id);
|
||||||
|
CREATE INDEX idx_audit_logs_action ON audit_logs(action);
|
||||||
|
CREATE INDEX idx_audit_logs_resource ON audit_logs(resource_type, resource_id);
|
||||||
|
|
||||||
|
-- Time-series partitioning preparation
|
||||||
|
CREATE INDEX idx_audit_logs_monthly
|
||||||
|
ON audit_logs(date_trunc('month', timestamp), timestamp);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Performance Optimization
|
||||||
|
|
||||||
|
#### **Partial Indexes**
|
||||||
|
```sql
|
||||||
|
-- Index only active sessions
|
||||||
|
CREATE INDEX idx_active_sessions
|
||||||
|
ON user_sessions(user_id, app_id) WHERE active = true;
|
||||||
|
|
||||||
|
-- Index only non-revoked permissions
|
||||||
|
CREATE INDEX idx_active_permissions
|
||||||
|
ON granted_permissions(token_id, scope) WHERE revoked = false;
|
||||||
|
|
||||||
|
-- Index only system permissions
|
||||||
|
CREATE INDEX idx_system_permissions
|
||||||
|
ON available_permissions(scope, parent_scope) WHERE is_system = true;
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **Composite Indexes**
|
||||||
|
```sql
|
||||||
|
-- Application ownership queries
|
||||||
|
CREATE INDEX idx_applications_ownership
|
||||||
|
ON applications(owner_type, owner_owner, created_at);
|
||||||
|
|
||||||
|
-- Token verification queries
|
||||||
|
CREATE INDEX idx_token_verification
|
||||||
|
ON static_tokens(app_id, key_hash);
|
||||||
|
|
||||||
|
-- Permission evaluation queries
|
||||||
|
CREATE INDEX idx_permission_evaluation
|
||||||
|
ON granted_permissions(token_type, token_id, permission_id, revoked);
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Security Considerations
|
||||||
|
|
||||||
|
### Data Protection
|
||||||
|
|
||||||
|
#### **Sensitive Data Handling**
|
||||||
|
```sql
|
||||||
|
-- HMAC keys should be encrypted at application level
|
||||||
|
-- Token hashes use BCrypt with cost 14
|
||||||
|
-- Audit logs contain no sensitive data in plaintext
|
||||||
|
|
||||||
|
-- Row-level security (RLS) for multi-tenant isolation
|
||||||
|
ALTER TABLE applications ENABLE ROW LEVEL SECURITY;
|
||||||
|
ALTER TABLE static_tokens ENABLE ROW LEVEL SECURITY;
|
||||||
|
ALTER TABLE user_sessions ENABLE ROW LEVEL SECURITY;
|
||||||
|
|
||||||
|
-- Example RLS policy for application isolation
|
||||||
|
CREATE POLICY app_owner_policy ON applications
|
||||||
|
FOR ALL TO app_user
|
||||||
|
USING (owner_owner = current_setting('app.user_id'));
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **Access Control**
|
||||||
|
```sql
|
||||||
|
-- Database roles for different access patterns
|
||||||
|
CREATE ROLE kms_api_service;
|
||||||
|
CREATE ROLE kms_readonly;
|
||||||
|
CREATE ROLE kms_admin;
|
||||||
|
|
||||||
|
-- Grant appropriate permissions
|
||||||
|
GRANT SELECT, INSERT, UPDATE, DELETE ON applications TO kms_api_service;
|
||||||
|
GRANT SELECT, INSERT, UPDATE, DELETE ON static_tokens TO kms_api_service;
|
||||||
|
GRANT SELECT, INSERT, UPDATE, DELETE ON user_sessions TO kms_api_service;
|
||||||
|
GRANT SELECT, INSERT, UPDATE, DELETE ON granted_permissions TO kms_api_service;
|
||||||
|
GRANT SELECT, INSERT ON audit_logs TO kms_api_service;
|
||||||
|
|
||||||
|
-- Read-only access for reporting
|
||||||
|
GRANT SELECT ON ALL TABLES IN SCHEMA public TO kms_readonly;
|
||||||
|
|
||||||
|
-- Admin access for maintenance
|
||||||
|
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO kms_admin;
|
||||||
|
```
|
||||||
|
|
||||||
|
### Audit and Compliance
|
||||||
|
|
||||||
|
#### **Audit Triggers**
|
||||||
|
```sql
|
||||||
|
-- Automatic audit logging trigger
|
||||||
|
CREATE OR REPLACE FUNCTION audit_trigger_function()
|
||||||
|
RETURNS TRIGGER AS $$
|
||||||
|
BEGIN
|
||||||
|
INSERT INTO audit_logs (
|
||||||
|
user_id, action, resource_type, resource_id,
|
||||||
|
old_values, new_values, ip_address
|
||||||
|
) VALUES (
|
||||||
|
current_setting('app.user_id', true),
|
||||||
|
TG_OP,
|
||||||
|
TG_TABLE_NAME,
|
||||||
|
COALESCE(NEW.id, OLD.id)::text,
|
||||||
|
CASE WHEN TG_OP = 'DELETE' THEN row_to_json(OLD) ELSE NULL END,
|
||||||
|
CASE WHEN TG_OP = 'INSERT' THEN row_to_json(NEW)
|
||||||
|
WHEN TG_OP = 'UPDATE' THEN row_to_json(NEW)
|
||||||
|
ELSE NULL END,
|
||||||
|
inet_client_addr()
|
||||||
|
);
|
||||||
|
RETURN COALESCE(NEW, OLD);
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql SECURITY DEFINER;
|
||||||
|
|
||||||
|
-- Apply audit trigger to sensitive tables
|
||||||
|
CREATE TRIGGER audit_applications
|
||||||
|
AFTER INSERT OR UPDATE OR DELETE ON applications
|
||||||
|
FOR EACH ROW EXECUTE FUNCTION audit_trigger_function();
|
||||||
|
|
||||||
|
CREATE TRIGGER audit_static_tokens
|
||||||
|
AFTER INSERT OR UPDATE OR DELETE ON static_tokens
|
||||||
|
FOR EACH ROW EXECUTE FUNCTION audit_trigger_function();
|
||||||
|
|
||||||
|
CREATE TRIGGER audit_granted_permissions
|
||||||
|
AFTER INSERT OR UPDATE OR DELETE ON granted_permissions
|
||||||
|
FOR EACH ROW EXECUTE FUNCTION audit_trigger_function();
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Migration Strategy
|
||||||
|
|
||||||
|
### Migration Framework
|
||||||
|
|
||||||
|
The KMS uses a custom Go migration system with the following structure:
|
||||||
|
|
||||||
|
```
|
||||||
|
migrations/
|
||||||
|
├── 001_initial_schema.up.sql
|
||||||
|
├── 001_initial_schema.down.sql
|
||||||
|
├── 002_user_sessions.up.sql
|
||||||
|
├── 002_user_sessions.down.sql
|
||||||
|
├── 003_add_token_prefix.up.sql
|
||||||
|
└── 003_add_token_prefix.down.sql
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **Migration Management**
|
||||||
|
```go
|
||||||
|
// File: internal/database/migrations.go
|
||||||
|
type Migration struct {
|
||||||
|
Version int
|
||||||
|
Name string
|
||||||
|
UpScript string
|
||||||
|
DownScript string
|
||||||
|
AppliedAt time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
func RunMigrations(db *sql.DB, migrationsPath string) error {
|
||||||
|
// Create migration tracking table
|
||||||
|
createMigrationTable(db)
|
||||||
|
|
||||||
|
// Get applied migrations
|
||||||
|
applied, err := getAppliedMigrations(db)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run pending migrations
|
||||||
|
return runPendingMigrations(db, migrationsPath, applied)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Schema Versioning
|
||||||
|
|
||||||
|
#### **Version Control**
|
||||||
|
- **Sequential numbering**: 001, 002, 003...
|
||||||
|
- **Descriptive names**: Clear migration purpose
|
||||||
|
- **Rollback support**: Down scripts for every migration
|
||||||
|
- **Atomic operations**: Each migration in a transaction
|
||||||
|
|
||||||
|
#### **Migration Best Practices**
|
||||||
|
```sql
|
||||||
|
-- Always start with BEGIN; and end with COMMIT;
|
||||||
|
BEGIN;
|
||||||
|
|
||||||
|
-- Add new columns with default values
|
||||||
|
ALTER TABLE applications
|
||||||
|
ADD COLUMN token_prefix VARCHAR(10) DEFAULT NULL;
|
||||||
|
|
||||||
|
-- Add constraints after data migration
|
||||||
|
ALTER TABLE applications
|
||||||
|
ADD CONSTRAINT token_prefix_format
|
||||||
|
CHECK (token_prefix IS NULL OR token_prefix ~ '^[A-Z]{2,4}$');
|
||||||
|
|
||||||
|
-- Create indexes concurrently (outside transaction)
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
CREATE INDEX CONCURRENTLY idx_applications_token_prefix
|
||||||
|
ON applications(token_prefix) WHERE token_prefix IS NOT NULL;
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Query Patterns
|
||||||
|
|
||||||
|
### Common Query Patterns
|
||||||
|
|
||||||
|
#### **Application Queries**
|
||||||
|
```sql
|
||||||
|
-- Get application with ownership check
|
||||||
|
SELECT a.* FROM applications a
|
||||||
|
WHERE a.app_id = $1
|
||||||
|
AND (a.owner_owner = $2 OR $2 = 'admin@example.com');
|
||||||
|
|
||||||
|
-- List applications for user with pagination
|
||||||
|
SELECT a.app_id, a.app_link, a.owner_name, a.created_at
|
||||||
|
FROM applications a
|
||||||
|
WHERE a.owner_owner = $1
|
||||||
|
ORDER BY a.created_at DESC
|
||||||
|
LIMIT $2 OFFSET $3;
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **Token Verification Queries**
|
||||||
|
```sql
|
||||||
|
-- Verify static token
|
||||||
|
SELECT st.id, st.app_id, st.key_hash
|
||||||
|
FROM static_tokens st
|
||||||
|
WHERE st.app_id = $1;
|
||||||
|
|
||||||
|
-- Get token permissions
|
||||||
|
SELECT ap.scope
|
||||||
|
FROM granted_permissions gp
|
||||||
|
JOIN available_permissions ap ON gp.permission_id = ap.id
|
||||||
|
WHERE gp.token_type = 'static'
|
||||||
|
AND gp.token_id = $1
|
||||||
|
AND gp.revoked = false;
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **Session Management Queries**
|
||||||
|
```sql
|
||||||
|
-- Get active user session
|
||||||
|
SELECT us.* FROM user_sessions us
|
||||||
|
WHERE us.user_id = $1
|
||||||
|
AND us.app_id = $2
|
||||||
|
AND us.active = true
|
||||||
|
AND us.expires_at > NOW()
|
||||||
|
ORDER BY us.created_at DESC
|
||||||
|
LIMIT 1;
|
||||||
|
|
||||||
|
-- Clean up expired sessions
|
||||||
|
UPDATE user_sessions
|
||||||
|
SET active = false, updated_at = NOW()
|
||||||
|
WHERE active = true
|
||||||
|
AND expires_at < NOW();
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **Permission Evaluation Queries**
|
||||||
|
```sql
|
||||||
|
-- Check user permission
|
||||||
|
WITH user_permissions AS (
|
||||||
|
SELECT DISTINCT ap.scope
|
||||||
|
FROM user_sessions us
|
||||||
|
JOIN granted_permissions gp ON gp.token_type = 'user'
|
||||||
|
JOIN available_permissions ap ON gp.permission_id = ap.id
|
||||||
|
WHERE us.user_id = $1
|
||||||
|
AND us.app_id = $2
|
||||||
|
AND us.active = true
|
||||||
|
AND us.expires_at > NOW()
|
||||||
|
AND gp.revoked = false
|
||||||
|
)
|
||||||
|
SELECT EXISTS(
|
||||||
|
SELECT 1 FROM user_permissions
|
||||||
|
WHERE scope = $3 OR scope = split_part($3, '.', 1)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Get permission hierarchy
|
||||||
|
WITH RECURSIVE permission_tree AS (
|
||||||
|
-- Base case: root permissions
|
||||||
|
SELECT id, scope, name, parent_scope, 0 as level
|
||||||
|
FROM available_permissions
|
||||||
|
WHERE parent_scope IS NULL
|
||||||
|
|
||||||
|
UNION ALL
|
||||||
|
|
||||||
|
-- Recursive case: child permissions
|
||||||
|
SELECT ap.id, ap.scope, ap.name, ap.parent_scope, pt.level + 1
|
||||||
|
FROM available_permissions ap
|
||||||
|
JOIN permission_tree pt ON ap.parent_scope = pt.scope
|
||||||
|
)
|
||||||
|
SELECT * FROM permission_tree ORDER BY level, scope;
|
||||||
|
```
|
||||||
|
|
||||||
|
### Performance Tuning
|
||||||
|
|
||||||
|
#### **Query Optimization**
|
||||||
|
```sql
|
||||||
|
-- Use EXPLAIN ANALYZE for query planning
|
||||||
|
EXPLAIN (ANALYZE, BUFFERS)
|
||||||
|
SELECT st.id FROM static_tokens st
|
||||||
|
WHERE st.app_id = 'test-app' AND st.key_hash = 'hash123';
|
||||||
|
|
||||||
|
-- Optimize with covering indexes
|
||||||
|
CREATE INDEX idx_static_tokens_covering
|
||||||
|
ON static_tokens(app_id, key_hash)
|
||||||
|
INCLUDE (id, created_at);
|
||||||
|
|
||||||
|
-- Use partial indexes for frequent filters
|
||||||
|
CREATE INDEX idx_active_sessions_partial
|
||||||
|
ON user_sessions(user_id, app_id, expires_at)
|
||||||
|
WHERE active = true;
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **Connection Pooling Configuration**
|
||||||
|
```yaml
|
||||||
|
database:
|
||||||
|
host: postgres
|
||||||
|
port: 5432
|
||||||
|
name: kms
|
||||||
|
user: kms_api_service
|
||||||
|
max_open_connections: 25
|
||||||
|
max_idle_connections: 5
|
||||||
|
connection_max_lifetime: 300s
|
||||||
|
connection_max_idle_time: 60s
|
||||||
|
```
|
||||||
|
|
||||||
|
This database schema documentation provides comprehensive coverage of the KMS data model, suitable for developers, database administrators, and system architects who need to understand, maintain, or extend the database layer.
|
||||||
1233
docs/DEPLOYMENT_GUIDE.md
Normal file
1233
docs/DEPLOYMENT_GUIDE.md
Normal file
File diff suppressed because it is too large
Load Diff
828
docs/SECURITY_ARCHITECTURE.md
Normal file
828
docs/SECURITY_ARCHITECTURE.md
Normal file
@ -0,0 +1,828 @@
|
|||||||
|
# KMS Security Architecture
|
||||||
|
|
||||||
|
## Table of Contents
|
||||||
|
1. [Security Overview](#security-overview)
|
||||||
|
2. [Multi-Layered Security Model](#multi-layered-security-model)
|
||||||
|
3. [Authentication Security](#authentication-security)
|
||||||
|
4. [Token Security Models](#token-security-models)
|
||||||
|
5. [Authorization Framework](#authorization-framework)
|
||||||
|
6. [Data Protection](#data-protection)
|
||||||
|
7. [Security Middleware Chain](#security-middleware-chain)
|
||||||
|
8. [Threat Model](#threat-model)
|
||||||
|
9. [Security Controls](#security-controls)
|
||||||
|
10. [Compliance Framework](#compliance-framework)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Security Overview
|
||||||
|
|
||||||
|
The KMS implements a comprehensive security architecture based on defense-in-depth principles. Every layer of the system includes security controls designed to protect against both external threats and insider risks.
|
||||||
|
|
||||||
|
### Security Objectives
|
||||||
|
- **Confidentiality**: Protect sensitive data and credentials
|
||||||
|
- **Integrity**: Ensure data accuracy and prevent tampering
|
||||||
|
- **Availability**: Maintain service availability under attack
|
||||||
|
- **Accountability**: Complete audit trail of all operations
|
||||||
|
- **Non-repudiation**: Cryptographic proof of operations
|
||||||
|
|
||||||
|
### Security Principles
|
||||||
|
- **Zero Trust**: Verify every request regardless of source
|
||||||
|
- **Fail Secure**: Safe defaults when systems fail
|
||||||
|
- **Defense in Depth**: Multiple security layers
|
||||||
|
- **Least Privilege**: Minimal permission grants
|
||||||
|
- **Security by Design**: Security integrated into architecture
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Multi-Layered Security Model
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
graph TB
|
||||||
|
subgraph "External Threats"
|
||||||
|
DDoS[DDoS Attacks]
|
||||||
|
XSS[XSS Attacks]
|
||||||
|
CSRF[CSRF Attacks]
|
||||||
|
Injection[SQL Injection]
|
||||||
|
AuthBypass[Auth Bypass]
|
||||||
|
TokenReplay[Token Replay]
|
||||||
|
BruteForce[Brute Force]
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph "Security Perimeter"
|
||||||
|
subgraph "Load Balancer Security"
|
||||||
|
NginxSec[Nginx Security<br/>- Rate limiting<br/>- SSL termination<br/>- Request filtering]
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph "Application Security Layer"
|
||||||
|
SecurityMW[Security Middleware]
|
||||||
|
|
||||||
|
subgraph "Security Headers"
|
||||||
|
HSTS[HSTS Header<br/>max-age=31536000]
|
||||||
|
ContentType[Content-Type-Options<br/>nosniff]
|
||||||
|
FrameOptions[X-Frame-Options<br/>DENY]
|
||||||
|
XSSProtection[XSS-Protection<br/>1; mode=block]
|
||||||
|
CSP[Content-Security-Policy<br/>Restrictive policy]
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph "CORS Protection"
|
||||||
|
Origins[Allowed Origins<br/>Whitelist validation]
|
||||||
|
Methods[Allowed Methods<br/>GET, POST, PUT, DELETE]
|
||||||
|
Headers[Allowed Headers<br/>Authorization, Content-Type]
|
||||||
|
Credentials[Credentials Policy<br/>Same-origin only]
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph "CSRF Protection"
|
||||||
|
CSRFToken[CSRF Token<br/>Double-submit cookie]
|
||||||
|
CSRFHeader[X-CSRF-Token<br/>Header validation]
|
||||||
|
SameSite[SameSite Cookie<br/>Strict policy]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph "Rate Limiting Defense"
|
||||||
|
GlobalLimit[Global Rate Limit<br/>100 RPS per IP]
|
||||||
|
EndpointLimit[Endpoint-specific<br/>Limits per route]
|
||||||
|
BurstControl[Burst Control<br/>200 request burst]
|
||||||
|
Backoff[Exponential Backoff<br/>Failed attempts]
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph "Authentication Security"
|
||||||
|
MultiAuth[Multi-Provider Auth<br/>Header, JWT, OAuth2, SAML]
|
||||||
|
|
||||||
|
subgraph "Token Security"
|
||||||
|
JWTSigning[JWT Signing<br/>RS256 Algorithm]
|
||||||
|
TokenExpiry[Token Expiration<br/>Configurable TTL]
|
||||||
|
TokenRevocation[Token Revocation<br/>Blacklist in Redis]
|
||||||
|
TokenRotation[Token Rotation<br/>Refresh mechanism]
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph "Static Token Security"
|
||||||
|
HMACValidation[HMAC Validation<br/>SHA-256 signature]
|
||||||
|
TimestampCheck[Timestamp Validation<br/>5-minute window]
|
||||||
|
ReplayProtection[Replay Protection<br/>Nonce tracking]
|
||||||
|
KeyRotation[Key Rotation<br/>Configurable schedule]
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph "Session Security"
|
||||||
|
SessionEncryption[Session Encryption<br/>AES-256-GCM]
|
||||||
|
SessionTimeout[Session Timeout<br/>Idle timeout]
|
||||||
|
SessionFixation[Session Fixation<br/>Protection]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph "Authorization Security"
|
||||||
|
RBAC[Role-Based Access<br/>Hierarchical permissions]
|
||||||
|
PermissionCheck[Permission Validation<br/>Request-level checks]
|
||||||
|
ScopeValidation[Scope Validation<br/>Token scope matching]
|
||||||
|
PrincipleOfLeastPrivilege[Least Privilege<br/>Minimal permissions]
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph "Data Protection"
|
||||||
|
Encryption[Data Encryption]
|
||||||
|
|
||||||
|
subgraph "Encryption at Rest"
|
||||||
|
DBEncryption[Database Encryption<br/>AES-256 column encryption]
|
||||||
|
KeyStorage[Key Management<br/>Environment variables]
|
||||||
|
SaltedHashing[Salted Hashing<br/>BCrypt cost 14]
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph "Encryption in Transit"
|
||||||
|
TLS13[TLS 1.3<br/>All communications]
|
||||||
|
CertPinning[Certificate Pinning<br/>OAuth2/SAML providers]
|
||||||
|
MTLS[Mutual TLS<br/>Service-to-service]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph "Input Validation"
|
||||||
|
JSONValidation[JSON Schema<br/>Request validation]
|
||||||
|
SQLProtection[SQL Injection<br/>Parameterized queries]
|
||||||
|
XSSProtectionValidation[XSS Protection<br/>Input sanitization]
|
||||||
|
PathTraversal[Path Traversal<br/>Prevention]
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph "Monitoring & Detection"
|
||||||
|
SecurityAudit[Security Audit Log<br/>All operations logged]
|
||||||
|
FailureDetection[Failure Detection<br/>Failed auth attempts]
|
||||||
|
AnomalyDetection[Anomaly Detection<br/>Unusual patterns]
|
||||||
|
AlertSystem[Alert System<br/>Security incidents]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph "Database Security"
|
||||||
|
DBSecurity[PostgreSQL Security<br/>- Connection encryption<br/>- User isolation<br/>- Query logging<br/>- Backup encryption]
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph "Infrastructure Security"
|
||||||
|
ContainerSecurity[Container Security<br/>- Non-root user<br/>- Minimal images<br/>- Security scanning]
|
||||||
|
NetworkSecurity[Network Security<br/>- Internal networks<br/>- Firewall rules<br/>- VPN access]
|
||||||
|
end
|
||||||
|
|
||||||
|
%% Threat Mitigation Connections
|
||||||
|
DDoS -.->|Mitigated by| NginxSec
|
||||||
|
XSS -.->|Prevented by| SecurityMW
|
||||||
|
CSRF -.->|Blocked by| CSRFToken
|
||||||
|
Injection -.->|Stopped by| JSONValidation
|
||||||
|
AuthBypass -.->|Blocked by| MultiAuth
|
||||||
|
TokenReplay -.->|Prevented by| TimestampCheck
|
||||||
|
BruteForce -.->|Limited by| GlobalLimit
|
||||||
|
|
||||||
|
%% Security Layer Flow
|
||||||
|
NginxSec --> SecurityMW
|
||||||
|
SecurityMW --> GlobalLimit
|
||||||
|
GlobalLimit --> MultiAuth
|
||||||
|
MultiAuth --> RBAC
|
||||||
|
RBAC --> Encryption
|
||||||
|
Encryption --> JSONValidation
|
||||||
|
JSONValidation --> SecurityAudit
|
||||||
|
|
||||||
|
SecurityAudit --> DBSecurity
|
||||||
|
SecurityAudit --> ContainerSecurity
|
||||||
|
|
||||||
|
%% Styling
|
||||||
|
classDef threat fill:#ffcdd2,stroke:#d32f2f,stroke-width:2px
|
||||||
|
classDef security fill:#c8e6c9,stroke:#388e3c,stroke-width:2px
|
||||||
|
classDef auth fill:#e1bee7,stroke:#7b1fa2,stroke-width:2px
|
||||||
|
classDef data fill:#fff9c4,stroke:#f57f17,stroke-width:2px
|
||||||
|
classDef infra fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
|
||||||
|
|
||||||
|
class DDoS,XSS,CSRF,Injection,AuthBypass,TokenReplay,BruteForce threat
|
||||||
|
class SecurityMW,HSTS,ContentType,FrameOptions,XSSProtection,CSP,Origins,Methods,Headers,Credentials,CSRFToken,CSRFHeader,SameSite security
|
||||||
|
class MultiAuth,JWTSigning,TokenExpiry,TokenRevocation,TokenRotation,HMACValidation,TimestampCheck,ReplayProtection,KeyRotation,SessionEncryption,SessionTimeout,SessionFixation,RBAC,PermissionCheck,ScopeValidation,PrincipleOfLeastPrivilege auth
|
||||||
|
class Encryption,DBEncryption,KeyStorage,SaltedHashing,TLS13,CertPinning,MTLS,JSONValidation,SQLProtection,XSSProtectionValidation,PathTraversal,SecurityAudit,FailureDetection,AnomalyDetection,AlertSystem,DBSecurity data
|
||||||
|
class ContainerSecurity,NetworkSecurity,NginxSec,GlobalLimit,EndpointLimit,BurstControl,Backoff infra
|
||||||
|
```
|
||||||
|
|
||||||
|
### Security Layer Breakdown
|
||||||
|
|
||||||
|
1. **Perimeter Security**: Load balancer, rate limiting, DDoS protection
|
||||||
|
2. **Application Security**: Security headers, CORS, CSRF protection
|
||||||
|
3. **Authentication Security**: Multi-provider authentication with strong cryptography
|
||||||
|
4. **Authorization Security**: RBAC with hierarchical permissions
|
||||||
|
5. **Data Protection**: Encryption at rest and in transit
|
||||||
|
6. **Input Validation**: Comprehensive input sanitization and validation
|
||||||
|
7. **Monitoring**: Security event detection and alerting
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Authentication Security
|
||||||
|
|
||||||
|
### Multi-Provider Authentication Framework
|
||||||
|
|
||||||
|
The KMS supports four authentication providers, each with specific security controls:
|
||||||
|
|
||||||
|
#### **Header-based Authentication**
|
||||||
|
```go
|
||||||
|
// File: internal/auth/header_validator.go:42
|
||||||
|
func (hv *HeaderValidator) ValidateAuthenticationHeaders(r *http.Request) (*ValidatedUserContext, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Security Features:**
|
||||||
|
- **HMAC-SHA256 Signatures**: Request integrity validation
|
||||||
|
- **Timestamp Validation**: 5-minute window prevents replay attacks
|
||||||
|
- **Constant-time Comparison**: Prevents timing attacks
|
||||||
|
- **Email Format Validation**: Prevents injection attacks
|
||||||
|
|
||||||
|
**Implementation Details:**
|
||||||
|
```go
|
||||||
|
// HMAC signature validation with constant-time comparison
|
||||||
|
func (hv *HeaderValidator) validateSignature(userEmail, timestamp, signature string) bool {
|
||||||
|
mac := hmac.New(sha256.New, []byte(signingKey))
|
||||||
|
mac.Write([]byte(signingString))
|
||||||
|
expectedSignature := hex.EncodeToString(mac.Sum(nil))
|
||||||
|
return hmac.Equal([]byte(signature), []byte(expectedSignature))
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **JWT Authentication**
|
||||||
|
```go
|
||||||
|
// File: internal/auth/jwt.go:47
|
||||||
|
func (j *JWTManager) GenerateToken(userToken *domain.UserToken) (string, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Security Features:**
|
||||||
|
- **RSA Signatures**: Strong cryptographic signing
|
||||||
|
- **Token Revocation**: Redis-backed blacklist
|
||||||
|
- **Secure JTI Generation**: Cryptographically secure token IDs
|
||||||
|
- **Claims Validation**: Complete token verification
|
||||||
|
|
||||||
|
**Token Structure:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"iss": "kms-api-service",
|
||||||
|
"sub": "user@example.com",
|
||||||
|
"aud": ["app-id"],
|
||||||
|
"exp": 1642781234,
|
||||||
|
"iat": 1642694834,
|
||||||
|
"nbf": 1642694834,
|
||||||
|
"jti": "secure-random-id",
|
||||||
|
"user_id": "user@example.com",
|
||||||
|
"app_id": "app-id",
|
||||||
|
"permissions": ["app.read", "token.create"],
|
||||||
|
"token_type": "user",
|
||||||
|
"max_valid_at": 1643299634
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **OAuth2 Authentication**
|
||||||
|
```go
|
||||||
|
// File: internal/auth/oauth2.go
|
||||||
|
```
|
||||||
|
|
||||||
|
**Security Features:**
|
||||||
|
- **Authorization Code Flow**: Secure OAuth2 flow implementation
|
||||||
|
- **State Parameter**: CSRF protection for OAuth2
|
||||||
|
- **Token Exchange**: Secure credential handling
|
||||||
|
- **Provider Validation**: Certificate pinning support
|
||||||
|
|
||||||
|
#### **SAML Authentication**
|
||||||
|
```go
|
||||||
|
// File: internal/auth/saml.go
|
||||||
|
```
|
||||||
|
|
||||||
|
**Security Features:**
|
||||||
|
- **XML Signature Validation**: Assertion integrity verification
|
||||||
|
- **Certificate Validation**: Provider certificate verification
|
||||||
|
- **Attribute Extraction**: Secure claim processing
|
||||||
|
- **Replay Protection**: Timestamp and nonce validation
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Token Security Models
|
||||||
|
|
||||||
|
### Static Token Security (HMAC-based)
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
stateDiagram-v2
|
||||||
|
[*] --> TokenRequest: Client requests token
|
||||||
|
|
||||||
|
state TokenRequest {
|
||||||
|
[*] --> ValidateApp: Validate app_id
|
||||||
|
ValidateApp --> ValidatePerms: Check permissions
|
||||||
|
ValidatePerms --> GenerateToken: Create token
|
||||||
|
GenerateToken --> [*]
|
||||||
|
}
|
||||||
|
|
||||||
|
TokenRequest --> StaticToken: type=static
|
||||||
|
|
||||||
|
state StaticToken {
|
||||||
|
[*] --> GenerateHMAC: Generate HMAC key
|
||||||
|
GenerateHMAC --> HashKey: BCrypt hash (cost 14)
|
||||||
|
HashKey --> StoreDB: Store in static_tokens table
|
||||||
|
StoreDB --> GrantPerms: Assign permissions
|
||||||
|
GrantPerms --> Active: Token ready
|
||||||
|
|
||||||
|
Active --> Verify: Incoming request
|
||||||
|
Verify --> ValidateHMAC: Check HMAC signature
|
||||||
|
ValidateHMAC --> CheckTimestamp: Replay protection
|
||||||
|
CheckTimestamp --> CheckPerms: Validate permissions
|
||||||
|
CheckPerms --> Authorized: Permission check
|
||||||
|
CheckPerms --> Denied: Permission denied
|
||||||
|
|
||||||
|
Active --> Revoke: Admin action
|
||||||
|
Revoke --> Revoked: Update granted_permissions.revoked=true
|
||||||
|
}
|
||||||
|
|
||||||
|
Authorized --> TokenResponse: Success response
|
||||||
|
Denied --> ErrorResponse: Error response
|
||||||
|
Revoked --> [*]: Token lifecycle end
|
||||||
|
|
||||||
|
note right of StaticToken
|
||||||
|
Static tokens use HMAC signatures
|
||||||
|
- Timestamp-based replay protection
|
||||||
|
- BCrypt hashed storage
|
||||||
|
- Permission-based access control
|
||||||
|
- No expiration (until revoked)
|
||||||
|
end note
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **Token Format**
|
||||||
|
```
|
||||||
|
Format: {PREFIX}_{BASE64_DATA}
|
||||||
|
Example: ABC_xyz123base64encodeddata...
|
||||||
|
Validation: HMAC-SHA256(request_data, hmac_key)
|
||||||
|
Storage: BCrypt hash (cost 14)
|
||||||
|
Lifetime: No expiration (until revoked)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **Security Implementation**
|
||||||
|
```go
|
||||||
|
// File: internal/crypto/token.go:95
|
||||||
|
func (tg *TokenGenerator) HashToken(token string) (string, error) {
|
||||||
|
hash, err := bcrypt.GenerateFromPassword([]byte(token), tg.bcryptCost)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to hash token with bcrypt cost %d: %w", tg.bcryptCost, err)
|
||||||
|
}
|
||||||
|
return string(hash), nil
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### User Token Security (JWT-based)
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
stateDiagram-v2
|
||||||
|
[*] --> UserTokenRequest: User requests token
|
||||||
|
|
||||||
|
state UserTokenRequest {
|
||||||
|
[*] --> AuthUser: Authenticate user
|
||||||
|
AuthUser --> GenerateJWT: Create JWT with claims
|
||||||
|
GenerateJWT --> SetExpiry: Set expires_at, max_valid_at
|
||||||
|
SetExpiry --> StoreSession: Store user session
|
||||||
|
StoreSession --> Active: JWT issued
|
||||||
|
}
|
||||||
|
|
||||||
|
UserTokenRequest --> UserToken: type=user
|
||||||
|
|
||||||
|
state UserToken {
|
||||||
|
Active --> Verify: Incoming request
|
||||||
|
Verify --> ValidateJWT: Check JWT signature
|
||||||
|
ValidateJWT --> CheckExpiry: Verify expiration
|
||||||
|
CheckExpiry --> CheckRevoked: Check revocation list
|
||||||
|
CheckRevoked --> Authorized: Valid token
|
||||||
|
CheckRevoked --> Denied: Token invalid
|
||||||
|
CheckExpiry --> Expired: Token expired
|
||||||
|
|
||||||
|
Active --> Renew: Renewal request
|
||||||
|
Renew --> CheckRenewal: Within renewal window?
|
||||||
|
CheckRenewal --> GenerateNew: Issue new JWT
|
||||||
|
CheckRenewal --> Denied: Renewal denied
|
||||||
|
GenerateNew --> Active: New token active
|
||||||
|
|
||||||
|
Active --> Logout: User logout
|
||||||
|
Logout --> Revoked: Add to revocation list
|
||||||
|
|
||||||
|
Expired --> Renew: Attempt renewal
|
||||||
|
}
|
||||||
|
|
||||||
|
Authorized --> TokenResponse: Success response
|
||||||
|
Denied --> ErrorResponse: Error response
|
||||||
|
Revoked --> [*]: Token lifecycle end
|
||||||
|
|
||||||
|
note right of UserToken
|
||||||
|
User tokens are JWT-based
|
||||||
|
- Configurable expiration
|
||||||
|
- Renewable within limits
|
||||||
|
- Session tracking
|
||||||
|
- Hierarchical permissions
|
||||||
|
end note
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **Token Format**
|
||||||
|
```
|
||||||
|
Format: {CUSTOM_PREFIX}UT-{JWT_TOKEN}
|
||||||
|
Example: ABC123UT-eyJhbGciOiJSUzI1NiIs...
|
||||||
|
Validation: RSA signature + claims validation
|
||||||
|
Storage: Revocation list in Redis
|
||||||
|
Lifetime: Configurable with renewal window
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **Security Features**
|
||||||
|
- **RSA-256 Signatures**: Strong cryptographic validation
|
||||||
|
- **Token Revocation**: Redis blacklist with TTL
|
||||||
|
- **Renewal Controls**: Limited renewal window
|
||||||
|
- **Session Tracking**: Database session management
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Authorization Framework
|
||||||
|
|
||||||
|
### Role-Based Access Control (RBAC)
|
||||||
|
|
||||||
|
The KMS implements a hierarchical permission system with role-based access control:
|
||||||
|
|
||||||
|
#### **Permission Hierarchy**
|
||||||
|
```
|
||||||
|
admin
|
||||||
|
├── app.admin
|
||||||
|
│ ├── app.read
|
||||||
|
│ ├── app.write
|
||||||
|
│ │ ├── app.create
|
||||||
|
│ │ ├── app.update
|
||||||
|
│ │ └── app.delete
|
||||||
|
├── token.admin
|
||||||
|
│ ├── token.read
|
||||||
|
│ │ └── token.verify
|
||||||
|
│ ├── token.write
|
||||||
|
│ │ ├── token.create
|
||||||
|
│ │ └── token.revoke
|
||||||
|
├── permission.admin
|
||||||
|
│ ├── permission.read
|
||||||
|
│ ├── permission.write
|
||||||
|
│ │ ├── permission.grant
|
||||||
|
│ │ └── permission.revoke
|
||||||
|
└── user.admin
|
||||||
|
├── user.read
|
||||||
|
└── user.write
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **Role Definitions**
|
||||||
|
```go
|
||||||
|
// File: internal/auth/permissions.go:151
|
||||||
|
func (h *PermissionHierarchy) initializeDefaultRoles() {
|
||||||
|
defaultRoles := []*Role{
|
||||||
|
{
|
||||||
|
Name: "super_admin",
|
||||||
|
Description: "Super administrator with full access",
|
||||||
|
Permissions: []string{"admin"},
|
||||||
|
Metadata: map[string]string{"level": "system"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "app_admin",
|
||||||
|
Description: "Application administrator",
|
||||||
|
Permissions: []string{"app.admin", "token.admin", "user.read"},
|
||||||
|
Metadata: map[string]string{"level": "application"},
|
||||||
|
},
|
||||||
|
// Additional roles...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **Permission Evaluation**
|
||||||
|
```go
|
||||||
|
// File: internal/auth/permissions.go:201
|
||||||
|
func (pm *PermissionManager) HasPermission(ctx context.Context, userID, appID, permission string) (*PermissionEvaluation, error) {
|
||||||
|
// Cache lookup first
|
||||||
|
cacheKey := cache.CacheKey(cache.KeyPrefixPermission, fmt.Sprintf("%s:%s:%s", userID, appID, permission))
|
||||||
|
|
||||||
|
// Evaluate permission with hierarchy
|
||||||
|
evaluation := pm.evaluatePermission(ctx, userID, appID, permission)
|
||||||
|
|
||||||
|
// Cache result for 5 minutes
|
||||||
|
pm.cacheManager.SetJSON(ctx, cacheKey, evaluation, 5*time.Minute)
|
||||||
|
|
||||||
|
return evaluation, nil
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Authorization Controls
|
||||||
|
|
||||||
|
#### **Resource Ownership**
|
||||||
|
```go
|
||||||
|
// File: internal/authorization/rbac.go:100
|
||||||
|
func (a *AuthorizationService) AuthorizeApplicationOwnership(userID string, app *domain.Application) error {
|
||||||
|
// System admins can access any application
|
||||||
|
if a.isSystemAdmin(userID) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if user is the owner
|
||||||
|
if a.isOwner(userID, &app.Owner) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors.NewForbiddenError("You do not have permission to access this application")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **Token Scoping**
|
||||||
|
```go
|
||||||
|
// File: internal/services/token_service.go:400
|
||||||
|
func (s *tokenService) verifyStaticToken(ctx context.Context, req *domain.VerifyRequest, app *domain.Application) (*domain.VerifyResponse, error) {
|
||||||
|
// Get granted permissions for this token
|
||||||
|
permissions, err := s.grantRepo.GetGrantedPermissionScopes(ctx, domain.TokenTypeStatic, matchedToken.ID)
|
||||||
|
|
||||||
|
// Check specific permissions if requested
|
||||||
|
if len(req.Permissions) > 0 {
|
||||||
|
permissionResults, err := s.grantRepo.HasAnyPermission(ctx, domain.TokenTypeStatic, matchedToken.ID, req.Permissions)
|
||||||
|
// Validate all requested permissions are granted
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Data Protection
|
||||||
|
|
||||||
|
### Encryption at Rest
|
||||||
|
|
||||||
|
#### **Database Encryption**
|
||||||
|
```sql
|
||||||
|
-- Sensitive data encryption in PostgreSQL
|
||||||
|
CREATE TABLE applications (
|
||||||
|
app_id VARCHAR(100) PRIMARY KEY,
|
||||||
|
hmac_key TEXT, -- Encrypted with application-level encryption
|
||||||
|
created_at TIMESTAMP DEFAULT NOW()
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE static_tokens (
|
||||||
|
id UUID PRIMARY KEY,
|
||||||
|
key_hash TEXT NOT NULL, -- BCrypt hashed with cost 14
|
||||||
|
created_at TIMESTAMP DEFAULT NOW()
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **BCrypt Hashing**
|
||||||
|
```go
|
||||||
|
// File: internal/crypto/token.go:22
|
||||||
|
const BcryptCost = 14 // 2025 security standards (minimum 14)
|
||||||
|
|
||||||
|
func (tg *TokenGenerator) HashToken(token string) (string, error) {
|
||||||
|
hash, err := bcrypt.GenerateFromPassword([]byte(token), tg.bcryptCost)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to hash token with bcrypt cost %d: %w", tg.bcryptCost, err)
|
||||||
|
}
|
||||||
|
return string(hash), nil
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Encryption in Transit
|
||||||
|
|
||||||
|
#### **TLS Configuration**
|
||||||
|
```go
|
||||||
|
// TLS 1.3 configuration for all communications
|
||||||
|
tlsConfig := &tls.Config{
|
||||||
|
MinVersion: tls.VersionTLS13,
|
||||||
|
CipherSuites: []uint16{
|
||||||
|
tls.TLS_AES_256_GCM_SHA384,
|
||||||
|
tls.TLS_CHACHA20_POLY1305_SHA256,
|
||||||
|
tls.TLS_AES_128_GCM_SHA256,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **Certificate Pinning**
|
||||||
|
```go
|
||||||
|
// OAuth2/SAML provider certificate pinning
|
||||||
|
func (o *OAuth2Provider) validateCertificate(cert *x509.Certificate) error {
|
||||||
|
expectedFingerprints := o.config.GetStringSlice("OAUTH2_CERT_FINGERPRINTS")
|
||||||
|
|
||||||
|
fingerprint := sha256.Sum256(cert.Raw)
|
||||||
|
fingerprintHex := hex.EncodeToString(fingerprint[:])
|
||||||
|
|
||||||
|
for _, expected := range expectedFingerprints {
|
||||||
|
if fingerprintHex == expected {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Errorf("certificate fingerprint mismatch")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Security Middleware Chain
|
||||||
|
|
||||||
|
### Middleware Processing Order
|
||||||
|
|
||||||
|
1. **Request Logger**: Structured logging with security context
|
||||||
|
2. **Security Headers**: XSS, clickjacking, MIME-type protection
|
||||||
|
3. **CORS Handler**: Cross-origin request validation
|
||||||
|
4. **CSRF Protection**: Double-submit token validation
|
||||||
|
5. **Rate Limiter**: DDoS and abuse protection
|
||||||
|
6. **Authentication**: Multi-provider authentication
|
||||||
|
7. **Authorization**: Permission validation
|
||||||
|
8. **Input Validation**: Request sanitization and validation
|
||||||
|
|
||||||
|
### Rate Limiting Implementation
|
||||||
|
|
||||||
|
```go
|
||||||
|
// File: internal/middleware/security.go:48
|
||||||
|
func (s *SecurityMiddleware) RateLimitMiddleware(next http.Handler) http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
clientIP := s.getClientIP(r)
|
||||||
|
limiter := s.getRateLimiter(clientIP)
|
||||||
|
|
||||||
|
if !limiter.Allow() {
|
||||||
|
s.logger.Warn("Rate limit exceeded",
|
||||||
|
zap.String("client_ip", clientIP),
|
||||||
|
zap.String("path", r.URL.Path))
|
||||||
|
|
||||||
|
s.trackRateLimitViolation(clientIP)
|
||||||
|
|
||||||
|
http.Error(w, `{"error":"rate_limit_exceeded"}`, http.StatusTooManyRequests)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
next.ServeHTTP(w, r)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Brute Force Protection
|
||||||
|
|
||||||
|
```go
|
||||||
|
// File: internal/middleware/security.go:365
|
||||||
|
func (s *SecurityMiddleware) checkAndBlockIP(clientIP string) {
|
||||||
|
var count int
|
||||||
|
err := s.cacheManager.GetJSON(ctx, key, &count)
|
||||||
|
|
||||||
|
maxFailures := s.config.GetInt("MAX_AUTH_FAILURES")
|
||||||
|
if maxFailures <= 0 {
|
||||||
|
maxFailures = 5 // Default
|
||||||
|
}
|
||||||
|
|
||||||
|
if count >= maxFailures {
|
||||||
|
// Block the IP for 1 hour
|
||||||
|
blockInfo := map[string]interface{}{
|
||||||
|
"blocked_at": time.Now().Unix(),
|
||||||
|
"failure_count": count,
|
||||||
|
"reason": "excessive_auth_failures",
|
||||||
|
}
|
||||||
|
|
||||||
|
s.cacheManager.SetJSON(ctx, blockKey, blockInfo, blockDuration)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Threat Model
|
||||||
|
|
||||||
|
### External Threats
|
||||||
|
|
||||||
|
#### **Network-based Attacks**
|
||||||
|
- **DDoS**: Rate limiting and load balancer protection
|
||||||
|
- **Man-in-the-Middle**: TLS 1.3 encryption
|
||||||
|
- **Packet Sniffing**: End-to-end encryption
|
||||||
|
|
||||||
|
#### **Application-level Attacks**
|
||||||
|
- **SQL Injection**: Parameterized queries only
|
||||||
|
- **XSS**: Input validation and CSP headers
|
||||||
|
- **CSRF**: Double-submit token protection
|
||||||
|
- **Session Hijacking**: Secure session management
|
||||||
|
|
||||||
|
#### **Authentication Attacks**
|
||||||
|
- **Brute Force**: Rate limiting and account lockout
|
||||||
|
- **Credential Stuffing**: Multi-factor authentication support
|
||||||
|
- **Token Replay**: Timestamp validation and nonces
|
||||||
|
- **JWT Attacks**: Strong cryptographic signing
|
||||||
|
|
||||||
|
### Insider Threats
|
||||||
|
|
||||||
|
#### **Privileged User Abuse**
|
||||||
|
- **Audit Logging**: Complete audit trail
|
||||||
|
- **Role Separation**: Principle of least privilege
|
||||||
|
- **Session Monitoring**: Abnormal activity detection
|
||||||
|
|
||||||
|
#### **Data Exfiltration**
|
||||||
|
- **Access Controls**: Resource-level authorization
|
||||||
|
- **Data Classification**: Sensitive data identification
|
||||||
|
- **Export Monitoring**: Large data access alerts
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Security Controls
|
||||||
|
|
||||||
|
### Preventive Controls
|
||||||
|
|
||||||
|
#### **Authentication Controls**
|
||||||
|
- Multi-factor authentication support
|
||||||
|
- Strong password policies (where applicable)
|
||||||
|
- Account lockout mechanisms
|
||||||
|
- Session timeout enforcement
|
||||||
|
|
||||||
|
#### **Authorization Controls**
|
||||||
|
- Role-based access control (RBAC)
|
||||||
|
- Resource-level permissions
|
||||||
|
- API endpoint protection
|
||||||
|
- Ownership validation
|
||||||
|
|
||||||
|
#### **Data Protection Controls**
|
||||||
|
- Encryption at rest (AES-256)
|
||||||
|
- Encryption in transit (TLS 1.3)
|
||||||
|
- Key management procedures
|
||||||
|
- Secure data disposal
|
||||||
|
|
||||||
|
### Detective Controls
|
||||||
|
|
||||||
|
#### **Monitoring and Logging**
|
||||||
|
```go
|
||||||
|
// Comprehensive audit logging
|
||||||
|
type AuditLog struct {
|
||||||
|
ID uuid.UUID `json:"id"`
|
||||||
|
Timestamp time.Time `json:"timestamp"`
|
||||||
|
UserID string `json:"user_id"`
|
||||||
|
Action string `json:"action"`
|
||||||
|
ResourceType string `json:"resource_type"`
|
||||||
|
ResourceID string `json:"resource_id"`
|
||||||
|
IPAddress string `json:"ip_address"`
|
||||||
|
UserAgent string `json:"user_agent"`
|
||||||
|
Metadata map[string]interface{} `json:"metadata"`
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **Security Event Detection**
|
||||||
|
- Failed authentication attempts
|
||||||
|
- Privilege escalation attempts
|
||||||
|
- Unusual access patterns
|
||||||
|
- Token misuse detection
|
||||||
|
|
||||||
|
### Responsive Controls
|
||||||
|
|
||||||
|
#### **Incident Response**
|
||||||
|
- Automated threat response
|
||||||
|
- Token revocation procedures
|
||||||
|
- User account suspension
|
||||||
|
- Alert escalation workflows
|
||||||
|
|
||||||
|
#### **Recovery Controls**
|
||||||
|
- Backup and restore procedures
|
||||||
|
- Disaster recovery planning
|
||||||
|
- Business continuity measures
|
||||||
|
- Data integrity verification
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Compliance Framework
|
||||||
|
|
||||||
|
### OWASP Top 10 Protection
|
||||||
|
|
||||||
|
1. **Injection**: Parameterized queries, input validation
|
||||||
|
2. **Broken Authentication**: Multi-provider auth, strong crypto
|
||||||
|
3. **Sensitive Data Exposure**: Encryption, secure storage
|
||||||
|
4. **XML External Entities**: JSON-only API
|
||||||
|
5. **Broken Access Control**: RBAC, authorization checks
|
||||||
|
6. **Security Misconfiguration**: Secure defaults
|
||||||
|
7. **Cross-Site Scripting**: Input validation, CSP
|
||||||
|
8. **Insecure Deserialization**: Safe JSON handling
|
||||||
|
9. **Known Vulnerabilities**: Regular dependency updates
|
||||||
|
10. **Logging & Monitoring**: Comprehensive audit trails
|
||||||
|
|
||||||
|
### Regulatory Compliance
|
||||||
|
|
||||||
|
#### **SOC 2 Type II Controls**
|
||||||
|
- **Security**: Access controls, encryption, monitoring
|
||||||
|
- **Availability**: High availability, disaster recovery
|
||||||
|
- **Processing Integrity**: Data validation, error handling
|
||||||
|
- **Confidentiality**: Data classification, access restrictions
|
||||||
|
- **Privacy**: Data minimization, consent management
|
||||||
|
|
||||||
|
#### **GDPR Compliance** (where applicable)
|
||||||
|
- **Data Protection by Design**: Privacy-first architecture
|
||||||
|
- **Consent Management**: Granular consent controls
|
||||||
|
- **Right to Erasure**: Data deletion procedures
|
||||||
|
- **Data Portability**: Export capabilities
|
||||||
|
- **Breach Notification**: Automated incident response
|
||||||
|
|
||||||
|
#### **NIST Cybersecurity Framework**
|
||||||
|
- **Identify**: Asset inventory, risk assessment
|
||||||
|
- **Protect**: Access controls, data security
|
||||||
|
- **Detect**: Monitoring, anomaly detection
|
||||||
|
- **Respond**: Incident response procedures
|
||||||
|
- **Recover**: Business continuity planning
|
||||||
|
|
||||||
|
### Security Metrics
|
||||||
|
|
||||||
|
#### **Key Security Indicators**
|
||||||
|
- Authentication success/failure rates
|
||||||
|
- Authorization denial rates
|
||||||
|
- Token usage patterns
|
||||||
|
- Security event frequency
|
||||||
|
- Incident response times
|
||||||
|
|
||||||
|
#### **Security Monitoring**
|
||||||
|
```yaml
|
||||||
|
alerts:
|
||||||
|
- name: "High Authentication Failure Rate"
|
||||||
|
condition: "auth_failures > 10 per minute per IP"
|
||||||
|
severity: "warning"
|
||||||
|
|
||||||
|
- name: "Privilege Escalation Attempt"
|
||||||
|
condition: "permission_denied + elevated_permission"
|
||||||
|
severity: "critical"
|
||||||
|
|
||||||
|
- name: "Token Abuse Detection"
|
||||||
|
condition: "token_usage_anomaly"
|
||||||
|
severity: "warning"
|
||||||
|
```
|
||||||
|
|
||||||
|
This security architecture document provides comprehensive coverage of the KMS security model, suitable for security audits, compliance reviews, and security team training.
|
||||||
Reference in New Issue
Block a user