keyring

package module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 7, 2026 License: MIT Imports: 21 Imported by: 0

README

go-keyring

Go


One credential store for a Go desktop app: the OS keyring, with a sealed-file fallback inside a Flatpak. Package keyring, module github.com/Rethunk-Tech/go-keyring.

A Go desktop app keeps a token in the OS keyring (Secret Service on Linux, Credential Manager on Windows; the macOS Keychain works through the same backend but is untested). Inside a Flatpak, where the session keyring is not reachable by default, the same calls fall back to a file sealed under the XDG Secret portal's per-app secret, then to the host's Secret Service, then to a plain 0600 file. Reads are bounded, so a GUI is never held by an unlock prompt nobody answers.

Quick start

go get github.com/Rethunk-Tech/go-keyring

A worked example and the contracts: HUMANS.md.

Features

  • One Store with Get, Set and Delete, plus GetIn, SetIn and DeleteIn for an item another program shares.
  • A read behind an unlock prompt returns ErrPending after ReadTimeout, keeps running, and calls OnUnlocked when it completes.
  • Inside a Flatpak: a sealed file (AES-256-GCM), else the host keyring, else a plain file; Plaintext says which.
  • Items from an earlier fallback are found and moved forward on read, never lost.
  • ErrNotFound and ErrTooBig are zalando's own values, so errors.Is holds against its MockInit.
  • Typed ErrLocked and ErrNoProvider replace raw D-Bus text.

Documentation

Doc Audience
HUMANS.md Running and using the package
AGENTS.md Internals, invariants, and why
CONTRIBUTING.md Process — commits, tests, docs
SECURITY.md Vulnerability disclosure
CHANGELOG.md Release notes

License

MIT — see LICENSE. © 2026 Rethunk.Tech, LLC.

Documentation

Overview

Package keyring is one credential store for a Go desktop app: the OS keyring, with a sealed-file fallback inside a Flatpak.

Index

Constants

View Source
const ZalandoVersion = "v0.2.8"

ZalandoVersion is the zalando/go-keyring version this release's live tests ran against.

Variables

View Source
var (
	// ErrNotFound is zalando's ErrNotFound, the same value, so errors.Is holds for a caller that mocks the
	// backend with zalando's MockInit.
	ErrNotFound = zkeyring.ErrNotFound
	// ErrTooBig is zalando's ErrSetDataTooBig, the same value: Windows refuses a credential over 2,560 bytes.
	ErrTooBig = zkeyring.ErrSetDataTooBig
	// ErrPending means a read is still waiting on an unlock prompt. It is not a failure: the read keeps running
	// and Options.OnUnlocked fires when it completes. Plaintext also returns it when the store is busy.
	ErrPending = errors.New("keyring: waiting for the keyring to be unlocked")
	// ErrLocked wraps the backend error when an unlock prompt was dismissed or failed. Nothing is cached: the
	// next call prompts again.
	ErrLocked = errors.New("keyring: the keyring stayed locked")
	// ErrReservedName means an item of the store's own service is named "<shared service>.<name>", which the
	// Flatpak files keep for that shared service's item.
	ErrReservedName = errors.New("keyring: the name collides with a shared service's item")
	// ErrNoProvider wraps the D-Bus error raised when nothing answers as the Secret Service.
	ErrNoProvider = errors.New("keyring: no Secret Service provider is running")
)

Functions

This section is empty.

Types

type Options

type Options struct {
	Service  string // keyring service for Get, Set and Delete. Required
	SealInfo string // HKDF info deriving the sealed file's key from the portal secret. Required
	Folder   string // the Flatpak store's folder name under the data home. Required, one path element
	// SharedServices are other programs' services whose items the Flatpak files keep as "<service>.<name>";
	// a plain file moving to the host keyring puts those back under (service, name).
	SharedServices []string
	// ReadTimeout bounds how long Get waits before returning ErrPending. Zero means 3s.
	ReadTimeout time.Duration
	// PortalTimeout bounds the Secret portal call, which may sit behind a dialog. Zero means no bound.
	PortalTimeout time.Duration
	// OnUnlocked runs after a read that outlived ReadTimeout completes, or was overtaken by a Set or Delete, so
	// the app can retry what it deferred.
	OnUnlocked func()
}

Options configures a Store. Service, SealInfo and Folder have no defaults: a derived one would let two programs share a store without either choosing it.

type Store

type Store struct {
	// contains filtered or unexported fields
}

Store is one credential store. Use one Store per Folder per process: the Flatpak store's lock is per Store.

func New

func New(o Options) (*Store, error)

New returns a Store, or an error when a required option is empty or malformed.

func (*Store) Delete

func (s *Store) Delete(name string) error

Delete removes the secret under name; one that is already gone is not an error. It is not bounded.

func (*Store) DeleteIn

func (s *Store) DeleteIn(service, name string) error

DeleteIn removes the secret under another program's service and name.

func (*Store) Get

func (s *Store) Get(name string) (string, error)

Get returns the secret stored under name.

func (*Store) GetIn

func (s *Store) GetIn(service, name string) (string, error)

GetIn returns the secret another program shares under its own service and name. Outside a Flatpak, and in host-keyring mode, that program can read it too.

func (*Store) Plaintext

func (s *Store) Plaintext() (bool, error)

Plaintext reports whether secrets are in the unencrypted fallback file: inside a Flatpak, with neither the secret portal nor a host Secret Service. A store busy with a prompt returns (false, ErrPending) instead of waiting; a store that cannot be resolved returns (false, err).

func (*Store) Set

func (s *Store) Set(name, value string) error

Set stores value under name, replacing any earlier one. It is not bounded: a locked keyring holds it on the unlock prompt.

func (*Store) SetIn

func (s *Store) SetIn(service, name, value string) error

SetIn stores value under another program's service and name, as GetIn reads it.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL