Infisical: Self-Hosted Secrets Management for Your Infrastructure
Secrets management is one of those problems that starts small and gets dangerous fast. First it's a .env file in the repo (oops). Then it's a shared password doc. Then it's environment variables copy-pasted between servers, and nobody knows which production database password is current.
Photo by Elly Brian on Unsplash
Infisical is an open-source secrets management platform that centralizes your secrets -- API keys, database credentials, tokens, certificates -- in one place and syncs them to wherever they're needed: development environments, CI/CD pipelines, Docker containers, and Kubernetes clusters. Think of it as a developer-friendly alternative to HashiCorp Vault that doesn't require a PhD to configure.
Why Infisical Over .env Files
- Single source of truth -- One dashboard for all secrets across all environments
- Environment separation -- Dev, staging, and production secrets managed independently
- Access control -- Role-based permissions per project and environment
- Audit logging -- Track who accessed or modified which secret, when
- Automatic syncing -- Push secrets to CI/CD, Kubernetes, or cloud platforms
- Secret versioning -- History of every change with rollback capability
- Client SDKs -- Fetch secrets at runtime from Node.js, Python, Go, Java, and more
- End-to-end encryption -- Secrets encrypted client-side before reaching the server
The core problem Infisical solves: your secrets are scattered across .env files, CI/CD settings, cloud dashboards, and people's heads. Infisical gives them a single, auditable, access-controlled home.
Docker Deployment
# docker-compose.yml
services:
infisical:
image: infisical/infisical:latest
ports:
- "8080:8080"
environment:
- ENCRYPTION_KEY=your-random-32-byte-hex-key
- AUTH_SECRET=your-random-auth-secret
- DB_CONNECTION_URI=postgresql://infisical:infisicalpass@db:5432/infisical
- REDIS_URL=redis://redis:6379
- SITE_URL=https://secrets.yourdomain.com
depends_on:
- db
- redis
restart: unless-stopped
db:
image: postgres:16
volumes:
- infisical_db:/var/lib/postgresql/data
environment:
- POSTGRES_DB=infisical
- POSTGRES_USER=infisical
- POSTGRES_PASSWORD=infisicalpass
restart: unless-stopped
redis:
image: redis:7-alpine
volumes:
- infisical_redis:/data
restart: unless-stopped
volumes:
infisical_db:
infisical_redis:
# Generate required keys
openssl rand -hex 16 # ENCRYPTION_KEY (32 hex chars = 16 bytes)
openssl rand -base64 32 # AUTH_SECRET
docker compose up -d
Access Infisical at http://your-server:8080 and create your admin account.
Critical configuration:
ENCRYPTION_KEYencrypts secrets at rest. Back this up securely -- losing it means losing access to all stored secretsSITE_URLmust match your actual URL for SAML/OIDC callbacks and email links- Redis is required for session management and background jobs
- Put Infisical behind a reverse proxy with HTTPS in production
Organizing Secrets
Projects and Environments
Infisical organizes secrets in a hierarchy:
- Organization -- Your top-level account
- Projects -- Each application or service gets a project
- Environments -- Dev, staging, production (customizable)
- Folders -- Optional grouping within an environment
Example structure:
My Organization
├── web-app (project)
│ ├── Development
│ │ ├── DATABASE_URL=postgresql://localhost/dev
│ │ ├── API_KEY=dev-key-123
│ │ └── REDIS_URL=redis://localhost:6379
│ ├── Staging
│ │ ├── DATABASE_URL=postgresql://staging-db/app
│ │ └── ...
│ └── Production
│ ├── DATABASE_URL=postgresql://prod-db/app
│ └── ...
├── worker-service (project)
│ └── ...
└── mobile-api (project)
└── ...
Secret References
Reference secrets from other projects or environments to avoid duplication:
DATABASE_HOST=${web-app.production.DATABASE_HOST}
Change the source secret once, and all references update automatically.
Like what you're reading? Subscribe to Self-Hosted Weekly — free weekly guides in your inbox.
CLI Usage
The Infisical CLI is the primary way developers interact with secrets locally.
Install and Authenticate
# Install CLI
curl -1sLf 'https://dl.cloudsmith.io/public/infisical/infisical-cli/setup.deb.sh' | sudo bash
sudo apt install infisical
# Login
infisical login --domain=https://secrets.yourdomain.com
Inject Secrets into Your Shell
# Run a command with secrets injected as environment variables
infisical run --env=dev -- npm run dev
# Export secrets to your current shell
eval $(infisical export --env=dev --format=dotenv)
# Generate a .env file
infisical export --env=dev --format=dotenv > .env
This replaces the manual .env file workflow. Developers run infisical run -- <command>, and secrets are injected without touching disk.
CI/CD Integration
GitHub Actions
# .github/workflows/deploy.yml
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Fetch secrets from Infisical
uses: Infisical/secrets-action@v1
with:
url: https://secrets.yourdomain.com
client-id: ${{ secrets.INFISICAL_CLIENT_ID }}
client-secret: ${{ secrets.INFISICAL_CLIENT_SECRET }}
project-id: your-project-id
env-slug: production
- name: Deploy
run: ./deploy.sh
# All secrets are available as environment variables
GitLab CI
# .gitlab-ci.yml
deploy:
image: infisical/cli:latest
script:
- infisical login --method=universal-auth --client-id=$INFISICAL_CLIENT_ID --client-secret=$INFISICAL_CLIENT_SECRET --domain=https://secrets.yourdomain.com
- infisical run --env=production --project-id=your-project-id -- ./deploy.sh
Docker Compose
Inject secrets at container startup:
services:
my-app:
image: my-app:latest
entrypoint: ["infisical", "run", "--env=production", "--"]
command: ["node", "server.js"]
environment:
- INFISICAL_TOKEN=your-service-token
- INFISICAL_API_URL=https://secrets.yourdomain.com/api
Kubernetes Operator
For Kubernetes deployments, Infisical provides an operator that syncs secrets to Kubernetes Secrets:
# Install the operator
helm repo add infisical https://dl.cloudsmith.io/public/infisical/helm-charts/helm/charts/
helm install infisical-secrets-operator infisical/secrets-operator
Create a sync configuration:
apiVersion: secrets.infisical.com/v1alpha1
kind: InfisicalSecret
metadata:
name: my-app-secrets
spec:
hostAPI: https://secrets.yourdomain.com/api
authentication:
universalAuth:
secretsScope:
projectSlug: web-app
envSlug: production
credentialsRef:
secretName: infisical-credentials
secretNamespace: default
managedSecretReference:
secretName: my-app-env
secretNamespace: default
The operator polls Infisical and keeps the Kubernetes Secret in sync. Change a secret in the Infisical dashboard, and it propagates to your pods automatically.
Access Control
Roles and Permissions
- Admin -- Full access to all projects and settings
- Member -- Access to assigned projects, can read/write secrets
- Viewer -- Read-only access to assigned environments
- Custom roles -- Define granular permissions per project
Machine Identities
For CI/CD and automated access, create machine identities instead of using personal tokens:
- Go to Organization Settings > Machine Identities
- Create an identity with Universal Auth
- Assign it to specific projects and environments
- Use the client ID and secret in your automation
Machine identities have their own audit trails, separate from human users.
Infisical vs HashiCorp Vault
| Feature | Infisical | HashiCorp Vault |
|---|---|---|
| Setup complexity | Low (Docker + Postgres) | High (unsealing, HA config) |
| Learning curve | Straightforward | Steep |
| Web dashboard | Modern, developer-friendly | Functional but basic |
| Secret types | Key-value pairs | KV, PKI, databases, SSH, transit |
| Dynamic secrets | Limited | Extensive (auto-rotating DB creds) |
| Environment sync | Built-in | Requires custom tooling |
| CI/CD integrations | Native (GitHub, GitLab, etc.) | Via plugins |
| Kubernetes | Operator | CSI driver + injector |
| Access control | RBAC | Policies (HCL) |
| Audit logging | Yes | Yes (detailed) |
| High availability | Postgres replication | Raft/Consul |
| Secret rotation | Basic | Advanced (automatic) |
| Best for | Application secrets | Full infrastructure secrets |
Choose Infisical When
- Your primary need is managing application environment variables
- You want a developer-friendly dashboard that teams actually use
- You need CI/CD integration without weeks of configuration
- Your team is small to medium (under 50 engineers)
Choose Vault When
- You need dynamic secrets (auto-generated, auto-rotated database credentials)
- You need PKI certificate management
- You need transit encryption (encrypt/decrypt without exposing keys)
- You're managing secrets across a large, complex infrastructure
- Compliance requires advanced audit capabilities
Production Tips
Backup Strategy
Back up two things:
- PostgreSQL database -- All secrets (encrypted), projects, and audit logs
- ENCRYPTION_KEY -- Without this, the database backup is useless
# Database backup
docker exec infisical-db-1 pg_dump -U infisical infisical > infisical-backup.sql
Store the encryption key separately from the database backup. If both are compromised, your secrets are exposed.
Secret Rotation
Rotate secrets regularly, especially after team member departures:
- Update the secret in Infisical
- Infisical pushes the new value to all synced integrations
- Restart affected services to pick up the new values
Monitoring
Infisical logs all secret access. Review audit logs regularly for:
- Unexpected access patterns
- Access from unknown IP addresses
- Bulk secret reads (potential exfiltration)
The Bottom Line
Infisical fills the gap between "everyone shares a .env file" and "we need a full Vault deployment." It gives you centralized, encrypted, access-controlled secrets management with a dashboard that developers actually enjoy using. The CI/CD integrations and Kubernetes operator mean secrets flow from one source of truth to wherever they're needed. For most teams, that's exactly the right level of secrets management -- sophisticated enough to be secure, simple enough to actually adopt.
