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.