# missionMATCH Cleared Workforce Intelligence Platform for US government contractors. Go backend (mm-api), Vite and React frontend, PostgreSQL 16 with pgvector. The grounding doc `docs/STACK_DECISIONS.md` is the law; `CLAUDE.md` holds the hard rules (no Python, no dashes in written output, secrets server side only). ## Build The release build is FIPS validated (linux amd64): ``` make build # mm-api, the sync jobs, and provision-org, all GOFIPS140=v1.0.0 make test # unit suite, no database make ci-gates # the security gates: no X-Org-ID in the release binary, FIPS stamp present ``` Run with `GODEBUG=fips140=on` so the runtime uses the validated module that the build selected. ## Authentication and Accounts (Phase 2) The auth module (`internal/modules/auth`, primitives in `internal/platform/security`) issues opaque server side sessions and feeds the validated org into Postgres RLS, replacing the dev `X-Org-ID` header. Password hashing is PBKDF2 HMAC SHA 256 under the FIPS module; MFA is mandatory TOTP. See `CLAUDE.md` for the locked decisions and `docs/STACK_DECISIONS.md` section 7 for the rationale. ### Secrets All auth secrets load from the environment (on Bubbles, `/etc/missionmatch/api.env`, root owned 0600). Generate each with `openssl rand -base64 32`: ``` MM_CREDENTIAL_PEPPER MM_TOTP_KEK (exactly 32 bytes) MM_CSRF_KEY MM_RECOVERY_LOOKUP_KEY ``` Production also requires `MM_REQUIRE_FIPS=true`, `MM_ALLOW_DEV_HEADER_AUTH=false`, a government `MM_CLOUD`, and a real `MM_DATABASE_URL`; the server refuses to start otherwise. See `.env.example`. ### Bootstrap an organization Org creation is provisioning plus invites only (no public signup). The first org and owner are created by the migrator role: ``` make provision-org NAME="Galapagos Federal Systems" SLUG=galapagos \ EMAIL=owner@example.com OWNER="Owner Name" ``` It prints the org id, the owner user id, and a one time activation token. Delivery is manual at pilot: hand the owner the token, they redeem it at `POST /api/auth/invite/accept` with `{token, password}`, then enroll MFA. Additional users join the same way through `POST /api/users/invite` (an owner or admin, bounded to roles below their own). ### Integration tests The live suite runs against PG16 over Tailscale and is behind the `integration` build tag: ``` MM_APP_DSN=postgres://missionmatch_app:...@100.94.8.94:5432/missionmatch?sslmode=require \ MM_MIGRATOR_DSN=postgres://missionmatch_migrator:...@100.94.8.94:5432/missionmatch?sslmode=require \ make test-integration ``` Apply migrations first with `make migrate-up` (migrator DSN). `make test` excludes this suite. ## Release blocker The dev/pilot Postgres on M4 is NOT reboot durable (PGDATA lives on an external volume that macOS launchd cannot own). Credentials, MFA enrollments, and session state now live there, so a reboot would lock every user out with no recovery. Before this auth ships to any real pilot user, make the database reboot durable with scheduled backups and one tested restore.