Self-Host Infisical: HashiCorp Vault Alternative 2026
TL;DR
Infisical is a modern, developer-friendly open source secrets management platform — a simpler alternative to HashiCorp Vault for teams managing environment variables and secrets. It provides a web UI, CLI, SDKs, and integrations with GitHub Actions, Kubernetes, Docker, and major cloud providers. MIT license, ~17K GitHub stars. Self-host with Docker Compose in ~15 minutes. HashiCorp Vault is more powerful for PKI and dynamic secrets, but Infisical is the right choice for most teams managing app secrets and environment variables.
Key Takeaways
- Infisical: MIT license, ~17K GitHub stars, TypeScript/React, modern UI, focused on env vars and secrets
- HashiCorp Vault (now BSL): Enterprise PKI, dynamic secrets, complex setup — overkill for most teams
- OpenBao: Community fork of Vault with MPL 2.0 license — for teams that need Vault's power without BSL
- Setup: Docker Compose + Postgres, 15 minutes
- CLI injection:
infisical run -- node server.jsinjects secrets automatically - SDK: Available for Node.js, Python, Go, Java, Ruby, .NET
Why a Secrets Manager?
The problem with .env files:
- Secrets live in plaintext files on developer laptops
.envfiles accidentally get committed to Git- No audit log — who changed
DATABASE_URLlast Tuesday at 3am? - No access control — every developer has every secret
- Rotating secrets requires updating N servers manually
What a secrets manager provides:
- Centralized secret storage with encryption at rest
- Role-based access control (dev gets staging secrets, not prod)
- Audit log of every read and write
- Secret versioning (rollback to previous value)
- Automated injection into apps — no .env files on servers
Infisical vs HashiCorp Vault vs OpenBao
| Feature | Infisical | HashiCorp Vault | OpenBao |
|---|---|---|---|
| License | MIT | BSL 1.1 (non-OSS) | MPL 2.0 |
| Setup complexity | Simple (20 min) | Complex (hours) | Complex (hours) |
| UI | Modern, React | Basic | Basic |
| env var management | ✅ Core feature | Via KV secrets engine | Via KV secrets engine |
| Dynamic secrets | ❌ (limited) | ✅ | ✅ |
| PKI / certificates | ❌ | ✅ | ✅ |
| Secret leasing/renewal | ❌ | ✅ | ✅ |
| GitHub Stars | ~17K | ~32K | ~4K |
| Language | TypeScript/Go | Go | Go |
| Best for | App secrets, env vars | Enterprise PKI, dynamic secrets | Vault without BSL |
Recommendation: Use Infisical for most teams managing app environment variables and API keys. Use Vault or OpenBao if you need PKI, database credential rotation, or enterprise-level dynamic secrets.
Part 1: Docker Compose Setup
# docker-compose.yml
version: '3.8'
services:
infisical:
image: infisical/infisical:latest
container_name: infisical
restart: unless-stopped
environment:
# Required:
NODE_ENV: production
ENCRYPTION_KEY: "${INFISICAL_ENCRYPTION_KEY}" # 32-char random string
AUTH_SECRET: "${INFISICAL_AUTH_SECRET}" # 32-char random string
# Database:
DB_CONNECTION_URI: "postgresql://infisical:${POSTGRES_PASSWORD}@db:5432/infisical"
# Redis (for rate limiting and sessions):
REDIS_URL: "redis://redis:6379"
# Your deployment URL:
SITE_URL: "https://secrets.yourdomain.com"
# Email (optional but recommended for account verification):
SMTP_HOST: "${SMTP_HOST}"
SMTP_PORT: "587"
SMTP_USERNAME: "${SMTP_USER}"
SMTP_PASSWORD: "${SMTP_PASSWORD}"
SMTP_FROM_ADDRESS: "noreply@yourdomain.com"
ports:
- "8080:8080"
depends_on:
- db
- redis
db:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_DB: infisical
POSTGRES_USER: infisical
POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}"
volumes:
- postgres_data:/var/lib/postgresql/data
redis:
image: redis:7-alpine
restart: unless-stopped
command: redis-server --save 60 1 --loglevel warning
volumes:
- redis_data:/data
volumes:
postgres_data:
redis_data:
# .env — generate secure values:
INFISICAL_ENCRYPTION_KEY=$(openssl rand -hex 16) # Must be exactly 32 chars
INFISICAL_AUTH_SECRET=$(openssl rand -base64 32)
POSTGRES_PASSWORD=$(openssl rand -base64 24)
SMTP_HOST=smtp.yourdomain.com
SMTP_USER=noreply@yourdomain.com
SMTP_PASSWORD=your-smtp-password
docker compose up -d
Access at http://your-server:8080 (put behind Caddy/Nginx for HTTPS).
Part 2: HTTPS with Caddy
secrets.yourdomain.com {
reverse_proxy localhost:8080
}
Part 3: First Setup
- Visit
https://secrets.yourdomain.com - Create your admin account
- Create an Organization (e.g., "My Company")
- Create a Project (e.g., "backend-api")
- Add Environments (Development, Staging, Production)
- Add your secrets to each environment
Infisical Data Model
Organization
└── Projects
└── Environments (dev, staging, prod)
└── Secret folders
└── Secrets (KEY=VALUE)
Members can have different roles per project (Viewer, Developer, Admin).
Part 4: CLI — Inject Secrets into Any App
Install the Infisical CLI:
# macOS:
brew install infisical/get-cli/infisical
# Linux:
curl -1sLf 'https://dl.cloudsmith.io/public/infisical/infisical-cli/setup.deb.sh' | sudo bash
sudo apt-get install infisical
# Windows:
scoop install infisical
Login and Connect
# Set your self-hosted URL:
infisical login --domain https://secrets.yourdomain.com
# In your project directory, initialize:
infisical init
# Select your organization, project, and environment
# Creates: .infisical.json (commit this — no secrets in it)
Run Your App with Injected Secrets
# Inject secrets as environment variables and run:
infisical run -- node server.js
infisical run -- python app.py
infisical run -- npm start
infisical run --env staging -- node server.js # Use staging env
# Export secrets to a file (for tools that need .env):
infisical export --format dotenv > .env.local
# View all secrets in current environment:
infisical secrets
Docker Run with Infisical
# Inject Infisical secrets into a Docker container:
infisical run -- docker run \
-e DATABASE_URL \
-e API_KEY \
-e JWT_SECRET \
myapp:latest
Dockerfile — Service Token Approach (Production)
For production, use a Service Token (machine identity) instead of your personal login:
# Dockerfile
FROM node:20-alpine
RUN npm install -g @infisical/cli
COPY . .
RUN npm ci
# At runtime, use service token via INFISICAL_TOKEN env var:
CMD infisical run --token=$INFISICAL_TOKEN -- node server.js
# Generate a service token:
# Infisical UI → Project → Settings → Service Tokens → Add Token
# Copy the token — it's only shown once
# Run container with token:
docker run -e INFISICAL_TOKEN=st.xxx myapp:latest
Part 5: SDK Usage (Node.js)
For apps that need to fetch secrets programmatically (not just at startup):
import { InfisicalClient } from "@infisical/sdk";
const client = new InfisicalClient({
clientId: process.env.INFISICAL_CLIENT_ID!,
clientSecret: process.env.INFISICAL_CLIENT_SECRET!,
siteUrl: "https://secrets.yourdomain.com", // Your self-hosted URL
});
// Get a single secret:
const dbUrl = await client.getSecret({
secretName: "DATABASE_URL",
projectId: "your-project-id",
environment: process.env.NODE_ENV ?? "development",
});
console.log(dbUrl.secretValue);
// List all secrets:
const secrets = await client.listSecrets({
projectId: "your-project-id",
environment: "production",
});
Python:
from infisical_sdk import InfisicalSDKClient
client = InfisicalSDKClient(
client_id="your-client-id",
client_secret="your-client-secret",
site_url="https://secrets.yourdomain.com",
)
secret = client.getSecret(
secret_name="DATABASE_URL",
project_id="your-project-id",
environment="production",
)
print(secret.secretValue)
Part 6: GitHub Actions Integration
Reference Infisical secrets directly in CI/CD:
# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Inject Infisical Secrets
uses: Infisical/secrets-action@v1.0.7
with:
client-id: ${{ secrets.INFISICAL_CLIENT_ID }}
client-secret: ${{ secrets.INFISICAL_CLIENT_SECRET }}
env-slug: production
project-id: your-project-id
domain: https://secrets.yourdomain.com
# Secrets are now available as environment variables:
- name: Deploy
run: |
echo "Database: $DATABASE_URL" # Injected from Infisical
./deploy.sh
Part 7: Kubernetes Secret Injection
Infisical can sync secrets to Kubernetes as native Secrets:
# Install Infisical Operator:
# helm repo add infisical-helm-charts https://dl.cloudsmith.io/public/infisical/helm-charts/helm/charts/
# helm install --generate-name infisical-helm-charts/secrets-operator
# InfisicalSecret resource:
apiVersion: secrets.infisical.com/v1alpha1
kind: InfisicalSecret
metadata:
name: myapp-secrets
spec:
authentication:
universalAuth:
credentialsRef:
name: infisical-credentials # K8s secret with clientId/clientSecret
namespace: default
infisicalUrl: https://secrets.yourdomain.com
projectId: your-project-id
environment: production
managedSecretReference:
secretName: myapp-env # Creates/updates this K8s Secret
secretNamespace: default
Comparing with OpenBao (Vault Fork)
If you need features Infisical lacks — PKI, database credential rotation, identity-based secret delivery — consider OpenBao instead of HashiCorp Vault:
| Use Case | Tool |
|---|---|
| App env vars, API keys | Infisical |
| TLS certificate management | OpenBao (Vault fork) |
| Dynamic database credentials | OpenBao |
| Enterprise compliance / auditing | OpenBao |
| SSH certificate issuance | OpenBao |
| Most developer teams | Infisical |
OpenBao is the community fork of HashiCorp Vault (same as OpenTofu for Terraform), released under MPL 2.0 after Vault moved to BSL.
Backup
# Backup Postgres database:
docker exec db pg_dump -U infisical infisical | \
gzip > infisical-db-$(date +%Y%m%d).sql.gz
# Automated weekly backup script:
#!/bin/bash
docker exec infisical-db pg_dump -U infisical infisical | \
gzip > /backups/infisical-$(date +%Y%m%d).sql.gz
find /backups -name "infisical-*.sql.gz" -mtime +30 -delete
Cost Comparison
| Service | Monthly Cost (10 users) |
|---|---|
| Doppler (managed) | $24/month |
| HashiCorp Vault (HCP) | $35+/month |
| AWS Secrets Manager | ~$5 + per-API-call |
| Infisical (self-hosted) | ~$0 (server cost) |
See all open source HashiCorp alternatives at OSSAlt.com/alternatives/hashicorp-vault.