> ## 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.

# Store PAM session recordings externally

> Store session recordings in an S3-compatible bucket that you own.

By default, Infisical stores [session recordings](https://infisical.com/docs/documentation/platform/pam/sessions/session-recording.md) in its own database. If you need to control where recordings are kept and for how long, such as for data residency or compliance, store them in your own S3-compatible bucket instead.

Windows and Windows AD accounts require a bucket. Until their [template](https://infisical.com/docs/documentation/platform/pam/templates/overview.md) uses one, you can create these accounts but can't launch sessions on them.

## Supported providers

| Provider | Endpoint | Access key |
| - | - | - |
| AWS S3 | `https://s3.<region>.amazonaws.com` | An IAM user with the [required permissions](#bucket-permissions) |
| Cloudflare R2 | `https://<account-id>.r2.cloudflarestorage.com` | An R2 API token with **Object Read & Write** on the bucket |
| Google Cloud Storage | `https://storage.googleapis.com` | An HMAC key for a service account with **Storage Object User** on the bucket |
| OCI Object Storage | `https://<namespace>.compat.objectstorage.<region>.oraclecloud.com` | A customer secret key for a user who can `inspect buckets` and `manage objects` |

If you self-host Infisical, you can also store recordings on your own S3-compatible server, such as MinIO, after a server admin adds its hostname under [Allowed storage hostnames](https://infisical.com/docs/documentation/platform/admin-panel/server-admin.md#allowed-storage-hostnames).

## Prerequisites

* A bucket from one of the [supported providers](#supported-providers)
* The **Product Admin** [role](https://infisical.com/docs/documentation/platform/pam/concepts/access-control.md) in PAM, to edit templates

## Step 1: Prepare the bucket

### Connection

Infisical writes to the bucket with the credentials of an app connection in your organization. For AWS S3, you can use an [AWS connection](https://infisical.com/docs/integrations/app-connections/aws.md) whose credentials have the [permissions on the bucket](#bucket-permissions).

For any supported provider, including AWS S3, you can create an S3-Compatible Storage connection instead:

**Step 1**

Go to **Integrations** > **App Connections**, select **Add Connection**, and select **S3-Compatible Storage**.

**Step 2**

Enter the endpoint and access key for your provider from [Supported providers](#supported-providers).

### Bucket permissions

For AWS S3, give the connection's credentials these permissions, replacing `<bucket-name>` with the name of your bucket:

```json theme={"dark"}
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["s3:PutObject", "s3:GetObject", "s3:DeleteObject"],
      "Resource": "arn:aws:s3:::<bucket-name>/*"
    },
    {
      "Effect": "Allow",
      "Action": "s3:ListBucket",
      "Resource": "arn:aws:s3:::<bucket-name>"
    }
  ]
}
```

When you save a template, Infisical writes a test object to the bucket and then deletes it, to check that it can store recordings there.

### CORS policy

Your browser downloads recordings directly from the bucket when you view a session, so the bucket needs a CORS policy that allows requests from Infisical:

```json theme={"dark"}
[
  {
    "AllowedHeaders": ["*"],
    "AllowedMethods": ["GET"],
    "AllowedOrigins": ["https://app.infisical.com"],
    "MaxAgeSeconds": 3600
  }
]
```

If you use a different Infisical URL, such as `https://eu.infisical.com` or your own domain, replace `https://app.infisical.com` with that URL.

Where you add the policy depends on the provider:

* **AWS S3:** Open the bucket in the AWS console, go to **Permissions** > **Cross-origin resource sharing (CORS)**, select **Edit**, and paste the policy
* **Cloudflare R2:** Paste the same policy under the bucket's **Settings** > **CORS Policy**
* **Google Cloud Storage:** [Configure CORS](https://cloud.google.com/storage/docs/using-cors) with the same origin and the `GET` method
* **OCI Object Storage:** No policy needed, because OCI allows requests from any origin

## Step 2: Configure the template

Each template sets the storage for every account that uses it, so you can use different buckets for different templates.

**Step 1**

Go to **Privileged Access Management** > **Account Templates** and select the template.

**Step 2**

On the **General** tab, under **Session Recording**, set **Storage backend** to **S3 Bucket**.

**Step 3**

Fill in the bucket details:

* **Connection**: The AWS or S3-Compatible Storage connection with access to the bucket
* **S3 Bucket**: The name of the bucket
* **Region**: The bucket's AWS region, such as `us-east-1` (only for an AWS connection)
* **Key prefix (optional)**: A folder in the bucket to store recordings in, such as `pam-recordings/`

**Step 4**

Select **Save Changes**.

If Infisical can't reach the bucket, the template isn't saved and the error message says which permission is missing. If the bucket has no CORS policy that allows your Infisical URL, Infisical saves the template and shows a **Bucket CORS not configured** warning.

> [!WARNING]
>
> If you change the template's bucket, you can't view the recordings in the old bucket until you copy their objects to the new bucket. Keep each object's key the same when you copy it, since Infisical looks for each recording at the key it was saved under.
>
> If you only change the key prefix, the recordings that were already stored keep working. Don't move them to the new prefix, or Infisical won't be able to find them.

### Use a different bucket for one account

To store a Windows or Windows AD account's recordings in a different bucket from its template, [open the account's settings](https://infisical.com/docs/documentation/platform/pam/accounts/manage.md#open-an-account’s-settings), go to the **Advanced** tab, and select **Override** under **Recording Settings**.

The override only changes the bucket details, so the template's **Storage backend** must still be **S3 Bucket**. Other account types always use their template's storage.

## Managing retention

Infisical never deletes recordings from your bucket, so you decide how long to keep them. To delete or archive recordings after a set time, add a lifecycle rule to the bucket, such as an [S3 lifecycle rule](https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lifecycle-mgmt.html).

Infisical stores each session's recording under its own path in the bucket:

```text theme={"dark"}
<key-prefix>/<project-id>/<session-id>/
```

Once a lifecycle rule deletes a session's objects, you can't view that session's recording in Infisical.

The objects in the bucket are already encrypted when they arrive, because the [Gateway](https://infisical.com/docs/documentation/platform/gateways/overview.md) encrypts each part of the recording before it uploads it. You can also turn on server-side encryption on the bucket.


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