Commit 9796e7c
feat(security): two-doors separation for permission sets (ADR-0086 P2) (#2573)
Splits who may change a permission set into two non-overlapping doors,
enforced at the data layer instead of by convention.
块1 — package door (publish-time materialization):
- metadata-protocol: generic publish-time materializer registry
(registerPublishMaterializer); publishMetaItem projects a published body
into its data-plane row and surfaces materializeApplied (best-effort,
never thrown — same contract as seedApplied). publishPackageDrafts
aggregates it across the batch so a refused set is surfaced, not swallowed.
- promoteDraft now returns the draft's packageId so the materializer stamps
the owning package.
- plugin-security registers a `permission` materializer that upserts the
published set into sys_permission_set with managed_by:'package' +
package_id. The single-set upsert (upsertPackagePermissionSet) is shared
with bootstrapDeclaredPermissions, so boot and publish apply identical
own-row / foreign-package / env-authored rules. A publish that materializes
nothing (no owning package / name owned elsewhere) reports success:false.
块2 — admin door (data-layer write gate):
- The security middleware refuses any admin-door write to a
sys_permission_set row with managed_by:'package', and refuses a payload
(insert OR update, single object OR array) that forges managed_by:'package'.
- Placed before the empty-principal fall-open and the CRUD check, so it is a
real, unconditional boundary — it holds for a principal-less context and for
a superuser with modifyAllRecords. A multi-row/filter write is denied only
when a package-owned row actually falls within the write's own filter, so
env-only bulk edits still succeed. System/boot writes carry isSystem and
bypass the middleware, so the seeder and materializer are unaffected.
Tested: unit (materialize semantics, gate incl. array-forge / update-to-forge
/ principal-less / precise-bulk) + a dogfood test booting the real showcase
stack that publishes a package permission draft and drives the admin door
against the seeded package row over REST.
Claude-Session: https://claude.ai/code/session_014y5kiH3aPLWtRRRGcVrXcT
Co-authored-by: Claude <noreply@anthropic.com>1 parent 9860de4 commit 9796e7c
8 files changed
Lines changed: 688 additions & 51 deletions
File tree
- .changeset
- packages
- dogfood/test
- metadata-protocol/src
- plugins/plugin-security/src
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
Lines changed: 111 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
695 | 695 | | |
696 | 696 | | |
697 | 697 | | |
| 698 | + | |
| 699 | + | |
| 700 | + | |
| 701 | + | |
| 702 | + | |
| 703 | + | |
| 704 | + | |
| 705 | + | |
| 706 | + | |
| 707 | + | |
| 708 | + | |
| 709 | + | |
| 710 | + | |
| 711 | + | |
| 712 | + | |
| 713 | + | |
| 714 | + | |
| 715 | + | |
| 716 | + | |
| 717 | + | |
| 718 | + | |
| 719 | + | |
| 720 | + | |
| 721 | + | |
698 | 722 | | |
699 | 723 | | |
700 | 724 | | |
| |||
717 | 741 | | |
718 | 742 | | |
719 | 743 | | |
| 744 | + | |
| 745 | + | |
| 746 | + | |
| 747 | + | |
| 748 | + | |
| 749 | + | |
| 750 | + | |
| 751 | + | |
| 752 | + | |
| 753 | + | |
| 754 | + | |
| 755 | + | |
| 756 | + | |
720 | 757 | | |
721 | 758 | | |
722 | 759 | | |
| |||
729 | 766 | | |
730 | 767 | | |
731 | 768 | | |
| 769 | + | |
| 770 | + | |
| 771 | + | |
| 772 | + | |
| 773 | + | |
| 774 | + | |
| 775 | + | |
| 776 | + | |
| 777 | + | |
| 778 | + | |
| 779 | + | |
| 780 | + | |
732 | 781 | | |
733 | 782 | | |
734 | 783 | | |
| |||
4042 | 4091 | | |
4043 | 4092 | | |
4044 | 4093 | | |
| 4094 | + | |
| 4095 | + | |
| 4096 | + | |
| 4097 | + | |
| 4098 | + | |
| 4099 | + | |
| 4100 | + | |
4045 | 4101 | | |
4046 | 4102 | | |
4047 | 4103 | | |
| |||
4098 | 4154 | | |
4099 | 4155 | | |
4100 | 4156 | | |
| 4157 | + | |
4101 | 4158 | | |
4102 | 4159 | | |
4103 | 4160 | | |
| |||
4112 | 4169 | | |
4113 | 4170 | | |
4114 | 4171 | | |
| 4172 | + | |
| 4173 | + | |
| 4174 | + | |
| 4175 | + | |
| 4176 | + | |
| 4177 | + | |
| 4178 | + | |
| 4179 | + | |
| 4180 | + | |
| 4181 | + | |
| 4182 | + | |
| 4183 | + | |
| 4184 | + | |
| 4185 | + | |
| 4186 | + | |
| 4187 | + | |
| 4188 | + | |
| 4189 | + | |
| 4190 | + | |
| 4191 | + | |
| 4192 | + | |
| 4193 | + | |
| 4194 | + | |
4115 | 4195 | | |
4116 | 4196 | | |
4117 | 4197 | | |
| |||
4243 | 4323 | | |
4244 | 4324 | | |
4245 | 4325 | | |
| 4326 | + | |
| 4327 | + | |
| 4328 | + | |
| 4329 | + | |
| 4330 | + | |
| 4331 | + | |
| 4332 | + | |
| 4333 | + | |
| 4334 | + | |
| 4335 | + | |
| 4336 | + | |
| 4337 | + | |
| 4338 | + | |
| 4339 | + | |
4246 | 4340 | | |
4247 | 4341 | | |
4248 | 4342 | | |
| |||
4295 | 4389 | | |
4296 | 4390 | | |
4297 | 4391 | | |
| 4392 | + | |
| 4393 | + | |
| 4394 | + | |
| 4395 | + | |
4298 | 4396 | | |
4299 | 4397 | | |
4300 | 4398 | | |
| |||
4316 | 4414 | | |
4317 | 4415 | | |
4318 | 4416 | | |
| 4417 | + | |
| 4418 | + | |
| 4419 | + | |
| 4420 | + | |
| 4421 | + | |
| 4422 | + | |
| 4423 | + | |
| 4424 | + | |
| 4425 | + | |
| 4426 | + | |
| 4427 | + | |
4319 | 4428 | | |
4320 | 4429 | | |
4321 | 4430 | | |
| |||
4384 | 4493 | | |
4385 | 4494 | | |
4386 | 4495 | | |
| 4496 | + | |
| 4497 | + | |
| 4498 | + | |
| 4499 | + | |
| 4500 | + | |
| 4501 | + | |
| 4502 | + | |
| 4503 | + | |
4387 | 4504 | | |
4388 | 4505 | | |
4389 | 4506 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
577 | 577 | | |
578 | 578 | | |
579 | 579 | | |
580 | | - | |
| 580 | + | |
581 | 581 | | |
582 | 582 | | |
583 | 583 | | |
| |||
629 | 629 | | |
630 | 630 | | |
631 | 631 | | |
632 | | - | |
| 632 | + | |
| 633 | + | |
| 634 | + | |
| 635 | + | |
633 | 636 | | |
634 | 637 | | |
635 | 638 | | |
| |||
0 commit comments