Context
PR #44 shipped Microsoft 365 OAuth in Workit v2.260531.3, but the current happy path is still CLI-local:
wk auth add <email> --services m365 --readonly
That works when a technical operator can run the CLI on the same machine that receives the localhost callback. Bernardo is not technical; the product experience should be a single Telegram/web link he clicks to authenticate with Microsoft.
Problem
A raw Microsoft OAuth URL is not sufficient for Bernardo because PKCE requires the code_verifier and callback state to live somewhere trusted. If we send a URL whose redirect_uri is localhost, Bernardo's browser redirects to his own device, not the agent/Workit environment, so the token cannot be captured or stored.
Desired UX
- Felipe/Hermes generates a short-lived login link for Bernardo.
- Bernardo clicks the link in Telegram.
- Microsoft login opens in the browser.
- Callback lands on a trusted Workit/Hermes callback endpoint, not localhost.
- Workit exchanges the code with PKCE and stores the refresh token under the
m365 client namespace.
- Bernardo sees a success page: "Microsoft 365 connected read-only".
- No CLI, no copied auth code, no technical instructions.
Requirements
- Read-only only:
User.Read, Mail.Read, Calendars.Read, plus offline_access for refresh.
- No write scopes.
- Short-lived state, ideally 10 minutes.
- One-time-use state/code verifier.
- Token storage remains separate under Workit client
m365 / provider microsoft_graph.
- Audit event for created link, successful callback, failed callback, expired state.
- Do not log raw tokens or email body/content.
- Fail closed if state is missing/expired/reused, client id missing, tenant mismatch, or Graph
/me email does not match intended account.
Proposed implementation
Add a lightweight hosted login broker, either as:
Option A — Workit command + Hermes callback bridge
wk auth m365 broker start or equivalent local service started by Hermes/KHAW.
- Hermes exposes a public HTTPS callback URL or reverse tunnel.
- Generated login link embeds signed opaque state only.
Option B — Workit hosted mini callback service
- A small HTTP service in Workit that owns the state store and PKCE verifier.
- CLI/Hermes calls an endpoint to create the login session.
- Callback endpoint exchanges token and stores credentials.
Acceptance criteria
wk can generate a Bernardo-safe one-click URL without exposing secrets.
- Clicking the URL completes auth without CLI interaction from the user.
- Tests prove state is one-time, expires, and is bound to expected email.
- Tests prove no write scopes appear in generated OAuth URL.
- Tests prove callbacks with mismatched email fail closed.
- Dogfood with fake Client ID validates URL structure; real app config validates full login.
Context
PR #44 shipped Microsoft 365 OAuth in Workit v2.260531.3, but the current happy path is still CLI-local:
That works when a technical operator can run the CLI on the same machine that receives the localhost callback. Bernardo is not technical; the product experience should be a single Telegram/web link he clicks to authenticate with Microsoft.
Problem
A raw Microsoft OAuth URL is not sufficient for Bernardo because PKCE requires the
code_verifierand callback state to live somewhere trusted. If we send a URL whoseredirect_uriislocalhost, Bernardo's browser redirects to his own device, not the agent/Workit environment, so the token cannot be captured or stored.Desired UX
m365client namespace.Requirements
User.Read,Mail.Read,Calendars.Read, plusoffline_accessfor refresh.m365/ providermicrosoft_graph./meemail does not match intended account.Proposed implementation
Add a lightweight hosted login broker, either as:
Option A — Workit command + Hermes callback bridge
wk auth m365 broker startor equivalent local service started by Hermes/KHAW.Option B — Workit hosted mini callback service
Acceptance criteria
wkcan generate a Bernardo-safe one-click URL without exposing secrets.