wardkey exec
Fetches secrets from the active org, injects them as environment variables, and runs your command. This is the load-bearing command — the way most teams use Wardkey in CI and at runtime.
wardkey exec [flags] -- COMMAND [ARGS...]
The -- separator is required: everything after it is the user command, exactly as written. The CLI does not interpret it.
Quick recipes
# Inject every secret in the active org.
wardkey exec -- npm run start
# Limit the injected set with a glob.
wardkey exec --secrets 'prod/**' -- ./build.sh
# Multiple globs (comma-separated or repeat the flag).
wardkey exec --secrets 'prod/db/*,prod/api/*' -- terraform apply
# Namespace the injected vars so they don't collide with host env.
wardkey exec --prefix WARDKEY_ -- node dist/server.js
# Full control over the transform via a Go text/template.
wardkey exec --env-name-template '{{.Prefix}}APP_{{.DefaultName}}' \
--prefix MY_ -- ./run.sh
# Write a dotenv file instead of running a subprocess — useful for Docker.
wardkey exec --env-file ./.env.runtime
docker run --env-file ./.env.runtime myimage:latest
# Stream dotenv to stdout for piping.
wardkey exec --env-file - | docker run --env-file /dev/stdin myimage:latest
Flags
| Flag | Meaning |
|---|---|
--secrets strings | Comma-separated glob(s) limiting which secret paths are injected. * matches one path segment, ** matches any depth. Default: every secret in the org. |
--prefix string | String prepended to every injected env var name (e.g. WARDKEY_). |
--env-name-template string | Go text/template string overriding the default name transform. Fields: .Path, .DefaultName, .Prefix. |
--env-file string | Write a dotenv file instead of running a subprocess. Pass - for stdout. |
All global flags apply.
Path → env var name transform
By default, the secret path is uppercased and every non-alphanumeric byte is replaced with _:
| Secret path | Env var name |
|---|---|
db/password | DB_PASSWORD |
prod/db/postgres | PROD_DB_POSTGRES |
with-hyphen | WITH_HYPHEN |
Use --prefix STRING to prepend a namespace, or --env-name-template TPL to take over the transform completely. The template fields:
| Field | Value |
|---|---|
.Path | The raw secret path, e.g. prod/db/password. |
.DefaultName | The default-transformed name, e.g. PROD_DB_PASSWORD. |
.Prefix | Whatever was passed via --prefix (empty string otherwise). |
Exit codes
wardkey exec propagates the subprocess's exit code transparently — wardkey exec -- ./script.sh exits with whatever script.sh exited with. Wardkey-side errors use these codes:
| Code | Meaning |
|---|---|
| 0 | Subprocess exited cleanly (or --env-file wrote successfully). |
| 1 | Wardkey-side error: not logged in, missing org, API failure, no glob match, env name collision. |
| 127 | The command in your invocation was not found on $PATH. |
| N | Subprocess exited with code N. |
Secret hygiene
- Plaintext is held in this process's memory only long enough to write to the subprocess's env. After the subprocess returns, the in-memory copy is zeroed (best-effort — the subprocess's own copy is out of scope).
- Secret values are never written to stdout or stderr by
wardkey execitself. --env-fileis the only path where values land on disk. The dotenv file is created with mode0600.- The subprocess inherits stdin / stdout / stderr — whatever it does with the env vars is on it.
CI patterns
A few common shapes:
# GitHub Actions step — inject a project-scoped slice into the build.
- name: Build
run: wardkey exec --secrets 'prod/build/*' -- npm run build
# Docker — produce a dotenv file in the workflow, mount it into the container.
- name: Render env
run: wardkey exec --env-file ./runtime.env
- name: Run
run: docker run --env-file ./runtime.env myimage:latest