Skip to content

Compiled binaries never use the OS keychain for the master key #239

Description

@Minitour

Problem

Compiled capa binaries (bun build --compile) can't load @napi-rs/keyring. The package picks its platform addon (@napi-rs/keyring-<platform>) with a dynamic require at runtime. bun build --compile can't follow that require, so the native .node file is never embedded.

At runtime tryOpenKeyring() fails with Cannot find native binding and returns null, so every shipped binary falls back to the file tier (~/.capa/master.key). capa status reports Secret storage: file (fallback). This affects 2.1.x and 2.2.0.

Running from source (bun run src/cli/index.ts) does load the keyring, so the keychain tier only works in development.

Verified

  • A compiled probe that requires @napi-rs/keyring fails with Cannot find native binding.
  • A compiled probe with a static require("@napi-rs/keyring-win32-x64-msvc") embeds the addon and works: a missing entry returns null, and set/get/delete round-trips.
  • @napi-rs/keyring 2.1.0 works on Windows when loaded.

Proposed fix

  1. Embed the addon per build target. Generate a small module at build time with a static require of the platform package for BUN_TARGET, and use it in master-key-store.ts before falling back to the dynamic require.
    • The release workflow cross-compiles (linux-arm64 on x64, darwin-x64 on arm64), so each job needs that target's optional package installed (for example bun install --os/--cpu, or an explicit bun add of the platform package).
    • Linux builds should consider musl vs gnu.
  2. Safe fallback for existing installs. Only use the OS keychain for users who don't already have a master key:
    • If ~/.capa/master.key already exists, keep using the file tier. Don't migrate it into the keychain.
    • The keychain tier applies only when no file key exists (new installs). Keep the file copy for rollback, as loadMasterKey does today.
    • Rationale: upgrading must never change where existing secrets' key lives, and must not trigger new keychain prompts.
  3. Account for macOS keychain prompts. Unsigned binaries, or binaries whose signature changes on every upgrade, may prompt for keychain access. Verify the prompt behavior before enabling on macOS; code signing may be needed first.

Acceptance criteria

  • A new install on each release target reports Secret storage: keychain / dpapi / libsecret, or falls back to file when the platform service is unavailable (e.g. headless Linux without Secret Service).
  • An existing install with ~/.capa/master.key keeps reporting file, and all stored secrets still decrypt after upgrading.
  • There are no keychain prompts on upgrade for existing users.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions