Security overview
The product runs as root on your server and holds the Docker socket, which is equivalent to root on the host. Everything below follows from that: whoever controls the console, the management API, the agent or a shell on the host controls every instance on it.
What the server stores, and where
| What | Where | How it is protected |
|---|---|---|
| Users, instances, jobs, schedules, the audit trail, the license register and the policy half of the configuration | The master database: PostgreSQL in the ohm-postgres container, on the loopback only, or your own SQL Server | Console passwords are stored as hashes. Every stored credential - the console accounts' authenticator secrets, the SMTP password, backup storage keys, git tokens, the outbound proxy's password, the GeoIP account - is encrypted under the API's key ring |
| The API's key ring, and the console's | The Docker volumes ohm-api-keys and ohm-web-keys | Root only. Without ohm-api-keys the stored credentials cannot be opened, so back it up with the database |
| The agent's two credentials, the registry credential and the rest of the host's half of the configuration | /etc/antelao/agent.env | Mode 0600, root only |
| The console key and the GeoIP, Fail2Ban and CrowdSec service keys | /var/lib/ohm-agent/host-state.json | Mode 0600, root only |
| The DNS provider token for the console's Let's Encrypt certificate, when it uses DNS-01 | /var/lib/ohm-agent/certificate-dns01.credential | Mode 0600, root only |
| The application root: the database connection, container data, generated secrets, certificates, GeoIP databases, logs, license files | /root/.local/share/ohm/ | Root only |
| Instance trees: Odoo configuration, filestores, addons | /var/lib/odoo/instances | Root, and the instance's own container |
| Backups and the archive | /var/lib/odoo/backup, /var/lib/odoo/archive, and any off-site target you add | Backup encryption locks an archive with a key of yours |
Every file is listed on Configuration and state. Shell access to the host reaches all of it, which is why the host's own SSH has to be protected at least as carefully as the console.
What leaves the server
| What | Where to | When |
|---|---|---|
| The license check-in, or the daily report of a server with no license | license.antelao.io, license.antelao.app | Daily by default. What it carries is listed in What the check-in reports and in Article 4.2 of the license agreement |
| Update checks and image pulls | ghcr.io, Docker Hub, nightly.odoo.com, GitHub, packages.antelao.io | Daily, and when you update |
| GeoLite2 downloads, with your MaxMind account | download.maxmind.com | Every 24 hours, by the GeoIP service |
| Certificate requests and renewals | Let's Encrypt, and your DNS provider's API for DNS-01 | When a certificate is requested or nears expiry |
| The SMTP host in your mail profile, over TLS | When the server sends one of its messages | |
| Alerts | The channels you set up: e-mail, Slack, Discord, webhooks | When a rule matches |
| Backups | The off-site targets you add | On schedule or by hand |
| CrowdSec's collections and community blocklist | hub-cdn.crowdsec.net, api.crowdsec.net | While CrowdSec is switched on |
| The payment providers' address lists | Stripe, Paddle, Mollie | Hourly, for the Payments firewall rules |
The check-in and the daily report carry no database, filestore, log or credential. The full list of addresses, for a proxy's allow-list, is What the server reaches; a network that lets nothing out directly can send all of it through an outbound proxy.
A support bundle leaves the server only when you download it and send it yourself.
How updates arrive
The server checks for newer images, ohm releases and host packages every day, and the console's
Updates page and ohm server update say what is newer. An update is applied when an
administrator applies it, from the Updates page or with ohm server upgrade; the agent then
carries the upgrade through by itself, its own restart included. Every one of the product's own
images is checked against its signature before it runs, and one that does not verify is refused. The
antelao-ohm package, Docker and the host's operating system are yours to update with apt. See
Updating Antelao.
Under the license agreement, Article 11, security patches and fixes are supplied only to the extent your edition or a separate support agreement says, and an update can change features and defaults: read the release notes before you apply one.
Who gets in
Each layer works on its own, and each one is on this manual's page for it:
| Layer | Protects | Page |
|---|---|---|
| The host firewall | Which ports answer the network at all | The firewall and exposure, the port table |
| The server's firewall rules | Who may reach the console and the management API | The firewall and exposure |
| Password, authenticator app and passkeys, account lockout | Each console account | Multi-factor authentication and passkeys |
| Cloudflare Turnstile | The console's sign-in, against scripted guessing | Cloudflare Turnstile |
| Roles and instance scoping | What a signed-in person may see and do | Users and roles |
| API keys | Every program that calls the management API | API keys |
| The agent's key and its allow-list | The agent, the way back in when the console is down | Who may reach the agent |
| An instance's firewall rules | Who may reach which paths of an instance | The firewall and exposure |
| Pre-authentication | An instance nobody should reach without a password you handed out | Pre-authentication |
| Rate limits | Guessing and floods, on the API and on every instance | Rate limits |
| Fail2Ban and CrowdSec | Banning addresses that behave like attackers | Intrusion prevention |
Several of these are licensed features. What happens to each when a license stops carrying it is on When the license changes.
Reporting a vulnerability
Report a suspected vulnerability in the product privately to Antelao at
support@antelao.io, with the release (ohm --version) and the steps
that show it. Do not post it on the community forum or in a public issue.