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

creds

package
v0.5.0 Latest Latest
Warning

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

Go to latest
Published: Oct 16, 2026 License: Apache-2.0 Imports: 17 Imported by: 0

Documentation

Overview

Package creds resolves credentials (spec §7). M1 implements the read class.

tailkeeper never reads variables it did not define: TS_* and TAILSCALE_* are ignored even when present, because developer shells often hold full-permission user tokens in them.

Index

Constants

View Source
const (
	EnvClientID     = "TAILKEEPER_READ_CLIENT_ID"
	EnvClientSecret = "TAILKEEPER_READ_CLIENT_SECRET"
	EnvAPIKey       = "TAILKEEPER_READ_API_KEY"
	EnvOIDCToken    = "TAILKEEPER_OIDC_TOKEN"
	EnvReexec       = "TAILKEEPER_REEXEC"
)

Variable names of the read class (spec §7.3).

Variables

View Source
var ErrReexecRequired = tkerr.New(tkerr.CredentialUnavailable,
	"the exec provider must re-run tailkeeper under its wrapper", "")

ErrReexecRequired means the exec provider must re-run tailkeeper under its wrapper.

Functions

func PrivacyKey

func PrivacyKey(p config.Provider, sys System) (*privacy.Key, error)

PrivacyKey reads TAILKEEPER_PRIVACY_KEY from where provider p keeps the read credential (spec §7.6): the environment for env and exec (exec's wrapper puts it there), the credential file for file. oidc stores no secret, so it has no key. No key set is not an error: masking then names nothing.

func Reexec

func Reexec(wrapper []string, self string, args []string) error

Reexec replaces this process with: wrapper argv..., self, args... The wrapper (a secret manager's run command; see docs/recipes/) injects the read credential into the environment of the tailkeeper it starts. File descriptors survive exec, so this works for the stdio MCP server too.

Types

type Kind

type Kind string

Kind is the authentication scheme of a credential.

const (
	KindOAuth     Kind = "oauth"
	KindAPIKey    Kind = "api_key"
	KindFederated Kind = "federated"
)

type Read

type Read struct {
	Kind         Kind
	ClientID     string // OAuth client or federated identity ID: not a secret
	ClientSecret Secret // OAuth only
	APIKey       Secret // API access token only
	Audience     string // federated only
	IDToken      func(ctx context.Context) (string, error)
	Provider     string // env, file, exec or oidc
}

Read is a resolved read credential. Its String method never prints a secret, and shows only the start of the client ID.

func Resolve

func Resolve(ctx context.Context, p config.Provider, sys System) (Read, error)

Resolve turns a configured provider into a Read credential.

func (Read) String

func (r Read) String() string

type Secret

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

Secret holds a credential's bytes in a closure, not in a field: fmt prints a struct's fields itself, without calling Format, for a bad verb (%p, %w) and for an unexported field of another struct, and a function prints as an address under every verb. So no verb, on a Secret or on anything holding one, and no JSON encoder or logger, can reach the bytes. privacy.Key is built the same way.

func NewSecret

func NewSecret(s string) Secret

NewSecret wraps s.

func (Secret) Format

func (Secret) Format(f fmt.State, _ rune)

Format keeps the bytes out of every verb fmt hands a Format method; it has a value receiver so that a Secret printed by value, as a field or an element, calls it.

func (Secret) MarshalText

func (Secret) MarshalText() ([]byte, error)

MarshalText keeps the bytes out of JSON and of text-based loggers.

func (Secret) Reveal

func (s Secret) Reveal() string

Reveal returns the bytes: the one way to read them, used only to send them.

func (Secret) String

func (Secret) String() string

String is what a Secret is called as text outside fmt.

type System

type System struct {
	Getenv   func(string) string
	ReadFile func(string) ([]byte, error) // files a variable names ("file:" values) and the OIDC token file
	// ReadSecretFile checks a credential file and reads it through the file it
	// checked, so nothing can be put in the path's place between the check and the
	// read. It is config.ReadSecretFile when nil: a System built without it takes the
	// safe read, and there is no path that checks a file by name and reads it by name
	// afterwards. A test that has no real file replaces it with a fake that does both.
	ReadSecretFile func(string) ([]byte, error)
	HTTPClient     *http.Client // used only to fetch platform OIDC tokens
}

System is the environment and filesystem a provider reads. Tests replace it.

Jump to

Keyboard shortcuts

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