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

# Session logs

> Keep an encrypted record of every request an AI agent makes, stored by Infisical or in your own Amazon S3 bucket.

A session log is a record of every request an agent makes during a [session](https://infisical.com/docs/documentation/platform/agent-vault/sessions): the method, host, path, status code, and whether the proxy attached a credential. The [proxy](https://infisical.com/docs/documentation/platform/agent-vault/proxies.md) adds every request it receives to the session log, including requests to hosts that no [access bundle](https://infisical.com/docs/documentation/platform/agent-vault/access-bundles.md) covers.

The proxy encrypts the records before they leave your network, and Infisical stores them for you. If you self-host Infisical, your server administrator [sets up where Infisical stores them](https://infisical.com/docs/self-hosting/guides/session-log-storage.md).

## Viewing session logs

You can view a session's logs if you created the session or you're an Agent Vault admin, for up to 30 days after they're recorded if Infisical stores them (see [Retention](#retention)).

**In Infisical**

Go to **Sessions** and select **View Session Logs** on the session's row. You can filter and search the requests, and while the session is active, new requests appear as the proxy uploads them.

![The Session Logs sheet for an active session, listing each request's time, method, host, path, upstream status, and outcome](https://mintlify.s3.us-west-1.amazonaws.com/infisical/images/platform/agent-vault/session-logs-view.png)

**Through the API**

The API returns a session's logs as chunks. A chunk is one encrypted batch of [records](#what-gets-recorded) that a proxy uploaded.

**Step 1**

Call [the endpoint that lists session logs](https://infisical.com/docs/api-reference/endpoints/agent-vault-session-logs/list.md). It returns the newest chunks first. To get older chunks, call it again with the response's `nextCursor` as `cursor`.

> [!NOTE]
>
> If Infisical can't read session logs, the request fails with the error `AgentVaultSessionLogStorageUnavailable`, and the message says why.

**Step 2**

Download each chunk from its `presignedGetUrl` within 5 minutes, before the URL expires.

**Step 3**

Decrypt the chunk with AES-256-GCM. The key is `sessionLogs.sessionKey`, base64 decoded. The first 12 bytes of the chunk are the IV, and the last 16 bytes are the authentication tag. The associated data is the SHA-256 digest of `<sessionId>|<chunkId>|v1`.

**Step 4**

Parse the decrypted bytes as JSON. Each chunk holds an array of records, and `decision` holds the [outcome](#what-gets-recorded) in lowercase:

```json theme={"dark"}
{
  "ts": "2026-09-16T10:31:04.221Z",
  "seq": 8412,
  "proxyId": "<proxy-id>",
  "method": "POST",
  "host": "api.github.com",
  "port": "443",
  "path": "/repos/acme/web/issues",
  "status": 201,
  "decision": "brokered",
  "service": "github",
  "accessBundle": "code-review"
}
```

This Node.js script reads the newest page of a session's logs:

```javascript expandable theme={"dark"}
import { createDecipheriv, createHash } from "node:crypto";

const token = "<your-access-token>";
const sessionId = "<session-id>".toLowerCase();

const res = await fetch(`https://app.infisical.com/api/v1/agent-vault/sessions/${sessionId}/logs`, {
  headers: { Authorization: `Bearer ${token}` }
});
const { sessionLogs, chunks } = await res.json();

for (const chunk of chunks) {
  const body = Buffer.from(await (await fetch(chunk.presignedGetUrl)).arrayBuffer());

  const aad = createHash("sha256").update(`${sessionId}|${chunk.chunkId}|v1`).digest();
  const decipher = createDecipheriv(
    "aes-256-gcm",
    Buffer.from(sessionLogs.sessionKey, "base64"),
    body.subarray(0, 12)
  );
  decipher.setAAD(aad);
  decipher.setAuthTag(body.subarray(-16));
  const plaintext = Buffer.concat([decipher.update(body.subarray(12, -16)), decipher.final()]);

  console.log(JSON.parse(plaintext.toString("utf8")));
}
```

> [!NOTE]
>
> The script runs outside a browser, so CORS rules don't apply to it.

To receive new logs as they arrive, call [the endpoint that tails session logs](https://infisical.com/docs/api-reference/endpoints/agent-vault-session-logs/tail.md) without a cursor, then call it every few seconds with the previous response's `nextCursor`. Any response can repeat a chunk you already read, so skip any chunk whose `chunkId` and `proxyId` you've already read. If a chunk's download returns 404, the proxy may still be uploading it, so try again a few seconds later. If the download still returns 404 after about 2 minutes, stop retrying. If the proxy finishes the upload later, [the endpoint that lists session logs](https://infisical.com/docs/api-reference/endpoints/agent-vault-session-logs/list.md) returns the chunk.

To export every chunk, page through [the endpoint that lists session logs](https://infisical.com/docs/api-reference/endpoints/agent-vault-session-logs/list.md). The tail is for following new logs as they arrive.

## What gets recorded

Each request produces one record with:

| Field | What it holds |
| - | - |
| **Time** | When the request was made |
| **Method**, **Host**, **Path** | Where the request went, for example `POST api.github.com/repos/acme/web/issues` |
| **Upstream status** | The HTTP status code the API returned, such as `201`. For **Blocked** and **Error** requests, it's the status code the proxy returned, such as `403` or `502` |
| **Outcome** | What the proxy did with the request |
| **Service** | The service that matched the request, if any |

The outcome is one of four:

| Outcome | What happened |
| - | - |
| **Brokered** | A service matched and the proxy attached its credential to the request |
| **Passthrough** | No service matched, or the matching service has no credential. The proxy forwarded the request without a credential |
| **Blocked** | The proxy refused the request, for one of the reasons in [Blocked requests](https://infisical.com/docs/documentation/platform/agent-vault/proxies.md#blocked-requests) |
| **Error** | The proxy couldn't reach the destination host |

Request and response bodies, headers, and query strings aren't recorded.

## Storing session logs in your own S3 bucket

To keep session logs longer than 30 days, or in your own AWS account, store them in an Amazon S3 bucket you own. This is called external storage.

> [!NOTE]
>
> External storage is a paid feature.
>
> If you're using Infisical Cloud, it's available under the **Enterprise Tier**. If you're self-hosting Infisical, contact [sales@infisical.com](mailto:sales@infisical.com) to purchase an enterprise license to use it.

Infisical reaches your bucket through an [AWS app connection](https://infisical.com/docs/integrations/app-connections/aws.md), which signs in to AWS by assuming an IAM role you create.

You'll switch between Infisical and AWS during setup: Infisical generates the AWS policy for your bucket, you set up the bucket and role in AWS, and then you create the connection in Infisical with the role's ARN.

### Prerequisites

* The [Admin role](https://infisical.com/docs/documentation/platform/agent-vault/access-control.md) in Agent Vault
* An [Amazon S3 bucket](https://docs.aws.amazon.com/AmazonS3/latest/userguide/create-bucket-overview.html) to store the records in
* Permission in AWS to edit the bucket's CORS configuration, create IAM roles, and attach policies to them

### Step 1: Start in Infisical

**Step 1**

In Agent Vault, go to **Administration** > **Settings** and select **Configure** or **Set Up Session Logs** on the **Session Logs** card.

**Step 2**

Turn on **Enable**, then under **Storage**, select **External storage**.

**Step 3**

Enter the **Region** and **Bucket** of your S3 bucket.

**Step 4**

Optionally, enter a **Key Prefix** to store session logs under one path in a bucket you also use for other data.

**Step 5**

Select **View AWS Setup**. Infisical shows an **IAM policy** with your bucket and key prefix already filled in, so you can paste it into AWS as it is.

Leave the **Session Logs** dialog open. You'll fill in **AWS Connection** in [Step 3](#step-3-finish-in-infisical), after you create the role it uses. Open AWS in another browser tab.

### Step 2: Set up in AWS

#### Add a CORS rule to the bucket

Your browser downloads session logs directly from your bucket, so the bucket has to accept requests from Infisical. Add a CORS rule for Infisical to the bucket.

**Step 1**

In the Amazon S3 console, open the session logs bucket, go to **Permissions**, and select **Edit** under **Cross-origin resource sharing (CORS)**.

**Step 2**

Paste this rule, then select **Save changes**. If the bucket already has CORS rules, add this rule's object to the existing array instead of replacing it, so other applications that use the bucket keep working:

```json Infisical Cloud (US) theme={"dark"}
[
    {
        "AllowedHeaders": ["*"],
        "AllowedMethods": ["GET"],
        "AllowedOrigins": ["https://app.infisical.com"],
        "MaxAgeSeconds": 3000
    }
]
```

```json Infisical Cloud (EU) theme={"dark"}
[
    {
        "AllowedHeaders": ["*"],
        "AllowedMethods": ["GET"],
        "AllowedOrigins": ["https://eu.infisical.com"],
        "MaxAgeSeconds": 3000
    }
]
```

If you self-host Infisical or use a dedicated instance, replace `AllowedOrigins` with your instance's URL.

#### Create an IAM role for Infisical

> [!NOTE]
>
> If you already have an AWS app connection you want to use, skip to [Attach the IAM policy](#attach-the-iam-policy).

Infisical assumes this role to write session logs to the bucket.

> **If you self-host Infisical**
>
> To assume a role, your Infisical instance needs AWS credentials of its own.
>
> If your instance runs on AWS (for example on EC2, ECS, or EKS), leave `INF_APP_CONNECTION_AWS_ACCESS_KEY_ID` and `INF_APP_CONNECTION_AWS_SECRET_ACCESS_KEY` unset. Infisical then uses the credentials of the instance profile, task role, or IAM role for service accounts (IRSA), and that role needs the `sts:AssumeRole` policy below.
>
> If your instance doesn't run on AWS, give it an IAM user:
>
> **Step 1**
>
> In the IAM console, [create an IAM user](https://console.aws.amazon.com/iam/home#/users/create) for your Infisical instance.
>
> **Step 2**
>
> Attach this inline policy to the user, so it can assume the roles your connections use:
>
> ```json theme={"dark"}
> {
>     "Version": "2012-10-17",
>     "Statement": [
>         {
>             "Sid": "AllowAssumeAnyRole",
>             "Effect": "Allow",
>             "Action": "sts:AssumeRole",
>             "Resource": "arn:aws:iam::*:role/*"
>         }
>     ]
> }
> ```
>
> **Step 3**
>
> Open the user's **Security credentials** tab and create an access key.
>
> ![Access Key Step 1](https://mintlify.s3.us-west-1.amazonaws.com/infisical/images/integrations/aws/integrations-aws-access-key-1.png)
>
> ![Access Key Step 2](https://mintlify.s3.us-west-1.amazonaws.com/infisical/images/integrations/aws/integrations-aws-access-key-2.png)
>
> ![Access Key Step 3](https://mintlify.s3.us-west-1.amazonaws.com/infisical/images/integrations/aws/integrations-aws-access-key-3.png)
>
> **Step 4**
>
> Set the access key ID as `INF_APP_CONNECTION_AWS_ACCESS_KEY_ID` and the secret access key as `INF_APP_CONNECTION_AWS_SECRET_ACCESS_KEY` in your instance's environment, then restart the instance.
>
> When you create the role's trust policy, enter the AWS account ID of this IAM user or instance role, not an Infisical Cloud account ID.

**Step 1**

In the IAM console, go to [Create role](https://console.aws.amazon.com/iam/home#/roles/create?step=selectEntities). Under **Trusted entity type**, select **AWS account**.

![IAM Role Creation](https://mintlify.s3.us-west-1.amazonaws.com/infisical/images/integrations/aws/integration-aws-iam-assume-role.png)

**Step 2**

Select **Another AWS account**, and enter the AWS account ID that Infisical assumes the role from:

* Infisical Cloud (US): `381492033652`
* Infisical Cloud (EU): `345594589636`
* Dedicated instance: contact Infisical support for your account ID
* Self-hosted: the account ID of your instance's credentials (see [If you self-host Infisical](#if-you-self-host-infisical))

Enable **Require external ID** and enter your Organization ID. You can copy it from your Infisical URL: it's the ID after `/organizations/`.

**Step 3**

Select **Next** to go to the **Add permissions** page. Then, select **Next** again without choosing a policy. You'll add the permissions as an inline policy after the role exists.

**Step 4**

Enter a **Role name** that includes Infisical and what the connection is for, such as `infisical-payments-prod`, then select **Create role**. CloudTrail logs every action Infisical takes under this role's name, so a descriptive name shows anyone reading the logs where those actions came from.

#### Attach the IAM policy

Attach the **IAM policy** from [Step 1](#step-1-start-in-infisical) to the IAM role, or to the role or user your existing connection signs in as.

**Step 1**

In the IAM console, open the role or user. On the **Permissions** tab, select **Add permissions** > **Create inline policy**, switch to the **JSON** editor, and paste the policy.

**Step 2**

Select **Next**, enter a **Policy name**, then select **Create policy**.

**Step 3**

If you created a new role, copy its **ARN** from the **Summary** section.

![Copy IAM Role ARN](https://mintlify.s3.us-west-1.amazonaws.com/infisical/images/integrations/aws/integration-aws-iam-assume-arn.png)

### Step 3: Finish in Infisical

Go back to the **Session Logs** dialog.

**Step 1**

Under **AWS Connection**, select **Create New Connection**.

> [!NOTE]
>
> If you already have an AWS app connection you want to use, select it here instead. Then, select **Save** and skip the remaining steps.

**Step 2**

Enter a **Name**, keep the **Assume Role (Recommended)** method, paste the role's ARN into **Role ARN**, and select **Connect to AWS**. Infisical creates the connection in Agent Vault and selects it.

**Step 3**

Select **Save**.

![The Session Logs dialog with Enable turned on and an AWS connection, region, bucket, and key prefix filled in](https://mintlify.s3.us-west-1.amazonaws.com/infisical/images/platform/agent-vault/session-logs-setup.png)

When you save, Infisical checks that the bucket exists and that the IAM user or role can write to it. If either check fails, Infisical shows the error and doesn't save the settings. If your browser can't read from the bucket, the **Session Logs** card shows a warning after you save.

> [!TIP]
>
> You've successfully set up external storage for session logs.

## Managing session logs

### Turning session logs off

Session logs are on unless an admin turns them off. To stop recording, turn off **Enable** in the **Session Logs** dialog and select **Save**.

Turning session logs off also hides the logs already recorded:

* With default storage, turning session logs back on shows those logs again, as long as they're less than 30 days old
* With external storage, Infisical forgets the bucket and its AWS connection (to see the logs again, set up the same bucket and key prefix)

### Connections

If you use external storage, session logs use one AWS connection at a time, which you select in the **Session Logs** dialog.

To update the connection's AWS credentials, open the menu next to **Configure** on the **Session Logs** card and select **Edit AWS Credentials**. If the connection belongs to your organization, update its credentials under **Integrations** in your organization instead.

To add or delete Agent Vault's AWS connections, select **Manage Connections** from the same menu:

![The Manage Connections sheet listing Agent Vault's AWS connections, with the one session logs use marked In Use](https://mintlify.s3.us-west-1.amazonaws.com/infisical/images/platform/agent-vault/session-logs-connections.png)

You can't delete a connection while session logs use it. To delete the connection, first turn session logs off, select a different connection, or switch to default storage in the **Session Logs** dialog.

### Changing where session logs are stored

Infisical doesn't copy existing records when you switch storage or change the bucket or key prefix. Records written before the change don't show in Infisical until you switch back.

If you switch away from default storage, logs already in default storage still expire after 30 days.

### Retention

How long session logs are kept depends on where they're stored:

* **Default storage**: you can look back at the last 30 days of session logs, unless your plan sets a different period
* **External storage**: Infisical never deletes session logs from your bucket (to delete older logs automatically, add an [S3 Lifecycle rule](https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lifecycle-mgmt.html) to the bucket)

If you use external storage, don't modify or add files in the folder that session logs use. Restrict who in your AWS account can delete or overwrite these files.

## Troubleshooting

If the AWS connection returns an error, a red alert icon appears next to **Settings** in the Agent Vault sidebar, and the **Settings** page shows the error.

If you use default storage and session logs can't be read, contact Infisical support, or your server administrator if you self-host.


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