Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

README.md

infra

CDK v2 (TypeScript) app for OpenJobRadar's data plane, control plane, and first API route. See ADR-0021 (data plane: single tenant table vs. one-per-entity, the due-work GSI's date-bucketing), ADR-0022 (control plane: Cognito user pool, PKCE client, MFA posture), and ADR-0024 (GET /me: HTTP API + Cognito JWT authorizer, no-Docker-bundling constraint) for the design decisions — and why no AWS account ID ever appears in this source tree.

What's here

  • bin/app.ts — entry point, instantiates all three stacks in dependency order (data plane → control plane → API, since the API stack needs constructs from both). Resolves envName (dev/stage/prod) from CDK context (-c envName=...) or OPENJOBRADAR_ENV, defaulting to dev; fails closed on anything else. Account/region come only from CDK_DEFAULT_ACCOUNT/ CDK_DEFAULT_REGION — never a literal. Cognito Hosted UI callback/logout URLs come from OPENJOBRADAR_CALLBACK_URLS / OPENJOBRADAR_LOGOUT_URLS (comma-separated); dev alone gets a localhost default, stage/prod must set both explicitly or synth fails closed.
  • lib/env.ts — the shared EnvName type every stack uses.
  • lib/data-plane-stack.ts (TenantTable + DueWorkTable), lib/control-plane-stack.ts (Cognito user pool + Hosted UI domain + app client), lib/api-stack.ts (HTTP API + Cognito JWT authorizer + one Lambda, GET /me) — one file per construct, independently documented.
  • src/openjobradar/lambda_handlers/ (Python side, not here) — thin Lambda entry points. Code.fromAsset zips src/ verbatim with no dependency-install step, which only works because these handlers stay dependency-light (boto3 only — see ADR-0024's consequences for what adding a handler that needs PyYAML/jsonschema would require).
  • test/ — Jest + aws-cdk-lib/assertions unit tests against the synthesized CloudFormation templates (key schemas, GSI shape, encryption/PITR, password policy, MFA config, JWT authorizer wiring, IAM grant shape, CORS per environment, removal policy per environment, and a direct check that no 12-digit AWS account ID ever appears in synthesized output).

Commands

npm ci                    # install (uses the committed package-lock.json)
npm run build              # tsc typecheck (noEmit)
npm test                   # jest
npm run synth               # cdk synth — no AWS credentials required (environment-agnostic)
npx cdk synth -c envName=prod   # synth a specific environment

npm run synth / npx cdk synth never touch AWS by themselves; only cdk deploy does, and that needs real credentials for whichever of the three accounts (ADR-0010) you're targeting. Verified locally with AWS credentials fully unset (env -u AWS_PROFILE ..., a fresh HOME) — synth still succeeds and no account ID leaks into the template — which is exactly the credential-free environment CI's infra job runs in.

What's not here yet

No SES, no KMS CMK for the credentials vault (ADR-0007), no DueWorkIndex/Dispatcher compute (EventBridge, SQS lanes) — only one Lambda-backed route exists (GET /me). IAM for that route is table-scoped, not yet entity-scoped (tracked open in ADR-0024's consequences and docs/THREAT-MODEL.md).