Open
Conversation
Implement a permissions system for API keys so tokens can be restricted to specific operations instead of having full access. Scopes follow the pattern "resource:action" (e.g., instance:read, image:write, build:delete). Key changes: - New lib/scopes package with scope constants, context helpers, and middleware - JWT tokens can now carry a "permissions" claim with an array of scope strings - Auth middleware extracts permissions from JWT and stores in request context - Scope middleware enforces per-route permission requirements - Token CLI (hypeman-token) supports -scopes flag and -list-scopes - Backward compatible: tokens without "permissions" claim get full access - Uses "permissions" claim name to avoid collision with registry token "scope" Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
sjmiller609
commented
Mar 17, 2026
Documents the feature from a user/operator perspective: available scopes by resource type, CLI usage for creating scoped tokens, backward compatibility, and example scenarios for common use cases. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds three tests in lib/scopes/routes_test.go: - TestAllRoutesHaveScopes: builds the full chi router (OpenAPI + manual routes) and asserts every route has a scope in RouteScopes or is explicitly marked in PublicRoutes. Fails CI if a new endpoint is added without a scope mapping. - TestRouteScopesHaveNoStaleEntries: catches stale scope entries left behind when endpoints are removed. - TestPublicRoutesAreNotInRouteScopes: ensures no route is contradictorily listed in both maps. Also exports RouteScopes and adds PublicRoutes for spec.yaml, spec.json, and swagger endpoints. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
… tests - extractPermissions now stores an empty permission set (deny all) when the "permissions" claim is present but not a valid array, preventing privilege escalation from malformed tokens. - Add middleware integration test (TestMiddleware_EnforcesScopes) that proves scope enforcement works end-to-end with a real chi router: blocks missing scopes, allows matching scopes, wildcard, legacy tokens, and empty permissions. - Add test for malformed permissions claim in JwtAuth middleware. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Summary
lib/scopespackage that defines permission scopes following theresource:actionpattern (e.g.,instance:read,image:write,build:delete)permissionsclaim with an array of scope strings; tokens without this claim retain full access (backward compatible)JwtAuthandOapiAuthenticationFunc) extracts thepermissionsclaim and stores parsed scopes in the request contexthypeman-tokenCLI gains-scopes(comma-separated scope list) and-list-scopesflagsexec,cp) enforceinstance:writescope viaRequireScopeScope mapping
All API routes are mapped to scopes in
lib/scopes/scopes.go:routeScopes. The resource types are:instance:image:volume:snapshot:build:device:ingress:resource:Each prefix supports
read,write, anddeleteactions (exceptresource:which is read-only). The wildcard*grants all permissions.Usage
Test plan
go test ./lib/scopes/— scope parsing, validation, context helpers, RequireScope middlewarego test ./lib/middleware/— legacy tokens get full access, scoped tokens have permissions in context, wildcard tokens workgo vetclean on all changed packages🤖 Generated with Claude Code
Note
Medium Risk
Introduces new authorization checks across API routes based on JWT
permissionsclaims; misconfigured scope mappings or claim parsing could unintentionally block access or over/under-authorize requests.Overview
Adds scoped API-key permissions via a new
lib/scopespackage, including scope definitions (e.g.instance:read), a per-route scope map, and middleware that returns403 Forbiddenwhen a request lacks the required scope.Updates JWT authentication (
JwtAuthandOapiAuthenticationFunc) to extract an optionalpermissionsclaim into request context (missing claim remains full access for backward compatibility; malformed claim becomes deny all), wires scope enforcement into the main API router, and appliesinstance:writechecks to theexec/cpWebSocket endpoints.Extends the
hypeman-tokenCLI to list available scopes and mint scoped tokens, and adds tests to ensure scope enforcement works and that all routes are mapped (or explicitly public).Written by Cursor Bugbot for commit 1f3e39e. This will update automatically on new commits. Configure here.