ThatAIguyA world of ideas

THE CONSCIOUSNESS ATLAS
Read. Experiment. Follow the evidence.

ConsciousnessLearn · Explore · Joseph Anady

Janady13/missionmatch / docs/CREDENTIAL_CONSUMERS.md

Source identity, revision, and recovered contents.

GitHub sourceSource text recovered

Source identity

FieldRecorded value
Source typeGitHub source
Original recordJanady13/missionmatch / docs/CREDENTIAL_CONSUMERS.md
DateNot specified in source
RepositoryJanady13/missionmatch
Revision720d47fae476b0d38477ae4401697d372b1ea2bc
Branchfeature/opportunity-to-outcome
Path or archive memberdocs/CREDENTIAL_CONSUMERS.md
Original SHA-256a78ae5f787cfcae12b4b9253a8f38365fc2ad74c969841b9fe7057feb8729c12
Git blob SHAd49fdafbfd8db192574fb422c4549ab7dcf2aa9e
Reading-copy SHA-256a78ae5f787cfcae12b4b9253a8f38365fc2ad74c969841b9fe7057feb8729c12

Original source ↗

Recovered source transcript

# CREDENTIAL CONSUMERS: THE COMPLETE INVENTORY Created 29 July 2026 from incident D6. **References only. No values, ever.** ## Why this file exists The D5 rotation was planned against a list of five consumers, held in memory. Two more existed and were found only by breaking: - the second API node keeps its **own** `MM_DATABASE_URL` in its **own** api.env, so it crashed on restart after the control plane rotation - `mm-identity-sync.sh` hardcodes **two** DSNs in **two different clusters**, so a blanket substitution would have written the control plane password into the tenant line A rotation enumerated from memory is a rotation that will miss something. From now on **every rotation enumerates from this file**, and any consumer discovered outside it is a defect in this file to be fixed in the same change. ## The clusters, because this is what caused D6 There are **three separate PostgreSQL clusters**, and roles are **cluster scoped** while databases are not. Two databases sharing a cluster share its roles. CLUSTER 1 M4 100.94.8.94:5432 databases: missionmatch (PRODUCTION TENANT), missionmatch_staging THESE TWO SHARE A ROLE NAMESPACE. That is what made a staging rehearsal change a production credential. CLUSTER 2 megamind-agi-wsl 100.77.114.40:5433 database: missionmatch (CONTROL PLANE, authoritative identity) CLUSTER 3 none other in service ## The roles CLUSTER 1, M4 missionmatch_migrator PRODUCTION TENANT only, from 29 Jul missionmatch_staging_migrator STAGING only. Created 29 Jul as the D6 structural fix. CONNECT on missionmatch is REVOKED, proven by refusal. missionmatch_app production tenant application role missionmatch_compliance eeo schema, NOBYPASSRLS CLUSTER 2, control plane missionmatch_app missionmatch_migrator missionmatch_compliance missionmatch_aioe ## THE CONSUMERS, every one ### Bubbles, 100.90.97.104 | file | variable | role | cluster | |---|---|---|---| | `/etc/missionmatch/api.env` | `MM_DATABASE_URL` | app | 2, control plane | | `/etc/missionmatch/api.env` | `MM_MIGRATOR_DATABASE_URL` | migrator | 1, tenant | | `/etc/missionmatch/api.env` | `MM_TENANT_DSN_TENANT_ACME` | app | 1, tenant | | `/etc/missionmatch/api.env` | `MM_TENANT_DSN_TENANT_ACME_COMPLIANCE` | compliance | 1, tenant | | `/etc/missionmatch/api.env` | `MM_COMPLIANCE_DATABASE_URL` | compliance | 1, tenant | | `/etc/missionmatch/staging.env` | `MM_MIGRATOR_DATABASE_URL` | **staging_migrator** | 1, staging | | `/etc/missionmatch/staging.env` | `MM_DATABASE_URL` | app | 1, staging | | `/etc/missionmatch/staging.env` | `MM_COMPLIANCE_DATABASE_URL` | compliance | 1, staging | | `/etc/missionmatch/backup.dsn` | bare DSN | migrator | 1, tenant | | `/etc/missionmatch/sam-sync.env` | `MM_MIGRATOR_DATABASE_URL` | migrator | 1, tenant | | `/etc/missionmatch/sam-sync.env` | `MM_COMPLIANCE_DATABASE_URL` | compliance | 1, tenant | | `/etc/mm-alert.env` | `SMTP_PASS` | Gmail app password | n/a | **The two `sam-sync.env` rows were added 29 July 2026 from finding D7**, where they were discovered by breaking rather than by reading, which is the same way the last two missing consumers were found. That file feeds THREE units, `mm-sam-sync`, `mm-awards-sync` and `mm-rates-sync`, so one stale line there stops three jobs at once and each one reports the same authentication failure, which reads like three problems and is one. It also carries `SAM_API_KEY`, `DATA_GOV_API_KEY`, `PDL_API_KEY`, `BLS_API_KEY`, `KAGGLE_KEY`, `HF_TOKEN` and `ONET_API_KEY`, so it is a secrets file in its own right and not only a DSN holder. **`backup.dsn` was already listed here and was still missed by the D5 rotation.** A complete inventory is necessary and not sufficient: the rotation has to actually enumerate from it. That is why step 1 of the procedure below says read this file, and it is now the step that failed rather than a step that was absent. ### megamind-agi WSL, 100.77.114.40 | file | variable | role | cluster | |---|---|---|---| | `/etc/missionmatch/api.env` | `MM_DATABASE_URL` | app | 2, control plane | | `/etc/missionmatch/db.env` | `MM_DATABASE_URL` | app | 2 | | `/etc/missionmatch/db.env` | `MM_MIGRATOR_DATABASE_URL` | migrator | 2 | | `/etc/missionmatch/db.env` | `MM_COMPLIANCE_DATABASE_URL` | compliance | 2 | | `/etc/missionmatch/db.env` | `MM_AIOE_DATABASE_URL` | aioe | 2 | | `/etc/missionmatch/backup.dsn` | bare DSN | migrator | 2 | | `/etc/missionmatch/db.env` | `MM_TENANT_MIGRATOR_DSN_TENANT_ACME` | migrator | **1, tenant** | | `/etc/mm-alert.env` | `SMTP_PASS` | Gmail app password | n/a | **The trap that used to be here is gone, and it took two months to find.** Until 29 July 2026 `mm-identity-sync.sh` carried both DSNs INLINE, on two adjacent lines, one per cluster. This file described it as a trap and left it standing: a `sed` across the file would write the wrong password into one of them and the failure would surface hours later as a failed sync rather than immediately. It was never rewritten because nothing could see it. The out of repo secret sweep found both values on its first clean run, and the script now resolves `MM_MIGRATOR_DATABASE_URL` and `MM_TENANT_MIGRATOR_DSN_TENANT_ACME` from `db.env`, failing by NAME if either key is absent. The two DSN rows above are now env file rows like every other consumer, so the rotation procedure reaches them by enumeration instead of by memory. **The same change took both credentials out of `argv`.** The old script passed each DSN to `psql` and to `sync-tenant-identity` as a command line flag, and `argv` is world readable through `ps`, so any account on that host could read both migrator passwords out of the process table for as long as a run lasted. Measured before and after: one exposure visible during a run of the old script, zero during the repaired one. A flag is a weaker hiding place than an environment variable, not a stronger one. ### Ops scripts, added 29 July 2026 from finding D10 **This section exists because two of the five broken consumers lived here and this file did not mention scripts at all.** An inventory that covers env files and not the scripts beside them is not an inventory, and the repository secret sweep cannot see any of these paths because they are not in the repository. | file | how it gets its credential | role | cluster | |---|---|---|---| | `/usr/local/sbin/mm-db-backup.sh` (Bubbles) | reads `/etc/missionmatch/backup.dsn` | migrator | 1, tenant | | `/usr/local/sbin/mm-db-backup.sh` (Bubbles) | ssh key auth to VALKYRIE, root's own key | n/a | n/a | | `/usr/local/sbin/mm-restore-drill.sh` (Bubbles) | reads `api.env` **since 29 Jul** | migrator | 1, tenant | | `/usr/local/sbin/mm-identity-sync.sh` (megamind-agi) | reads `db.env` **since 29 Jul**, two keys, no argv | migrator | **1 and 2** | | `/usr/local/sbin/mm-disk-watch.sh` (Bubbles) | none, calls `mm-alert.sh` | n/a | n/a | | `/usr/local/sbin/mm-alert.sh` (Bubbles and megamind-agi) | reads `/etc/mm-alert.env` | Gmail app password | n/a | | `/usr/local/sbin/mm-watch.sh` (Bubbles) | none, HTTP probes only | n/a | n/a | | `/usr/local/sbin/mm-offsite-watch.sh` (megamind-agi) | none, HTTP probes only | n/a | n/a | **`mm-restore-drill.sh` HARDCODED A PLAINTEXT MIGRATOR PASSWORD until 29 July.** It was therefore a consumer no inventory listed, invisible to the repository sweep, and the D5 rotation left it holding a dead value. The consequence was that the one instrument whose entire purpose is to prove a backup can be restored could not run at all. It now reads `MM_MIGRATOR_DATABASE_URL` from `api.env` and refuses to start if it is absent, so it follows every future rotation without anyone remembering it exists. **The rule that follows: a script is a consumer.** When adding an ops script that touches a database, add a row here in the same change. And prefer reading an env file to embedding a value, because a consumer that reads the store follows a rotation for free while a consumer that embeds one has to be found. ### Application accounts, not database roles | where | what | |---|---| | control plane `users` table | operator, tenant superusers, recruiters | | staging `users` table | `patriciacox6@aol.com`, `desk.admin@fg-talent.test` | | staging `users` table, Gate C fixtures | `gatec.recruiter@fg-talent.test`, `gatec.manager@fg-talent.test` | Rotate these with `cmd/rotate-credential`, which goes through the real pepper and PBKDF2 path rather than reimplementing the KDF. ### Other secrets in the env files `MM_CREDENTIAL_PEPPER`, `MM_TOTP_KEK`, `MM_CSRF_KEY`, `MM_RECOVERY_LOOKUP_KEY`, `MM_MEGAMIND_TOKEN`, and the OpenAI key in the M4 secrets file. The first two are **versioned** and rotate without a flag day; the rest do not, which is recorded in the risk register rather than pretended away. ## The rotation procedure 1. Read this file. Do not enumerate from memory. 2. Confirm the cluster for every consumer. A password is only valid in its own. 3. Take a fresh backup of the affected cluster. 4. **Update every consumer FIRST**, while the old credential still works. 5. `ALTER ROLE` **last**. The moment it commits, consumers already carrying the new value simply start working, and there is no window where nothing connects. 6. Restart anything that reads its DSN at boot. Both API nodes do. 7. Prove every consumer **by role name and status code**, never by printing a DSN. 8. Prove an **authenticated login**, which is the only thing that exercises control plane identity resolution end to end. 9. If a consumer was found that is not in this file, **add it in the same change**. 10. **Enumerate the ops scripts too**, not only the env files. Two of the five consumers broken by the D5 rotation were scripts, and one of them held a plaintext password that the repository secret sweep can never see because the file is not in the repository.

Search equations, builds, manuscript text, and recovered sources.