Files
lazysecrets/docs/repos.md
T
keb 17d2705e12 feat: e opens a repo's SOPS or .env file, in nvim, sops edit or your editor (#1)
`e` on a file in a repo opens it; on a secret, it opens the file at that key's line.

- **SOPS files**: `sops edit` in the terminal, then back to lazysecrets with the keys reloaded. Exit 200 (nothing changed) shows "unchanged".
- **Other files inside nvim** (`$NVIM` set): lazysecrets asks that nvim, over `--remote-expr`, to open the file once lazysecrets' terminal closes, then quits. The file lands in the window you came from, not the closing float. Started from a shell in a terminal, it opens in the previous window straight away. No change to the nvim plugin is needed.
- **Otherwise**: `$VISUAL`/`$EDITOR` in the terminal (with `+N`, `file:N` or `-g file:N` for editors that take a line), else the system default app.

The repo provider now records each key's line (YAML node lines, env/ini line numbers) behind a new optional `provider.Files` interface. Other providers show "only SOPS and .env files in repos can be opened".

The nvim handoff was tested against a headless nvim 0.12: a floating terminal closed on exit the way snacks does, and a shell in a split. A file name with a space and a quote opened at the right line in both. Unit tests cover lines per format, the nvim, sops and default-app paths, and the editor line arguments.

Note: `e` is a new default key, so a config that already binds `e` to something else now gets the "bound to both" error, until one of them is rebound.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Karl-Einar Bergstrøm <karl-einarb@outlook.com>
Reviewed-on: #1
2026-10-11 09:34:05 +02:00

3.6 KiB

SOPS and .env files in git repos

lazysecrets shows git repositories under Repos: their SOPS-encrypted files (YAML, JSON, .env, INI) and plain env files as vaults, and the keys in them (db.password, list[0]) as secrets.

Which repos

Repos lists every repo with secret files under the roots (~/git by default; one or two levels down, repo or org/repo), any listed in paths, and any you starred something in (the repo, a file or a key), wherever it is. They're checked in the background.

Started inside a repo, that repo gets a row of its own at the top, Repo · <name>, and lazysecrets opens on it, with the files under the directory you started in first. In the flat list (`) it sorts first, marked · here.

A repo without secret files isn't listed. --dir <path> starts somewhere else, for example in one project of a monorepo.

Repos load themselves as they're found, files and keys, since they're local and cheap: Go to searches them without loading anything by hand.

Which files

Env files: .env, .env.local, prod.env and the like, also when git-ignored (as they usually are), in the folders git tracks files in; not .env.example, .sample, .template and the like. They're read directly; a file with SOPS metadata is always treated as SOPS, whatever its name.

Folders of dependencies and caches are never looked in, tracked or not: node_modules, vendor, .venv, venv, __pycache__, .terraform, .gradle, .yarn, .next and the like.

SOPS files: those tracked by git, then the first of

  1. include/exclude in the repo's own .lazysecrets.yaml (committed, so everyone sees the same files),
  2. include/exclude in the config,
  3. where the repo's .sops.yaml creation_rules say SOPS files go,
  4. the whole repo.

include/exclude apply to env files too.

providers:
  repos:
    roots: [~/git]                             # folders of repos (the default; [] turns it off)
    paths: [~/work/infra]                      # single repos elsewhere
    include: ["secrets/**", "**/*.sops.yaml"]  # globs from the repo root; ** for any depth
    exclude: ["**/testdata/**"]

Decrypting

Listing never decrypts: SOPS encrypts values only, so keys and metadata (encryption, last modified) are read straight from the files. Revealing, copying or lazysecrets get decrypts one value with your sops binary, so whatever sops uses works (age keys, Azure Key Vault through az, AWS/GCP KMS, PGP). When sops can't decrypt, its whole error message is shown.

Opening files

e opens the selected file, or on a secret, its file at that key's line:

  • SOPS files open with sops edit, which decrypts them into your editor ($SOPS_EDITOR or $EDITOR) and encrypts them again when you save. lazysecrets comes back after, with the file's keys reloaded.
  • Other files, when lazysecrets runs inside nvim (its plugin, or :terminal): lazysecrets quits and the file opens in that nvim, in the window you came from.
  • Otherwise in $VISUAL or $EDITOR in the terminal, coming back after; without either, in the system's default app for the file.

Editors that take a line (vim, nvim, nano, emacs, micro, helix, VS Code, Zed, Sublime and others) start on the key. With sops edit that works for editors taking +N (vim, nvim, nano, emacs, micro and others), and needs sops 3.8 or later.

Links name the repo by its git remote, so they open in a colleague's clone wherever it is:

lazysecrets://repo/git.example.com%2Fteam%2Finfra/secrets%2Fapp.yaml/db.password

See links.