← Back to dashboard
infisicaltoolingfresh

Infisical Integration Guide

Text
██╗███╗   ██╗███████╗██╗███████╗██╗ ██████╗ █████╗ ██╗
██║████╗  ██║██╔════╝██║██╔════╝██║██╔════╝██╔══██╗██║
██║██╔██╗ ██║█████╗  ██║███████╗██║██║     ███████║██║
██║██║╚██╗██║██╔══╝  ██║╚════██║██║██║     ██╔══██║██║
██║██║ ╚████║██║     ██║███████║██║╚██████╗██║  ██║███████╗
╚═╝╚═╝  ╚═══╝╚═╝     ╚═╝╚══════╝╚═╝ ╚═════╝╚═╝  ╚═╝╚══════╝

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.local files. Fetch at runtime via a Machine Identity, inject locally with infisical run, and catch leaks before they ship with infisical 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/sdk for Node, infisicalsdk for 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 scan finds 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:

Official Documentation


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:

Bash
INFISICAL_CLIENT_ID=...        # the ONLY secrets that stay in .env.local / Vercel env
INFISICAL_CLIENT_SECRET=...

2. SDK — fetch secrets at runtime (Node)

Bash
npm install @infisical/sdk
TypeScript
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.

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:

Bash
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.

YAML
# .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.12
        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.local sprawl: move Anthropic/Gemini, Daraja/M-Pesa, Supabase/Neon, and Cloudflare credentials into Infisical; the app fetches them via Machine Identity. Only INFISICAL_CLIENT_ID/_SECRET remain in .env.local / Vercel env. See ENV_MASTER.md.
  • Security: the bootstrap clientSecret is still a secret — keep it server-side, scope the Machine Identity to least privilege, and rotate it. infisical scan belongs 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-action imports secrets into workflows via a Machine Identity (Universal Auth or OIDC) — see §4; pairs with the Vercel deploy pipeline in DEPLOYMENT_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).