Infisical Integration Guide
Technology: infisical · Category: tooling · Last reviewed: 2026-08-23
Source: https://tech-stack.codeamanilabs.org/guide/infisical
Insight:
Infisical centralizes secrets so you stop scattering keys across
.env.localfiles — a Machine Identity fetches them at runtime, leaving only two bootstrap secrets behind. Open-source and self-hostable (data residency for KDPA), andinfisical scanin CI catches leaked keys before they ship.
██╗███╗ ██╗███████╗██╗███████╗██╗ ██████╗ █████╗ ██╗
██║████╗ ██║██╔════╝██║██╔════╝██║██╔════╝██╔══██╗██║
██║██╔██╗ ██║█████╗ ██║███████╗██║██║ ███████║██║
██║██║╚██╗██║██╔══╝ ██║╚════██║██║██║ ██╔══██║██║
██║██║ ╚████║██║ ██║███████║██║╚██████╗██║ ██║███████╗
╚═╝╚═╝ ╚═══╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═════╝╚═╝ ╚═╝╚══════╝
Infisical Integration Guide
Focus: Centralize codeAmani's secrets (Anthropic/Gemini keys, Daraja/M-Pesa creds, DB URLs) in one open-source, self-hostable platform instead of scattered
.env.localfiles. Fetch at runtime via a Machine Identity, inject locally withinfisical run, and catch leaks before they ship withinfisical scan.
Overview
Infisical is an open-source secret-management platform. It replaces ad-hoc .env sprawl
with a single source of truth organized by project → environment → folder path. Three
ways codeAmani uses it:
- SDK (
@infisical/sdkfor Node,infisicalsdkfor Python) — fetch secrets at runtime. - CLI (
@infisical/cli) —infisical run -- <cmd>injects secrets as env vars into a child process (they never hit disk);infisical scanfinds leaks in code + git history. - Self-host — point any client at your own instance via
siteUrl(data residency for KDPA compliance).
Auth uses a Machine Identity + Universal Auth: exchange a clientId/clientSecret
for a short-lived token. Those two bootstrap secrets are the only thing that still lives
in .env.local / Vercel env — everything else moves into Infisical.
Here is the core idea at a glance — your app carries only two bootstrap secrets and fetches the rest at runtime:
flowchart LR
A["App at runtime"] -->|"clientId + clientSecret<br/>from .env.local"| B["Machine Identity<br/>Universal Auth"]
B -->|"short-lived token"| C["Infisical platform<br/>project · environment · path"]
C -->|"secret value"| A
A -->|"uses key"| D["Anthropic · Daraja<br/>Supabase · Cloudflare"]
Official Documentation
| Resource | URL |
|---|---|
| Getting started | https://infisical.com/docs/documentation/getting-started/introduction |
| Node SDK | https://infisical.com/docs/sdks/languages/node |
| CLI overview | https://infisical.com/docs/cli/overview |
| Universal Auth (machine identity) | https://infisical.com/docs/documentation/platform/identities/universal-auth |
| GitHub (self-host) | https://github.com/Infisical/infisical |
1. Bootstrap credentials
Create a Machine Identity in the Infisical dashboard, attach it to your project, and
copy its Universal Auth clientId + clientSecret. These two are the bootstrap secrets:
INFISICAL_CLIENT_ID=... # the ONLY secrets that stay in .env.local / Vercel env
INFISICAL_CLIENT_SECRET=...
2. SDK — fetch secrets at runtime (Node)
npm install @infisical/sdk # current major is v5.x (from the node-sdk-v2 repo)
import { InfisicalSDK } from "@infisical/sdk";
// Cloud default; pass { siteUrl } for a self-hosted instance
const client = new InfisicalSDK();
await client.auth().universalAuth.login({
clientId: process.env.INFISICAL_CLIENT_ID!,
clientSecret: process.env.INFISICAL_CLIENT_SECRET!,
});
const secret = await client.secrets().getSecret({
secretName: "DARAJA_CONSUMER_SECRET",
projectId: "proj_abc123",
environment: "production",
secretPath: "/mpesa", // optional folder
expandSecretReferences: true,
});
console.log(secret.secretValue);
getSecret throws on a missing key (StatusCode=404 Secret not found) — handle it rather
than silently falling back, so a misconfigured environment fails loudly at startup.
SDK v5 note:
getSecret/listSecretsacceptviewSecretValue(defaulttrue). If you passviewSecretValue: false,secretValuecomes back masked as<hidden-by-infisical>— leave it at the default when you actually need the value.
3. CLI — local dev + leak scanning
The CLI gives you two wins — secrets injected into dev without ever touching disk, and a scanner that catches leaks before they ship:
flowchart TD
A["infisical login + init<br/>links repo to project · env"] --> B["infisical run -- npm run dev"]
B -->|"inject as env vars<br/>nothing written to disk"| C["dev server child process"]
A --> D["infisical scan"]
D --> E{"Leaked secret in<br/>code or git history?"}
E -->|"yes"| F["fail pre-commit · CI"]
E -->|"no"| G["safe to ship"]
npm install -g @infisical/cli
infisical login # interactive
infisical init # link the repo to a project/environment
# Inject secrets as env vars into the dev server (nothing written to disk):
infisical run -- npm run dev
# Pre-commit / CI: scan code + git history for leaked secrets
infisical scan
4. CI/CD — secrets in GitHub Actions
In CI you don't run infisical login interactively — instead the official
Infisical/secrets-action authenticates a
Machine Identity and injects the project's secrets into the job as env vars. Store only
the two bootstrap values (client-id/client-secret) as GitHub Actions secrets; everything
else stays in Infisical.
flowchart LR
A["GitHub Actions job"] -->|"client-id + client-secret<br/>from GH secrets"| B["Infisical secrets-action<br/>Universal Auth"]
B -->|"short-lived token"| C["Infisical platform<br/>project · env · path"]
C -->|"export-type env"| D["secrets as env vars<br/>in later steps"]
D --> E["build · deploy · migrate"]
# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# Authenticate via Machine Identity (Universal Auth) and inject secrets
# as env vars for every subsequent step in this job.
- uses: Infisical/secrets-action@v1.0.16
with:
method: "universal" # default
client-id: ${{ secrets.INFISICAL_CLIENT_ID }} # the only two GH secrets you need
client-secret: ${{ secrets.INFISICAL_CLIENT_SECRET }}
project-slug: "your-project-slug"
env-slug: "production" # dev | staging | production
secret-path: "/" # default; e.g. "/mpesa"
domain: "https://app.infisical.com" # change for a self-hosted instance
# Secrets are now plain env vars — reference them like any other.
- name: Deploy
run: |
echo "Deploying with DARAJA_CONSUMER_KEY=${DARAJA_CONSUMER_KEY:+set}"
npm run deploy
Inputs above are the verified Universal Auth keys; export-type defaults to env. Set
export-type: file (with file-output-path) instead if a step needs an on-disk .env.
OIDC (method: oidc, identity-id) is also supported and removes the long-lived
client-secret entirely — prefer it once your CI provider trust is configured.
Gotcha — least-privilege identity scope: create a separate Machine Identity per
environment and grant it read-only access to only the project/path that workflow needs
(e.g. the production env at /). A CI identity scoped to every project becomes a single
key that can exfiltrate your entire secret store if the client-secret GH secret leaks.
Rotate the client-secret on a schedule and keep the identity off any path it doesn't read.
codeAmani notes
- Replaces
.env.localsprawl: move Anthropic/Gemini, Daraja/M-Pesa, Supabase/Neon, and Cloudflare credentials into Infisical; the app fetches them via Machine Identity. OnlyINFISICAL_CLIENT_ID/_SECRETremain in.env.local/ Vercel env. SeeENV_MASTER.md. - Security: the bootstrap
clientSecretis still a secret — keep it server-side, scope the Machine Identity to least privilege, and rotate it.infisical scanbelongs in the pre-deploy checklist (SECURITY.md) to catch committed keys. - Compliance / data residency: self-host (
siteUrl) to keep secret material in a region you control — relevant to KDPA 2019 (COMPLIANCE_GUIDE.md). - CI/CD: the official
Infisical/secrets-actionimports secrets into workflows via a Machine Identity (Universal Auth or OIDC) — see §4; pairs with the Vercel deploy pipeline inDEPLOYMENT_RUNBOOK.md. - Runtime cost: fetching on every cold start adds latency — cache the authenticated client / fetched secrets per lambda instance (pairs well with the Upstash cache).
Official docs: