# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview This is an API Key Management Service (KMS) built with Go backend and React TypeScript frontend. The system manages API keys, user authentication, permissions, and provides both static tokens and user JWT tokens with hierarchical permission scopes. **Key Technologies:** - **Backend**: Go 1.23+ with Gin/Gorilla Mux, PostgreSQL, JWT tokens - **Frontend**: React 19+ with TypeScript, Ant Design 5.27+ - **Infrastructure**: Podman/Docker Compose, Nginx, Redis (optional) - **Security**: HMAC token signing, RBAC permissions, rate limiting ## Architecture The project follows clean architecture principles with clear separation: ``` cmd/server/ - Application entry point internal/ - Go backend core logic ├── domain/ - Domain models and business logic ├── repository/ - Data access interfaces and PostgreSQL implementations ├── services/ - Business logic layer ├── handlers/ - HTTP request handlers (Gin-based) ├── middleware/ - Authentication, logging, security, CSRF middleware ├── config/ - Configuration management with validation ├── auth/ - JWT, OAuth2, SAML, header-based auth providers ├── cache/ - Redis caching layer (optional) ├── metrics/ - Prometheus metrics collection └── database/ - Database connection and migrations kms-frontend/ - React TypeScript frontend with Ant Design migrations/ - PostgreSQL database migration files test/ - Integration and E2E tests (both Go and bash) docs/ - Comprehensive technical documentation nginx/ - Nginx configuration for reverse proxy ``` ## Development Commands ### Go Backend ```bash # Run the server locally (requires environment variables) INTERNAL_HMAC_KEY=test-hmac-key JWT_SECRET=test-jwt-secret AUTH_SIGNING_KEY=test-signing-key go run cmd/server/main.go # Build the binary go build -o api-key-service ./cmd/server # Run tests (uses kms_test database) go test -v ./test/... # Run tests with coverage go test -v -coverprofile=coverage.out ./test/... go tool cover -html=coverage.out -o coverage.html # Run specific test suites go test -v ./test/ -run TestHealthEndpoints go test -v ./test/ -run TestApplicationCRUD go test -v ./test/ -run TestStaticTokenWorkflow go test -v ./test/ -run TestConcurrentRequests ``` ### React Frontend ```bash # Navigate to frontend directory cd kms-frontend # Install dependencies (Node 24+, npm 11+) npm install # Start development server npm start # Build for production npm run build # Run tests npm test ``` ### Podman Compose & Development Environment **CRITICAL**: This project uses `podman-compose`, not `docker-compose`. ```bash # Start all services (PostgreSQL, API, Nginx, Frontend) podman-compose up -d # Check service health curl http://localhost:8081/health # View logs podman-compose logs -f # View specific service logs podman-compose logs -f api-service podman-compose logs -f postgres # Stop services podman-compose down # Rebuild services after code changes podman-compose up -d --build ``` ## Database Operations **CRITICAL**: All database operations use `podman exec` commands. Never use direct `psql` commands. ### Database Access ```bash # Access database shell (container name: kms-postgres) podman exec -it kms-postgres psql -U postgres -d kms # Run SQL commands via exec podman exec -it kms-postgres psql -U postgres -c "SELECT * FROM applications LIMIT 5;" # Check specific tables podman exec -it kms-postgres psql -U postgres -d kms -c "\dt" podman exec -it kms-postgres psql -U postgres -d kms -c "SELECT token_id, app_id, user_id FROM static_tokens LIMIT 5;" # Apply migrations manually if needed podman exec -it kms-postgres psql -U postgres -d kms -f /docker-entrypoint-initdb.d/001_initial_schema.up.sql ``` ### Database Testing ```bash # Create test database (if needed) podman exec -it kms-postgres psql -U postgres -c "CREATE DATABASE kms_test;" # Reset test database podman exec -it kms-postgres psql -U postgres -c "DROP DATABASE IF EXISTS kms_test; CREATE DATABASE kms_test;" # Check test data podman exec -it kms-postgres psql -U postgres -d kms -c "SELECT * FROM applications WHERE name LIKE 'test-%';" ``` ## Testing The project uses podman-compose for all testing environments and database operations. ### End-to-End Testing ```bash # Start test environment with podman-compose, guaranteeing that it updates with --build podman-compose up -d --build # Wait for services to be ready sleep 10 # Run comprehensive E2E tests with curl ./test/e2e_test.sh # Test against specific server and user BASE_URL=http://localhost:8080 USER_EMAIL=admin@example.com ./test/e2e_test.sh # Clean up test environment podman-compose down ``` ### Go Integration Tests ```bash # Run Go integration tests (uses kms_test database) go test -v ./test/... # With podman-compose environment podman-compose up -d sleep 10 go test -v ./test/... podman-compose down ``` ### Test Environments & Ports - **Port 8080**: Main API service - **Port 8081**: Nginx proxy (main access point) - **Port 3000**: React frontend (direct access) - **Port 5432**: PostgreSQL database - **Port 9090**: Metrics endpoint (if enabled) The service provides different test user contexts: - Regular user: `test@example.com` - Admin user: `admin@example.com` - Limited user: `limited@example.com` ## Key Configuration ### Required Environment Variables ```bash # Security (REQUIRED - minimum 32 characters each) INTERNAL_HMAC_KEY= JWT_SECRET= AUTH_SIGNING_KEY= # Database DB_HOST=postgres # Use 'postgres' for containers, 'localhost' for local DB_PORT=5432 DB_NAME=kms DB_USER=postgres DB_PASSWORD=postgres DB_SSLMODE=disable # Server SERVER_HOST=0.0.0.0 SERVER_PORT=8080 # Authentication AUTH_PROVIDER=header # or 'sso' AUTH_HEADER_USER_EMAIL=X-User-Email # Features RATE_LIMIT_ENABLED=true CACHE_ENABLED=false # Set to true to enable Redis METRICS_ENABLED=true SAML_ENABLED=false # Set to true for SAML auth ``` ### Optional Configuration ```bash # Rate Limiting RATE_LIMIT_RPS=100 RATE_LIMIT_BURST=200 AUTH_RATE_LIMIT_RPS=5 AUTH_RATE_LIMIT_BURST=10 # Caching (Redis) REDIS_ADDR=localhost:6379 REDIS_DB=0 # Security MAX_AUTH_FAILURES=5 AUTH_FAILURE_WINDOW=15m IP_BLOCK_DURATION=1h # Logging LOG_LEVEL=debug # debug, info, warn, error LOG_FORMAT=json ``` ## API Structure ### Core Endpoints - **Health**: `/health`, `/ready` - **Authentication**: `/api/login`, `/api/verify`, `/api/renew` - **Applications**: `/api/applications` (CRUD operations) - **Tokens**: `/api/applications/{id}/tokens` (Static token management) - **Metrics**: `:9090/metrics` (Prometheus format, if enabled) ### Permission System Hierarchical permission scopes (parent permissions include child permissions): - `internal.*` - System operations (highest level) - `app.*` - Application management - `token.*` - Token operations - `repo.*` - Repository access (example domain) - `permission.*` - Permission management Example: `repo` permission includes `repo.read` and `repo.write`. ## Database Schema ### Key Tables - `applications` - Application definitions with HMAC keys - `static_tokens` - Static API tokens with prefixes - `available_permissions` - Permission catalog - `granted_permissions` - Token-permission relationships - `user_sessions` - User session tracking with JWT - `audit_events` - Comprehensive audit logging ### Migration System - Auto-runs on startup - Located in `/migrations/` - Uses `golang-migrate/migrate/v4` - Supports both up and down migrations ## Code Patterns & Architecture ### Backend Patterns - **Repository Pattern**: Data access via interfaces (`internal/repository/interfaces.go`) - **Dependency Injection**: Services receive dependencies via constructors - **Middleware Chain**: Security, auth, logging, rate limiting - **Structured Errors**: Custom error types with proper HTTP status codes - **Structured Logging**: Zap logger with JSON output - **Configuration Provider**: Interface-based config with validation - **Multiple Auth Providers**: Header, OAuth2, SAML support ### Frontend Patterns - **React 19** with TypeScript - **Ant Design 5.27+** component library - **Context API** for authentication state (`AuthContext.tsx`) - **Axios** for API communication with interceptors - **React Router 7+** for navigation - **Component Structure**: Organized by feature (Applications, Tokens, Users, Audit) ### Security Patterns - **HMAC Token Signing**: All tokens cryptographically signed - **JWT with Rotation**: User tokens with refresh capability - **Rate Limiting**: Per-endpoint and per-user limits - **CSRF Protection**: Token-based CSRF protection - **Audit Logging**: All operations logged with user attribution - **Input Validation**: Comprehensive validation at all layers ## Development Notes ### Critical Information - **Go Version**: Requires Go 1.23+ (currently using 1.24.4) - **Node Version**: Requires Node 24+ and npm 11+ - **Database**: Auto-migrations run on startup - **Container Names**: Use `kms-postgres`, `kms-api-service`, `kms-frontend`, `kms-nginx` - **Default Ports**: API:8080, Nginx:8081, Frontend:3000, DB:5432, Metrics:9090 - **Test Database**: `kms_test` (separate from `kms`) ### Important Files - `internal/config/config.go` - Complete configuration management - `docker-compose.yml` - Service definitions and environment variables - `test/e2e_test.sh` - Comprehensive curl-based E2E tests - `test/README.md` - Detailed testing guide - `docs/` - Technical documentation (Architecture, Security, API docs) ### Development Workflow 1. Always use `podman-compose` (not `docker-compose`) 2. Database operations via `podman exec` only 3. Required environment variables for local dev (HMAC, JWT, AUTH keys) 4. Run tests after changes: `go test -v ./test/...` 5. Use E2E tests to verify end-to-end functionality 6. Frontend dev server connects to containerized backend ### Security Considerations - Never commit secrets to repository - All tokens use HMAC signing with secure keys - Rate limiting prevents abuse - Comprehensive audit logging for compliance - Input validation at all layers - CORS and security headers properly configured