Skip to content

reoclo run

reoclo run [options] -- <command...>

Resolves every Secrets Manager value your automation key can read, injects them into a child process as environment variables, and runs it. Values are never written to disk and never printed. The child’s exit code is passed straight through, so reoclo run is transparent to whatever CI system is watching it.

This is how you consume managed secrets in any pipeline — GitHub Actions, Gitea Actions, GitLab CI, Woodpecker, or a local script.

Terminal window
REOCLO_AUTOMATION_KEY=rca_... reoclo run -- ./migrate.sh

Everything after -- is the command. Use -- even when it looks unnecessary; without it, flags meant for your command are parsed as flags for reoclo.

FlagDescription
-p, --project <name>Only inject this project. Repeatable. Omit to inject every project the key can read.
--commit <sha>Record a commit SHA on the audit entry.

reoclo run requires an automation key (rca_), read from REOCLO_AUTOMATION_KEY or REOCLO_API_KEY. A reoclo login session is rejected — an interactive session is a person, and this command exists to hand values to machines.

The key needs a read grant on each project you want injected. A tenant admin adds one from the project’s Access tab; see Granting access.

Only the grant matters. An automation key restricted to no servers and no operations still resolves secrets normally, which makes a dedicated, otherwise-powerless key the right thing to put in CI.

With no -p, every project the key is granted is injected. That is usually what you want, and it means adding a secret to a granted project requires no pipeline change.

Pass -p to narrow it — repeat the flag for more than one:

Terminal window
reoclo run -p payments-production -- ./migrate.sh
reoclo run -p payments-production -p shared-infra -- ./deploy.sh

Naming a project the key cannot read is an error, and the command fails without running your child process. A project that exists but is not granted and a project that does not exist are reported identically, so a key cannot be used to probe which projects exist.

A resolved value overrides an inherited environment variable of the same name. If your runner already exports DATABASE_URL and the granted project also defines DATABASE_URL, the child sees the managed one.

Each run opens a short-lived resolve session (15 minutes) and records two audit entries: the session being opened, and the keys that were resolved. Only key names are recorded — never values.

On GitHub Actions and Gitea Actions, GITHUB_RUN_ID and GITHUB_SHA are picked up automatically, so runs are attributable to a workflow and a commit with no extra wiring. Elsewhere, pass --commit yourself:

Terminal window
reoclo run --commit "$CI_COMMIT_SHA" -- ./release.sh

reoclo run fails closed. If resolution fails for any reason — no grant, a project you cannot read, an expired key — the child process does not run. It will never silently execute your command with the secrets missing.

Run a migration with every granted secret injected:

Terminal window
REOCLO_AUTOMATION_KEY=rca_... reoclo run -- ./migrate.sh

Log in to a registry without the password ever reaching your shell history or the process table:

Terminal window
reoclo run -p shared-infra -- sh -c 'echo "$DOCKERHUB_PASSWORD" | docker login --password-stdin -u "$DOCKERHUB_USERNAME"'

Check that a key is present without revealing it:

Terminal window
reoclo run -- sh -c '[ -n "$STRIPE_API_KEY" ] && echo present'
CodeMeaning
0Success (or the child exited 0)
1Resolution failed — no grant, or no readable project matched -p
2Bad arguments (e.g. no command after --)
3Authentication failure — the key is invalid or expired
4Not an automation key (a reoclo login session, or no credential at all)
nAny other code is the child’s own exit code, passed through

Because the child’s code is passed through, a non-zero exit is not necessarily a Reoclo error. A script that exits 1 on its own is indistinguishable from a resolution failure by code alone; read the message on stderr, which is written only by reoclo run itself.