secrets

package
v0.0.3 Latest Latest
Warning

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

Go to latest
Published: Jul 16, 2026 License: MIT Imports: 6 Imported by: 0

Documentation

Overview

Package secrets resolves declared secret REFERENCES (which live in git: EnvVar.secret_ref / secret_key) to secret VALUES (which never live in git) for one environment.

A secret has two halves:

  • a non-sensitive REFERENCE — the env-var NAME, the k8s Secret name, and the key within it. KCL projects this into the manifest as a `secretKeyRef`. It is reproducible and version-controlled.
  • a sensitive VALUE — obtained at resolve time from a per-env PROVIDER. Never in git, never in KCL render output.

This package owns the VALUE side. KCL only emits the provider DECLARATION (type + path); all value resolution happens here in Go so secrets never enter the KCL renderer.

Two provider kinds:

  • "dotenv" (dev/local): forge reads a gitignored dotenv keyed by env-var NAME, resolves declared refs from it, and — for k8s targets — RENDERS Secret objects from it CLI-side. Local clusters only.
  • "external" (prod/staging): forge never sees values. k8s references pre-existing Secrets (External Secrets Operator / sealed); host & external runtimes obtain secrets via workload identity / ambient env. forge only validates the secretKeyRef wiring (it can't, and so does not, validate the values themselves).

The package is intentionally decoupled from internal/cli to avoid an import cycle (cli depends on secrets, not the reverse). It reuses internal/hostlaunch's dotenv reader, which only imports the stdlib — no cycle risk.

forge:exclude-contract secrets is a secret-reference→value resolution utility (per-env dotenv / external providers), not a contract-shaped service. Opt out of the require-contract rule.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func RenderDeclaredSecrets

func RenderDeclaredSecrets(declared []DeclaredSecret, dot Provider, env, namespace string) ([]map[string]any, error)

RenderDeclaredSecrets builds k8s Secret manifests from a RenderedSecrets provider's declared Secrets. Each declared key resolves to its value:

  • from="dotenv": resolve Key from the dotenv provider `dot` (the same .env.<env> machinery DotenvSecrets uses). A missing dotenv key is an error (listed per Secret/key) — the value can't be rendered.
  • from="literal": use the inline Value, but ONLY when env is dev/e2e. A literal in any other env is a hard error (the trust-safe gate).

Returns the Secret manifests (one per declared Secret) in deterministic order, or a single aggregated error listing every problem. namespace is stamped on each Secret's metadata.

func RenderK8sSecrets

func RenderK8sSecrets(p Provider, refs []SecretRef, namespace string) []map[string]any

RenderK8sSecrets builds k8s Secret manifests (as []map[string]any, ready to marshal to YAML/JSON) from the resolved values, grouping refs by SecretName; each Secret's stringData[SecretKey] = resolved(EnvName). Only Kind "dotenv" produces output; "external"/"none" return nil (prod references pre-existing Secrets). Skips refs whose value doesn't resolve (ValidateDeclaredRefs is the gate for those). Deterministic ordering (sorted Secret names + keys) for stable diffs.

func ValidateDeclaredRefs

func ValidateDeclaredRefs(p Provider, refs []SecretRef, dotenvPath string) error

ValidateDeclaredRefs returns a single fail-fast error listing every declared ref the provider cannot supply. For Kind "dotenv": each EnvName must be present in All(). For "external"/"none": returns nil (forge cannot see those values).

Types

type DeclaredSecret

type DeclaredSecret struct {
	Name string
	Keys map[string]DeclaredSecretKey
}

DeclaredSecret is one explicitly-declared k8s Secret a RenderedSecrets provider renders: a Secret NAME and a map of in-Secret key -> value SOURCE. Mirrors the cli RenderedSecretEntity (the secrets package stays decoupled from cli, so cli maps its entity -> this).

type DeclaredSecretKey

type DeclaredSecretKey struct {
	From  string
	Key   string
	Value string
}

DeclaredSecretKey is the value source for one key in a DeclaredSecret. From is "dotenv" (resolve Key from the dotenv provider) or "literal" (inline Value, gated to dev/e2e by RenderDeclaredSecrets).

type Provider

type Provider interface {
	Kind() string // "dotenv" | "external" | "none"
	// Resolve returns the value for an env var by NAME (dotenv-key
	// convention: the key in the dotenv == the EnvVar.name). ok=false
	// when this provider has no value for name.
	Resolve(name string) (value string, ok bool)
	// All returns every value the provider can supply, keyed by name.
	// dotenv: the whole file. external/none: nil.
	All() map[string]string
}

Provider resolves declared secret references to values for one env.

func NewProvider

func NewProvider(cfg *ProviderConfig) (Provider, error)

NewProvider builds a Provider. cfg==nil -> a noop provider (Kind "none", All nil, Resolve always !ok) so callers need no nil checks. dotenv: loads the file now; a MISSING dotenv file is a non-fatal empty provider with a returned error==nil but Kind "dotenv" and empty All (so validation, not load, reports missing declared keys) — BUT if the file exists and is unreadable/malformed, return the error.

type ProviderConfig

type ProviderConfig struct {
	Type string // "dotenv" | "external"
	Path string // dotenv path (already resolved to an absolute/project path by caller)
}

ProviderConfig is the cli-decoupled view of the KCL secret_provider entity. (cli maps KCLEntities.SecretProvider -> this.)

type SecretRef

type SecretRef struct {
	EnvName    string
	SecretName string
	SecretKey  string
}

SecretRef is a declared reference extracted from the entities: the env-var NAME (== dotenv key), the k8s Secret NAME, and the key within that Secret. SecretKey defaults to EnvName when empty (matches the KCL _env_source lambda).

Jump to

Keyboard shortcuts

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