Learn

Learn SealBox step by step

No security background needed. Each lesson first explains what we're doing with an everyday analogy, then shows the command.

1. Start in 5 minutes

⏱ 5 minutesNeeds: Python 3.12+

SealBox is a command-line tool. Once it's installed, a few commands in your project folder are all it takes.

Install

$ pip install sealbox        # or: pipx install sealbox
$ sealbox -V                 # print the version: sealbox 0.3.0

Check your project

init changes no files. It looks at the project and lists the next steps in order:

$ cd my-project
$ sealbox init
sealbox 0.3.0 · project: C:\my-project

  · This project has no vault yet
  · No team (single user)        → sealbox team init --github <name>
  ⚠ Exposed secrets in 3 file(s) → sealbox seal

Next steps:
  1) sealbox seal
  2) sealbox recovery setup

Seal, back up, run

$ sealbox seal                     # move secrets into the vault
$ sealbox recovery setup           # recovery code (once)
$ sealbox exec -- python app.py    # run your program with the secrets
$ git add .sealbox
$ git commit -m "vault"

Tip: Whenever you're stuck, type sealbox status. Every problem line comes with the command that fixes it. For details on a command, use sealbox help seal. Typos get corrected too: sealbox sael answers "Did you mean: seal?".

2. Core concepts

Five ideas are enough to understand SealBox. We'll explain each with an analogy from home.

🏠

The big picture: Imagine you've hired a cleaner (the agent). To do the job, they need to go into every room. You don't leave your jewellery on the table; you put it in the safe, and you leave a note on the table saying "jewellery is in the safe". The cleaner sees the note but never the jewellery. SealBox does that for your code.

🔐 Vault

.sealbox/project.vault. Every secret sits here, encrypted with AES-256-GCM. Because it's encrypted, it can go into the repo.

🗝 Vault key (DEK)

The single key that opens the vault. It's never on disk: it's kept in Windows Credential Manager, the macOS Keychain or the Linux Secret Service.

🏷 Placeholder

A random name like __SECURE_TCKN_103d…__. It's written in place of personal data such as emails, national IDs and IBANs.

🌱 Environment variable

Instead of a password, the code says os.environ["DB_PASSWORD"]. The value is handed in from outside while the program runs.

✅ Approval window

When a program asks for secrets, this window shows which values will be handed over. There's no setting to skip it.

🧯 Recovery code

A backup code that opens the vault if the key is lost. You can split it into 3 shares; any 2 are enough.

What goes where?

What was foundWhat happens
Password, token or API key in code (a whole string)Moves to the vault; the code becomes os.environ["X"] / process.env.X / System.getenv("X")
The same value repeated in a commentRedacted with a placeholder
Email, national ID, phone, IBAN, nameRedacted with a placeholder (use vault expose if needed)
.env fileSecret lines go to the vault, .env is deleted, .env.sealed stays
JSON / YAML / TOML configRedacted, and the report tells you which environment variable to read
Part of a URL, or an unsupported languageLeft alone with a [!] warning; move it by hand

3. Seal your first project

⏱ 5 minutesCommands: seal --check, seal

Just look first

--check touches nothing. If there are exposed secrets it exits with code 1, so you can use it in CI too.

$ sealbox seal --check
.env → .env.sealed: 1 value(s) moved to the vault (DB_PASSWORD)
3 file(s) scanned (0.0 s).
There are unredacted secrets on disk. Run 'sealbox seal'.

Seal

$ sealbox seal                     # the whole project
$ sealbox seal src/config.py       # a single file

Run it from the project root. If you run it from a subfolder like src and there's a .env, .git or vault above it, SealBox stops, because the .env up there would be left exposed. If you chose that folder on purpose, pass -w ..

What happens to your files?

Each language reads the secret its own standard way. The logic of your code doesn't change:

Python
# before
KEY = "sk_live_51N…"
# after
KEY = os.environ["KEY"]
JavaScript / TS
// before
const key = "sk_live_51N…"
// after
const key = process.env.KEY
Java
// before
String key = "sk_live_51N…";
// after
String key = System.getenv("KEY");

Reverting a file and sealing it again doesn't create duplicates in the vault, because the same value always maps to the same entry.

