Help us shape the future of Go! Take the 2026 Go Developer Survey

credentials

package
v4.2.0 Latest Latest
Warning

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

Go to latest
Published: Nov 1, 2026 License: Apache-2.0 Imports: 11 Imported by: 0

Documentation

Overview

Package credentials stores and resolves the OAuth token of one profile: access token, refresh token, expiry and type.

Resolution order:

  1. GITLAB_MCP_REFRESH_TOKEN in the environment (CI, automation).
  2. The OS keyring — Secret Service on Linux, Keychain on macOS, Credential Manager on Windows — keyed by the profile name.
  3. A file under the profile directory, restricted to the current account (0600, or an ACL on Windows), written only when the keyring was unavailable, and warned about on every use.

A missing keyring entry falls through quietly. A broken keyring (no session bus, no secret service) also falls through, so a headless machine still works, and its error is reported if nothing else is found.

GitLab rotates the refresh token on every refresh and revokes the old one at once (§2.3), so a refresh token from the environment works exactly once. The pair it rotates into is saved to the keyring or the file stamped with a hash of the variable's value, and while the variable still holds that value the stored descendant is used in its place. Without that, the second start after a refresh would present a spent token.

Index

Constants

View Source
const ServiceName = "gitlab-mcp"

ServiceName is the keyring service identifier.

Variables

View Source
var ErrKeyringSilent = errors.New("credentials: the profile records a token in the OS keyring and the " +
	"keyring returned nothing. It is more likely locked or unreachable than empty: unlock it and try again. " +
	"`gitlab-mcp login` writes a fresh token, which works around this rather than fixing it")

ErrKeyringSilent is what a keyring that answers "nothing" looks like when the profile says a token was stored in it.

The two are not the same and the advice differs. A missing token is fixed by logging in. A keyring that has the token and will not hand it over — locked, or a session bus that cannot reach the daemon — is fixed by unlocking it, and logging in again writes a second token beside the first without addressing the cause.

View Source
var ErrNotFound = errors.New("credentials: no token found; run `gitlab-mcp login`")

ErrNotFound means no token is stored anywhere.

Functions

This section is empty.

Types

type Backend

type Backend interface {
	Get(service, account string) (string, error)
	Set(service, account, secret string) error
	Delete(service, account string) error
}

Backend is the keyring contract. Tests substitute an in-memory one.

func OSKeyring

func OSKeyring() Backend

OSKeyring returns the production keyring backend.

type Source

type Source string

Source identifies where a token came from.

const (
	SourceEnv     Source = "env"
	SourceKeyring Source = "keyring"
	SourceFile    Source = "file"
)

Source values.

type Store

type Store struct {
	Profile  string
	Keyring  Backend
	FilePath string
	Env      func(string) string
	// Warn receives human-readable warnings; the plaintext fallback is
	// announced through it on every use rather than once at login.
	Warn func(string)
	// ExpectKeyring says the profile records that a token was saved to
	// the keyring. It changes only the error: with it, a keyring that
	// answers "nothing" is reported as a keyring that will not answer
	// rather than as a token that was never there.
	ExpectKeyring bool
	// contains filtered or unexported fields
}

Store resolves and saves the token for one profile.

func (*Store) Delete

func (s *Store) Delete() error

Delete removes the token from every store and reports every failure. Missing entries are fine. The environment is not a store.

func (*Store) EnvToken added in v4.1.3

func (s *Store) EnvToken() string

EnvToken is the refresh token the environment gives, read through config.Lookup as every setting is, so spaces alone are none.

func (*Store) Resolve

func (s *Store) Resolve() (*oauth2.Token, Source, error)

Resolve returns the token and where it came from.

The environment wins, except over a stored pair rotated from the very value it holds: that pair is the environment token's live successor. A token from the environment carries only the refresh token, so the first call refreshes it.

func (*Store) ResolveStored

func (s *Store) ResolveStored() (*oauth2.Token, Source, error)

ResolveStored returns the token from the keyring or the file, ignoring the environment override: it is the token logout can revoke and delete.

func (*Store) Save

func (s *Store) Save(tok *oauth2.Token) (Source, error)

Save stores the token in the keyring, or in the file when the keyring fails, and reports where it landed. A successful keyring save removes a stale plaintext copy, so there is one source of truth.

While the environment override is set, the saved pair is stamped as its successor (see Resolve); a pair saved without it is not.

Jump to

Keyboard shortcuts

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