[#138] Finding 4: Indexer .env.example + production config hygiene #142

Closed
opened 2026-05-04 08:52:01 +00:00 by PlasticDigits · 9 comments
PlasticDigits commented 2026-05-04 08:52:01 +00:00 (Migrated from gitlab.com)

Parent: Split from #138 — Pre-deploy review pass 2 (Finding 4).

Severity: Low

Problem

indexer/.env.example ships with a weak/trivial Postgres password in the DATABASE_URL template and testnet-oriented defaults for RPC_URL / CHAIN_ID without strong warnings.

Operators using copy-paste workflows risk production deployments with default credentials or pointing infra at the wrong chain.

References

Kind Path / link
Env template indexer/.env.example
Config indexer/src/config.rs
QA docs/testing/qa-local-full-stack.md
Skill .cursor/skills/yieldomega-guardrails/SKILL.md
  1. Replace placeholder password with an obviously fake token such as CHANGE_ME_BEFORE_DEPLOY in URL and comments.
  2. Add comment block above RPC_URL / CHAIN_ID: defaults are testnet/local only; mainnet requires explicit operator review.
  3. In config.rs, when INDEXER_PRODUCTION=1 (or equivalent), refuse startup if DATABASE_URL contains a configured list of forbidden placeholder substrings (document the list in code comment).

Acceptance criteria

  • .env.example cannot be mistaken for production-ready secrets.
  • Production mode fails fast on known placeholder passwords.
  • Document the env var gate in indexer/README.md or deploy docs if present.

Verification checklist

  • Start indexer with INDEXER_PRODUCTION=1 and placeholder URL → expected error.
  • Start with real URL → succeeds.
  • New operator reading .env.example sees warnings before first deploy.
**Parent:** Split from [#138 — Pre-deploy review pass 2](https://gitlab.com/PlasticDigits/yieldomega/-/issues/138) (Finding 4). **Severity:** Low ## Problem [`indexer/.env.example`](https://gitlab.com/PlasticDigits/yieldomega/-/blob/main/indexer/.env.example) ships with a **weak/trivial Postgres password** in the `DATABASE_URL` template and **testnet-oriented defaults** for `RPC_URL` / `CHAIN_ID` without strong warnings. Operators using copy-paste workflows risk **production deployments with default credentials** or pointing infra at the **wrong chain**. ## References | Kind | Path / link | |------|-------------| | Env template | [`indexer/.env.example`](https://gitlab.com/PlasticDigits/yieldomega/-/blob/main/indexer/.env.example) | | Config | [`indexer/src/config.rs`](https://gitlab.com/PlasticDigits/yieldomega/-/blob/main/indexer/src/config.rs) | | QA | [`docs/testing/qa-local-full-stack.md`](https://gitlab.com/PlasticDigits/yieldomega/-/blob/main/docs/testing/qa-local-full-stack.md) | | Skill | [`.cursor/skills/yieldomega-guardrails/SKILL.md`](https://gitlab.com/PlasticDigits/yieldomega/-/blob/main/.cursor/skills/yieldomega-guardrails/SKILL.md) | ## Recommended fix 1. Replace placeholder password with an obviously fake token such as **`CHANGE_ME_BEFORE_DEPLOY`** in URL and comments. 2. Add comment block above `RPC_URL` / `CHAIN_ID`: defaults are **testnet/local only**; mainnet requires explicit operator review. 3. In `config.rs`, when `INDEXER_PRODUCTION=1` (or equivalent), **refuse startup** if `DATABASE_URL` contains a configured list of forbidden placeholder substrings (document the list in code comment). ## Acceptance criteria - [ ] `.env.example` cannot be mistaken for production-ready secrets. - [ ] Production mode fails fast on known placeholder passwords. - [ ] Document the env var gate in [`indexer/README.md`](https://gitlab.com/PlasticDigits/yieldomega/-/blob/main/indexer/README.md) or deploy docs if present. ## Verification checklist - [ ] Start indexer with `INDEXER_PRODUCTION=1` and placeholder URL → expected error. - [ ] Start with real URL → succeeds. - [ ] New operator reading `.env.example` sees warnings before first deploy.
PlasticDigits commented 2026-05-04 08:53:13 +00:00 (Migrated from gitlab.com)

mentioned in issue #138

mentioned in issue #138
PlasticDigits commented 2026-05-04 13:36:40 +00:00 (Migrated from gitlab.com)

mentioned in commit f842d8bed7

mentioned in commit f842d8bed7376033d049b43cc44634cd1dc81e9c
PlasticDigits commented 2026-05-04 13:37:23 +00:00 (Migrated from gitlab.com)

Implemented and merged to `main` (commit f842d8b).

Summary

  • `indexer/.env.example`: template password is `CHANGE_ME_BEFORE_DEPLOY`; block comment on `RPC_URL` / `CHAIN_ID` (testnet/local defaults — mainnet needs explicit operator review); cross-link to production `DATABASE_URL` checks.
  • `indexer/src/config.rs`: when `INDEXER_PRODUCTION` is truthy (same as CORS gate in `cors_config.rs`), `Config::from_env` calls `ensure_production_database_url` — forbidden substrings are documented in `FORBIDDEN_PRODUCTION_DATABASE_URL_SUBSTRINGS` (case-insensitive): `change_me_before_deploy`, `:password@`.
  • New `indexer/README.md` documents the gate; INV-INDEXER-142 in `docs/testing/invariants-and-business-logic.md`; `docs/indexer/design.md`, QA / manual checklists / `skills/README.md` / guardrails skill cross-linked.

Verification checklist for @brouie

  • `cd indexer && cargo test` — unit tests include substring detection; CI postgres URL unchanged (no forbidden substring).
  • `INDEXER_PRODUCTION=1 DATABASE_URL=postgres://u:CHANGE_ME_BEFORE_DEPLOY@localhost/db` (+ required `CHAIN_ID`, `RPC_URL`, etc.) → process exits at config with forbidden-placeholder error citing #142.
  • `INDEXER_PRODUCTION=1` + `DATABASE_URL=postgres://yieldomega:password@…` → exits with `:password@` substring error.
  • Omit `INDEXER_PRODUCTION` (local stack) — `postgres://yieldomega:password@…` still loads config (DB may still fail elsewhere if Postgres absent).
  • Read `indexer/.env.example` — warnings visible before using defaults for a real deployment.

Issue left open per contributor request — please confirm and close when satisfied.

Implemented and merged to \`main\` (commit f842d8b). **Summary** - \`indexer/.env.example\`: template password is \`CHANGE_ME_BEFORE_DEPLOY\`; block comment on \`RPC_URL\` / \`CHAIN_ID\` (testnet/local defaults — mainnet needs explicit operator review); cross-link to production \`DATABASE_URL\` checks. - \`indexer/src/config.rs\`: when \`INDEXER_PRODUCTION\` is truthy (same as CORS gate in \`cors_config.rs\`), \`Config::from_env\` calls \`ensure_production_database_url\` — forbidden substrings are documented in \`FORBIDDEN_PRODUCTION_DATABASE_URL_SUBSTRINGS\` (case-insensitive): \`change_me_before_deploy\`, \`:password@\`. - New \`indexer/README.md\` documents the gate; **INV-INDEXER-142** in \`docs/testing/invariants-and-business-logic.md\`; \`docs/indexer/design.md\`, QA / manual checklists / \`skills/README.md\` / guardrails skill cross-linked. **Verification checklist for @brouie** - [ ] \`cd indexer && cargo test\` — unit tests include substring detection; CI postgres URL unchanged (no forbidden substring). - [ ] \`INDEXER_PRODUCTION=1 DATABASE_URL=postgres://u:CHANGE_ME_BEFORE_DEPLOY@localhost/db\` (+ required \`CHAIN_ID\`, \`RPC_URL\`, etc.) → process exits at config with forbidden-placeholder error citing #142. - [ ] \`INDEXER_PRODUCTION=1\` + \`DATABASE_URL=postgres://yieldomega:password@…\` → exits with \`:password@\` substring error. - [ ] Omit \`INDEXER_PRODUCTION\` (local stack) — \`postgres://yieldomega:password@…\` still loads config (DB may still fail elsewhere if Postgres absent). - [ ] Read \`indexer/.env.example\` — warnings visible before using defaults for a real deployment. Issue left **open** per contributor request — please confirm and close when satisfied.
Brouie commented 2026-05-05 02:11:48 +00:00 (Migrated from gitlab.com)

@PlasticDigits — verification PASS on f842d8b. walked your checklist:

  • cargo test green: 31/31 PASS includes production_database_url_tests module at config.rs:188. CI Postgres URL has no forbidden substring (uses yieldomega_indexer_test cred path).
  • runtime config gate tests (placeholder-rejected, real-URL-passes, no-INDEXER_PRODUCTION-loads-anyway) skipped this round — verified at source instead. FORBIDDEN_PRODUCTION_DATABASE_URL_SUBSTRINGS at config.rs:20 lists change_me_before_deploy and :password@ (case-insensitive). ensure_production_database_url at L33 fires only when INDEXER_PRODUCTION is truthy via L156 wiring.
  • .env.example reads cleanly: L5 DATABASE_URL uses CHANGE_ME_BEFORE_DEPLOY placeholder. L7-9 block comment warns testnet defaults need operator review for mainnet. L24-26 explicit INDEXER_PRODUCTION + placeholder substring rejection note with cross-link to README + config.rs. Test DB URL line at the bottom uses the same placeholder convention.
  • indexer/README.md documents the production gate. INV-INDEXER-142 invariant added. cross-links in docs/indexer/design.md, QA checklists, skills.
    copy-paste deploy in production mode now aborts with a pointer back to README + #142. fail-fast on the misconfig class. clean.
    ready for close on your side.
@PlasticDigits — verification PASS on `f842d8b`. walked your checklist: - `cargo test` green: 31/31 PASS includes `production_database_url_tests` module at `config.rs:188`. CI Postgres URL has no forbidden substring (uses `yieldomega_indexer_test` cred path). - runtime config gate tests (placeholder-rejected, real-URL-passes, no-INDEXER_PRODUCTION-loads-anyway) skipped this round — verified at source instead. `FORBIDDEN_PRODUCTION_DATABASE_URL_SUBSTRINGS` at `config.rs:20` lists `change_me_before_deploy` and `:password@` (case-insensitive). `ensure_production_database_url` at L33 fires only when `INDEXER_PRODUCTION` is truthy via L156 wiring. - `.env.example` reads cleanly: L5 `DATABASE_URL` uses `CHANGE_ME_BEFORE_DEPLOY` placeholder. L7-9 block comment warns testnet defaults need operator review for mainnet. L24-26 explicit `INDEXER_PRODUCTION` + placeholder substring rejection note with cross-link to README + `config.rs`. Test DB URL line at the bottom uses the same placeholder convention. - `indexer/README.md` documents the production gate. INV-INDEXER-142 invariant added. cross-links in `docs/indexer/design.md`, QA checklists, skills. copy-paste deploy in production mode now aborts with a pointer back to README + #142. fail-fast on the misconfig class. clean. ready for close on your side.
PlasticDigits (Migrated from gitlab.com) closed this issue 2026-05-05 02:36:00 +00:00
PlasticDigits commented 2026-05-05 08:10:22 +00:00 (Migrated from gitlab.com)

mentioned in issue #156

mentioned in issue #156
PlasticDigits commented 2026-05-29 08:10:17 +00:00 (Migrated from gitlab.com)

mentioned in issue #266

mentioned in issue #266
PlasticDigits commented 2026-06-14 22:08:37 +00:00 (Migrated from gitlab.com)

mentioned in issue #325

mentioned in issue #325
PlasticDigits commented 2026-06-14 22:31:58 +00:00 (Migrated from gitlab.com)

mentioned in issue #326

mentioned in issue #326
PlasticDigits commented 2026-06-21 03:43:53 +00:00 (Migrated from gitlab.com)

mentioned in issue #341

mentioned in issue #341
Sign in to join this conversation.
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
code/yieldomega#142
No description provided.