Java note: A static final constant is now filled at runtime instead of compile time. Code that uses such a constant in a switch case or an annotation won't compile after the move. That rarely happens with secrets.

4. Run your program with the vault

🎟

Analogy: exec works like a doorman. Your program says "I need the password". The doorman asks you, "Shall I hand over these 4 values?" If you say yes, the values are given only for that run and taken back when it ends.

$ sealbox exec -- python app.py        # Python
$ sealbox exec -- npm start            # Node.js
$ sealbox exec -- java Main.java       # Java
$ sealbox exec -- mvn spring-boot:run  # Maven / Gradle
  • Everything after -- is your normal command.
  • An approval window opens first. There's deliberately no flag or environment variable that skips it.
  • If a known secret appears in your program's output, it's printed as [REDACTED:..].

Note: The output goes through a pipe, so interactive or colourful terminal programs may behave a little differently. The filter doesn't catch secrets printed reversed or in pieces. The approval window is the real protection.

If your program uses redacted data

Data like emails or national IDs is redacted with a placeholder, because usually it isn't needed at runtime. If your program really uses it, turn it into an environment variable:

$ sealbox vault expose __SECURE_EMAIL_8f2c…__
$ sealbox vault expose __SECURE_EMAIL_8f2c…__ --as ADMIN_EMAIL

5. Manage values in the vault

Values are never printed to the terminal on their own. Showing and deleting both ask for approval.

$ sealbox vault list                       # names and placeholders (no values)
$ sealbox vault reveal DB_PASSWORD         # show it in the approval window
$ sealbox vault reveal __SECURE_TCKN_…__   # look at redacted data
$ sealbox vault set DB_PASSWORD            # change or add
$ sealbox vault remove --unused            # delete unused entries

Reverting a file doesn't delete anything from the vault. If a value changed, the old one is left orphaned, and vault remove --unused cleans it up. An entry still used by a placeholder or variable name in some file isn't deleted (use --force to insist).

6. Add a teammate

⏱ 10 minutesNeeds: a passphrase-protected SSH key on your GitHub account
🔑

Analogy: You copy the vault key and give each teammate a box locked with their own padlock. Anyone can see the boxes, since they sit in the repo. But each box opens only with its owner's key, and that key is their SSH key on GitHub.

Preparation (everyone, once)

You need a passphrase-protected SSH key on your computer, with its public half added to your GitHub account. Keys without a passphrase are rejected, because any program on the machine (agents included) could read them.

$ ssh-keygen -t ed25519              # set a passphrase when asked
$ ssh-keygen -p -f ~/.ssh/id_ed25519 # add a passphrase to an existing key
# add the contents of ~/.ssh/id_ed25519.pub under GitHub → Settings → SSH keys

You (owner)

$ sealbox team init --github my-name      # create the team, you're the owner
$ sealbox team add teammate              # github.com/teammate.keys
$ sealbox team add alice --owner          # let her add and remove people too
$ git add .sealbox
$ git commit -m "add teammate to the vault"
$ git push

Your teammate

$ git pull
$ sealbox exec -- python app.py   # the SSH passphrase is asked in a window the first time

After the first open, the key is cached in the Windows store and isn't asked for again.

Removing someone

$ sealbox team remove teammate    # the vault key is rotated
$ sealbox team list               # members and SSH fingerprints

Remember: A removed person can still open the old vault from git history with the old key. That's why team remove lists the values they may have seen. Change those passwords at their source (database, API dashboard).

Check .gitignore: If the root .gitignore excludes the whole .sealbox/ folder, the vault never reaches the repo. The team commands and status warn you about this.

7. If you lose the key

🧯

Analogy: There's always some way to lose your house key: Windows gets reset, you change computers, a profile breaks. The recovery code is a spare key kept somewhere you trust. Split it into 3 shares and one can stay with your mum, one in a safe, one on a USB stick. Any 2 of them open the door.

Today, while everything works (once)

$ sealbox recovery setup                    # the code appears in a window; write it down
$ sealbox recovery shares                   # optional: split into 2-of-3 shares
$ sealbox recovery export D:\project.sapkit # optional: a USB / cloud kit

The code and the shares are never printed to the terminal; they're only shown in a window. Recovery copies live under ~/.sealbox/recovery/, so they never enter the repo. There's one code per user, and new projects are tied to it without asking you for the code again.

