From 794155dbab953e2183cbde0dea44e764b921590e Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 2 Nov 2026 15:45:39 +0000 Subject: [PATCH] docs(adr-0143): note that the installer-client server slice landed (PR #29097) Append-only amendment note at D2's "Slices" bullet: the connect door takes the installer's client, the grant handle uses it for authorize, exchange and refresh, the connection state reads client { source, clientId, hasSecret } and never the secret, and an installer instance is no longer held degraded for a missing clientId. The original sentence is unchanged. Claude-Session: https://claude.ai/code/session_01ADHkmPosotet8HaKtCv2id Co-authored-by: Claude --- ...43-outbound-connector-auth-is-open-tier.md | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/docs/adr/0143-outbound-connector-auth-is-open-tier.md b/docs/adr/0143-outbound-connector-auth-is-open-tier.md index 5f6bed8096e..1ff4c71e834 100644 --- a/docs/adr/0143-outbound-connector-auth-is-open-tier.md +++ b/docs/adr/0143-outbound-connector-auth-is-open-tier.md @@ -250,6 +250,34 @@ carry and forbid; exact key spelling is the spec slice's, reviewed against this > declared and not served, and its schema description says so: off `provider: 'mcp'` over http an > instance that declares it is held degraded for a missing `clientId`, and on MCP over http the > provider registers a client dynamically instead of taking the installer's. +> +> > **Amended (2026-11-02, #29256) — the server slice landed (PR #29097).** The sentence above that +> > begins "Until the server slice lands" records the state before PR #29097, merged on 2026-11-02 as +> > `ec0316ea44`. The key names are the maintainer's ruling of record `6580268872`, letter A. +> > +> > - **The connect door takes the installer's client.** `POST +> > /api/v1/automation/connectors/:name/connection` reads the closed body `{ clientId, clientSecret? }` +> > and hands it to the service as `client`. An instance declaring `clientSource: 'installer'` begun +> > without one, a client offered to an instance that declares its own or registers one dynamically, +> > and any other body key are refused `400 VALIDATION_ERROR`. The read and revoke legs take no client. +> > The rule is `packages/services/service-automation/src/plugin.ts#installerClientOfBegin`. +> > - **The grant handle uses it for authorize, exchange and refresh.** The authorization URL carries its +> > id, the code is exchanged as it, and every refresh sends it. It is kept in the connection's client +> > record, its secret encrypted at rest through the `secret` channel as D3 states, and read back by +> > `packages/services/service-automation/src/oauth2-grant/installer-client.ts#parseKeptConnectionClient`. +> > A kept client whose kind no longer matches the declaration is a reconnect, never used: +> > `packages/services/service-automation/src/oauth2-grant/grant-handle.ts#endpointOf`. +> > - **The state never reads the secret.** The connection state answers +> > `client { source: 'installer', clientId, hasSecret }`, and never the secret: +> > `packages/spec/src/contracts/automation-service.ts#ConnectorConnectionState`. +> > - **The instance is served.** An instance declaring `clientSource: 'installer'` is no longer held +> > degraded for a missing `clientId`, and on MCP over http discovery finds the endpoints and registers +> > no client. The schema description no longer says the key is not served. +> > - **The ui slice is #28869, still open.** Until it lands, the Console begins a connect with no +> > client, so such an instance is refused there with the 400 that names the vendor registration step; +> > the door above connects it. The pins are +> > `packages/services/service-automation/src/connector-connection-door.test.ts` and +> > `packages/qa/dogfood/test/connector-installer-oauth-client.dogfood.test.ts`. ### D3 — Secrets are references; tokens are runtime state in a connection record