Skip to content

fix(workforce-validation): block ordinary public construction of study projections #242

Description

@seonghobae

Finding

Draft #235 made ValidityStudyView structurally immutable after purpose-bound authorization, but the exported type was still ordinarily constructible through ValidityStudyView(...). That public API shape suggested that callers could manufacture an object described as an authorized, field-minimized output without passing through read_validity_study(...), Keyverse policy evaluation, owner-port target verification, or persisted-record reconstruction.

This is distinct from #241. #241 prevents post-read mutation of a legitimate returned projection. #242 narrows the ordinary constructor surface; it does not make a Python runtime type cryptographically unforgeable or suitable as authorization provenance.

Test-first repair

Canonical #235 ordinary lineage:

  • 1b1d2e5c7cd492f57c806408618429e83f1e09d4: ordinary public ValidityStudyView(...) construction must raise TypeError. It was superseded before hosted execution, so no hosted RED is claimed.
  • b655063cc7d9680de5743949b9b66e631530b904: the public constructor becomes non-issuing; the authorized read path constructs the projection only after Keyverse authorization, owner-port read, exact record reconstruction, and tenant/study target verification.
  • 412c62b279a4d3b5448dd2817c835e0aa85b412d: README records the decisive invariant: the view is a data projection, not a durable authorization credential or cryptographic capability. Consequential downstream actions must re-authorize and re-resolve authoritative state.
  • workforce-validation: remove importable view issuer that bypasses authorized read path #245 later removes the remaining ordinary module-level _issue_validity_study_view(...) helper. Current source constructs the tuple-backed projection inline after authorization and target verification.

Low-level tuple.__new__(ValidityStudyView, ...) can still fabricate the runtime shape, as is inherent to this tuple-backed Python value representation. That is outside the supported ordinary constructor surface and, more importantly, is not accepted anywhere as evidence that authorization occurred. The security boundary is purpose-bound authorization plus authoritative re-resolution, not exclusivity of object construction.

CodeRabbit independently reviewed the relevant predecessor repairs and reported no blocking issue in their requested scopes. Those reviews are historical static evidence only and are not transferred as current merge approval.

Current successor state

#235 has since advanced through #243#245, #249 and #253 to exact 72ec2296cbc6b2df94e9c4e7394a8990061d0c88, still open · Draft · mechanically mergeable over protected develop@eb9757f8649aaad026a9865508d9aad50c1a7a4f. Current source keeps ordinary ValidityStudyView(...) non-issuing, exposes no module-level unconditional issuer, reconstructs principal/record evidence, validates exact UUID storage, captures the exact concrete repository function before authorization, rejects the inherited Protocol declaration, and invokes that same captured function after authorization.

Exact-head CodeRabbit reviewed 72ec2296... for the #253/#249 scope and found no blocking defect there. This is current-head static evidence only, not a ruleset-qualifying APPROVED review.

Current-head Foundation 33974101917, CodeQL PR 33974102004, SAST Semgrep 33974101951, and Security Scan 33974101943 remain queued/non-terminal at the latest fresh read. No hosted GREEN, 100% owned statement/branch coverage, executed PostgreSQL GREEN, terminal security completion, or qualifying approval is claimed.

Keep this issue open through exact-head hosted/security acceptance, qualifying ordinary review, and normal protected integration. #100 retains the durable single-writer baseline invariant. Do not treat constructor exclusivity, tuple runtime type, or a predecessor static review as reusable authorization evidence.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions