Secure by default uplift #511

Merged
alexkenley merged 1 commit from codex/secure-by-default-uplift into main 2026-06-01 15:30:08 +02:00
alexkenley commented 2026-06-01 15:13:08 +02:00 (Migrated from github.com)

Summary

  • bind the Docker Compose web UI to 127.0.0.1 by default via APP_BIND, while keeping explicit APP_BIND=0.0.0.0 opt-in for LAN/reverse-proxy deployments
  • update README and .env.example so Docker and native quickstarts follow the same loopback-first security posture
  • encrypt generic API integration keys at rest with the existing Fernet-backed src.secret_storage, migrate legacy plaintext keys on load, and keep API responses masked
  • route scheduled Miniflux integration reads through the integration loader so encrypted keys still work outside the settings UI
  • add regression coverage for default bind behavior and integration-key encryption/migration

Why

The README already tells users to treat Odysseus like an admin console and prefer loopback binds, but the recommended Docker path published the app on all host interfaces by default. Generic API integrations also kept bearer/header/basic credentials plaintext in data/integrations.json, despite the app already having encrypted secret storage for similar credentials.

Validation

  • python -m compileall src\\integrations.py routes\\auth_routes.py src\\task_scheduler.py
  • venv\\Scripts\\python.exe -m pytest tests/test_security_regressions.py -k "docker_compose_binds_web_ui_to_loopback_by_default or readme_native_quickstart_uses_loopback or integrations_api_keys_are_encrypted_at_rest or integrations_plaintext_keys_migrate_on_load"
  • venv\\Scripts\\python.exe -m pytest tests/test_security_regressions.py
  • venv\\Scripts\\python.exe -m pytest tests/test_review_regressions.py
  • docker compose config confirms Odysseus now publishes host_ip: 127.0.0.1

Full-suite note: venv\\Scripts\\python.exe -m pytest currently reports 350 passed, 1 skipped, 6 failed on this Windows checkout. The failures appear unrelated to this patch: cookbook POSIX path expectations, mocked Apple Silicon backend expectation, Node ESM import of S:/... without file://, and an existing task-scheduler mock serialization case.

I checked the open PR list. I did not see a direct duplicate for Docker APP_BIND defaults or generic API integration key encryption. PR #450 goes the opposite direction for macOS LAN accessibility; this PR keeps LAN access available as an explicit opt-in. PR #236 covers optional SOPS-encrypted env secrets and looks complementary rather than overlapping with runtime integration-key storage.

## Summary - bind the Docker Compose web UI to `127.0.0.1` by default via `APP_BIND`, while keeping explicit `APP_BIND=0.0.0.0` opt-in for LAN/reverse-proxy deployments - update README and `.env.example` so Docker and native quickstarts follow the same loopback-first security posture - encrypt generic API integration keys at rest with the existing Fernet-backed `src.secret_storage`, migrate legacy plaintext keys on load, and keep API responses masked - route scheduled Miniflux integration reads through the integration loader so encrypted keys still work outside the settings UI - add regression coverage for default bind behavior and integration-key encryption/migration ## Why The README already tells users to treat Odysseus like an admin console and prefer loopback binds, but the recommended Docker path published the app on all host interfaces by default. Generic API integrations also kept bearer/header/basic credentials plaintext in `data/integrations.json`, despite the app already having encrypted secret storage for similar credentials. ## Validation - `python -m compileall src\\integrations.py routes\\auth_routes.py src\\task_scheduler.py` - `venv\\Scripts\\python.exe -m pytest tests/test_security_regressions.py -k "docker_compose_binds_web_ui_to_loopback_by_default or readme_native_quickstart_uses_loopback or integrations_api_keys_are_encrypted_at_rest or integrations_plaintext_keys_migrate_on_load"` - `venv\\Scripts\\python.exe -m pytest tests/test_security_regressions.py` - `venv\\Scripts\\python.exe -m pytest tests/test_review_regressions.py` - `docker compose config` confirms Odysseus now publishes `host_ip: 127.0.0.1` Full-suite note: `venv\\Scripts\\python.exe -m pytest` currently reports 350 passed, 1 skipped, 6 failed on this Windows checkout. The failures appear unrelated to this patch: cookbook POSIX path expectations, mocked Apple Silicon backend expectation, Node ESM import of `S:/...` without `file://`, and an existing task-scheduler mock serialization case. ## Related PR check I checked the open PR list. I did not see a direct duplicate for Docker `APP_BIND` defaults or generic API integration key encryption. PR #450 goes the opposite direction for macOS LAN accessibility; this PR keeps LAN access available as an explicit opt-in. PR #236 covers optional SOPS-encrypted env secrets and looks complementary rather than overlapping with runtime integration-key storage.
Sign in to join this conversation.
No description provided.