Self-hostedTalon Studio v1.0.2-beta
Security Hardening
What the appliance refuses to start with, and the essentials for exposing it safely: generated secrets, strict mode, and TLS at the edge.
What refuses to start
The app checks its configuration before anything else and exits with Refusing to start: insecure configuration, followed by the list of problems, when it finds one. Two kinds of finding refuse startup:
A stock install never meets either: with nothing set, every secret is generated strong. Set TALON_STRICT_SECURITY=true as well — it keeps that behaviour even if NODE_ENV is overridden, and makes /api/metrics require the TALON_METRICS_TOKEN bearer rather than accepting a signed-in session.
Secrets and the first admin
Leave AUTH_SECRET, TALON_ENCRYPTION_KEY and POSTGRES_PASSWORD unset and they are generated into /data/secrets (a mode-0700 directory of mode-0600 files). If you set your own, use openssl rand -hex 32. Keep the encryption key stable across upgrades, and keep a copy off the volume.
There is no default admin password. The first admin gets a random one, shown once and saved to /data/secrets/initial-admin.txt; the first sign-in forces a change. Delete the file afterwards.
The generated password goes straight to the container's output, not through the app's logger, so it is not kept in /data/logs or sent on by the app's syslog forwarding. The container runtime's own log still holds that line, which is one more reason the first sign-in forces a change.
Network and TLS
The published compose file binds the app to 127.0.0.1 on the host. Reach it through a reverse proxy that terminates TLS, and restrict who can reach the proxy — a VPN, security groups or an internal load balancer.
Set NEXTAUTH_URL to the https:// address. AUTH_TRUST_HOST defaults to true in the image.
Set TALON_TRUST_PROXY=true only when the proxy sets X-Real-IP, which Studio reads first, and overwrites X-Forwarded-For — the Caddyfile on Install does both. It is what lets IP-allowlisted API tokens and per-client rate limits see the real client address; forwarding headers from an untrusted path can be spoofed.
Postgres (5432) and pySigma (8001) bind to 127.0.0.1 inside the container. Never publish them.
If you use SOC notable push, each deployed search carries a webhook URL with a per-workspace HMAC token in its query string. Treat those URLs as secrets.
Public health probes (/api/health, /api/health/live) return only a status. Version, licence and content detail need a session or the metrics token.
Tip
Put a TALON_METRICS_TOKEN in place before anything scrapes /api/metrics, and keep the proxy from buffering responses — agent runs and the assistant stream their output.
Outbound connections
Outbound HTTPS uses the container's OS trust store. For a corporate CA, mount the bundle and set NODE_EXTRA_CA_CERTS; an on-prem SIEM connection also takes its own CA certificate (PEM) in the Connect SIEM dialog.
Integration URLs may point at loopback and LAN hosts, because on-prem SIEMs are normal; cloud-metadata endpoints are always blocked. TALON_STRICT_OUTBOUND_URLS=true blocks every private range.
A private or localhost AI base URL, and AI endpoints with invalid TLS, are rejected unless you set TALON_ALLOW_PRIVATE_AI_BASE_URLS or TALON_ALLOW_INSECURE_AI_TLS.
Sigma translation and validation never leave the appliance: the pySigma sidecar runs inside the container. Text sent to an AI model goes only to the provider you configure.
Inside the container
The entrypoint runs as root only to initialise Postgres and set volume ownership. pySigma, the migrations and the app run as the unprivileged talon user, and Postgres as postgres.
The compose file sets no-new-privileges. The Helm chart drops every Linux capability except the five the entrypoint needs (CHOWN, DAC_OVERRIDE, FOWNER, SETGID, SETUID), disallows privilege escalation, and applies the runtime's default seccomp profile.
Every image the publish workflow pushes is signed and carries an SBOM as a signed attestation. Install → Pull the image shows how to verify one.