feat(secrets): make SMTP_PASSWORD Group-2-only (BUNYIP-529) #527

Merged
nrupard merged 2 commits from feat/BUNYIP-529-smtp-group2-only into main 2026-08-12 20:21:28 +02:00
Owner

Per David: SMTP_PASSWORD is sourced only from the Group-2 Infisical runtime fetch (or the email_config DB row), never a Group-1 file/sync secret. This removes it from every Group-1 site so Infisical is the sole runtime source.

Removed from Group-1 (completeness sweep: 11 sites / 5 files)

  • compose.yml: the smtp_password secret definition, the SMTP_PASSWORD_FILE env, and the service secrets-list entry; the email comment now points at Group-2.
  • scripts/sync-secrets.nu: the SECRET_MAP entry, and the self-test's empty-optional-key example (switched to FORGEJO_API_TOKEN).
  • scripts/init-secrets.nu: the dev-throwaway generator line.
  • .env.example: the SMTP_PASSWORD comment, the secret-files list, and the DEV-ONLY var list.
  • docs/secrets-infisical.md: the /bunyip/app table row, the dual-source note, and the source-precedence section (rewritten for Group-2-only).

Kept (correctly not Group-1)

The config.rs slot (secret_env("SMTP_PASSWORD"), which the Infisical fetch fills), the DB email_config precedence, the email_config.smtp_password at-rest column, and the Infisical fetch itself.

Validation

  • scripts/sync-secrets.nu --self-test: 16 checks pass (the SECRET_MAP now derives consistently from compose.yml; this self-test runs in CI's check.yml).
  • No Rust changed, so fmt/clippy/build are unaffected (CI runs them anyway).

Precedence now

DB email_config row > a stray plain SMTP_PASSWORD env (e.g. one left in a SOPS file) > Infisical fetch. With no DB row and no stray value, Infisical is the source.

Companion to DEV-581 (the c-01 SOPS SMTP_PASSWORD was already removed by the operator). Decision recorded in BUNYIP-529.

Per David: `SMTP_PASSWORD` is sourced only from the Group-2 Infisical runtime fetch (or the `email_config` DB row), never a Group-1 file/sync secret. This removes it from every Group-1 site so Infisical is the sole runtime source. ## Removed from Group-1 (completeness sweep: 11 sites / 5 files) - `compose.yml`: the `smtp_password` secret definition, the `SMTP_PASSWORD_FILE` env, and the service secrets-list entry; the email comment now points at Group-2. - `scripts/sync-secrets.nu`: the `SECRET_MAP` entry, and the self-test's empty-optional-key example (switched to `FORGEJO_API_TOKEN`). - `scripts/init-secrets.nu`: the dev-throwaway generator line. - `.env.example`: the `SMTP_PASSWORD` comment, the secret-files list, and the DEV-ONLY var list. - `docs/secrets-infisical.md`: the `/bunyip/app` table row, the dual-source note, and the source-precedence section (rewritten for Group-2-only). ## Kept (correctly not Group-1) The `config.rs` slot (`secret_env("SMTP_PASSWORD")`, which the Infisical fetch fills), the DB `email_config` precedence, the `email_config.smtp_password` at-rest column, and the Infisical fetch itself. ## Validation - `scripts/sync-secrets.nu --self-test`: 16 checks pass (the `SECRET_MAP` now derives consistently from `compose.yml`; this self-test runs in CI's `check.yml`). - No Rust changed, so fmt/clippy/build are unaffected (CI runs them anyway). ## Precedence now DB `email_config` row > a stray plain `SMTP_PASSWORD` env (e.g. one left in a SOPS file) > Infisical fetch. With no DB row and no stray value, Infisical is the source. Companion to DEV-581 (the c-01 SOPS `SMTP_PASSWORD` was already removed by the operator). Decision recorded in BUNYIP-529.
feat(secrets): make SMTP_PASSWORD Group-2-only (Infisical, not a file secret)
Some checks failed
E2E / PR gate (pull_request) Successful in 27s
Check / fmt + clippy + build + tests (pull_request) Has been cancelled
9a7e77a441
Per BUNYIP-529 (David's decision): SMTP_PASSWORD is sourced only from the Group-2 Infisical runtime fetch (or the email_config DB row), never a Group-1 file/sync secret. Remove it from every Group-1 site: the compose.yml secret definition, the SMTP_PASSWORD_FILE env, and the service secrets list; the sync-secrets.nu SECRET_MAP (and its self-test's empty-optional-key example, now FORGEJO_API_TOKEN); the init-secrets.nu dev generator; and the /bunyip/app table row, dual-source note, and precedence text in docs/secrets-infisical.md. Also update .env.example. The config slot (secret_env), the DB email_config path, and the Infisical fetch are unchanged.

sync-secrets.nu --self-test passes (16 checks).

#BUNYIP-529

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
docs(compose): note the Group-2 runtime fetch in the secrets header
All checks were successful
E2E / PR gate (pull_request) Successful in 27s
Check / fmt + clippy + build + tests (pull_request) Successful in 4m47s
Create release / Create release from merged PR (pull_request) Has been skipped
5f1d9cff91
The header claimed "nothing at runtime talks to a secrets manager", which the Group-2 Infisical fetch (SMTP) made false. Qualify it: Group-1 secrets are read only from /run/secrets/* (no runtime fetch), and Group-2 integration secrets (SMTP) are the exception the app fetches from Infisical at runtime, gracefully.

#BUNYIP-529

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
nrupard deleted branch feat/BUNYIP-529-smtp-group2-only 2026-08-12 20:21:29 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/bunyip!527
No description provided.