Skip to content

fix(auth): reject unsafe children projections#183

Closed
marcus-pousette wants to merge 1 commit into
fix/auth-scope-source-parentfrom
fix/auth-children-filter-redaction
Closed

fix(auth): reject unsafe children projections#183
marcus-pousette wants to merge 1 commit into
fix/auth-scope-source-parentfrom
fix/auth-children-filter-redaction

Conversation

@marcus-pousette

Copy link
Copy Markdown
Collaborator

Stack

Stacked on #182, which is stacked on #157. Merge #157#182 → this PR.

In one sentence

Fail closed when a capability-scoped children(parent) projection needs an out-of-scope operation that cannot yet be represented without revealing restricted data.

Why rejection is necessary

The core children(parent) result is a causal closure. A move/delete can be selected under its old parent after the node has already left the readable subtree, and a descendant payload/insert can be selected because it restores an ancestor.

Silently removing that operation leaves the receiver's projection stale. Sending the full operation can reveal a private destination, descendant, or payload. Sync v0 has no redacted remove/restore record that can satisfy both requirements.

Until that wire representation exists, the only safe behavior is to reject the whole scoped projection.

What changes?

  • filter(all) keeps its existing per-operation redaction behavior.
  • For children(parent), a denied move, delete, tombstone, or payload rejects the projection.
  • An out-of-scope descendant insert or boundary-crossing insert-upsert also rejects because it is a causal dependency.
  • A denied direct-child insert can still be suppressed when it represents a private child rather than a required boundary transition.

Size and validation

  • 3 files, +84/-5
  • production: +30/-4
  • tests: +49/-1
  • changeset: 5 lines
  • auth TypeScript build and all 35 auth tests pass

Regressions cover move, delete, tombstone, payload, insert-upsert, and descendant restore dependencies.

Follow-up

A future protocol version should add redacted boundary removal/restore records. This PR deliberately does not invent an ad-hoc projection that could leak data or diverge.

@marcus-pousette

Copy link
Copy Markdown
Collaborator Author

Closing rather than stacking another patch: the current-membership filter still leaks historical operations after a node leaves an excluded subtree and later re-enters (including signed moves that name the excluded parent and superseded payloads). The checks here only fire while the node is currently out of scope, so the PR's security claim is incomplete. A smaller fail-closed op-log projection replacement is in progress on top of #188; it will be linked here when opened.

@marcus-pousette

Copy link
Copy Markdown
Collaborator Author

Replacement opened as #190. It requires state-independent document-wide access for historical op-log projection and enforces read_payload for payload updates, clears, and inline insert payloads. Production code is net smaller, and the PR body includes the concrete leave/private-write/re-enter leak that this PR could not close.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant