diff --git a/package.json b/package.json index 61e3d48..e5d77b4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "devhelm", - "version": "0.6.1", + "version": "0.6.2", "description": "DevHelm CLI — manage monitors, deployments, and infrastructure as code", "author": "DevHelm ", "license": "MIT", diff --git a/skills/devhelm-manage/SKILL.md b/skills/devhelm-manage/SKILL.md index 3db5053..4481d4d 100644 --- a/skills/devhelm-manage/SKILL.md +++ b/skills/devhelm-manage/SKILL.md @@ -38,15 +38,19 @@ design: most of its operations touch credentials or plan state. | "Revoke key X" (reversible) | `devhelm api-keys revoke ` | | "Delete key X" (permanent) | `devhelm api-keys delete ` | -**The value of a key is only shown once at creation time.** The -`list` and `get` endpoints return only the last-4 and the ID. Never -promise the user you can retrieve the full value later. - -**Default API key:** every DevHelm organization has a permanent -default API key created at org-creation time. It's named `Default` -and scoped to the org. Users can rotate it any time; they can't -delete it without creating a replacement first (the API enforces -this). +**The full key value is returned on every read** (`list`, `get`, +`create`, `regenerate`). Treat API key payloads as sensitive when +writing them to logs or chat transcripts — never paste them into +commit messages, PR descriptions, or any output that could be +shared. + +**Starter key:** every new DevHelm org gets one API key named +`Default` created during onboarding so the user can authenticate +the CLI in one copy-paste. It's an ordinary key — no special flag, +no protection, no uniqueness. If the user asks "where's my default +key?", match `name == "Default"` in `devhelm api-keys list` output; +if it's missing, they renamed or deleted it and should create a +new key rather than you trying to resurrect anything. Full field details: `@references/api-keys.md`. diff --git a/skills/devhelm-manage/references/api-keys.md b/skills/devhelm-manage/references/api-keys.md index 7d8eadb..be96e27 100644 --- a/skills/devhelm-manage/references/api-keys.md +++ b/skills/devhelm-manage/references/api-keys.md @@ -5,21 +5,25 @@ programmatic access to DevHelm — CLI, SDKs, Terraform, direct HTTP. Every workspace has at least one; most have several (one per environment, one per CI, one per engineer). -## The default key +## The starter key -Every DevHelm organization is created with a **permanent default API -key** named `Default` at org-creation time. Users see it once during -onboarding (with a copy button), after which only the last-4 is -visible. +Every new DevHelm organization is created with one starter API key +named `Default`. It's the key the setup-complete screen surfaces to +the user so they can authenticate the CLI in one copy-paste. -The default key: +This is an **ordinary API key** — no special flag, no protection, +no uniqueness. The user can: -- Can't be deleted without creating a replacement first. -- Is scoped to the org (full access within it). -- Can be rotated any time (`devhelm api-keys rotate default`). +- Rename it (`devhelm api-keys update --name=…`). +- Rotate its value (`devhelm api-keys regenerate `). +- Revoke or delete it once they've created a replacement. -It's the key the onboarding skill-install flow embeds into -`~/.devhelm/contexts.json`. +Do not treat "Default" as a first-class concept in skill prose or +flag semantics. It's just a name. If a user asks "where's my default +key?", find it with `devhelm api-keys list` and match on `name == +"Default"`; if it's missing, the user renamed or deleted it and +you should offer to create a new key rather than resurrecting a +"default" state. ## Create @@ -27,22 +31,21 @@ It's the key the onboarding skill-install flow embeds into devhelm api-keys create --name="ci-deploy" ``` -Response: +Response (includes the full `key` value): ```json { - "id": "key_...", + "id": 12, "name": "ci-deploy", - "value": "devhelm_pat_", - "last4": "...a3f1", - "createdAt": "..." + "key": "dh_live_", + "createdAt": "...", + "updatedAt": "...", + "lastUsedAt": null, + "revokedAt": null, + "expiresAt": null } ``` -**The `value` field is ONLY present in the create response.** All -subsequent `list` / `get` calls return the key without `value`, -only `last4`. There is no "reveal" endpoint. - ## List / get ```bash @@ -50,8 +53,11 @@ devhelm api-keys list devhelm api-keys get ``` -Returns name, ID, `last4`, `createdAt`, `lastUsedAt`, `revokedAt` -(if revoked). +Both endpoints return the full key value along with name, id, +timestamps, and revoke/expire state. There is no "last-4 only" +masking on reads — users and scripts can retrieve the value at any +time. Treat API key payloads as sensitive when writing them to logs +or chat transcripts. ## Revoke vs. delete @@ -73,7 +79,7 @@ devhelm api-keys delete ```bash # 1. Create a replacement -NEW=$(devhelm api-keys create --name="ci-deploy-v2" --output=json | jq -r '.value') +NEW=$(devhelm api-keys create --name="ci-deploy-v2" --output=json | jq -r '.key') # 2. Update consumers to use $NEW (e.g. GitHub Actions secret, ~/.devhelm) # ... @@ -82,6 +88,10 @@ NEW=$(devhelm api-keys create --name="ci-deploy-v2" --output=json | jq -r '.valu devhelm api-keys revoke ``` +Alternatively, `devhelm api-keys regenerate ` rotates the value +on an existing key record (same id, new value) — useful when you +need to keep external references to the key name/id stable. + Never revoke first, create second — you'll break live automation. ## Scopes diff --git a/skills/devhelm-manage/references/workspaces.md b/skills/devhelm-manage/references/workspaces.md index aef3797..e3f2acc 100644 --- a/skills/devhelm-manage/references/workspaces.md +++ b/skills/devhelm-manage/references/workspaces.md @@ -58,10 +58,11 @@ in a UI that can show plan changes. - **Cross-workspace references don't work.** A notification policy in workspace A can't target a monitor in workspace B. Resources are fully scoped. -- **API tokens are per-workspace.** The onboarding default key - belongs to the workspace it was created in; switching workspaces - in the CLI context means you're using a different token (if - configured) or no token (if not). +- **API tokens are per-organization, not per-workspace.** The key + grants access to the whole org; the `x-phelm-workspace-id` header + picks which workspace each request operates on. Switching + workspaces in the CLI context reuses the same token against a + different workspace id. - **Role matters.** VIEWER users can't create anything; MEMBER can create most resources; ADMIN can manage team; OWNER can change billing. `devhelm auth me` shows the current role.