Architecture & Security
How envv actually works, and why your secrets are safer than SaaS alternatives.
The Core Principle
We store your secrets so teammates can sync them — but we can't read them.
envv uses end-to-end encryption where all encryption and decryption happens on your machine. Secrets are encrypted with your team's public keys before being pushed to our servers. Only team members with private keys can decrypt. Our servers store ciphertext we can't use.
Built on Battle-Tested Technology
envv is built on Mozilla SOPS (Secrets OPerationS), which has been used in production by thousands of companies since 2015. We're not reinventing cryptography - we're adding team collaboration to a proven foundation.
Foundation
- Encryption: AES-256-GCM (NIST-approved AEAD cipher)
- Key format: Modern age keys (simpler than PGP, auditable)
- CLI: Built on SOPS - battle-tested since 2015
- Backend: Handles team coordination, never sees secret values
We're still iterating on the backend architecture. Working with design partners to figure out what actually matters for 3-10 person teams.
How Encryption Works
When You Push Secrets
envv push .env --env prod
AES-256-GCM locally
Ciphertext to backend
What gets encrypted (stored in .envv/ and backend):
What's happening:
- ✓ Secret value is encrypted with AES-256-GCM
- ✓ Data key is encrypted with your team's age public keys
- ✓ MAC ensures file integrity (detects tampering)
- ✓ Zero plaintext on disk
When You Run Your App
envv run -- npm start
In memory only
Zero plaintext on disk
Team Management Architecture
The Trust Model
The backend's job: store encrypted secrets and manage team membership.
Secrets are encrypted on your machine before upload. Your private keys stay on your laptop. The backend stores ciphertext it can't decrypt and tracks which public keys belong to which projects.
What the Backend Knows
| Information | Stored? | Why |
|---|---|---|
| User email | ✓ Yes | Account management |
| Team membership | ✓ Yes | Access control |
| Public keys (age/PGP) | ✓ Yes | Enable encryption for team |
| Audit logs (who, when) | ✓ Yes | Compliance and security |
| Encrypted secrets | ✓ Yes | Stored so teammates can sync (but we can't decrypt) |
| Plaintext secret values | ✗ No | Never sent to our servers |
| Private keys | ✗ No | Generated and stored locally |
Team Workflow
Scenario: Alice wants to give Bob access to team secrets
Security Properties
End-to-End Encryption
Secrets are encrypted on your machine and can only be decrypted by team members with private keys. The backend cannot decrypt your secrets even if compromised. We store encrypted secrets so your team can sync them, but we can't decrypt them. We know who's on your team and when they accessed the system — but we can't read any secret values, even if we wanted to.
Offline-First
Your app continues to work even if:
- Our backend is down
- You're on an airplane
- Your VPN is disconnected
- We go out of business
Encryption and decryption happen entirely locally. Backend is only needed for team management.
Auditable
Unlike SaaS secret managers where you trust their claims:
- ✓ Our code is open source (fork of Mozilla SOPS)
- ✓ Encryption happens client-side (you can verify)
- ✓ Encrypted files are in your git (you control them)
Audit Trail
Here's the thing about secrets: they move through your organization like water through soil. Developers pull them down at coffee shops, CI pipelines grab them at 3am, contractors access them from God-knows-where. And for most teams, that flow is invisible. A black box. You find out something went wrong only after it's already gone wrong.
We built the audit trail because we've been in that war room. The one where everyone's staring at each other asking "who had access to production?" and nobody knows. The silence is deafening. The CEO is on the call. Legal is taking notes.
Never again.
Everything Leaves a Mark
Every time someone touches your secrets — every push, every pull, every permission change — envv writes it down. Not because we're paranoid (okay, a little paranoid), but because the alternative is chaos. Here's what we capture:
| Event | The Story It Tells |
|---|---|
| push | Someone updated secrets. Which environment? How many keys changed? New version created. |
| pull | Someone grabbed secrets. From where? At what time? This is the one you'll query most. |
| rollback | Someone hit undo. From which version to which? Usually means something broke. |
| access granted | The team grew. Who got in? What can they see? Who let them in? |
| access revoked | Someone's out. Contractor finished, employee left, trust ended. The door closed. |
| key rotation | Someone's being careful. Old key deprecated, new key active. Good hygiene. |
The Anatomy of a Log Entry
Each entry answers the questions that matter when you're under pressure:
- Who: Not just a user ID — the actual person. Traceable, accountable.
- When: UTC timestamp. Down to the second. Time zones won't save anyone.
- Where: IP address. User agent. Was it their laptop or a server in Romania?
- What: The action, the resource, the specific thing that was touched.
- Context: Which org, which project, which environment. The full picture.
- Outcome: Did it work? If not, why? Failed attempts matter too.
Pulling the Thread
The API gives you what you need, how you need it. Query the whole org when you're doing compliance reviews. Drill into a single project when something smells off.
Paginated, filterable, exportable. Pipe it to Datadog, dump it into Splunk, build dashboards in Grafana. The data belongs to you — we just keep it safe.
When You'll Thank Yourself
You won't think about audit logs on a normal Tuesday. They're furniture. Background noise. But then comes the day — and it always comes — when you need them desperately:
- The compliance audit: "Show us who accessed production secrets in Q3." You pull the report in thirty seconds. The auditor nods. Meeting over.
- The breach investigation: "What did they touch?" You know. Exactly. Every secret they pulled, every timestamp, every IP. The forensics team can work.
- The awkward offboarding: Contractor's last day was tense. Did they grab anything on the way out? Check the log. Sleep easier.
- The "it's not working" ticket: Developer swears they pushed the new API key. Log says they didn't. Mystery solved in two minutes.
The audit trail won't prevent bad things from happening. But it turns "we have no idea" into "here's exactly what happened." And in a crisis, that's everything.
Threat Model
What We Protect Against
| Threat | Protection |
|---|---|
| Laptop stolen | Secrets encrypted at rest, private key is passphrase-protected |
| Git repo leaked | Secrets are encrypted, useless without private keys |
| Backend compromised | Only encrypted secrets stored, attackers get ciphertext they can't decrypt |
| Insider threat | Audit logs track all access, remove team member = re-encrypt |
| Supply chain attack | Builds are reproducible, binary is signed, code is open source |
What We Don't Protect Against
Be honest about limitations:
- Malware on your laptop (could steal private key or memory)
- Social engineering (could trick you into revealing secrets)
- Quantum computers (AES-256 is quantum-resistant for now)
- $5 wrench attack (XKCD 538)
Comparison to Alternatives
vs HashiCorp Vault
Vault: Centralized secret storage, requires server running 24/7
envv: Decentralized (git), works offline, no server required
vs AWS Secrets Manager
AWS: Cloud-hosted, requires internet, AWS lock-in
envv: Local-first, works offline, cloud KMS optional
vs 1Password Teams
1Password: Great for humans, not designed for CI/CD
envv: CLI-first, designed for developers and automation
vs Plain SOPS
SOPS: Manual key management, no team features
envv: Automated team management, audit logs, rotation
Compliance
envv's architecture makes compliance easier:
- SOC 2: Audit logs track all access
- GDPR: No PII in secrets, data stays in your region
- HIPAA: Encryption at rest and in transit
- PCI-DSS: Secrets never stored unencrypted
Enterprise plan includes compliance documentation and support.
Questions?
Security Concerns?
We take security seriously. If you've found a vulnerability, please report it via GitHub Security Advisories.
For general architecture questions: GitHub Discussions