Skip to content

Forgeplane audit logging

Forgeplane audit logging records the actor, action, resource, and state transition for meaningful platform operations. Records are immutable and sensitive values are redacted before storage.

Automatic cleanup of audit_records runs when the coordinator starts and then daily. Each cleanup reloads audit_retention_days, so a change applies to the next cleanup without a restart. Supported periods are 30, 90, or 365 days; the default is 90 days. The same policy applies to every action and outcome, including security events such as authentication and authorization denials. Shortening the window makes existing history older than the new window, including security history, eligible to expire on the next cleanup. Records strictly older than the fixed UTC cutoff expire; records exactly at the cutoff remain.

Retention uses the server-controlled recorded_at value. Occurrence time does not control retention, and redelivery does not reset recording time.

Cleanup deletes receipts for activity records with their history in the same transaction. It retains receipts for all other records and does not delete active execution-recovery state. A cleanup or policy-load failure is reported by the audit readiness check until a later cleanup succeeds.

Coordinator writers store required evidence in audit_records. A record for a database mutation is committed in the same transaction as that mutation; if required evidence cannot be recorded, the mutation rolls back. Security denials remain denied when their independently committed evidence cannot be recorded, and the coordinator emits a safe recording-failure signal.

Records distinguish authenticated users, service accounts, scoped plugin background principals, named system principals, explicit processes, and anonymous authentication attempts. A receipt makes repeated delivery of the same occurrence idempotent and detects conflicting evidence. Receipts are not history. Activity receipts expire with their history because activity has no delivery owner or acknowledgement lifecycle. Non-activity receipts remain available for recovery after the corresponding history record expires. This includes every administrator_recovery.attempt outcome.

Plugin permission commands record the actual caller and captured ownership scope; internal invocation admission records the actual root/background actor separately from initiating provenance. A background actor is not an administrator or System fallback. Grant, ceiling and background-identity mutations commit their required audit and command result atomically. Historical evidence is not current execution authority; see Plugin action permissions.

Registry command receipts are separate from audit occurrence receipts. Core plugin resource changes and permitted parent deletions commit their minimal command result, revisions and required audit atomically. These results retain original authoritative attribution and an audit reference without command keys, credentials or plugin feature content. Audit-history expiration does not erase the longer-lived command result or block existing audit cleanup.

The freshly authenticated original caller can reconcile that result even after membership or owning Team/Organization deletion. It is historical evidence, not authorization for a new write, restoration or execution. An absent receipt is not rollback proof. See original-key outcomes.

The history API, admin viewer, and export service read audit_records. Access is checked against the historical scope captured with each record, not current resource ownership or the active Team selector alone. User scope records historical user ownership; it does not grant the named user access, and Team-scoped reads exclude it. Missing and inaccessible details share the same private response.

Audit history is separate from execution acknowledgement and state-recovery evidence. The owner of an operation retains the state needed to recover or redeliver it; audit retention does not replace or delete that state.

External execution attempts keep their intent, safe outcome fingerprint, immutable receipt, and pending projection state independently of audit-history cleanup. The signed outcome envelope remains in the delivery stream only until the coordinator acknowledges it. Equivalent outcome redelivery reuses the receipt. Conflicting or stale evidence is rejected rather than rewriting history or completing another attempt.

The authorized System Settings page and internal readiness expose one bounded audit check. It identifies:

  • unavailable recorder configuration or storage;
  • cleanup that has not completed or has failed;
  • unresolved external outcomes; and
  • pending or retrying terminal-outcome projection.

The signal contains safe reason codes, effective retention, timestamps, and remediation. It does not contain event evidence, resource identifiers, raw database errors, or secrets. A successful audit write clears a recording-availability failure. A successful cleanup clears a retention failure. Outcome projection recovery retries automatically without repeating the external effect.

For an unresolved outcome, do not infer that an absent or expired history record means the external effect did not happen. Inspect the retained Run and attempt state, allow a late signed outcome when available, and make cancellation or explicit requeue a separate operator decision.

Audit records are grouped by operation area:

