go-keyring: Cross-platform secrets for Go applications
Cross-platform keyring interface for Go
At a glance
- What is it?
- go-keyring gives Go programs one API for storing, retrieving, and deleting secrets through native keyring services on macOS, Linux, BSD, and Windows. It is a good fit for local credentials, but it depends on functioning desktop keyring infrastructure and does not provide secret synchronization or cross-machine recovery.
- Who is it for?
- Adopt go-keyring for a Go CLI or desktop application that must keep short-lived local credentials in the current operating system's keyring, especially if a statically linked binary matters. Do not adopt it as a general secret vault, server-side secret manager, or cloud synchronization layer.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 7 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.
Editorial analysis
go-keyring targets credentials stored on one user machine
go-keyring addresses a narrow but common problem in Go applications: avoiding plaintext secret files when a program needs a credential again on the same machine. The README gives the case of a CLI that calls an API with a username and password. Instead of asking the user for those values on every invocation, the application can save them in the operating system's credential store and retrieve them later.
The target audience is developers building Go applications that run on the user's workstation. This includes local command-line tools and desktop programs. The project supports macOS, Linux, BSD, and Windows, but it does not describe Linux server operation without a Secret Service provider. Nor does it present cloud storage, team secret sharing, audit trails, or application-level access control as features.
The public Go API is intentionally small: `Set`, `Get`, and a deletion operation exist for storing, retrieving, and removing secrets. A secret is identified through a service name and a user name. That pair also has a direct effect on how credentials appear in native tools. On Windows, the README states that the library combines them into a `service:username` target. This simple identity model works well for one application storing several account credentials, but the documentation does not describe tags, folders, metadata, secret versions, or shared access groups.
One API dispatches to operating-system keyring providers
The repository layout shows a shared interface in `keyring.go` and separate operating-system implementations named `keyring_darwin.go`, `keyring_unix.go`, and `keyring_windows.go`. A fallback file and a mock implementation are also present. Based on that layout, callers use the same package-level operations while the selected provider handles the platform-specific work.
On macOS, the documented dependency is `/usr/bin/security`. The library interfaces with the OS X Keychain through that command rather than through a C binding. The repository description says this design was chosen partly to simplify use with statically linked binaries. The README's direct CLI section gives the matching `security` commands for adding, finding, and deleting generic passwords.
Linux and BSD use the Secret Service D-Bus interface, which the README associates with GNOME Keyring. The Go module includes `github.com/godbus/dbus/v5`, which aligns with that documented mechanism. The expected default collection is `login`. If it is missing, the README directs Linux users to create a password keyring named `login` through Seahorse. This is an important deployment condition: importing the Go package does not create the desktop session, keyring daemon, collection, or session necessary to use it.
Windows uses Credential Manager, and `go.mod` includes `github.com/danieljoos/wincred`. The README states that the service and username are combined as `service:username`, matching the target form used in its `cmdkey` and PowerShell examples. These details show that go-keyring is an adapter over existing operating-system facilities, not a new credential database.
The README does not provide an installation command
The README does not document a project-specific `go install` command or a module dependency command. It does, however, identify the import path used throughout the example:
import "github.com/zalando/go-keyring"For a first real use, create a Go program that saves a password and then retrieves it with the same service and user identifiers. The following is the complete API flow printed in the README, with no additional behavior added:
package main
import (
"log"
"github.com/zalando/go-keyring"
)
func main() {
service := "my-app"
user := "anon"
password := "secret"
err := keyring.Set(service, user, password)
if err != nil {
log.Fatal(err)
}
secret, err := keyring.Get(service, user)
if err != nil {
log.Fatal(err)
}
log.Println(secret)
}Running the program should first store `secret` under service `my-app` and user `anon`, then print the retrieved value. The first real check is platform-specific, however. A macOS user needs `/usr/bin/security`. A Linux or BSD user needs a Secret Service D-Bus provider and a `login` collection. A Windows user needs Credential Manager. The source does not document one common user prompt across all four systems, so application developers should not assume identical interactive behavior.
Command-line access exposes the provider and credential boundaries
The README documents direct command-line access because it is useful for debugging, scripting, and understanding the native provider behind the Go package. On macOS, `security add-generic-password` creates or updates a generic password, while `find-generic-password` retrieves it. The service and account fields form the lookup identity used by the Go API.
Linux and BSD commands use `secret-tool`, supplied by libsecret. Store and lookup commands use the attributes `service` and `username`. The label is only a human-readable description, while those attributes identify the item:
secret-tool lookup service "service" username "user"This makes it possible to inspect an item created by a Go program, but it also means changing service or user names changes its identity. Developers should choose stable values tied to the application and account rather than display labels.
On Windows, `cmdkey` can create and delete generic credentials, but the README explicitly states that it cannot retrieve passwords directly. Retrieval examples therefore use PowerShell and `Get-StoredCredential`, either from the CredentialManager module or through the documented Windows API path. The extra module is not part of go-keyring itself. It is useful for inspection, but its installation requirement should not be confused with a dependency needed to compile the library.
The library's deletion API is relevant for logout, credential replacement, and account removal, but the README does not document rollback, backup, recovery, or migration between operating systems. Deleting a secret through one native tool can make a later Go lookup fail because the identity no longer exists.
In-memory MockInit separates application tests from desktop keyrings
go-keyring includes an explicit testing path for systems without a working keyring implementation. Calling `MockInit()` replaces the operating-system-defined provider with an in-memory one. This allows a Go test to exercise the same `Set` and `Get` calls without relying on Keychain, Secret Service, D-Bus, or Credential Manager:
func TestMockedSetGet(t *testing.T) {
keyring.MockInit()
err := keyring.Set("service", "user", "password")
if err != nil {
t.Fatal(err)
}
p, err := keyring.Get("service", "user")
if err != nil {
t.Fatal(err)
}
if p != "password" {
t.Error("password was not the expected string")
}
}This is useful for unit tests because the assertions concern package behavior, not the security policies or prompts of a particular desktop. It is not a persistent secret store, and the README does not claim that data survives process termination. Any test that depends on credentials surviving between processes would therefore need a different setup.
The repository also lists improved test coverage as a contribution item. That is worth noting for adoption decisions: the project has testing support and an OS-aware test description, but the README itself calls for better coverage. Application teams should still test missing items, access failures, provider errors, deletion, repeated writes, and platform sessions against their real supported environments. The mock cannot reproduce those native integration conditions.
Linux desktop dependencies and account boundaries constrain deployment
The largest documented deployment constraint appears on Linux and BSD. The package expects the Secret Service D-Bus interface and the default `login` collection. A minimal container, headless server, or Linux session without an available keyring provider may have Go and D-Bus installed but still lack the user-facing credential service required by this implementation. The README points to GNOME Keyring as a provider, not as a mandatory application for every distribution.
The keyring belongs to the operating-system account and desktop session. The documentation does not promise that one user's stored value is visible to another user, even when both launch the same application. It also does not document roaming between machines, synchronization through iCloud or cloud secret services, shared credentials for multiple users, or recovery after the native keyring is removed.
Another limitation is the boundary between storage and secret lifecycle. go-keyring can store, retrieve, and delete a secret, but the README does not define automatic expiration, rotation, auditing, conflict resolution, or rollback. Nor does it document behavior for multiple simultaneous application instances updating the same service and user pair. The macOS `security` example uses `-U` to update an existing item, but that CLI option does not establish that every platform has identical update semantics.
This makes go-keyring unsuitable as the only control for highly privileged secrets when no native keyring exists. The package also cannot provide an application-level recovery flow by itself. Those capabilities would need to come from the surrounding application or a different kind of secret service.
MIT licensing, Go 1.18, and recent releases shape adoption cost
The module declares Go 1.18 in `go.mod`, so applications need to account for that language baseline when integrating it. Direct dependencies are `github.com/danieljoos/wincred v1.2.3` for Windows-related access and `github.com/godbus/dbus/v5 v5.2.2` for D-Bus, with `golang.org/x/sys v0.27.0` listed as an indirect dependency. These dependencies also become part of the application's module graph and build review.
The project uses the MIT License. That permits use, modification, distribution, and sublicensing under the license's conditions, including preservation of its copyright and license notice. This is a factual summary of the stated license rather than legal advice. The repository also includes `LICENSE`, `CONTRIBUTING.md`, `SECURITY.md`, and `MAINTAINERS`.
The repository is not archived. Its last push was on 2026-10-16, and the recent release list includes `v0.2.8` from 2026-03-23, following `v0.2.7` from 2026-03-20. The README directs security issues to the maintainers and says the team will try to respond within two workdays. It does not provide a compatibility promise for every earlier release, so an adopting application should pin and review the module version it uses.
Unlike alternatives that provide a hosted secret service, go-keyring contains no remote API, account provisioning, synchronization policy, or centralized audit system. Unlike C-bound keyring wrappers, it avoids a C binding for the statically linked binary use case described by its authors. That narrower design is its principal advantage and its principal constraint.
Editorial conclusion
Adopt go-keyring for a Go CLI or desktop application that must keep short-lived local credentials in the current operating system's keyring, especially if a statically linked binary matters. Do not adopt it as a general secret vault, server-side secret manager, or cloud synchronization layer. Verify first that every supported workstation has the required keyring provider, especially the Secret Service D-Bus interface on Linux and BSD, and agree on deletion and missing-secret handling before shipping.
Frequently asked questions
Which operating systems does go-keyring support?
The README lists macOS, Linux, BSD through the Secret Service D-Bus interface, and Windows through Credential Manager. Support still depends on the native service being available on the user's machine.
How can I test go-keyring without a system keyring?
Call `MockInit()` to replace the operating-system provider with an in-memory implementation. The README shows this approach in a Go test that stores and retrieves `password`.
What is required to use go-keyring on Linux or BSD?
A Secret Service D-Bus provider such as GNOME Keyring must be available, along with the expected `login` collection. The README explains that a missing collection can be created through Seahorse.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/zalando-go-keyring)Was this useful?