Skip to main content

Local Secrets

Source file: examples/local_secrets.hen

What It Demonstrates

  • secret.env(...)
  • secret.file(...)
  • optional dotenv fallback for secret.env(...)
  • built-in output masking for secret-derived values
  • structural verification without reading live secrets

Key Pattern

$ ENV_VALUE = secret.env("HOME")
$ CLIENT_ID = secret.file("./secrets/demo_client_id.txt")

This avoids shell callbacks for secret loading while keeping the values in ordinary scalar slots.

If you prefer local dotenv files during development, add a preamble directive and keep the same secret.env(...) binding surface:

dotenv .env.local

$ API_TOKEN = secret.env("HEN_API_TOKEN")

Process environment values still win when both sources define the same key.

If a dotenv-backed or process-backed value is not secret, bind it through env("NAME") instead so it stays visible in ordinary output.

Run It

hen verify ./examples/local_secrets.hen
hen run ./examples/local_secrets.hen 0 --non-interactive

What To Notice

  • hen verify validates the syntax without loading the environment variable or file.
  • The file path is resolved relative to the collection working directory.
  • Secret-derived values are masked in output automatically.
  • Dotenv-backed secret.env(...) values are masked the same way, but plain dotenv entries are not treated as secret unless you bind them through secret.env(...).
  • The example uses HOME so it runs on a typical workstation without extra setup.

Related reference: Secrets and redaction