Vault environment coverage snapshot
Generated: 2026-05-12 (static reference — live vault read required to refresh)
Vault path prefix: /MooseQuest/
Environments: prod, staging, dev
Script: scripts/vault/audit_coverage.py
Status: Reference snapshot — derived from taxonomy doc (docs/ops/vault-token-taxonomy.md Section 3) pending first live run with INFISICAL_CLIENT_ID / INFISICAL_CLIENT_SECRET / INFISICAL_PROJECT_ID configured.
To generate a live snapshot:
bash python3 scripts/vault/audit_coverage.py \ --output docs/ops/2026-05-12-vault-coverage-snapshot.mdSeedocs/ops/runbooks/vault-coverage-audit.mdfor full setup and re-run procedure.Scope note: This audit covers secrets stored in Infisical only. AWS-resident workload secrets (SSM Parameter Store) are not in scope — per
feedback_aws_workloads_use_ssm_not_vault.md, those secrets are managed separately in AWS and are never written to Infisical.
Summary
| Metric | Count |
|---|---|
| Credential secrets tracked (excl. companions) | 23 |
Companion secrets (__EXPIRES_AT, __CLIENT_ID, __SCOPES) |
estimated 10–15 |
| Secrets with expected env drift (by design) | 16 |
| Secrets that must be present in all active envs | 4 |
| Prod-only (account-wide, intentional) | 16 |
| Staging-only (anomaly — would require investigation) | 0 expected |
| Dev-only (Stripe test-mode) | 1 |
Expected coverage matrix (credential secrets)
Derived from docs/ops/vault-token-taxonomy.md Section 3.
Cell value: expected presence per env (yes = must exist, — = intentionally absent, ? = unresolved — needs live audit).
| Secret | Prod | Staging | Dev | Drift? | Notes |
|---|---|---|---|---|---|
CF_ACCESS_MGMT |
yes | — | — | by design | Account-wide CF Access mgmt token; no staging equivalent |
CF_ACCESS_SVC_CONSOLE |
yes | yes | — | expected | Separate CF Access service token per env (different Access apps) |
CF_ACCESS_SVC_VAULT |
yes | yes | — | expected | Separate CF Access service token per env |
CF_DNS_EDIT_GETRAXX_COM |
yes | — | — | by design | One CF account; staging CI reads prod path |
CF_DNS_EDIT_RAXX_APP |
yes | — | — | by design | Same |
CF_PAGES_DEPLOY |
yes | — | — | by design | CF Pages project is single; envs are CF Pages envs, not Infisical envs |
CF_WAF_EDIT_RAXX_APP |
? | — | — | — | Token flagged missing in #747; provisioning pending |
HEROKU_API_KEY |
yes | yes | — | expected | Separate Heroku OAuth token per app (prod/staging are separate Heroku apps) |
HEROKU_PLATFORM_API_TOKEN |
yes | yes | — | expected | Same — confirm whether duplicate of HEROKU_API_KEY (open Q in taxonomy §7) |
ALPACA_PAPER_API_KEY_ID |
yes | yes | — | expected | Separate Alpaca paper keys per env |
ALPACA_PAPER_API_SECRET_KEY |
yes | yes | — | expected | Paired with above |
ALPACA_LIVE_API_KEY_ID |
yes | — | — | by design | Never in staging — real-money key |
ALPACA_LIVE_API_SECRET_KEY |
yes | — | — | by design | Paired with above |
POSTMARK_SERVER_TOKEN |
yes | yes | — | expected | Separate Postmark server per env to prevent staging sending real email |
STRIPE_RESTRICTED_KEY |
yes | — | yes | expected | Prod: live restricted key; dev: Stripe test-mode key |
ANTHROPIC_API_KEY |
yes | — | — | by design | One Anthropic account; staging + dev share prod key |
AWS_ACCESS_KEY_ID |
yes | — | — | by design | Single IAM user (claude-infisical-bootstrap); not replicated |
AWS_SECRET_ACCESS_KEY |
yes | — | — | by design | Paired with above |
GITHUB_API_READONLY_TOKEN |
yes | — | — | by design | One GitHub org |
GOOGLE_WORKSPACE_SA_KEY_JSON |
yes | — | — | by design | One Google Workspace org |
INFISICAL_SERVICE_TOKEN |
yes | — | — | by design | Dispatcher reads only prod secrets |
SLACK_BOT_TOKEN |
yes | — | — | by design | One Slack workspace |
BOT_USER_SLACK_TRADING_MASTER_API |
yes | — | — | by design | Same workspace |
DREAMHOST_API_KEY |
yes | — | — | by design | Single DreamHost account |
DYN_PASSWORD |
yes | — | — | by design | Oracle Dyn; stays (see feedback_dyndns_stays.md) |
GitHub App bot paths (/MooseQuest/raxx-*-bot/)
Each bot path holds APP_ID, INSTALLATION_ID, PRIVATE_KEY_PEM.
| Bot path | Prod | Staging | Dev | Notes |
|---|---|---|---|---|
/MooseQuest/raxx-dev-bot/ |
yes | — | — | One GitHub App installation |
/MooseQuest/raxx-ops-bot/ |
yes | — | — | Same |
/MooseQuest/raxx-pm-bot/ |
yes | — | — | Same |
Drift items requiring review
The following secrets are expected to have env-specific values but their
staging presence has not been confirmed by a live vault read. A live run of
audit_coverage.py will confirm presence or surface the gap:
| Secret | Expected | Risk if missing from staging |
|---|---|---|
CF_ACCESS_SVC_CONSOLE |
prod + staging | Staging console cannot pass CF Access gate → 403 on all staging console requests |
CF_ACCESS_SVC_VAULT |
prod + staging | Vault probe from staging agent fails → rotation pipeline cannot reach vault from staging |
HEROKU_API_KEY |
prod + staging | CI staging deploys fail (no Heroku token to push slug) |
HEROKU_PLATFORM_API_TOKEN |
prod + staging | Same |
ALPACA_PAPER_API_KEY_ID |
prod + staging | Staging Raptor cannot connect to Alpaca paper trading → 401 on all trade calls |
ALPACA_PAPER_API_SECRET_KEY |
prod + staging | Paired with above |
POSTMARK_SERVER_TOKEN |
prod + staging | Staging email flows use prod server → staging test emails go to real inboxes |
STRIPE_RESTRICTED_KEY (dev) |
dev | Stripe billing tests in dev hit live API → test charges to real account |
Open questions from taxonomy §7
These unresolved questions affect the coverage picture and should be answered before the Phase 2 rename migration:
-
Are
HEROKU_API_KEYandHEROKU_PLATFORM_API_TOKENthe same physical token stored under two names, or two distinct OAuth authorizations? If the same, one should be deprecated — the staging coverage gap is effectively one secret, not two. -
CF_WAF_EDIT_RAXX_APPis flagged as_(missing)_in the taxonomy (tracked in #747). Until it is provisioned, there is a WAF edit gap in prod. This audit cannot confirm its Infisical presence until the live script is run. -
Should
ALPACA_LIVE_API_KEY_ID/ALPACA_LIVE_API_SECRET_KEYbe stored in vault pre-launch? Taxonomy §7 Q5 recommends yes (rotation cadence enforcement). A live audit will confirm whether they are already seeded.
Next steps
-
Run
audit_coverage.pywith live credentials to replace this reference snapshot with real data:bash python3 scripts/vault/audit_coverage.py \ --output docs/ops/2026-05-12-vault-coverage-snapshot.md -
For each secret flagged as "drift" in the live output that is not marked "by design" in the taxonomy, open a
type:reliabilityissue to provision the missing env entry. -
For each staging-env gap in the "expected" list above, verify and provision per the remediation steps in
docs/ops/runbooks/vault-coverage-audit.md. -
Re-run the audit monthly (or after any vault provisioning change) and commit the updated snapshot to
docs/ops/.