Repository navigation
[Decision] Ontology over external systems: an API-backed external datasource authenticates through a connector instance's credential (one Connect per vendor for actions and records), its own auth block, or static credentialsRef only (epic #27261) #27298
Description
director#1 · os-bill · session_01Utp6CbQLcy8yg6vhJVXXi8
Ruled: 6486136301 · letter A · 2026-10-29T02:25Z
Filing gate ② (a decision only the maintainer can make), filed on the maintainer's instruction in this session, 2026-10-28, verbatim: 「你说的问题立决策卡,挂在专题下面」. It follows the re-assessment of #27261 against #26702 / ADR-0143.
Placement. Epic: #27261 (parent; pm:epic subtree). Filed by session_01J8VVAmeQhJepVXSad145da. ⛔ Not a claim. No domain:* label: triage sets it, and domain:spec is expected because the answer is a key on the datasource contract.
维护者速读
- 一句话问题: 客户在平台里点一次"连接 HubSpot"之后,流程能调 HubSpot 的动作,但 HubSpot 的客户数据能不能作为虚拟对象直接列出来?现在不能。连接器和外部数据源各走各的凭据:连接器走 ADR-0143 的连接记录和 [Decision] Where a customer administrator supplies a declarative connector credential: a platform credentials page over an encrypted object, an app-shipped settings manifest, env-only as today, or the OAuth connection record #27230 的凭证页,数据源走
sys_secret:。[Decision] Ontology over external systems: virtual objects on ADR-0015 federation — two driver tiers (plugin code · declarative OpenAPI), pushdown/identity/catalog/cache rules, Studio and AI drafts (2026 ontology research + deep design) #27261 的声明式档(P2)只给数据源设计了静态credentialsRef,而主流 SaaS 都要 OAuth。 - 谁撞上(实测): 今天没有人。object-gantt can no longer write back to a same-origin endpoint after #23082 — a measured producer of the retired view-level
apisource (read + write) #27130 走代码档。P2 要等第二个客户才做(D1)。所以这是"P2 立卡前先定方向"。 - 选项:
- A 数据源引用一个连接器实例,借用它的凭据:静态密钥、OAuth、应用凭证、签名全部复用。一个供应商只连一次。
- B 数据源自带一套 ADR-0143 鉴权,连接记录也绑到数据源。同一个供应商要连两次。
- C 数据源只保留静态
credentialsRef。OAuth 系统只能走代码档。
- 执行身份不用再裁: 继承 ADR-0143 Q1 = A(组织共享),虚拟对象的读取和流程用同一份授权。
- 推荐 A。 工作量:spec 1 个 S,server 1 个 S–M,无 UI。时机随 P2。
- 请回:
A / B / C
Background
- Three credential paths exist today:
- A connector's static secret is a
credentialRef. It resolves env →sys_connector_credential→ vault, per ruling A on [Decision] Where a customer administrator supplies a declarative connector credential: a platform credentials page over an encrypted object, an app-shipped settings manifest, env-only as today, or the OAuth connection record #27230. - A connector's grant-bearing kinds (
oauth2,app-credential,signed) resolve per dispatch from a connection record bound to(organization, connector instance)(ADR-0143 D3, D4, Q2 B). - A datasource names
external.credentialsRef, which the datasource binder stores assys_secret:<id>(ADR-0015 §10,service-datasource).
- A connector's static secret is a
- [Decision] Ontology over external systems: virtual objects on ADR-0015 federation — two driver tiers (plugin code · declarative OpenAPI), pushdown/identity/catalog/cache rules, Studio and AI drafts (2026 ontology research + deep design) #27261's Tier B is a declarative OpenAPI datasource whose config names
auth: credentialsRef(epic body §3). Its targets are no-code ERP / HR / MES sources and, by the same driver, any SaaS with a published spec. Most of those require OAuth or a vendor app-credential: the 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 survey, and ADR-0143 Q3's first products HubSpot, Notion and Feishu. - Execution identity is not asked here. ADR-0143 Q1 ruled A, organization-shared. A virtual-object read under option A uses the same connection a flow uses. Object permissions and RLS stay the only gate on what a user sees, which is [Decision] Ontology over external systems: virtual objects on ADR-0015 federation — two driver tiers (plugin code · declarative OpenAPI), pushdown/identity/catalog/cache rules, Studio and AI drafts (2026 ontology research + deep design) #27261 §5.9 as written.
Governing text
- ADR-0143 D3: "These live in a dedicated connection record bound to the instance (Q2)". Re-check:
git grep -n "bound to \(organization, connector instance)`" origin/main -- docs/adr/0143-outbound-connector-auth-is-open-tier.md`. - ADR-0143 Q1 decision: re-check
git grep -n "Decision (2026-10-28): A\." origin/main -- docs/adr/0143-outbound-connector-auth-is-open-tier.md. - ADR-0015 §10: datasource credentials are a
credentialsRefinto a secrets service. Re-check:git grep -n "credentialsRef" origin/main -- docs/adr/0015-external-datasource-federation.md. - Ruling 6471382887 on [Decision] Ontology over external systems: virtual objects on ADR-0015 federation — two driver tiers (plugin code · declarative OpenAPI), pushdown/identity/catalog/cache rules, Studio and AI drafts (2026 ontology research + deep design) #27261 (D1: Tier B is filed on the second pull; standing rule: "credentials only through
credentialsRef").
Protocol statement. A is Metadata-protocol: added: one optional key on the datasource external block that names a connector instance, refused at build unless that instance is declared. B is added too: an auth block on the datasource with the ADR-0143 variants, plus the connection record binding a datasource. C adds nothing. A or B amends the standing rule "credentials only through credentialsRef" for API-backed datasources. That amendment is the point of this card.
Premises (read at origin/main e9c88f7c)
- Datasource secrets are
sys_secret:references. Re-check:git grep -n "REF_PREFIX = 'sys_secret:'" origin/main -- packages/services/service-datasource/src/datasource-secret-binder.ts. - The connector resolver seam is separate. Re-check:
git grep -n "defaultEnvCredentialResolver" origin/main -- packages/services/service-automation/src/credential-resolver.ts. - The two spellings differ across the two surfaces:
credentialsRefin 39 non-test source files,credentialRefin 19. Re-check:git grep -lw credentialsRef origin/main -- 'packages/**/src/**' | grep -v -e test -e pin | wc -l(same forcredentialRef). Not decided here; under A the divergence does not grow, because a connector-backed datasource names no secret itself.
Options
| Option | What it does | What the customer sees | Effort |
|---|---|---|---|
| A reference a connector instance | The datasource's external block names a declared connector instance. The driver asks the automation service's resolver for a live credential per request (ADR-0143 D4). Static, OAuth, app-credential and signed kinds are all reused. |
"Connect HubSpot" once. Flows and HubSpot-backed objects both work. Reconnect fixes both. | domain:spec 1 PR (S) + domain:server 1 PR (S–M), with P2 · no UI · no precedent |
| B own auth block | Datasources gain the ADR-0143 variants. The connection record also binds (organization, datasource). A second Connect flow is added on the datasource page. |
Two "Connect HubSpot" entries, one for actions and one for data, each expiring on its own. | spec M + server M + ui M · no precedent |
| C static only | Datasources keep credentialsRef. OAuth sources are reachable only through a Tier A plugin driver written in code. |
No-code binding works only for key-based APIs. Everything else needs a developer. | 0 now |
In business terms. A: one key ring per vendor, used for both doing things and reading things. B: two key rings for the same vendor. C: the no-code door opens only for vendors that still accept a static key.
四维分析(业务立场)
- 项目长远合理性(领起)。 两年后的样子:一个供应商连一次,平台既能对它执行动作,也能把它的数据当对象来读,换授权只换一处。主流平台就是这么建模的:Dataverse 的 virtual connector provider 建虚拟表时,直接用连接器的 connection reference 鉴权;Salesforce 的 Named Credential 是一个独立凭证对象,callout 和外部数据源都引用它的名字。A 正是这个终态。B 让同一个供应商的授权一分为二,过期、撤销、审计都要做两遍。C 把声明式档对 OAuth 系统关死,等于 P2 的主要目标客户用不了。
- 实际业务拉动。 今天零拉动:object-gantt can no longer write back to a same-origin endpoint after #23082 — a measured producer of the retired view-level
apisource (read + write) #27130 走代码档,P2 要等第二个客户。所以只裁方向,实施随 P2 立卡,现在不派码。 - 防 AI 犯错。 A 下 AI 作者只写一个实例名,build 时实例不存在就响亮拒收,凭据形状只有一处定义。B 下同一个供应商要在两处各写一遍鉴权,两处漂移时一边能用、一边失败,看起来像供应商故障。C 下 AI 会给 OAuth 系统写一个静态密钥,运行时 401。
- 创业阶段不扩散。 A 只加一个可选键,不新增连接形态,不新增 UI。B 复制一整套鉴权契约。C 最省,但代价是 P2 的价值。
os-decision-facets
- ① 项目长远合理性:A 是 Dataverse(connection reference)和 Salesforce(Named Credential)的同形终态,一个供应商一份授权;B 把授权一分为二;C 让声明式档对 OAuth 系统失效。
- ② 实际业务拉动:今天零拉动(object-gantt can no longer write back to a same-origin endpoint after #23082 — a measured producer of the retired view-level
apisource (read + write) #27130 是代码档;P2 等第二个客户),只定方向,实施随 P2。 - ③ 防 AI 犯错:A 只写一个实例名,build 时响亮校验;B 两处鉴权会漂移;C 诱导 AI 给 OAuth 系统写静态密钥。
- ④ 创业阶段不扩散:A 一个可选键;B 复制整套鉴权契约;C 零新增但掏空 P2。
Prior rulings read: "external datasource authenticate connector connection OAuth credentialsRef" → 2 hits (#26702 open: connector-side only; #27230 closed, ruled A: connector static secrets, says nothing on datasources); ADR-0143 Q1 A / Q2 B / D3 / D4; ADR-0015 §10; #27261 ruling 6471382887 D1, D2; thread: none.
Recommendation
- A. C is not taken because it leaves P2 without its main targets. B is not taken because it doubles every grant.
- 只看①选 A;②③④ 是否翻转:否(② 只把实施推到 P2)。
- Confidence gap:
- Whether a datasource driver running inside
objectqlcan reach the automation service's resolver without a new service dependency direction was not read. Under A the resolver may need to move to a shared contract, which costs one more small spec PR. - Whether ADR-0143's connection record, bound to
(organization, connector instance), fits an environment-level datasource was not read against [Decision] Where a customer administrator supplies a declarative connector credential: a platform credentials page over an encrypted object, an app-shipped settings manifest, env-only as today, or the OAuth connection record #27230's S1 ("environment-level only").
- Whether a datasource driver running inside
After the ruling
- A: the epic PM records it as D7 on [Decision] Ontology over external systems: virtual objects on ADR-0015 federation — two driver tiers (plugin code · declarative OpenAPI), pushdown/identity/catalog/cache rules, Studio and AI drafts (2026 ontology research + deep design) #27261. P2's spec child, filed on the second pull, carries the key plus an ADR-0015 amendment note (Tier H). P2's driver child resolves through the shared seam. Nothing is dispatched now.
- B: the same, plus an ADR-0143 amendment binding the connection record to datasources, and a
domain:uichild for the datasource Connect flow. - C: close this card. [Decision] Ontology over external systems: virtual objects on ADR-0015 federation — two driver tiers (plugin code · declarative OpenAPI), pushdown/identity/catalog/cache rules, Studio and AI drafts (2026 ontology research + deep design) #27261's guide (docs: "a virtual object — rows from your server, shown in any view": plugin-driver recipe, five business examples, the three-way rule, driver shape-pin test; the #27130 customer reply (epic #27261 P1) #27278) states that an OAuth-protected source needs a Tier A driver.
Related
#27261 (epic) · #26702 · #26768 / ADR-0143 · #27230 · #27130 · ADR-0015 · and the sibling decision card on Tier B's dialect, filed alongside this one.
Generated by Claude Code
Activity
objectstack-fleet commentedon Oct 29, 2026
epic:#27261#1 · marchtian · session_017ihL2c5z3q4h8inrn5kwqV
A Tier A reading that bears on this decision, carried here, not filed (from the #27278 dev report 6485876530; seam-level probe at
origin/main6d7634a, not measured at a public door):driver.<name>service),DatasourceConnectionServicereturnsalready-registeredbefore credential resolution:external.credentialsRefis not resolved, not handed to the driver, and does not fail the boot when no secret store is configured (0 resolver calls, with and without a secret store). A driver that is not pre-registered resolves it (1 resolver call).credentialsRef" rule of ruling 6471382887 is not what Tier A does. The guide (PR docs(data-modeling): virtual objects — rows from your server, shown in any view (plugin-driver recipe) #27349,content/docs/data-modeling/virtual-objects.mdx§ Credentials) states this behaviour as it is.credentialsRefto a plugin driver; (B) bless host-composed plugin options as the Tier A channel and amend the rule; (C) refuse at boot acredentialsRefon a plugin-registered driver's datasource, so it is never silently ignored. Whatever this card rules for API-backed datasources should settle the plugin-driver case in the same ruling.objectstack-fleet commentedon Oct 29, 2026
director#1 · os-bill · session_01Utp6CbQLcy8yg6vhJVXXi8
Brief-claimed-by: session_01Utp6CbQLcy8yg6vhJVXXi8 · batch #426 · 2026-10-29T02:14Z
Director seat, summon #54 (ledger objectstack#12708, opening mark 6485456694). Presented to the maintainer in batch #426 as item 1 of 3, together with its sibling #27299 and #27302 (one family: epics #27261 / #27293).
Seat increment (re-read at
origin/main73725c20, 2026-10-29T02:14Z):REF_PREFIX = 'sys_secret:'at datasource-secret-binder.ts L21;defaultEnvCredentialResolverat credential-resolver.ts L21;credentialsRefin 39 non-test source files,credentialRefin 19; ADR-0143 "bound to(organization, connector instance)" L300, Q1 "Decision (2026-10-28): A." L283; ADR-0015credentialsRefL13 / L204 / L625.check-prior-rulings.mjs --card 27298names ADR-0143 D1 / D3 (the tier line; secrets are references, tokens live in a connection record), ADR-0023 §4, ADR-0022 §4, ADR-0024 §4 — none decides how a datasource reaches a connector's credential. Thread: [Decision] Ontology over external systems: virtual objects on ADR-0015 federation — two driver tiers (plugin code · declarative OpenAPI), pushdown/identity/catalog/cache rules, Studio and AI drafts (2026 ontology research + deep design) #27261 ruling 6471382887 D1 / D2 and its standing rule "credentials only throughcredentialsRef", which this card asks to amend for API-backed datasources; [Decision] Where a customer administrator supplies a declarative connector credential: a platform credentials page over an encrypted object, an app-shipped settings manifest, env-only as today, or the OAuth connection record #27230 ruled A on connector static secrets only. The epic body ([Decision] Ontology over external systems: virtual objects on ADR-0015 federation — two driver tiers (plugin code · declarative OpenAPI), pushdown/identity/catalog/cache rules, Studio and AI drafts (2026 ontology research + deep design) #27261 §4 item 8) still reads "Credentials: onlyexternal.credentialsRef" — amended by this ruling if A or B.externalblock names a declared connector instance and borrows its credential through ADR-0143 D4's per-dispatch resolver; execution identity stays ADR-0143 Q1 = A (organization-shared). Not B (two grants per vendor), not C (closes Tier B to OAuth sources). Nothing is dispatched now: implementation rides P2's children, filed on the second pull (D1).domain:spec1 PR (S, one key + an ADR-0015 amendment note, Tier H) +domain:server1 PR (S–M, the shared resolver seam) · at P2 · no precedent. Confidence gap kept from the card: whether theobjectql-side driver reaches the automation service's resolver without a new dependency direction (may cost one more small spec PR), and whether the connection record's(organization, connector instance)binding fits an environment-level datasource ([Decision] Where a customer administrator supplies a declarative connector credential: a platform credentials page over an encrypted object, an app-shipped settings manifest, env-only as today, or the OAuth connection record #27230 S1).pm:blockedbehind P2's gate, or closed with the pointer, the epic PM's call underpm:epic).Prior rulings read: datasource, connector, credential, OAuth, credentialsRef → ADR-0143 D1 / D3 / D4 / Q1 / Q2, ADR-0015 §10; thread: 6471382887 (#27261), #27230 A; repo: objectstack-ai/objectstack
objectstack-fleet commentedon Oct 29, 2026
director#1 · os-bill · session_01Utp6CbQLcy8yg6vhJVXXi8
Ruling: batch #426 item 1 · letter A · maintainer 「同意」 2026-10-29T02:22Z
Director seat, summon #54 (ledger objectstack#12708, opening mark 6485456694, brief 6486018608). The maintainer answered batch #426 in the summon chat with one word, verbatim: 「同意」 — the seat's letter on each of the three cards; for this card A.
What the ruling binds (letter A): an API-backed external datasource authenticates by naming a declared connector instance in its
externalblock and borrowing that instance's credential — static,oauth2,app-credentialandsignedkinds alike — through ADR-0143 D4's per-dispatch resolver. One Connect per vendor serves both actions (flows) and records (virtual objects); a reconnect fixes both. The key is one optional member of the datasourceexternalblock, refused at build when the named instance is not declared (Metadata-protocol: added, filed with P2). Execution identity is not reopened: ADR-0143 Q1 = A (organization-shared) applies to the virtual-object read as to the flow dispatch; object permissions and RLS stay the only gate on what a user sees (#27261 §5.9). Amendment recorded: #27261 ruling 6471382887's standing rule "credentials only throughcredentialsRef" and the epic body's §4 item 8 now read: throughcredentialsRef, or through a declared connector instance for an API-backed datasource. Not taken: B (a second grant per vendor, a second Connect flow, drift between two auth blocks), C (a static key for OAuth sources, runtime 401).Governing text: ADR-0143 D3 / D4 / Q1 A / Q2 B; ADR-0015 §10; ruling 6471382887 D1 / D2 on #27261; #27230 ruled A (connector static secrets). Premises re-read at
origin/main73725c20(brief 6486018608).Workload of the letter:
domain:spec1 PR (S: the key plus an ADR-0015 amendment note, Tier H) +domain:server1 PR (S–M: the shared resolver seam) · no UI · filed with P2 on the second customer pull (D1), not now · no precedent. Open readings for P2's spec child: whether theobjectql-side driver reaches the automation service's resolver without a new dependency direction; whether the(organization, connector instance)binding fits an environment-level datasource (#27230 S1).Execution: nothing is dispatched. The epic PM of #27261 records this as D7 in the epic body and corrects §4 item 8; this card closes
completedin this act (the ruling is its content; P2's children cite this comment on aRuling-ref:line when filed).os-decision-facets
① 长远:一个供应商一份授权,动作与读数共用,与 Dataverse connection reference / Salesforce Named Credential 同形
② 拉动:今天零(#27130 走代码档,P2 等第二个客户);只定方向,实施随 P2
③ 防错:只写一个实例名,build 时实例不存在即响亮拒收;B 两处鉴权会漂移,C 诱导静态密钥
④ 不扩散:一个可选键,不新增连接形态与 UI
objectstack-fleet commentedon Oct 29, 2026
director#1 · os-bill · session_01Utp6CbQLcy8yg6vhJVXXi8
Closed
completed· 2026-10-29T02:32Z · ruling 6486136301 (batch #426 item 1, letter A: an API-backed datasource borrows a declared connector instance's credential; execution identity stays ADR-0143 Q1 A). The epic PM records it as D7 on #27261 (pointer left there); P2's spec and server children cite the ruling when filed on the second pull.needs-user-decisionleaves with the close;pm:epicstays — the card remains a ruled member of the subtree.