> For the complete documentation index, see [llms.txt](https://docs.p0.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.p0.dev/integrations/siem-integrations/audit-log-format.md).

# Audit log format

Reference for P0 audit log fields, actions, and payload formats streamed to SIEM integrations.

P0 streams structured audit logs to your configured SIEM integration. This reference documents the log payload format, the complete action hierarchy, and example payloads for each action.

* [General fields](#general-fields)
* [Action hierarchy](#action-hierarchy)
* [Access policy actions](#access-policy-actions)
* [JIT configuration actions](#jit-configuration-actions)
* [Role management actions](#role-management-actions)
* [Integration install actions](#integration-install-actions)
* [API key actions](#api-key-actions)
* [Access bundle actions](#access-bundle-actions)
* [Agentic client actions](#agentic-client-actions)
* [Permission request actions](#permission-request-actions)
* [Permission request lifecycle](#permission-request-lifecycle)
* [Pre-approval lifecycle actions](#pre-approval-lifecycle-actions)
* [SSH session actions](#ssh-session-actions)
* [File transfer actions](#file-transfer-actions)
* [Authentication and authorization actions](#authentication-and-authorization-actions)

## General fields

Every audit log event contains the following fields:

| Field            | Type   | Description                                                                   |
| ---------------- | ------ | ----------------------------------------------------------------------------- |
| `vendor_account` | string | Your P0 organization (tenant) identifier                                      |
| `data`           | object | Diff or data associated with the action                                       |
| `type`           | string | Event source: `api`, `permission-requests`, `preapproval`, or `notifier`      |
| `timestamp`      | string | ISO 8601 formatted timestamp (for example, `2025-01-17T18:15:11.458Z`)        |
| `action`         | string | The specific audit action identifier                                          |
| `user_id`        | string | Identifier of the actor who performed the action (typically an email address) |
| `user_type`      | string | Actor type: `USER`, `API_KEY`, or `PUBLIC_ACCESS`                             |
| `token_id`       | string | Identifier of the API key used, when the actor is an API key (optional)       |

API events also include `src_ip` and `user_agent` fields when those values are available.

### Example payload

```json
{
  "vendor_account": "your-org",
  "data": {},
  "type": "api",
  "timestamp": "2025-01-17T18:15:11.458Z",
  "action": "admin.roles.user.added",
  "user_id": "user@example.com",
  "user_type": "USER",
  "token_id": "<token id>"
}
```

## Action hierarchy

P0 audit actions follow a hierarchical naming convention. The top-level prefix indicates the category of the action.

```
admin
  .jit
    .approvable-duration.set
    .expiry-option
      .created
      .deleted
      .reset
    .max-access-duration.set
    .standing-access-duration.set
  .roles
    .user
      .added
      .deleted
    .group
      .added
      .deleted
  .integration
    .installed
    .updated
    .removed
  .api-key
    .created
    .deleted
  .bundles
    .created
    .updated
    .deleted
  .policies
    .created
    .updated
    .deleted
  .agentic-client
    .created
api
  .jit
    .permission-requests
      .created
      .approved
      .denied
      .revoked
    .preapproval
      .created
      .revoked
ssh
  .session
    .start
    .end
file-transfer
  .upload
  .download
  .object-delete
auth
  .authentication.failed
  .authorization.failed
```

## Access policy actions

These actions are logged when access policies are created, updated, or deleted. Access policies were formerly called routing rules.

{% hint style="warning" %}
**Renamed event types:** Routing-rule changes are now emitted under the `admin.policies.*` actions listed in the following table. The former `admin.routing-rules.*` actions no longer exist. If you built SIEM alerts or filters on the old names, update them to the new ones:

Alerts that still match on `admin.routing-rules.*` stop firing without error, so update them to avoid silent gaps in coverage.
{% endhint %}

| Former action                 | Current action           |
| ----------------------------- | ------------------------ |
| `admin.routing-rules.created` | `admin.policies.created` |
| `admin.routing-rules.updated` | `admin.policies.updated` |
| `admin.routing-rules.deleted` | `admin.policies.deleted` |

### `admin.policies.created`

A new access policy was created. The `data` field has the difference between the old and new version of the access policies document.

```json
{
  "timestamp": "2025-08-11T15:29:16.802Z",
  "action": "admin.policies.created",
  "user_agent": "Mozilla/5.0 ...",
  "data": {
    "version": {
      "-": "<old version id>",
      "+": "<new version id>"
    },
    "rules": [
      {
        "action": "admin.policies.created",
        "name": "Test",
        "diff": {
          "+": {
            "disabled": false,
            "resource": { "type": "any" },
            "requestor": { "type": "any" },
            "approval": [{ "type": "persistent" }],
            "name": "Test"
          }
        }
      }
    ]
  },
  "token_id": "<token id>",
  "vendor_account": "your-org",
  "src_ip": "::1",
  "user_id": "user@example.com",
  "user_type": "USER"
}
```

### `admin.policies.updated`

An access policy update occurred. The `data` field has the difference between the old and new version of the access policies document.

```json
{
  "timestamp": "2025-08-11T15:29:16.802Z",
  "action": "admin.policies.updated",
  "user_agent": "Mozilla/5.0 ...",
  "data": {
    "version": {
      "-": "<old version id>",
      "+": "<new version id>"
    },
    "rules": [
      {
        "action": "admin.policies.updated",
        "name": "Test",
        "diff": {
          "approval": [
            {
              "type": {
                "-": "persistent",
                "+": "p0"
              },
              "options": {
                "+": { "allowOneParty": true }
              }
            }
          ]
        }
      }
    ]
  },
  "token_id": "<token id>",
  "vendor_account": "your-org",
  "src_ip": "::1",
  "user_id": "user@example.com",
  "user_type": "USER"
}
```

### `admin.policies.deleted`

An access policy was deleted. The `data` field has the difference between the old and new version of the access policies document.

```json
{
  "timestamp": "2025-08-11T15:29:16.802Z",
  "action": "admin.policies.deleted",
  "user_agent": "Mozilla/5.0 ...",
  "data": {
    "version": {
      "-": "<old version id>",
      "+": "<new version id>"
    },
    "rules": [
      {
        "name": "Test",
        "diff": {
          "-": {
            "requestor": { "type": "any" },
            "name": "Test",
            "approval": [
              {
                "options": { "allowOneParty": true },
                "type": "p0"
              }
            ],
            "disabled": false,
            "resource": { "type": "any" }
          }
        },
        "action": "admin.policies.deleted"
      }
    ]
  },
  "token_id": "<token id>",
  "vendor_account": "your-org",
  "src_ip": "::1",
  "user_id": "user@example.com",
  "user_type": "USER"
}
```

{% hint style="info" %}
In access policy diff payloads, `"+"` indicates added values and `"-"` indicates removed values.
{% endhint %}

## JIT configuration actions

These actions are logged when just-in-time access configuration settings are modified.

### Approvable duration

#### `admin.jit.approvable-duration.set`

The approvable duration is updated. This controls how long access requests remain open before being automatically denied.

```json
{
  "action": "admin.jit.approvable-duration.set",
  "type": "api",
  "vendor_account": "your-org",
  "timestamp": "2025-01-17T18:12:43.766Z"
}
```

### Expiry options

#### `admin.jit.expiry-option.created`

An expiry option was created.

```json
{
  "action": "admin.jit.expiry-option.created",
  "type": "api",
  "vendor_account": "your-org",
  "timestamp": "2025-01-17T18:12:43.766Z"
}
```

#### `admin.jit.expiry-option.deleted`

An expiry option was deleted.

```json
{
  "action": "admin.jit.expiry-option.deleted",
  "type": "api",
  "vendor_account": "your-org",
  "timestamp": "2025-01-17T18:12:43.766Z"
}
```

#### `admin.jit.expiry-option.reset`

Expiry options have been reset to defaults.

```json
{
  "action": "admin.jit.expiry-option.reset",
  "timestamp": "2025-01-17T18:15:11.458Z",
  "vendor_account": "your-org",
  "type": "api"
}
```

## Role management actions

The system logs these actions when roles are added or removed from users or groups on the **Settings** page under the **Access Control** section.

P0 roles include: `owner`, `iamViewer`, and `manager` (approver). You can assign roles to individual users or to groups.

### `admin.roles.user.added`

An admin has assigned a role to a user.

```json
{
  "action": "admin.roles.user.added",
  "vendor_account": "your-org",
  "type": "api"
}
```

### `admin.roles.user.deleted`

An admin removed a role from a user.

```json
{
  "action": "admin.roles.user.deleted",
  "vendor_account": "your-org",
  "type": "api"
}
```

### `admin.roles.group.added`

A role is assigned to a group by the system.

```json
{
  "action": "admin.roles.group.added",
  "vendor_account": "your-org",
  "type": "api"
}
```

### `admin.roles.group.deleted`

The system removes a role from a group.

```json
{
  "action": "admin.roles.group.deleted",
  "vendor_account": "your-org",
  "type": "api"
}
```

## Integration install actions

These actions are logged when integrations are installed, updated, or removed.

**Terminology:**

| Term        | Definition                                                                                                                |
| ----------- | ------------------------------------------------------------------------------------------------------------------------- |
| Integration | A resource integration such as Google Cloud, AWS, Kubernetes, SSH, or Snowflake                                           |
| Component   | The type of integration capability (for example, IAM management, IAM assessment, Resource Explorer, HTTP Event Collector) |
| Item        | An individual installation identifier (for example, a Google Cloud project ID or an AWS account ID)                       |

### `admin.integration.installed`

A new entry installs an integration component.

```json
{
  "action": "admin.integration.installed",
  "vendor_account": "your-org",
  "data": {
    "component": "iam-assessment",
    "id": "test-project",
    "delta": {
      "state": {
        "+": "installed",
        "-": "configure"
      }
    }
  },
  "type": "api"
}
```

AWS integration example with federated login configuration:

```json
{
  "action": "admin.integration.installed",
  "vendor_account": "your-org",
  "timestamp": "2025-01-16T22:05:23.273Z",
  "type": "api",
  "data": {
    "id": "123452051234",
    "delta": {
      "login": {
        "identity": {
          "-": { "type": "email" }
        },
        "provider": {
          "+": {
            "identityProvider": "test_okta",
            "appId": "appid1",
            "type": "okta",
            "method": {
              "type": "saml",
              "accountCount": { "type": "single" }
            }
          }
        },
        "type": {
          "-": "iam",
          "+": "federated"
        }
      },
      "state": {
        "+": "installed",
        "-": "configure"
      }
    },
    "component": "iam-write"
  }
}
```

### `admin.integration.removed`

The system removed an installation entry from an integration component. This can apply to an entire integration or a specific item.

Component deletion:

```json
{
  "type": "api",
  "data": { "key": "aws" },
  "action": "admin.integration.removed",
  "timestamp": "2025-01-16T21:46:36.144Z",
  "vendor_account": "your-org"
}
```

Item deletion:

```json
{
  "action": "admin.integration.removed",
  "data": {
    "id": "test-project",
    "component": "iam-assessment"
  },
  "vendor_account": "your-org",
  "type": "api",
  "timestamp": "2025-01-16T22:23:05.096Z"
}
```

### `admin.integration.updated`

An integration component is configured. For example, setting the account ID for an AWS integration before installing any of its components.

```json
{
  "action": "admin.integration.updated",
  "data": {
    "key": "aws",
    "config": {
      "iam-write": {},
      "base": {},
      "inventory": {},
      "iam-assessment": {}
    }
  },
  "timestamp": "2025-01-16T21:46:51.260Z",
  "type": "api",
  "vendor_account": "your-org"
}
```

## API key actions

These actions are logged when API keys for programmatic access to the P0 API are created or deleted.

### `admin.api-key.created`

An API key has been created.

```json
{
  "action": "admin.api-key.created",
  "type": "api",
  "vendor_account": "your-org",
  "timestamp": "2025-01-17T00:48:09.227Z"
}
```

### `admin.api-key.deleted`

An API key has been deleted.

```json
{
  "action": "admin.api-key.deleted",
  "timestamp": "2025-01-17T00:48:13.129Z",
  "vendor_account": "your-org",
  "type": "api"
}
```

## Access bundle actions

These actions are logged when access bundles are created, updated, or deleted. The `data` field identifies the affected bundle by its `id`, and for create and update events also includes its `label`.

### `admin.bundles.created`

A new access bundle was created.

```json
{
  "action": "admin.bundles.created",
  "type": "api",
  "vendor_account": "your-org",
  "timestamp": "2025-01-17T18:15:11.458Z",
  "data": {
    "id": "<bundle id>",
    "label": "Engineering on-call"
  },
  "user_id": "user@example.com",
  "user_type": "USER"
}
```

### `admin.bundles.updated`

An existing access bundle was updated.

```json
{
  "action": "admin.bundles.updated",
  "type": "api",
  "vendor_account": "your-org",
  "timestamp": "2025-01-17T18:16:02.114Z",
  "params": {
    "id": "<bundle id>"
  },
  "data": {
    "id": "<bundle id>",
    "label": "Engineering on-call"
  },
  "user_id": "user@example.com",
  "user_type": "USER"
}
```

### `admin.bundles.deleted`

An access bundle was deleted.

```json
{
  "action": "admin.bundles.deleted",
  "type": "api",
  "vendor_account": "your-org",
  "timestamp": "2025-01-17T18:17:45.902Z",
  "params": {
    "id": "<bundle id>"
  },
  "data": {
    "id": "<bundle id>"
  },
  "user_id": "user@example.com",
  "user_type": "USER"
}
```

## Agentic client actions

These actions are logged when an agentic client is registered with the [agentic gateway](/agentic-access/agentic-gateway.md). An agentic client is either a confidential client (`client_credential_post`) or a federated client (`jwt_bearer`).

{% hint style="info" %}
Agentic client registration is in beta.
{% endhint %}

The `data` field describes the registered client. Which fields are present depends on the client `type`.

| Field          | Type   | Description                                                                                                                                                    |
| -------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`           | string | Client identifier. For a confidential client, the client ID. For a federated client, the client subject, formatted `federated/<providerId>/subject/<subject>`. |
| `registration` | string | How the client was registered: `manual` when a P0 user registers it through the API, or `automatic` when a gateway registers it through dynamic registration.  |
| `status`       | string | Client lifecycle state: `active` or `disabled`.                                                                                                                |
| `type`         | string | Client type: `client_credential_post` (confidential client) or `jwt_bearer` (federated client).                                                                |
| `hostname`     | string | Confidential clients only. Host that registered the client.                                                                                                    |
| `platform`     | string | Confidential clients only. Client platform: `claude-code`, `claude-agents`, or `custom`.                                                                       |
| `redirectUri`  | string | Confidential clients only. OAuth redirect URI registered for the client.                                                                                       |
| `version`      | string | Confidential clients only. Client version.                                                                                                                     |
| `issuer`       | string | Federated clients only. Trust authority issuer that validated the client.                                                                                      |
| `providerId`   | string | Federated clients only. Federation provider that validated the client.                                                                                         |

### `admin.agentic-client.created`

An agentic client was registered. A `manual` registration is attributed to the P0 user in the `user_id` and `user_type` fields. An `automatic` registration is performed by a gateway on the token validation path, so it has no user actor.

Confidential client, manual registration:

```json
{
  "action": "admin.agentic-client.created",
  "type": "api",
  "vendor_account": "your-org",
  "timestamp": "2025-01-17T18:15:11.458Z",
  "data": {
    "id": "<client id>",
    "registration": "manual",
    "status": "active",
    "type": "client_credential_post",
    "hostname": "workstation-01",
    "platform": "claude-code",
    "redirectUri": "https://redirect.example.com",
    "version": "1.0.0"
  },
  "user_id": "user@example.com",
  "user_type": "USER"
}
```

Federated client, automatic registration through dynamic registration:

```json
{
  "action": "admin.agentic-client.created",
  "type": "api",
  "vendor_account": "your-org",
  "timestamp": "2025-01-17T18:15:11.458Z",
  "data": {
    "id": "federated/<provider id>/subject/<subject>",
    "registration": "automatic",
    "status": "active",
    "type": "jwt_bearer",
    "issuer": "https://issuer.example.com",
    "providerId": "<provider id>"
  }
}
```

## Permission request actions

These actions are logged when users create, approve, revoke, or deny permission requests through the P0 web application, CLI, or notifier integrations (Slack, Microsoft Teams).

{% hint style="info" %}
For the approve, revoke, and deny events, the `type` field is `notifier` if the user takes the action via Slack or Microsoft Teams, or `api` if the user takes the action in the P0 web application.
{% endhint %}

### `api.jit.permission-requests.created`

The system has received a request to create a new permission request.

```json
{
  "action": "api.jit.permission-requests.created",
  "user_type": "USER",
  "src_ip": "<ip>",
  "timestamp": "2025-07-07T23:19:20.126Z",
  "user_id": "user@example.com",
  "user_agent": "P0 CLI/0.18.6",
  "vendor_account": "your-org",
  "data": [
    {
      "requestId": "9MMAsmlwAAnHjzNJkE5o",
      "message": "Access requested",
      "processingMillis": 1234,
      "scriptName": "p0",
      "command": [
        "request", "ssh", "session",
        "<instance name>",
        "--public-key", "<public key>"
      ]
    }
  ]
}
```

### `api.jit.permission-requests.approved`

The system has approved a permission request.

```json
{
  "action": "api.jit.permission-requests.approved",
  "vendor_account": "your-org",
  "timestamp": "2025-07-07T23:21:55.636Z",
  "src_ip": "<ip>",
  "params": {
    "requestId": "9MMAsmlwAAnHjzNJkE5o"
  },
  "user_id": "user@example.com",
  "user_agent": "Chrome/137.0.0.0",
  "user_type": "USER"
}
```

### `api.jit.permission-requests.denied`

The system has denied a permission request.

```json
{
  "action": "api.jit.permission-requests.denied",
  "src_ip": "<ip>",
  "params": {
    "requestId": "aeRv8bsBOBvYbMXsNjrI"
  },
  "user_type": "USER",
  "user_id": "user@example.com",
  "vendor_account": "your-org",
  "user_agent": "Chrome/137.0.0.0",
  "timestamp": "2025-07-07T23:30:48.275Z"
}
```

### `api.jit.permission-requests.revoked`

A permission request has been revoked.

```json
{
  "action": "api.jit.permission-requests.revoked",
  "params": {
    "requestId": "9MMAsmlwAAnHjzNJkE5o"
  },
  "user_agent": "Chrome/137.0.0.0",
  "user_id": "user@example.com",
  "user_type": "USER",
  "timestamp": "2025-07-07T23:26:00.701Z",
  "vendor_account": "your-org",
  "src_ip": "<ip>"
}
```

## Permission request lifecycle

The following audit events are logged as P0 processes a permission request through its lifecycle. These are system-generated events that track internal state transitions.

### `permission-requests.created`

A permission request has been created and is in the `NEW` state.

```json
{
  "action": "permission-requests.created",
  "timestamp": "2025-07-08T21:46:13.323Z",
  "request_id": "kYdqnPxnb7Gugp2iqKR5",
  "data": {
    "commandLine": "request ssh session <instance name> --sudo false",
    "requestor": "user@example.com",
    "approvedOnly": false,
    "access": "session",
    "permission": {
      "provider": "gcloud",
      "destination": "<instance name>",
      "sudo": false,
      "publicKey": "<public key>",
      "parent": "<project id>",
      "resource": {
        "zone": "<zone>",
        "projectId": "<project id>",
        "instanceName": "<instance name>",
        "fullName": "<resource id>"
      },
      "zone": "<zone>"
    },
    "lastUpdatedTimestamp": 1752011173323,
    "type": "ssh",
    "principal": "user@example.com",
    "status": "NEW",
    "requestedTimestamp": 1752011173323
  }
}
```

### `permission-requests.granted`

A permission request has been granted and access has been provisioned.

```json
{
  "action": "permission-requests.granted",
  "timestamp": "2025-07-07T23:22:05.166Z",
  "request_id": "9MMAsmlwAAnHjzNJkE5o",
  "data": {
    "access": "session",
    "approvalDetails": {
      "approvalSource": "webapp",
      "approvedTimestamp": 1751930515300,
      "id": "approver@example.com",
      "email": "approver@example.com",
      "name": "approver@example.com"
    },
    "principal": "user@example.com",
    "canEscalate": false,
    "requestedTimestamp": 1751930359906,
    "grantTimestamp": 1751930525165,
    "permission": {
      "zone": "<zone>",
      "parent": "<project id>",
      "provider": "gcloud",
      "resource": {
        "fullName": "<resource name>",
        "instanceName": "<instance name>",
        "zone": "<zone>",
        "projectId": "<project id>"
      },
      "destination": "<instance name>",
      "publicKey": "<public key>",
      "sudo": false
    },
    "type": "ssh",
    "requestor": "user@example.com",
    "lastUpdatedTimestamp": 1751930525166,
    "status": "DONE",
    "approvedOnly": false,
    "expiryTimestamp": 1751930815529,
    "isAwaitingExpiry": true,
    "commandLine": "request ssh session <instance name> --sudo false"
  }
}
```

### `permission-requests.denied`

The system has denied the permission request.

```json
{
  "action": "permission-requests.denied",
  "request_id": "Dc7PgjoZSYpG47wAi7H4",
  "data": {
    "approvalDetails.id": "approver@example.com",
    "approvalDetails.email": "approver@example.com",
    "approvalDetails.name": "approver@example.com",
    "approvalDetails.approvedTimestamp": 1751995305355,
    "approvalDetails.approvalSource": "webapp",
    "status": "DENIED"
  },
  "timestamp": "2025-07-08T17:21:45.497Z"
}
```

### `permission-requests.revoked`

A permission request has been revoked and access has been deprovisioned.

When a user revokes a request (through the web app, Slack, Microsoft Teams, or email), the payload includes a `revocationDetails` object that identifies who revoked the request. This is distinct from the requestor (`requestor`) and the recipient of access (`principal`): a request that a user ends themselves is a *relinquish*, whereas a request that a different user ends is a *revoke*. Use `revocationDetails.email` to attribute the action to the user who performed it.

| Field                                | Type   | Description                                                                                          |
| ------------------------------------ | ------ | ---------------------------------------------------------------------------------------------------- |
| `revocationDetails.id`               | string | Source ID of the user who revoked the request                                                        |
| `revocationDetails.name`             | string | Display name of the user who revoked the request. Optional; present when a display name is available |
| `revocationDetails.email`            | string | Email of the user who revoked the request                                                            |
| `revocationDetails.revokedTimestamp` | number | Time (epoch milliseconds) when the user revoked the request                                          |
| `revocationDetails.revocationSource` | string | Where the revocation originated: `webapp`, `slack`, `msTeams`, or `email`                            |

```json
{
  "action": "permission-requests.revoked",
  "request_id": "9MMAsmlwAAnHjzNJkE5o",
  "timestamp": "2025-07-07T23:26:03.241Z",
  "data": {
    "requestor": "user@example.com",
    "requestedTimestamp": 1751930359906,
    "isAwaitingExpiry": false,
    "approvalDetails": {
      "approvedTimestamp": 1751930515300,
      "id": "approver@example.com",
      "name": "approver@example.com",
      "email": "approver@example.com",
      "approvalSource": "webapp"
    },
    "revocationDetails": {
      "id": "admin@example.com",
      "name": "admin@example.com",
      "email": "admin@example.com",
      "revokedTimestamp": 1751930763241,
      "revocationSource": "webapp"
    },
    "grantTimestamp": 1751930525165,
    "principal": "user@example.com",
    "approvedOnly": false,
    "commandLine": "request ssh session <instance name> --sudo false",
    "type": "ssh",
    "expiryTimestamp": 1751930815529,
    "access": "session",
    "permission": {
      "destination": "<instance name>",
      "sudo": false,
      "parent": "<project id>",
      "zone": "<zone>",
      "resource": {
        "fullName": "<resource name>",
        "zone": "<zone>",
        "instanceName": "<instance name>",
        "projectId": "<project id>"
      },
      "publicKey": "<public key>",
      "provider": "gcloud"
    },
    "lastUpdatedTimestamp": 1751930763241,
    "status": "REVOKED",
    "canEscalate": false,
    "revokedTimestamp": 1751930763241
  }
}
```

> **Note**: `revocationDetails` is present only for requests revoked after this attribution was introduced. Older revoked requests, and requests that expire automatically, don't include it.

### `permission-requests.expired`

A permission request has expired and access has been automatically deprovisioned.

```json
{
  "action": "permission-requests.expired",
  "timestamp": "2025-07-08T16:52:37.198Z",
  "request_id": "R4EuCBttAGQIPfreDfVC",
  "data": {
    "principal": "user@example.com",
    "approvalDetails": {
      "approvalSource": "webapp",
      "email": "approver@example.com",
      "name": "approver@example.com",
      "id": "approver@example.com",
      "approvedTimestamp": 1751993254002
    },
    "isAwaitingExpiry": false,
    "approvedOnly": false,
    "access": "session",
    "permission": {
      "provider": "gcloud",
      "parent": "<project id>",
      "publicKey": "<public key>",
      "zone": "<zone>",
      "resource": {
        "projectId": "<project id>",
        "zone": "<zone>",
        "instanceName": "<instance name>",
        "fullName": "<resource name>"
      },
      "sudo": false,
      "destination": "<instance name>"
    },
    "expiryTimestamp": 1751993554159,
    "revokedTimestamp": 1751993557198,
    "lastUpdatedTimestamp": 1751993557198,
    "type": "ssh",
    "requestor": "user@example.com",
    "commandLine": "request ssh session <instance name> --sudo false",
    "status": "EXPIRED",
    "grantTimestamp": 1751993258475,
    "requestedTimestamp": 1751993250693,
    "canEscalate": false
  }
}
```

## Pre-approval lifecycle actions

These actions are logged when pre-approvals are created or revoked.

### `api.jit.preapproval.created`

A new pre-approval was created.

```json
{
  "action": "api.jit.preapproval.created",
  "data": {
    "type": "ssh",
    "access": "group",
    "permission": {
      "provider": "aws",
      "name": "group-name",
      "key": "Developer",
      "sudo": false,
      "parent": "391052057035",
      "alias": "p0-dev",
      "resource": {}
    },
    "allowId": "32cdcab1-bae1-4a21-9fc3-a4234cac87f6",
    "source": "allow",
    "principal": "user@example.com",
    "isAwaitingExpirationReminder": true,
    "expirationReminderTimestamp": 1755302400000,
    "approver": {
      "approvalSource": "evidence",
      "approvedTimestamp": 1754330463656,
      "id": "user@example.com",
      "name": "user@example.com",
      "email": "user@example.com"
    },
    "startsAt": 1754330463656,
    "endsAt": 1756512000000,
    "createdAt": 1754330463723
  },
  "pre_approval_id": "PzCPjpJeYgAGw3koW6Tb",
  "status": "created",
  "timestamp": 1754330464112,
  "type": "preapproval"
}
```

### `api.jit.preapproval.revoked`

An existing pre-approval has been manually revoked.

```json
{
  "action": "api.jit.preapproval.revoked",
  "data": {
    "evidenceId": "TX7lyLXt29zcGumgxWyW"
  },
  "params": {
    "evidenceId": "TX7lyLXt29zcGumgxWyW"
  },
  "status": "created",
  "timestamp": 1754331366618,
  "vendor_account": "your-org",
  "src_ip": "::1",
  "type": "api",
  "user_agent": "Mozilla/5.0 ...",
  "user_type": "USER",
  "user_id": "user@example.com",
  "token_id": "<token id>"
}
```

## SSH session actions

These actions are logged when a user starts or ends an SSH session opened through the P0 CLI. The `data` field identifies the permission request that authorized the session (`requestId`), the session (`sshSessionId`), the acting user, and the granted `permission`. For sessions that go through an Azure bastion, the `data` field also includes the bastion session identifiers.

### `ssh.session.start`

A user started an SSH session.

```json
{
  "action": "ssh.session.start",
  "type": "api",
  "vendor_account": "your-org",
  "timestamp": "2025-07-07T23:22:10.500Z",
  "data": {
    "requestId": "9MMAsmlwAAnHjzNJkE5o",
    "sshSessionId": "<session id>",
    "user": {
      "email": "user@example.com",
      "uid": "abc123"
    },
    "permission": {
      "provider": "gcloud",
      "destination": "<instance name>",
      "sudo": false
    }
  },
  "user_id": "user@example.com",
  "user_type": "USER"
}
```

### `ssh.session.end`

A user's SSH session ended.

```json
{
  "action": "ssh.session.end",
  "type": "api",
  "vendor_account": "your-org",
  "timestamp": "2025-07-07T23:35:47.882Z",
  "data": {
    "requestId": "9MMAsmlwAAnHjzNJkE5o",
    "sshSessionId": "<session id>",
    "user": {
      "email": "user@example.com",
      "uid": "abc123"
    },
    "permission": {
      "provider": "gcloud",
      "destination": "<instance name>",
      "sudo": false
    }
  },
  "user_id": "user@example.com",
  "user_type": "USER"
}
```

## File transfer actions

These actions are logged when a user transfers files to or from an instance using the P0 CLI. P0 stages transferred files in an intermediary bucket, so a single transfer can emit an upload, a download, and an object-delete event. The `data` field identifies the authorizing permission request (`requestId`), the transfer (`fileTransferId`), the staging bucket (`bucketName`), the target instance (`instanceId`), and the `outcome` of the operation (`success` or `failure`).

### `file-transfer.upload`

A file was uploaded to the staging bucket.

```json
{
  "action": "file-transfer.upload",
  "type": "api",
  "vendor_account": "your-org",
  "timestamp": "2025-07-07T23:40:02.310Z",
  "data": {
    "requestId": "9MMAsmlwAAnHjzNJkE5o",
    "fileTransferId": "<file transfer id>",
    "bucketName": "<bucket name>",
    "instanceId": "<instance id>",
    "outcome": "success"
  },
  "user_id": "user@example.com",
  "user_type": "USER"
}
```

### `file-transfer.download`

A file was downloaded from the staging bucket to the target instance.

```json
{
  "action": "file-transfer.download",
  "type": "api",
  "vendor_account": "your-org",
  "timestamp": "2025-07-07T23:40:05.774Z",
  "data": {
    "requestId": "9MMAsmlwAAnHjzNJkE5o",
    "fileTransferId": "<file transfer id>",
    "bucketName": "<bucket name>",
    "instanceId": "<instance id>",
    "outcome": "success"
  },
  "user_id": "user@example.com",
  "user_type": "USER"
}
```

### `file-transfer.object-delete`

P0 deleted the transferred object from the staging bucket after a successful download.

```json
{
  "action": "file-transfer.object-delete",
  "type": "api",
  "vendor_account": "your-org",
  "timestamp": "2025-07-07T23:40:06.219Z",
  "data": {
    "requestId": "9MMAsmlwAAnHjzNJkE5o",
    "fileTransferId": "<file transfer id>",
    "bucketName": "<bucket name>",
    "instanceId": "<instance id>",
    "outcome": "success"
  },
  "user_id": "user@example.com",
  "user_type": "USER"
}
```

## Authentication and authorization actions

These actions are logged when P0 receives invalid authentication or authorization requests.

### `auth.authentication.failed`

A call to the API lacked a valid access token.

```json
{
  "action": "auth.authentication.failed",
  "src_ip": "209.169.98.86",
  "status": "created",
  "timestamp": 1754006124918,
  "type": "api",
  "user_agent": "Mozilla/5.0 ...",
  "vendor_account": "your-org",
  "user_type": "USER",
  "user_id": "user@example.com",
  "token_id": "<token id>"
}
```

### `auth.authorization.failed`

A call to the API had a valid access token but attempted an action the user lacked permissions for.

```json
{
  "action": "auth.authorization.failed",
  "src_ip": "209.169.98.86",
  "status": "created",
  "timestamp": 1754006124918,
  "type": "api",
  "user_agent": "Mozilla/5.0 ...",
  "vendor_account": "your-org",
  "user_type": "USER",
  "user_id": "user@example.com",
  "token_id": "<token id>",
  "data": {
    "permissions": ["integration.read", "catalog.view"],
    "roles": ["owner"]
  }
}
```
