Skip to content

Restrict runtime file permissions at startup and fix the service unit template (SEC 2/27) - #247

Merged
alfwro13 merged 1 commit into
mainfrom
sec-2-prod-file-modes
Oct 11, 2026
Merged

alfwro13 merged 1 commit into
mainfrom
sec-2-prod-file-modes

Conversation

@alfwro13

@alfwro13 alfwro13 commented Oct 11, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • New utils.harden_runtime_permissions() runs first in the main.py lifespan: project dir 0700, .env and config.json 0600, group/other write bits cleared under data/ and models/ (symlinks skipped, idempotent, unchangeable paths reported in one warning).
  • config.json is now created 0600 on first boot and for the atomic temp file in update_config_atomic (config._open_private), independent of umask. .env already keeps/creates 0600 through python-dotenv >= 1.2.2 (covered by a test).
  • README service template: drops Group=www-data, adds UMask=0077; short File permissions note; assets/system_architecture.md section 7.
  • Test client fixtures patch main.harden_runtime_permissions so the suite never chmods the checkout.

Not shipped by this PR (prod ops, after deploy + restart)

  1. Edit /etc/systemd/system/stock_analysis_project.service: remove Group=www-data, add UMask=0077, then sudo systemctl daemon-reload and restart.
  2. Rotate every .env secret (APP_SECRET_KEY, API key with the Home Assistant update at the same time, embed and confirm tokens, SMTP, Nextcloud, FRED, Hugging Face, dashboard password). Rotate only after the first restart on this code, so the new values are written into an already-private .env.

Test plan

  • pytest tests/test_05_config_and_utils.py tests/test_06_auth.py tests/test_rss_feed.py (175 passed)
  • CI full suite
  • After deploy on prod: stat -c '%a %U:%G %n' . .env config.json data models data/analysis.db shows 700, 600, 600 and no group/other write bit

… template (SEC 2/27)

On every start the app sets the project dir to 0700, .env and config.json to 0600 and clears group/other write bits under data/ and models/. config.json is created 0600 even under a loose umask. README unit template drops Group=www-data and adds UMask=0077.
@alfwro13
alfwro13 merged commit bdd488a into main Oct 11, 2026
5 checks passed
@alfwro13
alfwro13 deleted the sec-2-prod-file-modes branch October 11, 2026 16:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant