Skip to main content
Version: Next · development

Account activity

Provider and source authority

This portable contract describes its linked source snapshot. For current deployment instructions, use current installation, authentication and native Cloudflare guides. Historical receipts do not verify later builds.

Account activity records selected successful session changes and personal Codex connection changes. It works with local password, personal-token and configured browser OAuth sessions, requires only read:user, and is shared by both infrastructure tracks. It is not a record of every action in Forgejo or a complete security audit.

Browse your history​

  1. Open Your account → User settings → Account activity, or visit /audit on your Golf installation.
  2. Search the loaded rows or sort a column in the shared compact table. These controls do not search or sort unloaded history. Expand Event details to inspect the exact event and operation IDs, actor/target session handles, credential kind, revoked count and sign-in expiry when applicable. These handles cannot authenticate a request; no token, cookie, IP or invented device name is exposed.
  3. Use Load more activity to continue the captured history. New events stay outside that snapshot.
  4. Use Refresh activity to capture a new boundary and see later events.

The view is private to the current immutable account. Another account's history is not available to organization or provider administrators through this API. Provider identity, session revocation and expiry are checked; errors remain visible rather than becoming a successful empty history. The browser removes private data on sign-out or revocation and does not persist activity in localStorage.

What gets recorded​

Recorded actionMeaning
SIGN_INA new Golf session was committed; its absolute expiry is included.
SIGN_OUTA retained Golf session was explicitly logged out.
SESSION_REVOKEDA caller revoked one accessible active Golf session.
OTHER_SESSIONS_REVOKEDA caller revoked all other active sessions; the exact count may be zero.
SESSION_REPLACEDA successful sign-in replaced an existing Golf session cookie.
CODEX_LOGIN_STARTEDAn explicit personal Codex login began; no temporary code or credential is recorded.
CODEX_LOGIN_COMPLETEDNative account login/cache completion was recorded; this is not model verification.
CODEX_LOGIN_CANCELEDThe observed pending personal login was cancelled.
CODEX_CONNECTION_REFRESHEDA requested native account-state refresh was recorded.
CODEX_CONNECTION_DISCONNECTEDThe Golf-owned personal connection/cache was disconnected; provider revocation remains separate.

The generated enum names have the AUDIT_ACTION_ prefix. For individual/bulk revocation, the credential kind belongs to the caller, not necessarily the removed session. The bulk event has no individual target. Same-account replacement and sign-in share an operation ID; a cross-account switch records separate operation IDs and only each account's own session handles. An operation ID correlates records; it is not a retry token.

Automatic expiry cleanup, OAuth refresh, credential removal after invalid grants or identity rejection, failed attempts and provider repository changes are not recorded. Logging out with no valid retained cookie succeeds without creating an event. A retained expired session can still produce an explicit sign-out event.

History starts when recording is enabled. Existing PAT/OAuth sessions survive the additive migration, but their old sign-ins are not fabricated. Events retain their non-credential session references after session removal. An empty history does not prove an account never acted.

Read the same snapshot from the CLI​

Supply a token through the CLI's existing secret input, then run:

./bin/golf audit list --limit 20
./bin/golf audit list --limit 20 --before-id BEFORE_ID --snapshot-id SNAPSHOT_ID

Replace the placeholders with the first response's exact data.nextBeforeId and data.snapshotId strings. Retain that snapshot for every subsequent page; an empty next cursor ends traversal. Each command creates and logs out its own temporary PAT session, which itself adds events. Starting a fresh snapshot on each command would keep including later CLI activity. No saved CLI credentials or managed CLI OAuth is added.

The API reference specifies cursor validation, fields and bounds. Activity uses keyset cursors, not the page.nextPage contract used by repository collections.

Storage and upgrade boundary​

Each covered mutation and event commits in one Golf PostgreSQL transaction; a failed audit insert rolls back that mutation. Account locks keep captured history stable while other sessions sign in, sign out or switch accounts. This does not make upstream OAuth rotation or provider writes atomic with Golf's database.

SQL guards reject ordinary updates, deletes and truncation of history. A database owner can alter those guards or replace data: this is application-level append-only storage, not cryptographic tamper evidence, WORM retention or compliance assurance. Referenced Golf identities and immutable history remain after the live harness removes its provider users and sessions. There is no retention scheduler or deletion/export API yet; coordinate backup and account-lifecycle planning accordingly.

Audit-aware writers must replace all old Golf binaries before an audited operating window is claimed. Old compatible binaries can still change sessions without inserting events. The qualified live upgrade replaced one Golf service; it does not prove gapless audit during a mixed-version rolling deployment. Running the audit migration's down path deletes its history; retaining the schema while rolling back a binary can still resume unaudited writes.

Broader successful/failed-event coverage, organization audit, retention/export, transactional outbox, jobs and full recovery remain open. See the product's exact account audit contract and implementation evidence.