Documentation

Configuration

Personal Agent is domain-agnostic: one built image serves every deployment, and you point it at your own domain through a handful of environment variables. Throughout the docs, app.example.com and id.example.com are placeholders — substitute your own hostnames.

All backend settings use the PERSONAL_AGENT__ env prefix (__ nests - e.g. PERSONAL_AGENT__OIDC__ISSUER). The Docker / Compose path reads them from compose/.env in the personal-agent-org/deploy repo; the Helm chart (charts/personal-agent in the same repo) sets the non-secret ones under config.* and the secrets under externalSecrets.data. The defaults are sensible - most operators only set the domain knobs and the secrets below.

!!! note “Identity provider has its own page” Issuer, audience, the OIDC clients and how to use a non-Keycloak provider are documented separately in OIDC provider configuration.


Environment variables

Everything domain-specific derives from a few top-level variables (in compose/.env, copied from compose/.env.example):

Variable Example Meaning
APP_ORIGIN https://app.example.com The app’s public origin (SPA + API as seen by a browser / device). Sets PERSONAL_AGENT__PUBLIC_BASE_URL.
KEYCLOAK_ORIGIN https://id.example.com Keycloak base URL.
REALM personal-agent Keycloak realm name.
OIDC_ISSUER https://id.example.com/realms/personal-agent External OIDC issuer configured on the backend. The backend publishes its discovered client contract to every frontend.
CORS_ORIGINS ["https://app.example.com"] JSON array of allowed browser origins. Usually just the app origin. Sets PERSONAL_AGENT__SECURITY__CORS_ORIGINS.

Secrets

Generate strong, unique values (e.g. openssl rand -base64 32):

Variable Meaning
POSTGRES_PASSWORD Application database password.
BYOK_MASTER_KEY Master key for envelope-encrypting admin-managed provider keys (sets PERSONAL_AGENT__SECURITY__BYOK_MASTER_KEY). Required to store/use any provider credential.
WHATSAPP_WEBHOOK_SECRET Shared HMAC secret for the optional WhatsApp bridge webhook (sets PERSONAL_AGENT__INTEGRATIONS__WHATSAPP_WEBHOOK_SECRET).

Same-origin defaults

If the SPA, API, SSE and WebSocket are served from the same origin (the usual single-host reverse-proxy setup), you only need the backend identity configuration and secrets — the browser uses API/SSE/WS bases from window.location at runtime. Set the PA_* overrides only if the API is on a different origin than the SPA:

Variable Default When to set
PA_API_BASE <origin>/api/v1 API on a different origin.
PA_SSE_BASE <origin>/api/v1 SSE on a different origin.
PA_WS_BASE ws(s)://<origin>/api/v1 WS on a different origin.
PA_APP_ORIGIN <origin> Override the app origin used to build OIDC redirect URIs.

The backend config defaults are env-driven and need no changes — only the .env edge values above.


How the SPA gets its config

The frontend is one static image for every deployment. Runtime config is rendered at container start by compose/frontend-entrypoint.sh (in the personal-agent-org/deploy repo), which writes /config.js (window.__APRIL_CONFIG__) from the environment and then runs nginx — no rebuild per environment.

The SPA obtains authentication mode, external issuer and public client id from GET /api/v1/public/client-config. It has no identity-provider URL override or fallback. When the PA_API_BASE / PA_SSE_BASE / PA_WS_BASE / PA_APP_ORIGIN transport overrides are empty, the entrypoint uses same-origin values from window.location; the redirect paths remain part of the SPA itself.


Public base URL & cloud sandboxes

PERSONAL_AGENT__PUBLIC_BASE_URL (set from APP_ORIGIN) is the origin that on-demand cloud coding/browser sandboxes and Computer Service instances dial back to (and the SPA / browser-extension OIDC bootstrap read it). It must be the externally reachable origin, not an internal service name; if unset, the backend falls back to the first CORS_ORIGINS entry.

Inside the Compose network, spawned sandbox containers reach the backend by service name via PERSONAL_AGENT__SANDBOX__BACKEND_URL (http://backend:8000 by default) on the PERSONAL_AGENT__SANDBOX__NETWORK network - that internal URL is separate from the public origin above and normally needs no change.

By default a cloud sandbox’s workspace is ephemeral (torn down with the container). Set SANDBOX_STORAGE_BACKEND (which maps to PERSONAL_AGENT__SANDBOX__STORAGE_BACKEND) to persist it and restore it into a fresh sandbox: none (default), local (a backend volume), or s3 (an S3/MinIO bucket, configured via the PERSONAL_AGENT__SANDBOX__STORAGE_S3_* settings).

The bundled web tools’ outbound User-Agent and the Met.no weather integration’s contact string default to a generic project URL; configure a real contact on the weather integration if you use it heavily (Met.no’s ToS asks for one).


LLM provider credentials

!!! warning “Not environment variables” LLM provider credentials are not env vars. They are admin-managed “platform keys” entered in the admin console (Admin -> Providers, at /admin/providers) and stored envelope-encrypted in the database using BYOK_MASTER_KEY. Set that secret before adding any provider; with no master key set, key storage is disabled.