envspec

package module
v0.0.0-...-dddc2fe Latest Latest
Warning

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

Go to latest
Published: May 4, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Package envspec parses @env-spec decorated .env files and resolves secret references from pluggable backends. It is Varlock-compatible: any .env file that uses the @env-spec decorator syntax can be parsed and resolved.

The core flow is: Parse → Resolve → use the resulting Env (inject into a child process, merge into os.Environ, or read individual values).

schema, _ := envspec.ParseFile(".envspec")
env, _    := envspec.Resolve(ctx, schema, resolver1, resolver2)
cmd       := envspec.Exec(env, "cog", "serve")

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Exec

func Exec(env *Env, name string, args ...string) *exec.Cmd

Exec creates an exec.Cmd with the resolved env merged into os.Environ().

Types

type BitwardenCLIResolver

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

func NewBitwardenCLIResolver

func NewBitwardenCLIResolver() *BitwardenCLIResolver

func (*BitwardenCLIResolver) CanResolve

func (r *BitwardenCLIResolver) CanResolve(ref SecretRef) bool

func (*BitwardenCLIResolver) Name

func (r *BitwardenCLIResolver) Name() string

func (*BitwardenCLIResolver) Resolve

func (r *BitwardenCLIResolver) Resolve(ctx context.Context, ref SecretRef) (string, error)

type BitwardenResolver

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

BitwardenResolver resolves secrets from a Bitwarden Secrets Manager API. This targets Vaultwarden's /api/secrets/{id} endpoint.

func NewBitwardenResolver

func NewBitwardenResolver(baseURL, token string) *BitwardenResolver

NewBitwardenResolver creates a resolver that talks to a Bitwarden/Vaultwarden Secrets Manager API. The baseURL should include the scheme and host (e.g. "http://localhost:8222"). The token is a machine account access token.

func (*BitwardenResolver) CanResolve

func (r *BitwardenResolver) CanResolve(ref SecretRef) bool

func (*BitwardenResolver) Name

func (r *BitwardenResolver) Name() string

func (*BitwardenResolver) Resolve

func (r *BitwardenResolver) Resolve(ctx context.Context, ref SecretRef) (string, error)

type ChainResolver

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

ChainResolver tries multiple resolvers in order.

func Chain

func Chain(resolvers ...Resolver) *ChainResolver

Chain creates a ChainResolver that tries resolvers in order.

func (*ChainResolver) CanResolve

func (c *ChainResolver) CanResolve(ref SecretRef) bool

func (*ChainResolver) Name

func (c *ChainResolver) Name() string

func (*ChainResolver) Resolve

func (c *ChainResolver) Resolve(ctx context.Context, ref SecretRef) (string, error)

type Entry

type Entry struct {
	Key     string    // variable name (e.g. "ANTHROPIC_API_KEY")
	Default string    // default value after the '=' (may be empty)
	Ref     SecretRef // parsed @env-spec decorator
	Line    int       // source line number
}

Entry is a single variable declaration in an envspec file.

type Env

type Env struct {
	Vars map[string]string
}

Env holds resolved environment variable key-value pairs.

func Resolve

func Resolve(ctx context.Context, schema *Schema, resolvers ...Resolver) (*Env, error)

Resolve resolves all entries in a schema using the provided resolvers. Resolvers are tried in order; the first that can resolve a ref wins. If no resolver can handle a ref and the entry has a non-empty default, the default is used. Otherwise an error is returned.

func (*Env) Get

func (e *Env) Get(key string) string

Get returns a single variable's value.

func (*Env) Merge

func (e *Env) Merge(other *Env)

Merge adds all vars from other into e, overwriting on conflict.

func (*Env) MergeOS

func (e *Env) MergeOS() []string

MergeOS returns os.Environ() with the envspec vars overlaid.

func (*Env) Pairs

func (e *Env) Pairs() []string

Pairs returns the env as a []string suitable for exec.Cmd.Env.

type EnvResolver

type EnvResolver struct{}

func NewEnvResolver

