Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Audit Log

Every Organization keeps an audit log: a chronological record of the significant actions taken in that Organization — who did what, to which object, and when. Use it to answer questions like “who deleted the staging Environment?” or “when was this app last scaled, and by whom?”.

What is recorded

Each entry captures:

  • Action — one of create, update, delete, invite, join, leave, deploy, rollback, promote, scale, restart, transfer, publish, unpublish, credentials_read, block, unblock, verify, release.
  • Who — the ID of the user who performed the action, or null when the platform acted on its own (transfer blocks, background domain checks, automatic token revokes).
  • What — the kind of object (organization, project, environment, resource, group, secret, variable, invitation, domain, deploy_token, git_connection, repo_link) and its ID.
  • When — a UTC timestamp.
  • Details — action-specific context, such as the Resource name, the Environment it lives in, the new replica count for a scale, or a custom domain that was added or removed. A released domain is recorded twice: once for the organization that released it, once for the organization that was serving it. A blocked or unblocked entry’s details always name the reason (currently always the monthly transfer allocation).

Recorded actions include:

ObjectActions
Organizationcreated, updated, deleted, ownership transferred
Projectcreated, updated, deleted; member capabilities changed; member removed
Environmentcreated, updated, deleted, deployment triggered, promoted from another environment, deployment rolled back
Resourcecreated, updated, deleted, scaled, restarted, deployment triggered, rolled back, database or bucket attached or detached, blocked or unblocked for exceeding the monthly transfer allocation, custom domain added, verified (by you or the background check), released, removed, or expired unverified
Object Storagebucket made public or private, access credentials read, storage-tier move started or abandoned, object deleted
Groupcreated, updated, deleted, member added or removed, project access granted, changed or revoked, per-environment override set or removed
Secretcreated, updated, deleted — by scope (Organization, Project, or Environment)
VariableOrganization or Environment variable set or removed
Invitationsent, resent, cancelled, accepted
Deployment tokencreated, revoked (by a person, or automatically with a reason)
GitHub/GitLab connectionconnected, disconnected
Repository linklinked or changed, unlinked, Deploy latest run

Secret entries record the secret’s scope and name only — never its value. Variable entries likewise record the variable’s scope and key, not its value.

The log records changes, not reads — viewing a page or listing Resources leaves no entry. The one deliberate exception is reading an Object Storage bucket’s access credentials, which is always logged because the credentials grant standing access.

Who can view it

Only the Organization’s Owner and Admins can read the audit log. Regular members — and project guests, who are not Organization members at all — receive a permission error. See Access Control for how these roles work.

Reading the log

The audit log is exposed through the platform API at your Organization’s audit-logs endpoint. You can call it with your CLI’s API token — paas auth token prints it for scripting:

curl -H "Authorization: Bearer $(paas auth token)" \
  "https://api.d2o.io/api/v1/organizations/acme/audit-logs"

For self-hosted installations, substitute your API origin. Entries come back newest first:

[
  {
    "id": "8f2c1e0a-6b7d-4a2e-9c31-5d8e0f4a2b91",
    "organization_id": "1b9e7d34-2a5f-4c8e-b061-7f3a9c2d5e10",
    "user_id": "c4a2f8d1-9e3b-47c6-8a50-2b6d1e9f7c34",
    "action": "scale",
    "resource_type": "resource",
    "resource_id": "5e0d3b7a-1f9c-4826-a4d2-8c7b5a1e9f03",
    "details": {
      "name": "web",
      "replicas": 3,
      "environment": "production"
    },
    "created_at": "2026-08-30T14:12:07.412391Z"
  },
  {
    "id": "0a7b5c3d-8e1f-42a9-b6c4-3d9e2f8a1b05",
    "organization_id": "1b9e7d34-2a5f-4c8e-b061-7f3a9c2d5e10",
    "user_id": "c4a2f8d1-9e3b-47c6-8a50-2b6d1e9f7c34",
    "action": "create",
    "resource_type": "resource",
    "resource_id": "5e0d3b7a-1f9c-4826-a4d2-8c7b5a1e9f03",
    "details": {
      "name": "web",
      "type": "WebApp",
      "environment": "production"
    },
    "created_at": "2026-08-28T09:44:51.208763Z"
  }
]

Paging

Two query parameters control paging:

  • limit — entries per page. Defaults to 50; capped at 100.
  • offset — how many entries to skip. Defaults to 0.
curl -H "Authorization: Bearer $(paas auth token)" \
  "https://api.d2o.io/api/v1/organizations/acme/audit-logs?limit=100&offset=100"

Next steps