Skip to content

Authentication & Authorization #198

@jmgilman

Description

@jmgilman

Authentication & Authorization

Overview

Implement comprehensive authentication and authorization system using Keycloak for JWT token validation and Role-Based Access Control (RBAC) with domain-based permission patterns for certificate issuance.

Objective

Create a secure authentication layer that validates JWT tokens from Keycloak, implements RBAC policies for certificate operations, and enforces domain-based permissions using glob patterns to control which certificates users can request.

Tasks

JWT Validation Setup

  • Implement JWT validator in internal/auth/keycloak.go
  • Configure JWT validation parameters:
    type JWTConfig struct {
      IssuerURL          string        // For issuer validation
      ClientID           string        // For audience validation
      JWKSEndpoint       string        // JWKS URL
      JWKSCacheDuration  time.Duration // 5 minutes as per spec
    }
  • Implement JWKS (JSON Web Key Set) fetching:
    • Fetch JWKS from Keycloak JWKS endpoint on startup
    • Cache JWKS in memory with 5-minute TTL
    • Implement automatic refresh when cache expires
    • Handle JWKS rotation gracefully
  • Implement local JWT token validation:
    • Verify token signature against cached JWKS
    • Validate token expiration
    • Verify issuer matches expected Keycloak realm
    • Verify audience/client ID
    • All validation done locally without Keycloak calls
  • Extract user identity and claims from validated tokens
  • Handle JWKS fetch failures with graceful degradation

JWT Token Validation Middleware

  • Create JWT validation middleware in internal/api/middleware/auth.go
  • Implement Gin middleware for authentication:
    func JWTAuthMiddleware(validator *JWTValidator) gin.HandlerFunc
  • Extract Bearer token from Authorization header
  • Validate token locally using cached JWKS
  • Extract and store user context in Gin context:
    • User ID/username
    • Roles
    • Permissions
    • Token claims
  • Return appropriate error responses:
    • 401 Unauthorized for missing/invalid tokens (use error schema from 07 Security & Validation)
    • 403 Forbidden for insufficient permissions (use error schema from 07 Security & Validation)
  • Log authentication failures for security monitoring

RBAC Implementation

  • Implement RBAC system in internal/auth/rbac.go
  • Define permission model as specified:
    • cert:issue:client - Can issue client certificates
    • cert:issue:server - Can issue server certificates
    • cert:issue:<domain-pattern> - Domain-restricted issuance
  • Create permission extraction from JWT token claims
  • Implement permission checking functions:
    func HasPermission(ctx context.Context, permission string) bool
    func CanIssueCertificate(ctx context.Context, profile string, domains []string) bool
  • Map Keycloak roles to certificate permissions
  • Cache permission evaluations for request duration

Domain Permission Validation

  • Implement domain validation logic using glob patterns
  • Support patterns like:
    • *.example.com - Wildcard subdomain
    • api.*.example.com - Specific wildcard pattern
    • example.com - Exact domain match
  • Validate all SAN entries against user permissions
  • Implement validation function:
    func ValidateDomainPermissions(permissions []string, requestedDomains []string) error
  • Deny requests if any SAN entry is not authorized
  • Return detailed error messages for authorization failures
  • Support both DNS names and IP addresses in SANs

RBAC Middleware

  • Create RBAC middleware in internal/api/middleware/rbac.go
  • Implement Gin middleware for authorization:
    func RequirePermission(permission string) gin.HandlerFunc
    func RequireCertificatePermission(profile string) gin.HandlerFunc
  • Check permissions based on endpoint requirements
  • Validate domain permissions for certificate issuance requests
  • Log authorization failures for security monitoring
  • Include detailed reasons in authorization failure responses

GORM Models for Auth

  • Use the AuditEvent model and storage responsibilities defined in 05 Database Layer

Security Audit Logging

  • Implement audit logging for authentication events
  • Log authentication failures with:
    • Timestamp
    • Actor identity (if available)
    • IP address
    • Failure reason
    • Request details
  • Log authorization failures with:
    • Requested resource
    • Required permissions
    • User's actual permissions
    • Denied domains (if applicable)
  • Store audit logs in audit.events table as defined in 05 Database Layer
  • Ensure PII is properly handled in logs

Health Check Integration

  • Implement JWKS availability check for health endpoint per 06 Monitoring & Observability
  • Verify JWKS cache is populated and not expired
  • Use for readiness probe to ensure auth system is operational per 06 Monitoring & Observability

Acceptance Criteria

  • JWT tokens from Keycloak successfully validated
  • JWKS cached with 5-minute TTL
  • Token expiration and signature validation working
  • RBAC permissions correctly extracted from tokens
  • Domain permissions enforced using glob patterns
  • All SAN entries validated against permissions
  • Authentication failures return 401 status
  • Authorization failures return 403 status
  • Audit events logged to database
  • Security metrics tracked for authentication failures

Technical Considerations

  • Use standard JWT libraries for token validation
  • All JWT validation performed locally after JWKS is cached
  • Implement proper error handling for JWKS fetch failures
  • Use context for passing authentication information
  • Ensure constant-time comparison for security-sensitive operations
  • JWKS only fetched from Keycloak when cache expires (5-minute TTL)
  • Use prepared statements with GORM to prevent SQL injection

Dependencies

  • JWT and JOSE libraries:
    • github.com/golang-jwt/jwt/v5
    • github.com/square/go-jose/v3 (for JWKS)
  • HTTP client for Keycloak communication
  • GORM models from issue feat: adds cuetools package #1
  • Gin middleware support

Testing Requirements

  • Unit tests for JWT token validation
  • Unit tests for RBAC permission checks
  • Unit tests for domain glob pattern matching
  • Integration tests with mock JWKS endpoint
  • Test various token scenarios:
    • Valid tokens
    • Expired tokens
    • Invalid signatures
    • Missing required claims
  • Test permission scenarios:
    • Sufficient permissions
    • Insufficient permissions
    • Domain pattern matching edge cases
  • Test JWKS caching behavior
  • Test audit logging for all event types

Definition of Done

  • Code reviewed and approved
  • All tests passing
  • Successfully validates Keycloak JWT tokens
  • RBAC policies enforced correctly
  • Domain permissions working with glob patterns
  • Audit logging functional
  • Security review completed
  • No sensitive data exposed in logs

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions