Security Architecture
๐Ÿ”
Infisical
Open Source Secrets Management Platform

Secrets Platform Architecture: Infisical, Machine Identities, and Vault Boundaries

How Infisical moves secrets from a hardcoded problem to a managed one. The platform components, auth flows for machines and humans, the project-environment-path hierarchy, SDK delivery patterns, and where self-hosting changes the trust model.

Overview

Every application has secrets. Database URLs, API keys, signing tokens, OAuth client IDs. The naive solution is a .env file. It works for one developer on one project. It breaks when you have three environments, four services, a CI system, and a Kubernetes cluster that all need different values for the same key.

Infisical is an open source platform that treats secrets as a first-class resource. Instead of copying values into environment files or injecting them through a patchwork of CI settings and K8s secrets, you store them once and deliver them through a controlled interface. The platform knows which application is asking, which environment it runs in, and what paths it has permission to read. Everything else is denied by default.

The platform ships five integrated products: Secrets Management, Secrets Scanning, Certificate Management (PKI), a KMS for data encryption, and Privileged Access Management. Most teams start with secrets management and expand from there.

๐Ÿ—„๏ธ

Centralized Store

All secrets in one place. Project, environment, and folder-path scoped. Fine-grained RBAC determines who and what can read each path.

๐Ÿค–

Machine Identities

Service accounts for machines. Auth via Universal Auth (clientId/clientSecret), OIDC, AWS, GCP, Azure, Kubernetes, or SPIFFE. Returns short-lived tokens.

๐Ÿ”„

Dynamic Secrets

Generate short-lived credentials on demand. Database users that expire after 15 minutes. No long-lived static passwords for high-value systems.

๐Ÿ”

Secrets Scanning

Detect hardcoded credentials in git history, CI pipelines, and PR diffs before they reach production. Integrates with GitHub, GitLab, and Bitbucket.

The Core Mental Model

Infisical is a delivery infrastructure, not just a key-value store. A secret lives in the platform under a project, environment, and folder path. Applications get their secrets through one of four delivery paths: CLI injection, SDK runtime fetch, Kubernetes operator sync, or Agent daemon. The delivery path determines when the secret leaves the vault and how long it lives in the process. Understanding these paths is the foundation for choosing the right integration pattern.

Platform Components

Infisical is built from four infrastructure pieces. The API backend serves all requests. PostgreSQL stores all secrets and platform data. Redis handles caching, async queues, and cron jobs. The clients are how users and machines interact with the API.

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ CLIENT LAYER โ”‚ โ”‚ Web UI โ”‚ CLI (infisical run) โ”‚ SDK โ”‚ K8s Operator โ”‚ โ”‚ Infisical Agent โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ HTTPS / TLS 1.2+ โ–ผ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ API BACKEND โ”‚ โ”‚ REST API ยท Auth middleware ยท RBAC enforcement โ”‚ โ”‚ Audit log writer ยท Event hooks ยท Rotation engine โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ”‚ โ–ผ โ–ผ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ PostgreSQL โ”‚ โ”‚ Redis โ”‚ โ”‚ secrets (enc.) โ”‚ โ”‚ cache ยท queue ยท cron jobs โ”‚ โ”‚ users, projects โ”‚ โ”‚ session tokens โ”‚ โ”‚ audit events โ”‚ โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

API Backend

The REST API is the single entry point for everything. A request arrives, the API validates the bearer token, checks RBAC for the requested operation and path, then either returns the secret value or denies the request. There is no side channel. The audit log entry is written on every request, success or failure.

Infisical Cloud routes all traffic through Cloudflare, which enforces TLS and terminates DDoS traffic. Self-hosted instances must configure TLS at the reverse proxy layer. The API requires TLS 1.2 or higher and does not serve requests over plaintext HTTP.

Storage Backend: PostgreSQL

All secrets, user records, project configs, RBAC policies, and audit events live in Postgres. Secret values are encrypted at the application layer before being written. The database holds ciphertext, not plaintext. An attacker with read access to the Postgres instance sees encrypted blobs without the decryption keys, which live separately in the API server's key store.

For Infisical Cloud, the database is a managed Postgres instance inside the platform's private network. For self-hosting, you provide the Postgres connection string.

Caching and Queue Layer: Redis

Redis serves three roles. It caches frequently-accessed resources (project metadata, RBAC policies) so that common read paths do not hit Postgres on every request. It backs the async task queue for long-running operations like secret rotation jobs and webhook delivery. It also stores scheduled cron job state, including rotation schedules for dynamic secrets.

The caching layer is a correctness concern, not just a performance one. An RBAC policy change must invalidate cached policies. Infisical handles this internally; you should not bypass the API to write directly to the database, because the cache invalidation will not fire.

Clients

Six delivery surfaces exist for applications and users:

  • Web UI: Browser portal for managing secrets, configuring identities, reviewing audit logs, and setting up integrations.
  • CLI (infisical): Terminal tool for interactive use, scripting, and CI pipelines. infisical run -- <command> spawns a child process with secrets injected as environment variables. Nothing is written to disk.
  • SDKs: Runtime libraries for Node.js, Python, Java, Go, Ruby, and .NET. Fetch secrets at startup, inject into process.env, or query individual values by name.
  • Kubernetes Operator: A Kubernetes-native CRD controller. Syncs secrets from Infisical into Kubernetes Secrets objects. Applications read from K8s secrets as normal; the operator keeps values current.
  • Infisical Agent: A daemon that runs alongside your application. It handles token acquisition, renewal, and secret templating, then writes a rendered config file or populates the environment for the process it manages.
  • Secret Syncs: Push integrations that mirror secrets into third-party systems: GitHub Actions secrets, AWS Parameter Store, Vercel environment variables, and more.

Secret Hierarchy

Infisical organizes everything under four levels: organization, project, environment, and folder path. Every secret lives at exactly one leaf in this tree. The tree is how RBAC scopes access.

Organization: codeamani-labs โ””โ”€โ”€ Project: payments-service โ”œโ”€โ”€ Environment: dev โ”‚ โ”œโ”€โ”€ / STRIPE_SECRET_KEY=sk_test_... โ”‚ โ””โ”€โ”€ /ai ANTHROPIC_API_KEY=... โ”œโ”€โ”€ Environment: staging โ”‚ โ”œโ”€โ”€ / STRIPE_SECRET_KEY=sk_test_... โ”‚ โ””โ”€โ”€ /database DATABASE_URL=postgres://... โ””โ”€โ”€ Environment: production โ”œโ”€โ”€ / STRIPE_SECRET_KEY=sk_live_... โ”œโ”€โ”€ /ai ANTHROPIC_API_KEY=... โ”œโ”€โ”€ /database DATABASE_URL=postgres://prod... โ””โ”€โ”€ /payments DARAJA_CONSUMER_KEY=...

Projects

A project is the top-level container for one service or product. Each project has its own set of environments, its own secret namespace, and its own access control list. Machine Identities are assigned to projects and scoped to specific environment+path combinations within them.

Environments

Each project gets three environments by default: dev, staging, and production. You can add custom environments. The same secret name can exist in each environment with a different value. A DATABASE_URL in dev points to a local Postgres; the same key in production points to the managed instance with SSL and a connection pooler.

Folder Paths

Within an environment, secrets are organized into folder paths. The root path / holds shared top-level secrets. Subpaths group by domain: /ai, /database, /payments, /storage. This matters for RBAC. A Machine Identity running the billing service can be scoped to production /payments only. It cannot read the AI keys in production /ai even if it tries. The scoping is enforced at the API layer, not at the application layer.

Path Scoping vs. Per-Secret RBAC

Infisical uses path-based RBAC rather than per-secret permissions. This means you design your folder structure with access control in mind, not as an afterthought. A payment service CI identity scoped to production /payments automatically gets access to every secret under that path. Adding a new secret to that path requires no RBAC change. Moving a secret to a different path may require updating role assignments. Design paths around the teams and services that need them, not around alphabetical ordering.

Machine Identity and Auth

A Machine Identity is an entity that represents a workload. Think of it as the Infisical equivalent of an AWS IAM role or a GCP service account. You create one identity per environment per service. Each identity gets a role assignment and an authentication method. At runtime the workload authenticates using that method and receives a short-lived access token. All subsequent API calls use that token.

01

Create Identity

Create a Machine Identity in the dashboard. Assign a role (viewer, operator, custom). Configure an auth method and token TTL.

02

Authenticate

The workload presents credentials to the Infisical API using the configured method (clientId/secret, OIDC JWT, AWS SigV4, etc.).

03

Receive Token

Infisical validates the credentials and returns a short-lived access token. The TTL is configured per identity (default: 7 days for Universal Auth; shorter for OIDC).

04

Fetch Secrets

All subsequent API requests use the access token as a bearer token. The API enforces the identity's RBAC scope on every request.

Universal Auth

The default auth method for servers and CI pipelines. The identity gets a clientId and a clientSecret. These two values are the bootstrap credentials: the only secrets that must exist outside Infisical. Store them in your platform's secret management (Vercel env vars, GitHub Actions secrets). At startup, the application exchanges them for a short-lived Infisical access token and uses that token for all secret fetches.

// Node.js SDK โ€” Universal Auth bootstrap import { InfisicalSDK } from '@infisical/sdk'; const client = new InfisicalSDK(); await client.auth().universalAuth.login({ clientId: process.env.INFISICAL_CLIENT_ID, clientSecret: process.env.INFISICAL_CLIENT_SECRET, }); // Cache the client at module scope. One auth per cold start. export default client;

OIDC Auth

For workloads running on platforms that issue OIDC tokens (GitHub Actions, GitLab CI, AWS EKS, GCP Cloud Run), you can skip the clientSecret entirely. The CI system issues a JWT bound to the workflow run. Infisical verifies the JWT signature against the provider's JWKS endpoint, checks audience and claim conditions you configure, and issues an access token. No static secret is exchanged. The bootstrap problem disappears.

This is the preferred method for GitHub Actions. The workflow requests an OIDC token, Infisical verifies it, and secrets are fetched for that run only. A leaked token is useless after the run ends.

Platform-Native Auth (AWS, GCP, Azure, Kubernetes)

For workloads on major cloud platforms, Infisical can verify platform-issued identity assertions directly. An EC2 instance authenticates using AWS SigV4 against the EC2 metadata service. A GKE pod presents its service account JWT. An AKS deployment uses its managed identity. The platform validates the assertion against its native authentication endpoint and issues an Infisical token. No client secret is managed by the application at all.

Lockout and Rate Limiting

Universal Auth login endpoints have lockout enabled by default. 3 consecutive failed login attempts within a 30-second window locks the endpoint for 5 minutes. This is a brute-force defense for the bootstrap credentials. OIDC and platform-native methods are not affected because they do not use passwords. For Universal Auth in automated systems, use a retry budget with backoff rather than aggressive retry loops, since failures will lock the identity.

Auth Method Bootstrap Secret Required Best For Token Lifetime
Universal Auth clientId + clientSecret Any server, Vercel, Render, VMs Configurable (1h to 7d)
OIDC Auth None (JWT from provider) GitHub Actions, GitLab CI, GKE, EKS Per job/run
AWS Auth None (EC2/Lambda metadata) EC2, Lambda, ECS, EKS Configurable
Kubernetes Auth None (pod service account JWT) Any K8s cluster with OIDC Configurable
Token Auth Static token (rotate manually) Simple scripts, legacy integrations Until revoked
SPIFFE Auth None (SVID from SPIRE) Service mesh workloads with SPIRE Per SVID rotation

Delivery Methods

Once authenticated, the application needs to get secrets into its process. The right method depends on when you need the secret, whether the runtime restarts frequently, and how the rest of your stack is built.

CLI Injection: infisical run

The simplest integration. Wrap your start command with infisical run --env=production -- node server.js. Infisical authenticates, fetches all secrets at the configured path, and injects them as environment variables into the child process. The parent shell sees nothing. Nothing is written to disk. The secrets are visible only inside the running process.

# Dev: inject secrets, start Next.js infisical run --env=dev -- npm run dev # Production: specific path, non-interactive token infisical run \ --env=production \ --path=/payments \ --token="$INFISICAL_TOKEN" \ -- node dist/server.js # Non-interactive auth (CI): exchange credentials for a token first export INFISICAL_TOKEN=$( infisical login \ --method=universal-auth \ --client-id="$INFISICAL_CLIENT_ID" \ --client-secret="$INFISICAL_CLIENT_SECRET" \ --silent --plain )

SDK: Runtime Fetch

The SDK authenticates at process startup and fetches secrets at runtime. This is the right choice for long-running servers, Vercel functions, and any runtime where you want to handle secret values in code rather than rely on environment variable injection. The key pattern: authenticate once at module scope, cache the SDK client, then fetch secrets by name or inject a whole path into process.env in one call.

// Fetch and inject all secrets from a path const { secrets } = await client.secrets().listSecrets({ projectId: 'proj_abc123', environment: 'production', secretPath: '/payments', expandSecretReferences: true, attachToProcessEnv: true, // populates process.env }); // Or fetch a single secret and fail loud if missing const secret = await client.secrets().getSecret({ secretName: 'STRIPE_SECRET_KEY', projectId: 'proj_abc123', environment: 'production', secretPath: '/payments', expandSecretReferences: true, });

Note that getSecret throws a StatusCode=404 error when the secret is absent. This is correct behavior. A missing secret at startup should crash the process loudly, not produce a silent undefined that causes a downstream failure two minutes later.

Kubernetes Operator

The Kubernetes Operator syncs Infisical secrets into Kubernetes Secret objects using CRDs. Applications read from K8s secrets as normal through environment variable references or volume mounts. The operator watches for changes in Infisical and re-syncs on updates. This keeps the interface familiar for teams already using K8s secrets, while making Infisical the single source of truth for values.

