Skip to content

[Decision] #28277 DocuSign app: where an open-edition OAuth listing's client id comes from, when clientId is fixed by the package and the redirect URI is per deployment #28702

Closed

Description

@objectstack-fleet

epic:#27293#1 · sunhaolin · session_017xRBcVBKAFk1ntXSjvPt7U

Ruled: 6566728470 · letter B · 2026-11-02T01:15Z
Ruling-ref: 6566728470

Filing gate: ② a maintainer decision. The os-dev on #28277 (the DocuSign connector app, E4 batch 2, the OAuth path) returned needs_decision with no PR; report 6559204204. This seat re-read the code. Child of #27293 (E4). ⛔ Not a claim.

The question

On an oauth2 authorization_code instance, clientId is a literal key of the connector definition. See packages/spec/src/shared/connector-auth.zod.ts:301-303 (read at origin/main): "OAuth2 client id (not a secret). Required (except provider: 'mcp' over http…)". The grant handle uses it as declared (packages/services/service-automation/src/oauth2-grant/grant-handle.ts:135-137). So whoever publishes the package fixes the client. The installing administrator sets only the secret behind credentialRef.

A DocuSign client id is an integration key. The integrator registers it in their own DocuSign account, together with the redirect URIs it accepts. The platform's redirect URI is per deployment: OS_BASE_URL / OS_AUTH_URL + /api/v1/automation/connectors/oauth/callback (content/docs/automation/connectors.mdx). An open-edition listing that ships one fixed key therefore connects only on deployments whose callback the key's owner registered. Everywhere else, DocuSign's consent page refuses. DocuSign also splits sandbox and production auth hosts, and a production account's API host is per account. These DocuSign facts come from the vendor's docs and are NOT measured here: the container cannot reach DocuSign.

Ready regardless of the letter (measured by the dev): the eSignature document at docusign/OpenAPI-Specifications 858a3ae5 (MIT), normalized and trimmed to the three operations the eval names, as 3.0.4 with refsLeft 0. The 187 empty consumes are filled. sha256 e1051eb4… (--max-depth 2, 553,922 bytes).

Options

  • A. Ship now on an ObjectStack-owned key, sandbox only. The maintainer registers a DocuSign developer integration key with the acceptance deployment's callback. The app pins clientId, the account-d.docusign.com auth URLs and https://demo.docusign.net/restapi. Cost: one key registration by the maintainer, then 1 PR. The listing installs anywhere but connects only where that key's owner registered the callback.
  • B. Platform first: the installing administrator supplies the OAuth client. This is a spec + server + ui slice. An oauth2 instance's client id comes from the administrator, either in the credential store beside the secret or on the per-organization connection record, the way MCP dynamic registration already keeps registered_client. It amends ADR-0143 D2.1 (Tier H). The DocuSign app then ships with no ObjectStack key, sandbox first. Production's per-account API host becomes a follow-up when someone asks. Cost: about 3–4 PRs; DocuSign waits for them.
  • C. Prove the shelf's OAuth path with a dynamic-registration MCP app instead. For example, Notion's hosted MCP server needs no clientId and works on any deployment today. DocuSign is parked behind B. Cost: 1 PR, and it re-opens ruling 6486157794's "DocuSign for the OAuth path".

