# Audit log

Which access changes the audit log records, the fields of each entry, who can read it, and how to page through it with the GraphQL API.

The audit log records changes to access in your organization: who did what, to whom, and when. Entries can’t be changed or deleted through the API. You read the log with the `auditLogEntries` GraphQL query; the CLI has no command for it.

## What’s recorded [#whats-recorded]

The audit log records these seven actions. Each one is recorded when the change succeeds.

| Action | Recorded when | Target |
| --- | --- | --- |
| `iam.role.assign` | A role is assigned, including when an invite grants a role to an existing account | The principal |
| `iam.role.revoke` | A role is revoked | The principal |
| `iam.member.remove` | A member is removed | The principal |
| `iam.org_invite.create` | A pending invite is stored for an email address without an account | The email address |
| `iam.org_invite.revoke` | A pending invite is canceled | The invite ID |
| `iam.service_account.create` | A service account is created | The service account’s principal |
| `iam.service_account.revoke` | A service account is revoked | The service account’s principal |

The audit log doesn’t record organization or project lifecycle changes, resource changes such as launching an instance, or refused requests. Writing an entry never blocks the change itself: if an entry can’t be written, the change still takes effect, so in rare cases an action is missing from the log.

## Entry fields [#entry-fields]

Each entry has these fields.

| Field | Description |
| --- | --- |
| `id` | Unique ID of the entry. |
| `orgId` | The organization the action happened in. |
| `projectId` | The project, for a project-scoped role assignment or revocation. Otherwise `null`. |
| `actor` | The principal that performed the action. |
| `action` | The action key from the table above. |
| `target` | What the action was applied to, as listed in the table above. |
| `outcome` | `SUCCESS` for every recorded action. |
| `occurredAt` | When the action happened, as an RFC 3339 timestamp. |
| `details` | Action-specific context as a JSON string, for example the role URN that was assigned. |

## Who can read it [#who-can-read-it]

Reading the audit log requires the `iam.audit_log.list` permission on the organization. Both `roles/owner` and `roles/viewer` include it, assigned org-wide. See [Built-in roles](/docs/iam/roles).

## Paging through the log [#paging-through-the-log]

`auditLogEntries` returns one page of entries, newest first, with a stable order for entries recorded at the same moment. You can read the whole organization’s log, or narrow it to the entries of one project with `projectId`. Only project-scoped role assignments and revocations carry a project, so a narrowed query leaves out every other action.

The page tells you where you are:

- `entries` – the entries on this page.
- `total` – how many entries match your query across all pages.
- `offset` and `limit` – the window you were actually served.
- `hasMore` – `true` while entries remain beyond this page. When it’s `false`, you’ve read to the end.

`limit` defaults to 100 and is capped at 500. If you ask for more than 500, you get 500, and the `limit` in the response says so. The cap applies to one page only; every entry is reachable by paging. To get the next page, add the served `limit` to `offset` and repeat while `hasMore` is `true`.

The following steps show the paging loop.

1. Request the page with `offset` 0.
1. Process its entries, de-duplicating on `id`.
1. If `hasMore` is `true`, set `offset` to `offset` + `limit`, request the next page and repeat from step 2. If it’s `false`, you’ve read the whole log.

<Callout type="note">

The log is written while you read it. If new entries are recorded while you page through, they’re added at the front and shift older entries back, so an entry can appear on two consecutive pages. No entry is skipped. De-duplicate on `id` if you need each entry exactly once.

</Callout>

```graphql
query {
  iam {
    auditLogEntries(input: { orgId: "<org-id>", offset: 0, limit: 100 }) {
      entries {
        id
        actor
        action
        target
        outcome
        occurredAt
        details
      }
      total
      offset
      limit
      hasMore
    }
  }
}
```

## Related [#related]

- [Assign and revoke roles](/docs/iam/assign-roles)
- [Manage organization members](/docs/iam/manage-members)
- [Use service accounts](/docs/iam/service-accounts)
- [API access](/docs/platform/access/api)

