Skip to content

docs(qa): checklist items for the 17.7 pre-release security fixes - #21943

Merged
objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/issue-21932-checklist-17-7-security
Oct 6, 2026
Merged

objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/issue-21932-checklist-17-7-security

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Part of #21932

Clause-②: no

What changes

The platform checklist gains items for the rules the 17.7 pre-release security follow-up landed, and two re-checks from the card are resolved. All edits are in docs/qa/platform-checklist/areas/*.json. automation.json is untouched (open PR #21928 holds it).

Card row Disposition Item
#21792 (PR #21809) settings audit and secret-valued settings new item platform-core.settings-audit-secret-fingerprint
#21846 (PR #21872) implicit account linking new item identity-auth.implicit-account-linking-ownership
#21839 (PR #21890) share-link password three clauses added, rev 4 to 5 access-security.share-link-capability-tokens
#21836 (PR #21879) global search skips unreadable objects, plus the two cases #21880 lists new item search.global-search-skips-unreadable
re-check 1: A2 / A7 and the plugin-driver boundary rev 2 to 3 integration-system.datasource-credential-refusal-matrix
re-check 2: the #21845 CLI and quorum N1 notes already applied by #21891, no edit cli.scaffold-first-run, cli.scaffold-console-first-paint, approvals.quorum-m-of-n

Each item states rules, not reproductions. Withheld security detail stays out.

Grounding, per row

  • Settings audit fingerprint. Both ledgers record the keyed digest for a secret-valued setting, or no fingerprint when none is available, and never the value or an unkeyed hash. Grounded in settings-service.ts#secretAuditDigest, config-change-audit.ts#CONFIG_CHANGE_ACTION and the contract text at crypto-provider.ts#keyedDigest. The pin is settings-audit-secret-digest.test.ts (7 cases). The offline check carries a positive control: the non-secret key's unkeyed digest IS found, so a no-hit on the secret rows means something. The no-keyed-digest arm cannot be reached on a stock boot, so that clause is scored from the pin.
  • Implicit account linking. Four rules: no implicit link to an unverified local user; an unlink is honoured; an explicit, signed-in link still works and lifts the refusal; the platform IdP exception holds only on its OAuth path. Grounded in implicit-account-linking.ts (decideImplicitLink, IMPLICIT_LINK_REFUSED, PLATFORM_IDP_PROVIDER_ID, recordUnlinkTombstone, refuseImplicitAccountLink) and the published sso.mdx section. The pin is implicit-account-linking.test.ts. The item reuses the local OIDC provider recipe from identity-auth.linked-accounts-social. The platform-IdP clause and the operator override are pin-scored, and knownGaps says why.
  • Share-link password. The stored hash leaves on no exit (mint, list, redemption). The password is accepted from the X-Share-Password header, the query form is still accepted, and the default CORS allow-list carries the header. Both public routes answer Cache-Control: no-store and Vary: X-Share-Password on every outcome, and the authenticated routes do not. Grounded in share-link-service.ts#withoutPasswordHash, share-link-routes.ts#SHARE_LINK_PUBLIC_RESPONSE_HEADERS, the runtime share-links.ts#PUBLIC_RESPONSE_HEADERS and adapter.ts#DEFAULT_CORS_ALLOW_HEADERS. The pins are the [#21839] blocks in share-link-password.test.ts, share-links-public-cache-headers.test.ts and the hono-plugin CORS case. Existing clause indices are unchanged.
  • Global search. An unreadable object is never queried, named or counted. An explicit objects= naming one answers exactly as a name that matches no object. The object stays refused at its own door. Row scope still narrows a searched object, and a term found only in a field hidden from the caller yields no hit. Grounded in protocol.ts#searchAll (the canReadObject pre-filter and the getQueryableFields narrowing). The pins are the dogfood search-skip-unreadable.dogfood.test.ts and the 12 unit cases in protocol.search-skip-unreadable.test.ts. The two security(search): a field-narrowed search still matches through the name field's pinyin companion #21880 cases have no end-to-end pin yet, and knownGaps says so. The open pinyin-companion finding on security(search): a field-narrowed search still matches through the name field's pinyin companion #21880 is recorded as a knownGap with a flag-off instruction, at class level only. The persona reuses the area recipe qa-contributor-bound-member.
  • Datasource credential matrix. A2 / A7 (acceptance[1] and acceptance[6]) are recorded as a known environment gap. They need a reachable credential-protected database of a shipped driver, which no run has had. No recipe is claimed, because none is proven. A successful publish alone may not score them, and the stored-credential half of A7 can be read as a partial reading. Separately, the unknown-driver clause, step 7, its negative and the title now state the ruled boundary from decision: how a datasource driver with no shipped config contract keeps credentials out of metadata (declaration vs. key-name heuristic) #21921 and the docs note docs(drivers): a plugin driver's config is its author's to keep free of credentials #21927. For a plugin driver, only the fixed spellings are redacted (the canonical keys, the former aliases and URL credentials). A non-canonical key served as written is the boundary, not a FAIL. Grounded in common.zod.ts#CANONICAL_CREDENTIAL_KEYS and datasource-credential-redaction.ts#redactableConfigKeys.

Re-check 2 evidence (no edit)

At the claim ref 9dce635337:

Remaining on #21932 (held, not in this PR)

#21932 remains open for these two rows.

Validation (at a72b827e43)

Acceptance notes

  • Source citations name test cases and symbols, never line numbers, because check:platform-checklist refuses a file:line pin.
  • content/docs/data-modeling/drivers.mdx says a plugin driver's config is "stored and served to administrators as written". The read redactor still withholds the canonical spellings (password, authToken), the former aliases and URL credentials for such a driver (redactableConfigKeys). So the docs sentence is slightly broader than the code, and the code is the more protective of the two. The checklist follows the code. This is noted only, with no card. Carrier: none.
  • A run of search.global-search-skips-unreadable picks the walled object and the hidden-field value on the live boot, behind premise guards. The item names likely candidates and does not assume them.

Generated by Claude Code

Adds three items and extends two for the rules the 17.7 pre-release
follow-up landed:

- platform-core.settings-audit-secret-fingerprint (new): the settings
  audit trail fingerprints a secret-valued setting with the keyed digest
  or not at all, never the value or an unkeyed hash.
- identity-auth.implicit-account-linking-ownership (new): no implicit
  link to an unverified local user, an unlink is honoured, the explicit
  signed-in link still works, the platform IdP exception holds only on
  its OAuth path.
- search.global-search-skips-unreadable (new): global search skips
  unreadable objects and fields instead of failing; row scope still
  narrows; a term only in a hidden field yields no hit.
- access-security.share-link-capability-tokens rev 5: the stored hash
  never leaves, the X-Share-Password header, no-store on public answers.
- integration-system.datasource-credential-refusal-matrix rev 3: A2/A7
  recorded as a known environment gap; the unknown-driver clause states
  the ruled plugin-driver boundary.

Claude-Session: https://claude.ai/code/session_01VDtqoecgES7ScQYGbFVDRv
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added the size/m label Oct 6, 2026
@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Oct 6, 2026
@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 6, 2026 03:14
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 6, 2026 03:15
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 6, 2026
Merged via the queue into main with commit 412d7dd Oct 6, 2026
36 of 37 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-21932-checklist-17-7-security branch October 6, 2026 03:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/m skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants