Recipe: Inject Secrets Manager values into a CI workflow
When to use this
Section titled “When to use this”Use this recipe when:
- The user wants a workflow step to read secrets stored in Reoclo Secrets Manager.
- A secret project already exists and holds the keys the step needs.
- The user has, or can create, an automation key (
rca_).
Do not use this recipe to give an application its environment variables at deploy time. If Reoclo deploys the app, environment variable references are the correct mechanism — direct the user to Environment variable references instead.
Background (1 paragraph for context)
Section titled “Background (1 paragraph for context)”reoclo run resolves every Secrets Manager project an automation key is granted, injects the values into a child process as environment variables, and runs it. The values never touch the CI provider’s secret store, are never written to disk, and are never printed. The child’s exit code is passed through unchanged.
Detection
Section titled “Detection”Step 1 — Confirm the workflow has a step that needs secrets:
grep -rn "secrets\." .github/workflows/ .gitea/workflows/ 2>/dev/nullEach ${{ secrets.X }} that is not REOCLO_AUTOMATION_KEY is a candidate to move into Reoclo.
Step 2 — Confirm which Reoclo project holds the keys:
Ask the user for the secret project name. Do not guess it. Do not assume it matches the repository name.
Step 3 — Do not attempt to read the values:
You cannot verify the values, and you must not try. reoclo secrets get requires an interactive session and will fail with exit code 4 under an automation key.
The change
Section titled “The change”Step A — Have the user create an automation key and grant it access
Section titled “Step A — Have the user create an automation key and grant it access”Instruct the user to do both of these in the dashboard. You cannot do them:
- API Keys → Automation Keys tab → create a key. It begins with
rca_and is shown once. - The secret project → Access tab → add a grant for that Automation key with
read.
Tell the user to leave the key with no servers and no operations. Resolution is gated by the grant, not by the key’s operations. State this plainly if they ask why the key needs no permissions.
Without the grant in step 2, nothing works. It is the most commonly missed step.
Step B — Add the key as one CI secret
Section titled “Step B — Add the key as one CI secret”The key goes in the CI provider as REOCLO_AUTOMATION_KEY. This replaces the individual secrets, which the user should remove from the CI provider only after verification passes.
Step C — Install the CLI and wrap the command
Section titled “Step C — Install the CLI and wrap the command”Rewrite the step so the CLI is installed and the existing command is wrapped:
- name: Run migrations with injected secrets env: REOCLO_AUTOMATION_KEY: ${{ secrets.REOCLO_AUTOMATION_KEY }} run: | curl -sSL https://get.reoclo.com/cli | bash reoclo run -- ./migrate.shRules:
- Everything after
--is the command. Always include--. - Remove the
env:entries for secrets now coming from Reoclo. Leave unrelatedenv:entries alone. - Do not add
-punless the user asked to restrict which projects are injected. With no-p, every granted project is injected, and adding a secret later needs no workflow change. - Gitea’s runner is GitHub-Actions-compatible. The same YAML works there. Do not rewrite it.
Verification
Section titled “Verification”Check 1 — Confirm a key resolves without printing it:
reoclo run -- sh -c '[ -n "$DATABASE_URL" ] && echo resolved'Expected output: resolved
If nothing prints and the command fails, the grant from Step A.2 is missing.
Check 2 — Confirm the failure mode is closed, not silent:
Resolution failure means the child never runs. If the user reports the command running with empty variables, the key resolved a project that does not contain those keys — that is a project-contents problem, not a grant problem.
Check 3 — Map the exit code:
| Code | Meaning |
|---|---|
| 1 | No grant, or no readable project matched -p |
| 3 | Key invalid, expired, or revoked |
| 4 | Not an automation key, or no credential reached the runner |
Any other non-zero code is the child’s own exit code passed through.
Pitfalls
Section titled “Pitfalls”Do not confuse reoclo run (CLI, injects Secrets Manager values) with reoclo/run@v2 (Action, runs a command on a managed server). The Action’s env: input is a literal passthrough of CI secrets and never touches Secrets Manager. No Action injects secrets — the CLI must be installed.
Do not add echo "$SECRET" to prove injection worked. Values injected by reoclo run did not come from the CI provider, so the CI provider does not mask them, and printing one writes it to the log in the clear. Use the [ -n "$VAR" ] check in Check 1.
Do not add set -x to a script that receives injected values. It prints every expanded command, including secrets.
Do not use reoclo secrets get in a workflow. It requires an interactive session and exits 4 under an automation key. reoclo run is the machine path.
Do not tell the user to grant the automation key operations or server access. A grant on the project is sufficient and a powerless key is the point.
Do not delete the old CI provider secrets until Check 1 passes. Verify first, then clean up.