Projects
sei

sei

Rust Shell Dockerfile GitHub

sei - Save Env Inject

You don’t leave your front door open just because you’ll need to get back in tomorrow.

Manages environment secrets in GNOME Keyring instead of .env files. TUI for editing, CLI for injection.

Why?

.env files sit in the project directory — any tool with file access can read them:

  • AI agents (Claude Code, Copilot) read project files for context analysis
  • Security scanners with vulnerabilities (e.g. Trivy — secrets were exfiltrated)
  • CI/CD pipelines and build tools scan the working directory
  • git add . accidentally commits secrets

sei stores secrets in GNOME Keyring — encrypted, protected by GUI prompt, invisible to file-based tools.

Architecture

Without sei

reads

reads

reads

reads

Claude Code

.env file
Plaintext in project directory

Trivy / Scanner

git add .

Application

With sei

D-Bus + GUI prompt

.envs() inheritance

no access
(no .env, no D-Bus)

no access
(no file present)

GNOME Keyring
Collection: sei-secrets
encrypted in ~/.local/share/keyrings/

sei

Application

Claude Code

Scanner

Installation

curl -fsSL https://xi72yow.github.io/sei/install.sh | sudo bash

This adds the sei APT repository and installs the package. Updates come via apt upgrade.

Manual (build from source)

Requires Podman.

git clone https://github.com/xi72yow/sei.git
cd sei
./build.sh --install

Or build only and install separately:

./build.sh
sudo apt install --reinstall ./dist/sei_*.deb

Prerequisite

A running Secret Service daemon — GNOME Keyring (gnome-keyring-daemon), KeePassXC, or any other daemon implementing the freedesktop Secret Service API.

Usage

TUI

sei
Bildschirmfoto vom 2026-03-29 11-32-55

On startup, sei scans for .env* files in the current directory. If new or changed files are found, the Import tab opens automatically with a diff view. Stage names are derived from the file suffix (.env → default, .env.production → production).

After import, the Store tab shows all keyring entries:

Bildschirmfoto vom 2026-03-29 11-34-58

Each entry gets a 3-digit ID (001–999) for quick CLI access. Entries matching the current directory are highlighted. All keybindings are shown in the footer.

Running Commands

# Inline picker — choose entry interactively
sei node server.js

# By ID (skip picker)
sei 001 node server.js
sei 002 podman compose up -d

# By path + stage
sei run -s production -- node server.js
sei run -p ~/projects/api -s prod -- node server.js

# -- only needed when cmd starts with a flag
sei run --id 001 -- --some-flag
Bildschirmfoto vom 2026-03-29 11-41-10

When no ID is given, sei shows an inline picker to select an entry before running the command. Entries matching the current directory are shown first.

Secrets are passed via environment inheritance — no temp files, no CLI arguments. The keyring is locked after loading.

Compose Integration

sei injects env vars into the process it spawns. For Compose, reference the variables in your compose.yml:

services:
  app:
    image: myapp
    environment:
      - DB_HOST        # value from host env (set by sei)
      - DB_PORT
      - API_KEY
sei 001 podman compose up -d

Security Model

Protection Layers

1. Own Collection
sei-secrets with own password
→ no auto-unlock at login

2. Keyring Encryption
AES on disk (~/.local/share/keyrings/)

3. GUI Prompt
D-Bus requires graphical confirmation
→ terminal tools blocked

4. Auto-Lock
sei locks on quit and after sei run
→ exposure window minimized

5. No Files
No .env in project directory
→ nothing to read/scan/commit

Attack VectorWithout seiWith sei
AI agent reads project files.env directly readableNo file present
AI agent uses secret-toolGUI prompt blocks terminal
Scanner exfiltrates secrets.env is foundNothing on disk
git add . / git commit -a.env gets committedNothing to commit
Shoulder surfing.env open in editorValues masked
Process monitoring (ps)Secrets not in CLI arguments
Root access / disk forensics.env plaintextKeyring encrypted

Technical Details

  • Language: Rust (no unsafe)
  • TUI: ratatui + ratatui-textarea + crossterm
  • Keyring: zbus (D-Bus, freedesktop Secret Service API, pure Rust)
  • Collection: sei-secrets (own collection, own password)
  • Metadata: 3-digit ID, created/updated timestamps per entry
  • Async: tokio + futures-util
  • CLI: clap (derive) + ID shorthand
  • Build: Container-based via Podman
  • Package: .deb for amd64 (stripped, LTO)

License

Not yet licensed. All rights reserved.