Skip to content

Delegated sessions: act as the signed-in user via refresh-token BYOK#1

Merged
selic merged 2 commits into
mainfrom
feat/delegated-refresh-token
Jul 17, 2026
Merged

Delegated sessions: act as the signed-in user via refresh-token BYOK#1
selic merged 2 commits into
mainfrom
feat/delegated-refresh-token

Conversation

@selic

@selic selic commented Jul 17, 2026

Copy link
Copy Markdown
Member

What

App-only (client-credentials) sessions act as the app registration — writes are attributed to the app and its application permissions apply tenant-wide. This adds a delegated BYOK shape so a session acts as a real user:

  • HTTP: x-ms-tenant-id + x-ms-client-id + x-ms-refresh-token (public client, refresh-token grant)
  • stdio / server-env: MS_REFRESH_TOKEN instead of MS_CLIENT_SECRET
  • scripts/device-login.mjs — zero-dependency device-code helper; prints the refresh token to keep (valid ~90 days past last use)

Design notes

  • Precedence: when both a secret and a refresh token arrive, the refresh token wins — header-overlay proxies (the MCP gateway's sessionMode: per-user) can add headers but cannot remove the shared spec's placeholder secret.
  • Rotation: Entra may return a successor refresh token on redemption; the client adopts it for the session's lifetime.
  • Session binding hash includes the refresh token; distinct users → distinct principals (the existing keyHash model, unchanged).
  • 401/403 messages now explain both credential shapes and delegated scopes.

Gateway pairing (NDR)

Users register the refresh token at the gateway's /me as a personal credential (field x-ms-refresh-token, plus x-ms-client-id of the public client) — per-user sessions layer them as headers; Planner writes then attribute to the actual person.

Tests

33 passing (12 new): config combinations (secret XOR refresh token), resolveAuth shapes + precedence + distinct key hashes, GraphClient delegated grant + access-token caching + rotated-token adoption, app-only regression.

🤖 Generated with Claude Code

esamotija-ndr and others added 2 commits July 17, 2026 03:20
…n user)

Second BYOK shape: x-ms-tenant-id + x-ms-client-id + x-ms-refresh-token
(or MS_REFRESH_TOKEN for stdio) redeems a delegated Graph token — the
user's own Planner permissions apply and writes are attributed to them,
which app-only client-credentials can never do. Entra-rotated refresh
tokens are adopted for the session's lifetime. When both a secret and a
refresh token arrive the refresh token wins: header-overlay proxies (the
MCP gateway's per-user sessions) can add headers but not remove the shared
spec's placeholders. scripts/device-login.mjs is the one-time sign-in
helper that prints the refresh token to register.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Delegated sessions via refresh-token BYOK — act as the signed-in user.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@selic
selic merged commit 1dd0f7a into main Jul 17, 2026
2 checks passed
@selic
selic deleted the feat/delegated-refresh-token branch July 17, 2026 07:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants