An open API service indexing awesome lists of open source software.

https://github.com/santhsecurity/envseal

Secret vault for the agent era. Hardware-sealed at rest, GUI-gated at use, only injected into approved child processes.
https://github.com/santhsecurity/envseal

Last synced: 2 months ago
JSON representation

Secret vault for the agent era. Hardware-sealed at rest, GUI-gated at use, only injected into approved child processes.

Awesome Lists containing this project

README

          


envseal

# envseal

[![crates.io](https://img.shields.io/crates/v/envseal-cli.svg?label=envseal-cli)](https://crates.io/crates/envseal-cli)
[![crates.io](https://img.shields.io/crates/v/envseal-mcp.svg?label=envseal-mcp)](https://crates.io/crates/envseal-mcp)
[![docs.rs](https://img.shields.io/docsrs/envseal)](https://docs.rs/envseal)
[![CI](https://github.com/santhsecurity/envseal/actions/workflows/ci.yml/badge.svg)](https://github.com/santhsecurity/envseal/actions/workflows/ci.yml)
[![License: MIT OR Apache-2.0](https://img.shields.io/badge/license-MIT%20OR%20Apache--2.0-blue.svg)](LICENSE-MIT)

> ⚠️ **Beta.** Actively hardening toward 1.0. [Try to break it.](SECURITY.md)

> **Hey, thanks for trying envseal.** Small solo project. Core (vault,
> hardware seal, signal taxonomy, sealed config) is hand-tested on
> Windows + Linux end-to-end with 900+ unit, regression, property, and
> adversarial tests, but it hasn't been stress-tested by anyone other
> than me. If something is awkward, wrong, or surprising,
> [open an issue](https://github.com/santhsecurity/envseal/issues). I
> read all of them. The CTF in `envseal ctf start` is the fastest way
> to attack it; I'll publicly credit anyone who finds something.

> **Recent (0.3.14):** Encrypted audit log (AES-256-GCM events under a
> per-vault hardware-sealed key), every deferred audit follow-up closed
> (atomic Windows DACL at create, persistent TOTP rate-limit, homoglyph
> defense on every dialog field, full symlink-destruction sweep), and
> the rmcp dependency bumped to 1.6 to clear all open advisories. See
> [CHANGELOG.md](CHANGELOG.md) and [ROADMAP.md](ROADMAP.md) for what's
> next.

> **Sudo can't read your keys.** Hardware-sealed at rest, GUI-gated at use, copyable to no other machine.

**envseal** is a developer-first secret vault that turns API keys into
device-bound capabilities. The plaintext exists in exactly two places:
inside the silicon that minted it (Secure Enclave, TPM, or DPAPI-bound
user master), and inside the descendant process you authorized at the
keyboard. Nowhere else: not in `cat`, not in `/proc/PID/mem`, not in a
stolen `master.key`, not in your shell history.

## Why?

In 2026, AI agents run with full filesystem and shell access. Every `.env` file is readable via `cat .env`. Every API key pasted into a chat window is logged to cloud AI providers. Stack the failure modes:

| Current Defense | Why It Fails |
|----------------|-------------|
| `.gitignore` | Prevents commit, not read. |
| `.cursorignore` | Prompt-based; pushed out of the context window. |
| OS Keychain | Agent calls `secret-tool lookup` and walks out with plaintext. |
| Password managers | Authenticate the *user*, not the *program* asking. |
| `.env` + `dotenv` | Agent runs `cat .env` and the rest is history. |
| Pasting into chat | Key enters context, logs, and cloud retention. |

**envseal** authenticates the *program*. Secrets can only be released
to a whitelisted binary, approved via a GUI popup terminal-bound agents
cannot click, and the wrap key that protects the vault never leaves
your physical device.

## The two guarantees

1. **The key cannot leave this machine.** The master key on disk is
double-wrapped: passphrase (Argon2id) on the inside, hardware-bound
seal on the outside (Windows DPAPI, macOS Secure Enclave, Linux
TPM 2.0). Even with `master.key` copied off and the passphrase
brute-forced, the file does not decrypt on any other device.
`envseal doctor` reports your active tier.
2. **The key cannot be read without you at the keyboard.** Every
release goes through a desktop popup. `sudo`, `ptrace`,
`cat /proc/PID/mem`, agent shells with full root: none of them can
click "Allow." Headless attackers see only `Error::NoDisplay`.

## Install

### From `cargo` (any platform with Rust 1.77+)

```bash
# CLI (binary on PATH is `envseal`). RECOMMENDED, fully tested.
cargo install envseal-cli --locked

# MCP server for AI agents (Claude Desktop, Cursor, Antigravity, Gemini CLI). RECOMMENDED, fully tested.
cargo install envseal-mcp --locked

# Native desktop app (egui, no JavaScript, no webview). UNTESTED, use at your own risk.
cargo install envseal-gui --locked
```

> **Surface status.** The CLI and MCP server are the recommended,
> production-ready entry points; every release runs them through the
> full unit / integration / adversarial / property / regression /
> deep-security / e2e suites. The desktop GUI ships builds but the
> end-to-end UX flows are not yet covered by automated tests; treat
> it as a preview until the GUI test harness lands. CLI + MCP have
> parity for every security-relevant operation, so nothing is gated
> behind the GUI.

Or from a checkout:
```bash
git clone https://github.com/santhsecurity/envseal
cd envseal
cargo install --path cli --locked
cargo install --path mcp --locked
cargo install --path desktop-native --locked
```

### Pre-built binaries

Binary releases for Windows / macOS / Linux are attached to each
[GitHub release](https://github.com/santhsecurity/envseal/releases).
Download the archive for your platform, extract, and place
`envseal` (and optionally `envseal-mcp`, `envseal-gui`) somewhere
on your `PATH`.

### Optional: keyhog scanner

`envseal scan` and `envseal init --from-history` use the
[keyhog](https://github.com/santhsecurity/keyhog) scanner when
present (896 secret-pattern detectors with GPU acceleration). When
keyhog isn't on `PATH`, envseal falls back to a built-in regex
scanner that covers the common providers. To install:
```bash
cargo install keyhog --locked
```
keyhog is intentionally NOT a hard dependency. It pulls in GPU
runtimes that most envseal users don't want, and the fallback
regex catches the most common cases. If you operate at scale or
audit unfamiliar codebases, install keyhog separately.

### First-run setup (one minute)

```bash
# 1. Verify your platform's protection tier (DPAPI, Secure Enclave, TPM).
envseal doctor

# 2. Initialize your vault by storing your first secret. envseal will
# prompt for a passphrase via a desktop dialog. Stdin is the only
# way values enter the vault; never pass secrets as CLI args.
echo 'sk-proj-…' | envseal store openai-key

# 3. Use it. The first inject pops an approval dialog. Click
# "Allow Always" and you won't see it again for that binary+secret.
envseal inject openai-key=OPENAI_API_KEY -- python app.py

# 4. Other day-to-day operations.
envseal list # names only, never values
envseal peek openai-key # redacted preview
envseal revoke openai-key # secure zero-fill + delete

# 5. Shell completions (optional).
eval "$(envseal completions bash)" # add to .bashrc
eval "$(envseal completions zsh)" # add to .zshrc
envseal completions fish | source # add to config.fish
```

### For AI agents (via MCP)

The agent-native workflow uses `envseal_request_key`. The agent proposes
a key name, a GUI popup appears, the user pastes the value. **The agent
never sees the secret.**

```
Agent: "I need your Cloudflare API token"
→ calls envseal_request_key("cloudflare-api", "Cloudflare API Token")
→ GUI popup: "Paste your Cloudflare API Token: [________] [Store]"
User: *copies from dashboard, pastes into popup, clicks Store*
→ Secret encrypted and stored. Agent receives only "stored".

Agent: "Deploying to Cloudflare..."
→ calls envseal_inject(cloudflare-api=CLOUDFLARE_API_TOKEN -- wrangler deploy)
→ GUI popup: "Allow wrangler to access cloudflare-api? [Allow Once] [Always Allow] [Deny]"
User: *clicks Allow Once*
→ wrangler deploys. Key never touched the chat.
```

**Same effort as pasting into chat**: 1 paste + 1 click vs 1 paste. The extra click IS the security.

## Security tiers: pick how friction-heavy you want approvals

envseal ships with three preset tiers. Switch with `envseal security
preset standard | hardened | lockdown` (or click the tier buttons in
the desktop GUI's Settings tab). Detection signals fire the same way
in every tier; the tier decides what `Action` each `Severity` maps
to via the policy table at `core/src/guard/signal.rs`.

| Tier | Approval popup | Friction | Default for | Use when… |
|---|---|---|---|---|
| **Standard** | Allow Once / Allow Always / Deny | None, instant approval | Daily dev | You trust your shell + the binaries you run |
| **Hardened** | Same buttons + 2-second pre-popup delay | Anti-click-through delay, virtual keyboard on X11 | CI runners, second laptops | You want a beat to think before approving |
| **Lockdown** | Same buttons + 5-second delay + 4-digit numeric challenge before each batch | Maximum friction, hard-blocks any `Hostile` signal | High-value vaults, root accounts | You want it to be obviously inconvenient to approve under coercion |

The tier promotes signal severities through a 5×3 policy matrix. A
`Severity::Hostile` signal (e.g. `io.stdin.piped`) at Standard
surfaces as a friction gate; at Hardened it's a friction gate with
delay; at Lockdown it's a hard block. You can override any
`(severity, tier)` cell or any specific `SignalId` via
`envseal security override-tier` / `override-signal` (or the
read-only summary in the desktop GUI's Settings panel).

## Security surface: every toggle, in one place

These are the knobs that ship with envseal. Most are on by default;
the rest you opt into. **Every action is hash-chained into the audit
log**, so flipping a setting is itself an event you can review later.

### Approval pipeline

| Knob | Command | What it does |
| --- | --- | --- |
| Tier | `envseal security preset ` | Sets the entire policy matrix in one shot. Per-cell overrides win over the preset. |
| Per-signal override | `envseal security override ` | Pin one detector (e.g. `io.stdin.piped`) to a specific action regardless of tier. |
| Per-tier override | `envseal security override-tier : ` | Override one cell of the 5×3 matrix (e.g. `hostile:standard = block`). |
| List overrides | `envseal security overrides` | Read-only dump of every current override. |
| Approval delay | `envseal security set approval_delay_secs ` | Anti-click-through delay before the popup accepts a click (default 2 s on Hardened, 5 s on Lockdown). |
| Numeric challenge | `envseal security set challenge_required true` | Require the user to type a 4-digit code shown on screen before approval (default on Lockdown). |
| Audit logging | `envseal security set audit_logging ` | Toggle the hash-chained log. Off only ever for fully-air-gapped CI. |
| TOTP 2FA | `envseal security totp-setup` / `totp-disable` | Adds an HOTP/TOTP second factor on top of the passphrase for vault unlock. |
| Relay required | `envseal security set relay_required true` | Refuse local GUI; only accept approvals via the paired-device relay. For headless / SSH workflows. |
| X11 auto-upgrade | `envseal security set x11_auto_upgrade ` | When on X11 (no input isolation), auto-promote to virtual-keyboard input so passphrases can't be `xdotool`-replayed. |

### Always-on hardening (no toggle, it just runs)

These are not configurable; they're the floor.

- **Vault root validation**: refuses to open in `/tmp`, world-writable
dirs, or any path whose component is a symlink. Path-traversal in
secret names rejected at parse time.
- **AES-256-GCM with `name`-bound AAD**: every secret is sealed with
its own name as additional authenticated data, so a renamed file on
disk fails to decrypt.
- **Argon2id KDF**: passphrase wrapping uses Argon2id with parameters
sized for ≥ 0.5 s on a modern laptop.
- **Hardware seal**: the wrap key that protects `master.key` is
bound to the device's TPM 2.0 / Secure Enclave / Windows DPAPI.
Stolen `master.key` won't open on another box.
- **Self-preload check**: refuses to run if `LD_PRELOAD`,
`DYLD_INSERT_LIBRARIES`, or equivalent is set in the inherited env.
- **Process hardening**: `PR_SET_DUMPABLE(0)`, `RLIMIT_CORE = 0`,
`O_CLOEXEC` on every secret FD, `PR_SET_NO_NEW_PRIVS` before exec.
- **Memory protection**: `memfd_secret()` on Linux 5.14+ unmaps the
master key from kernel page tables; `mlock` + `MADV_DONTDUMP`
fallback on older kernels; `VirtualLock` on Windows; `mlock` on
macOS. Master key zeroized on drop.
- **Hash-chained audit log**: every event includes the SHA-256 of
the previous entry. Tampering breaks the chain; the corrupted file
is rotated to `audit.log.corrupted-` and a fresh chain starts.
- **Policy integrity**: `policy.toml` is HMAC-signed; any unsigned
edit rejects subsequent operations until repaired.
- **Empty-secret refusal**: vault refuses to store a zero-byte
value (defends against `cat /dev/null | envseal store creds`).
- **CTF flag carve-out**: `Vault::decrypt("ctf-flag")` returns
`CryptoFailure` unconditionally, audited as
`critical [ctf.flag.decrypt_attempt]`. Verify-by-hash only.

### Detection signals (each one fires its own audit event)

| Source | Signal id | Severity | What it catches |
| --- | --- | --- | --- |
| `migration.preexec` | `io.stdin.piped` | hostile | A secret value piped into envseal's stdin on a tty session |
| `migration.preexec` | `io.cmdline.shell_subst` | hostile | `$(…)` / backtick / `eval` in the requesting argv |
| `guard.gui` | `gui.input_injector` | critical | xdotool / ydotool / xte / wtype running |
| `guard.gui` | `gui.screen_recorder` | warn | OBS / SimpleScreenRecorder / ffmpeg recording |
| `guard.gui` | `gui.accessibility_tool` | warn | screen-reader / AT-SPI bridge active |
| `guard.gui` | `gui.session.ssh` | critical | SSH session, no local display |
| `guard.gui` | `gui.session.x11_forward` | critical | X11 forwarding, passphrase interceptable |
| `guard.gui` | `gui.session.remote_desktop` | warn | RDP / VNC session detected |
| `guard.env` | `env.loader.preload` | critical | `LD_PRELOAD` or peer set in inherited env |
| `vault.entropy` | `secret.entropy.too_short` | warn | secret < 8 bytes |
| `vault.entropy` | `secret.entropy.low_shannon` | warn | low Shannon entropy for its length |
| `vault.entropy` | `secret.entropy.placeholder.` | warn | matches `todo`, `changeme`, `your-api-key`, … |
| `audit.chain` | `audit.chain.rotated_corruption` | critical | tamper-detected log was rotated |
| `vault.binary` | `binary.tampered` | critical | approved binary's hash no longer matches |
| `vault.policy` | `policy.tampered` | critical | `policy.toml` HMAC mismatch |
| `vault.dpapi` | `vault.dpapi.device_mismatch` | critical | `master.key` wrap was minted on a different device |
| `ctf` | `ctf.flag.decrypt_attempt` | critical | something tried to read the CTF flag |
| `ctf` | `ctf.verify.incorrect` | info | wrong flag submitted |

Every signal renders to stderr at the time it fires AND is appended
to the audit log. `envseal audit --json` gives the full structured
stream; `envseal security overrides` shows the action you've pinned
for each.

### Sandbox tiers (for `supervised`)

`envseal supervised = [--sandbox=] -- ` runs
the child under live leak-detection AND, optionally, a sandbox:

| Sandbox tier | Linux | macOS | Windows |
| --- | --- | --- | --- |
| `none` (default) | observe only | observe only | observe only |
| `standard` | seccomp filter (no `ptrace`, no `process_vm_readv`) | `sandbox_init` `pure-computation` profile | Job Object with restricted handle access |
| `hardened` | + new pid/mount/uts namespaces | + restricted-network profile | + restricted desktop |
| `lockdown` | + read-only root, no network namespace | + filesystem-read-only profile | + integrity-low token |

The supervisor inspects child stdout/stderr in real time; any
substring match for a known secret value triggers
`supervisor_leak_detected` and terminates the child.

## CTF: try to break it. Publicly credited if you do.

Once a secret enters the vault, the claim is: **nobody gets it
out.** Not a human, not an AI agent, not both working together.

```bash
envseal ctf start # generates ENVSEAL_CTF{...}, seals it, switches the vault to Lockdown
envseal ctf rules # what's allowed, what's banned (only DMA / cold-boot / JTAG are off-limits)
envseal ctf status # check active challenge + verification hash
envseal ctf verify # submit a guess
envseal ctf reset # clean up + restore your pre-CTF tier
```

**What's allowed:** memory reading (`/proc/pid/mem`, `process_vm_readv`,
`ptrace`), binary replacement, PATH poisoning, `LD_PRELOAD`, GUI
automation tools (xdotool, ydotool, xte, libinput replay), config
tampering, side channels (timing/cache/power), kernel modules,
sandbox escape, race conditions, TOCTOU, anything creative in
software.

**What's banned**: only physical hardware attacks (DMA via
Thunderbolt/PCIe, cold-boot RAM transplant, JTAG). Those bypass
software on every machine, not just envseal.

**Reward:** Hall of Fame in `SECURITY.md` + writeup credit. There's
no bug-bounty cash because this is a one-person project, but if you
demonstrate a Tier 1 break (extract the flag from a Lockdown vault),
the writeup will be the public record of envseal's first failure
mode, high-prestige finding.

## MCP server setup

envseal ships an MCP (Model Context Protocol) server that lets AI
agents store, list, inject, and verify secrets without ever seeing
plaintext. Each tool call surfaces a GUI approval popup that the
human authorizes; the agent only sees `OK` or `denied`.

Run `which envseal-mcp` to get the absolute path of the binary
installed by `cargo install envseal-mcp` (or by extracting the
release archive to your `PATH`). Every config below needs it
(replace `/path/to/envseal-mcp`).

#### Claude CLI (Claude Code)

```bash
claude mcp add envseal /path/to/envseal-mcp
```

Or edit `~/.claude.json` and add to `mcpServers`:

```json
{
"mcpServers": {
"envseal": {
"command": "/path/to/envseal-mcp"
}
}
}
```

#### Gemini CLI

Edit `~/.gemini/settings.json`:

```json
{
"mcpServers": {
"envseal": {
"command": "/path/to/envseal-mcp"
}
}
}
```

Gemini CLI requires **absolute** paths; `~` expansion is not honored.

#### Cursor / Antigravity / generic MCP-aware editor

Add to your editor's MCP config (typically `~/.cursor/mcp.json` or
`~/.antigravity/mcp.json`):

```json
{
"mcpServers": {
"envseal": {
"command": "/path/to/envseal-mcp"
}
}
}
```

#### Verify the MCP server is wired up

After restarting your agent, ask it: "list the envseal tools you have".
The agent should enumerate `envseal_store`, `envseal_inject`,
`envseal_list`, `envseal_audit`, `envseal_doctor`, etc. If it says it has
no envseal tools, the path in the MCP config is wrong or the binary is
not executable. Try `chmod +x /path/to/envseal-mcp` and check the agent's
MCP startup log.

Per-agent web walkthroughs: [docs/setup/](docs/setup/) has copy-pasteable
agent-specific prompts (Cursor, Antigravity, Gemini CLI, Claude CLI,
manual) for the same configuration.

## The `.envseal` File

Drop-in `.env` replacement. **Safe to commit to git**: contains references, not values:

```bash
# .envseal: safe to commit
DATABASE_URL=database-url
REDIS_URL=redis-url
OPENAI_API_KEY=openai-key
STRIPE_SECRET_KEY=stripe-key
```

```bash
# Generate from existing vault secrets
envseal init

# Run your app
envseal inject-file .envseal -- npm run dev
```

## Commands

| Command | Description |
|---------|-------------|
| `envseal store [--force] [--gui]` | Store a secret (stdin or GUI popup) |
| `envseal request-key [--description d]` | Agent-initiated GUI key request |
| `envseal inject = -- ` | Inject secret into a process |
| `envseal inject-file -- ` | Inject all secrets from `.envseal` file |
| `envseal run -- [args...]` | Run command with explicit `.envseal` mappings |
| `envseal shell [--login]` | Open subshell with mapped secrets injected |
| `envseal pipe -- ` | Deliver a single secret on the child's stdin (no env var) |
| `envseal supervised = [--sandbox=] -- ` | Run with real-time leak detection and optional sandbox tier (`standard`, `hardened`, `lockdown`) |
| `envseal scan [--deep] [--path ]` | Scan dotfiles + cwd `.env*` (or whole `$HOME` with `--deep`); uses `keyhog` if installed |
| `envseal scan --system` | Hand off to `keyhog scan-system`. Every mounted drive + every git history (needs keyhog). |
| `envseal` *(no args)* / `envseal tui` | Open the interactive terminal UI (Welcome, Quickstart, Secrets, Doctor, Scanner, Audit, CTF) |
| `envseal import <.env> [--delete]` | Migrate from `.env` to envseal |
| `envseal init [path]` | Scaffold `.envseal` project file |
| `envseal doctor` | System security readiness check |
| `envseal status [--json]` | Show vault status (tier, secret count, etc.) |
| `envseal list` | List secret names (never values) |
| `envseal peek ` | Show a redacted preview of a secret |
| `envseal revoke ` | Secure delete a secret |
| `envseal copy ` | Duplicate a secret |
| `envseal rename ` | Rename a secret |
| `envseal alias ` | Generate shell aliases that wrap `envseal run` |
| `envseal policy show` | Show whitelist rules |
| `envseal policy revoke-binary ` | Remove rules for a binary |
| `envseal audit [N]` | Show last `N` audit log entries |
| `envseal security show\|set\|preset` | Manage security configuration tiers |
| `envseal health [--max-age=N]` | Secret health/compliance report |
| `envseal git-hook ` | Install and inspect leak-prevention hook |
| `envseal hook [bash\|zsh\|fish]` | Manage the shell preexec hook that captures typed keys |
| `envseal init --from-history` | Migrate every secret previously typed at the shell |
| `envseal op run -- ` / `envseal doppler run -- ` / `envseal vault run -- ` | Drop-in compatibility shims for 1Password / Doppler / HashiCorp Vault CLI surface |
| `envseal emergency-revoke` | Wipe all secrets from the vault |
| `envseal ctf ` | CTF challenge workflows |
| `envseal completions ` | Generate shell completions |

## Threat model

The full defense list lives under
[Always-on hardening](#always-on-hardening-no-toggle-it-just-runs)
above. This table is the operator-facing version: who can read a
secret today, and who cannot.

**Zero network connections.** envseal makes none. No telemetry, no
update checks, no cloud accounts.

| Attacker | Access? |
|----------|---------|
| AI agent with terminal access | No, cannot interact with GUI popup |
| Malicious script in build pipeline | No, binary not whitelisted |
| Root user (ptrace/proc) | No, `memfd_secret` + `PR_SET_DUMPABLE(0)` |
| Stolen `master.key` on attacker's machine | No, hardware seal refuses on a different device |
| Brute-force passphrase against stolen `master.key` | No, without the device's TPM/SEP/DPAPI key the wrap doesn't open |
| Human at the keyboard | Yes, can approve via GUI |
| Remote desktop attacker | Partial, detected via `assess_gui_security()` |
| Supply chain (npm token theft) | No, token never enters agent context |

### GUI Security Assessment

envseal continuously monitors the GUI environment:

- **Remote session detection**: SSH, X11 forwarding, RDP/VNC
- **Input injection detection**: xdotool, ydotool, xte, wtype
- **Screen recording detection**: OBS, SimpleScreenRecorder, ffmpeg
- **Threat classification**: Safe / Degraded / Hostile

### Platform Support

| Platform | GUI Backend | Hardware Seal | In-Memory | Sandbox | Status |
|----------|-------------|---------------|-----------|---------|--------|
| Linux | zenity / kdialog | TPM 2.0 (via tpm2-tools, optional) | `memfd_secret` (5.14+) | unshare namespaces (Hardened/Lockdown) | Supported |
| macOS | osascript | Secure Enclave (P-256, ECIES) | mlock | `sandbox_init` profiles | Supported |
| Windows | PowerShell Forms | DPAPI (TPM-rooted on Win10+) | VirtualLock | Job Objects | Supported |

## Migrating from `.env`, `op`, `doppler`, or your shell history

envseal is built to be the cheapest path off whatever you're using today. Pick the entry point that matches how the secrets are leaking:

```bash
# 1. Bulk migrate a .env file
envseal import .env --delete

# 2. Migrate everything you've already typed at the prompt
envseal init --from-history # scans bash/zsh/fish history,
# imports each detected key into the vault

# 3. Live-capture future keys without thinking about it
envseal hook install # auto-detects $SHELL,
# writes a preexec hook into .bashrc/.zshrc/.config/fish/config.fish
# Now whenever you type:
# OPENAI_API_KEY=sk-... node app.js
# envseal pops a "store this for next time?" dialog before the command runs.

# 4. Drop-in for existing scripts that called op / doppler / vault
envseal op run -- node app.js # 1Password CLI shape
envseal doppler run --config dev -- npm run dev # Doppler shape
envseal vault run -- ./deploy.sh # HashiCorp Vault shape
```

After migration, `envseal run -- ` reads the nearest `.envseal` file and injects every reference. (See [The `.envseal` File](#the-envseal-file) above for the format.)

## Desktop app (preview, untested)

The `envseal-gui` binary in `desktop-native/` is a pure-Rust **egui/eframe** app (no webview) covering the read-only views the CLI exposes. As noted in [Install](#install) above, the GUI is not yet covered by the automated test suites. Tabs:

- **Dashboard**: Overview of vault state and recent activity
- **Secrets**: View and revoke stored secrets
- **Store**: Encrypt new secrets via the GUI
- **Policy**: View and revoke binary access rules
- **Settings**: Security tier, input protection, and threat assessment
- **Audit**: Session activity tracking
- **Health**: Secret health and compliance report
- **Scanner**: Scan for leaked secrets and misconfigurations

## Vulnerability reports

Beyond the CTF, we welcome vulnerability reports at any tier, from GUI
bypass to crypto weakness. See **[SECURITY.md](SECURITY.md)** for the
3-tier disclosure program and how to submit findings.

## Roadmap & contributing

What's in flight, what's queued, and (importantly) a list of
well-scoped items we'd love outside contributors to take on. From
"add a regex pattern" to "build the watchdog process that monitors
envseal's heartbeats and detects spoofed popups," there's something
at every experience level.

**→ [ROADMAP.md](ROADMAP.md)**: the full living roadmap, with claim
instructions and Hall-of-Fame credit for shipped contributions.

A few highlights currently open for community work:

- **Heartbeat & watchdog process**: a separate lightweight monitor
that consumes signed heartbeats from envseal, observes OS popup
events, and alerts on anomalies. Out-of-tree by design; a great
systems-programming entry point.
- **Telegram-bot relay**: phone approvals via inline buttons, no
envseal mobile app required.
- **`cargo fuzz` harness for the v3 envelope parser**: `core/fuzz/`
is primed for it.
- **Reproducible-build verifier**: independently rebuild a release
tag and confirm byte-for-byte equivalence.
- **Documentation translation**: wider reach in non-English-speaking
dev communities.

See [CONTRIBUTING.md](CONTRIBUTING.md) for the dev setup and merge
bar; ROADMAP.md has the architectural context for each item.

## License

MIT OR Apache-2.0

## About

Built by [Santh](https://santh.dev).