Repository navigation
docs(drivers): say what the read path withholds from a plugin driver's config - #21953
Merged
objectstack-fleet[bot] merged 1 commit intoOct 6, 2026
Conversation
…s config The plugin-contributed-driver paragraph said `config` is "stored and served to administrators as written". The write half holds: a driver with no shipped contract gets no config verdict, so the row is stored as written. The read half did not: `redactDatasourceConfig` hides the canonical credential keys (`password`, `authToken`) and their former aliases at every object depth, plus URL userinfo passwords and credential query parameters, for every driver, contracted or not. The paragraph now names that fixed, name-based set, says everything else is served as written, and keeps the plugin author's responsibility and the `external.credentialsRef` route. Docs only; no code change. Claude-Session: https://claude.ai/code/session_01VF48aw8RPG6wzDnMgp6rtw Co-authored-by: Claude <noreply@anthropic.com>
This was referenced Oct 6, 2026
objectstack-fleet
Bot
deleted the
claude/issue-21950-plugin-driver-config-redaction-docs
branch
October 6, 2026 06:12
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #21950
Clause-②: no
What
One paragraph in
content/docs/data-modeling/drivers.mdx: the plugin-contributed-driver paragraph that #21927 landed. It said a plugin driver'sconfigis "stored and served to administrators as written". The stored half holds. The served half did not: the read path withholds a fixed, name-based set for every driver, contracted or not. The paragraph now names that set and says everything else is served as written. It keeps #21927's intent: the config is unvalidated, keeping secrets out of it is the plugin author's job, and the credential belongs inexternal.credentialsRef.Docs only, no code change. The ruling on #21921 stands (no heuristic, no registration API): 「我觉得不需要协议,也不需要改动这么多代码」 and 「同意作废,文档补一句」.
Before (
drivers.mdx:157-:160at3c7785d4):After:
The code the new text rests on (
3c7785d4)Every clause was checked against the code, not taken from the card.
packages/spec/src/data/driver/config-registry.zod.ts:435:return id ? DRIVER_CONFIG_SCHEMAS[id] : undefined;config-registry.zod.ts:522:if (!schema) return { known: false };packages/spec/src/data/datasource.zod.ts:693runsreportDriverConfigIssues(ctx, ds.driver, ds.config, ['config']);, and:485returns early onif (!result.known) return;.datasource-admin-service.ts:1031(validateDriverConfig) and:1061(DatasourceSchema.safeParse(record)).packages/spec/src/data/datasource-credential-redaction.ts:372:const canonical = derived.length > 0 ? derived : [...CANONICAL_CREDENTIAL_KEYS];. For a driver with no contract,derivedis empty.:374:return [...new Set([...canonical, ...FORMER_CREDENTIAL_ALIASES, ...stillWritable])];packages/spec/src/data/driver/common.zod.ts:437:export const CANONICAL_CREDENTIAL_KEYS = ['password', 'authToken'] as const;The alias list starts at:448.datasource-credential-redaction.ts:520buildsconst hidden = new Set(redactableConfigKeys(driver));, and:527testsif (hidden.has(key)), an exact-case match.:546-:547recurse only intovalue && typeof value === 'object' && !Array.isArray(value). An array falls through to:550,out[key] = value;.:537runsredactUrlCredentials(value)on every string value.:451) composesredactUrlPassword(:405, which keeps the username) withredactUrlCredentialQueryParams(:436). The second filters onCREDENTIAL_URL_QUERY_PARAM_NAMES(common.zod.ts:311-:312, the union of:299-:300), matched case-insensitively (common.zod.ts:621).passthroughSecretPathsreturns[]when the id does not resolve (:227).refusedCredentialPathsreads a schema that isundefined(config-registry.zod.ts:435).datasource-admin-service.ts:554(getDatasource) andpackages/spec/src/kernel/metadata-type-redaction.ts:93(the built-indatasourceredactor for the metadata read exits) both callredactDatasourceConfig.datasource-credential-redaction.ts:66-:71("canonical spellings are therefore redacted by NAME for unknown drivers too") and:88-:94("strips it for EVERY driver").Measured, not only read. A scratch probe (not committed) ran
redactDatasourceConfig('com.vendor.snowflake', …)andDatasourceSchema.safeParsefromsrcat3c7785d4:password,authToken,pwd,token, a nestedtoken, a nested URL's userinfo password and?password=/?AuthToken=query pairs.Password(case variant),privateKey,apiKey,clientSecret, a nestedsecretand apasswordinside an array element as written.getMetadataTypeRedactor('datasource')reported the same paths underconfig..Checks
The diff is one
.mdxfile and touches no package, so there is no dependency-closure build step for the diff itself.@objectstack/lintand@objectstack/client/@objectstack/client-reactwere built (with their closures) only because three of the gates read built output.node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackon the actual diff at809a8641. It gives the same 40 commands the dispatch named.809a8641. Reconciliation:✓ dispatch-gates --ran: 40 derived famil(ies) accounted for — 40 run, 0 NOT-MEASURED (a DERIVED zero — all 40 recorded an exit code and none of them is 3).pnpm --filter @objectstack/spec run check:skill-examplesfirst exited 3 withPREREQUISITE NOT MET(noclient-reactdeclarations). That exit is not a measurement. After building@objectstack/client-reactand@objectstack/clientit exited 0:✅ 262 prose examples type-check across 3 surface(s).dispatch-gateslists outside its 40, and theBuild Docsjob.Changeset
None (
skip-changeset). No published package'sfiles[]shipscontent/docs. As a probe, the new sentence's text was searched for in every packagedist/, inpackages/spec/llms.txt, inpackages/spec/promptsand inskills/: 0 hits. Positive control:redactDatasourceConfiginpackages/spec/dist, 10 files.Acceptance notes
Out of scope, handed to the seat for filing (code, not docs): the read-path still-writable table (
STILL_WRITABLE_CREDENTIAL_KEYS) is indexed by the rawdriverspelling atdatasource-credential-redaction.ts:373. Its siblingpassthroughSecretPathsresolves aliases throughresolveDriverId(:226-:227), and this lookup does not. A function-level probe shows two symptoms:turso|libsqlrow of this page's at-rest table (drivers.mdx:185) holds for one spelling only.Object.prototypemember makes the lookup throw (stillWritable is not iterable). This fails closed.One line, one fix. This PR does not touch it.
This PR does not change the at-rest-risk section below the paragraph.
Generated by Claude Code