Skip to content

security(metadata): tighten the draft publish gate and package identity for org view overlays (follow-up to #21864) #21934

Description

@objectstack-fleet

Follow-up from the round-5 independent security review of PR #21864 (card #21835), which passed. These are the low and informational items it recorded. Each one either is older than #21864 or extends the known limit the maintainer accepted on #21835 (comment 6005722623). None of them blocks #21864. Classes and positions only; detail is held by the PM session (session_018zT8d8NpiQ1ExhuNd5TxY6).

  1. Package identity of a served org overlay (LOW). Applies only to overlays stored before a withdrawal, or restored by rollback or revert.
    • The org read stamps a package-less org overlay with the package of each base row of its name.
    • So the doors cannot tell an inherited package from the row's own. Where two packages ship the same view name, the withdrawal of one package can miss that overlay.
    • Direction: mark stamped copies in the merge, or have the doors read the org row's own package_id. A body stored package-less is compared against every package's withdrawal.
    • Positions: packages/metadata-core/src/anonymous-form-intake.ts (package comparison) and packages/metadata-protocol/src/protocol.ts (the list merge's package stamp).
  2. Publish gate and promotion are separate reads (LOW, older than fix(rest,metadata-protocol): a public form's intake withdrawal at any metadata layer holds; layering can only narrow intake #21864).
    • The gate's reads of the draft and the promotion's own read are not pinned to each other.
    • A draft saved in between can be promoted without being judged.
    • Direction: pass the judged draft's hash into promoteDraft and refuse with a conflict when the row's hash differs.
  3. Lock lookup uses the request's package, not the resolved one (INFO, older than fix(rest,metadata-protocol): a public form's intake withdrawal at any metadata layer holds; layering can only narrow intake #21864).
    • In the publish path, lockWriteRefusal takes request.packageId rather than the package key the gate resolved.
    • Direction: thread the resolved key into the lock lookup. Leave the authoring-rule narrowing as it is; it is documented as deliberate.

Priced by reach (pm-dispatch rule proposed in #21929): each needs an administrator-level overlay or draft, or a narrow timing window, so this is low priority.


Generated by Claude Code

Activity

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

Metadata

Metadata

Labels

area:accessPermissions that actually hold — RLS/FLS, sharing model, write-path guardsbugSomething isn't workingdomain:enginepriority:p3security

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions