Skip to content

Commit 39f87e6

Browse files
authored
Correct project scoping and lifecycle documentation (#487)
* Correct project scoping and lifecycle docs Document ID-only request scoping, first-class SDK project options, stable project lifecycle error codes, and org-wide authorization requirements for project administration. * Clarify project resource cleanup wording
1 parent 796a23e commit 39f87e6

3 files changed

Lines changed: 15 additions & 41 deletions

File tree

info/projects.mdx

Lines changed: 12 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,14 @@ Every organization has at least one project. Resources that existed before proje
1818
Your organization must always have **at least one active project**. The API returns `409 Conflict` if you try to delete the last remaining project:
1919

2020
```json
21-
{ "code": "conflict", "message": "organization must have at least one project" }
21+
{ "code": "last_active_project", "message": "organization must have at least one project" }
2222
```
2323

24-
A project must also be empty before it can be deleted — archive or remove its active resources first.
24+
A project must also be empty before it can be deleted. If active resources remain, the API returns `409 Conflict` with code `project_not_empty`; delete or otherwise remove those resources and retry. Organizations without Projects enabled receive `404 Not Found` with code `projects_disabled` from project-management endpoints.
2525

2626
## Scoping Requests to a Project
2727

28-
Pass the `X-Kernel-Project-Id` header a project ID or name — on any API request to scope it to a specific project. Without the header (and without a project-scoped API key), requests act on your organization's **default project**: reads return the default project's resources, and writes create resources in it.
28+
Pass the `X-Kernel-Project-Id` header with a project ID on any API request to scope it to a specific project. Project names are not accepted in this header. Without the header (and without a project-scoped API key), requests act on your organization's **default project**: reads return the default project's resources, and writes create resources in it.
2929

3030
```bash
3131
curl https://api.onkernel.com/browsers \
@@ -46,40 +46,29 @@ curl https://api.onkernel.com/browsers \
4646

4747
### SDK usage
4848

49-
Set the header on the client so every request is scoped to the project. You can also override it per-request.
49+
Set the project ID on the client so every request is scoped to that project.
5050

5151
<CodeGroup>
5252
```typescript TypeScript
5353
import Kernel from '@onkernel/sdk';
5454

5555
// Scope the whole client to a project
5656
const kernel = new Kernel({
57-
defaultHeaders: { 'X-Kernel-Project-Id': 'proj_abc123' },
57+
projectID: 'proj_abc123',
5858
});
5959

6060
const browser = await kernel.browsers.create();
61-
62-
// Or override per-request
63-
const other = await kernel.browsers.create(
64-
{},
65-
{ headers: { 'X-Kernel-Project-Id': 'proj_def456' } },
66-
);
6761
```
6862

6963
```python Python
7064
from kernel import Kernel
7165

7266
# Scope the whole client to a project
7367
kernel = Kernel(
74-
default_headers={"X-Kernel-Project-Id": "proj_abc123"},
68+
project_id="proj_abc123",
7569
)
7670

7771
browser = kernel.browsers.create()
78-
79-
# Or override per-request
80-
other = kernel.browsers.create(
81-
extra_headers={"X-Kernel-Project-Id": "proj_def456"},
82-
)
8372
```
8473

8574
```go Go
@@ -97,25 +86,14 @@ func main() {
9786

9887
// Scope the whole client to a project.
9988
client := kernel.NewClient(
100-
option.WithHeader("X-Kernel-Project-Id", "proj_abc123"),
89+
option.WithProjectID("proj_abc123"),
10190
)
10291

10392
browser, err := client.Browsers.New(ctx, kernel.BrowserNewParams{})
10493
if err != nil {
10594
panic(err)
10695
}
10796
_ = browser
108-
109-
// Or override per-request.
110-
other, err := client.Browsers.New(
111-
ctx,
112-
kernel.BrowserNewParams{},
113-
option.WithHeader("X-Kernel-Project-Id", "proj_def456"),
114-
)
115-
if err != nil {
116-
panic(err)
117-
}
118-
_ = other
11997
}
12098
```
12199
</CodeGroup>
@@ -128,6 +106,7 @@ API keys can be **org-wide** or **project-scoped**.
128106

129107
- **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.
130108
- **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`.
109+
- **Most project administration requires an org-wide credential.** A project-scoped key may rename its own project, but cannot create, archive, or delete projects, or change project limits.
131110

132111
### OAuth
133112

@@ -137,16 +116,16 @@ OAuth tokens (used by the Kernel CLI and MCP server) are **always org-wide**. Yo
137116

138117
The Kernel [CLI](/reference/cli/projects) has first-class project support:
139118

140-
- A global `--project <id-or-name>` flag scopes any command to a single project. Names are resolved case-insensitively, so `--project staging` works.
119+
- A global `--project <project-id>` flag scopes any command to a single project ID.
141120
- The `KERNEL_PROJECT` environment variable does the same, so you can set it once in your shell or CI.
142121
- A `kernel projects` command group lets you list, create, get, and delete projects, and manage per-project limit overrides.
143122

144123
```bash
145124
# Scope a single command
146-
kernel browsers list --project staging
125+
kernel browsers list --project proj_abc123
147126

148127
# Scope every command in the shell
149-
export KERNEL_PROJECT=staging
128+
export KERNEL_PROJECT=proj_abc123
150129
kernel apps list
151130

152131
# Manage projects
@@ -315,7 +294,7 @@ if err := client.Projects.Delete(ctx, "proj_abc123"); err != nil {
315294
</CodeGroup>
316295

317296
<Info>
318-
You can't delete a project that still owns active resources, and you can't delete the last remaining active project in your org.
297+
Project deletion is a soft delete. A project that still owns active resources returns `project_not_empty`; the final active project returns `last_active_project`.
319298
</Info>
320299

321300
## Concurrency Limits

reference/cli.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ kernel invoke my-app action-name --payload '{"key":"value"}'
9090
- `--version`, `-v` - Print the CLI version
9191
- `--no-color` - Disable color output
9292
- `--log-level <level>` - Set the log level (trace, debug, info, warn, error, fatal, print)
93-
- `--project <id-or-name>` - Scope the request to a specific [project](/reference/cli/projects) (also reads the `KERNEL_PROJECT` env var)
93+
- `--project <project-id>` - Scope the request to a specific [project](/reference/cli/projects) ID (also reads the `KERNEL_PROJECT` env var)
9494

9595
## JSON Output
9696

reference/cli/projects.mdx

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,14 @@ Manage [Projects](/info/projects) from the CLI and scope other commands to a spe
66

77
## Scoping commands to a project
88

9-
Use the global `--project` flag (or the `KERNEL_PROJECT` environment variable) to scope any `kernel` command to a project. The flag accepts either a **project ID** or a **project name** — names are resolved case-insensitively by listing your projects.
9+
Use the global `--project` flag (or the `KERNEL_PROJECT` environment variable) to scope any `kernel` command to a project ID. Project names are accepted by project-management commands whose arguments say `<id-or-name>`, but not by this global request-scoping flag.
1010

1111
```bash
12-
# Scope a single command by name
13-
kernel browsers list --project staging
14-
1512
# Scope by ID
1613
kernel browsers list --project proj_abc123
1714

1815
# Scope via environment variable
19-
export KERNEL_PROJECT=staging
16+
export KERNEL_PROJECT=proj_abc123
2017
kernel apps list
2118
```
2219

@@ -26,8 +23,6 @@ Under the hood, the flag adds the `X-Kernel-Project-Id` header to every authenti
2623
Project-scoped API keys are already bound to a project server-side, so you don't need `--project` when using them — but if you do pass it, it must match the key's project or the request is rejected.
2724
</Info>
2825

29-
If the name is ambiguous (multiple projects share it) or no match is found, the CLI returns a clear error; pass the project ID instead.
30-
3126
## Commands
3227

3328
### `kernel projects list`

0 commit comments

Comments
 (0)