{{ message }}
feat(site): OAuth2 device, consent and public-client admin screens (early sketches) - #28390
Closed
designertyler wants to merge 5 commits into
Closed
feat(site): OAuth2 device, consent and public-client admin screens (early sketches)#28390designertyler wants to merge 5 commits into
designertyler wants to merge 5 commits into
Conversation
Contributor
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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.

Early sketches of three OAuth2 surfaces, opened as a draft to get design feedback. None of them are wired to anything — they depend on backend work that isn't merged.
/device/oauth2/authorizeFlows 1 and 2 are standalone pages with no dashboard chrome, built on
SignInLayout+Welcomelike/cli-authandlogin/device. Flow 3 is admin-facing and sits inside dashboard chrome. All three follow the Coder Kit guidance. 41 Storybook stories cover every state.Flow 1 — Device authorization
DeviceAuthEnterCodeViewDeviceAuthConfirmViewDeviceAuthResultViewStep 1 is skipped when the user arrives with
?user_code=(theverification_uri_completecase). Step 2 shows the code back to the user because RFC 8628 §5.4 requires it. Step 3 has no redirect — the CLI polls and picks up the result itself, so each state ends by saying the tab is safe to close.Flow 2 — Consent / scope page
OAuth2ConsentPageViewOAuth2ConsentRedirectViewOAuth2ConsentErrorViewBuilds on #28045, which adds
Scopes []stringtoRenderOAuthAllowDataand lists the raw strings.scopes.tsmaps the catalog incoderd/rbac/scopes_catalog.go(externalLowLevel+externalComposite) to descriptions, groups them by resource and orders the most consequential first. Raw scope names stay visible in mono underneath — the description is what the decision is made on, the identifier is what gets debugged later. The three errors added in that PR (errUnknownScope,errScopeNotAllowed,errNoGrantableScope) each get a screen.Decisions worth arguing about:
all, or no scope at all, is a warning rather than a list item. feat: validate and persist OAuth2 authorization scope #28045 falls back to the existing "full access to your account" sentence. Listing a full grant as if it were one permission understates it, so it gets a prominent warning Alert — the one placeprominentis used, which the Kit reserves for page-level conditions.Flow 3 — Public-client admin UI (PLAT-504)
OAuth2ClientsPageViewOAuth2ClientFormViewOAuth2ClientDetailViewAdmin-facing, so these sit inside dashboard chrome rather than using
SignInLayout. Sketched as new components rather than edits toDeploymentSettingsPage/OAuth2AppsSettingsPage, so the existing pages stay reviewable side by side.Decisions worth arguing about:
Open questions for reviewers
coderd/oauth2provider/tokens.gohas// TODO: Client creds, device code, andmetadata.goadvertises onlyauthorization_codeandrefresh_token. Existing device-flow code (GitDeviceAuth,LoginOAuthDevicePage) is Coder acting as a client to GitHub, the mirror image of Flow 1./oauth2/authorizeserved by the SPA. That URL is currently rendered by the Go templatesite/static/oauth2allow.htmlviaShowAuthorizePage, so the registered route is unreachable until the backend serves the SPA there and exposes the app record — name, icon, scopes, redirect URI — to the frontend. Bigger decision than the visual design.verification_uri_complete? It decides whether Flow 1 step 1 is ever skippable in practice.SignInLayoutclips at 200% zoom. Out of scope here — it's shared with login,/cli-authandlogin/device. At a 640x400 viewport the Confirm screen'smainsits attop: -139px, so the top of the card is unreachable. Changingh-screentomin-h-screenwith vertical padding fixes it (verified locally); wants its own PR.Design system audit — changes made after reading the Coder Kit guidance
Flow 1 was first built against the components as they exist in
site/src/components, then revised against the Kit docs. Twelve things changed, and Flow 2 was built to the same rules from the start:aria-describedby+aria-invalidprominentis for page-level messagesprominentPERMISSIONS REQUESTED,uppercaseon the inputfont-semibold,tracking-[0.2em],text-xs font-medium uppercase tracking-widesize-icon-*, hide decorative iconssize-8on result iconssize-icon-lg,aria-hiddengapover marginsmt-4/mt-6stacksgap<main>landmark<h1>grew Confirm to 758px and pushed the top off-screenA follow-up fix after review: the device code field used
WDJB-MJHTas its placeholder, which read as an already-filled field. It's now anXXXX-XXXXmask with the example moved to helper text.Deliberate deviation:
pages/error-pageprescribes a full-pageEmptyStatefor terminal feedback. The result and error screens useSignInLayout+Welcomeinstead, so every step of a flow reads as one surface, while adopting the error-page rules (factual copy, always a way back). Happy to switch if reviewers disagree.Checks
pnpm checkandpnpm lint:typespass.🤖 Opened by Coder Agents on behalf of @designertyler.