# Audit log

> Page: https://docs.plotwork.dev/audit-log. Index of every page: https://docs.plotwork.dev/llms.txt

An organisation's audit log says who changed what in the organisation, and when. The owner and the admins read it in the portal, and on Enterprise they export it, or have their SIEM poll it with a key that can do nothing else.

## TL;DR

| Question | Answer |
|---|---|
| Which plan? | Pro keeps 30 days of events and shows them in the portal. Enterprise keeps 365 days, or the days the contract sets, and adds the export. The Free plan records nothing. |
| Who can read it? | The owner and the admins, on the organisation's Audit log tab. A member and a reader cannot. On Enterprise, an organisation API key with the `audit:read` scope can too. |
| What is recorded? | Members, invitations and roles, ownership, API keys, diagrams, folder rules, the brand, icons, avatar and style rules, "Keep diagrams editable", drift reports from CI, single sign-on (its settings, its domains, every sign-in through your provider, failed ones, people added on first sign-in, and the owner's emailed-code sign-ins while it is required), and changes Plotwork support made, with the reason given. |
| What is never in it? | A diagram's source, a key's value, a token, a color, or a full IP address. |
| How does a SIEM get it? | It polls `GET /orgs/{org}/audit/export` with a key that has only `audit:read`, and sends the `Plotwork-Next-Cursor` header back as `after` each time. |
| Is there a push? | Yes, on Enterprise: each event can be sent as it happens to Datadog, Dynatrace, Splunk, Microsoft Sentinel or a signed webhook. See [Send audit events and drift to your tools](https://docs.plotwork.dev/siem-delivery.md). Polling the export still works, and is the record to reconcile against. |

## 1. Read the log

Open the organisation in the portal and choose the Audit log tab. The newest events come first, a page at a time, with a button for older ones.

| Column | What it shows |
|---|---|
| When | How long ago, with the exact time on hover |
| Who | A member's email address, a key's name tagged API key, CI tagged CI, or Plotwork support |
| What | What happened, with facts such as the role given or the setting chosen |
| On | What it was done to: a member, an invited address, a key, a diagram, an icon or a folder |
| From | The network the request came from: an IPv4 /24 or an IPv6 /48, never the full address |

Three filters narrow the list, and each reaches every event the plan keeps:

| Filter | Narrows to |
|---|---|
| What | One group of actions, such as Members or API keys |
| Who | One email address or key name, as the log shows it. Choose a suggestion or press Enter. |
| When | The last 24 hours, 7 days, or 30 days |

## 2. Export it (Enterprise)

The tab has two downloads, CSV and JSON Lines, with the filters you chose. One file holds up to 1,000 events, oldest first. Downloading is itself recorded.

The same export is an API route:

```bash
curl -s "https://api.plotwork.dev/orgs/acme-platform/audit/export?format=jsonl" \
  -H "X-API-Key: $PLOTWORK_AUDIT_KEY" -D headers.txt -o events.jsonl
```

| Parameter or header | Meaning |
|---|---|
| `format` | `jsonl` (the default) or `csv` |
| `after` | Where to start: the `Plotwork-Next-Cursor` header of the export before |
| `actor`, `action`, `target`, `from`, `to` | The same filters as the log. `action` takes an action or a group such as `orgs.member`; `from` and `to` take ISO 8601 times. |
| `Plotwork-Next-Cursor` | The last event in this export. Send it as `after` next time. |
| `Plotwork-More` | `true` when more events are waiting after this export: ask again at once. |

A cell in the CSV that a spreadsheet would run as a formula starts with `'`, because a diagram's name is text a member typed.

## 3. Connect a SIEM

1. In the organisation's Keys tab, create a key and choose "Audit log only: read and export it". That key reads the log and is refused everywhere else, so it cannot publish or delete.
2. Store the key in the SIEM's secret store.
3. Poll the export every few minutes. Keep the last `Plotwork-Next-Cursor` you saw, and send it as `after`. While `Plotwork-More` is `true`, ask again straight away.
4. Parse each line against the [event schema](https://docs.plotwork.dev/schemas/plotwork.audit-event.json).

| SIEM | How it polls |
|---|---|
| Splunk | An HTTP input or a scripted input that runs the request above and keeps the cursor in a checkpoint |
| Datadog | A small job that runs the request and sends each line to the Logs intake |
| Microsoft Sentinel | A codeless connector or a logic app with a REST API poller, paging by the `after` parameter |

A key's export is not recorded as an event, so polling does not fill the log with its own reads. The key's last use is on the Keys tab.

## 4. The event

Every event has the same shape, version 1. A field may be added; none is removed or changes meaning without a new version.

| Field | Meaning |
|---|---|
| `version` | `1` |
| `id` | The event's id |
| `orgId` | The organisation's id |
| `at` | When it happened, as an ISO 8601 time in UTC |
| `action` | What happened, such as `orgs.member.role` (the list is below) |
| `actor.kind` | `user`, `key`, `ci` or `operator` |
| `actor.id` | The account id, the key id, or null for Plotwork support |
| `actor.name` | The email address or key name when it was recorded, "Plotwork support", or null once a deleted account is forgotten |
| `target.type`, `target.id`, `target.name` | What it was done to: its kind, its id, and its name or address |
| `metadata` | A few facts, such as `role`, `keepEditable`, `folder`, `scopes` or `reason` |
| `ip` | The network the request came from, or null |
| `userAgent` | The first 200 characters of the user agent, or null |
| `requestId` | The request id, which Plotwork support can look up |

| Group | Actions |
|---|---|
| Organisation | `orgs.org.create`, `orgs.org.rename` |
| Members | `orgs.member.add`, `orgs.member.remove`, `orgs.member.leave`, `orgs.member.role`, `orgs.owner.transfer` |
| Invitations | `orgs.invite.create`, `orgs.invite.revoke`, `orgs.invite.accept` |
| API keys | `orgs.key.create`, `orgs.key.reveal`, `orgs.key.revoke` |
| Diagrams | `orgs.diagram.publish`, `orgs.diagram.update`, `orgs.diagram.edit`, `orgs.diagram.restore`, `orgs.diagram.lock`, `orgs.diagram.unlock`, `orgs.diagram.delete` |
| Folder rules | `orgs.folder_rule.set`, `orgs.folder_rule.clear` |
| Look | `orgs.brand.set`, `orgs.brand.clear`, `orgs.icon.set`, `orgs.icon.delete`, `orgs.avatar.set`, `orgs.avatar.clear`, `orgs.style_rules.set`, `orgs.style_rules.clear` |
| Settings | `orgs.settings.editable`, `orgs.settings.publishing` |
| Members' public diagrams | `orgs.publishing.move`, `orgs.publishing.unpublish` |
| CI | `orgs.drift.report` |
| Contract | `orgs.contract.set`, `orgs.contract.end` |
| Integrations | `orgs.integration.create`, `orgs.integration.update`, `orgs.integration.delete` |
| The log itself | `orgs.audit.export` |

## 5. How long events are kept

| Plan | Kept |
|---|---|
| Free | Nothing is recorded |
| Pro | 30 days |
| Enterprise | 365 days, or the days the contract sets |

A daily clean-up removes older events. When an organisation moves to a plan that keeps fewer days, the next clean-up removes what that plan does not keep. The log goes with the organisation. When an account is deleted, its email address is cleared from every log and its id stays.

## See also

| Page | Why |
|---|---|
| [Organisations](https://docs.plotwork.dev/organisations.md) | Roles, keys and who may do what |
| [Single sign-on](https://docs.plotwork.dev/single-sign-on.md) | The sign-in events this log records |
| [Plans and billing](https://docs.plotwork.dev/plans-and-billing.md) | What Pro and Enterprise include |
| [Enterprise rollout](https://docs.plotwork.dev/enterprise-rollout.md) | Keys and CI across many repositories |
| [Send audit events and drift to your tools](https://docs.plotwork.dev/siem-delivery.md) | Push each event to Datadog, Dynatrace, Splunk, Microsoft Sentinel or a webhook |
| [Privacy policy](https://docs.plotwork.dev/privacy-policy.md) | What the log stores, and for how long |
| [API reference](https://docs.plotwork.dev/api/get-orgs-org-audit.md) | The read and export routes |
