Overview
Infisical is an open-source secrets-management platform: store, version, scope, and serve application secrets through a web UI and REST API, with projects, environments, and access controls. This template deploys a stateless Infisical server tier (UI and API on port8080) backed by a bundled PostgreSQL that holds every stored secret, and a bundled highly-available Redis with Sentinel for its cache and background-job queues. The default is a single server replica; infisical.replicas scales the server tier out over the shared database and cache.
What Gets Created
ENCRYPTION_KEY and AUTH_SECRET is not created by the template — see Prerequisites.
Prerequisites
Infisical encrypts every stored secret with anENCRYPTION_KEY and signs every session and token with an AUTH_SECRET. Both are long-lived root-of-trust values, so you supply them through a dictionary secret created before installing; neither value ever passes through Helm values.
Create the root-of-trust secret
ENCRYPTION_KEY, a 16-byte hex string, and AUTH_SECRET, a 32-byte base64 string.secrets.name to this name. Secrets are org-level, so no GVC flag is involved.Back both values up outside Control Plane
ENCRYPTION_KEY cannot be rotated without losing the data it protects — every secret stored in Infisical is encrypted with it, and a changed key makes all of them unreadable. Rotating AUTH_SECRET invalidates every session and token. Keep a copy of both somewhere safe, so a rebuilt install can read an existing database or a restored backup.- Authenticated SMTP — a dictionary secret holding
SMTP_USERNAMEandSMTP_PASSWORD. See Email. - Scheduled database backups — a bucket and cloud account (or S3-compatible credentials) for the bundled PostgreSQL. See Backing Up.
Installation
Once the root-of-trust secret exists, install from the marketplace registry, pointingsecrets.name at it and replacing the bundled database password:
postgres.config.credentialsSecretName to a name no other release uses — secret names are org-wide.
Other ways to install and manage the template:
UI
CLI
Terraform
Pulumi
Configuration
Infisical Server
Prerequisite Secret
smtp.auth.secretName to its name. The server identity is granted reveal on exactly that secret.
cpln workload force-redeployment RELEASE_NAME-infisical --gvc GVC_NAME.
Access
Bundled PostgreSQL
The database is the postgres template as a subchart, so every knob of that template is available underpostgres.*. The chart builds the credentials secret from postgres.credentials.* for you — nothing to create before installing.
Bundled Redis
Redis is required — the server does not boot without it, so there is no toggle to disable it. The bundled redis template runs three data nodes and three Sentinels; the server connects through Sentinel (REDIS_SENTINEL_HOSTS, master mymaster), so a Redis failover is transparent to it. Redis holds only cache and queue state, never stored secrets, and runs without persistence.
redis.sentinel.auth is enabled.
Connecting
publicAccess.enabled: false there is no public endpoint; reach the UI from your machine through a tunnel instead and open http://localhost:8080:
First Run
Infisical ships no default account: the first person to sign up becomes the server administrator, and with public access on that form is open to anyone who can reach the endpoint.Wait for the server workload to report ready
Boot up migration failed retries — they stop once the migrations complete.Open the endpoint and sign up
Close open sign-ups
Operations
Backing Up
Scheduled backups of the bundled PostgreSQL are off by default. Enablingpostgres.backup.enabled: true adds one cron workload, RELEASE_NAME-postgres-backup, that runs pg_dumpall on the schedule and uploads a gzipped dump to your bucket under the configured prefix. Pick a postgres.backup.provider and complete the matching setup before installing or upgrading with it on.
- AWS S3
- Google Cloud Storage
- MinIO / S3-compatible
Create a bucket
postgres.backup.aws.bucket and postgres.backup.aws.region to match.Set up a cloud account
postgres.backup.aws.cloudAccountName to its name.Create a bucket-scoped IAM policy
YOUR_BUCKET_NAME) and set postgres.backup.aws.policyName to its name. The template attaches it to the bundled PostgreSQL identity and nothing else:ENCRYPTION_KEY it was written under — every secret in it is encrypted with that key, which lives only in the secret you created. Back that secret up alongside the database. The PostgreSQL volume set RELEASE_NAME-pg-vs takes no scheduled snapshots; a final snapshot is taken when the volume set is deleted and kept 7 days.
Restoring a Backup
Each backup is a gzipped plain-SQLpg_dumpall archive. Restoring means replaying that SQL into the bundled PostgreSQL, then starting a server whose secrets.name holds the same ENCRYPTION_KEY and AUTH_SECRET the dump was written under. The one transport that carries a dump into the container intact is cpln workload exec with --stdin and a base64 wrapper on both ends — raw binary piped through exec is corrupted:
CREATE ROLE and CREATE DATABASE statements, so a straight replay collides with the database the server already created and migrated on first boot; and no server replica may be connected while you drop and recreate that database before the replay.
Upgrading from 1.0.0
Version 1.1.0 adopted thepostgres 3.4.1 template, which stopped taking database credentials as values. Infisical absorbed that change rather than passing it on — the chart now creates the credentials secret itself — so there is no new prerequisite, only a rename of three keys:
helm upgrade after an install can restart the bundled PostgreSQL even when its values are unchanged, so expect a brief interruption.Scaling and Availability
infisical.replicas sets how many server replicas run. The server is stateless over the shared PostgreSQL and Redis, so replicas need no peer discovery or sticky sessions, and two or more give near-zero-downtime rolling restarts. Every replica runs the database migrations on boot; a migration lock serializes them so they run exactly once no matter how many replicas start together.
infisical.resources.maxMemory at 2Gi when scaling out — a cold multi-replica boot running migrations runs out of memory at 1Gi.
The bundled Redis is already highly available (three data nodes, three Sentinels, automatic failover). The bundled PostgreSQL is a single instance on a persistent volume: a node failure reschedules it and reattaches the same volume, so the exposure is minutes of downtime, not data loss. Stored secrets live only in PostgreSQL and survive restarts, redeploys, and upgrades under the same release name.
Troubleshooting
Deployment never becomes ready and the logs are empty
Deployment never becomes ready and the logs are empty
cpln helm install reported success, cpln logs returns nothing, and cpln workload get-deployments RELEASE_NAME-infisical --gvc GVC_NAME -o yaml shows The secret INFISICAL_KEYS_SECRET_NAME no longer exists. Workload updates are paused until the secret is added or the reference to the secret removed. under status.versions[].message.Cause: The root-of-trust secret named by secrets.name does not exist (or, with SMTP auth on, the secret named by smtp.auth.secretName does not).Fix: Create it (see Prerequisites). The deployment recovers on its own once the secret exists; cpln workload force-redeployment RELEASE_NAME-infisical --gvc GVC_NAME skips the wait.Logs show Boot up migration failed during first boot
Logs show Boot up migration failed during first boot
cpln logs '{gvc="GVC_NAME", workload="RELEASE_NAME-infisical"}' --limit 50 --since 10m shows repeated Boot up migration failed lines shortly after install, and the workload is not yet ready.Cause: The server started before the bundled PostgreSQL finished initializing and is retrying its migrations.Fix: Nothing — the retries stop once the database accepts connections and the workload becomes ready. If the lines keep coming, check RELEASE_NAME-postgres with cpln workload get-deployments RELEASE_NAME-postgres --gvc GVC_NAME -o yaml.Second install refused as managed by a different release
Second install refused as managed by a different release
cannot be updated because it is being managed by a different release and creates nothing.Cause: Both releases use the same postgres.config.credentialsSecretName. Secret names are org-wide, and the first release owns that one. Nothing is shared, overwritten, or deleted.Fix: Set postgres.config.credentialsSecretName to a distinct name for the second release and install again.Upgrade from 1.0.0 fails with config.username was REMOVED in postgres 3.4.0
Upgrade from 1.0.0 fails with config.username was REMOVED in postgres 3.4.0
config.username was REMOVED in postgres 3.4.0 (or the same message for config.password / config.database) and tells you to create a dictionary secret.Cause: Your values file still carries postgres.config.username, postgres.config.password, or postgres.config.database.Fix: Rename them to postgres.credentials.* as described in Upgrading from 1.0.0. Do not create a secret yourself — this template creates it.Render fails because redis.sentinel.auth must stay disabled
Render fails because redis.sentinel.auth must stay disabled
infisical: redis.sentinel.auth must stay disabled — Infisical authenticates only the data nodes (REDIS_PASSWORD), not the sentinels.Cause: redis.sentinel.auth.password.enabled or redis.sentinel.auth.fromSecret.enabled is true.Fix: Turn Sentinel authentication off. To require a password on the data nodes, set redis.redis.auth.password.enabled: true and a value for redis.redis.auth.password.value instead.Login does not stick or links point at the wrong host
Login does not stick or links point at the wrong host
SITE_URL) does not match the host you reach it on — typically a custom domain in front of the workload while infisical.siteUrl is still empty and derives the canonical endpoint.Fix: Set infisical.siteUrl to the URL users actually open, including https://, and upgrade the release.Important Notes
- Create the root-of-trust secret before installing —
secrets.namemust name an existing dictionary secret withENCRYPTION_KEYandAUTH_SECRET. A missing secret wedges the deployment silently. ENCRYPTION_KEYandAUTH_SECRETare write-once — never rotate them. A changedENCRYPTION_KEYmakes every stored secret unreadable; a changedAUTH_SECRETinvalidates every session. Back both up outside Control Plane.- Sign up right after install — the first account becomes the server administrator and the form is open to anyone who can reach the endpoint. Then set Signup mode to Disabled in the Server Console.
- Redis is required, not optional — the server does not boot without it, and Sentinel authentication must stay off.
- Keep
infisical.resources.maxMemoryat2Gi— a cold boot withinfisical.replicasof 2 or more runs out of memory at1Gi. - Change
postgres.credentials.passwordbefore installing — it seeds the database on first boot and is not updated by later value edits. - Give each release its own
postgres.config.credentialsSecretName— secret names are org-wide, and a second release on the same name is refused at install. - A database backup is only as good as the key — a restored dump is unreadable without the
ENCRYPTION_KEYit was written under. - Uninstalling deletes the PostgreSQL volume set and every stored secret in it; your root-of-trust secret is yours and survives.
- Set
smtp.requireTls: falseonly for a plaintext mail catcher — real providers on port587need it lefttrue.