auth

package
v0.24.0 Latest Latest
Warning

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

Go to latest
Published: Jun 19, 2026 License: MIT Imports: 28 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func BaseMethod added in v0.23.0

func BaseMethod(method string) string

BaseMethod strips the "+tpm" sealing modifier, returning the underlying auth flow: "oidc", "ldap", "token", or "mtls". The login dispatch switches on this so a "+tpm" variant routes to the same flow as its base.

func FetchTokenFromSocket added in v0.24.0

func FetchTokenFromSocket(ctx context.Context, socketPath string) (string, error)

FetchTokenFromSocket retrieves a Vault token from a peer dotvault daemon's web API exposed over a Unix-domain socket — the programmatic equivalent of

curl --unix-socket <socketPath> http://localhost/api/v1/token

It backs dotvault-to-dotvault token sharing: a remote-forwarded socket (e.g. ~/.ssh/dotvault.sock created by an SSH RemoteForward from a machine running the dotvault web UI) lets a host with no interactive login facility borrow the live token from a peer that has one.

It is best-effort and never fatal. An empty path, an unexpandable ~, a missing socket file, a stale socket (file present but no listener), a non-200 response (the peer holds no token), or a malformed body all resolve to ("", nil) so the caller simply carries on with its normal auth flow. The returned token is deliberately NOT validated here — callers run LookupSelf before adopting it, exactly as they do for the token file and DOTVAULT_TOKEN.

func IsExpired

func IsExpired(err error) bool

IsExpired reports whether err is the token-expired sentinel. The Start loop uses this to route expired tokens through the same recovery path as a 403 response.

func ReadTokenEnv

func ReadTokenEnv() string

ReadTokenEnv reads the Vault token from the DOTVAULT_TOKEN environment variable. VAULT_TOKEN is deliberately ignored — it belongs to the `vault` CLI, and honouring it would let an unrelated shell session's token leak into the daemon (the Vault SDK's own VAULT_TOKEN pickup is likewise neutralised in internal/vault.NewClient).

An env-var token is necessarily plaintext: there is no way to TPM-seal an environment value. The "+tpm" sealing applies only to the token file.

func ReadTokenFile

func ReadTokenFile(path string) (string, error)

ReadTokenFile reads a Vault token from a file, trimming whitespace. Returns empty string (not error) if the file doesn't exist.

A file written by WriteTokenFile with sealing on carries sealedTokenPrefix; this transparently unseals it via the TPM. A plaintext file is returned verbatim, so existing token files keep working and migration is free.

func ResolveToken

func ResolveToken(tokenFilePath string) string

ResolveToken returns a Vault token, checking the DOTVAULT_TOKEN env var first, then the token file. Returns empty string if neither is set. A sealed token file that cannot be unsealed resolves to "" (the warning is logged in ReadTokenFile), which the auth flow treats as "no usable token, re-authenticate" — never a silent plaintext fallback.

func SealTokenAtRest added in v0.23.0

func SealTokenAtRest(method string) bool

SealTokenAtRest reports whether the auth method requests TPM-sealing of the token file — the "+tpm" suffix. When true, WriteTokenFile seals the token under the TPM and writes a self-describing sealed envelope, which ReadTokenFile transparently unseals on read (so the daemon, the CLI, and the public client/ facade all consume it without knowing the method).

func WriteTokenFile

func WriteTokenFile(path string, token string, seal bool) error

WriteTokenFile writes a Vault token to a file with 0600 permissions. When seal is true the token is sealed under the TPM (machine-bound) and written as a self-describing sealed envelope that ReadTokenFile transparently unseals. Sealing requires a working TPM (Linux/Windows); seal=true on a host with no hardware backend returns an error rather than silently writing plaintext — the same no-silent-fallback contract as mtls+tpm key sealing.

Types

type LifecycleManager

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

LifecycleManager manages token TTL checks and renewal.

func NewLifecycleManager

func NewLifecycleManager(client *vault.Client, checkInterval time.Duration, disableRenewal bool) *LifecycleManager

NewLifecycleManager creates a new token lifecycle manager. When disableRenewal is true the manager still monitors TTL and signals re-auth when the token expires, but never calls RenewSelf.

func (*LifecycleManager) NeedsReauth

func (lm *LifecycleManager) NeedsReauth() bool

NeedsReauth returns true if the token is expired or needs re-authentication.

func (*LifecycleManager) Reload

func (lm *LifecycleManager) Reload()

Reload signals the lifecycle goroutine to perform an immediate tryReload on the next scheduling pass — used by the SIGHUP handler and by the in-process token-file watcher (internal/tokenwatch) so a freshly-written token file (the configured tokenFilePath, by default ~/.dotvault-token) is picked up without waiting for the 5-minute lifecycle tick. Coalescing: concurrent or back-to-back calls collapse into a single reload. Safe to call before or after Start; calls made before Start are buffered and consumed by the goroutine on its first select.

func (*LifecycleManager) SetOnReauth

func (lm *LifecycleManager) SetOnReauth(fn func())

SetOnReauth registers a callback fired when the manager transitions into the needs-reauth state. The callback runs synchronously on the lifecycle goroutine — keep it short. In web mode this is used to clear the in-memory Vault token so the SPA's status check reflects "logged out".

func (*LifecycleManager) SetTokenFilePath

func (lm *LifecycleManager) SetTokenFilePath(p string)

SetTokenFilePath wires a token file path so that on detection of an invalid/expired token the manager will attempt to reload (and re-validate) the token from disk or DOTVAULT_TOKEN before declaring re-auth necessary. This lets an external facility (e.g. a tty session running `dotvault login`) recover a running daemon without a restart.

func (*LifecycleManager) SetTokenSocket added in v0.24.0

func (lm *LifecycleManager) SetTokenSocket(p string)

SetTokenSocket wires the path to a peer dotvault's web-API Unix socket so the recovery path can borrow the peer's live token (dotvault-to-dotvault sharing) before declaring re-auth necessary. Empty disables it. See FetchTokenFromSocket.

func (*LifecycleManager) Start

func (lm *LifecycleManager) Start(ctx context.Context) <-chan error

Start begins the token lifecycle goroutine. Returns a channel that receives errors (e.g., when re-auth is needed). The goroutine stops when ctx is cancelled.

type LoginStatus

type LoginStatus struct {
	State      string            `json:"state"`
	Token      string            `json:"-"`
	Error      string            `json:"error,omitempty"`
	MFAMethods []vault.MFAMethod `json:"mfa_methods,omitempty"`
}

LoginStatus represents the current state of an async login attempt.

type LoginTracker

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

LoginTracker manages async login attempts keyed by session ID.

func NewLoginTracker

func NewLoginTracker(vc *vault.Client) *LoginTracker

NewLoginTracker creates a new LoginTracker.

func (*LoginTracker) Clear

func (lt *LoginTracker) Clear(sessionID string)

Clear removes a completed login session.

func (*LoginTracker) Close

func (lt *LoginTracker) Close()

Close stops the background GC goroutine.

func (*LoginTracker) GetStatus

func (lt *LoginTracker) GetStatus(sessionID string) *LoginStatus

GetStatus returns the current login status for a session. Returns nil if the session does not exist.

func (*LoginTracker) StartLogin

func (lt *LoginTracker) StartLogin(sessionID, mount, username, password string)

StartLogin begins an async LDAP login attempt. The login runs in a background goroutine with a 5-minute timeout. Poll GetStatus to check progress.

func (*LoginTracker) SubmitTOTP

func (lt *LoginTracker) SubmitTOTP(sessionID, passcode string)

SubmitTOTP submits a TOTP passcode for an in-progress MFA login.

type MTLSParams added in v0.23.0

type MTLSParams struct {
	// Connectivity for building a cert-presenting login client.
	VaultAddress  string
	CACert        string
	TLSSkipVerify bool

	Method          string // "mtls" | "mtls+tpm"
	BootstrapMethod string
	BootstrapMount  string
	CertMount       string
	CertRole        string
	PKIMount        string
	PKIRole         string
	KeyType         string
	CommonName      string // template over {{.user}}
	TTL             string
	ReissueBefore   time.Duration
	SealToPCRs      bool
	StorageDir      string
	BYOCert         string
	BYOKey          string
}

MTLSParams carries everything the cert-auth flow needs. It is populated by the daemon (cmd/dotvault) from the validated vault.mtls config and attached to a Manager whose AuthMethod is "mtls" or "mtls+tpm".

type Manager

type Manager struct {
	VaultClient   *vault.Client
	TokenFilePath string
	// AuthMethod is the configured method: "oidc", "ldap", "token", "mtls", or
	// "mtls+tpm". A "+tpm" suffix on any base method (e.g. "oidc+tpm") also
	// requests TPM-sealing of the cached token file at rest; for "mtls+tpm"
	// that is in addition to the cert key the cert flow already seals.
	AuthMethod string
	AuthMount  string // auth mount path
	AuthRole   string // optional role
	Username   string
	// TokenSocket is an optional path to a peer dotvault's web-API Unix
	// socket. When set, Login first tries to borrow a live token from the
	// peer (dotvault-to-dotvault sharing) before running the configured
	// interactive flow. A missing or stale socket is ignored. See
	// FetchTokenFromSocket.
	TokenSocket string
	// MTLS is required when the base auth method is "mtls".
	MTLS *MTLSParams
}

Manager orchestrates Vault authentication.

func (*Manager) Authenticate

func (m *Manager) Authenticate(ctx context.Context) error

Authenticate attempts to authenticate with Vault. It first tries to reuse an existing token, then falls back to the configured method.

func (*Manager) Login

func (m *Manager) Login(ctx context.Context) error

Login runs the configured fresh-auth flow unconditionally, without attempting to reuse an existing token. Used by `dotvault login` and as the fallback path inside Authenticate.

func (*Manager) ReissueIfDue added in v0.23.0

func (m *Manager) ReissueIfDue(ctx context.Context) error

ReissueIfDue rotates the certificate when it is inside the re-issue window, using the current operational Vault token (no human). It is a no-op for non-cert methods, when no credential exists, or when the cert is not yet due for rotation. The daemon calls this periodically so a long-running process whose token keeps renewing still rotates its certificate before expiry — without this, a warm daemon never re-enters the cert flow and the cert could expire unrotated. Safe to call repeatedly: after one successful rotation the fresh NotAfter moves out of the window and subsequent calls return nil.

Jump to

Keyboard shortcuts

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