sensitive

package
v0.51.0 Latest Latest
Warning

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

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

Documentation

Overview

Package sensitive routes ResourceOutput fields flagged as Sensitive through a secrets.Provider, returning sanitized placeholders for state persistence and a hydrated map for in-process consumers.

Per the engine-sensitive-output-routing design (workflow v0.27.0):

  • Route is invoked on Create/Update only. Read/Adoption/Refresh paths use Sanitize-only logic (not in this package — see cmd/wfctl/infra_apply.go) to prevent cache pollution.
  • The placeholder format "secret_ref://<SecretKey(resource,key)>" is distinct from the user-supplied "secret://<key>" config-reference convention.
  • Routing trigger is exclusively out.Sensitive[k]==true (per-call dynamic). ResourceDriver.SensitiveKeys() is NOT consulted here; it remains a display-masking signal.

Limitation (v0.27.0): only string-typed sensitive output values are supported. Non-string sensitive outputs (e.g., []byte, int) yield an error from Route. Future expansion via a MarshalSensitive interface is out of scope.

Index

Constants

View Source
const (
	// PlaceholderPrefix is the URI scheme used in state.Outputs values to
	// reference a routed secret stored in the configured secrets.Provider.
	// Distinct from secrets.SecretPrefix ("secret://") which is for
	// user-supplied config references.
	PlaceholderPrefix = "secret_ref://"
)

Variables

This section is empty.

Functions

func IsPlaceholder

func IsPlaceholder(v any) bool

IsPlaceholder reports whether v is a string with the PlaceholderPrefix. Non-string values return false.

func MaskSensitiveForDiff

func MaskSensitiveForDiff(driverKeys []string, desired, current map[string]any) (map[string]any, map[string]any)

MaskSensitiveForDiff returns copies of desired and current with sensitive keys elided from BOTH sides. A key is considered sensitive when:

  • it is named in driverKeys (i.e., ResourceDriver.SensitiveKeys()), OR
  • its value in current matches the PlaceholderPrefix.

Eliding from both sides ensures driver.Diff or other field-by-field comparators don't report drift when state has a placeholder and live has a different (or absent) value. Non-sensitive keys are passed through unchanged.

Either input may be nil; the corresponding output is also nil.

func Placeholder

func Placeholder(resourceName, outputKey string) string

Placeholder returns PlaceholderPrefix + SecretKey(resourceName, outputKey), replacing a routed value in state.Outputs.

func Revoke

func Revoke(
	ctx context.Context,
	provider secrets.Provider,
	resourceName string,
	mergedKeys []string,
) error

Revoke deletes routed secrets for resourceName. mergedKeys is the union of placeholder-derived keys (caller extracts from pre-delete state.Outputs) and any legacy heuristic keys. Errors from provider.Delete are aggregated via errors.Join — Revoke does NOT stop on the first error so partial cleanup proceeds. Keys that were never stored (provider returns secrets.ErrNotFound) are silently treated as success.

func Route

func Route(
	ctx context.Context,
	provider secrets.Provider,
	resourceName string,
	out *interfaces.ResourceOutput,
) (sanitized map[string]any, hydrated map[string]string, err error)

Route routes sensitive fields from out through provider, keying each secret via SecretKey(resourceName, outputKey). Returns:

  • sanitized: a copy of out.Outputs with sensitive values replaced by PlaceholderPrefix + SecretKey(resourceName, k). Suitable for persistence to interfaces.IaCStateStore.
  • hydrated: a flat map keyed by SecretKey of values that were routed. Suitable for in-process hand-off to post-apply consumers in the same wfctl invocation. Empty when no fields were routed.

Routing trigger is out.Sensitive[k] == true with out.Outputs[k] present (any value, including empty string). When the sensitive key's value is absent from out.Outputs the key is silently SKIPPED — neither provider.Set is called nor a placeholder inserted (the engine has no value to route; existing routed-secret in provider stays as-is).

Errors:

  • resourceName == "" with non-empty Sensitive map → error (defensive; out.Name is intentionally NOT consulted, since Read/Adoption paths may have empty out.Name).
  • provider == nil with non-empty Sensitive map AND any sensitive key present in out.Outputs → error naming the resource and keys.
  • provider.Set returns an error → error wrapping the failed key. Set is invoked in sorted order by key for determinism; on first error the loop stops and previously-Set values are NOT cleaned up (idempotent overwrite on Apply rerun is the recovery path).

Out is not mutated.

func SecretKey

func SecretKey(resourceName, outputKey string) string

SecretKey returns the canonical secrets.Provider key for a resource's output. The key is provider-safe and collision-resistant for distinct (resourceName, outputKey) pairs. Exported so audit-state-secrets and other consumers can recompute routed-secret names from known resource/output pairs.

Types

This section is empty.

Jump to

Keyboard shortcuts

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