Repository navigation
connectors: request-signing auth kind for the openapi and rest providers (RSA2 / HMAC canonical-request signers: Alipay, WeChat Pay, Aliyun, Tencent Cloud, e签宝) — the vendor-auth half that #26702 does not cover #26710
Description
Blocked-by: #26768
Filing gate ③ (maintainer-directed task). The maintainer in this session, 2026-10-27, on the three action recommendations of the MCP / OpenAPI directory survey, verbatim: 「三条行动建议 立卡」 → 「建议 1+2立卡」 → 「3 不考虑」 → 「你应该使用 pm-dispatch 技能立卡」. This card is recommendation 2, narrowed: the survey's recommendation was one ADR admitting both OAuth2 and request signing into the declarative connector auth contract. While this card was being drafted, #26702 (filed 2026-10-27 13:23Z from the maintainer's ruling 「OAuth 放开源层,先起草 ADR 修订」) took the OAuth2 half — authorization-code, client-credentials and the vendor app-credential exchange (Feishu / DingTalk / WeCom) — and owes the successor ADR. What remains uncovered is request signing, which no grant type produces: the caller signs each request with a private key or HMAC secret. This card is that half.
Filed by session_01J8VVAjRKqdoEYQ4hXxtBuf. ⛔ Not a claim. Lane suggestion: domain:spec for the auth variant (a Seam: with domain:server for packages/connectors/connector-openapi, connector-rest and packages/services/service-automation). Triage sets labels and priority. Sequencing note for triage: the successor ADR #26702 item 1 owes should decide signing in the same record (裁决一次裁清), so this card is a candidate sub-issue of #26702; it is not Blocked-by: #26702 as a whole, because the signer needs none of the grant machinery.
Business reason. The Chinese payment, cloud and e-signature platforms the marketplace's China lane needs do not use OAuth or static keys on their APIs; they sign every request:
| Platform | Scheme (official docs) | Machine-readable spec |
|---|---|---|
| Alipay OpenAPI v3 | RSA2 (SHA256withRSA) over a canonical request | yes, OpenAPI 3.0.3 YAML (alipay/alipay-sdk-java-all v3/api/openapi.yaml, about 746 operations, 2026-09-23; repository carries no LICENSE) |
| WeChat Pay APIv3 | WECHATPAY2-SHA256-RSA2048 |
none found |
| Aliyun OpenAPI | ACS3-HMAC-SHA256 | proprietary metadata (aliyun/aliyun-openapi-meta) |
| Tencent Cloud | TC3-HMAC-SHA256 | online explorer only |
| e签宝 (esign.cn) | request signature or OAuth2 | none found |
| AWS (for the global shelf) | SigV4 | Smithy models, not OAS |
Without a signing auth kind, none of these is reachable from a declarative instance, whatever OAuth2 support lands; a flow that needs to create an Alipay trade or a Tencent Cloud resource cannot be authored as metadata. With it, the Alipay v3 document (the only official OpenAPI document found among Chinese platforms) becomes a drop-in openapi instance.
Who acts. The ADR author named by #26702 (the domain:skills seat drafts, the maintainer lands, Tier H) extends the record with the signing decision; then domain:spec adds the variant to ConnectorInstanceAuthSchema; then domain:server implements the signer seam in the shared transport and wires openapi and rest. Reader: app authors declaring auth: { type: 'signed', scheme: 'alipay-rsa2', … } in content/docs/automation/connectors.
Dedupe (semantic issue search, objectstack-ai/objectstack, open and closed, 2026-10-27): "connector auth OAuth2 client credentials authorization code request signing HMAC RSA access_token exchange ADR ConnectorInstanceAuthSchema" → 3 hits: #26702 (open; OAuth2 and app-credential exchange, no signing), #14506 (closed; identity ADR mirror), #8075 (closed; inline-credential census). No card covers request signing.
Governing text
packages/spec/src/shared/connector-auth.zod.ts:113-114(header of the declarative auth block): "OAuth2 is intentionally absent (enterprise tier, ADR-0015)." The declared kinds arenone | bearer | api-key | basic(lines 119–145). Re-check:git grep -n "intentionally absent" origin/main -- packages/spec/src/shared/connector-auth.zod.ts.- ADR-0097 line 119: "The open tier deliberately omits OAuth2 from
ConnectorInstanceAuthSchema" and §3:credentialRefresolves at materialization; inline secrets are refused at publish. Re-check:git grep -n "deliberately omits OAuth2" origin/main -- docs/adr/0097-declarative-connector-instances.md. - AGENTS.md Prime Directive [WIP] Add Chinese version of the documentation #13: an accepted ADR binds until a superseding ADR says otherwise — the auth boundary moves by ADR, which connectors: outbound OAuth in the open tier — connection-scoped authorization-code / client-credentials / app-credential tokens, refreshed per dispatch, for the openapi, mcp and rest providers #26702 item 1 already owes; this card adds the signing decision to that record rather than opening a second one.
- AGENTS.md Prime Directive Add comprehensive test suite for Zod schema validation #12: contract-first; the variant is a closed enum of named schemes, refused at publish when unknown — never a free-form "custom header function".
Protocol statement. Metadata-protocol: added: a new ConnectorInstanceAuthSchema variant. Proposed shape, for the ADR to settle: { type: 'signed', scheme: <closed enum: 'alipay-rsa2' | 'wechatpay-rsa2048' | 'aliyun-acs3-hmac-sha256' | 'tencentcloud-tc3-hmac-sha256' | 'aws-sigv4' | 'hmac-sha256-generic'>, keyId: string, credentialRef: string, …scheme-specific non-secret parameters }. The private key or HMAC secret is a credentialRef only (ADR-0097 §3). Skills-docs: follow-up owed — content/docs/automation/connectors, skills/objectstack-automation.
Premises (each with a re-check; read at c3fb185a)
- No signing kind exists in either the declarative or the runtime auth union. Re-check:
git grep -n "z.literal('" origin/main -- packages/spec/src/shared/connector-auth.zod.ts(expected: oauth2, api-key, basic, bearer, none only). - The
openapiprovider applies one static auth globally and ignoressecuritySchemes. Re-check:git grep -n "securitySchemes" origin/main -- packages/connectors/connector-openapi/src/openapi-connector.ts(type only, no consumer). - connectors: outbound OAuth in the open tier — connection-scoped authorization-code / client-credentials / app-credential tokens, refreshed per dispatch, for the openapi, mcp and rest providers #26702 does not list signing in its grant types or its spec variant. Re-check: read connectors: outbound OAuth in the open tier — connection-scoped authorization-code / client-credentials / app-credential tokens, refreshed per dispatch, for the openapi, mcp and rest providers #26702 "Work" items 3 and 5.
Work
- ADR (with connectors: outbound OAuth in the open tier — connection-scoped authorization-code / client-credentials / app-credential tokens, refreshed per dispatch, for the openapi, mcp and rest providers #26702 item 1): admit a
signedauth kind with a closed scheme enum into the open tier; state which schemes ship first and that the secret is always acredentialRef. - Spec: the variant above in
ConnectorInstanceAuthSchema, publish-time refusal of an unknown scheme and of any inline key. - Runtime: a
RequestSignerseam in the shared connector transport (packages/services/service-automationor the connectors' shared layer, triage's call): given the resolved secret and the outgoing request (method, URL, headers, body), produce the signed headers / query. First signers:alipay-rsa2,aliyun-acs3-hmac-sha256,tencentcloud-tc3-hmac-sha256;aws-sigv4andwechatpay-rsa2048follow when a consumer declares them. Signers are pure functions with vectors from the vendors' published examples. - Providers:
openapiandrestaccept the variant;mcpdoes not (MCP servers do not sign; out of scope).
Acceptance
- A declarative
openapiinstance over the normalized Alipay v3 document (see connectors: auto-shelf readiness — declarativeincludeand a loud Swagger 2.0 refusal for connector-openapi;tools/listpagination, fatal 401 and a tool-snapshot hash for connector-mcp; an offline spec-normalization tool #26709's normalization tool) withauth: { type: 'signed', scheme: 'alipay-rsa2', keyId, credentialRef }dispatches a sandbox query end to end; the request carries the AlipayAuthorizationheader computed by the signer; the private key appears nowhere insys_metadata, inGET /api/v1/automation/connectors, or in logs. - Signer unit tests reproduce the vendors' published signature examples byte for byte for each shipped scheme.
- An unknown
schemeor an inline key is refused at publish with a located error; changeset per touched package.
Out of scope
- OAuth2 grants and app-credential (
appKey/secret → access_token) exchange: connectors: outbound OAuth in the open tier — connection-scoped authorization-code / client-credentials / app-credential tokens, refreshed per dispatch, for the openapi, mcp and rest providers #26702. - Writing OpenAPI documents for WeChat Pay, WeCom, e签宝 where the vendor publishes none: recommendation 3, not filed (「3 不考虑」).
Related
#26702 (parent candidate) · ADR-0097 · ADR-0015 · ADR-0023 · #26709 (recommendation 1, same batch).
Generated by Claude Code
Activity
objectstack-fleet commentedon Oct 27, 2026
Triage: first grade —
enhancement·security·priority:p1·domain:server·area:api·pm:queue· triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-27T14:17Z⛔ Not a claim, ⛔ not a dispatch.
security: a request-signing auth kind (RSA2 / HMAC canonical-request signers) for the openapi and rest providers. It is a new connector auth kind, so a protocol addition. Under [Decision] Triage priority caliber for protocol additions: keep 「协议新增定 p1」 for every addition, or grade additions an app asks for at p2 unless a release needs them #26368 ruling A, every protocol addition is p1. Handled directly in 18.x. Skills, docs and eval are owed ([Decision] pm-dispatch: which PRs owe aSkills-docs:line (the #26184 audit Part B rule draft) — protocol-kind only, protocol-kind plus narrowing, or not adopted #26369 B). It is narrowed in its body to signing only (OAuth is connectors: outbound OAuth in the open tier — connection-scoped authorization-code / client-credentials / app-credential tokens, refreshed per dispatch, for the openapi, mcp and rest providers #26702). Keys are stored encrypted. ⛔ No key material or signature in logs or errors.Generated by Claude Code
objectstack-fleet commentedon Oct 27, 2026
pm:queue→pm:blocked·domain:serverseat 3 ·session_01QSeKYmQXM3rHJcPnrEPk4B· 2026-10-27T15:10ZBlocked-by: #26768
docs/adr/**, Tier H) thedomain:skillsseat drafts and the maintainer lands. Every server slice (connection record, grant types or signers, per-dispatch resolve, providers) implements decisions that record has not made yet, so nothing here is dispatchable by the server lane today.carries item 1 of #26702 and item 1 of #26710), so one record decides OAuth2, the app-credential exchange and request signing together, as connectors: request-signing auth kind for the openapi and rest providers (RSA2 / HMAC canonical-request signers: Alipay, WeChat Pay, Aliyun, Tencent Cloud, e签宝) — the vendor-auth half that #26702 does not cover #26710 asked. This card keeps its other items unchanged; its grade and labels stay.pm:queue; re-read its premises against the merged record before claiming.objectstack-fleet commentedon Oct 28, 2026
Part of #27293 (E1 platform prerequisites) · 2026-10-28T14:59Z
Epic link on the maintainer's ruling 「是否建议立专题卡统一处理。」→「同意」 (2026-10-28,
session_01J8VVAjRKqdoEYQ4hXxtBuf). Role in the chain: the request-signing auth kind that admits the signature-authenticated half of E4 (Alipay v3 first); decided in the same ADR as #26702. Lane claims and dispatch proceed as triage set them; the epic PM seat (epic:#27293) tracks this card and reserves only what it drives in order. ⛔ Not a claim.Generated by Claude Code
objectstack-fleet commentedon Oct 28, 2026
epic:#27293#1 · sunhaolin · session_017xRBcVBKAFk1ntXSjvPt7U
Reserved for the epic subtree · 2026-10-28T15:12Z —
pm:epicadded;pm:blocked(Blocked-by: #26768) unchanged.The maintainer in
session_017xRBcVBKAFk1ntXSjvPt7U, 2026-10-28, verbatim: 「有很多子卡,这是没有挂到子任务,你应该处理。」 This card is attached under #27293 and now carriespm:epic: other seats' candidate reads skip it; the epic PM claims it with the full claim protocol when it dispatches. ⛔ Not a claim, ⛔ not a dispatch.objectstack-fleet commentedon Oct 29, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: 可对外的 API | none | P②
Triage: unblocked · p1 kept ·
domain:server· 2026-10-29T04:02Z⛔ Not a claim.
main(d745bb5e). Its remaining item 3 is the cloud mirror record (cloud#3350, PR cloud#3354), which this card's open-tier request-signing kind does not wait on.pm:blocked→pm:queue, with p1 kept. ⛔ A signing secret never reaches/meta, a log line or an error body. It resolves through connectors:sys_connector_credential+ open-tier resolver chain (env → credential object → vault), reconcile on credential change, install-local prompt for missingcredentialRefs (ruling A on #27230) #27237's credential chain once that lands, so read connectors:sys_connector_credential+ open-tier resolver chain (env → credential object → vault), reconcile on credential change, install-local prompt for missingcredentialRefs (ruling A on #27230) #27237's surface before the claim.Generated by Claude Code