When a bad day comes

SituationWhat to do
Windows was reset, the project folder is still thereEnter the code or 2 shares with sealbox recovery restore
You're on a team and an owner rotated the keyNothing. The new key is picked up automatically via SSH
New computer, and the vault folder is gone toosealbox recovery restore --kit D:\project.sapkit
No code, no kit, no teamsealbox vault reset: a new empty vault is created and the old one is set aside. Get the secrets again from their services

Unlock order: Windows store → (with a team) SSH key → an error message with a recovery suggestion. If you're not sure what to do, sealbox status tells you.

8. Working in VS Code

The extension doesn't do the work itself. It wires buttons to the sealbox command, so the command has to be installed first.

Install

  1. pip install sealbox (or install it into your project's .venv).
  2. In VS Code open Extensions (Ctrl+Shift+X) → search SealBox → Install. Or use the Marketplace page. In Cursor, Windsurf or VSCodium it comes from Open VSX.
  3. If you have a .vsix file: code --install-extension sealbox-0.3.0.vsix

The extension looks in the .venv of the project folder and its parents first, then on PATH. If it's somewhere else, put its path in the sealbox.executable setting.

Daily flow

  1. Type. When you write a password into a file and save, that spot gets a yellow squiggle.
  2. Click the lightbulb. Choose "Move this file's secrets into the vault". The value goes to the vault and the code becomes os.environ[...].
  3. Hover. A "Show value" link appears on a __SECURE_..__ placeholder or on os.environ["X"]. The value shows after the approval window. If you choose "Copy", the clipboard is cleared after 30 seconds.
  4. Run. Use "SealBox: Run program with the vault" from the Command Palette. If you run with the plain ▶ and get a KeyError, the extension suggests it for you.
  5. Check the status bar. It shows how many secrets are in the vault and how many people share it, and warns when there's no recovery code. Click it to open the menu.

Command Palette (Ctrl+Shift+P → "SealBox")

CommandEquivalent
SealBox: MenuEvery action in one list
SealBox: Scan project (any exposed secrets?)seal --check
SealBox: Move this file's secrets into the vaultseal <file>
SealBox: Move all project secrets into the vaultseal
SealBox: Run program with the vaultexec -- …
SealBox: Show a value from the vaultvault reveal
SealBox: Give redacted data to the program at runtimevault expose
SealBox: Delete unused entries from the vaultvault remove --unused
SealBox: Add a teammate (GitHub user)team add
SealBox: Create a recovery coderecovery setup
SealBox: Reopen the vault with a recovery coderecovery restore

Security: The recovery code, the shares and your SSH passphrase never pass through the extension. They're all shown or asked for in separate windows that Python opens. The extension only reads the output of seal --check --json, which has lines, columns and categories, but no values.

9. Secret checks in CI

seal --check exits with code 1 when it finds exposed secrets. Use it as a gatekeeper on pull requests:

.github/workflows/sealbox.yml
name: sealbox
on: [push, pull_request]
jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: "3.12"
      - run: pip install sealbox
      - run: sealbox seal --check

This step doesn't open the vault and needs no key. It only checks whether there are unredacted secrets on disk. Add --json for a machine-readable report.

10. FAQ

Is SealBox a proxy?

No. Agents read files straight from disk, and a proxy in between would never see that. SealBox removes secrets from your files for good.

Is it safe to put the vault in the repo?

Yes, it's designed for that. project.vault is encrypted with AES-256-GCM, and its key isn't in the repo. .sealbox/.gitignore keeps backups and lock files out.

What about secrets I've already committed?

They stay in git history; SealBox doesn't rewrite it. sealbox history tells you which vault values appear in old commits and whether they were pushed. Change those values at their source, and run sealbox hook install so it doesn't happen again.

Does it find every secret?

No. Regex can miss secrets that are split up, encoded (\u0040, hex, ROT13) or buried in prose. Review the report and add custom_rules if needed. For names, use the person_names list.

Can I use it in Turkish?

sealbox --lang tr … or SEALBOX_LANG=tr. The default is your computer's language. The extension follows VS Code's language too.

I installed it under the old name (secure-ai-proxy).

You don't need to do anything. Old .secure_proxy/ folders and secure_proxy.toml are still read, and the old credential-store entry moves to the new name on first open.