How secrets work
orun supports two ways to use encrypted secrets:- Whole-file: Create a
secrets.yamlfile in the root of your manifest repository, encrypt the entire file with SOPS, and commit the encrypted result. orun decrypts the file at apply time and makes the key-value pairs available as environment variables to your deployments. - Inline: Place individual
ENC[AES256_GCM,...]values directly in a Deployment’sspec.envmap. orun detects these patterns and decrypts them in place before starting the container.
- If
secrets.yamlexists in the repository root, orun decrypts it first to cache the SOPS data key. - orun walks every Deployment’s
envmap and decrypts any inlineENC[...]values using the cached data key.
Key file location
orun resolves the age private key from the following sources, in priority order:- The path passed via the
--age-key-pathflag toorun start. - The
SOPS_AGE_KEY_FILEenvironment variable on the node. - The default path:
/opt/orun/keys/age.key.
/opt/orun/keys/age.key on each node, or set SOPS_AGE_KEY_FILE to a custom path.
Setup steps
Generate an age key pair
Install age and generate a key pair on a secure machine.The public key is printed to stdout. Keep the private key (
age.key) secure — you will copy it to each node.Add the public key to your SOPS config
Create or update
.sops.yaml in the root of your manifest repository with the public key from the previous step.Create and encrypt your secrets file
Create a Encrypt it with SOPS using your age public key:Rename the output to
secrets.yaml file with your plaintext secrets:secrets.yaml and delete the plaintext file before committing.Commit the encrypted file
Commit the SOPS-encrypted
secrets.yaml to your manifest repository. The file is safe to store in version control — without the age private key, the contents cannot be decrypted.Inline encrypted values
Instead of a whole-filesecrets.yaml, you can place SOPS-encrypted values directly in a Deployment’s env map. Generate an encrypted value with SOPS and paste the ENC[...] string as the field value:
ENC[...] values before passing them to the container. Plain values like LOG_FORMAT: json are passed through unchanged.
Inline decryption requires the data key to be cached first. orun loads it by decrypting
secrets.yaml in phase one. If secrets.yaml is absent and no data key is cached from a previous cycle, inline ENC[...] values cannot be decrypted.Nested secrets and key flattening
If yoursecrets.yaml uses nested YAML structures, orun flattens nested keys into dot-separated paths when injecting them as environment variables. For example:
database.password and database.host.
Reference
| Constant | Value | Description |
|---|---|---|
DefaultAgeKeyPath | /opt/orun/keys/age.key | Default path orun looks for the age private key on the node |
AgeKeyFileEnv | SOPS_AGE_KEY_FILE | Environment variable that overrides the default key path |
