Security¶
Security profiles¶
The ODPM_SECURITY_PROFILE / --security-profile axis sets posture (passwords and publish binds), separate from ODPM_SCENARIO (topology / workflow).
| Profile | Scenario default | New user_settings / secrets |
Published ports |
|---|---|---|---|
convenience |
developer |
manager=1, admin user=admin (unchanged) |
no forced 127.0.0.1 |
hardened |
server |
random in .odpm/secrets.json; settings use ${@secret:odpm.db_manager_password} and ${@secret:odpm.db_default_admin_password} |
Postgres and all published → 127.0.0.1 |
Override: CLI --security-profile wins over env ODPM_SECURITY_PROFILE, else scenario default.
ci: Odoo password secret bootstrap is off; port binds stay scenario-owned (postgres on localhost, not all published), even if override is hardened.
Source of truth for Odoo passwords is user_settings.json after expand (${VAR} / ${@secret:} across the whole file). odpm never rewrites an existing settings file. On hardened, if password fields in raw settings are plaintext / empty / not ${@secret:…} — WARNING (file unchanged).
New hardened projects: if .odpm/secrets.json is missing, odpm creates odpm.db_manager_password and odpm.db_default_admin_password (token_urlsafe, 0600).
An existing Odoo database does not pick up a new admin password automatically — use --set-admin-pass with -d.
See ADR-023, local secrets, user-settings.
Passwords in configuration¶
| Setting | Purpose |
|---|---|
db_manager_password in user_settings.json |
Odoo database manager password (admin_passwd) |
db_default_admin_login / db_default_admin_password |
Administrator account when creating a DB / --set-admin-pass |
| PostgreSQL credentials | Injected into service config and compose (shared POSTGRES_ODOO_PASS for now) |
On a laptop (convenience), template defaults are fine. On a server (hardened), prefer secrets + refs.
Secrets and git¶
Do not commit passwords, API tokens, or private keys. Project .env is usually not committed. Prefer user_settings.json without real secrets in git (on hardened — ${@secret:…} refs).
Module secrets (API keys, integration tokens)¶
Use .odpm/secrets.json (gitignored). odpm mounts a normalized copy at /run/odpm/secrets.json (developer and server).
- Commit only
.odpm/secrets.example.jsonwithREPLACE_MEstubs. - After import, odpm sets source mode
0600. - Do not log
/run/odpm/secrets.jsonvalues or duplicate them into composeenvironment:.
Details: local secrets.
--secrets-file imports JSON v1 into .odpm/secrets.json early in bootstrap (before full user_settings ${@secret:} expand).
server scenario and internet exposure¶
Default profile hardened: localhost-only ports, passwords via secrets.
- Terminate HTTPS at a reverse proxy.
- Enable
proxy_modeinodoo.conf; usedbfilterwhen hosting multiple DBs. - Do not widen published ports to
0.0.0.0in compose by hand. - App role
odoois NOSUPERUSER; admin rolepostgresis still required for ensure-role. Admin and app still sharePOSTGRES_ODOO_PASStoday. - Firewall: expose SSH and the HTTPS proxy only.
- Do not use
dev_modeon an internet-facing instance; it is ignored inserver. - Debugger port is not needed on the server.
Local development¶
Default profile convenience: simple passwords and open ports for local tools. To try a production-like layout: ODPM_SECURITY_PROFILE=hardened or --security-profile hardened without changing scenario.