feat: l for details; details for vaults, scopes and files; getting started; the age of cached lists (#17)

- `l` goes to the details of what is selected; `enter` still drills in
- vaults, scopes and files show their details (vault settings from the listing, no extra requests)
- with nothing to show, the right pane says how to get started
- a list from the cache says how old it is while it reloads
- what is expiring, in the status pane and `lazysecrets expiring`
- when access is refused, what to check, for Azure and Databricks
- no group list in an account's details, and no Microsoft Graph call for it

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit was merged in pull request #17.
This commit is contained in:
kebandClaude Opus 5.5 committed 2026-10-11 14:24:08 +02:00
1 parent 9b0329e9da
commit 09bacd8438
32 files changed
+1321 -254

No files matched your search

+35 -8
View File
@@ -16,12 +16,10 @@ A service principal is used instead when `AZURE_CLIENT_ID`,
On an account's group row, the fourth pane shows who it signs in as: name,
user, tenant, object ID, whether the session used MFA, directory roles
(built-in ones by name) and its subscriptions, read from az's account list
and the token lazysecrets already has. Below them are the groups the
account is in, nested ones too: those come from Microsoft Graph, once a
session, the first time the pane shows them. `y` on the row copies the
object ID, the one access policies and role assignments ask for; `tab`
goes into the pane, where `j`/`k` pick any field or group, `/` filters
them (`/tenant`, `/platform`) and `y` copies the selected one.
and the token lazysecrets already has: no requests of their own. `y` on
the row copies the object ID, the one access policies and role
assignments ask for; `l` goes into the pane, where `j`/`k` pick any
field, `/` filters them (`/tenant`) and `y` copies the selected one.
If an account's az login has expired, the status line says so once, and the
Details pane on that account's rows says it until you sign in: press `L`
@@ -40,8 +38,10 @@ vault resources (e.g. *Reader*). Key Vault data-plane access is separate
| read secret values | *Key Vault Secrets User* |
| read certificate details | *Key Vault Certificate User* |
A missing permission is shown in the pane, including the action that was
denied.
A missing permission is shown in the pane, shortened to what was denied
(the action, or the access policy permission), with what to check: a
role or group to activate in PIM, access from the vault's owner, or, when
its firewall refused, the network you're on.
## Vaults you can't discover
@@ -64,3 +64,30 @@ Secrets, keys and certificates, each on their own tab of the Secrets pane
key (PEM public key) or certificate; private key material is never
fetched. `v` lists an item's versions. Items expiring within
`expiryWarningDays` (30 by default) are marked `⚠ 12d`, expired ones `✗`.
The status pane (`0`) lists them across every vault loaded, opened or
cached, soonest first, and its line counts them (`⚠ 3 expiring`); `enter`
on one goes to it. That makes no requests of its own: expiry dates come
with the lists. It says how many vaults it covers; `ctrl+a` in search
loads the rest.
For a pipeline or a cron job, `lazysecrets expiring` lists them in every
vault of every account, loading each vault's lists (a few at a time):
```sh
$ lazysecrets expiring --days 30
LEFT EXPIRES TYPE VAULT NAME LINK
expired 2026-03-01 certificate kv-app-prod old-tls lazysecrets://azure/kv-app-prod.vault.azure.net/certificates/old-tls
12d 2026-10-23 secret kv-app-prod api-key lazysecrets://azure/kv-app-prod.vault.azure.net/secrets/api-key
```
`--days` defaults to `expiryWarningDays`. Accounts that need a sign-in and
lists it can't read are named on stderr, one line each. Like grep, it
exits 0 when nothing expires, 1 when it lists something, and 2 when it
couldn't check everything.
On a vault, the right pane shows its settings: resource group, location,
SKU, whether access is by Azure roles or access policies, soft delete and
purge protection, which networks can reach it, private endpoints and tags.
They come with the list of vaults, so they cost no extra requests and are
cached with it.
+3 -2
View File
@@ -114,8 +114,9 @@ What lazysecrets has loaded is kept in
you: the Sources lists, vaults and scopes, and secrets' names and metadata
(tags, dates, references), never values. On the next start they show at
once, and anything older than two minutes reloads in the background when
you go to it, or when Go to searches it. Revealing and copying always
fetch the value live.
you go to it, or when Go to searches it. While it does, the pane's
bottom border says how old what it shows is (`cached 3h ago`). Revealing
and copying always fetch the value live.
Lists not loaded for 30 days are dropped, and so is everything from an
account you're no longer signed in to. Repos aren't cached: their files
+8
View File
@@ -13,6 +13,14 @@ Secrets in Azure Key Vault-backed scopes are read through Databricks; if
Databricks refuses, lazysecrets reads the backing vault directly with your
az login (which then needs the [Key Vault roles](azure.md#permissions)).
When Databricks refuses, the pane says what to check: access to the
workspace and READ on the scope, or, when the workspace's IP access list
refused, the network you're on.
On a scope, the right pane shows who has access to it and how much
(manage, write, read). Databricks shows that only to the scope's
managers; to others it says so.
Hide profiles you don't want in the [config](config.md):
```yaml
+4 -4
View File
@@ -13,7 +13,8 @@ The rule: a letter in the lists, ctrl+ that letter where you type a filter
|---|---|
| `j`/`k`, `↑`/`↓` | move |
| `g`/`G` | top / bottom |
| `tab`/`l`, `shift+tab`/`h` | next / previous pane |
| `tab`, `shift+tab`/`h` | next / previous pane |
| `l` | the details of what's selected, on the right (`h` goes back) |
| `1`–`4` | jump to pane |
| `enter` / `esc`, `⌫` | drill in / back (also clears a filter or leaves the versions view) |
| `[` / `]` | previous / next tab of the focused pane: Sources and Favourites in Sources; Secrets, Keys, Certs in Secrets |
@@ -107,9 +108,8 @@ anything loads.
The pane on the right describes what's selected in the pane you're in: the
account or subscription in Sources, the vault in Vaults, the secret in
Secrets. Going into it (`4`, or `tab` from an account's row) keeps it on
that; there `j`/`k`, `/` and `y` work on its rows, and `shift+tab` goes
back. A value you reveal stays in view whichever pane you're in, until
Secrets. Going into it (`l`, or `4`) keeps it on that; there `j`/`k`,
`/` and `y` work on its rows, and `h` goes back. A value you reveal stays in view whichever pane you're in, until
it's hidden.
On top, the status pane (`0`) shows the version, a newer release and how
+7
View File
@@ -63,6 +63,13 @@ 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.
On a file, the right pane shows how it's encrypted and the keys it's
encrypted for (public: age recipients, Key Vault keys, KMS ARNs, PGP
fingerprints), when it was last encrypted, and what git knows of it:
tracked, ignored or neither, and its last commit. A plain `.env` file that
git tracks, or that isn't ignored, is marked in red: its values are in the
repo's history, or easily could be.
## Opening files
`e` opens the selected file, or on a secret, its file at that key's line: