vauthlogin

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Oct 23, 2026 License: ISC Imports: 20 Imported by: 1

README

vauth-login

Standalone Vault authentication using an SSH agent or JWT, with encrypted token caching. Native Go binaries for Windows and Linux, plus a Node module and CLI. Extracted from vvauth: authentication only, no identity-profile, secret/environment expansion, shell installation, or child process execution.

Install

Download vauth-login-windows-amd64.exe or vauth-login-linux-amd64 from the GitHub release, check SHA256SUMS, and put it on your PATH as vauth-login.exe or vauth-login. Windows release binaries are Authenticode signed; an unavailable signing server fails the release rather than publishing an unsigned executable.

Or install the Go CLI:

go install github.com/131/vauth-login/cmd/vauth-login@latest

The Node CLI exposes the same commands:

npm install -g vauth-login

Use

vauth-login                 # stdout: token; stderr: status and remaining validity
vauth-login --renew         # force a fresh login (not merely a lease renewal)
vauth-login --source        # stdout: export VAULT_TOKEN='…'
vauth-login version         # release/build version, without authenticating

login and connect are optional aliases for the default operation. --ir://json JSON-encodes the token; otherwise it is written without a trailing newline. --source produces a bash export with a trailing newline. Status goes only to stderr, for example Vauth token: reused · 11h. No token or Vault address is included in that status.

In bash, verify the producer succeeds before sourcing its output:

if token_export=$(vauth-login --source); then
  eval "$token_export"
  unset token_export
fi

Configuration

The first existing file wins: VAUTHRC, ./.vauthrc, then ~/.vauthrc. VAULT_ADDR is the fallback when vault_addr is absent. Existing vvauth configuration files work without changes; env.* is ignored, including malformed or hostile environment-map keys. Authentication fields support $${env.NAME} substitution from the process environment, not profile or secret expansion.

vault_addr: https://vault.example.test
ssh_auth:
  path: ssh
  role: developer
# Or jwt_auth: {path: jwt, role: developer, jwt: "$${env.LOGIN_JWT}"}
token_cache: true

Recognized keys: vault_addr, ssh_auth, jwt_auth, token_cache, and ssh-agent-crypt. The last key is retained for configuration compatibility; local encrypted secret files and their environment expansion belong to vvauth, not this package.

SSH authentication uses SSH_AUTH_SOCK. Without it, the native Windows binary autodiscovers the Pageant (0.75+) named pipe, then the OpenSSH agent pipe. It does not use WM_COPYDATA or an external signing helper. Without an agent, disk caching is disabled; JWT authentication can still work. The Node implementation uses ssh2's Pageant transport when no Windows socket is configured.

Token lifecycle and cache

The inherited VAULT_TOKEN takes priority over the disk cache. When authentication is configured, an uncached inherited token is validated with lookup-self. The cache is ~/.vauth/tokens/<session-sha256>.creds, encrypted/authenticated by ssh-agent-crypt v3. The session hash and JSON payload match vvauth's Node and Go implementations: either implementation can read the other's cache. The native Windows cache is under the Windows user's home; the WSL cache is under the Linux user's home.

A usable cached token is reused locally without contacting Vault. In the last third of its lease it is renewed if renewable, otherwise replaced by a fresh login. An expired cache or a 400/403 from token lookup/renewal triggers login; network and server failures are not treated as invalid tokens. --renew ignores both inherited and cached tokens. Without authentication configuration, the library ignores inherited/cache tokens and the CLI fails rather than reporting an empty token as success.

Cache encryption chooses VAUTH_USER_IDENTITY, then VAUTH_USER_MAIL, then the ssh-agent-crypt default selector. Decryption uses the fingerprint embedded in the armor. Writes use distinct temporary files and atomic replacement; normal reuse does not rewrite the cache. Cache failures do not expose tokens or prevent a successful login. token_cache: false disables cache access entirely.

API and tests

See API_and_tests.md for Node/Go APIs, transport and test details. Both APIs expose connection, token lookup and Vault HTTP transport so consumers can share the authentication boundary without reimplementing it.

Security boundary

A configuration file chooses the Vault origin and authentication role. This package preserves vvauth's configuration precedence; it does not make a cloned repository's .vauthrc trustworthy. Review it before permitting SSH-agent signing. Whoever controls the agent socket can decrypt its caches. Tokens are bearer credentials: don't log stdout, enable shell tracing around exports, or store tokens in plaintext files.

The default HTTP transports do not follow redirects and have a 60-second deadline including the response body. HTTP errors expose status/body to programmatic callers, but their printable messages omit bodies to avoid echoing credentials. Go callers overriding HTTPClient own its redirect/timeout policy. Cache reuse intentionally does not check revocation online; use LookupSelf/lookupSelf when that validation is needed. It is a Vault client, not a replacement for Vault's server-side authorization.

Credits

  • François Leurent / 131
  • Go/Node extraction and validation with OpenAI Codex
  • Original vvauth and ssh-agent-crypt implementations and contributors
  • Code signing courtesy of Essilor International

ISC license, inherited from vvauth.

Documentation

Overview

Package vauthlogin authenticates to Vault using ssh-agent or JWT and caches the token with ssh-agent-crypt. It does not resolve environments.

Index

Constants

View Source
const PackageName = "vauth-login"

PackageName is the npm name a project uses to pin vauth: `"dependencies": {"vauth-login": "^1.0.0"}` in its package.json.

Variables

View Source
var Version string

Version is the running version (ldflags -X or debug.ReadBuildInfo), checked by New against the current directory's package.json; empty or non-semver values ("(devel)") skip the check.

Functions

func CheckProjectVersion

func CheckProjectVersion(manifest, version string) error

CheckProjectVersion fails when manifest (a package.json) declares a dependency on PackageName that version does not satisfy. A missing manifest, dependency or unparseable version is not an error.

func Environ

func Environ() map[string]string

Environ converts os.Environ() into a map.

func HumanDiff

func HumanDiff(seconds float64, max int) string

HumanDiff formats a duration in seconds with at most max units ("1d 3h"), like nyks/date/humanDiff.

func LocateRC

func LocateRC(environ map[string]string, cwd, home string) string

LocateRC returns the first existing configuration file among VAUTHRC, ./.vauthrc and ~/.vauthrc, or an empty string.

func ReplaceEnv

func ReplaceEnv(str string, dict Lookup) string

ReplaceEnv expands $$key and $${key} macros against dict (nyks string/replaceEnv semantics): unknown keys stay, expansions recurse.

func ShellEscape

func ShellEscape(value string) string

ShellEscape single-quotes a value for bash.

Types

type AgentCrypt

type AgentCrypt struct {
	Path     string `yaml:"path"`
	Identity string `yaml:"identity"`
}

AgentCrypt points to a local ssh-agent-crypt armored JSON file whose keys feed $${secrets.X}.

type HTTPError

type HTTPError struct {
	Status int
	Body   string
}

HTTPError reports an unexpected Vault status code.

func (*HTTPError) Error

func (e *HTTPError) Error() string

type JWTAuth

type JWTAuth struct {
	Path string `yaml:"path"`
	JWT  string `yaml:"jwt"`
	Role string `yaml:"role"`
}

JWTAuth configures a Vault jwt login.

type Lookup

type Lookup map[string]any

Lookup resolves dotted paths ($${env.X}) in nested string maps.

type LookupToken

type LookupToken struct {
	TTL           float64 `json:"ttl"`
	Renewable     bool    `json:"renewable"`
	CreationTTL   int64   `json:"creation_ttl"`
	EntityID      string  `json:"entity_id"`
	LeaseDuration int64   `json:"lease_duration"`
}

LookupToken is the token metadata returned by lookup-self.

type RC

type RC struct {
	VaultAddr  string      `yaml:"vault_addr"`
	SSHAuth    *SSHAuth    `yaml:"ssh_auth"`
	JWTAuth    *JWTAuth    `yaml:"jwt_auth"`
	TokenCache *bool       `yaml:"token_cache"`
	AgentCrypt *AgentCrypt `yaml:"ssh-agent-crypt"`
	// contains filtered or unexported fields
}

RC is the parsed .vauthrc, after $${env.X} expansion.

func ParseRC

func ParseRC(body []byte, file string, environ map[string]string) (*RC, error)

ParseRC parses a .vauthrc body and expands its $${env.X} macros against environ. Environment/profile configuration (env.*) is ignored.

func (*RC) AuthKey

func (rc *RC) AuthKey() string

AuthKey renders ssh_auth and jwt_auth as JSON members, in the order of the parsed document. Programmatic configurations are rendered from the structs.

type SSHAuth

type SSHAuth struct {
	Path string `yaml:"path"`
	Role string `yaml:"role"`
}

SSHAuth configures the Vault ssh auth plugin (nonce challenge).

type Vauth

type Vauth struct {
	RC         RC
	VaultAddr  string
	VaultToken string
	// Agent is the ssh-agent address; empty disables ssh authentication.
	Agent string
	// TokenCache enables the on-disk token cache in CacheDir.
	TokenCache bool
	CacheDir   string
	HomeDir    string
	// Environ is the process environment snapshot used for macros.
	Environ map[string]string
	// Stdout/Stderr/Stdin default to the process streams.
	Stdout     io.Writer
	Stderr     io.Writer
	HTTPClient *http.Client
	// Now overrides the clock (tests).
	Now func() time.Time
	// contains filtered or unexported fields
}

Vauth is a configured client. New builds one from the process environment; fields may be set directly for programmatic use.

func New

func New() (*Vauth, error)

New loads the configuration from the environment and the first .vauthrc found (VAUTHRC, ./.vauthrc, ~/.vauthrc).

func (*Vauth) Connect

func (v *Vauth) Connect(renew bool) (string, error)

Connect establishes VaultToken: the environment token, then the cached one (renewed in the last third of its lease), then a new login. With renew, a new login is forced. Without an authentication method, no token is used.

func (*Vauth) Login

func (v *Vauth) Login(source, renew bool) error

Login prints a token or an export suitable for a bash sourcing shell.

func (*Vauth) LookupSelf

func (v *Vauth) LookupSelf(token string) (*LookupToken, error)

LookupSelf validates a token online and returns metadata including entity ID.

func (*Vauth) Request

func (v *Vauth) Request(method, path, token string, payload any, expect int) (int, []byte, error)

Request performs a JSON Vault call. Set expect to zero to handle status yourself.

func (*Vauth) TokenCacheFile

func (v *Vauth) TokenCacheFile() string

TokenCacheFile is the armored cache file for this configuration.

func (*Vauth) TokenCacheKey

func (v *Vauth) TokenCacheKey() string

TokenCacheKey isolates cached tokens by Vault address and authentication configuration. It matches the Node implementation byte for byte.

func (*Vauth) VaultURL

func (v *Vauth) VaultURL(path string) string

VaultURL returns an API URL relative to this configured Vault.

Directories

Path Synopsis
cmd
vauth-login command
Command vauth is the standalone Vault credentials helper: same commands and flags as the vvauth npm package (cnyks runner).
Command vauth is the standalone Vault credentials helper: same commands and flags as the vvauth npm package (cnyks runner).

Jump to

Keyboard shortcuts

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