From 49f2f8f3582e280d135cb8ffe33d4185a7cf800a Mon Sep 17 00:00:00 2001 From: akxue <18199652+akxue@users.noreply.github.com> Date: Mon, 17 Aug 2026 02:39:54 +0000 Subject: [PATCH 1/3] docs: document deployment API key lifecycle and reserved env vars Explain that each deployment mints its own deployment-scoped KERNEL_API_KEY, that KERNEL_API_KEY and ENTRYPOINT_RELPATH are reserved (user-supplied values are overridden), and how a superseded deployment's key is drained after in-flight invocations complete. Co-Authored-By: Claude Opus 4.8 --- apps/deploy.mdx | 25 +++++++++++++++++++++++++ info/api-keys.mdx | 12 ++++++++++++ 2 files changed, 37 insertions(+) diff --git a/apps/deploy.mdx b/apps/deploy.mdx index 6c3262c5..ce16ee47 100644 --- a/apps/deploy.mdx +++ b/apps/deploy.mdx @@ -65,6 +65,31 @@ kernel deploy my_app.py --env-file .env ``` +### Reserved environment variables + +Kernel injects a few environment variables into every deployment and its invocations. These names are **reserved** — if you set them via `--env` or `--env-file`, Kernel overrides your value, so setting them has no effect: + +- `KERNEL_API_KEY` — each deployment is given its own deployment-scoped API key at deploy time (see [Deployment API keys](/info/api-keys#deployment-api-keys)). The SDKs read this from the environment by default, so your app is already authenticated as itself. Passing your own `KERNEL_API_KEY` does **not** replace it. +- `ENTRYPOINT_RELPATH` — set by the platform to locate your entrypoint. + +If your app needs a different, long-lived key (for example an org- or project-scoped key), pass it under a **non-reserved** name and read it explicitly: + + +```python Python +import os +from kernel import Kernel + +# Use your own key from a non-reserved var instead of the injected deployment key. +client = Kernel(api_key=os.environ["MY_KERNEL_API_KEY"]) +``` + +```typescript TypeScript +import Kernel from '@onkernel/sdk'; + +const client = new Kernel({ apiKey: process.env.MY_KERNEL_API_KEY }); +``` + + ## Deployment notes - **The dependency manifest (`package.json` for JS/TS, `pyproject.toml` for Python) must be present in the root directory of your project.** diff --git a/info/api-keys.mdx b/info/api-keys.mdx index 5cf8560e..d152ae5f 100644 --- a/info/api-keys.mdx +++ b/info/api-keys.mdx @@ -88,6 +88,18 @@ func main() { ``` +## Deployment API keys + +When you deploy an app, Kernel mints a **deployment-scoped API key** for that deployment and injects it into the deployment (and every invocation it runs) as the `KERNEL_API_KEY` environment variable. Because the SDKs read `KERNEL_API_KEY` from the environment by default, your app can call the Kernel API as itself without you managing a key. + +Key points about deployment keys: + +- **One key per deployment.** Each deploy (including a redeploy of the same app) mints a fresh deployment key. `KERNEL_API_KEY` is a [reserved environment variable](/apps/deploy#reserved-environment-variables) — a value you supply at deploy time is overridden by the injected key. To use your own long-lived key, pass it under a non-reserved name. +- **Lifecycle tied to the deployment.** A deployment key stays valid while its deployment is active. When you redeploy, the new deployment supersedes the old one, and the old deployment's key is released once it is no longer needed — that is, once the superseded deployment is stopped **and** no invocation is still running on it. +- **In-flight invocations are drained, not cut off.** If an invocation is still running on a deployment that gets superseded, its key is kept valid until that invocation completes; the key is released right after. An idle redeploy (nothing in flight) releases the old key immediately. In the rare case where an invocation's workflow terminates without releasing the key, a background sweep releases it after a grace period (~95 minutes). You do not need to manage any of this — it is automatic. + +If you need a credential whose lifetime you control (for CI, a persistent backend, or sharing across deployments), create an org- or project-scoped key as described below and reference it explicitly rather than relying on the injected `KERNEL_API_KEY`. + ## 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. From a7bc7d30ae7e6dcf8aa0e2ce63656498171168a0 Mon Sep 17 00:00:00 2001 From: akxue <18199652+akxue@users.noreply.github.com> Date: Mon, 17 Aug 2026 17:35:38 +0000 Subject: [PATCH 2/3] clarify: a user-supplied key covers only the app's own calls, not the deployment key --- apps/deploy.mdx | 2 ++ info/api-keys.mdx | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/deploy.mdx b/apps/deploy.mdx index ce16ee47..d133bcbd 100644 --- a/apps/deploy.mdx +++ b/apps/deploy.mdx @@ -90,6 +90,8 @@ const client = new Kernel({ apiKey: process.env.MY_KERNEL_API_KEY }); ``` +This only changes the key **your own API calls** authenticate as. Kernel still injects the deployment key and uses it to run the invocation and report its result, so you can't replace the deployment key — you're only choosing the credential for the calls your app makes. + ## Deployment notes - **The dependency manifest (`package.json` for JS/TS, `pyproject.toml` for Python) must be present in the root directory of your project.** diff --git a/info/api-keys.mdx b/info/api-keys.mdx index d152ae5f..8d7ae74b 100644 --- a/info/api-keys.mdx +++ b/info/api-keys.mdx @@ -98,7 +98,7 @@ Key points about deployment keys: - **Lifecycle tied to the deployment.** A deployment key stays valid while its deployment is active. When you redeploy, the new deployment supersedes the old one, and the old deployment's key is released once it is no longer needed — that is, once the superseded deployment is stopped **and** no invocation is still running on it. - **In-flight invocations are drained, not cut off.** If an invocation is still running on a deployment that gets superseded, its key is kept valid until that invocation completes; the key is released right after. An idle redeploy (nothing in flight) releases the old key immediately. In the rare case where an invocation's workflow terminates without releasing the key, a background sweep releases it after a grace period (~95 minutes). You do not need to manage any of this — it is automatic. -If you need a credential whose lifetime you control (for CI, a persistent backend, or sharing across deployments), create an org- or project-scoped key as described below and reference it explicitly rather than relying on the injected `KERNEL_API_KEY`. +If you need a credential whose lifetime you control (for CI, a persistent backend, or a resource that should outlive any single deployment), create an org- or project-scoped key as described below and pass it explicitly to the client. This only affects the calls your app makes — the platform still injects the deployment key and uses it to run the invocation and report its result, so you're choosing the credential for your own calls, not replacing the deployment key. ## List and inspect API keys From 6bf2556bb575acdfbd3884216185e932c1e2084e Mon Sep 17 00:00:00 2001 From: akxue <18199652+akxue@users.noreply.github.com> Date: Mon, 17 Aug 2026 17:38:40 +0000 Subject: [PATCH 3/3] clarify reserved env var section: split 'reserved' from 'use your own key' --- apps/deploy.mdx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/apps/deploy.mdx b/apps/deploy.mdx index d133bcbd..1e411963 100644 --- a/apps/deploy.mdx +++ b/apps/deploy.mdx @@ -69,10 +69,12 @@ kernel deploy my_app.py --env-file .env Kernel injects a few environment variables into every deployment and its invocations. These names are **reserved** — if you set them via `--env` or `--env-file`, Kernel overrides your value, so setting them has no effect: -- `KERNEL_API_KEY` — each deployment is given its own deployment-scoped API key at deploy time (see [Deployment API keys](/info/api-keys#deployment-api-keys)). The SDKs read this from the environment by default, so your app is already authenticated as itself. Passing your own `KERNEL_API_KEY` does **not** replace it. +- `KERNEL_API_KEY` — a per-deployment API key Kernel mints at deploy time (see [Deployment API keys](/info/api-keys#deployment-api-keys)). The SDKs read it from the environment by default, so your app authenticates with this key automatically. - `ENTRYPOINT_RELPATH` — set by the platform to locate your entrypoint. -If your app needs a different, long-lived key (for example an org- or project-scoped key), pass it under a **non-reserved** name and read it explicitly: +#### Using a different key for your app's calls + +You can't change `KERNEL_API_KEY` itself, but you can have your app authenticate with a different key — say a long-lived org- or project-scoped key that outlives any single deployment. Put it in a **non-reserved** variable and pass it to the client explicitly: ```python Python @@ -90,7 +92,7 @@ const client = new Kernel({ apiKey: process.env.MY_KERNEL_API_KEY }); ``` -This only changes the key **your own API calls** authenticate as. Kernel still injects the deployment key and uses it to run the invocation and report its result, so you can't replace the deployment key — you're only choosing the credential for the calls your app makes. +Now the API calls your app makes go out as your key. The deployment key stays in place for Kernel's own use — running the invocation and reporting its result — so your key only needs permissions for the calls you actually make. ## Deployment notes