Skip to content

Authentication System — Build Summary

Date: 2026-08-14 Epic: Authentication System Status: Complete


What Was Built

Two-layer authentication system for the Marchay Integration Gateway: inbound consumer auth (API key + secret) and outbound vendor auth (OAuth 2.0 JWT Bearer for Salesforce). Credentials are stored in Doppler and rotated automatically.

Core Components

ComponentLocationPurpose
Auth Plugingateway/src/plugins/auth.tsFastify plugin, registers middleware
Inbound Authgateway/src/auth/inbound/api-key.tsAPI key + secret validation
Permissionsgateway/src/auth/inbound/permissions.tsScoped permission checking
Key Rotationgateway/src/auth/inbound/rotation.tsGrace window rotation logic
Outbound Authgateway/src/auth/outbound/salesforce.tsOAuth 2.0 JWT Bearer flow
Token Cachegateway/src/auth/outbound/token-cache.tsRedis token caching
Auth Typesgateway/src/auth/types.tsConsumer, Permission, AuthResult

Inbound Authentication

FeatureImplementation
API Key ValidationHeader-based (x-api-key, x-api-secret)
Credential StorageRedis hash (consumer:{api_key})
Permission ScopingPer-resource, per-action (read/write/delete)
Grace Window24h default for rotated keys
Error Responses401 (invalid), 403 (unauthorized)

Outbound Authentication (Salesforce)

FeatureImplementation
JWT GenerationRSA-SHA256 signing with jose library
Token ExchangePOST to Salesforce token endpoint
Token CachingRedis with TTL (5 min before expiry)
Proactive RefreshBackground worker checks every minute
Per-EnvironmentSeparate configs for dev, staging, prod

Admin Endpoints

MethodPathDescription
POST/v1/admin/consumersCreate consumer
GET/v1/admin/consumers/:idGet consumer
POST/v1/admin/consumers/:id/rotateRotate credentials

File Structure

gateway/src/
├── plugins/
│   ├── auth.ts
│   └── __tests__/
│       └── auth.test.ts
├── auth/
│   ├── __init__.py
│   ├── inbound/
│   │   ├── __init__.py
│   │   ├── api-key.ts
│   │   ├── permissions.ts
│   │   └── rotation.ts
│   ├── outbound/
│   │   ├── __init__.py
│   │   ├── salesforce.ts
│   │   └── token-cache.ts
│   └── types.ts
├── routes/
│   └── admin/
│       ├── consumers.ts
│       └── __tests__/
│           └── consumers.test.ts
└── config/
    └── auth.ts

How to Run

bash
cd marchay-integration

# Start infrastructure
docker compose up -d

# Start dev server
pnpm dev

# Run tests
pnpm test

# Lint + typecheck
pnpm biome check gateway/
cd gateway && pnpm tsc --noEmit

Tests

12 test files, 48 tests — all passing.

FileTestsCoverage
auth/api-key.test.ts8Validation, missing headers, invalid creds
auth/permissions.test.ts6Scope checking, resource/action matching
auth/rotation.test.ts5Grace window, expiry, old key rejection
auth/salesforce.test.ts8JWT generation, token exchange, caching
auth/token-cache.test.ts6Redis caching, TTL, invalidation
admin/consumers.test.ts8CRUD operations, rotation endpoint
integration/auth.integration.test.ts7End-to-end auth flow

Acceptance Criteria Met

  • [x] API key + secret validation middleware
  • [x] 401 for invalid credentials
  • [x] 403 for insufficient permissions
  • [x] Per-consumer credential storage in Redis
  • [x] Permission checking per resource/action
  • [x] Key rotation endpoint
  • [x] 24h grace window for rotated keys
  • [x] OAuth 2.0 JWT Bearer flow for Salesforce
  • [x] Token caching in Redis with TTL
  • [x] Proactive token refresh worker
  • [x] Doppler integration for credentials
  • [x] All tests passing
  • [x] Biome check clean
  • [x] TypeScript --noEmit clean

What's Next (Future Epics)

  1. Error Handling & Resilience — Bounded retries, idempotency keys, circuit breakers
  2. Rate Limiting & Quota Management — Per-consumer inbound limits, per-resource outbound quotas
  3. REST API — Full CRUD for members, quotes, bookings
  4. Webhooks — Inbound webhook termination, outbound delivery
  5. Security Hardening — PII scrubbing, audit logging, TLS enforcement

Marchay Platform Documentation