go-keyring

Cross-platform Go library for storing secrets in the OS-native keyring or keychain.

Library
Go
vv0.2.8
1,325stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
67/100Good
Development Activity56
Maintenance48
Community64
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
76/100Good
Architecture85
Code Quality78
Innovation82
Learning Curve60

go-keyring is a small, dependency-light Go library for storing and retrieving secrets in the operating system’s native credential store, exposing a single Set/Get/Delete/DeleteAll/ListUsers API that works transparently across the macOS Keychain, the Linux/BSD Secret Service D-Bus interface, and the Windows Credential Manager.

It exists because most Go keyring wrappers require cgo bindings to native libraries, which complicates static linking; go-keyring instead shells out to platform tools (the macOS security binary, D-Bus for Linux/BSD, and wincred for Windows) so applications built with it stay statically linked, easily cross-compiled binaries. A built-in MockInit()/MockRestore() pair makes it straightforward to unit test code that depends on keyring access without touching the real OS credential store.

What You Get

  • A unified Keyring interface with Set, Get, Delete, DeleteAll, and ListUsers methods that behave identically on macOS, Linux/BSD, and Windows
  • Native OS integration with no cgo required — shells out to /usr/bin/security on macOS, the Secret Service D-Bus API on Linux/BSD, and the Windows Credential Manager via wincred
  • A built-in in-memory mock provider (MockInit/MockRestore/MockInitWithError) for testing code that touches the keyring without a real OS credential store
  • Typed error sentinels (ErrNotFound, ErrSetDataTooBig) for consistent error handling across all three platforms
  • Automatic encoding/decoding of secrets that the macOS Keychain would otherwise mangle for multi-line or non-ASCII values

Common Use Cases

  • Storing a CLI tool’s API token or password after first login so users aren’t prompted on every run
  • Persisting OAuth refresh tokens for a desktop or CLI application securely instead of in a dotfile
  • Building developer tools that need to cache credentials for external APIs without shipping a custom encrypted storage format
  • Writing testable code paths that read and write secrets, using MockInit in unit tests to avoid OS keyring dependencies in CI

Under The Hood

Architecture The library is a single Go package (keyring) whose public surface is defined in keyring.go as a small Keyring interface (Set/Get/Delete/DeleteAll/ListUsers). Platform-specific implementations live in build-tag-gated files — keyring_darwin.go (macOS), keyring_unix.go (Linux/BSD via D-Bus, gated to builds with dbus/cgo support), keyring_windows.go, and a keyring_fallback.go for unsupported targets — each registering itself into a package-level provider variable from its own init() function, so the right backend is wired up automatically at build time based on GOOS. keyring_mock.go swaps an in-memory mockProvider into that same provider variable for tests. The Linux/BSD backend further delegates to an internal secret_service package that wraps the Secret Service D-Bus calls, and internal/shellescape provides quoting for the macOS os/exec invocations. Changing the core Keyring interface touches all platform files symmetrically, which is about as clean a one-interface/N-platform-strategy design as a small Go library gets.

Tech Stack Written in Go 1.18 with a deliberately minimal dependency footprint: github.com/danieljoos/wincred for Windows Credential Manager access, github.com/godbus/dbus/v5 for the Linux/BSD Secret Service protocol, and golang.org/x/sys as an indirect dependency. There is no web framework, database, or custom build tooling — just go build/go test. CI runs on GitHub Actions across ubuntu (in a container with gnome-keyring installed), macOS, Windows, and FreeBSD runners, exercising the real platform keyring rather than only the mock.

Code Quality Test coverage is substantial for the package’s size — keyring_test.go, keyring_mock_test.go, and secret_service_test.go together cover the public API and the D-Bus backend. Notably, the Linux CI job unlocks a real gnome-keyring-daemon under dbus-run-session and runs the actual test suite against it rather than relying solely on the mock, which is an unusually thorough integration-testing setup for a small library. Error handling uses typed sentinel errors (ErrNotFound, ErrSetDataTooBig) consistently across all backends, and naming follows idiomatic Go conventions throughout. No dedicated linter configuration (e.g. golangci-lint) is present in the repo, though CI enforces go build/go test across all four supported platforms.

API Design The public API is deliberately minimal: five free functions (Set, Get, Delete, DeleteAll, ListUsers) mirroring the Keyring interface, callable directly with zero setup — no client struct to construct, no context threading, no cgo build tags for the caller to manage. The MockInit()/MockRestore() pair gives an ergonomic testing seam without requiring a mocking framework. The README goes further than most libraries by documenting the equivalent native CLI commands (security, secret-tool, cmdkey/PowerShell) for each supported OS, which is useful for debugging outside of Go. Getting started requires essentially one import and one function call.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search