Add backend resolver interface with file and env backends plus phase-3 stubs
Introduce the single Backend interface every credential source implements.
v0 ships two working backends: file (0600 KEY=VALUE env files, parsed in
pure Go, never sourced; looser permission masks refused before read) and
env (process-environment indirection). Bitwarden Secrets Manager and
HashiCorp Vault ship as explicit not-implemented stubs behind the same
interface so the phase-3 connectors are drop-ins. All failures are typed
ResolveErrors carrying only the ref, backend, and a fixed reason enum —
never material.
💘 Generated with Crush
Assisted-by: Crush:glm-5.2
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
package backend
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
)
|
||||
|
||||
// Env resolves refs through process-environment indirection: ref.Source
|
||||
// is the variable name. This is the crush exposure-minimization pattern —
|
||||
// configs carry env var NAMES, never literals. The value is read on
|
||||
// demand and kept in memory only.
|
||||
type Env struct{}
|
||||
|
||||
// NewEnv returns the env backend.
|
||||
func NewEnv() *Env { return &Env{} }
|
||||
|
||||
// Name implements Backend.
|
||||
func (e *Env) Name() string { return "env" }
|
||||
|
||||
// Resolve implements Backend.
|
||||
func (e *Env) Resolve(ctx context.Context, ref Ref) (string, error) {
|
||||
v, ok := os.LookupEnv(ref.Source)
|
||||
if !ok {
|
||||
return "", Err(ref, e.Name(), ReasonMissingKey)
|
||||
}
|
||||
if v == "" {
|
||||
return "", Err(ref, e.Name(), ReasonEmptyValue)
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
Reference in New Issue
Block a user