Skip to content
    Security and trust

    Guardrails before autonomy.

    Opafra runs commands on your production servers. This page sets out how it reaches them, what it keeps, and who can act on them.

    Last updated: 24 September 2026

    Security questions and questionnaires go to [email protected]. To report a vulnerability, read how to report it first.

    How Opafra reaches your servers

    Opafra is agentless. It opens SSH connections from its own servers to your hosts, as the SSH user you set for each host, to run plans, run dry-run checks, test connections and open the browser terminal. It also connects on a timer to check that each host answers and to read basic host facts. Nothing is installed on the host, and nothing of Opafra’s keeps running there after a run.

    Each organization has its own SSH certificate authority. On a host set up for certificates, every run and every browser terminal session connects with a fresh key and a certificate that lasts five minutes. The certificate carries one principal for your organization, never a login user, and the host maps that principal to the users you choose, so a certificate signed for another organization does not open it. Its key id names the organization and the server, so the host’s own auth log says who connected. A host can also use a key you give Opafra instead.

    Opafra records each host’s SSH key the first time it connects and checks it on every connection after that, including each bastion on the way. A host that presents a different key is refused, the refusal is recorded, and only an Admin or the Owner can accept the new key.

    A plan can do on a host whatever that SSH user can do. Opafra does not filter commands. Connect as a user scoped to the work rather than as root, and the host’s own permissions stay the outer limit.

    What Opafra stores, and what it does not

    • Stored: your inventory (host names, addresses, ports and SSH users), plans and every revision of them, scripts and config templates, run records and run output with secrets masked, host facts, and the audit log.
    • Stored sealed: the credentials you give Opafra itself, under your organization’s own key (next section).
    • Not stored: the values held in your external secret manager. A plan carries a reference such as secret://prod/db-password. Opafra fetches the value when the step that needs it runs, and records each fetch with the reference. The run record keeps the reference, and the run log has the value masked.

    Credentials and encryption

    Credentials Opafra holds are sealed per organization. A 256-bit root key, supplied to the service from its environment and never written to the database, wraps one random 256-bit data key per organization. Each value is sealed with AES-256-GCM under its organization’s data key, and the ciphertext is bound to that organization, so a value copied onto another organization’s record does not open. Without the root key the store refuses to seal or open anything.

    Sealed this way: secrets in the built-in store, environment secret variables, server passwords and private keys, managed SSH keys, git and GitHub App credentials, discovery source credentials, webhook signing secrets, the private key of your organization’s SSH certificate authority, and the settings Opafra uses to reach your secret manager.

    • Secret managers are integrations. Connect HashiCorp Vault, Infisical, AWS Secrets Manager or GCP Secret Manager, or use the built-in encrypted store. With an external manager the value stays there until a run needs it.
    • Run output is masked before it is shown or stored. Two layers: the exact values of the secrets a run fetched or received as secret inputs, and known shapes such as private key blocks, bearer tokens, password assignments and common provider tokens. A secret shorter than four characters is refused, because it cannot be masked reliably.
    • Sign-in. Sign in with Google, Microsoft, GitHub or GitLab, or with an email and a password, which is stored as a bcrypt hash.
    • API tokens are shown once and stored as a SHA-256 hash. They can expire, and each acts in one organization only, with membership checked on every request.

    Is Opafra multi-tenant?

    Yes. Organizations share the service and its database. Every query for an organization’s data is scoped to the organization of the person or token asking, and a request for another organization’s record answers as if it did not exist. Credentials are sealed under each organization’s own data key, and each organization has its own SSH certificate authority, as above. Deleting an organization deletes every record it owns, its secrets and its data key in one transaction, and keeps the audit log.

    Who can touch production

    An environment can be protected. Then only the Owner acts on it by role alone. Everyone else, Admins included, needs a grant for that environment, and a grant can carry an expiry, so two hours of production access ends after two hours without anyone remembering to undo it.

    Who can touch

    prod

    Effective access to prod per member.
    MemberViewRunManageVia
    Ada LovelaceOwnerView allowedRun allowedManage allowedOrg role (owner)
    Bo ChenAdminView not allowedRun not allowedManage not allowedNo access
    Alex MoreauOperatorView allowed, expires in 2hRun allowed, expires in 2hManage not allowedGrant, expires in 2h
    Dana OkaforOperatorView allowedRun allowedManage not allowedGrant, permanent
    Eli NovakViewerView not allowedRun not allowedManage not allowedNo access
    Grant#a91cprod
    Alex MoreauOperator
    Run on prod for 2h, to patch nginx across prod.
    Approved by
    Dana Okafor, 14:02
    Window
    14:05 to 16:05
    Connections
    3, each on a 5 min certificate
    Ends on its own at 16:05
    • Four roles: Owner, Admin, Operator and Viewer.
    • Approval gates. An environment can require approval. A run that targets its hosts then waits for a person. An Operator, Admin or Owner can reject it. To approve a run into a protected environment, the approver must also hold access to that environment: a current grant, or being the Owner. The approval records who decided, when, and which revision of the plan. If the plan changes before the run starts, the approval is void and a new one is needed.
    • Access requests. A person asks for access to an environment with a reason, and the request cannot be approved by the person who made it. Only the Owner can grant access to themselves. An Admin who grants access directly is recorded doing so.
    • Self-approved runs are allowed, and marked. A small team often has nobody else to ask, so Opafra does not refuse it. The record and the approvals list flag every run approved by the person who started it, so a reviewer can find each one.
    • Dry runs. A dry run shows, for each host, the resolved command, script or arguments every step would run, with secrets masked. For config templates, packages, services, users, firewall rules, cron entries and nginx reloads it also reads the host and reports whether anything would change.

    The record

    Opafra writes the record as the work happens. The audit log is append-only, and the database enforces it: it refuses to change or delete an entry. Entries outlive the person who made them, whose email stays on each entry, and the organization that owned them.

    • Every run: who started it, who approved it and which revision of the plan, and what happened on each host. For a plan the composer drafted, which model drafted it and who asked. A dry run is recorded as its own run.
    • Every sign-in, successful or failed, with the IP address and browser it came from.
    • Access and credentials: grants, access requests, role changes, member removals, server and SSH key changes, host keys pinned, refused and accepted, secret manager connections, API tokens, every change to a secret Opafra stores (by name, without its value), every secret a run fetched, and every browser terminal opened to a host.
    • Every export of the log itself.

    Admins can search and filter it, export it as CSV or NDJSON, and let a SIEM poll it over the API with a token.

    The AI composer

    The composer drafts plans and cannot run anything. Its tools edit the draft and nothing else. A draft stays a draft until a person keeps it, and then goes through the same dry run, access checks and approval as any other plan. Every plan records whether the composer drafted it, with which model, and who asked.

    QuestionAnswer
    Can the AI make changes on its own?No. It drafts plans; people preview, approve and run them.
    What does the model receive?Your request, the plan being edited, host names and group names, and the names and descriptions of your scripts, config templates and modules.
    Does it receive credentials or secrets?No. Credentials, secret values, script bodies and host output are not sent to it. A plan step that uses a secret carries the reference, not the value.

    Hosting

    Hosted in the EU. Works with servers anywhere. Opafra runs on Hetzner in Germany and Finland, and reaches your hosts over SSH wherever they are, on any cloud or in any datacenter.

    On Enterprise, customer-hosted execution runs the execution layer inside your own network.

    Backups and incidents

    The database is backed up every day. If an incident affects your organization, we alert your organization by email.

    Reporting a vulnerability

    If you think you have found a security problem in Opafra, email [email protected]. Include what you found, where, how to reproduce it, and what an attacker could do with it. One email per issue.

    What happens next.

    • We acknowledge your report within 2 business days.
    • We send a first assessment, whether it is valid, how severe it is and what happens next, within 7 business days.
    • We keep you updated as the fix progresses, and tell you when it ships.

    In scope: the Opafra application and its API, and opafra.com. Out of scope: servers that belong to Opafra’s customers, which you must never test; denial of service and load testing; social engineering; scanner output without a demonstrated impact; missing headers with no exploit.

    Rules. Test only inside an organization you created. If you reach another organization’s data, stop: do not keep, repeat or share it, and report the single request that showed it. Run commands only against hosts you own, with test credentials.

    Safe harbour. If you make a good faith effort to comply with this policy during your security research, we will consider your research to be authorized, we will work with you to understand and resolve the issue quickly, and Opafra will not recommend or pursue legal action related to your research. Should legal action be initiated by a third party against you for activities that were conducted in accordance with this policy, we will make this authorization known.

    Disclosure. Please keep the issue private until a fix has shipped and we have agreed a date with you.

    Rewards. Opafra does not run a paid bug bounty.

    The same contact, in the machine-readable form, is at /.well-known/security.txt.

    Send us the questionnaire.

    Security questionnaires are answered by email. Write to [email protected].