- Docs
- Security
- Secrets
Secrets
Read named credentials from the environment or Vault, separate from layered config.
secrets returns one named credential on demand, without it sitting in a YAML file or a log line. Use it for API keys, webhook signing secrets, and provider tokens, separate from layered config.
Quick start
Section titled “Quick start”SECRETS_ADAPTER=envSECRETS_PREFIX=ZEVERSECRETS_PREFIX=ZEVERZEVER_STRIPE_KEY=sk_live_...ZEVER_WEBHOOK_SECRET=whsec_...prefix is required (default ZEVER) and must have no /, .., or spaces; DEMO_KEY then reads ZEVER_DEMO_KEY exactly (reference).
Read a secret
Section titled “Read a secret”package main
import ( "context" "fmt" "os"
"github.com/zenta-dev/zever/config" "github.com/zenta-dev/zever/container")
func main() { os.Setenv("ZEVER_DEMO_KEY", "s3cr3t") c := container.New(config.Default()) ctx := context.Background() defer c.Close(ctx)
s, err := c.Secrets() if err != nil { fmt.Println("resolve error:", err) return } val, _ := s.Get(ctx, "DEMO_KEY") fmt.Println("bytes:", len(val)) names, _ := s.List(ctx) fmt.Println("count:", len(names))}bytes: 6count: 1Assert on value length, never the value. Secrets() resolves lazily; its Close(ctx) takes a context, unlike most services.
Use Vault for rotation and payments
Section titled “Use Vault for rotation and payments”env is read-only, so Set/Delete return secrets.ErrNotSupported and rotation means restarting with new env values. For payment credentials use vault (KV v2): Get, Set, Delete, List over HTTP, 5s timeout, values never in errors.
SECRETS_ADAPTER=vaultSECRETS_ADDR=https://vault.internal:8200SECRETS_MOUNT=secretSECRETS_TOKEN_FILE=/run/secrets/vault-tokenaddr (scheme + host, https only unless allow_insecure: true for test setups), mount (no spaces, .., empty or dot segments; each /-separated segment is URL-escaped, so nested mounts like team/secret work and reserved characters cannot shift path segments), and one of token/token_file are required; namespace is optional. token_file must be readable by its owner only (0600 or stricter) unless allow_insecure_token_file_perms: true explicitly permits broader access. Register with vault.Register() (adapters/secrets/vault). Adapters: secrets/env (default, read-only) and secrets/vault; names must match [A-Za-z0-9._-]+ (ValidateName).
Production checklist
Section titled “Production checklist”- Prefer
secretsover config env for anything that signs money or auth:paymentwebhook_secret, theauthJWT secret, provider keys. - Values never appear in errors, only service and field names (
cfg.RedactedServices()).
Troubleshooting
Section titled “Troubleshooting”Secrets() fails at startup with a prefix error
prefix is empty or contains /, .., or a space. Set SECRETS_PREFIX to a plain namespace such as ZEVER.
Get reports “not found” for an exported variable
The lookup is <PREFIX>_<NAME> exactly, case included; with ZEVER, name DEMO_KEY needs ZEVER_DEMO_KEY.
Set always fails
That is the env contract: read-only by design. Store the value in the environment or process manager, or switch to vault.