No description
  • TypeScript 84%
  • JavaScript 16%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Nyaaan 2ed1a6f17a Fix OpenBao preferences not saving
Freelens sends the store's toJSON() result over Electron IPC as-is, and
vaultPaths was the MobX observable array (a Proxy), which structured
clone rejects. Every renderer-side change threw "An object could not be
cloned" and never reached the main process, so nothing was persisted.
Return a plain copy instead.

Also load the store only once per process. Freelens keeps the extension
module cached across disable/enable cycles, and each loadExtension()
call re-read the file and stacked another sync reaction and IPC listener
that were never disposed, re-broadcasting on-disk state over in-flight
edits on every reload.

Bump to 0.1.1 so reinstalling over 0.1.0 doesn't hit Freelens's
same-version install timeout.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 01:02:30 +11:00
build Add Freelens extension syncing Kubernetes clusters from OpenBao 2026-08-08 15:34:41 +10:00
src Fix OpenBao preferences not saving 2026-10-06 01:02:30 +11:00
.gitignore Add Freelens extension syncing Kubernetes clusters from OpenBao 2026-08-08 15:34:41 +10:00
.tool-versions Add Freelens extension syncing Kubernetes clusters from OpenBao 2026-08-08 15:34:41 +10:00
electron.vite.config.js Add Freelens extension syncing Kubernetes clusters from OpenBao 2026-08-08 15:34:41 +10:00
package-lock.json Fix OpenBao preferences not saving 2026-10-06 01:02:30 +11:00
package.json Fix OpenBao preferences not saving 2026-10-06 01:02:30 +11:00
README.md Add Freelens extension syncing Kubernetes clusters from OpenBao 2026-08-08 15:34:41 +10:00
tsconfig.json Add Freelens extension syncing Kubernetes clusters from OpenBao 2026-08-08 15:34:41 +10:00

@stacktonic/freelens-vault-extension

A Freelens extension that syncs Kubernetes clusters from kubeconfigs stored in OpenBao (KV v1 or v2), so clusters show up in the Freelens Catalog without ever keeping kubeconfigs in ~/.kube/config.

How it works

  1. On a timer (and on demand via the status bar), the extension authenticates to OpenBao by reusing your local bao/vault CLI session — it reads $BAO_TOKEN/$VAULT_TOKEN, or the token cached by bao login ($BAO_TOKEN_PATH/$VAULT_TOKEN_PATH, defaulting to ~/.vault-token). The extension never asks for or stores a token itself.
  2. For each configured Vault path (mount name included, e.g. secret/kubeconfigs), it recursively discovers every secret underneath — the same traversal kubeswitch uses, so a path copied from a kubeswitch config finds the same secrets.
  3. Each secret's kubeconfig YAML (plain or base64, kubeswitch-style) is split into one file per context (so a multi-context kubeconfig secret becomes multiple clusters), written into the extension's own data folder.
  4. One KubernetesCluster catalog entity is published per context, pointing at that file — exactly how Freelens's own built-in kubeconfig sync works, just sourced from OpenBao instead of a folder on disk.

Removed/rotated secrets are detected on the next sync and their clusters and temp files are cleaned up. A transient OpenBao outage does not blank your existing clusters — the last-known set stays until a sync succeeds again.

Setup

  1. bao login (or otherwise ensure $BAO_TOKEN/$VAULT_TOKEN is set) on the machine running Freelens.

  2. Store your kubeconfigs as secrets under one or more Vault paths, one secret per cluster (nested subfolders are fine — they're searched recursively), e.g. for a KV v2 mount:

    bao kv put secret/kubeconfigs/prod-eu kubeconfig=@prod-eu.kubeconfig.yaml
    bao kv put secret/kubeconfigs/staging  kubeconfig=@staging.kubeconfig.yaml
    
  3. Install the extension in Freelens (Preferences → Extensions), then open Preferences → OpenBao Vault and set:

    • OpenBao address — e.g. https://vault.internal:8200
    • Vault paths — one per line, mount name included, e.g. secret/kubeconfigs (defaults to that)
    • KV engine version — v2 (versioned, the default) or v1
    • Kubeconfig field — the key holding the YAML inside each secret, defaults to kubeconfig (falls back to the secret's only field if it has just one)
    • Refresh interval, Vault namespace (if used), Skip TLS verification (only for a trusted self-signed OpenBao instance)
  4. Click the "OpenBao" item in the status bar to sync immediately; your clusters appear in the Catalog once the sync succeeds.

Already using kubeswitch?

If you already have a vault-kind store configured in kubeswitch's ~/.kube/switch-config.yaml, use the Import from kubeswitch field at the bottom of the Preferences tab instead of re-entering everything by hand: point it at your switch-config.yaml (defaults to the standard path) and click Import. It's a one-time copy of that store's address, paths, KV engine version, and kubeconfig field into the fields above — it does not keep reading the file afterward, so the two configs can drift if you edit one later. If your kubeswitch config has more than one vault store, the first one's address/engine/field are used and every store's paths are combined.

Known limitations

  • Materialized kubeconfig files live in plaintext in the extension's data folder — the same trust boundary as Freelens's own kubeconfig sync cache and ~/.kube/config. There is no in-memory/inline kubeconfig option in the public Freelens extension API.
  • Only the "reuse an existing Bao CLI session" auth flow is supported — no AppRole/Kubernetes-auth login from within the extension. This matches kubeswitch's own vault store, which has the same restriction.
  • One OpenBao address/token for the whole extension, even if your kubeswitch config declares multiple vault stores with different addresses — only the first one's connection settings are used (their paths are still combined).

Development

npm install
npm run build         # type-check + electron-vite build -> out/
npm run pack:dev       # build + npm pack -> a .tgz you can install into Freelens