security: deploy hardening (fail-closed bind, secret-backup ignores, deps)#95
Merged
Conversation
- HIGH #1/#2: refuse to bind a non-loopback host with auth disabled (serve() guard + --allow-insecure / PLUTUS_ALLOW_INSECURE opt-in). Stops docker compose up / serve --host 0.0.0.0 from publishing an open billing console; the demo image sets --allow-insecure since its data is disposable. Covers the auth default-off AND fail-off-on-misconfig cases. - MED #9: .gitignore/.dockerignore matched only *.plutus-bak-*; the real backups are config.yaml.bak-<ts> (file-sourced secrets) -> now config.yaml* + *.bak-*. - MED #11: dependency upper bounds (stripe<14, reportlab<5, PyYAML<7, pytest<10). - LOW #15: alerts.require_tls (opt-in) fails closed if TLS can't be established. - LOW #16: Dockerfile runs as a non-root user. - LOW #17: PyYAML is a hard requirement at server start (no silent config degrade). - #10: docs/deploy-hardening.md — safe-deploy checklist for operators. 268 tests pass (+5 guard tests). Addresses the deploy-posture findings from the 2026-07-05 security review. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Deploy hardening — HIGH #1/#2 + MED #9/#11 + LOW #15/#16/#17 (2026-07-05 review)
Closes the deploy-posture findings — the class most likely to bite an internal rollout.
non-loopback host with auth disabled (
serve()guard). This covers both theDocker/compose
serve --demo --host 0.0.0.0default and the authoff-by-default / fail-off-on-misconfig cases that could publish an open billing
console. Escape hatch:
--allow-insecure/PLUTUS_ALLOW_INSECURE=1for atrusted network; the disposable demo image opts in explicitly so quick-try
still works. Production (
serve --host 0.0.0.0, no flag) now errors out unlessauth is configured.
matched only
*.plutus-bak-*, but real backups areconfig.yaml.bak-<ts>→added
config.yaml*+*.bak-*to.gitignoreand.dockerignore.stripe<14,reportlab<5,PyYAML<7,pytest<10) for reproducible builds.alerts.require_tls(opt-in) refuses to send over an unencryptedlink. Standalone OSS positioning — launch post, comparison, awesome-list #16 (LOW) Docker image runs as non-root. Feature: Budget exhaustion forecast #17 (LOW) PyYAML is a hard
requirement at server start (no silent config-parser degrade).
docs/deploy-hardening.md— operator safe-config checklist.Tests
268 pass (
pytest tests/ -q), +5 intest_deploy_guard.py(refuses public+auth-off;allows loopback / auth-on / explicit opt-in). Verified via CLI:
serve --host 0.0.0.0exits with a clear "refusing to serve" error;--allow-insecureand127.0.0.1start normally. Only config/Docker/CI files + the startup guard changed.