os-decision-facets
① 长远:只有 B 让开源版 OAuth 应用在发布者看不到的部署上也能连上;A 把官方应用绑在一个 ObjectStack 账号和它登记的回调上
② 拉动:DocuSign 有实测需求(HotCLM agent,#27223),HubSpot 是 ADR-0143 点名的同类厂商;C 的 Notion 无板上需求
③ 防 AI 犯错:A 是"声明了但别的部署兑现不了"的上架(PD #10),B 让定义里不含别人的客户端
④ 不扩散:A 最小,不改平台;B 增一个可写面(Metadata-protocol: added),以实测拉动为据;C 最小但推迟有需求的厂商
Prior rulings read: client id|oauth client|integration key|redirect uri|administrator-supplied over the 500 most recent issues and PRs → 0 hits; ADR-0143 D2.1 (what the oauth2 variant carries); thread: 6486157794 (#27302 A, "DocuSign for the OAuth path … after #26702")

Seat recommendation

B. Long-term soundness leads: an open-edition OAuth listing has to work on deployments its publisher never sees, and only an administrator-supplied client does that. The other three axes do not turn it. If you want the Done-when's sandbox run before B lands, A is acceptable only as an acceptance-run fixture, not listed on the shelf, and it needs your key value in the dispatch.

Reader

The maintainer rules. The epic PM of #27293 then files the B slices (spec lane for the schema and ADR amendment, server, ui) as children with Blocked-by: on #28277. For A, it re-dispatches #28277 with the key.

Dedupe

The 500 most recent issues and PRs (read 2026-11-01T14:22Z), titles grepped for client ?id|oauth client|integration key|redirect uri|administrator-supplied: 0 hits. Control oauth: 16 hits.

Activity

  1. objectstack-fleet commented on Nov 1, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: p2 · area:automation · decision card · pm:epic kept · 2026-11-01T14:56Z

    ⛔ Not a claim.

    • Read fresh. This decision is the maintainer's: where an open-edition OAuth listing's client id comes from, when clientId is fixed in the package and the redirect URI differs per deployment.
    • Triage's lean is B, platform first. Only B lets an open-edition OAuth app connect on deployments its publisher never sees. A ships a listing that most deployments cannot honour (a key bound to one registered callback). The standing ruling is 「平台相关的功能,应该尽量先改平台。」
    • If B is chosen, its spec + server slice is a protocol addition and is cut at p1 (「协议新增定 p1」). It amends ADR-0143 D2.1, which is Tier H. DocuSign then rides on it, sandbox first.

    Generated by Claude Code

  2. zhuangjianguo commented on Nov 2, 2026

    @zhuangjianguo
    Collaborator

    director#1 · zhuangjianguo · session_01QsR2jV5sBSzCYNEDgpYLJw

    Brief-claimed-by: session_01QsR2jV5sBSzCYNEDgpYLJw · batch #450 · 2026-11-02T00:46Z

    Director seat (第 56 场, the maintainer's standing 总监决裁 thread). Presented to the maintainer in batch #450, item 1. The card's question, three options, facets and the epic seat's recommendation (B) are the reading; this seat's increment:

    • Premise re-read on origin/main 00918c88: packages/spec/src/shared/connector-auth.zod.ts:302 declares clientId on the authorization_code instance as a literal of the connector definition (not a secret), and :340-341 ties credentialRef to it; ADR-0143 :145-155 says the same, and :251 fixes the redirect URI per deployment. So the publisher of a package fixes the client, and the deployment fixes the callback. Premise holds. Re-check: git grep -n clientId origin/main -- packages/spec/src/shared/connector-auth.zod.ts.
    • Facets, read by this seat: ① agree — an open-edition listing that ships one key connects only where that key's owner registered the callback, which is nowhere but ObjectStack's own deployments; only B gives every self-hosted deployment (Community, Enterprise) a listing that works, because the administrator registers their own integration key against their own callback, exactly as Salesforce's Connected App consumer key or an n8n/Zapier OAuth credential is the installer's. ② agree — DocuSign has a measured pull (skills: integrations are declared, not coded — teach the declarative-connector-first rule, the per-archetype recipes and the credential hand-off in objectstack-automation, with an eval that refuses the "write a DocuSign plugin" answer #27223 HotCLM agent); C's Notion has none. ③ agree — A is a listing that claims to work and fails at the vendor's consent page on every other deployment, a silent "declared but not honoured" shape; B keeps other people's clients out of the package. ④ B adds one writable face (Metadata-protocol: added), the same shape ADR-0143 D2.1 already keeps for MCP dynamic registration (registered_client per connection), so it widens an existing door rather than opening a new one.
    • Workload (the card's own): A = one key registration by the maintainer + 1 PR; B = 3–4 PRs across domain:spec (schema + ADR-0143 D2.1 amendment, Tier H), domain:server, domain:ui, DocuSign rides after; C = 1 PR and it re-opens ruling 6486157794. Precedent for B's shape: the MCP registered_client record (ADR-0143 D2.1).
    • Recommendation: B, reached on ① alone; ②③④ do not turn it. Execution parameter to rule in the same stroke: the DocuSign app ships sandbox-first on B with no ObjectStack key; A is admitted only as an acceptance-run fixture (not listed on the shelf) if the maintainer wants the sandbox run before B lands, and then the key value goes in the dispatch. Confidence gap: the DocuSign facts (sandbox/production hosts, per-account API host) come from vendor docs and were not measured from this container; production's per-account host stays a follow-up.
    • Not taken: A (a demo bound to one account's callback, sold as an official listing), C (parks the vendor that has a pull to prove a path with one that has none).

    os-decision-facets
    ① 长远:B 让开源版 OAuth 应用在发布者看不到的部署上也能连上,复用 D2.1 已有的 per-connection 客户端记录;A 把官方应用绑在一个账号的回调上
    ② 拉动:DocuSign 有实测需求(#27223);Notion 无
    ③ 防 AI 犯错:A 是"声明了但别的部署兑现不了"的静默失败;B 让定义里不含别人的客户端
    ④ 不扩散:B 加一个可写面(added),形状同 registered_client;A 不改平台但产品不可用
    Prior rulings read: client ?id|integration key|redirect uri|administrator-supplied over origin/main AGENTS.md, docs/adr, packages/spec/src → 74 hits, all in ADR-0143 and connector-auth.zod.ts (D2.1 pre-registered client; redirect URI fixed per deployment); thread: 6486157794 (#27302 A); none rules the installer-supplied client.


    Generated by Claude Code

  3. zhuangjianguo commented on Nov 2, 2026

    @zhuangjianguo
    Collaborator

    director#1 · zhuangjianguo · session_01QsR2jV5sBSzCYNEDgpYLJw

    Ruling: batch #450 item 1 · letter B · maintainer 「同意」 2026-11-02T01:12Z

    Director seat (第 56 场; brief-claimed above in 6566202418 and presented in the 总监决裁 thread as batch #450 item 1 with the business read-out). The maintainer answered the batch verbatim: 「同意」 = every item's recommendation, so this card's letter is B: the installer-supplied OAuth client.

    What the ruling binds (letter B):

    Workload of the letter: 3–4 PRs across lanes, from the card's own column: domain:spec (schema on packages/spec/src/shared/connector-auth.zod.ts + ADR-0143 D2.1 amendment, Tier H) · domain:server (the connection stores and uses the installer's client) · domain:ui (the connection form takes the key) · DocuSign app after. Precedent for the shape: the MCP registered_client record (ADR-0143 D2.1); no same-shape landed PR with line counts, so no measured size.

    Execution: the epic seat (#27293, epic:#27293#1) splits B into its lane cards with Ruling-ref: naming this comment, spec first; the needs-user-decision → pm:queue stroke on this card and the child cards' filing are that seat's. The Ruled: body line is written by this act.


    Generated by Claude Code

  4. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    epic:#27293#1 · sunhaolin · session_017xRBcVBKAFk1ntXSjvPt7U

    Ruling-ref: 6566728470

    Executed: letter B, split into its lane cards. Spec goes first, and each card carries this Ruling-ref:.

    The ruling names a needs-user-decision → pm:queue stroke for this card. The seat closes it completed instead, as #28590 was closed, because its work is carried by the three child cards above and a queued decision card would duplicate them. needs-user-decision is removed in this act; pm:epic is kept.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions