Security architecture

Zero plaintext.
Every layer.

envfyio is built around a single constraint: no secret ever touches the application database in the clear. Encryption at rest, private networking, zero-trust access, short-lived tokens, immutable audit logs.

Threat model

What we protect against

The attack surface we designed around — and the controls that mitigate each risk.

DB exfiltration

If an attacker dumps the application database, they find no secret values — all secrets are stored encrypted via Infisical's end-to-end encryption model.

E2E encryption at rest
Credential leakage

Long-lived API keys committed to repos or stored in .env files are the most common secret leak vector.

Short-TTL tokens · no repo secrets
Public API exposure

A secrets API on the public internet is a target regardless of auth strength. envfyio's API is not reachable from outside the tailnet.

Tailscale — tailnet-only API
Lateral movement

A compromised service should not be able to read secrets belonging to other services. Namespace isolation prevents cross-app access.

Per-app project isolation
Insider access

Without audit logs, it's impossible to know what was accessed and by whom. All access events are logged immutably.

Immutable audit log
Stale credentials

Credentials that never expire accumulate risk over time. All machine identities issue short-TTL tokens with configurable max lifetimes.

Auto-expiring tokens · rotation
Network

Private by design — not by configuration

The secrets API has no public IP address. Access requires being on the Tailscale tailnet. The web dashboard adds a second gate via Cloudflare Access.

Internet
CI runner
GitHub Actions
Dev laptop
admin
k8s pod
gofyio / prod
↓ Tailscale WireGuard tunnel
Tailnet · envfyio.internal
Infisical API
:8080
Web UI
+ CF Access
↓ Running on dev102
Host · dev102
PostgreSQL
encrypted at rest
Redis
session cache
Infisical
core service
No public ingress for the secrets API
Cloudflare Access — identity-gated web UI
TLS on every connection, even inside the tailnet
Encryption

End-to-end encryption at rest

Infisical uses E2EE so that secret values are encrypted before they leave the client and can only be decrypted with the workspace key — not at the database layer.

AES-256-GCM

Secret values are encrypted with AES-256-GCM. Each workspace has a unique encryption key — never stored alongside the ciphertext.

Key hierarchy

Workspace key → secret key → ciphertext. Each layer is separately derived. Compromise of one level does not expose the full keyspace.

DB has only ciphertext

The PostgreSQL database never holds plaintext secret values. A full DB dump yields only encrypted blobs — useless without the workspace key.

TLS everywhere

All API traffic uses TLS 1.3 — including inside the tailnet. Secrets are never transmitted in the clear, even over private network segments.

Identity & access

Short-lived tokens, scoped access

Machine identities replace long-lived API keys. Every token has an expiry, a project scope, and a path restriction. Revocation is instant.

Control Before envfyio With envfyio
Credential type Long-lived API key Short-TTL access token
Scope Full DB access Per-project, per-env, per-path
Rotation Manual, infrequent Automatic, configurable TTL
Revocation Deploy required Instant — dashboard or API
Audit trail None Every access logged with actor
Storage Repo / .env / DB Infisical only — never in app
envfyio · Security · #AEFF00

Zero plaintext. Every layer. Every app.