Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
92af4fa
Document audit logs API
yummybomb Jun 23, 2026
6392fd8
Add Go audit log examples
yummybomb Jun 23, 2026
3b91857
Clarify audit log filter wording and show paging headers
yummybomb Jun 24, 2026
e4dbf8b
Clarify audit log date range limit
yummybomb Jun 24, 2026
1ac1f19
Document audit log search and export workflows
yummybomb Jul 16, 2026
0bb6b42
Restructure audit log guide for parallel transport sections
yummybomb Jul 16, 2026
85eb462
Drop Before you start section from audit log guide
yummybomb Jul 16, 2026
8ffb09c
Show complete SDK exporter loop for audit log chunks
yummybomb Jul 17, 2026
ea3c521
Move CLI usage out of audit log guide to CLI reference
yummybomb Jul 17, 2026
5433c1b
Move raw HTTP examples out of audit log guide to API reference
yummybomb Jul 17, 2026
c58722a
docs(audit-logs): align SDK, CLI, and API descriptions with existing …
yummybomb Jul 17, 2026
e706b47
Clarify audit log export safety
yummybomb Jul 17, 2026
8a3300c
Write complete audit log export chunks
yummybomb Jul 17, 2026
1467268
Polish audit logs description
yummybomb Jul 17, 2026
291dc28
Simplify audit log search examples
yummybomb Jul 17, 2026
e876655
Clarify audit log method filters
yummybomb Jul 17, 2026
4c96d64
Clarify audit log API filters
yummybomb Jul 17, 2026
0afb910
Simplify audit log exclusion wording
yummybomb Jul 17, 2026
f03b0e3
Clarify audit log user search
yummybomb Jul 17, 2026
a217e20
Simplify audit log download behavior
yummybomb Jul 20, 2026
f831769
Merge branch 'main' into hypeship/document-audit-logs-api
yummybomb Jul 20, 2026
5472320
Show accepted audit log time formats
yummybomb Jul 20, 2026
8fa8062
Condense audit log time guidance
yummybomb Jul 20, 2026
e6754da
Make export safeguards scannable
yummybomb Jul 20, 2026
bb5c6b6
Use SDK audit log download helpers
yummybomb Jul 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@
]
},
"info/api-keys",
"info/audit-logs",
"browsers/file-io",
"browsers/curl",
"browsers/ssh",
Expand Down Expand Up @@ -295,6 +296,7 @@
"reference/cli/managed-auth",
"reference/cli/projects",
"reference/cli/api-keys",
"reference/cli/audit-logs",
"reference/cli/mcp"
]
}
Expand Down
189 changes: 189 additions & 0 deletions info/audit-logs.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
---
title: "Audit Logs"
description: "Search and export audit logs for API requests across your organization"
---

Audit logs record authenticated API requests across your entire organization. Use them to review who called Kernel, which endpoint they called, when the request happened, and how the request completed.

Choose the workflow that matches the amount of data you need:

| Workflow | Best for | Output |
|----------|----------|--------|
| Search | Interactive investigation and recent activity | Paginated JSON events |
| Export | Archival, compliance, and offline analysis | JSON Lines (`.jsonl`) or gzip-compressed JSON Lines (`.jsonl.gz`) |

Audit logs are ordered newest first. Time windows use an inclusive `start` and exclusive `end`: `[start, end)`. A search or export can cover up to 30 days. Split longer periods into multiple time windows.
Comment thread
yummybomb marked this conversation as resolved.

Both workflows are also available from the [CLI](/reference/cli/audit-logs). For the underlying HTTP API, see [search](https://kernel.sh/docs/api-reference/audit-logs/list-audit-logs) and [export](https://kernel.sh/docs/api-reference/audit-logs/download-an-audit-log-export-chunk) in the API reference.

## Filter audit logs

The API and SDKs use the same filters for search and export:

- `auth_strategy` filters by authentication method, such as `api_key`, `dashboard`, or `oauth`.
- `service` filters by the service that emitted the audit event.
- `method` returns only requests that use the specified HTTP method.
- `exclude_method` omits requests that use any of the specified HTTP methods.
- `search` matches path, user ID, email, client IP, and status.
- `search_user_id` matches requests from the specified user IDs in addition to any free-text matches.

<Note>
The API and SDKs include all methods unless you filter. Only the CLI excludes `GET` by default to reduce noise. Pass `--include-get` to remove that default exclusion, or pass `--method GET` to return only GET requests.
</Note>
Comment thread
yummybomb marked this conversation as resolved.

## Search audit logs

Each API page contains up to 100 events. The SDK pagination helpers request older pages as you iterate.

<CodeGroup>
```typescript TypeScript
import Kernel from '@onkernel/sdk';

const kernel = new Kernel({
apiKey: process.env.KERNEL_API_KEY,
});

for await (const event of kernel.auditLogs.list({
start: '2026-06-01T00:00:00Z',
end: '2026-06-02T00:00:00Z',
method: 'POST',
})) {
console.log(event.timestamp, event.method, event.path, event.status);
}
```

```python Python
import os
from kernel import Kernel

client = Kernel(api_key=os.environ["KERNEL_API_KEY"])

for event in client.audit_logs.list(
start="2026-06-01T00:00:00Z",
end="2026-06-02T00:00:00Z",
method="POST",
):
print(event.timestamp, event.method, event.path, event.status)
```

```go Go
package main

import (
"context"
"fmt"
"time"

"github.com/kernel/kernel-go-sdk"
)

func main() {
ctx := context.Background()
client := kernel.NewClient()

pager := client.AuditLogs.ListAutoPaging(ctx, kernel.AuditLogListParams{
Start: time.Date(2026, time.June, 1, 0, 0, 0, 0, time.UTC),
End: time.Date(2026, time.June, 2, 0, 0, 0, 0, time.UTC),
Method: kernel.String("POST"),
})
for pager.Next() {
event := pager.Current()
fmt.Println(event.Timestamp, event.Method, event.Path, event.Status)
}
if err := pager.Err(); err != nil {
panic(err)
}
}
```
</CodeGroup>

See the [API reference](https://kernel.sh/docs/api-reference/audit-logs/list-audit-logs) for the full request and response schema.

## Export audit logs

The export API returns one chunk per request. Export paging uses a cursor rather than the page token used by search; both are opaque values you pass back unchanged.

Repeat requests until `X-Has-More` is `false`, passing `X-Next-Cursor` back as `cursor`. With the `jsonl.gz` format, each chunk is an independent gzip member, and appending the members produces a valid gzip file. With `jsonl`, each chunk contains raw JSON Lines that you can also append.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dense export format prose

Low Severity

This guide paragraph packs three separable points—the cursor loop, jsonl.gz member appending, and raw jsonl appending—into continuous prose. That violates the guide bullet-list rule for scannability when a section enumerates multiple distinct concepts.

Fix in Cursor Fix in Web

Triggered by learned rule: Use bullet lists when covering multiple distinct points in guides

Reviewed by Cursor Bugbot for commit bb5c6b6. Configure here.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Guide documents raw export protocol

Medium Severity

The Export section teaches the raw HTTP export protocol—chunk-per-request paging, X-Has-More / X-Next-Cursor, and append semantics—before the SDK examples. That violates the guide rule that info/ pages use SDK examples and only a one-liner plus link for REST, leaving deep HTTP detail to the API reference.

Fix in Cursor Fix in Web

Triggered by learned rule: Guide pages use SDK examples only — no CLI or REST API subsections

Reviewed by Cursor Bugbot for commit bb5c6b6. Configure here.


The SDK download helpers verify each chunk, retry transient transfer failures, and write the complete export to a destination you provide. They don't close the destination.

<CodeGroup>
```typescript TypeScript
import { open } from 'node:fs/promises';
import Kernel from '@onkernel/sdk';

const kernel = new Kernel({
apiKey: process.env.KERNEL_API_KEY,
});

const file = await open('audit-logs.jsonl.gz', 'w');
try {
await kernel.auditLogs.download(
{
start: '2026-06-01T00:00:00Z',
end: '2026-06-02T00:00:00Z',
format: 'jsonl.gz',
exclude_method: ['GET'],
},
file,
);
} finally {
await file.close();
}
```

```python Python
import os
from kernel import Kernel

client = Kernel(api_key=os.environ["KERNEL_API_KEY"])

with open("audit-logs.jsonl.gz", "wb") as file:
client.audit_logs.download(
to=file,
start="2026-06-01T00:00:00Z",
end="2026-06-02T00:00:00Z",
format="jsonl.gz",
exclude_method=["GET"],
)
```

```go Go
package main

import (
"context"
"os"
"time"

"github.com/kernel/kernel-go-sdk"
)

func main() {
ctx := context.Background()
client := kernel.NewClient()

file, err := os.Create("audit-logs.jsonl.gz")
if err != nil {
panic(err)
}
defer file.Close()

_, err = client.AuditLogs.Download(ctx, kernel.AuditLogDownloadParams{
Start: time.Date(2026, time.June, 1, 0, 0, 0, 0, time.UTC),
End: time.Date(2026, time.June, 2, 0, 0, 0, 0, time.UTC),
Format: kernel.AuditLogExportChunkParamsFormatJSONLGz,
ExcludeMethod: []string{"GET"},
}, file)
if err != nil {
panic(err)
}
}
```
</CodeGroup>

For atomic file replacement and cleanup after failed downloads, use the [CLI download command](/reference/cli/audit-logs#kernel-audit-logs-download).

Export chunks contain one JSON object per line. They use the same fields as search results and add `event_id`, which provides a stable tie-breaker when multiple events share a timestamp.

See the [API reference](https://kernel.sh/docs/api-reference/audit-logs/download-an-audit-log-export-chunk) for the full request and response schema.
3 changes: 3 additions & 0 deletions reference/cli.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ kernel --version
<Card icon="key" title="API Keys" href="/reference/cli/api-keys">
Create, list, rename, and delete API keys.
</Card>
<Card icon="clock-rotate-left" title="Audit Logs" href="/reference/cli/audit-logs">
Search and download organization audit logs.
</Card>
</Columns>

## Quick Start
Expand Down
93 changes: 93 additions & 0 deletions reference/cli/audit-logs.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
---
title: "Audit Logs"
---

Search and download [organization audit logs](/info/audit-logs) from the CLI.

Time values can be dates (`2026-06-01`) or timestamps (`2026-06-01T15:04:05Z`). Dates begin at midnight UTC.

## `kernel audit-logs search`

Search audit logs within a time window. Results are ordered newest first.

```bash
kernel audit-logs search \
--start 2026-06-01 \
--end 2026-06-08 \
--search /browsers \
--limit 500 \
--output json
```

If you omit the time flags, the command searches from 24 hours ago through now. The start is inclusive and the end is exclusive. Each time window can cover up to 30 days.

| Flag | Description |
|------|-------------|
| `--start <time>` | Inclusive start. Defaults to 24 hours ago. |
| `--end <time>` | Exclusive end. Defaults to now. |
| `--search <text>` | Search path, user ID, email, client IP, and status. |
| `--method <method>` | Return only requests that use this HTTP method. |
| `--exclude-method <method>` | Exclude requests that use this HTTP method. GET remains excluded unless you pass `--include-get`. |
| `--include-get` | Remove the default GET exclusion when `--method` is not set. |
| `--service <service>` | Filter by service. |
| `--auth-strategy <strategy>` | Filter by authentication strategy. |
| `--user-id <id>` | Add a user ID to the search. Repeat the flag for multiple IDs. |
| `--limit <n>` | Maximum total number of results. Defaults to `100`. |
| `--output json`, `-o json` | Output raw JSON array. |

<Note>
`--limit` controls the total number of CLI results. The CLI automatically requests API pages of up to 100 records until it reaches that limit or runs out of results.
</Note>

### Include GET requests

By default, the CLI returns matching requests for every HTTP method except GET. `--include-get` removes that default exclusion. `--method` selects exactly one method, so `--method GET` returns only GET requests.

```bash
# Return all matching methods, including GET
kernel audit-logs search --include-get

# Return only GET requests
kernel audit-logs search --method GET
```

## `kernel audit-logs download`

Download matching audit logs in a time window as one gzip-compressed JSONL file.

```bash
kernel audit-logs download \
--start 2026-06-01 \
--end 2026-07-01 \
--to audit-june.jsonl.gz
```

`--start` and `--end` are required. The start is inclusive and the end is exclusive, and the time window can cover up to 30 days.

| Flag | Description |
|------|-------------|
| `--start <time>` | Inclusive start. Required. |
| `--end <time>` | Exclusive end. Required. |
| `--search <text>` | Search path, user ID, email, client IP, and status. |
| `--method <method>` | Return only requests that use this HTTP method. |
| `--exclude-method <method>` | Exclude requests that use this HTTP method. GET remains excluded unless you pass `--include-get`. |
| `--include-get` | Remove the default GET exclusion when `--method` is not set. |
| `--service <service>` | Filter by service. |
| `--auth-strategy <strategy>` | Filter by authentication strategy. |
| `--user-id <id>` | Add a user ID to the search. Repeat the flag for multiple IDs. |
| `--to <path>` | Output `.jsonl.gz` path. For the example above, the default is `audit-logs-20260601-20260701.jsonl.gz`. |
| `--force` | Replace an existing output file. |

For example, `--start 2026-06-01 --end 2026-07-01` covers all of June in UTC.

### Download behavior

The CLI downloads up to 50,000 records per batch, verifies each batch's SHA-256 checksum, and automatically retries transient failures.

The requested output appears only after the full download succeeds. Failed downloads are removed, though a completed download may remain at `<output>.partial` if it can't be moved to the requested path.

Downloads don't resume: rerunning the command starts over. Existing files are replaced only when you pass `--force`.

## Aliases

You can also use `kernel audit-log`, `kernel auditlogs`, or `kernel auditlog`.
Loading