This project implements a broker and interceptor to protect third-party secrets and enforce policy on protected outbound calls.
See docs/threat-model.md for the full threat model and invariants.
See docs/admin-auth.md for the admin authentication model and audit requirements.
See docs/credential-type-extension-playbook.md for the contract-first playbook for adding new secret material and runtime auth types.
- Completed an additional storage-focused review against:
docs/development/engineering-process.mddocs/development/data-storage-postgres-redis-rules.md
- Result: no direct N+1 query pattern found in repository implementations (no await-in-loop data fetch pattern).
- Follow-up risks identified:
TemplateRepository.listLatestTemplatesByTenantcurrently fetches all active versions and deduplicates in memory.- Several tenant-scoped list queries sort by
createdAtwithout composite(tenant_id, created_at)indexes.
- Node.js 20+
- pnpm 9+
- Docker and Docker Compose
-
Install dependencies:
pnpm install
-
Start infrastructure (PostgreSQL + Redis + migrations):
pnpm infra:up
This starts PostgreSQL/Redis and applies Prisma migrations.
-
Build all packages:
pnpm build
-
Start the services:
Terminal 1 - broker-admin-api (control plane):
cd apps/broker-admin-api pnpm devTerminal 2 - broker-api (data plane):
cd apps/broker-api pnpm dev
Run both APIs as Docker services (plus postgres/redis):
pnpm infra:up:apps
pnpm infra:smokeOptional profiles:
- Include management tools:
pnpm infra:up:apps:tools
- Include local Vault dev:
pnpm infra:up:apps:vault
| Command | Description |
|---|---|
pnpm infra:up |
Start PostgreSQL + Redis and run migrations |
pnpm infra:up:tools |
Also starts pgAdmin and Redis Commander |
pnpm infra:up:apps |
Start PostgreSQL + Redis + both API containers |
pnpm infra:up:apps:tools |
Start full stack plus pgAdmin and Redis Commander |
pnpm infra:up:apps:vault |
Start full stack plus local Vault dev service |
pnpm infra:smoke |
Validate broker-admin-api and broker-api health endpoints |
pnpm infra:down |
Stop containers (preserves data) |
pnpm infra:down:volumes |
Stop containers and delete all data |
pnpm infra:prod:config |
Validate production compose env/config |
pnpm infra:prod:config:example |
Validate production compose with .env.production.example |
pnpm infra:prod:up |
Start production compose stack (requires production env) |
pnpm infra:prod:down |
Stop production compose stack |
pnpm docker:build:broker-admin-api |
Build production image for control-plane API |
pnpm docker:build:broker-api |
Build production image for data-plane API |
pnpm db:migrate |
Run pending migrations |
pnpm db:migrate:dev |
Create new migration during development |
pnpm db:studio |
Open Prisma Studio for database inspection |
pnpm backup:build |
Build the backup workload package |
pnpm backup:run |
Create an encrypted, versioned S3 backup through broker |
pnpm backup:restore |
Restore a selected S3 backup through broker |
Default Docker Compose configuration:
| Service | URL | Credentials |
|---|---|---|
| PostgreSQL | postgresql://broker:broker@127.0.0.1:5432/broker |
broker / broker |
| Redis | redis://:broker@127.0.0.1:6379 |
password: broker |
broker-admin-api (--apps) |
http://localhost:8080/healthz |
static auth in .env |
broker-api (--apps) |
https://localhost:8081/healthz |
mTLS/session flows |
| pgAdmin (with --tools) | http://localhost:5050 |
admin@broker.local / admin |
| Redis Commander (with --tools) | http://localhost:8082 |
- |
Vault dev (with --vault) |
http://localhost:8200 |
token: dev-root-token (default) |
Copy .env.example to .env and adjust as needed:
cp .env.example .envFor production compose, use:
cp .env.production.example .env.productionKey environment variables:
shared local infrastructure:
BROKER_POSTGRES_USER,BROKER_POSTGRES_PASSWORD,BROKER_POSTGRES_DBBROKER_POSTGRES_PORT,BROKER_REDIS_PORT,BROKER_REDIS_PASSWORD
broker-admin-api (port 8080):
BROKER_ADMIN_API_INFRA_ENABLED=trueBROKER_ADMIN_API_DATABASE_URL=postgresql://broker:broker@127.0.0.1:5432/brokerBROKER_ADMIN_API_REDIS_URL=redis://:broker@127.0.0.1:6379BROKER_ADMIN_API_SECRET_KEY_B64=<32-byte-base64>
broker-api (port 8081):
BROKER_API_INFRA_ENABLED=trueBROKER_API_DATABASE_URL=postgresql://broker:broker@127.0.0.1:5432/brokerBROKER_API_REDIS_URL=redis://:broker@127.0.0.1:6379BROKER_API_SECRET_KEY_B64=<same key as admin API>
Docker app-profile defaults (container network):
BROKER_ADMIN_API_DATABASE_URL_DOCKER=postgresql://broker:broker@postgres:5432/brokerBROKER_ADMIN_API_REDIS_URL_DOCKER=redis://:broker@redis:6379BROKER_API_DATABASE_URL_DOCKER=postgresql://broker:broker@postgres:5432/brokerBROKER_API_REDIS_URL_DOCKER=redis://:broker@redis:6379infra:smokeuses TLS verification + client cert by default (apps/broker-api/certs/healthcheck-client.*).
- CI now validates both code quality and compose orchestration:
.github/workflows/ci.ymlruns lint/typecheck/test/build, validates production compose config, and runs a container smoke test.
- Production container images are defined in:
apps/broker-admin-api/Dockerfileapps/broker-api/Dockerfile
- Production compose template:
docker-compose.production.yml
- For production runtime, set strict env values at minimum:
NODE_ENV=production- Admin API:
BROKER_ADMIN_API_SECRET_KEY_B64, OIDC or hardened static auth, vault config if vault mode is enabled - Broker API:
BROKER_API_SECRET_KEY_B64,BROKER_API_STATE_PATHorBROKER_API_INITIAL_STATE_JSON - Both APIs: externalized
*_DATABASE_URLand*_REDIS_URL
- The dedicated workload lives in
packages/backup-workload. - It uploads encrypted backups to S3 through normal broker workload execution, not direct AWS credentials in the workload.
- Backup ids are date-stamped and versioned as
v000001-YYYYMMDDTHHMMSSZ. - The bundle includes:
- PostgreSQL dump
- broker-admin local CA material when local issuer mode is used
- broker-api TLS certificate directory when configured
- shared secret keys required to decrypt broker-managed secrets after restore
- The S3 integration template must declare path-group
constraints.upstream_auth.type=aws_sigv4. - The S3 template must also allow bucket-root list operations used for version discovery.
- Restore is intentionally gated by
BACKUP_WORKLOAD_RESTORE_CONFIRM=RESTORE.
See packages/backup-workload/README.md for setup details and the example S3 template.
broker-interceptor/
├── apps/
│ ├── broker-admin-api/ # Control plane API (port 8080)
│ ├── broker-api/ # Data plane API (port 8081)
│ └── admin-web/ # Admin UI (React)
├── packages/
│ ├── db/ # Prisma schema + repositories
│ ├── schemas/ # OpenAPI/Zod schemas
│ ├── auth/ # Authentication utilities
│ ├── crypto/ # Cryptographic operations
│ ├── policy-engine/ # Policy evaluation
│ └── ... # Other shared packages
├── docker-compose.yml # Local/CI compose stack with profiles
└── scripts/ # Infra lifecycle and smoke scripts