Git for your secrets.

Share secrets with your team without trusting a third party.
Sync directly between machines. No cloud accounts, no subscriptions, no vendor lock-in.

Terminal
$ envctl init
Generating identity...
 Fingerprint: sha256:7f3a...

$ envctl env var set API_KEY=sk_live_...
 Secret encrypted and signed

$ envctl status
 Synced with 2 peers

Why envctl?

No .env Files

Run commands with secrets injected directly into the process. No plaintext files on disk, no accidental commits.

P2P Sync

Sync secrets across the internet with remote teammates. Optional relay for async sync when peers are offline.

Post-Quantum

ML-KEM-768 encryption protects your secrets against future quantum attacks.

Audit Trail

Every change is cryptographically signed. Know who changed what, and when.

Git-like Workflow

Familiar commands: push, pull, status, log. Branch-like environments for dev, staging, prod.

Remote Teams

Works across the globe. Invite distributed teammates with a single command. Revoke access instantly.

A Different Approach

Most secrets tools require you to trust a cloud provider with your plaintext data.
envctl takes a fundamentally different approach: you hold the keys.

Traditional Tools

Doppler, Infisical, 1Password, etc.

  • Centralized server holds your secrets
  • You authenticate to retrieve them
  • Vendor sees your plaintext data
  • Network required for every access
  • Per-seat pricing scales with team
  • Vendor lock-in

envctl

Distributed, cryptographic ownership

  • Secrets encrypted locally before sync
  • Peer-to-peer sync between machines
  • No one sees plaintext but you
  • Offline-first, works without network
  • Free and open source
  • Export anytime, no lock-in

Think of it like Git changed version control from centralized (SVN) to distributed.
envctl does the same for secrets: cryptographic ownership with P2P sync.

Install

go install envctl.dev/go/envctl@latest

Requires Go 1.25+. See releases for other options.

Quick Start

1

Initialize your identity

$ envctl init

Generates your keypair. This is your identity across all projects.

2

Create a project

$ envctl project create

Sets up envctl in your current directory.

3

Add secrets

$ envctl env var set API_KEY=sk_live_...

Secrets are encrypted immediately with your key.

4

Invite your team

$ envctl project invite alice@example.com
Share this with your teammate:
  envctl join abc123...

Teammates join with a single command.

5

Use your secrets

$ envctl env use prod
 .env written (2 secrets)

Materializes decrypted .env file for your current session.

Or run commands without writing secrets to disk:

$ envctl env apply -- npm start

Commands

envctl init Generate identity
envctl project create Create project
envctl join Join existing project
envctl env var set KEY=val Add or update secret
envctl env var delete KEY Remove secret
envctl env var list Show secrets
envctl env use <env> Write .env file
envctl env apply -- <cmd> Run with secrets (no file)
envctl env shell Interactive shell with secrets
envctl env create <name> Create environment
envctl env delete <name> Delete environment
envctl status Show sync status
envctl log View history
envctl project invite Invite teammate
envctl project relay set <url> Enable relay sync
envctl project relay status Check relay connection
envctl daemon start Start background daemon
envctl daemon stop Stop daemon
envctl env list List environments
envctl env clear Remove .env file
envctl env edit Edit in $EDITOR
envctl doctor Check installation health
envctl ci keygen Generate CI keypair
envctl ci export Export encrypted bundle
envctl ci apply -- <cmd> Run with CI secrets

Environments

Projects have multiple environments (dev, staging, prod) with separate secrets. Team members can have access to specific environments.

1

List environments

$ envctl env list
Environments for 'myproject':

* dev          (3 members) [default]
  staging      (2 members)
  prod         (1 member)

See all environments and who has access. The asterisk marks your current environment.

2

Create a new environment

$ envctl env create qa
 Created environment 'qa'

Add environments as your project grows. New members get access to default environments only.

3

Switch environments

$ envctl env use staging
 .env written (5 secrets)

Decrypts and writes secrets for the selected environment to your .env file.

4

Run without .env file

$ envctl env apply -e prod -- ./deploy.sh
Passphrase:
 Running with 8 secrets

For extra security, run commands with secrets injected directly into the process environment. No .env file is written to disk—secrets exist only in memory for the duration of the command.

5

Interactive shell with secrets

$ envctl env shell -e staging
Passphrase:
Starting zsh with 5 secrets from myproject/staging
Type 'exit' to leave and clear secrets from memory.

$ echo $API_KEY
sk_live_...
$ exit

Exited envctl shell. Secrets cleared from memory.

Start an interactive shell session with secrets loaded. Your normal shell (bash, zsh, PowerShell) starts with secrets available. Type 'exit' when done—secrets are cleared from memory automatically.

6

Delete an environment

$ envctl env delete old-env --force
 Deleted environment 'old-env'

Remove environments you no longer need. Use --force if members still have access.

7

Local overrides

$ cat .env.dev
DATABASE_URL=postgres://localhost/mydb
DEBUG=true

$ envctl env use dev
 .env written (5 secrets)
Applied 2 override(s) from .env.dev

Create a .env.<environment> file (e.g., .env.dev) to override shared secrets with personal settings. Local overrides take precedence over secrets from the ops chain. This is useful for local database URLs, debug flags, or other per-developer settings that shouldn't be shared. Use --no-overrides to ignore local override files.

Relay Server

The relay enables async sync when teammates are offline. Messages are stored encrypted and delivered when peers come online. The relay never sees your secrets—only encrypted blobs.

Checking status...
View full status page
1

Enable relay for your project

$ envctl project relay set relay.envctl.dev

Configure a relay URL. The protocol (wss://) and path (/ws) are added automatically. This is recorded in your project chain and shared with teammates.

2

Check relay status

$ envctl project relay status
Relay Status for myproject

  URL: wss://relay.envctl.dev/ws
  Status: connected

The daemon maintains a persistent connection and automatically reconnects if disconnected.

3

Sync happens automatically

When you push secrets, they're sent to online peers directly via P2P. For offline peers, messages are encrypted and stored on the relay until they reconnect.

CI/CD Integration

Use secrets in CI pipelines without network access to teammates or relay servers.
Export an encrypted bundle to your repo—only CI runners with the private key can decrypt it.

1

Generate a CI keypair

$ envctl ci keygen
Generated CI keypair for project "myproject"

Public key stored on project chain (committed)

CI Private Key (store in your CI platform's secrets as ENVCTL_CI_KEY):

Kz4xN2U5...base64...

This private key will NOT be shown again.
Store it securely in your CI platform now.

Generate an ML-KEM-768 keypair. The public key is stored on the team chain and synced to all project members. The private key is shown once—store it in your CI platform's secrets.

2

Export encrypted bundle

$ envctl ci export -e prod -o .envctl/prod.enc
Identity passphrase:
Exported 8 variables to .envctl/prod.enc

Export your secrets as an encrypted bundle using the public key. Any team admin can export—no need to share the CI private key. Safe to commit to your repository.

3

Use in CI pipelines

# GitHub Actions example
- name: Run tests with secrets
  env:
    ENVCTL_CI_KEY: ${{ secrets.ENVCTL_CI_KEY }}
  run: envctl ci apply -b .envctl/prod.enc -- npm test

Decrypt and run commands with secrets injected. No daemon or identity required—just the bundle and CI private key. Secrets exist only in memory during execution.

4

Update secrets

$ envctl env var set -e prod NEW_API_KEY=sk_live_...
$ envctl ci export -e prod -o .envctl/prod.enc
$ git add .envctl/prod.enc && git commit -m "Update prod secrets"

When secrets change, re-export the bundle and commit. Any team admin can export without needing the CI private key. Git history shows when secrets changed.

Offline builds No network calls to external services during CI
GitOps workflow Secret changes tracked in git history (encrypted)
No plaintext on disk Secrets decrypted only in process memory
Audit trail Bundles signed by exporter's identity
Post-quantum encryption ML-KEM-768 + AES-256-GCM hybrid encryption

Pricing

The CLI is free and open source. The relay is optional infrastructure
for async sync when teammates are offline. Pay only if you need it.

Free

$0 /month
  • Public relay access
  • 7 day message retention
  • Rate limited
  • Community support
Get Started

Enterprise

Custom
  • Dedicated relay server
  • Unlimited retention
  • Self-hosting option
  • Priority support & SLA
Contact Sales

How envctl Compares

Most secrets tools lock you into cloud accounts and charge per seat.
envctl is infrastructure you own. Secrets sync peer-to-peer. No middleman.

Feature envctl Polykey Doppler Infisical HashiCorp Vault 1Password
No cloud account required self-host self-host
P2P sync (no server)
Post-quantum encryption
Open source
Zero infrastructure setup
Git-like CLI workflow
Signed audit trail
No plaintext on disk env apply vaults
Offline CI builds
GitOps for secrets encrypted vaults
Free tier unlimited unlimited 5 users 5 users self-host
Per-seat pricing