For AI agents: a documentation index is available at /llms.txt. A markdown version of this page is available at /guide/self-hosted/admin/security.md.
Security
Hardening a self-hosted deployment — network exposure, credentials, TLS and access review.
On Cloud, most of this is handled for you. Self-hosted, it is yours. The items below are ordered by how much damage getting them wrong causes.
#Network exposure
PostgreSQL must never be internet-facing
Port 5432 should be reachable only from the application server. An exposed database is the single most damaging misconfiguration on a self-hosted install.
| Port | Should be |
|---|---|
| 443 (HTTPS) | Public |
| 80 (HTTP) | Public — redirect to HTTPS |
| 8080 (application) | Internal only, behind the proxy |
| 8088 (Superset) | Internal, or restricted to admins |
| 5432 (PostgreSQL) | Internal network only |
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw deny 5432/tcp
sudo ufw status verbose
Publishing 8080 bypasses your TLS
If the app port is reachable from outside, traffic reaches it without ever passing through the proxy that terminates TLS. Bind it to the internal interface.
#Credentials
Service passwords live as plaintext files in ./secrets/.
Change every shipped default
Anything that came with the package is public knowledge.
Restrict filesystem access
chmod 600, owned by the account that runs the stack.Keep them out of version control
Add
secrets/to.gitignore.Encrypt every backup that contains them
A
secrets.tar.gzis an archive of live passwords. Store it encrypted with restricted access — see Backup.
#TLS
- Terminate TLS at the proxy or load balancer; the app speaks plain HTTP inside.
- Use Let's Encrypt or a commercial certificate.
- Automate renewal and alert on expiry — a lapsed certificate is a full outage, and it happens on a predictable date you can monitor.
#Application access
The same controls as Cloud apply once you are inside the product:
Enable for admins first, then require it workspace-wide. Make sure people save recovery codes.
Grant the least access that works. Keep the admin list short.
Where your licence includes it, keep one break-glass admin that does not depend on the identity provider.
Who changed what, and when.
#API keys
If the Public API add-on is enabled, keys are real credentials:
- Scope them narrowly; a key can never exceed its owning role's permissions
- One key per integration, so you can revoke one without breaking the rest
- The secret is shown once at creation — store it in a secrets manager
- Rotate periodically; revoke immediately when an integration is retired
Webhook deliveries are signed with X-OS-Signature (HMAC-SHA256). Verify that
signature on your endpoint rather than trusting the payload.
#Data handling
Attachments inherit project permissions
A file on a task is visible to that project's members. Sensitive material belongs in a project with restricted membership.
Backups contain everything
Database dumps and the secrets archive together are a complete copy of your workspace and its credentials. Encrypt at rest, restrict access, and keep them off the application host.
Logs can contain identifiers
logs/error.log may include request context. Treat it as sensitive when
sharing with support.
#Review on a schedule
Admin list, project membership, active API keys, and whether any leavers still have accounts.
Certificate expiry, container health, disk headroom, backup freshness.
Product security posture and disclosures.