Skip to content

Security Self-hosted

A checklist for an instance that carries real work. Everything here is something the product actually gives you, with a link to the page that covers it properly.

Deployment

Put TLS in front. The bundled Caddy container listens on plain HTTP and does not terminate TLS. Terminate it in your own proxy, load balancer or tunnel, and point that at <host>:<PROXY_PORT>. See Install.

Publish one port. Only the Caddy container publishes a port. PocketBase, the API, the MCP server and the collaboration server talk to each other on an internal Docker network and should never be reachable from outside.

Leave the PocketBase dashboard closed.POCKETBASE_ADMIN_ENABLED defaults to false, and Caddy answers /_/ with a 404 while it is off. Turn it on only to debug, and turn it off again.

Keep the data directory outside the application directory. This is what the setup wizard insists on, and it is also what makes an update safe: the application directory is replaced, the data directory is not.

Secrets

Set a settings encryption key.PB_ENCRYPTION_KEY makes PocketBase encrypt the sensitive settings it stores in the database, including your SMTP password, OAuth2 client secrets and S3 keys. The wizard generates one and recommends it.

It cannot be rotated

Change or lose PB_ENCRYPTION_KEY after the first start and every encrypted setting becomes unreadable. Store it with your other secrets, and keep it alongside any backup you might restore from.

Keep .env out of reach. It holds the encryption key, the admin password and your web push private key. The wizard also drops a copy in your data directory as a convenience. Both are on the machine, so the authoritative copy belongs in your secret store.

Know what the admin password protects. Git OAuth client secrets and the access and refresh tokens from Connect with GitHub / GitLab / Gitea are stored encrypted with a key derived from POCKETBASE_ADMIN_PASSWORD. Rotating that password makes the stored git tokens unreadable and your team has to reconnect their providers.

AI provider keys stay on the server. Keys entered in Settings > Integrations > AI are stored by the instance and come back masked, never echoed to the browser. See AI settings.

Webhook signing secrets are write-only. A signing secret is stored encrypted and never shown again, as the field itself says. You can replace one; nobody can read it back. See Webhooks.

The admin account

The email and password you gave the setup wizard create two things on first install: the PocketBase superuser, and an app user with the OWNER role, already verified so it can sign in.

Two consequences worth knowing.

The superuser credentials are re-synced from .env at every container start, so changing POCKETBASE_ADMIN_PASSWORD there and restarting does change the superuser password. It does not change the OWNER user's password in the app, which is managed from the profile dialog like anyone else's.

OWNER is the only role that can detach the license, and the only role that outranks ADMIN everywhere. Give it to as few people as the work allows. See Roles and permissions.

Sign-in

Turn on rate limiting.POCKETBASE_RATE_LIMIT_ENABLED=true turns on PocketBase's rate limiter at boot. The wizard recommends it and defaults to yes.

Use your identity provider.Settings > Server > OAuth2 configures OAuth2 and OIDC providers with field mappings, and Settings > Server > Active Directory synchronizes users and groups from AD, pre-provisioning accounts from group membership. Both are available on a self-hosted instance with no gate. See Sign-in and identity.

Configure mail before you need it. Password resets and sign-in codes are email. An instance with broken SMTP is an instance where nobody locked out can get back in. See SMTP.

Watching and revoking

Sessions.Settings > Audit & Security > Active Sessions lists every session with its user, IP address, browser and operating system, and when it signed in. Revoke signs that person out of every device at once.

Audit log.Settings > Audit & Security > Audit Log records changes across the workspace, filterable by user, board, entity type, action and date range, and exportable as CSV or JSON.

Logs.Settings > Server > Logs holds structured events from the API and the PocketBase hooks. When a user reports a problem with an error reference like ERR-a1b2c3, that is how you find the entry behind it.

All three are covered in Audit, sessions and logs.

Data lifecycle

Set retention deliberately. Audit logs default to 90 days, everything else to 30. Lengthen the audit window if you have an obligation, and export before you ever shorten it. See Data retention.

Get backups off the machine. Point Backup Storage at a bucket, or copy the archives elsewhere yourself. A backup on the same disk as the database protects you from mistakes, not from hardware. See Backups and S3 storage.

Remember the encryption key travels with the backup. An archive restored onto an instance with a different PB_ENCRYPTION_KEY cannot read its own encrypted settings.

Outbound

Decide what may leave the box. Both network switches are off on a fresh instance, and a no-outbound install is a supported configuration. Turn on Allow features that reach the internet only if you want link previews, Unsplash or agents reading the web. Turn on Allow private network targets only if a webhook or an automation genuinely has to reach your own network. See Network policy.

The guard underneath stays on. Whatever you allow, outbound calls are still limited to http and https, still re-check every redirect hop, and still stream against a size budget.

Agents and programmatic access

Give each agent only the powers it needs. An agent's profile carries its powers and its guardrails. Has permission to covers Complete, Archive, Delete, Merge PRs and Read the web, and each one is off until you grant it. See Creating an agent.

Treat tokens as credentials. API tokens and MCP tokens act as the account that owns them. Issue one per integration so you can revoke one without breaking the rest. See REST API and MCP.

Local access is per agent. An agent that works on someone's computer through the desktop app needs that grant explicitly. An open desktop app does not by itself give any agent access to it.

Public surfaces

Public forms accept anonymous uploads. The extension allowlist and the per-submission file limit are configurable with FORMS_UPLOAD_ALLOWED_EXTENSIONS and FORMS_MAX_FILES_PER_SUBMISSION, and the default allows common image, document and archive types while always denying html, svg, xml and js. A form can also be password protected. See Sharing and submissions.

Published notes are public. Anything published from a note is readable by anyone with the link. See Access and publishing.

Truetask works the same on Truetask Cloud and on your own server. Pages and sections that apply to one model only are labelled.