Documentation
¶
Overview ¶
Package secrets stores per-source credentials separately from config.toml.
Per ADR-008, secrets live at ~/.config/clawtool/secrets.toml (mode 0600). Keeping them out of config.toml means the latter can be safely committed to a repo / synced via dotfiles, while credentials stay machine-local.
The store is structured as: scope (= source instance name) → key/value map. Scope "global" holds env that applies to every source.
Resolve() interpolates ${VAR} references in a config-supplied env map against secrets first, then the process env, returning the env that should be set on a spawned source process.
Index ¶
- func DefaultPath() string
- func ScrubEnv(parent []string) []string
- type Store
- func (s *Store) Delete(scope, key string)
- func (s *Store) Expand(scope, v string) (string, []string)
- func (s *Store) Get(scope, key string) (string, bool)
- func (s *Store) Rename(oldScope, newScope string) bool
- func (s *Store) Resolve(scope string, template map[string]string) (resolved map[string]string, missing []string)
- func (s *Store) Save(path string) error
- func (s *Store) Set(scope, key, value string)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func DefaultPath ¶
func DefaultPath() string
DefaultPath returns ~/.config/clawtool/secrets.toml (or the XDG variant). Mirrors config.DefaultPath but with the secrets.toml filename.
func ScrubEnv ¶ added in v0.22.36
ScrubEnv returns a fresh slice safe to assign to cmd.Env. Pass os.Environ() (or any []string of "K=V" entries). The input slice is NOT mutated.
When CLAWTOOL_KEEP_SECRETS=1 is set on the parent process, the function passes the env through unchanged — explicit opt-out for the rare cases where the operator wants the pre-octopus behaviour. The opt-out is logged once on stderr when the package is first imported... actually, it's a per-call decision, so no logging here; the caller can warn if they want that visible.
Types ¶
type Store ¶
Store is the in-memory representation of secrets.toml.
func LoadOrEmpty ¶
LoadOrEmpty reads the secrets file. A missing file is not an error; we return an empty store so callers can Set+Save without first running an init step.
func (*Store) Delete ¶
Delete removes a key from a scope. Empty scopes are pruned to keep the on-disk file tidy.
func (*Store) Expand ¶ added in v0.9.0
Expand resolves every ${VAR} reference in v against the secrets scope first, then the "global" scope, then the process env, returning the expanded string plus the list of variable names that could not be resolved (in encounter order, deduplicated).
A literal without any ${...} substring is returned verbatim with no missing entries — this is the hot-path callers depend on so they don't pay the regex cost on plain values.
func (*Store) Get ¶
Get returns the value for (scope, key). It checks the requested scope first, then the "global" scope, then returns ok=false. This lets the user define shared values once in [scopes.global] and override per instance only when needed.
func (*Store) Rename ¶ added in v0.22.2
Rename moves every secret stored under `oldScope` to `newScope`. Returns true when at least one key was moved, false when oldScope was empty or absent. If newScope already has keys, oldScope's values overwrite collisions — the caller is expected to refuse the rename earlier (config-side instance collision check) so reaching the secrets layer with an existing target is a logic error in the caller, not user-survivable input. Empty oldScope / newScope are normalised to "global" the same way Set / Get do.
func (*Store) Resolve ¶
func (s *Store) Resolve(scope string, template map[string]string) (resolved map[string]string, missing []string)
Resolve takes the env map a catalog entry asks for (e.g. {GITHUB_TOKEN: "${GITHUB_TOKEN}"}) and returns the env that should be set on the spawned source. Each ${VAR} reference is filled in by:
- The store at scope+key, then store global+key
- The process env
- Empty string (with `missing` populated so callers can warn)
Plain (non-${...}) values are passed through unchanged.