Audit Trails
Append-only audit trails for credential access, secrets, environment access, and approvals — how records are protected, how to query them, and how to export SOX evidence.
sfp server records security-relevant actions in append-only audit logs: credential and secret access, environment access, and every approval decision. The logs are queryable through the CLI and API, and the approval trail has a dedicated export for compliance reporting.
What gets recorded
Audit records are kept per domain, each in its own table, unified behind a single query interface:
Integrations & credentials
Integration created / updated / deleted; credential payloads accessed (credentials.accessed) — every read of a stored secret by an operation is an event
Approvals
Requested / approved / rejected / expired / stale — the full decision trail for every gated operation
Variables & secrets
Variable created / updated / deleted / accessed / resolved, including secret resolution at deploy time
Environment access
Frontdoor URL generation, environment lock / unlock, artifact access — attributed to the user or application token that performed it
Provider identities
A user's linked Git provider identity lifecycle: linked, token refreshed, used, revoked
Every record carries the action, the affected entity, the actor (email, and whether it was a user or the system), a timestamp, and domain-specific context such as repository, environment, or release candidate.
Immutability
Append-only. The database exposes no update or delete path for audit rows. Records cannot be edited after insertion, by any role, including owners.
Service-only writes. Only the server writes audit records; clients cannot insert their own.
Independent of the entities they describe. Environment access records survive the deletion of the environment they refer to.
The approval audit trail (SOX evidence)
Approval events carry additional fields beyond the common record, since they are the records a SOX Section 404 control is evidenced by. Each approval event also captures:
the requester and the resolver (enforcing that they are distinguishable — see segregation of duties in Release Approvals),
the source of the decision (web UI / API vs. issue-comment webhook),
the client IP address, user agent, and a request ID for cross-service correlation,
the response time from request to decision,
full context: task type, repository, domain, environment, release candidate, expiry, and rejection reason where applicable.
The trail is intended for long-horizon retention (seven years is the common SOX expectation). Records are stored in the instance's database; retention and archival are controlled by the operator.
Querying audit logs
CLI
--action accepts a domain prefix (integration) or an exact action (integration.created). Results are available as a table or JSON.
API
GET /audit exposes the same unified view with action, actor, and limit query parameters.
Compliance export
For periodic compliance reporting there is a dedicated, owner-only endpoint over the approval trail:
repositoryIdentifier
Required — the project to report on
year or from/to
Reporting period (year=2025 expands to the calendar year)
status
Filter to requested, approved, rejected, expired, or stale
environment, domain, taskType
Narrow to specific targets
requestedBy, resolvedBy
Filter by actor
includeChangelog
Enrich each approval with the package changelog of what actually shipped
format=csv
Stream the full matching dataset as CSV (approvals_<repo>_<year>.csv) instead of paged JSON
The CSV export streams the complete result set rather than a single page, and the underlying pagination guarantees that rows are neither dropped nor duplicated while new audit events arrive during the export. The output contains one row per approval event, with actor, decision, timestamps, response time, and deployment context.
The release overview API can also be asked to attach approval evidence inline: GET /releases?repositoryIdentifier=...&includeApprovals=true annotates each environment's release with who requested and who approved the deployment that put it there.
Last updated
Was this helpful?