> ## Documentation Index
> Fetch the complete documentation index at: https://infisical.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Audit logs

> Track and investigate every action performed within Infisical.

> [!NOTE]
>
> Audit logs are available under Infisical's [Pro, Advanced, and Enterprise](https://infisical.com/pricing) plans, with retention that varies by plan.
>
> If you're self-hosting Infisical, contact [sales@infisical.com](mailto:sales@infisical.com) to purchase an Enterprise license.

Infisical records every action performed in your organization as a structured event, so security and compliance teams can investigate incidents, prove access boundaries to auditors, and answer questions about who did what.

![Audit logs](https://mintlify.s3.us-west-1.amazonaws.com/infisical/images/platform/audit-logs/audit-logs-table.png)

## View audit logs

Anyone with the **Read** permission on **Audit Logs** has access to view audit logs. For more information, check out [Role-based access controls](https://infisical.com/docs/documentation/platform/access-controls/role-based-access-controls.md).

### For an organization

To view all events in an organization across every product:

> [tab] Infisical UI
>
> **Step 1**
>
> From your organization's home page, go to **Audit Logs**.
>
> **Step 2**
>
> Narrow down the results with [filters](#filtering-audit-logs).

> [tab] API
>
> Call the endpoint without a `projectId` to get events across the whole organization.
>
> ```bash theme={"dark"}
> curl -G "https://app.infisical.com/api/v1/organization/audit-logs" \
>   -H "Authorization: Bearer <your-access-token>" \
>   --data-urlencode "limit=100"
> ```
>
> See the [audit log export API reference](https://infisical.com/docs/api-reference/endpoints/audit-logs/export-audit-log.md) for the full parameter list.

### For a product

To view all events scoped to a single product:

> [tab] Infisical UI
>
> **Step 1**
>
> Open the product from the organization sidebar.
>
> **Step 2**
>
> For **Secrets Management**, **Certificate Manager**, **KMS**, **Agent Vault**, and **Secret Scanning**, select the project you want to audit.
>
> > [!NOTE]
> >
> > For **Privileged Access Manager**, skip this step.
>
> **Step 3**
>
> Select **Audit Logs** in the product's sidebar.
>
> **Step 4**
>
> Narrow down the results with [filters](#filtering-audit-logs).

> [tab] API
>
> Pass a `projectId` to scope the response to one project's events.
>
> ```bash theme={"dark"}
> curl -G "https://app.infisical.com/api/v1/organization/audit-logs" \
>   -H "Authorization: Bearer <your-access-token>" \
>   --data-urlencode "projectId=<project-id>" \
>   --data-urlencode "limit=100"
> ```
>
> See the [audit log export API reference](https://infisical.com/docs/api-reference/endpoints/audit-logs/export-audit-log.md) for the full parameter list.
>
> > [!NOTE]
> >
> > **Privileged Access Management (PAM)** uses a single project that Infisical manages internally. There's no public API for looking up that project's ID.
> >
> > Instead, call the organization endpoint (see [For an organization](#for-an-organization)) and filter `eventType` to PAM [event types](#event-types), (e.g., `eventType=pam-session-start,pam-session-end`).

## Log structure

Each log contains the following fields:

**id** `string`

The log entry's UUID.

**ipAddress** `string`

The source IP address of the request.

**userAgent** `string`

The raw `User-Agent` header of the client.

**userAgentType** `string`

The client category: `web`, `cli`, `k8-operator`, `terraform`, `InfisicalPythonSDK`, `InfisicalNodeSDK`, or `other`.

**expiresAt** `string`

When Infisical will delete the log entry, based on your plan's retention.

**createdAt** `string`

When the action occurred, in ISO 8601 format.

**updatedAt** `string`

Always equals `createdAt`. Audit log entries are append-only.

**orgId** `string`

The organization the action occurred in.

**projectId** `string`

The project the action affected. Empty for organization-level events.

**projectName** `string`

The name of the project at the time of the action. Empty for organization-level events.

**event** `object`

The action that occurred.

**properties**

**type** `string`

The event type (for example, `create-secret`). See [Event types](#event-types) for the full catalog.

**class** `string`

The [event class](#event-classes) the event type belongs to: `management`, `authentication`, `authorization`, or `data-access`.

**metadata** `object`

Context specific to the event. The shape depends on `event.type`; a `get-secret` event carries `environment`, `secretPath`, `secretKey`, and `secretVersion`, while a batch event like `create-secrets` carries a `secrets` array.

**actor** `object`

Who performed the action.

**properties**

**type** `string`

The actor category: commonly `user`, `identity`, or `platform`. Machine and system actors add more categories, for example `kmipClient`, `scimClient`, and `gateway`.

**metadata** `object`

Identifying information for the actor. The shape depends on `actor.type`.

**user actor**

**userId** `string`

The user's ID.

**email** `string`

The user's email.

**username** `string`

The user's username.

**permission** `object`

The user's effective permissions at the time of the action.

**identity actor**

**identityId** `string`

The machine identity's ID.

**permission** `object`

The identity's effective permissions at the time of the action.

### Example payload

```json expandable theme={"dark"}
{
   "id": "[UUID]",
   "ipAddress": "[IP_ADDRESS]",
   "userAgent": "[USER_AGENT_STRING]",
   "userAgentType": "web",
   "expiresAt": "[TIMESTAMP]",
   "createdAt": "[TIMESTAMP]",
   "updatedAt": "[TIMESTAMP]",
   "orgId": "[ORGANIZATION_UUID]",
   "projectId": "[PROJECT_UUID]",
   "projectName": "[PROJECT_NAME]",
   "event": {
       "type": "get-secret",
       "class": "data-access",
       "metadata": {
           "environment": "prod",
           "secretPath": "/db",
           "secretId": "[SECRET_UUID]",
           "secretKey": "DATABASE_URL",
           "secretVersion": 3
       }
   },
   "actor": {
       "type": "user",
       "metadata": {
           "email": "[EMAIL]",
           "userId": "[USER_UUID]",
           "username": "[USERNAME]",
           "permission": {
               "metadata": {},
               "auth": {}
           }
       }
   }
}
```

## Event classes

Every [event type](https://infisical.com/docs/documentation/platform/audit-logs.md#param-type) belongs to one of four classes, based on the kind of activity the event records.

| Class | What it covers | Default |
| - | - | - |
| `management` | Creates, updates, deletes, membership, roles, policies, background jobs, and the start and end of privileged sessions | Always on |
| `data-access` | Reads and lists, plus the crypto operations that return or operate on secret material, such as KMS encrypt and decrypt | Always on |
| `authentication` | Logins, failed logins, organization selection, machine identity authentication, and Gateway enrollment and connections | On |
| `authorization` | [Permission denials](#permission-denials) | Off |

### Choose which classes to record

You can turn authentication and authorization events on or off. Management and data access events are always recorded, so the log always has every configuration change and every read of secret material.

> [!NOTE]
>
> Recording authorization events requires the new privilege system. If your organization still uses legacy privilege management, the **Authorization** toggle is disabled. To upgrade, go to **Access Control** in your organization and select **Learn More & Upgrade**.

> [tab] For an organization
>
> These settings cover organization-level events, such as membership and login changes. Projects and sub-organizations have their own settings.
>
> **Step 1**
>
> From your organization's home page, go to **Audit Logs** and select the **Settings** tab.
>
> **Step 2**
>
> Turn a class on or off, then select **Save Changes**.
>
> You need the **Edit** permission on **Audit Logs**, which the admin role has.

> [tab] For a project
>
> These settings cover only the project's events.
>
> **Step 1**
>
> Open the project, go to **Audit Logs**, and select the **Settings** tab.
>
> **Step 2**
>
> Under **Event Classes**, turn a class on or off, then select **Save Changes**.
>
> You need the **Edit** permission on **Audit Logs**, which the admin role has.

> [tab] API
>
> Update the organization's classes with [the organization audit log settings endpoint](https://infisical.com/docs/api-reference/endpoints/audit-logs/update-organization-audit-log-settings.md), or one project's classes with [the project audit log settings endpoint](https://infisical.com/docs/api-reference/endpoints/audit-logs/update-project-audit-log-settings.md). The request replaces the current settings, so include both `authentication` and `authorization`.
>
> ```bash theme={"dark"}
> curl -X PUT "https://app.infisical.com/api/v1/organization/audit-log-settings" \
>   -H "Authorization: Bearer <your-access-token>" \
>   -H "Content-Type: application/json" \
>   -d '{
>     "eventClasses": [
>       {"eventClass": "authentication", "isEnabled": true},
>       {"eventClass": "authorization", "isEnabled": false}
>     ]
>   }'
> ```

> [!NOTE]
>
> Any changes you make apply to new events within 10 minutes. Events already in the log aren't affected.

### Permission denials

If you [turn authorization events on](#choose-which-classes-to-record), Infisical records a `permission-denied` event whenever a user or machine identity tries an action its role doesn't allow. The event's metadata includes:

| Field | What it contains |
| - | - |
| `permissionAction` | The action the role didn't allow, such as `create` |
| `permissionSubject` | The resource type the action was on, such as `secrets` |
| `permissionSubjectDetails` | The resource the actor targeted, such as an environment and secret path |
| `route` | The endpoint the actor called |
| `method` | The HTTP method of the request |
| `projectId` | The project the request was for, if it had one |

> [!NOTE]
>
> If the same denial repeats within a minute, Infisical records it once, then records one summary event with the number of repeats in `suppressedRepeats`. The summary's `suppressedFrom` and `suppressedUntil` fields give the start and end of the interval covered by that count.

## Filtering audit logs

You can filter audit logs to find events more easily. When you set more than one filter, an event needs to match all of them to appear in the results.

> [!NOTE]
>
> Every filter is an exact match, so wildcards like `*` aren't supported.

### By date

> [tab] Infisical UI
>
> Use the date range buttons at the top of the audit logs page. The page defaults to the last hour on load. Presets include 1 day, 1 week, 1 month, and 3 months, and the custom picker takes any range up to 3 months.

> [tab] API
>
> Pass `startDate` and `endDate` as ISO 8601 timestamps, up to 3 months apart. If you omit `startDate`, the endpoint defaults to the previous day at 00:00 UTC; if you omit `endDate`, it defaults to now.
>
> ```bash theme={"dark"}
> curl -G "https://app.infisical.com/api/v1/organization/audit-logs" \
>   -H "Authorization: Bearer <your-access-token>" \
>   --data-urlencode "startDate=2026-01-01T00:00:00Z" \
>   --data-urlencode "endDate=2026-01-31T23:59:59Z"
> ```

### Advanced filters

> [tab] Infisical UI
>
> Select **Search audit logs** from the audit logs menu and choose the filter you want to add:
>
> | Filter | Matches | Requires |
> | - | - | - |
> | `event` | One or more event types (for example, `create-secret`, `update-secret`) | |
> | `class` | One or more [event classes](#event-classes) (for example, `data-access`, `authorization`) | |
> | `actor` | The actor type (for example, `user`, `identity`, `platform`, `kmipClient`, `scimClient`, and so on) | |
> | `actor_id` | A specific actor ID | `actor` set to a type that carries an ID (see below) |
> | `source` | The client that made the request: `web`, `cli`, `k8-operator`, `terraform`, an SDK, or `other` | |
> | `project` | A single project | |
> | `environment` | An environment slug in that project (for example, `prod`) | `project`; applies to secret events only |
> | `secret_path` | The folder path a secret event touched (for example, `/db`) | `project`; applies to secret events only |
> | `secret_key` | The exact key name a secret event touched (for example, `DATABASE_URL`) | `project`; applies to secret events only |

> [tab] API
>
> Pass filters as query parameters to `GET /api/v1/organization/audit-logs`:
>
> | Parameter | Matches | Requires |
> | - | - | - |
> | `eventType` | One or more event types, comma-separated (for example, `create-secret,update-secret`) | |
> | `eventClass` | One or more [event classes](#event-classes), comma-separated (for example, `data-access,authorization`) | |
> | `actorType` | The actor type (for example, `user`, `identity`, `platform`, `kmipClient`, `scimClient`) | |
> | `actor` | A specific actor ID | `actorType` set to a type that carries an ID (see below) |
> | `userAgentType` | The client that made the request: `web`, `cli`, `k8-operator`, `terraform`, an SDK, or `other` | |
> | `projectId` | A single project | |
> | `environment` | An environment slug in that project (for example, `prod`) | `projectId`; applies to secret events only |
> | `secretPath` | The folder path a secret event touched (for example, `/db`) | `projectId`; applies to secret events only |
> | `secretKey` | The exact key name a secret event touched (for example, `DATABASE_URL`) | `projectId`; applies to secret events only |
> | `eventMetadata` | A key/value pair inside `event.metadata`. See [Filtering by event metadata](#filtering-by-event-metadata). | |

> [!NOTE]
>
> Actor ID filtering is only supported for actor types that carry an ID: `user`, `identity`, `service`, `kmipClient`, `kmipServer`, `gateway`, `relay`, `agentVaultProxy`, `acmeProfile`, `acmeAccount`, `estAccount`, and `scepAccount`.
>
> `platform`, `scimClient`, and `unknownUser` don't have an ID field and can only be filtered by type.

### Special characters

Every filter compares the raw string value as-is, so filter values that contain `$`, `.`, `/`, `@`, or any other special character work without escaping.

For example, to filter for a secret key named `$DB/PROD.URL`:

```bash theme={"dark"}
curl -G "https://app.infisical.com/api/v1/organization/audit-logs" \
  -H "Authorization: Bearer <your-access-token>" \
  --data-urlencode "projectId=<project-id>" \
  --data-urlencode "eventType=get-secret" \
  --data-urlencode "secretKey=\$DB/PROD.URL"
```

In the above example, `\$` is only there to stop the shell from expanding `$DB` as a variable. The filter itself takes `$DB/PROD.URL` as-is.

### Filtering by event metadata

The API accepts an `eventMetadata` query parameter that matches key/value pairs inside `event.metadata`. Pass it as `key1=value1,key2=value2`. Every pair has to match on the same event.

Use it for queries the built-in filters can't express, like every login for a specific identity, or every secret sync run for a specific destination:

```bash theme={"dark"}
curl -G "https://app.infisical.com/api/v1/organization/audit-logs" \
  -H "Authorization: Bearer <your-access-token>" \
  --data-urlencode "eventType=login-identity-universal-auth" \
  --data-urlencode "eventMetadata=identityId=<identity-id>"
```

> [!NOTE]
>
> Values that contain a literal `,` can't be filtered this way, because `,` separates the pairs. Values with `=` work: only the first `=` in each pair is treated as the separator, so the rest of the string passes through.

## Common filters

Here are a few common patterns for filtering audit logs, grouped by product.

### Secrets Management

> [accordion] Who read a specific secret
>
> Find every read of `DATABASE_URL` in the `prod` environment.
>
> > [tab] Infisical UI
> >
> > **Step 1**
> >
> > Go to **Organization > Audit Logs**.
> >
> > **Step 2**
> >
> > Select **Search audit logs** and add these filters:
> >
> > * `event`: `get-secret`
> > * `project`: the project holding the secret
> > * `environment`: `prod`
> > * `secret_key`: `DATABASE_URL`
>
> > [tab] API
> >
> > ```bash theme={"dark"}
> > curl -G "https://app.infisical.com/api/v1/organization/audit-logs" \
> >   -H "Authorization: Bearer <your-access-token>" \
> >   --data-urlencode "projectId=<project-id>" \
> >   --data-urlencode "environment=prod" \
> >   --data-urlencode "eventType=get-secret" \
> >   --data-urlencode "secretKey=DATABASE_URL"
> > ```

> [accordion] Who opened a folder
>
> Find every time someone loaded the secrets in the `/db` folder — for example, by opening it in the web UI, running `infisical secrets-manager secrets`, or having an app fetch it at startup. Each event records the folder, the actor, and how many secrets came back.
>
> > [tab] Infisical UI
> >
> > **Step 1**
> >
> > Go to **Organization > Audit Logs**.
> >
> > **Step 2**
> >
> > Select **Search audit logs** and add these filters:
> >
> > * `event`: `get-secrets`
> > * `project`: the project holding the folder
> > * `environment`: `prod`
> > * `secret_path`: `/db`
>
> > [tab] API
> >
> > ```bash theme={"dark"}
> > curl -G "https://app.infisical.com/api/v1/organization/audit-logs" \
> >   -H "Authorization: Bearer <your-access-token>" \
> >   --data-urlencode "projectId=<project-id>" \
> >   --data-urlencode "environment=prod" \
> >   --data-urlencode "eventType=get-secrets" \
> >   --data-urlencode "secretPath=/db"
> > ```

> [accordion] All writes to production
>
> Find every creation, update, and deletion of secrets in a project's `prod` environment over the last 7 days.
>
> > [tab] Infisical UI
> >
> > **Step 1**
> >
> > Go to **Organization > Audit Logs**.
> >
> > **Step 2**
> >
> > Set the date range to the last 7 days.
> >
> > **Step 3**
> >
> > Select **Search audit logs** and add these filters:
> >
> > * `event`: `create-secret`, `update-secret`, `delete-secret`, `create-secrets`, `update-secrets`, `delete-secrets`
> > * `project`: the project you want to audit
> > * `environment`: `prod`
> >
> > Include the batch event types (`create-secrets`, `update-secrets`, `delete-secrets`) so that bulk changes from the CLI or SDKs aren't missed. The `environment` filter only applies when a project is set.
>
> > [tab] API
> >
> > Replace `<start-date>` with an ISO 8601 timestamp for 7 days ago (for example, `2026-09-15T00:00:00Z`).
> >
> > ```bash theme={"dark"}
> > curl -G "https://app.infisical.com/api/v1/organization/audit-logs" \
> >   -H "Authorization: Bearer <your-access-token>" \
> >   --data-urlencode "projectId=<project-id>" \
> >   --data-urlencode "environment=prod" \
> >   --data-urlencode "eventType=create-secret,update-secret,delete-secret,create-secrets,update-secrets,delete-secrets" \
> >   --data-urlencode "startDate=<start-date>"
> > ```
> >
> > Include the batch event types (`create-secrets`, `update-secrets`, `delete-secrets`) so that bulk changes from the CLI or SDKs aren't missed.

> [accordion] Who deleted a secret
>
> Find who removed a specific secret key. Include the batch event so single and bulk deletes are both matched.
>
> > [tab] Infisical UI
> >
> > **Step 1**
> >
> > Go to **Organization > Audit Logs**.
> >
> > **Step 2**
> >
> > Select **Search audit logs** and add these filters:
> >
> > * `event`: `delete-secret`, `delete-secrets`
> > * `project`: the project holding the secret
> > * `secret_key`: the key that was deleted
> >
> > Read the actor column on each result to see who ran the delete. The `secret_key` filter only applies when a project is set.
>
> > [tab] API
> >
> > ```bash theme={"dark"}
> > curl -G "https://app.infisical.com/api/v1/organization/audit-logs" \
> >   -H "Authorization: Bearer <your-access-token>" \
> >   --data-urlencode "projectId=<project-id>" \
> >   --data-urlencode "eventType=delete-secret,delete-secrets" \
> >   --data-urlencode "secretKey=DATABASE_URL"
> > ```
> >
> > Read `actor.type` and `actor.metadata` on each result to see who ran the delete.

### Certificate Management

> [accordion] Recent certificate issuance
>
> Find every certificate issued from a project in the last 7 days.
>
> > [!NOTE]
> >
> > Externally-issued certificates (from a linked external CA) don't emit an issuance audit event when Infisical attaches the certificate. The `order-certificate-from-profile` event captures the request at submit time (typically with `event.metadata.status = pending`), and Infisical doesn't update the audit row later. To confirm which orders resulted in issued certificates, check the certificate list in **Certificate Manager**.
>
> > [tab] Infisical UI
> >
> > **Step 1**
> >
> > Go to **Certificate Manager**, select the project, and open **Audit Logs**.
> >
> > **Step 2**
> >
> > Set the date range to the last 7 days.
> >
> > **Step 3**
> >
> > Select **Search audit logs** and add:
> >
> > * `event`: `issue-cert`, `issue-pki-subscriber-cert`, `issue-certificate-from-profile`
> >
> > The returned `event.metadata` varies by issuance path:
> >
> > * `issue-cert` records the certificate authority (CA), its distinguished name (DN), and serial number
> > * Subscriber and profile events record the subscriber or profile ID and common name, with the serial number added once the certificate is issued
>
> > [tab] API
> >
> > ```bash theme={"dark"}
> > curl -G "https://app.infisical.com/api/v1/organization/audit-logs" \
> >   -H "Authorization: Bearer <your-access-token>" \
> >   --data-urlencode "projectId=<project-id>" \
> >   --data-urlencode "eventType=issue-cert,issue-pki-subscriber-cert,issue-certificate-from-profile" \
> >   --data-urlencode "startDate=<start-date>"
> > ```

> [accordion] Why a certificate failed to issue
>
> Find every certificate that Infisical couldn't issue, and the reason for each failure.
>
> Infisical records a `certificate-issuance-failed` event for certificates requested from a certificate profile through the API or the Infisical UI, ACME, EST, and SCEP, including renewals and certificates issued after an approval.
>
> > [!NOTE]
> >
> > If an automatic renewal fails before Infisical sends it to an external CA, Infisical records an `automated-renew-certificate-failed` event instead. Infisical doesn't record `certificate-issuance-failed` for EST enrollment through a certificate template, for EST requests rejected before Infisical reads the CSR (such as a failed sign-in or a rejected client certificate), or for requests the actor's role doesn't allow, which are recorded as [`permission-denied` events](#permission-denials).
>
> > [tab] Infisical UI
> >
> > **Step 1**
> >
> > In **Certificate Manager**, open **Audit Logs**.
> >
> > **Step 2**
> >
> > Select **Search audit logs** and add:
> >
> > * `event`: `certificate-issuance-failed`
>
> > [tab] API
> >
> > This request returns failures from across your organization, so the access token needs permission to read the organization's audit logs.
> >
> > ```bash theme={"dark"}
> > curl -G "https://app.infisical.com/api/v1/organization/audit-logs" \
> >   -H "Authorization: Bearer <your-access-token>" \
> >   --data-urlencode "eventType=certificate-issuance-failed"
> > ```
>
> The `event.metadata` of each result records which certificate failed and why:
>
> * `operation`: what was requested (`issue`, `sign`, `order`, or `renew`)
> * `enrollmentType`: how the certificate was requested (`api`, `acme`, `est`, or `scep`)
> * `error` and `errorName`: why issuance failed, such as a TTL longer than the certificate policy allows or an error from the CA
> * `certificateProfileId`, `profileName`, `caId`, `caName`, `commonName`, `applicationId`, and `applicationName`: the certificate the request was for, where Infisical knows them
> * `certificateRequestId`: the certificate request that failed, if Infisical had already created one
> * `originalCertificateId`: on a failed renewal, the certificate being renewed
> * `suppressedRepeats`, `suppressedFrom`, and `suppressedUntil`: on a summary event, how many identical failures Infisical counted instead of recording, and the minute they fell in
>
> The event's actor is `platform` if issuance fails after the original request has returned. That happens in two cases: an external CA, such as DigiCert or AWS Private CA, fails the order in the background, or issuance fails once an approver approves the request. An approved request for an external CA goes through the same background step. To find who requested a certificate through the API or the Infisical UI, filter by the original event, such as `order-certificate-from-profile`, and match the `certificateRequestId`.
>
> Infisical counts identical failures the same way it counts [repeated denials](#permission-denials). In each minute, it records the first failure with a given actor, operation, certificate, and error, then writes one summary event when the minute ends.

> [accordion] Who revoked a certificate
>
> Find every revocation in a project.
>
> > [tab] Infisical UI
> >
> > **Step 1**
> >
> > Go to **Certificate Manager**, select the project, and open **Audit Logs**.
> >
> > **Step 2**
> >
> > Select **Search audit logs** and add:
> >
> > * `event`: `revoke-cert`
> >
> > Read the actor column on each result to see who ran the revocation.
>
> > [tab] API
> >
> > ```bash theme={"dark"}
> > curl -G "https://app.infisical.com/api/v1/organization/audit-logs" \
> >   -H "Authorization: Bearer <your-access-token>" \
> >   --data-urlencode "projectId=<project-id>" \
> >   --data-urlencode "eventType=revoke-cert"
> > ```

### Key Management Service (KMS)

> [accordion] Recent key use
>
> Find every encryption, decryption, signature, and verification against KMS keys in a project.
>
> > [tab] Infisical UI
> >
> > **Step 1**
> >
> > Go to **KMS**, select the project, and open **Audit Logs**.
> >
> > **Step 2**
> >
> > Select **Search audit logs** and add:
> >
> > * `event`: `cmek-encrypt`, `cmek-decrypt`, `cmek-sign`, `cmek-verify`
> >
> > To narrow the results to a specific key, read `event.metadata.keyId` on each row.
>
> > [tab] API
> >
> > `cmek-*` events carry `keyId` in `event.metadata`, so match it with `eventMetadata` to scope to a specific key.
> >
> > ```bash theme={"dark"}
> > curl -G "https://app.infisical.com/api/v1/organization/audit-logs" \
> >   -H "Authorization: Bearer <your-access-token>" \
> >   --data-urlencode "projectId=<project-id>" \
> >   --data-urlencode "eventType=cmek-encrypt,cmek-decrypt,cmek-sign,cmek-verify" \
> >   --data-urlencode "eventMetadata=keyId=<kms-key-id>"
> > ```

> [accordion] Key lifecycle changes
>
> Find every KMS key created, updated, or deleted in a project.
>
> > [tab] Infisical UI
> >
> > **Step 1**
> >
> > Go to **KMS**, select the project, and open **Audit Logs**.
> >
> > **Step 2**
> >
> > Select **Search audit logs** and add:
> >
> > * `event`: `create-cmek`, `update-cmek`, `delete-cmek`
>
> > [tab] API
> >
> > ```bash theme={"dark"}
> > curl -G "https://app.infisical.com/api/v1/organization/audit-logs" \
> >   -H "Authorization: Bearer <your-access-token>" \
> >   --data-urlencode "projectId=<project-id>" \
> >   --data-urlencode "eventType=create-cmek,update-cmek,delete-cmek"
> > ```

### Secret Scanning

> [accordion] Recent scan runs
>
> Find every completed scan run in the last 7 days (both scheduled and on-demand). Each row represents one run, and `event.metadata` records the data source, the scan type, and the status. Successful runs also include `numberOfSecretsDetected`.
>
> > [tab] Infisical UI
> >
> > **Step 1**
> >
> > Go to **Secret Scanning**, select the project, and open **Audit Logs**.
> >
> > **Step 2**
> >
> > Set the date range to the last 7 days.
> >
> > **Step 3**
> >
> > Select **Search audit logs** and add:
> >
> > * `event`: `secret-scanning-data-source-scan`
> >
> > To also see the request rows for on-demand scans (which fire before the run completes), add `secret-scanning-data-source-trigger-scan` to the `event` filter. On-demand scans then appear twice: once as a trigger and once as a completed run.
>
> > [tab] API
> >
> > ```bash theme={"dark"}
> > curl -G "https://app.infisical.com/api/v1/organization/audit-logs" \
> >   -H "Authorization: Bearer <your-access-token>" \
> >   --data-urlencode "projectId=<project-id>" \
> >   --data-urlencode "eventType=secret-scanning-data-source-scan" \
> >   --data-urlencode "startDate=<start-date>"
> > ```
> >
> > Add `secret-scanning-data-source-trigger-scan` to `eventType` to also see the request rows for on-demand scans. On-demand scans then appear twice: once as a trigger and once as a completed run.

> [accordion] Finding updates
>
> View every finding an operator marked as remediated, dismissed, or otherwise updated.
>
> > [tab] Infisical UI
> >
> > **Step 1**
> >
> > Go to **Secret Scanning**, select the project, and open **Audit Logs**.
> >
> > **Step 2**
> >
> > Select **Search audit logs** and add:
> >
> > * `event`: `secret-scanning-finding-update`
>
> > [tab] API
> >
> > ```bash theme={"dark"}
> > curl -G "https://app.infisical.com/api/v1/organization/audit-logs" \
> >   -H "Authorization: Bearer <your-access-token>" \
> >   --data-urlencode "projectId=<project-id>" \
> >   --data-urlencode "eventType=secret-scanning-finding-update"
> > ```

### Privileged Access Management (PAM)

> [accordion] All privileged sessions this week
>
> Find every session start, end, or termination in the last 7 days.
>
> > [tab] Infisical UI
> >
> > **Step 1**
> >
> > Go to **PAM > Audit Logs**.
> >
> > **Step 2**
> >
> > Set the date range to the last 7 days.
> >
> > **Step 3**
> >
> > Select **Search audit logs** and add:
> >
> > * `event`: `pam-session-start`, `pam-session-end`, `pam-session-terminate`
>
> > [tab] API
> >
> > The PAM project ID isn't exposed publicly, so call the organization endpoint and filter by exact event names.
> >
> > ```bash theme={"dark"}
> > curl -G "https://app.infisical.com/api/v1/organization/audit-logs" \
> >   -H "Authorization: Bearer <your-access-token>" \
> >   --data-urlencode "eventType=pam-session-start,pam-session-end,pam-session-terminate" \
> >   --data-urlencode "startDate=<start-date>"
> > ```

> [accordion] Who accessed a specific PAM account
>
> View all access to a PAM account using its account ID.
>
> > [tab] Infisical UI
> >
> > **Step 1**
> >
> > Go to **PAM > Audit Logs**.
> >
> > **Step 2**
> >
> > Select **Search audit logs** and add:
> >
> > * `event`: `pam-account-access`, `pam-account-credentials-view`
> >
> > Each result's `event.metadata.accountId` names the account and `actor` names the accessor.
>
> > [tab] API
> >
> > `pam-account-access` events carry `accountId` in `event.metadata`, so match it with `eventMetadata`.
> >
> > ```bash theme={"dark"}
> > curl -G "https://app.infisical.com/api/v1/organization/audit-logs" \
> >   -H "Authorization: Bearer <your-access-token>" \
> >   --data-urlencode "eventType=pam-account-access,pam-account-credentials-view" \
> >   --data-urlencode "eventMetadata=accountId=<pam-account-id>"
> > ```

### Agent Vault

> [accordion] Sessions issued this week
>
> Find every session created or revoked in an Agent Vault project over the last 7 days.
>
> > [tab] Infisical UI
> >
> > **Step 1**
> >
> > In your Agent Vault project, go to **Audit Logs**.
> >
> > **Step 2**
> >
> > Set the date range to the last 7 days.
> >
> > **Step 3**
> >
> > Select **Search audit logs** and add:
> >
> > * `event`: `agent-vault-session-mint`, `agent-vault-session-revoke`
>
> > [tab] API
> >
> > ```bash theme={"dark"}
> > curl -G "https://app.infisical.com/api/v1/organization/audit-logs" \
> >   -H "Authorization: Bearer <your-access-token>" \
> >   --data-urlencode "projectId=<project-id>" \
> >   --data-urlencode "eventType=agent-vault-session-mint,agent-vault-session-revoke" \
> >   --data-urlencode "startDate=<start-date>"
> > ```

> [accordion] Proxy lifecycle events
>
> Find every proxy registration, token rotation, and revocation in an Agent Vault project.
>
> > [tab] Infisical UI
> >
> > **Step 1**
> >
> > In your Agent Vault project, go to **Audit Logs**.
> >
> > **Step 2**
> >
> > Select **Search audit logs** and add:
> >
> > * `event`: `agent-vault-proxy-register`, `agent-vault-proxy-token-rotate`, `agent-vault-proxy-revoke`, `agent-vault-proxy-delete`
>
> > [tab] API
> >
> > ```bash theme={"dark"}
> > curl -G "https://app.infisical.com/api/v1/organization/audit-logs" \
> >   -H "Authorization: Bearer <your-access-token>" \
> >   --data-urlencode "projectId=<project-id>" \
> >   --data-urlencode "eventType=agent-vault-proxy-register,agent-vault-proxy-token-rotate,agent-vault-proxy-revoke,agent-vault-proxy-delete"
> > ```

### Identities and authentication

> [accordion] Everything a specific identity did
>
> Investigate every action a machine identity took.
>
> > [tab] Infisical UI
> >
> > **Step 1**
> >
> > Go to **Organization > Audit Logs**.
> >
> > **Step 2**
> >
> > Select **Search audit logs** and add these filters:
> >
> > * `actor`: `identity`
> > * `actor_id`: the identity's ID
>
> > [tab] API
> >
> > ```bash theme={"dark"}
> > curl -G "https://app.infisical.com/api/v1/organization/audit-logs" \
> >   -H "Authorization: Bearer <your-access-token>" \
> >   --data-urlencode "actor=<identity-id>" \
> >   --data-urlencode "actorType=identity"
> > ```
> >
> > Set `actorType` for any non-user actor so the filter targets the right ID column. Only actor types with an ID field can be filtered this way; see the note under [Advanced filters](#advanced-filters) for the full list.

> [accordion] Failed login attempts for an identity
>
> Find failed login attempts by a machine identity, across every auth method.
>
> > [tab] Infisical UI
> >
> > **Step 1**
> >
> > Go to **Organization > Audit Logs**.
> >
> > **Step 2**
> >
> > Select **Search audit logs** and add these filters:
> >
> > * `event`: `login-identity-universal-auth-failed`, `login-identity-kubernetes-auth-failed`, `login-identity-oidc-auth-failed`, `login-identity-gcp-auth-failed`, `login-identity-aws-auth-failed`, `login-identity-jwt-auth-failed`
> > * `actor`: `identity`
> > * `actor_id`: the identity's ID
> >
> > Extend the `event` list to include any other `*-failed` variants your organization uses (SPIFFE, LDAP, AliCloud, and so on).
>
> > [tab] API
> >
> > ```bash theme={"dark"}
> > curl -G "https://app.infisical.com/api/v1/organization/audit-logs" \
> >   -H "Authorization: Bearer <your-access-token>" \
> >   --data-urlencode "eventType=login-identity-universal-auth-failed,login-identity-kubernetes-auth-failed,login-identity-oidc-auth-failed,login-identity-gcp-auth-failed,login-identity-aws-auth-failed,login-identity-jwt-auth-failed" \
> >   --data-urlencode "actor=<identity-id>" \
> >   --data-urlencode "actorType=identity"
> > ```

## Event types

Infisical emits hundreds of event types. Here are some of the most common ones you'll encounter.

> [accordion] Secrets
>
> | Event | When it fires |
> | - | - |
> | `get-secret` | A caller read a specific secret. |
> | `get-secrets` | A caller listed the secrets in a folder. |
> | `reveal-secret` | A user revealed a secret value in the UI. |
> | `create-secret`, `create-secrets` | A caller created a secret (single or batch). |
> | `update-secret`, `update-secrets` | A caller edited a secret (single or batch). |
> | `delete-secret`, `delete-secrets` | A caller deleted a secret (single or batch). |
> | `move-secrets` | A user moved secrets to another folder or environment. |
> | `duplicate-secret` | A user copied a secret to another folder or environment. |
> | `redact-secret-version-value` | An admin redacted a value from a secret's version history. |

> [accordion] Identities and authentication
>
> | Event | When it fires |
> | - | - |
> | `user-login` | A user signed in through SAML, OIDC, or LDAP. Infisical doesn't record this event for password, Google, GitHub, or GitLab sign-ins, for failed sign-ins, or for a sign-in where the user still has to finish creating their account or verify their email. For SAML and OIDC, `idpMfa` in the metadata shows whether the identity provider reported MFA, as described in [MFA for SSO logins](https://infisical.com/docs/documentation/platform/mfa.md#mfa-for-sso-logins). |
> | `create-identity`, `update-identity`, `delete-identity` | A machine identity was added, edited, or removed. |
> | `login-identity-*` (for example, `login-identity-universal-auth`, `login-identity-kubernetes-auth`, `login-identity-oidc-auth`, `login-identity-gcp-auth`, `login-identity-aws-auth`) | A machine identity authenticated. |
> | `login-identity-*-failed` | A machine identity's authentication attempt failed. |
> | `create-identity-universal-auth-client-secret`, `revoke-identity-universal-auth-client-secret` | A universal-auth client secret was issued or revoked. |
> | `clear-identity-universal-auth-lockouts`, `clear-identity-ldap-auth-lockouts` | An admin cleared a machine identity's lockout. |

> [accordion] Projects and access
>
> | Event | When it fires |
> | - | - |
> | `create-project`, `update-project`, `delete-project` | A project was created, edited, or deleted. |
> | `create-identity-project-membership`, `update-identity-project-membership`, `delete-identity-project-membership` | A machine identity joined, changed role in, or left a project. |
> | `update-user-org-membership`, `delete-user-org-membership` | A user's role or membership in the organization changed. |
> | `invite-org-members` | Users were invited to the organization, optionally with access to projects. |

> [accordion] Integrations and secret sync
>
> | Event | When it fires |
> | - | - |
> | `create-integration`, `delete-integration`, `manual-sync-integration` | A legacy integration was added, removed, or manually re-synced. |
> | `create-secret-sync`, `update-secret-sync`, `delete-secret-sync` | A user configured a secret sync destination. |
> | `secret-sync-sync-secrets`, `secret-sync-import-secrets`, `secret-sync-remove-secrets` | A sync run pushed, imported, or removed secrets from its destination. |

> [accordion] Approvals
>
> | Event | When it fires |
> | - | - |
> | `approval-request-create`, `approval-request-approve`, `approval-request-reject`, `approval-request-cancel` | The lifecycle of an approval request. |
> | `access-approval-request-create`, `access-approval-request-review`, `access-approval-request-update`, `access-approval-request-revoke` | The lifecycle of an access approval request. |
> | `access-approval-request-delegated-dispatch-retry` | A user retried an access approval request that never reached its external approval system, such as [ServiceNow](https://infisical.com/docs/documentation/platform/workflow-integrations/servicenow-integration.md). |
> | `access-approval-request-delegated-decision` | Infisical applied, or failed to apply, a decision that an external approval system such as ServiceNow returned for an access approval request. The event's actor is `platform`. |
> | `access-approval-request-cancel` | A user cancelled a pending access approval request that its external approval system was reviewing. |
> | `secret-approval-request`, `secret-approval-request-review`, `secret-approval-merged`, `secret-approval-closed`, `secret-approval-reopened` | The lifecycle of a secret change request. |
> | `approval-policy-create`, `approval-policy-update`, `approval-policy-delete` | An admin changed an approval policy. |

> [accordion] Authorization
>
> | Event | When it fires |
> | - | - |
> | `permission-denied` | A user or machine identity was refused an action its role doesn't allow. See [Permission denials](#permission-denials). |

> [accordion] Audit logs
>
> | Event | When it fires |
> | - | - |
> | `view-audit-logs` | A user opened the audit log viewer. |
> | `update-audit-log-settings` | An admin changed which event classes an organization or project records, or how long a project keeps its audit logs. |
> | `create-audit-report`, `get-audit-report`, `get-audit-reports`, `delete-audit-report` | A user managed a project-level audit report. |
> | `create-org-audit-report`, `get-org-audit-reports`, `delete-org-audit-report` | A user managed an organization-level audit report. |

For the full event catalog and every field the API accepts, see the [audit log export API reference](https://infisical.com/docs/api-reference/endpoints/audit-logs/export-audit-log.md).

## Next steps

> [card] [Stream audit logs](https://infisical.com/docs/documentation/platform/audit-log-streams/audit-log-streams.md)
>
> Forward audit logs to a SIEM, storage bucket, or observability stack.

> [card] [ClickHouse storage backend](https://infisical.com/docs/documentation/platform/audit-logs-clickhouse-setup.md)
>
> Keep queries fast when a self-hosted audit log table grows to hundreds of millions of rows.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.