Commit 45ba6ae
Fix 12 bugs from audit (security + correctness + tests) (#458)
* Gate gateway write and job-status endpoints behind auth
Fixes #446
* Guard version registry latest pointer against downgrade
Fixes #447
* Persist budget-window failure state across polls
Fixes #448
* Back off scheduler poll interval exponentially
Fixes #449
* Forbid unknown gateway request fields and cap payload size
Fixes #450
* Accumulate budget-window totals in Decimal
Fixes #451
* Make state_tax_revenue_impact optional for UK results
Fixes #452
* Redact exception details from gateway error responses
Fixes #453
* Guard budget-window child state transitions from missing entries
Fixes #454
* Redact Logfire span payloads for simulation functions
Fixes #455
* Clean up GCP credential temp file after use
Fixes #456
* Rename scheduler test and scaffold real-Modal integration bucket
Fixes #457
* Cache JWTDecoder at module scope to preserve JWKS LRU
The gateway auth dependency was constructing a new JWTDecoder per request,
which defeated PyJWKClient's internal JWKS cache and triggered a live
JWKS fetch on every gated call. Hoist decoder construction behind a
functools.lru_cache keyed on (issuer, audience) so one decoder is reused
across the lifetime of the process while still honoring env rotation
and app.dependency_overrides.
New coverage: same-env returns same instance, rotated audience returns
fresh instance, and a smoke test asserts JWTDecoder.__init__ runs at
most once across five requests. Also adds a positive-path test verifying
that app.dependency_overrides[require_auth] keeps gated endpoints
reachable (guards the override path other tests rely on).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Refuse to start when GATEWAY_AUTH_DISABLED leaks into production
Previously GATEWAY_AUTH_DISABLED was documented as dev-only but had no
runtime enforcement, so a single stray env var in a deploy config could
silently disable bearer-token auth in production. Add a startup guard
(enforce_production_auth_guard) invoked from the ASGI app factory that
refuses to boot when the bypass is set but the Modal environment looks
like production (missing, main, prod, production), and otherwise
requires an explicit GATEWAY_AUTH_DISABLED_ACK=I_UNDERSTAND_THIS_IS_DEV
acknowledgement. Even on the happy path we emit a CRITICAL log plus
logfire.error so the bypass is unmistakable in audit trails.
New coverage: guard no-ops when auth is enabled, refuses on missing
MODAL_ENVIRONMENT, refuses on every variant of prod MODAL_ENVIRONMENT
(main/prod/production/PROD), refuses in dev without ACK, refuses in dev
with wrong ACK, and allows+logs the banner in dev with correct ACK.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Cover the 256 KB payload-cap boundary on both sides
#450 added MAX_GATEWAY_REQUEST_BYTES=262_144 and an oversized-payload
rejection test but the existing coverage didn't pin the exact cap — a
future refactor could regress the limit to, say, 1 MB without any test
failing. Add two boundary tests: one constructs a payload encoded
just-under the cap and asserts SimulationRequest accepts it, the other
tops the cap by a handful of bytes and asserts the same ``too large``
ValidationError fires. The assertions log the actual encoded size so
diagnosing a drift on either side is straightforward.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent 5a8e95b commit 45ba6ae
27 files changed
Lines changed: 1741 additions & 86 deletions
File tree
- projects/policyengine-api-simulation
- fixtures/gateway
- src/modal
- gateway
- utils
- tests
- gateway
- integration
Lines changed: 11 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| 7 | + | |
7 | 8 | | |
8 | 9 | | |
9 | 10 | | |
10 | | - | |
11 | | - | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
12 | 19 | | |
13 | 20 | | |
14 | 21 | | |
15 | 22 | | |
16 | 23 | | |
17 | 24 | | |
| 25 | + | |
| 26 | + | |
18 | 27 | | |
19 | 28 | | |
20 | 29 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
41 | 41 | | |
42 | 42 | | |
43 | 43 | | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
| 14 | + | |
14 | 15 | | |
15 | 16 | | |
16 | 17 | | |
| |||
94 | 95 | | |
95 | 96 | | |
96 | 97 | | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
97 | 104 | | |
98 | 105 | | |
99 | 106 | | |
100 | | - | |
101 | | - | |
102 | | - | |
103 | | - | |
104 | | - | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
105 | 110 | | |
106 | 111 | | |
107 | 112 | | |
| |||
123 | 128 | | |
124 | 129 | | |
125 | 130 | | |
| 131 | + | |
126 | 132 | | |
127 | 133 | | |
128 | 134 | | |
129 | | - | |
130 | | - | |
131 | | - | |
132 | | - | |
133 | | - | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
134 | 138 | | |
135 | 139 | | |
Lines changed: 51 additions & 14 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
| 5 | + | |
5 | 6 | | |
6 | 7 | | |
7 | 8 | | |
| |||
10 | 11 | | |
11 | 12 | | |
12 | 13 | | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
13 | 18 | | |
14 | 19 | | |
15 | | - | |
16 | 20 | | |
17 | 21 | | |
18 | 22 | | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
19 | 33 | | |
20 | 34 | | |
21 | 35 | | |
| |||
38 | 52 | | |
39 | 53 | | |
40 | 54 | | |
41 | | - | |
42 | 55 | | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
43 | 62 | | |
44 | 63 | | |
45 | 64 | | |
| |||
54 | 73 | | |
55 | 74 | | |
56 | 75 | | |
57 | | - | |
58 | | - | |
59 | | - | |
60 | | - | |
61 | | - | |
62 | | - | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
63 | 94 | | |
64 | 95 | | |
65 | 96 | | |
66 | | - | |
67 | | - | |
68 | | - | |
69 | | - | |
70 | | - | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
71 | 108 | | |
72 | | - | |
| 109 | + | |
73 | 110 | | |
74 | 111 | | |
75 | 112 | | |
| |||
Lines changed: 52 additions & 6 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
29 | 29 | | |
30 | 30 | | |
31 | 31 | | |
32 | | - | |
33 | | - | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
34 | 49 | | |
35 | 50 | | |
36 | 51 | | |
| |||
59 | 74 | | |
60 | 75 | | |
61 | 76 | | |
62 | | - | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
63 | 80 | | |
64 | 81 | | |
65 | 82 | | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
66 | 87 | | |
67 | 88 | | |
68 | 89 | | |
| |||
75 | 96 | | |
76 | 97 | | |
77 | 98 | | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
78 | 102 | | |
79 | 103 | | |
80 | 104 | | |
81 | 105 | | |
82 | 106 | | |
83 | 107 | | |
84 | | - | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
85 | 115 | | |
86 | 116 | | |
87 | 117 | | |
| |||
122 | 152 | | |
123 | 153 | | |
124 | 154 | | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
125 | 163 | | |
126 | 164 | | |
127 | | - | |
| 165 | + | |
128 | 166 | | |
129 | 167 | | |
130 | 168 | | |
| |||
134 | 172 | | |
135 | 173 | | |
136 | 174 | | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
137 | 183 | | |
138 | 184 | | |
139 | | - | |
| 185 | + | |
140 | 186 | | |
141 | 187 | | |
142 | 188 | | |
| |||
Lines changed: 35 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
| 5 | + | |
5 | 6 | | |
6 | 7 | | |
7 | 8 | | |
| |||
16 | 17 | | |
17 | 18 | | |
18 | 19 | | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
19 | 24 | | |
20 | 25 | | |
21 | 26 | | |
| |||
129 | 134 | | |
130 | 135 | | |
131 | 136 | | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
132 | 165 | | |
133 | 166 | | |
134 | 167 | | |
| |||
140 | 173 | | |
141 | 174 | | |
142 | 175 | | |
143 | | - | |
| 176 | + | |
144 | 177 | | |
145 | 178 | | |
146 | 179 | | |
| |||
160 | 193 | | |
161 | 194 | | |
162 | 195 | | |
163 | | - | |
| 196 | + | |
164 | 197 | | |
165 | 198 | | |
166 | 199 | | |
| |||
0 commit comments