Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -113,6 +113,7 @@
"auth/faq"
]
},
"info/api-keys",
"browsers/file-io",
"browsers/curl",
"browsers/ssh",
Expand Down Expand Up @@ -256,6 +257,7 @@
"reference/cli/browsers",
"reference/cli/apps",
"reference/cli/projects",
"reference/cli/api-keys",
"reference/cli/mcp",
"reference/cli/extensions"
]
Expand Down
135 changes: 135 additions & 0 deletions info/api-keys.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
---
title: "API Keys"
description: "Create, scope, rotate, and delete Kernel API keys"
---

An API key is the credential your server, script, or CI job uses to call Kernel without an interactive login. Treat it like a password: keep it out of client-side code, store it in a secret manager, and rotate it when access changes.

Kernel only returns the plaintext key once, when you create it. Save the `key` value immediately. After that, Kernel only shows the masked value.

## Before you start

You need one existing Kernel credential to create another API key:

- Set `KERNEL_API_KEY` before running the SDK examples.

API keys can be **org** or **project** scoped:

- Omit `project_id` to create an org-scoped key that can access resources across your organization.
- Set `project_id` to create a project-scoped key that can only access resources in that project.
- When you authenticate with a project-scoped key, you can only create another project-scoped key for the same project.

## Create an API key

Use the SDKs when your backend needs to provision keys for environments, customers, or automation jobs.

### SDKs

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

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

const apiKey = await kernel.apiKeys.create({
name: 'staging-ci',
days_to_expire: 30,
project_id: 'proj_staging_9f3k',
});

console.log(apiKey.key); // Save this value now. Kernel won't show it again.
console.log(apiKey.id, apiKey.masked_key);
```

```python Python
import os
from kernel import Kernel

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

api_key = client.api_keys.create(
name="staging-ci",
days_to_expire=30,
project_id="proj_staging_9f3k",
)

print(api_key.key) # Save this value now. Kernel won't show it again.
print(api_key.id, api_key.masked_key)
```
</CodeGroup>

## List and inspect API keys

List keys to audit what exists. List and retrieve responses include `masked_key`, `project_id`, `project_name`, `created_by`, and expiry metadata, but they don't include the plaintext key.

<CodeGroup>
```typescript TypeScript
for await (const apiKey of kernel.apiKeys.list({ limit: 20 })) {
console.log(apiKey.id, apiKey.name, apiKey.masked_key);
}

const apiKey = await kernel.apiKeys.retrieve('key_01jwv4tn5m8k3q2v7x9p0a1bc2');
console.log(apiKey.project_id, apiKey.expires_at);
```

```python Python
import os
from kernel import Kernel

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

for api_key in client.api_keys.list(limit=20):
print(api_key.id, api_key.name, api_key.masked_key)

api_key = client.api_keys.retrieve("key_01jwv4tn5m8k3q2v7x9p0a1bc2")
print(api_key.project_id, api_key.expires_at)
```
</CodeGroup>

## Rename or delete an API key

Rename a key when the owner or purpose changes. Delete a key when the workload no longer needs access.

<CodeGroup>
```typescript TypeScript
await kernel.apiKeys.update('key_01jwv4tn5m8k3q2v7x9p0a1bc2', {
name: 'staging-ci-rotated',
});

await kernel.apiKeys.delete('key_01jwv4tn5m8k3q2v7x9p0a1bc2');
```

```python Python
import os
from kernel import Kernel

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

client.api_keys.update(
"key_01jwv4tn5m8k3q2v7x9p0a1bc2",
name="staging-ci-rotated",
)

client.api_keys.delete("key_01jwv4tn5m8k3q2v7x9p0a1bc2")
```
</CodeGroup>

## Rotate a key

Rotate by creating the replacement first, then deleting the old key after your workload has switched over.

1. Create a new API key with the same scope.
2. Store the new plaintext key in your secret manager.
3. Deploy or restart the workload that uses `KERNEL_API_KEY`.
4. Verify the workload can call Kernel.
5. Delete the old API key.

## Troubleshooting

| Error | What it means | What to do |
| --- | --- | --- |
| `400 Bad Request` | The name is missing, `days_to_expire` is outside `1`-`3650`, or `project_id` is empty. | Send a name, choose a valid expiry, or omit `project_id` for an org-scoped key. |
| `401 Unauthorized` | Kernel couldn't authenticate the request. | Set a valid `KERNEL_API_KEY`. |
| `404 Not Found` | The project doesn't exist or the caller can't access it. | Check the project ID. If you're using a project-scoped key, create keys only for that same project. |
2 changes: 1 addition & 1 deletion info/projects.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ other = kernel.browsers.create(
API keys can be **org-wide** or **project-scoped**.

- **Existing API keys are org-wide.** They see every resource in your organization across all projects. Include an `X-Kernel-Project-Id` header to restrict a single request to one project.
- **Project-scoped API keys** can only access resources inside the project they were issued for. Create one from the **API Keys** page in the dashboard and pick the target project when generating the key. Requests made with a scoped key are automatically limited to that project — no header required. If you do send an `X-Kernel-Project-Id` header and it conflicts with the key's project, the request is rejected with `403 Forbidden`.
- **Project-scoped API keys** can only access resources inside the project they were issued for. Create one from the **API Keys** page in the dashboard, the [CLI](/reference/cli/api-keys), an SDK, or the [API keys guide](/info/api-keys), and pass the target `project_id` when generating the key. Requests made with a scoped key are automatically limited to that project — no header required. If you do send an `X-Kernel-Project-Id` header and it conflicts with the key's project, the request is rejected with `403 Forbidden`.

### OAuth

Expand Down
3 changes: 3 additions & 0 deletions reference/cli.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ kernel --version
<Card icon="folder-tree" title="Projects" href="/reference/cli/projects">
Manage projects and scope commands with `--project`.
</Card>
<Card icon="key" title="API Keys" href="/reference/cli/api-keys">
Create, list, rename, and delete API keys.
</Card>
</Columns>

## Quick Start
Expand Down
83 changes: 83 additions & 0 deletions reference/cli/api-keys.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
---
title: "API Keys"
---

Manage [API keys](/info/api-keys) from the CLI.

## `kernel api-keys create`

Create an API key. By default, the new key is org-wide. Pass `--project-id` to create a key whose own access is scoped to that project.

```bash
kernel api-keys create \
--name staging-ci \
--days-to-expire 30 \
--project-id proj_staging_9f3k \
--output json
```

| Flag | Description |
|------|-------------|
| `--name <name>` | API key name. Required. |
| `--days-to-expire <days>` | Number of days until expiry, from `1` to `3650`. Omit for no expiry. |
| `--project-id <project_id>` | Create a project-scoped API key for this project. Omit for org-wide. |
| `--output json`, `-o json` | Output the raw JSON object, including the plaintext `key` on create. |

<Info>
`--project-id` controls the access scope of the new API key. The global `--project` flag only scopes the CLI request you're making.
</Info>

## `kernel api-keys list`

List API keys in the authenticated organization. API keys are masked.

```bash
kernel api-keys list --limit 20
```

| Flag | Description |
|------|-------------|
| `--limit <n>` | Maximum number of results to return. |
| `--offset <n>` | Number of results to skip. |
| `--output json`, `-o json` | Output the raw JSON array. |

## `kernel api-keys get <id>`

Show one API key by ID. The response includes the masked key and metadata, not the plaintext key.

```bash
kernel api-keys get key_01jwv4tn5m8k3q2v7x9p0a1bc2
```

| Flag | Description |
|------|-------------|
| `--output json`, `-o json` | Output the raw JSON object. |

## `kernel api-keys update <id>`

Rename an API key.

```bash
kernel api-keys update key_01jwv4tn5m8k3q2v7x9p0a1bc2 --name staging-ci-rotated
```

| Flag | Description |
|------|-------------|
| `--name <name>` | New API key name. Required. |
| `--output json`, `-o json` | Output the raw JSON object. |

## `kernel api-keys delete <id>`

Delete an API key.

```bash
kernel api-keys delete key_01jwv4tn5m8k3q2v7x9p0a1bc2 --yes
```

| Flag | Description |
|------|-------------|
| `--yes`, `-y` | Skip the confirmation prompt. |

## Aliases

You can also use `kernel api-key`, `kernel apikeys`, or `kernel apikey`.
5 changes: 2 additions & 3 deletions reference/cli/auth.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ Display authentication status, including the active user, organization, and toke
Set the `KERNEL_API_KEY` environment variable to authenticate without OAuth:

```bash
export KERNEL_API_KEY=<YOUR_API_KEY>
export KERNEL_API_KEY=sk_1234abcd
```

Create and manage API keys from the Kernel dashboard.
Create and manage API keys from the Kernel dashboard or with [`kernel api-keys`](/reference/cli/api-keys).

## Global flags
The following flags are available on every CLI command:
Expand All @@ -36,4 +36,3 @@ The following flags are available on every CLI command:
## Getting help
- `kernel --help` — Show the top-level command list.
- `kernel <command> --help` — Display command-specific usage and options.

Loading