Repository navigation
feat(auth): add device-code login - #111
Simon Liang (AgentWings) wants to merge 2 commits into
Conversation
Vitus Larrieu (vitus-dedalus)
left a comment
There was a problem hiding this comment.
issue (correctness, blocking): resource is configured but never sent. login.ts:465 uses it only to check the base URL. The request at login.ts:553 sends just client_id and scope. Without resource, the AS sets the token's audience (aud, who the token is for) to the client ID (token_device.go:150-152). The gateway requires aud == https://dcs.dedaluslabs.ai (cli_gateway_as_token.go:82). So every device token would be rejected even after the server enables the grant. The fake /device handler in the test never checks resource. Fix: pass it through and assert form.get('resource') === origin.
issue (design, blocking): the server refuses this grant on purpose, and turning it on is more than a config change. Right now the live AS answers unauthorized_client: Client not registered for device authorization grant for dedalus-cli. TestCLIClientRegistersOnlyNativeCodeFlow (seed_test.go:45) locks in that restriction. There's also a deeper gap: approving a device code never records the organization. userinfo.go:99-100 rejects dedalus-cli tokens that have no org, and browser authorization only works because authorize.go:229 records it. The server contract needs to come first.
Summary
Add
dedalus login --flow devicefor terminals that cannot open a browser or receive a loopback callback. With a configured provider, the command displays a verification link and code, waits for approval, and saves tokens for later commands with automatic refresh.Device authorization sends the configured API resource. Discovery verifies the issuer and advertised device grant and validates the device, token, and revocation endpoints. The saved revocation endpoint survives token refresh so logout can revoke the rotated refresh token before clearing local credentials. Failed revocation warns and still permits local sign-out.
Public device sign-in remains disabled: the default issuer and discovery URL are unset, and the command fails before making a network request. Enabling it requires verified client registration, API audience binding, and organization binding on the server; advertising discovery metadata alone is insufficient. Use an API key until that support is verified.
Depends on #106 and continues to target
feat/generated-browser-login. Includes the updated parent branch and resolves the conflicting login/logout documentation.Verification
pnpm buildandpnpm typecheckpass for ESM and CJS.node --test tests/*.test.mjs: 55 tests pass.pnpm test:package: 26 installed-package checks pass.git diff --checkpasses.Release limitation
Local fixtures verify the CLI protocol behavior, not hosted readiness. Server device-grant and organization-binding support remain prerequisites for enabling public device sign-in.