The operator authenticates using Kubernetes Auth (the pod's own service account JWT). No static credentials are stored in the cluster. The CRD definition specifies which project, environment, and path to sync, and into which Kubernetes namespace and Secret name to write.

Infisical Agent

The Agent is a sidecar daemon that handles token lifecycle and secret templating for processes that cannot use the SDK or CLI. It authenticates, keeps its token refreshed, and can write rendered configuration files using a template syntax. Applications read a local file or socket rather than calling the Infisical API directly. The Agent abstracts the auth complexity away from the application entirely.

Secret Syncs (Push Integrations)

For platforms that expect secrets in their own native format, Infisical can push values outward. Supported targets include GitHub Actions repository secrets, Vercel project environment variables, AWS Parameter Store, AWS Secrets Manager, GCP Secret Manager, and more. The sync runs when secrets change in Infisical. This means you edit secrets once in Infisical and let the sync push to the downstream platform, rather than maintaining values in two places.

Choosing a Delivery Method

Use CLI injection for local development and CI scripts. Use the SDK for servers that start infrequently and need to handle secret values programmatically. Use the Kubernetes Operator when your team already manages K8s secrets and you want to minimize application changes. Use the Agent for legacy applications that read config files and cannot be changed to use an SDK. Use Secret Syncs only for platforms where you cannot run any Infisical client directly (e.g., Netlify build environment, third-party SaaS that reads from GitHub secrets).

Encryption and Security Model

Infisical's security model covers encryption at rest and in transit, authenticated and authorized access for every request, and a full audit trail of every operation. The threat model is explicit about what it covers and what it does not.

Encryption at Rest

Secret values are encrypted at the application layer before being written to PostgreSQL. The database holds ciphertext. Infisical uses proven symmetric encryption (AES-256) for stored secrets. The encryption keys are managed by the API server, not stored alongside the ciphertext in the database.

This design means that read access to the PostgreSQL instance does not expose secret values. An attacker who dumps the database gets encrypted blobs. They need the application-layer keys to decrypt them, and those keys are not in the database.

Encryption in Transit

All client-to-server communication goes over TLS. Infisical Cloud routes through Cloudflare, which enforces TLS 1.2 as a minimum and provides DDoS protection. For self-hosted instances, TLS termination is the operator's responsibility (typically at an nginx or Caddy reverse proxy in front of the Infisical containers).

Audit Log

Every operation generates an audit event. Reads, writes, role changes, auth failures, and policy updates all appear in the audit log with a timestamp, actor identity, source IP, user agent, and relevant metadata. The log is append-only. You cannot delete entries through the API. For compliance requirements (SOC 2, ISO 27001), the audit log is the primary evidence trail for secret access patterns.

What the Threat Model Covers

  • Eavesdropping on communications: TLS on all client-server and server-storage paths.
  • Data tampering: Integrity checks at the storage layer; inconsistencies abort transactions and raise alerts.
  • Unauthorized access: Every inbound request requires a valid bearer token with sufficient RBAC permissions for the requested operation and path.
  • Actions without accountability: Audit log covers all mutations and sensitive reads.
  • Storage confidentiality breach: Application-layer encryption means plaintext never touches the database.
  • Anomalous access patterns: Infisical monitors for authentication attempts from previously unseen sources.

What the Threat Model Does Not Cover

  • Uncontrolled database access: An attacker with full PostgreSQL write access can manipulate or delete data in ways the application cannot prevent.
  • Runtime memory intrusion: A process with access to the live Infisical server's memory can extract decrypted values in flight.
  • Compromised client identities: If a machine identity's credentials are exposed, the attacker has access at that identity's permission level.
  • Administrator configuration tampering: Admin access to the Infisical dashboard can change RBAC policies to grant wider access.

These are not defects. They define what the system is designed to defend against and where operational controls must compensate.

Security Property Mechanism Where It Applies
Secrets encrypted at rest AES-256, application-layer PostgreSQL storage
Secrets encrypted in transit TLS 1.2+ (Cloudflare on Cloud) Client to API, API to storage
Authenticated access Bearer token on every request All API endpoints
Authorized access RBAC scoped to project/env/path Every read, write, and admin op
Audit trail Append-only event log All mutations and sensitive reads
Short-lived tokens TTL on all machine access tokens Machine Identities
Brute-force protection Lockout after 3 failures in 30s Universal Auth login endpoint
IP restrictions on tokens Configurable per Machine Identity Machine Identity access tokens

Cloud vs Self-Hosted

Infisical is fully open source under MIT license. The same codebase powers both Infisical Cloud and self-hosted instances. The choice between them is a data residency and operational question, not a features question.

Infisical Cloud

Managed service at app.infisical.com. Infisical operates PostgreSQL, Redis, and the API layer. All traffic routes through Cloudflare. The team handles upgrades, backups, uptime, and security patches. SOC 2 Type II certified. For most teams, this is the right default: it removes operational overhead and provides enterprise compliance out of the box.

Pricing is per-seat for human users. Machine Identities and API calls are not per-seat. The free tier supports unlimited secrets and environments with 5 member seats and 5 machine identities. Paid tiers start at $6 per seat per month and unlock SCIM provisioning, SAML SSO, and advanced RBAC.

Self-Hosted

Run Infisical on your own infrastructure. The official deployment path is Docker Compose or Helm chart. You bring PostgreSQL and Redis. The API containers connect to your storage. Your reverse proxy handles TLS. Infisical provides the application containers; you provide the substrate.

Self-hosting is worth the operational cost in specific cases: data residency requirements under regulations like GDPR or KDPA 2019 that restrict cross-border data transfer, air-gapped environments where outbound internet is not permitted, or organizations that cannot allow any third party to hold encrypted copies of their secrets even in ciphertext form.

When self-hosting, the siteUrl parameter on the SDK and the --domain flag on the CLI must point to your instance URL. The default https://app.infisical.com will not work. This is a common misconfiguration during initial setup.

Hybrid: Self-Host Infisical, Cloud-Backed Secrets

A third pattern: run the Infisical API yourself but back it with a managed database (Neon, Supabase, AWS RDS). This keeps compute and application data on your infrastructure while offloading database operations to a managed service. The Infisical API does not care where PostgreSQL lives as long as it gets a valid connection string.

Dimension Cloud Self-Hosted
Data residency US/EU regions; your secrets transit Infisical infra Full control; secrets never leave your network
Ops burden Zero; Infisical manages all infra You run Postgres, Redis, containers, TLS, upgrades
Compliance certifications SOC 2 Type II, ISO 27001 (Cloud) Must achieve your own certification for your instance
Feature parity Full; latest features land on Cloud first Depends on the version you run; manual upgrade path
Uptime SLA 99.99% on Enterprise tier Your responsibility; no SLA from Infisical
Air-gap support Not possible; requires outbound internet Supported; no outbound dependencies after setup

Cost Reality Check

Cost Reality Check

Infisical Cloud pricing is seat-based, not usage-based. You pay per human member, not per secret fetch or API call. Machine Identities are not charged per-seat. This means a team with 4 developers and 30 microservices, each with its own Machine Identity, pays for 4 seats. The 30 service identities making thousands of secret fetches per day add nothing to the bill.

The free tier gives you unlimited secrets, environments, and folders, with 5 member seats and 5 Machine Identities. The 5-identity limit is the constraint that forces most teams off free. Each microservice, CI pipeline, and staging environment typically needs its own identity for least-privilege scoping.

Self-hosting costs shift from licensing to infrastructure and engineering time. Running Postgres, Redis, and the Infisical containers on a cloud VM costs roughly $30 to $80 per month for a small deployment. Add managed database and Redis (e.g., Neon + Upstash) and it lands around $20 to $50. The hidden cost is the engineering time to handle upgrades, backups, and incident response when the secrets platform itself is unavailable.

Scenario Cloud Cost Notes
Startup: 3 devs, 5 services $0 (free tier) 5 seats, 5 identities covers this exactly
Small team: 8 devs, 20 services $48/mo (Pro, $6/seat x 8) 20 Machine Identities on Pro tier (unlimited)
Mid-size: 25 devs, 60 services $150/mo (Pro, $6/seat x 25) Still seat-based; service count is irrelevant
Self-hosted on VPS $30 to $80/mo infra Plus ops time for upgrades and incident response
Self-hosted with managed DB $20 to $50/mo Neon + Upstash Redis + 1x small VM for API
The Bootstrap Secret Is Still a Secret

Universal Auth requires two bootstrap values: INFISICAL_CLIENT_ID and INFISICAL_CLIENT_SECRET. These must live somewhere before Infisical can fetch anything. Common patterns: store them in Vercel project environment variables (for Vercel-hosted services), in GitHub Actions secrets (for CI), or in the platform's native secret system (AWS Secrets Manager, GCP Secret Manager, Azure Key Vault). The bootstrap secret is narrowly scoped: it only grants access to the paths that specific Machine Identity is assigned to. A leaked bootstrap secret for the payments service cannot access the AI keys or any other identity's paths.

Key Takeaways

Principles

  1. Create one Machine Identity per service per environment. A single identity with access to all environments is a single point of failure. Scoping each identity to production /payments or staging /database limits blast radius when a credential is compromised.
  2. Never use personal tokens for automated systems. Personal tokens are tied to a user account. When someone leaves the team, their token becomes invalid and breaks every automated process that used it. Machine Identities are not tied to any human account.
  3. Use OIDC auth wherever the platform supports it. GitHub Actions, GitLab CI, GCP Cloud Run, and AWS EKS can all issue OIDC tokens. OIDC eliminates the bootstrap secret entirely. There is no clientSecret to rotate, leak, or forget to revoke.
  4. Cache the authenticated SDK client, not individual secret values. Re-authenticating on every request adds latency and rate-limit exposure. Create the InfisicalSDK instance at module scope, authenticate once, and reuse it across all requests in that process lifetime.
  5. getSecret throws on missing keys by design. A missing secret at startup should crash the process. Catching the error and returning undefined turns a deployment configuration mistake into a runtime failure that is much harder to diagnose.
  6. Design folder paths around access boundaries, not taxonomy. The path /ai should contain everything the AI service needs and nothing the payments service needs. Path-based RBAC means your folder structure is your access control policy. Refactoring paths later requires updating role assignments.
  7. infisical scan belongs in CI, not just local development. Running the scanner only locally misses credentials that get committed in branches and PRs before the scan runs. Add it as a required CI step so that hardcoded secrets block the merge rather than reaching production.
  8. Secret Syncs are a bridge, not a destination. Using Infisical to push secrets to GitHub Actions or Vercel env vars is useful for platforms that cannot run a client. But every sync is a copy of the secret outside Infisical's audit trail. Prefer native delivery (SDK, CLI, Agent) where possible, and use syncs only where no client-side option exists.
  9. Self-hosting costs more than it appears. The software is free. The operational burden is not. Every upgrade cycle, every incident where the secrets platform is down, and every backup restoration test is engineering time. Cloud is usually right unless data residency or air-gap requirements force the decision.