Category Examples
Authentication auth.login.succeeded, auth.login.failed, auth.logout
Profile Password changes and API-key regeneration
Instances and runs Plan, apply, destroy, cancellation, failure, and version events
Drift Finding creation, updates, action requests, resolution, reopening, and suppression
Registry Template creation, validation, version creation, updates, and deletion
Plugin authority plugin.action_grant.created, plugin.action_grant.revoked, plugin.installation_grant.changed, background-identity changes and plugin.invocation.admitted
Approval run.approval.requested, run.approval.approved, run.approval.rejected

Service-account activity records the service-account actor identity.

Each event returned by the history API includes:

Field Purpose
recorded_at ISO 8601 server recording time
occurred_at Source occurrence time when supplied
actor Historical user, service-account, plugin-background, system, process, or anonymous provenance
action Exact action name, such as run.created
outcome succeeded, failed, denied, pending, or unresolved
resource_type / resource_id Affected resource
scope Captured platform, Team, project, user, or unknown ownership scope
correlation Available request, Run, attempt, and causation identifiers
before_evidence / after_evidence Absent, complete, or incomplete safe evidence

Complete before and after evidence makes resource changes reviewable without relying on application logs alone. Incomplete evidence remains visibly marked with its reason and measured limits; it is never presented as absent or complete.

Sensitive data is redacted from audit state before storage. Sensitive keys and credentials embedded in URL strings are redacted. Redaction applies to both before and after and cannot be disabled. Producers must still submit safe projections: redaction cannot identify a secret hidden in arbitrary prose or an error string, and raw request headers are not audit evidence.

The combined before and after evidence in audit_records is limited to 4 MB by default. Oversized evidence is represented as incomplete with the omission reason, safe size, and configured limit; no public content digest is stored. Recovery checkpoints retain the complete redacted evidence when it is required for safe redelivery.

Audit records are evidence, not a secret store. Do not use the audit log to transport credentials or large artifacts.

Execution outcome projections likewise exclude raw tool output, raw errors, secret material, and digests derived from secret material. Recovery notes should contain only identifiers, timestamps, states, and safe reason codes. See Recover an unresolved execution.

GET /api/v1/audit/actions returns the code-owned action catalog used for filter discovery: action, label, supported outcomes, required evidence side, and recording mode. It does not return observed event counts or last-seen timestamps. Those activity statistics are not part of the vocabulary contract.

The history API filters canonical records by:

  • date range;
  • actor principal or process ID;
  • resource type;
  • project; and
  • exact action string.

Filters can be combined. Queries use cursor-based pagination ordered by server recording time and record ID, so equal timestamps remain deterministic. Follow the response’s next_cursor to fetch the next page.

High-volume worker lifecycle events are included by default. Pass hide_noisy=true to exclude worker.registered, worker.status_changed, and worker.offline events when investigating higher-signal activity.

By default, history excludes unknown-scope records and the authorization.denied and authorization.failed actions, even when those actions have a Team or project scope. Platform audit readers can pass include_security_events=1 to include both sets in queries, individual details, and exports. The admin viewer offers an Include security and unscoped events checkbox for platform readers. Unknown scope does not grant Team access, and Team readers never see either set. A Team-scoped request with include_security_events=1 returns 403. Other values and repeated occurrences of this parameter return 400.

Export the current filtered history view as CSV or JSON:

Format Use case
CSV Spreadsheet analysis and compliance handoff
JSON Programmatic processing and SIEM ingestion

Exports retain the query filters and are bounded by:

Limit Value
Maximum events per export 5,000
Maximum export size 32 MB
Concurrent exports 2

A request that exceeds the measured encoded event or byte limit returns an error. A third concurrent export is rejected until a slot is free. Each export uses one database snapshot so records committed after selection starts cannot enter later pages. Authorization is checked again after serialization and before the attachment response is released; revoked access returns an error without an export attachment.

The admin audit viewer supports filters for resource type, actor, action, and date range, expandable evidence, and export of the current filtered view. Details show outcome, occurrence and recording times, process/system provenance, historical Team and project IDs, correlation IDs, and incomplete-evidence reasons with observed and configured byte sizes. Comparisons and copy controls are available only for complete evidence values.

For an infrastructure incident:

  1. identify the resource and time window;
  2. filter by project, actor, and action;
  3. compare the redacted before and after state;
  4. follow linked run, approval, drift, or service-account records; and
  5. export the filtered evidence when another system must process it.

See Run operations, Approval workflows, and Service accounts for the related operational records.