mirror of
https://github.com/coder/coder.git
synced 2026-10-16 14:48:56 +08:00
## Summary Coder validates every requested API key scope against a curated public catalog in `coderd/rbac`, but the docs never listed it. Readers had to infer the requestable set from the `codersdk.APIKeyScope` enum, which is a superset that includes internal scopes a token cannot carry. This adds `scripts/scopesdocgen`, which renders `docs/reference/api-key-scopes.md` from `rbac.ExternalScopeNames` and the policy definitions behind it: - built-in scopes (`coder:all`, `coder:application_connect`) - composite `coder:*` scopes, each with the permissions it expands to - low-level `resource:action` scopes, with the action descriptions the policy declares - the deprecated `all` / `application_connect` aliases and their canonical spellings The generator is wired into `make gen`, so CI fails when the scope catalog and the page drift apart. ## Also in this change - `coderd/apikey.go`: the unrequestable-scope `400` detail pointed at `admin/users/sessions-tokens#api-key-scopes`, which only ever held a partial list. It now points at the generated reference. - `docs/admin/users/sessions-tokens.md`: the partial enumeration and the "read the schema, but not all of it applies" caveat are replaced with a link to the reference. The how-to content stays. ## Verification - `go test ./scripts/scopesdocgen` covers the sentence formatting, the scope partitioning, and a guard that every name in `rbac.ExternalScopeNames()` appears on the rendered page. - `go test ./coderd -run 'TestTokenScoped|TestCreateTokenScopes|TestExternalScopesAreStorable|TestTokenLegacySingularScopeCompat'` passes, confirming the page's claims about the default scope and the rejection of internal scopes. - `make lint/emdash`, `make lint/docs-html`, `make lint/check-scopes`, `pnpm run check-docs`, and Vale on the changed pages are clean. Full `make pre-commit` passed. <details> <summary>Context and scope decisions</summary> Part of the DOCS Automated reference documentation project, which tracks generating reference pages from product source of truth instead of maintaining them by hand. DOCS-135 is the first item: it was filed as "wire up the existing generator," but `scripts/apikeyscopesgen` emits Go (`codersdk/apikey_scopes_gen.go`), not documentation, so there was no generator output to surface and this adds one. Decisions made while implementing: - **Placement.** `docs/reference/api-key-scopes.md`, as a direct child of Reference rather than inside `docs/reference/api/`, because that directory is owned by the swagger generator. - **Page shape.** Follows the `scripts/docgenenv` convention for generated reference pages: the generated marker and page metadata in front matter, the generated-content banner in the body, and sections starting at level two because the front-matter title renders as the page heading. - **Public scopes only.** The page lists what `rbac.IsExternalScope` accepts. Internal `resource:action` pairs are deliberately excluded, which is the distinction the old schema link failed to make. - **Acronym handling.** Policy action descriptions are lowercase source strings (`"ssh into a given workspace"`). The generator restores the casing of a small set of leading acronyms rather than editing the RBAC package, so the change stays inside the docs pipeline. Sibling backlog items turned out to be already delivered and are being rescoped separately: `metricsdocgen` and `auditdocgen` already write into their docs pages, and `scripts/configdocgen` already generates the configuration reference. </details> --- Generated with Coder Agents on behalf of @nickvigilante. Linear: [DOCS-135](https://linear.app/codercom/issue/DOCS-135/wave-1-wire-up-api-key-scopes-reference-to-docs) ## Product UI impact, please read This PR corrects three RBAC action description strings in `coderd/rbac/policy/policy.go`: | Action | Before | After | |---|---|---| | `workspace:start` | allows starting a workspace | start a workspace | | `workspace:stop` | allows stopping a workspace | stop a workspace | | `api_key:update` | update an api key, eg expires | update an api key, for example its expiry | These were internal-facing until this PR, which is what made them worth fixing: the new reference page renders them verbatim to operators, and "eg expires" is not decodable by a reader without codebase context. **They are not docs-only.** `make gen` propagates them to `coderd/rbac/object_gen.go` and `site/src/api/rbacresourcesGenerated.ts`, and `CreateEditRolePageView.tsx` renders the description next to each action in the custom roles editor. So this changes admin UI copy, and `CreateEditRolePageView.stories.tsx` means Pixel may now report a genuine snapshot diff on that component rather than the pre-existing failure noted below. The new wording matches the convention the rest of the table already follows (`ssh into a given workspace`, `create an AI Gateway key`), so this makes the UI more internally consistent, not less. Flagging it explicitly because a docs PR changing product copy deserves an owner's eyes rather than a silent merge. Happy to split it out if RBAC or frontend would rather own it, with the caveat that the reference page would then publish `eg expires` in the meantime. <details> <summary>CI note: Storybook / Pixel failure</summary> The `Storybook` check fails at its `Snapshot` step, and `Pixel / Review` reports `build failed` with no snapshots processed. **Updated:** this note originally said the branch touched no files under `site/`. That is no longer true. Correcting the RBAC policy description strings (CRF-24) required `make gen`, which regenerated `site/src/api/rbacresourcesGenerated.ts` alongside `coderd/rbac/object_gen.go`. That file is a generated string table with no rendered component behind it, so it still cannot account for a Storybook snapshot or Pixel build failure, but the original justification no longer holds and is replaced by this one. The failure predates that change: it was present when the branch genuinely had no `site/` diff. Every other check passes. </details>