Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -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 <hello@devhelm.io>",
"license": "MIT",
Expand Down
22 changes: 13 additions & 9 deletions skills/devhelm-manage/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,19 @@ design: most of its operations touch credentials or plan state.
| "Revoke key X" (reversible) | `devhelm api-keys revoke <id>` |
| "Delete key X" (permanent) | `devhelm api-keys delete <id>` |

**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`.

Expand Down
56 changes: 33 additions & 23 deletions skills/devhelm-manage/references/api-keys.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,53 +5,59 @@ 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 <id> --name=…`).
- Rotate its value (`devhelm api-keys regenerate <id>`).
- 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

```bash
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_<opaque>",
"last4": "...a3f1",
"createdAt": "..."
"key": "dh_live_<opaque>",
"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
devhelm api-keys list
devhelm api-keys get <id>
```

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

Expand All @@ -73,7 +79,7 @@ devhelm api-keys delete <id>

```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)
# ...
Expand All @@ -82,6 +88,10 @@ NEW=$(devhelm api-keys create --name="ci-deploy-v2" --output=json | jq -r '.valu
devhelm api-keys revoke <old-id>
```

Alternatively, `devhelm api-keys regenerate <id>` 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
Expand Down
9 changes: 5 additions & 4 deletions skills/devhelm-manage/references/workspaces.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Loading