Skip to main content

Security Overview

GospeLib follows a defense-in-depth strategy with multiple independent security layers. A failure in any single layer does not grant an attacker unrestricted access to user data or platform resources. Within the gateway perimeter, the architecture adopts a zero-trust posture: every request carries verified identity claims, every route enforces entitlement checks, and every data store is unreachable from the public internet.

Security Model

The security architecture is organized into three concentric layers:

┌─────────────────────────────────────────────────────┐
│ Network Boundary │
│ TLS termination, CORS allowlist, no public data │
│ endpoints │
│ ┌───────────────────────────────────────────────┐ │
│ │ Identity & Access │ │
│ │ Clerk JWT validation, X-User-Id injection, │ │
│ │ webhook signature verification │ │
│ │ ┌─────────────────────────────────────────┐ │ │
│ │ │ Authorization & Entitlements │ │ │
│ │ │ Plan-gated routes, per-tier rate │ │ │
│ │ │ limits, O(1) Redis entitlement checks │ │ │
│ │ └─────────────────────────────────────────┘ │ │
│ └───────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────┘

Outermost layer -- Network Boundary. The API gateway is the sole public endpoint. All backend services and data stores (PostgreSQL, FalkorDB, Redis) have no public endpoints. TLS 1.3 encrypts all external traffic; Phase 3 adds mTLS for inter-service communication.

Middle layer -- Identity & Access. Every request to the gateway must carry a valid Clerk JWT. The gateway validates the JWT signature against cached JWKS keys, extracts user claims, and injects trusted headers (X-User-Id, X-User-Plan) before forwarding to downstream services. Downstream services trust these headers because they are unreachable outside the gateway.

Innermost layer -- Authorization & Entitlements. Gateway middleware gates each route by the required entitlement (e.g., ai_features, interlinear_hebrew_greek). Entitlements are cached in Redis with O(1) lookup per request, avoiding hot-path calls to the billing service. Rate limits are enforced per plan tier.

Security Layers in Detail

Authentication Flow

Covers the full authentication lifecycle: Clerk OAuth sign-in, JWT issuance (15-minute access tokens, 30-day refresh tokens), gateway JWKS validation, header injection, and Clerk webhook sync that keeps the PostgreSQL gl_users table current. The auth service is a thin Go wrapper around Clerk, designed so that swapping the auth provider later changes only the wrapper -- nothing downstream.

Entitlements & Authorization

Defines the three plan tiers (Reader/Scholar/Academic), maps features to entitlements, and documents how the gateway enforces access control. The billing service pushes entitlement data to Redis; the gateway performs a single GET per request to check access. Stripe webhook integration handles subscription changes with idempotent event processing.

Secrets & Network Policy

Describes secret management (AWS Secrets Manager in Phase 1, External Secrets Operator in Phase 2, HashiCorp Vault in Phase 3), environment variable naming conventions, network topology, CORS policy, webhook signature verification for both Clerk and Stripe, data encryption at rest and in transit, PII redaction in logs, and GitHub Actions OIDC authentication.

Key Invariants

These properties hold across all phases of the platform:

InvariantEnforcement
No secret in git, ever.env.example has placeholders; .env.local is git-ignored
Gateway is the only public endpointNetwork policy; data stores have no public DNS
Every API request has a verified identityJWT validation middleware on all non-public routes
Entitlement checks are O(1)Redis cache with 60-second TTL, refreshed by billing service
Webhooks are signature-verifiedClerk and Stripe SDKs verify HMAC signatures before processing
Webhook processing is idempotentEvent IDs checked against gl_stripe_events / dedup tables
PII never appears in logsStructured logging middleware redacts sensitive fields

Phase Progression

Security capabilities evolve across deployment phases:

CapabilityPhase 1Phase 2Phase 3
AuthenticationClerk SaaSClerk SaaS (paid tier)Option: custom auth behind wrapper
Secret storageAWS Secrets Manager+ External Secrets Operator+ HashiCorp Vault (dynamic credentials)
Network encryptionTLS 1.3 (external)TLS 1.3 (external)+ mTLS (inter-service)
Encryption at restAWS managed keysAWS managed keysCustomer-managed keys (CMK)

Threat Model Summary

ThreatMitigation
Stolen JWT15-minute expiry; refresh tokens in secure storage (Keychain/SecureStore); sessions revocable via Clerk
Forged webhookHMAC signature verification on every Clerk and Stripe webhook
Replay attack on webhookIdempotency keys prevent duplicate processing
Unauthorized feature accessGateway entitlement middleware returns 403 before reaching downstream services
Credential leak in CIGitHub Actions uses OIDC (no long-lived AWS credentials); secrets are per-environment
Internal service impersonationServices only accept requests with gateway-injected headers; not publicly routable
Data exfiltrationData stores have no public endpoints; GDPR export/deletion endpoints for user self-service