Files
skybridge/CLAUDE.md
2025-08-26 19:15:37 -04:00

15 KiB

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

# 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

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

# Start all services (PostgreSQL, API, Nginx, Frontend)
podman-compose up -d

# Start with SSO testing enabled (Keycloak + SAML IdP)
podman-compose -f docker-compose.yml -f docker-compose.sso.yml 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
podman-compose logs -f keycloak
podman-compose logs -f saml-idp

# Stop services  
podman-compose down

# Stop SSO services
podman-compose -f docker-compose.yml -f docker-compose.sso.yml 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

# 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

# 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

# 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

# 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)
  • Port 8090: Keycloak SSO server (admin console)
  • Port 8091: SimpleSAMLphp IdP (SAML console: /simplesaml)
  • Port 8443: SimpleSAMLphp IdP (HTTPS)

The service provides different test user contexts:

  • Regular user: test@example.com
  • Admin user: admin@example.com
  • Limited user: limited@example.com

SSO Testing Users

For SSO testing with Keycloak or SAML IdP, use these credentials:

Email Password Permissions Provider
admin@example.com admin123 internal.* Keycloak
test@example.com test123 app.read, token.read Keycloak
limited@example.com limited123 repo.read Keycloak
user1@example.com user1pass Basic access SAML IdP
user2@example.com user2pass Basic access SAML IdP

SSO Access Points

Key Configuration

Required Environment Variables

# Security (REQUIRED - minimum 32 characters each)
INTERNAL_HMAC_KEY=<secure-hmac-key-32-chars-min>
JWT_SECRET=<secure-jwt-secret-32-chars-min>
AUTH_SIGNING_KEY=<secure-auth-key-32-chars-min>

# 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  # 'header', 'sso', or 'saml'
AUTH_HEADER_USER_EMAIL=X-User-Email

# SSO / OAuth2 Configuration (for Keycloak)
OAUTH2_ENABLED=false  # Set to true for OAuth2/OIDC auth
OAUTH2_PROVIDER_URL=http://keycloak:8080/realms/kms
OAUTH2_CLIENT_ID=kms-api
OAUTH2_CLIENT_SECRET=kms-client-secret
OAUTH2_REDIRECT_URL=http://localhost:8081/api/oauth2/callback

# SAML Configuration (for SimpleSAMLphp)
SAML_ENABLED=false  # Set to true for SAML auth
SAML_IDP_SSO_URL=http://saml-idp:8080/simplesaml/saml2/idp/SSOService.php
SAML_IDP_METADATA_URL=http://saml-idp:8080/simplesaml/saml2/idp/metadata.php
SAML_SP_ENTITY_ID=http://localhost:8081
SAML_SP_ACS_URL=http://localhost:8081/api/saml/acs
SAML_SP_SLS_URL=http://localhost:8081/api/saml/sls

# Features
RATE_LIMIT_ENABLED=true
CACHE_ENABLED=false  # Set to true to enable Redis
METRICS_ENABLED=true

Optional Configuration

# 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)
  • Audit: /api/audit/events, /api/audit/events/:id, /api/audit/stats (Audit log 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 with fields:
    • id, type, severity, status, timestamp
    • actor_id, actor_type, actor_ip, user_agent
    • resource_id, resource_type, action, description
    • details (JSON), request_id, session_id

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)
  • Audit Integration: Real-time audit log viewing with filtering, statistics, and timeline views

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

Audit System Architecture

  • Handler: internal/handlers/audit.go - HTTP endpoints for audit data
  • Logger: internal/audit/audit.go - Core audit logging functionality
  • Repository: internal/repository/postgres/audit_repository.go - Data persistence
  • Frontend: kms-frontend/src/components/Audit.tsx - Real-time audit viewing
  • API Service: kms-frontend/src/services/apiService.ts - Frontend-backend integration
  • Event Types: Hierarchical (e.g., auth.login, app.created, token.validated)
  • Filtering: Support for date ranges, event types, statuses, users, resource types
  • Statistics: Aggregated metrics by type, severity, status, and time

SSO Testing Workflow

Quick Start - OAuth2/OIDC Testing (Keycloak)

# 1. Start services with SSO enabled
podman-compose -f docker-compose.yml -f docker-compose.sso.yml up -d

# 2. Wait for Keycloak to start (check logs)
podman-compose logs -f keycloak

# 3. Test OAuth2 login flow
curl -v "http://localhost:8090/realms/kms/protocol/openid-connect/auth?client_id=kms-api&response_type=code&redirect_uri=http://localhost:8081/api/oauth2/callback"

# 4. Access Keycloak admin console
open http://localhost:8090
# Login with: admin / admin

# 5. Test API with OAuth2 token
# (Use Keycloak to get access token, then use in Authorization: Bearer header)

Quick Start - SAML Testing (SimpleSAMLphp)

# 1. Services should already be running from previous step

# 2. Access SAML IdP admin console  
open http://localhost:8091/simplesaml
# Login with: admin / secret

# 3. View IdP metadata
curl http://localhost:8091/simplesaml/saml2/idp/metadata.php

# 4. Test SAML authentication flow
# Navigate to your app and it should redirect to SAML IdP for auth

Environment Switching

# Switch to OAuth2 mode
podman exec kms-api-service sh -c "export AUTH_PROVIDER=sso OAUTH2_ENABLED=true && supervisorctl restart all"

# Switch to SAML mode  
podman exec kms-api-service sh -c "export AUTH_PROVIDER=sso SAML_ENABLED=true && supervisorctl restart all"

# Switch back to header mode
podman exec kms-api-service sh -c "export AUTH_PROVIDER=header && supervisorctl restart all"

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, kms-keycloak, kms-saml-idp
  • Default Ports: API:8080, Nginx:8081, Frontend:3000, DB:5432, Metrics:9090, Keycloak:8090, SAML:8091
  • Test Database: kms_test (separate from kms)
  • SSO Config: Located in sso-config/ directory

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

Build & Deployment Notes

  • Cache Issues: When code changes don't appear, use podman-compose build --no-cache
  • Route Registration: New API routes require full rebuild to appear in Gin debug logs
  • Error Handlers: Use HandleInternalError, HandleValidationError, HandleAuthenticationError
  • API Integration: Frontend components should use real API calls, not mock data
  • Field Mapping: Ensure frontend matches backend field names (e.g., actor_id vs user_id)

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