diff --git a/apps/deploy.mdx b/apps/deploy.mdx index 6c3262c5..1e411963 100644 --- a/apps/deploy.mdx +++ b/apps/deploy.mdx @@ -65,6 +65,35 @@ 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` — 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. + +#### 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 +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 }); +``` + + +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 - **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..8d7ae74b 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 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 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.