Karl-Einar Bergstrøm 4377eb98bf feat: share env files as encrypted links (#54)
Share `.env` files as an encrypted `lazysecrets://share/…` link. The files are encrypted with a secret's value, so anyone who can read that secret can open the link.

**Sharing:** `S` → `f` on a repo (all its plain env files), an env file, or a key in one (its file).
- **The key** is `share.key` from the repo's `.lazysecrets.yaml`, else from the config. It can be a `lazysecrets://` link, a Key Vault URL or an `@Microsoft.KeyVault(...)` reference.
- **Without `share.key`,** a picker built on Go to opens, titled "Share .env", with "Pick a secret to encrypt with" in its own border. It lists only secrets, leaving out values from plain `.env` files. Pasting a reference picks it. Picking shares at once, and the picker stays open until the link is copied. If the secret can't be used, the reason shows in red in the picker: it can't be read, or it doesn't meet `share.keyRules` (which rule failed is named). `esc` cancels.
- **`share.keyRules`** (defaults `minLength: 32`, `minClasses: 2`; never under 16) applies when sharing, not when opening.
- **On Azure,** the link pins the key's version, so rotating the key doesn't break old links, and disabling a version revokes them.
- **The command line:** `lazysecrets share [--key <secret>] <env files>`.

**Opening** works by paste, `ctrl+o`, the clipboard offer, the link handler or `lazysecrets <link>`.
1. It first says which repo the link is from, how many files it holds and which key it uses, and decrypts only after `o`.
2. It saves into the repo's clone, found by its remote, showing which files are new, which would replace one there, and which git doesn't ignore.
3. Without a clone, it asks for a folder and saves straight away. The prompt stays open, with the reason in red, until the files are written.
4. If decryption fails, a popup says why: the first line of the reason, `r` for the whole message, `g` to go to the key's secret. A key that has changed is named by where it lives: a Databricks or SOPS value changed in place, an Azure current version that isn't the one the link was made with, or a pinned version, meaning the link may be damaged.

**Format** (`internal/share`): a version byte, then a JSON header with the key, the repo and the file count, then an age file (scrypt 2^15, with the key's value as passphrase) holding the files as deflated JSON, all as unpadded base64url. Links are capped at 16 KB. A future format gets a new version, and old ones stay readable.

**Safety:**
- A link can only write env files, inside the folder: never in `.git`, never through a symlink.
- New files are created with mode 0600.
- Opening accepts an scrypt work factor of at most 2^20, and unpacks at most 1 MB.

**Along the way:**
- Opening a link to a secret ends on its details, as `enter` would.
- `o` on an Azure secret opens its portal page, and in the versions view, that version's page.
- The details pane follows its secret's list when it reloads in the background. Before, it kept what it showed first, including an old portal address.
- `ref.Read` is shared by `get` and sharing, with Azure `VersionedValue` for pinning.
- `provider.Contents` lets the demo repos share their env files. `--demo` has a share key (`kv-shared-prod / env-share`), so the whole flow works there.
- New dependency: `filippo.io/age`.

Tested end to end in the TUI and the demo, the CLI, and the `share` package. In a real vault: version pinning, opening into a clone, and revocation by disabling the version.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Reviewed-on: #54
2026-10-13 14:55:22 +02:00
2026-10-12 15:40:46 +02:00
2026-10-12 15:40:46 +02:00
2026-10-12 15:40:46 +02:00
2026-10-12 15:40:46 +02:00
2026-10-12 15:40:46 +02:00
2026-10-12 15:40:46 +02:00
2026-10-12 15:40:46 +02:00
2026-10-12 15:40:46 +02:00
2026-10-12 15:40:46 +02:00

lazysecrets

A terminal UI for finding, reading and sharing secrets. Inspired by the fantastic lazygit.

lazysecrets

Main features

  • Read-only: lazysecrets never creates, changes or deletes a secret. That's by design and may stay that way.
  • Zero setup: uses the logins you already have (az, the Databricks CLI, sops, git). No config file needed.
  • Search everything: ctrl+s searches every source at once, with fzf-style matching.
  • Share links: Share lazysecrets:// links with colleagues. A colleague opens it with their own access, from the terminal or with a click in the browser or chat. .env files can be shared too, as a link encrypted with a secret your team can read.
  • Neovim integration: via lazysecrets.nvim
  • Careful with values: values stay hidden until you reveal them, and copied values are cleared from the clipboard after 30 seconds.
  • Scriptable: lazysecrets get <link> prints a value for scripts and pipes.
  • Favourites: star the secrets you use most for easy access.
  • Expiry warnings: secrets, keys and certificates that expire soon are marked, listed together in the status pane.
  • Your way: rebind any key, pick a theme, and add custom commands to run on a secret.
  • Try it first: lazysecrets --demo runs on built-in sample data.
  • Supported platforms: Azure Key Vault, Databricks secret scopes, and SOPS and .env files in your git repos.

Early development: expect rough edges. See CHANGELOG.md for what's new.

Install

On macOS or Linux (arm64 or x86_64):

curl -fsSL https://git.kebcloud.no/keb/lazysecrets/raw/branch/main/install.sh | sh

It installs the latest release, from GitHub or else git.kebcloud.no, into ~/.local/bin after checking it against the release's checksums. sh -s -- v0.2.0 installs a given version, LAZYSECRETS_INSTALL_DIR somewhere else.

lazysecrets looks for a newer release once a day: the footer then shows ↑ v0.2.0, and U shows its changelog and updates in place (or run lazysecrets update).

Or build it yourself: go install git.kebcloud.no/keb/lazysecrets/cmd/lazysecrets@latest.

Get started

az login            # login with azure cli
lazysecrets         # start lazysecrets
lazysecrets --demo  # test with demo data

Pick a source on the left, then a vault, then a secret. With nothing signed in yet, the right pane says how to get started. The keys you'll use most:

Key Action
j/k, enter, esc move, drill in, back
l / h the details of what's selected / back
/ filter the list you're in
space reveal / hide the value
y copy the value (cleared from the clipboard after 30s)
ctrl+s Go to: search everything and jump there
f / F star / your favourites
s copy a link to share
? every key, searchable
q quit

Docs

  • Keys: every key, Go to, the layout, and rebinding keys
  • Azure Key Vault: accounts, permissions, pinned vaults
  • Databricks: profiles and Key Vault-backed scopes
  • SOPS and .env files: which repos and files, decrypting
  • Links: sharing, opening, lazysecrets get in scripts, and opening links from the browser and chat
  • Custom commands: run your own commands on a secret
  • Config: every option, themes, layered configs, the state file
  • Development: building, tests, pull requests and releasing

Privacy

lazysecrets never stores, caches or sends your secret values. It keeps the names and metadata of what you've loaded in a cache file readable only by you, to show it at once next time (cache: false turns it off). It talks only to the services you use it with, and collects no usage data. The one call of its own is a daily check for a new release, on GitHub or else git.kebcloud.no, which updateCheck: false turns off.

Repositories

The main repo of this codebase is at git.kebcloud.no. The GitHub mirror is for discoverability, issue-tracking and releases. It also makes it possible to give a ⭐ if you like lazysecrets!

Contributing

I don't take pull requests as I don't have time to review and test them. But bug reports and ideas are very welcome! Open an issue on GitHub and I'll have a look.

AI disclosure

Built with help from an agentic coding assistant. Every change is requested, reviewed and tested by me before it's merged.

License

Copyright © 2026 Karl-Einar Bergstrøm.

lazysecrets is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. See LICENSE.

v0.2.1
Latest
2026-10-15 10:52:43 +02:00
Languages
Go 99.1%
Shell 0.6%
JavaScript 0.3%