Every sign-in and every consequential action writes an entry: who did it, what they did, whether it worked, which resource it touched, when, and from where. Entries are never updated and never deleted.
What an entry holds#
| Field | What it is |
|---|---|
| Actor | The user id, plus their email as it was at the time |
| Actor type | A person, an API token, Opafra itself, or nobody (a sign-in that failed) |
| Action | A dotted verb, such as execution.start or ssh_key.generate |
| Outcome | Whether it succeeded or failed |
| Resource | The type and id of the thing affected |
| Summary | A one-line human description |
| Metadata | Structured detail specific to the action |
| IP address | Where the request came from |
| Client | The browser or tool that sent the request |
| Request id | Matches the request in Opafra's own logs, for support |
| Timestamp | When it happened |
The email is stored as a snapshot rather than looked up through the user record. That is deliberate: deleting a user must not turn their history into a row of blanks. The trail still says who did it after they have left.
What gets recorded#
Every area that changes state is covered:
- Sign-ins: every sign-in with a password or a provider, successful or failed, and every password reset requested or completed
- Runs: starting, aborting, and every approval decision
- Approvals: approve, reject, and the plan revision each decision applied to
- Inventory: creating, updating and deleting servers
- Credentials: generating, importing, updating and deleting SSH keys
- Secrets: connecting and disconnecting providers, and reading a secret
- Access: environment grants and revocations, access requests and their decisions
- Membership: invitations, removals, and role changes
- Git: connections, sources, syncs, and webhook state
- Sessions: opening a web SSH session
- Organization: settings changes, switching, leaving, deletion
Approvals carry the revision#
An approval entry records both the plan revision that was requested and the revision at the moment of decision, plus whether they differed.
Without that pair, the trail can say a run was approved but cannot say what was approved. With it, a plan edited between the request and the decision is visible in the record months later, which is the question an auditor actually asks.
Append-only#
Nothing in Opafra updates or deletes an audit entry. There is no edit path, no cleanup job, and no endpoint that would let one be rewritten.
One honest limitation#
Writing an entry is deliberately allowed to fail without failing the action it describes. If the audit write errors, the error is logged and the original operation still completes.
The reasoning: an audit failure that blocked a production run would turn a bookkeeping problem into an outage, and refusing to run because a log row could not be written is worse than running with a gap. It does mean the trail is not a guaranteed-complete ledger under database failure. It is complete in normal operation, and honest about the edge.
Sign-ins#
A successful sign-in is recorded against the person, with how they signed in. A failed one has no actor, because nobody signed in: the address that was typed is kept in its own field, never as the actor, and the reason is recorded in a few coarse words such as "wrong password". The person signing in still sees one generic message whatever the reason.
A sign-in appears in every organization the person belongs to, since a session can work in any of them. A failed attempt on an address with no account is not filed under any organization, so no customer learns that someone tried it.
What it does not cover#
Signing out. A session is a token that expires, not a server-side session, so there is no sign-out event to record.
A stated retention period. Nothing is trimmed today, and a stated period ships before launch.
Reading it#
The audit log is Admin and above. Operators change production; reading the record of who changed what is a separate job, matching how the roles are split.
Entries are scoped to your tenant. An organization sees its own events, a personal workspace sees its own, and neither can see the other.
Filter by action, by resource, by actor, by outcome, or search the summaries, then narrow by date. The common questions are "what did this person do", "what happened to this server", "who failed to sign in", and "what happened between these two times".
To take it elsewhere, export it as a file or pull it into a SIEM over the API. Exporting is itself recorded.
What is never in it#
Secret values. Metadata carries identifiers, fingerprints, revision numbers and decisions, never credentials. An SSH key's audit entry names its fingerprint and type, not any part of the key.
Next steps#
- Export the audit log for a file or a SIEM feed
- Safety model for how the audit log fits with the other controls
- Organizations and roles for who can read it