From 972a7f7e069116b6e51a6b472cf2fcea320bb8e5 Mon Sep 17 00:00:00 2001 From: masnwilliams <43387599+masnwilliams@users.noreply.github.com> Date: Sun, 14 Jun 2026 19:15:19 +0000 Subject: [PATCH] Document the API key rotate endpoint Replace the manual create-then-delete rotation steps with the rotate endpoint, covering days_to_expire, the expire_in_days grace window, and the related troubleshooting cases. --- info/api-keys.mdx | 83 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 75 insertions(+), 8 deletions(-) diff --git a/info/api-keys.mdx b/info/api-keys.mdx index 1f3b741..125fc8b 100644 --- a/info/api-keys.mdx +++ b/info/api-keys.mdx @@ -212,18 +212,85 @@ func main() { ## Rotate a key -Rotate by creating the replacement first, then deleting the old key after your workload has switched over. +`rotate` issues a replacement key in a single call and keeps the old key working for a short grace period, so your workload can switch over without downtime. The new key copies the rotated key's name and project scope, and—like create—Kernel returns the plaintext `key` only once. -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. +Two optional parameters control the timing: + +- `days_to_expire` sets the new key's lifetime in days (`1`-`3650`). Omit it to give the new key the same lifetime the rotated key originally had, or to never expire if the old key never did. +- `expire_in_days` sets how long the old key keeps working before it expires. Use `0` to revoke it immediately, or omit it for the default 7-day grace window. The old key stops authenticating automatically once the window passes—you don't need to delete it. + + +```typescript TypeScript +const rotated = await kernel.apiKeys.rotate('key_01jwv4tn5m8k3q2v7x9p0a1bc2', { + days_to_expire: 30, + expire_in_days: 7, +}); + +console.log(rotated.key); // Save this value now. Kernel won't show it again. +console.log(rotated.id, rotated.masked_key); +``` + +```python Python +import os +from kernel import Kernel + +client = Kernel(api_key=os.environ["KERNEL_API_KEY"]) + +rotated = client.api_keys.rotate( + "key_01jwv4tn5m8k3q2v7x9p0a1bc2", + days_to_expire=30, + expire_in_days=7, +) + +print(rotated.key) # Save this value now. Kernel won't show it again. +print(rotated.id, rotated.masked_key) +``` + +```go Go +package main + +import ( + "context" + "fmt" + + "github.com/kernel/kernel-go-sdk" +) + +func main() { + ctx := context.Background() + client := kernel.NewClient() + + rotated, err := client.APIKeys.Rotate( + ctx, + "key_01jwv4tn5m8k3q2v7x9p0a1bc2", + kernel.APIKeyRotateParams{ + DaysToExpire: kernel.Int(30), + ExpireInDays: kernel.Int(7), + }, + ) + if err != nil { + panic(err) + } + + fmt.Println(rotated.Key) // Save this value now. Kernel won't show it again. + fmt.Println(rotated.ID, rotated.MaskedKey) +} +``` + + +After you rotate a key: + +1. Store the new plaintext key in your secret manager. +2. Deploy or restart the workload that uses `KERNEL_API_KEY`. +3. Verify the workload can call Kernel before the grace window ends. + +To cut over immediately instead of using a grace window, pass `expire_in_days: 0` so the old key stops working as soon as the new one is issued. ## 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. | +| `400 Bad Request` | The name is missing, `days_to_expire` is outside `1`-`3650`, `expire_in_days` is outside `0`-`3650`, or `project_id` is empty. | Send a name, choose a valid expiry, or omit `project_id` for an org-scoped key. | +| `400 Bad Request` (rotate) | `days_to_expire` is shorter than `expire_in_days`, so the new key would expire before the old key's grace window ends. | Raise `days_to_expire` or lower `expire_in_days`. | | `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. | +| `404 Not Found` | The project or API key doesn't exist, or the caller can't access it. | Check the ID. If you're using a project-scoped key, you can only rotate keys in that same project. |