A developer I know committed a .env file with database credentials to GitHub. A bot found it in 12 seconds. By the time he noticed, someone had already dropped his production database.
Stop using .env files. Use a secrets manager.
What Infisical Offers for Free
Infisical free tier:
- Unlimited secrets across unlimited projects
- 5 team members
- End-to-end encryption
- CLI, SDK, and REST API
- Integrations with Vercel, Netlify, GitHub Actions, Docker
- Secret versioning and audit logs
- Self-host option (open source)
Quick Start
# Install CLI
brew install infisical/get-cli/infisical
# Login
infisical login
# Initialize in your project
infisical init
# Pull secrets as env vars
infisical run -- node server.js
# Your app gets DATABASE_URL, API_KEY, etc. without any .env file
REST API
# Get all secrets for an environment
curl 'https://app.infisical.com/api/v3/secrets/raw?workspaceId=YOUR_PROJECT_ID&environment=prod' \
-H 'Authorization: Bearer YOUR_TOKEN'
# Create a secret
curl -X POST 'https://app.infisical.com/api/v3/secrets/raw/DATABASE_URL' \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"workspaceId": "YOUR_PROJECT_ID",
"environment": "prod",
"secretValue": "postgres://user:pass@host:5432/db"
}'
# Update a secret
curl -X PATCH 'https://app.infisical.com/api/v3/secrets/raw/DATABASE_URL' \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"workspaceId": "YOUR_PROJECT_ID",
"environment": "prod",
"secretValue": "postgres://user:newpass@host:5432/db"
}'
Node.js SDK
const { InfisicalClient } = require('@infisical/sdk');
const client = new InfisicalClient({
siteUrl: 'https://app.infisical.com',
auth: { universalAuth: {
clientId: process.env.INFISICAL_CLIENT_ID,
clientSecret: process.env.INFISICAL_CLIENT_SECRET
}}
});
// Get a single secret
const dbUrl = await client.getSecret({
environment: 'prod',
projectId: 'YOUR_PROJECT_ID',
secretName: 'DATABASE_URL'
});
console.log(dbUrl.secretValue);
// Get all secrets
const secrets = await client.listSecrets({
environment: 'prod',
projectId: 'YOUR_PROJECT_ID'
});
// Create/update secrets
await client.createSecret({
environment: 'prod',
projectId: 'YOUR_PROJECT_ID',
secretName: 'NEW_API_KEY',
secretValue: 'sk-abc123'
});
CI/CD Integration (GitHub Actions)
# .github/workflows/deploy.yml
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: infisical/secrets-action@v1
with:
client-id: ${{ secrets.INFISICAL_CLIENT_ID }}
client-secret: ${{ secrets.INFISICAL_CLIENT_SECRET }}
project-id: YOUR_PROJECT_ID
env-slug: prod
- run: npm run deploy
# All secrets are now available as env vars
Docker Integration
# Instead of passing --env-file
# Use infisical to inject secrets at runtime
FROM node:20-alpine
RUN apk add --no-cache bash curl && \
curl -1sLf 'https://dl.cloudsmith.io/public/infisical/infisical-cli/setup.alpine.sh' | bash && \
apk add infisical
WORKDIR /app
COPY . .
RUN npm ci
CMD ["infisical", "run", "--", "node", "server.js"]
Why Secrets Manager Over .env Files
| Secrets Manager | .env Files |
|---|---|
| Encrypted at rest & transit | Plain text on disk |
| Access control & audit logs | Anyone with file access |
| Secret rotation | Manual updates everywhere |
| Works in CI/CD natively | Copy-paste between envs |
| Never in git history | One commit = leaked forever |
Need to securely scrape data? Check out my web scraping actors on Apify — secure, managed data collection.
Need help with secrets management? Email me at spinov001@gmail.com.
Top comments (0)