plugs: Microsoft 365 as the organization's own Entra application, each person signed in with Microsoft - #343
Merged
Merged
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
richard-epsilla
marked this pull request as draft
September 29, 2026 19:56
richard-epsilla
force-pushed
the
plug-microsoft365
branch
from
September 30, 2026 10:00
81714a0 to
cb62ecc
Compare
…h person signed in with Microsoft The plane is the hosted tree's, byte for byte (54193461): identity by config.mode, delegated by default (the calling person's refresh token, kept under rt-<member slug> on the record, redeemed for a Graph token), or the application (client credentials); no sites or people lists, Microsoft's own permissions are the boundary and its refusal is surfaced as it is; list_sites; a person who never signed in is told to sign in on the Plugins page. The local registry checks the ids and the secret at Entra when the plug is connected, runs the sign-in (start with a signed state naming the org, workspace, person and return address; complete redeems the code, keeps the refresh token in the secret store and remembers who signed in; sign-out forgets both), and the console's Plugins page offers Sign in with Microsoft, shows who is signed in, and finishes the return. Guide text: the identity, list_sites, never another identity. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
richard-epsilla
force-pushed
the
plug-microsoft365
branch
from
September 30, 2026 20:58
cb62ecc to
d5a8f72
Compare
…er id (hosted af17a309, plane byte for byte) The first hosted sign-in wrote an 84-character vault key name and the vault refused it, so the field a person's refresh token is kept under is now rt- plus sixteen hex characters of the member id's hash, the same derivation on both registries: a record written by either reads on either gateway. The local registry already derives the field from the plane. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…o nobody on the record Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
richard-epsilla
marked this pull request as ready for review
October 1, 2026 04:44
richard-epsilla
approved these changes
Oct 1, 2026
richard-epsilla
left a comment
Collaborator
There was a problem hiding this comment.
Up to date with main; the four required checks pass.
richard-epsilla
added a commit
to ZixiaoL/harnessrouter
that referenced
this pull request
Oct 3, 2026
…h person signed in with Microsoft (HarnessRouter#343) * plugs: Microsoft 365 as the organization's own Entra application, each person signed in with Microsoft The plane is the hosted tree's, byte for byte (54193461): identity by config.mode, delegated by default (the calling person's refresh token, kept under rt-<member slug> on the record, redeemed for a Graph token), or the application (client credentials); no sites or people lists, Microsoft's own permissions are the boundary and its refusal is surfaced as it is; list_sites; a person who never signed in is told to sign in on the Plugins page. The local registry checks the ids and the secret at Entra when the plug is connected, runs the sign-in (start with a signed state naming the org, workspace, person and return address; complete redeems the code, keeps the refresh token in the secret store and remembers who signed in; sign-out forgets both), and the console's Plugins page offers Sign in with Microsoft, shows who is signed in, and finishes the return. Guide text: the identity, list_sites, never another identity. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * ci: start checks * plugs: a person's Microsoft sign-in field is a short hash of the member id (hosted af17a309, plane byte for byte) The first hosted sign-in wrote an 84-character vault key name and the vault refused it, so the field a person's refresh token is kept under is now rt- plus sixteen hex characters of the member id's hash, the same derivation on both registries: a record written by either reads on either gateway. The local registry already derives the field from the plane. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * plugs: a Microsoft sign-out also drops a sign-in field that belongs to nobody on the record Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> --------- Co-authored-by: richard-epsilla <richard@epsilla.com> Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
This branch was successfully deployed
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.
The enterprise plug, revamped after the Caterpillar review (Richard, 2026-09-30): no API keys, Entra SSO.
gateway/plugs_plane.py, byte-identical with hosted 54193461): identity byconfig.mode.delegated(default) runs every call as the person the task runs for, with the refresh token they gave when they signed in with Microsoft (kept underrt-<member slug>on the record);applicationuses client credentials. No sites or people lists: Microsoft's own permissions are the boundary, and its refusal is surfaced as it is. Nine read tools includinglist_sites. A person who never signed in, or whose sign-in Microsoft revoked, is told to sign in on the Plugins page; the agent never borrows another identity.POST /v1/plugs/microsoft365/microsoft/startgives Microsoft's sign-in address with a signed state naming the org, workspace, person and return address;POST /v1/plugs/microsoft/completeredeems the code, keeps the refresh token in the secret store under the person's own field and remembers who they are;POST /v1/plugs/microsoft365/microsoft/signoutforgets both./plugins?code=&state=. The identity is a choice on the form.End to end on hr-test (0.27.0-rc.3 and again 0.27.0-rc.4 of this branch after the hashed sign-in field, our Azure tenant's application and a test person, 2026-09-30): connect through the console's form (checked at Entra, then Needs auth with the sign-in as the next step); Sign in with Microsoft opened Microsoft's pages, the person registered the second factor the tenant's security defaults require and signed in; back on Plugins the row reads Connected and the settings say who is signed in. A Claude Code task with the plug included then called
resources(answered with that person's name, address and tenant),find_people(the directory match) andlist_fileson its own OneDrive, which Microsoft refused with its own sentence ("Tenant does not have a SPO license"), reported verbatim and not worked around.Not in this slice (next steps from the meeting): pass-through of an Entra token sent on the task request, and fronting Microsoft's remote MCP servers with the person's token.
🤖 Generated with Claude Code