func NewEnvResolver() *EnvResolver

func (*EnvResolver) CanResolve

func (r *EnvResolver) CanResolve(ref SecretRef) bool

func (*EnvResolver) Name

func (r *EnvResolver) Name() string

func (*EnvResolver) Resolve

func (r *EnvResolver) Resolve(_ context.Context, ref SecretRef) (string, error)

type FileResolver

type FileResolver struct{}

func NewFileResolver

func NewFileResolver() *FileResolver

func (*FileResolver) CanResolve

func (r *FileResolver) CanResolve(ref SecretRef) bool

func (*FileResolver) Name

func (r *FileResolver) Name() string

func (*FileResolver) Resolve

func (r *FileResolver) Resolve(_ context.Context, ref SecretRef) (string, error)

type KeychainResolver

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

KeychainResolver resolves secrets from the OS keychain. It also serves as a write-through cache: when other resolvers succeed, their results can be stored here for offline fallback.

On macOS: uses `security find-generic-password` / `security add-generic-password` On Linux: uses `secret-tool` (libsecret / gnome-keyring) On Windows: uses `cmdkey` (Windows Credential Manager)

func NewKeychainResolver

func NewKeychainResolver(service string) *KeychainResolver

func (*KeychainResolver) CanResolve

func (r *KeychainResolver) CanResolve(ref SecretRef) bool

func (*KeychainResolver) Name

func (r *KeychainResolver) Name() string

func (*KeychainResolver) Resolve

func (r *KeychainResolver) Resolve(ctx context.Context, ref SecretRef) (string, error)

func (*KeychainResolver) Store

func (r *KeychainResolver) Store(ctx context.Context, ref SecretRef, value string) error

Store saves a resolved value to the OS keychain for later fallback.

type LiteralResolver

type LiteralResolver struct{}

func NewLiteralResolver

func NewLiteralResolver() *LiteralResolver

func (*LiteralResolver) CanResolve

func (r *LiteralResolver) CanResolve(ref SecretRef) bool

func (*LiteralResolver) Name

func (r *LiteralResolver) Name() string

func (*LiteralResolver) Resolve

func (r *LiteralResolver) Resolve(_ context.Context, _ SecretRef) (string, error)

type Resolver

type Resolver interface {
	Name() string
	CanResolve(ref SecretRef) bool
	Resolve(ctx context.Context, ref SecretRef) (string, error)
}

Resolver resolves a secret reference to its plaintext value.

type Schema

type Schema struct {
	Entries []Entry
	Path    string // source file path
}

Schema is the parsed representation of an envspec file.

func ParseFile

func ParseFile(path string) (*Schema, error)

ParseFile reads an @env-spec decorated file and returns a Schema.

type SecretRef

type SecretRef struct {
	Provider string            // e.g. "bitwarden", "literal", "env", "file", "vault-file", "keychain"
	Params   map[string]string // provider-specific params (id, name, path, etc.)
}

SecretRef describes where a single env var's value should come from.

type VaultFileResolver

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

VaultFileResolver resolves secrets from a locally decrypted Bitwarden vault export. The vault file is a JSON export that has been decrypted with the master password. Entries are looked up by UUID.

For the full multi-node flow: the encrypted vault.enc is synced via BlockSync. At node startup, the kernel decrypts it once using the master key from the OS keychain, and passes the resulting JSON to this resolver.

func NewVaultFileResolver

func NewVaultFileResolver(jsonData []byte) (*VaultFileResolver, error)

NewVaultFileResolver creates a resolver from a decrypted Bitwarden JSON export. The jsonData should be the decrypted vault contents (not the encrypted file).

func (*VaultFileResolver) CanResolve

func (r *VaultFileResolver) CanResolve(ref SecretRef) bool

func (*VaultFileResolver) Name

func (r *VaultFileResolver) Name() string

func (*VaultFileResolver) Resolve

func (r *VaultFileResolver) Resolve(_ context.Context, ref SecretRef) (string, error)

Jump to

Keyboard shortcuts

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