Commit f595a7f
committed
fix(approvals): refuse cross-org targeting on directory-less approver types
`user`, `field` and `manager` return EARLY in `resolveApproverSpec` — they name
a person outright instead of expanding a directory. D9's org resolution (#3824)
sat AFTER those returns, so an `organization` declared on one of them never
reached the check and was silently INERT.
That is precisely the behaviour ADR-0105 D9 rules out and the authoring docs
promise against ("`organization` on those is refused at runtime"). The `os lint`
rule caught it at author time, but the runtime claim was false — and a flow
stored before the lint existed, or assembled programmatically, got no signal.
Resolution moves to the top of `resolveApproverSpec`, above every early return,
so the refusal reaches all three types. The ordinary path is unchanged and
still free: with no `organization` declared the resolver returns the request's
organization without reading anything.
Why the existing tests missed it: `approver-org-scope.test.ts` calls the
resolver DIRECTLY, so it never traverses the early return, and the service-level
integration test only covered `position`. Both gaps are closed — the new case
opens a real request for each of the three directory-less types and asserts the
refusal, plus one that a directory-less approver with NO declaration is
untouched, so the guard cannot start costing the ordinary case.
Found by cloud's group-posture dogfood on a real `group` boot. The two links
that dogfood was written to check both hold: a cross-organization approver does
reach her queue through the D2 union wall, and `decide()` does accept her.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015FebXPaaGrLhGKw1LHPbpL1 parent 1d4756e commit f595a7f
3 files changed
Lines changed: 75 additions & 6 deletions
File tree
- .changeset
- packages/plugins/plugin-approvals/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 | + | |
Lines changed: 22 additions & 6 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
784 | 784 | | |
785 | 785 | | |
786 | 786 | | |
| 787 | + | |
| 788 | + | |
| 789 | + | |
| 790 | + | |
| 791 | + | |
| 792 | + | |
| 793 | + | |
| 794 | + | |
| 795 | + | |
| 796 | + | |
| 797 | + | |
| 798 | + | |
| 799 | + | |
| 800 | + | |
| 801 | + | |
| 802 | + | |
| 803 | + | |
787 | 804 | | |
788 | 805 | | |
789 | 806 | | |
| |||
798 | 815 | | |
799 | 816 | | |
800 | 817 | | |
801 | | - | |
802 | | - | |
803 | | - | |
804 | | - | |
805 | | - | |
806 | | - | |
| 818 | + | |
| 819 | + | |
| 820 | + | |
| 821 | + | |
| 822 | + | |
807 | 823 | | |
808 | 824 | | |
809 | 825 | | |
| |||
Lines changed: 27 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
158 | 158 | | |
159 | 159 | | |
160 | 160 | | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
161 | 188 | | |
162 | 189 | | |
163 | 190 | | |
| |||
0 commit comments