You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
mongo passthrough secrets with no binder slot (proxyPassword, TLS key material, passphrases) stay writable as at-rest cleartext — redacted on read since #9040, but the store-side half has no door #9124
Found while implementing #9040 (the options.auth.password refusal); filed rather than widened there, because these keys fail the refusal's own remedy test.
What was measured (mongodb@7.5.0, the client @objectstack/driver-mongodb spreads config.options into)
Four MongoClient options are honoured client secrets an author can write into the options passthrough:
The datasource secret binder injects exactly ONE secret per datasource, and that slot is the login password (external.credentialsRef resolution). A publish-door refusal of these keys would name a remedy that cannot work and remove the only way to configure an authenticated SOCKS5 proxy or a passphrase-protected key — the same posture as turso's still-writable encryptionKey (#8078; binder-slot expansion is #8081 scope item 4 and was explicitly not decided there either).
They are redacted on every read exit (PASSTHROUGH_SECRET_PATHS in packages/spec/src/data/datasource-credential-redaction.ts, with the restore mirror in service-datasource), so they are no longer SERVED in cleartext. The store-side half remains: the values sit cleartext in sys_metadata, written by an authoring path the platform accepts without comment — the exact residual-risk shape #8082's ruling declined for the login password.
Whether the binder grows named secret slots (covering turso encryptionKey + these four in one mechanism — #8081 item 4's question, generalized), or the platform accepts the at-rest residual risk for non-login secrets, or refuses them without a working remedy. Each option trades differently on capability vs. at-rest exposure; the #9040 PR body carries the per-key measurements.
Finding first-touch grading (triage seat): escalated to the decision inbox — finding → needs-user-decision + domain:services (the binder and its restore mirror live in service-datasource; the mongo driver family is not where a fix lands, so the #5499 investment freeze is not triggered), type Feature.
Why this cannot be graded into the queue: the three candidate dispositions are mutually exclusive, each was explicitly declined by the adjacent rulings (#8082 declined the residual-risk posture for the login password only; #9040 declined refusing keys whose refusal names a non-working remedy; #8081 closed with its item 4 — binder-slot expansion — recorded as undecided), and the choice sits on a security boundary, which is manual-floor territory regardless of prism alignment.
The decision: for the four honoured mongo client secrets writable via options passthrough (proxyPassword, tlsCertificateKeyFilePassword, key, passphrase) — and turso's encryptionKey, same shape — pick one:
A. Grow the binder: named secret slots per datasource (generalises the single login slot; one mechanism covers all five keys).
Measured business pull — zero measured today: no first-party example or known deployment uses an authenticated SOCKS5 proxy or passphrase-protected TLS key material through the passthrough (the keys were found by census, not by a user).
AI-agent error-resistance — B is the weakest (silent acceptance of a secret-shaped write is the quiet-tolerance shape); A and C both give the authoring path a loud, correct answer.
Startup scope discipline — A is a permanent capability + maintenance obligation bought against zero pull; B is the cheapest standing posture; C is cheap but subtracts a capability the client library genuinely honours.
Recommendation: B now, with A as the recorded route when pull materialises — accept-and-document the non-login residual risk (one sentence in the datasource security docs naming the four keys), and record that the first real deployment needing an authenticated proxy or key passphrase converts this card into the binder-slot programme (A). Prisms do not all point one way (coherence favours A), and the boundary is security — hence your inbox rather than auto-adjudication.
Maintainer ruling (2026-08-17, recorded by PM session session_01NYgmGheCzM6NrHZN436Cxf). The maintainer reviewed the decision-inbox report's six new cards and accepted the recommendations in full, verbatim: 「新进卡六张 同意你的建议」. For this card:
Ruled: Option B now — accept-and-document the at-rest residual risk for non-login secrets; Option A (named binder slots) is the recorded route when pull materialises.
Dispatching on the 03:19Z maintainer ruling: Option B — accept-and-document. Deliverable is the docs statement naming the four mongo options-passthrough keys plus turso's encryptionKey, and the recorded restart condition that converts this into the binder-slot programme (A).
⛔ Scope fence for the implementer: this is a documentation deliverable. Do not add a publish-door refusal (that is Option C, explicitly rejected per #9040's refusal-names-a-working-remedy invariant), and do not grow the binder (that is A, held for measured pull).
{
"issue": 9124,
"status": "done",
"branch": "claude/issue-9124-mongo-passthrough-at-rest-doc",
"pr": "https://github.com/objectstack-ai/objectstack/pull/9253",
"premise_still_valid": true,
"summary": "Implemented the maintainer's Option B ruling (accept-and-document) as a docs-only change: a new subsection in content/docs/data-modeling/drivers.mdx names the four mongo options-passthrough keys (proxyPassword, tlsCertificateKeyFilePassword, key, passphrase) plus turso's encryptionKey, states they are writable and stored at rest in sys_metadata as plain text, credits #9040's read-side redaction as the only protection today, and records the named restart condition (first real deployment needing an authenticated SOCKS5 proxy or passphrase-protected key converts this into the binder-slot programme, Option A). Verified every premise before writing: PASSTHROUGH_SECRET_PATHS in packages/spec/src/data/datasource-credential-redaction.ts covers exactly these keys, the restore mirror (restoreRedactedConfig) lives in service-datasource wired into datasource-admin-service.ts, turso's encryptionKey is a genuinely-writable top-level config key (same at-rest/redacted-on-read outcome shape, different code path from mongo's nested passthrough list), and sys_metadata is confirmed as the real durable storage table. No runtime code touched; Option A (binder slots) and Option C (publish-door refusal) stayed out of scope per the scope fence.",
"tests": "Documentation-only change; no test suite applies. Local gates derived via `node scripts/pm/dispatch-gates.mjs content/docs/data-modeling/drivers.mdx`, all green at commit 5dd33ddd0142131fd30b43bbcec7d749ec4285b1 (git rev-parse --short HEAD = 5dd33ddd0): `pnpm check:nul-bytes` (OK, 6041 files scanned, no control bytes), `pnpm check:docs-audit-scope` (OK, 178 hand-written docs in sync), `pnpm check:docs-redirects` (OK, 92 entries resolved), `pnpm check:role-word` (OK, 43 baselined files, no new occurrences) at repo root; `pnpm --filter @objectstack/spec run check:empty-state` (OK, all classified), `check:liveness` (green -- pre-existing unregistered-dogfood-proof-tag warnings are informational and unrelated to this change), `check:strictness-ledger` (OK), `check:variant-docs` (OK, 18 discriminated unions governed/exempt) in packages/spec, since content/docs/** is a CI trigger path in spec-liveness-check.yml. packages/spec was built first (pnpm --filter @objectstack/spec build, exit 0) per the toolchain-trap note; gen:schema/gen:openapi produced no diff since no spec source changed. CI on PR #9253 is in_progress at report time -- not waited on per the draft-PR-time reporting contract.",
"open_questions": [],
"out_of_scope_findings": [
"filed as #9254: the auto-generated `options` field description in packages/spec/src/data/driver/mongo.zod.ts (rendered into content/docs/references/data/driver-mongo.mdx and the Studio connection-form help text) overstates the write-side refusal -- it reads \"credential material is refused\", true only for options.auth.password, not for the four keys this card documents. Not fixed in-place: it is a packages/spec source edit pulling in a different (build/docs-regen) verification surface than this docs-only PR."
]
}
Activity
os-project-manager commentedon Aug 16, 2026
Finding first-touch grading (triage seat): escalated to the decision inbox —
finding→needs-user-decision+domain:services(the binder and its restore mirror live in service-datasource; the mongo driver family is not where a fix lands, so the #5499 investment freeze is not triggered), typeFeature.Why this cannot be graded into the queue: the three candidate dispositions are mutually exclusive, each was explicitly declined by the adjacent rulings (#8082 declined the residual-risk posture for the login password only; #9040 declined refusing keys whose refusal names a non-working remedy; #8081 closed with its item 4 — binder-slot expansion — recorded as undecided), and the choice sits on a security boundary, which is manual-floor territory regardless of prism alignment.
The decision: for the four honoured mongo client secrets writable via
optionspassthrough (proxyPassword,tlsCertificateKeyFilePassword,key,passphrase) — and turso'sencryptionKey, same shape — pick one:sys_metadatastays for non-login secrets; read-side redaction (mongoconfig.options.auth.passwordis a fourth spelling of an inline credential — authorable, persisted cleartext, unredacted, and read by the client #9040, shipped) remains the only protection.Four-prism:
config.options.auth.passwordis a fourth spelling of an inline credential — authorable, persisted cleartext, unredacted, and read by the client #9040 itself honoured.Recommendation: B now, with A as the recorded route when pull materialises — accept-and-document the non-login residual risk (one sentence in the datasource security docs naming the four keys), and record that the first real deployment needing an authenticated proxy or key passphrase converts this card into the binder-slot programme (A). Prisms do not all point one way (coherence favours A), and the boundary is security — hence your inbox rather than auto-adjudication.
Generated by Claude Code
os-zhuang commentedon Aug 17, 2026
Maintainer ruling (2026-08-17, recorded by PM session
session_01NYgmGheCzM6NrHZN436Cxf). The maintainer reviewed the decision-inbox report's six new cards and accepted the recommendations in full, verbatim: 「新进卡六张 同意你的建议」. For this card:Ruled: Option B now — accept-and-document the at-rest residual risk for non-login secrets; Option A (named binder slots) is the recorded route when pull materialises.
proxyPassword,tlsCertificateKeyFilePassword,key,passphrase) and turso'sencryptionKey: written via theoptionspassthrough they are stored at rest insys_metadataunencrypted; read-side redaction (mongoconfig.options.auth.passwordis a fourth spelling of an inline credential — authorable, persisted cleartext, unredacted, and read by the client #9040) is the shipped protection.config.options.auth.passwordis a fourth spelling of an inline credential — authorable, persisted cleartext, unredacted, and read by the client #9040's own invariant.Label flipped
needs-user-decision→pm:queue(docs deliverable) in the same stroke.Generated by Claude Code
os-project-manager commentedon Aug 17, 2026
Claim — PM dispatch seat, session
session_01Y26DJEHSBhhAQ6wwfsHNza, branchclaude/issue-9124-mongo-passthrough-at-rest-doc.Dispatching on the 03:19Z maintainer ruling: Option B — accept-and-document. Deliverable is the docs statement naming the four mongo
options-passthrough keys plus turso'sencryptionKey, and the recorded restart condition that converts this into the binder-slot programme (A).⛔ Scope fence for the implementer: this is a documentation deliverable. Do not add a publish-door refusal (that is Option C, explicitly rejected per #9040's refusal-names-a-working-remedy invariant), and do not grow the binder (that is A, held for measured pull).
Generated by Claude Code
docs(data): accept-and-document mongo/turso passthrough secrets with …
os-project-manager commentedon Aug 17, 2026
{ "issue": 9124, "status": "done", "branch": "claude/issue-9124-mongo-passthrough-at-rest-doc", "pr": "https://github.com/objectstack-ai/objectstack/pull/9253", "premise_still_valid": true, "summary": "Implemented the maintainer's Option B ruling (accept-and-document) as a docs-only change: a new subsection in content/docs/data-modeling/drivers.mdx names the four mongo options-passthrough keys (proxyPassword, tlsCertificateKeyFilePassword, key, passphrase) plus turso's encryptionKey, states they are writable and stored at rest in sys_metadata as plain text, credits #9040's read-side redaction as the only protection today, and records the named restart condition (first real deployment needing an authenticated SOCKS5 proxy or passphrase-protected key converts this into the binder-slot programme, Option A). Verified every premise before writing: PASSTHROUGH_SECRET_PATHS in packages/spec/src/data/datasource-credential-redaction.ts covers exactly these keys, the restore mirror (restoreRedactedConfig) lives in service-datasource wired into datasource-admin-service.ts, turso's encryptionKey is a genuinely-writable top-level config key (same at-rest/redacted-on-read outcome shape, different code path from mongo's nested passthrough list), and sys_metadata is confirmed as the real durable storage table. No runtime code touched; Option A (binder slots) and Option C (publish-door refusal) stayed out of scope per the scope fence.", "tests": "Documentation-only change; no test suite applies. Local gates derived via `node scripts/pm/dispatch-gates.mjs content/docs/data-modeling/drivers.mdx`, all green at commit 5dd33ddd0142131fd30b43bbcec7d749ec4285b1 (git rev-parse --short HEAD = 5dd33ddd0): `pnpm check:nul-bytes` (OK, 6041 files scanned, no control bytes), `pnpm check:docs-audit-scope` (OK, 178 hand-written docs in sync), `pnpm check:docs-redirects` (OK, 92 entries resolved), `pnpm check:role-word` (OK, 43 baselined files, no new occurrences) at repo root; `pnpm --filter @objectstack/spec run check:empty-state` (OK, all classified), `check:liveness` (green -- pre-existing unregistered-dogfood-proof-tag warnings are informational and unrelated to this change), `check:strictness-ledger` (OK), `check:variant-docs` (OK, 18 discriminated unions governed/exempt) in packages/spec, since content/docs/** is a CI trigger path in spec-liveness-check.yml. packages/spec was built first (pnpm --filter @objectstack/spec build, exit 0) per the toolchain-trap note; gen:schema/gen:openapi produced no diff since no spec source changed. CI on PR #9253 is in_progress at report time -- not waited on per the draft-PR-time reporting contract.", "open_questions": [], "out_of_scope_findings": [ "filed as #9254: the auto-generated `options` field description in packages/spec/src/data/driver/mongo.zod.ts (rendered into content/docs/references/data/driver-mongo.mdx and the Studio connection-form help text) overstates the write-side refusal -- it reads \"credential material is refused\", true only for options.auth.password, not for the four keys this card documents. Not fixed in-place: it is a packages/spec source edit pulling in a different (build/docs-regen) verification surface than this docs-only PR." ] }Generated by Claude Code
Generated by Claude Code
fix(spec): correct mongo options describe string to state the real re…
docs(data): accept-and-document mongo/turso passthrough secrets with …
fix(spec): correct mongo options describe string to state the real re…