Opafra runs commands on production servers. This page is the answer to "what stops that going wrong", written for someone evaluating whether to allow it.
Six controls, each independent, each covered in depth elsewhere.
1. Nothing is installed#
Opafra connects over ordinary SSH as a user you nominate, using a credential you install. There is no agent, no daemon, and no package on the host.
The security consequence is the one worth stating: adopting Opafra grants it exactly
the access of one SSH user, and removing it is deleting one line from
authorized_keys. There is no residue, no privileged process, and no inbound path from
your hosts to Opafra. Every connection is outbound from Opafra to the host, when a run
needs it.
See what agentless means.
2. Preview before change#
A dry run executes a plan with every write suppressed. It connects to each host, resolves every variable, and reports what would happen there.
Fifteen tools support a real read-only check and report would create, would change or
no change per host. Everything else, including raw commands, is shown as the exact
resolved text that would run rather than guessed at.
The honest limit is stated on that page: a preview is not a guarantee, and a raw command cannot be predicted. What it reliably does is surface the difference between hosts before the change rather than during it.
3. Approval on protected environments#
An environment can require approval, and then every run whose targets land in it pauses before its first step and waits for a person.
Two properties make this stronger than a per-plan gate:
- It belongs to the environment. A plan written later by someone who never read the policy is gated anyway.
- Environments are derived from resolved targets. Naming a production host directly is exactly as gated as targeting the environment, so there is no phrasing of a plan that opts out.
The gate opens once, before anything runs, rather than on every step. A gate on every step trains approvers to click through, which produces an audit trail and no scrutiny.
Approval records who decided, when, and which plan revision they approved compared to the revision at decision time, so an edit landing between request and approval is visible rather than silently honoured.
See approval gates.
4. Roles and tenant isolation#
Four hierarchical roles. The meaningful boundary is Operator to Admin: an Operator changes production, an Admin changes who may change production. Approving a gated run requires Operator or above, so a decision is made by someone who could have made the change themselves.
Tenancy is enforced at the query rather than the screen. Every read is scoped to the caller's tenant, every change by id checks ownership, and defaults fail closed.
An object you may not see reports as missing, not forbidden. "Forbidden" confirms an object exists, which turns an id into something worth guessing at.
5. Secrets are references#
A plan carries secret://provider/namespace/key, never a value. The reference resolves at
the moment of use and the credential goes to the host without ever entering the plan, the
run log, or a preview.
This is what lets a plan be reviewed by people who should not see the credential, kept in git, and shown to an approver in full. Redaction over-matches on purpose, covering references, arguments whose names look like credentials, and rendered config contents in a diff.
A generated SSH private key is shown once, at creation, and no endpoint returns it again.
See secret references.
6. An append-only record#
Runs, approvals with their revisions, inventory and credential changes, secret reads, grants, membership changes and web SSH sessions are all recorded. Nothing updates or deletes an entry.
Actor emails are snapshotted at the time of the action, so deleting a user does not blank their history.
See audit log.
What Opafra does not claim#
Worth being direct, because a security review is where overstatement gets found:
- It cannot predict a raw command.
ssh.cmdruns arbitrary text with the connecting user's privilege. Preview shows the text; judgement is yours. - It does not stop a run's author approving it. If your policy needs four eyes, that is policy you enforce, not a rule the product applies.
- A revision change is reported, not blocked. The approver is told the plan moved under them and decides.
- The audit write is fire-and-forget. A failed log write does not fail the operation, because refusing to run over a bookkeeping error would turn it into an outage.
- It cannot act on an unreachable host. There is nothing on the host to queue work, which is the trade-off agentless makes.
How the controls combine#
Each control is independent, and none of them is the whole answer. A dry run does not stop a determined mistake; an approval gate does not know what a command does; the audit log prevents nothing at all and answers everything afterwards.
Together they mean a change to production is previewed, authorised by a named person against a known plan revision, executed with a scoped credential that never appears in the plan, and recorded permanently.