Skip to content

docs: show the MCP and OAuth steps in the architecture diagrams - #1270

Merged
mforce merged 3 commits into
mainfrom
docs/architecture-mcp
Oct 12, 2026
Merged

mforce merged 3 commits into
mainfrom
docs/architecture-mcp

Conversation

@mforce

@mforce mforce commented Oct 12, 2026

Copy link
Copy Markdown
Owner

docs/architecture.md predates the MCP milestone (#789). This PR adds /mcp and its OAuth gates to the deployment, module and request-pipeline diagrams. It also corrects three pipeline claims that were wrong before the MCP work. Only this one file changes.

What changed

  1. Request pipeline. The diagram shows UseMcpOriginCheck, UseOAuthApiAddressLimits and UseOAuthApiInFlightRelease in their Program.cs order:
  2. Placement table. Each new step has a row that says why it sits where it does and what breaks if it moves. The rows draw on MCP slice 3: map /mcp, wire RBAC and tools/list filtering #806 and the code comments.
  3. Deployment. AI apps (MCP clients) call the API over HTTPS. The API box and table list /mcp and the OAuth authorization server. No provider names were added.
  4. Feature modules. Access's label now says "users, Identity, connected apps and OAuth". Module names did not change.

Corrections to rows that were already wrong

  • Binding-error response. UseCluckworkBindingFailureResponse was missing from the diagram. It must sit directly inside request logging. If it moves outside the logger, malformed JSON logs a 500 at Error while the client gets a 400.
  • Epoch row. The old row said the check depends on tenant resolution. It does not: it reads both IDs from the token's claims, and CredentialEpochVerifier bypasses the tenant filter. The row now gives the real constraint. The check runs after authentication and before authorization and idempotent replay.
  • Origin row wording. The row now names the step that would answer first if the check moved: the rate limits (429), authorization for a tokenless POST (401), or the endpoint for a GET (405).

How it was checked

Every claim was checked against the code at 497e29e6. These tests pin the placements:

Placement Pinned by
Binding-error response inside request logging RequestLoggingTests.Binding_failure_logs_one_completion_at_information_with_status_400
Origin check before the rate limits and authentication McpEndpointTests.ForeignOrigin_Gets403_BeforeAuthentication_OnEveryMethod
Address limits before the rate limiter OAuthFailClosedTests.ForgedBearers_FromOneAddress_RunOutOfTheFailureBudget, BearersInFlight_FromOneAddress_AreCapped_AndAnotherAddressIsNot
Epoch check, then in-flight release, then forced password change, authorization and idempotency CredentialEpochMiddlewareOrderTests.Program_PinsTheCompleteCredentialGateSequence
In-flight release before tool work OAuthFailClosedTests.AuthenticatedWorkInFlight_DoesNotHoldAuthenticationPermits

These ran locally and passed:

  • CouplingMatrixRealTreeTests, 3 of 3. This test checks the module diagram's node set.
  • The two ImagePin tests.

The changed Mermaid blocks render with mermaid-cli. Two local review rounds found no remaining defect.

Refs #789, #806.

The request pipeline now shows UseMcpOriginCheck, UseOAuthApiAddressLimits
and UseOAuthApiInFlightRelease in Program.cs order, with a placement row
for each. Authentication covers OpenIddict reference tokens on /mcp, the
epoch node covers superseded app tokens and last-use stamps, and forwarded
headers come only from trusted proxies (#1260). The MustChangePassword
node id is MUSTCHANGE, so it no longer reads as the MCP server.

The deployment diagram adds AI apps calling /mcp and the OAuth endpoints,
and Access's label covers connected apps and OAuth.
The Origin row now names the step that answers first when the check
moves: the rate limits (429), authorization (401) or the endpoint (405).
The binding-error response gets a node and a row, because outside the
request logger malformed JSON logs a 500 at Error while the client gets
a 400. The epoch row now states its real constraint: after
authentication, before authorization and idempotent replay. Its query
does not depend on tenant resolution.
@mforce
mforce merged commit 4b859e9 into main Oct 12, 2026
17 checks passed
@mforce
mforce deleted the docs/architecture-mcp branch October 12, 2026 18:27
@mforce

mforce commented Oct 12, 2026

Copy link
Copy Markdown
Owner Author

Before and after for the three diagrams this PR changed. Before is docs/architecture.md at 497e29e6, the base. After is at 4b859e9f, the merge commit. Both were rendered with mermaid-cli at 1:1.

Deployment. AI apps (MCP clients) are added as a caller, and the API box now lists /mcp and OAuth.

Feature modules. Access is relabelled "users, Identity, connected apps and OAuth". The module names are unchanged.

Request pipeline. The new steps are the MCP Origin check, the OAuth API address limits and the in-flight permit release. The authentication and epoch nodes are reworded, the edge node adds the binding-error response, and the MCP node id is renamed MUSTCHANGE.

The images are attached in this order: deployment before and after, feature modules before and after, request pipeline before and after.

Deployment diagram, before

Deployment diagram, after

Feature modules diagram, before

Feature modules diagram, after

Request pipeline diagram, before

Request pipeline diagram, after

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.

1 participant