You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Launchpad provider turn-on: a managed-policy refusal answers 500 internal_error #176
Found by the independent review of the v0.1.7 rebuild (#172, PR #174, row 18). Same family as #128 (a refusal surfaced as internal_error), but on a different path.
What happens. The Launchpad's provider turn-on writes through settings.updateSettingsWith(...) (apps/server/src/lazurio/providerRefresh.ts:194-198). From v0.1.7 every settings write is vetted by the managed policy (managed.vetWrite and managedProviders.vetWrite in apps/server/src/serverSettings.ts), and a refusal fails with ServerSettingsError. The route maps every ServerSettingsError to a 500 internal_error (apps/server/src/lazurio/providerRefreshRoute.ts:42), so a policy that disallows a provider or locks its enabled reaches the Launchpad and the logs as an internal error. The person cannot tell that the Organization's policy refused it.
No test covers the refusal on this path: providerRefresh.test.ts and providerRefreshRoute.test.ts provide ManagedPolicy.layerTest() without a policy. The only refusal test is row 15's at the settings layer (modelRecommendation.test.ts, "the overlay's settings writes stay inside the managed policy").
Impact today. None on Lazurio Environments: Lazurio installs no managed policy file (/etc/t3code/policy.json on Linux). It matters on any policy-managed install.
Proposed fix.
In the route, answer a policy refusal (ServerSettingsError with operation write-managed-setting or use-disallowed-provider) with 403 and a body that names the setting or provider instance; keep internal_error for real I/O failures.
Add a providerRefresh.test.ts case under a policy that disallows Codex: enable: true is refused and the settings file stays unchanged.
The independent review of PR #174 (head cff53b33f7) found a second route of the same class, in row 15. It belongs here, so both are fixed together.
Model recommendation.apps/server/src/lazurio/modelRecommendationRoute.ts:63 maps every failure to failEnvironmentInternal, a 500 internal_error. In v0.1.7 the settings write it makes is checked by the managed policy. A policy that locks defaultModelSelection (or disallows the recommended provider) therefore reaches the client as an internal error, as on the provider turn-on route above. The row-15 test "the overlay's settings writes stay inside the managed policy" (modelRecommendation.test.ts) covers the refusal at the settings layer only, not the route's answer.
Proposed fix, same as above. Answer a policy refusal (ServerSettingsError with operation write-managed-setting or use-disallowed-provider) with 403 and the locked setting or provider. Add a route test with ManagedPolicy.layerTest() and a policy that locks the field.
The impact today is still none, because Lazurio installs no policy file.
Activity
immakermatty commentedon Nov 4, 2026
The independent review of PR #174 (head
cff53b33f7) found a second route of the same class, in row 15. It belongs here, so both are fixed together.Model recommendation.
apps/server/src/lazurio/modelRecommendationRoute.ts:63maps every failure tofailEnvironmentInternal, a 500internal_error. In v0.1.7 the settings write it makes is checked by the managed policy. A policy that locksdefaultModelSelection(or disallows the recommended provider) therefore reaches the client as an internal error, as on the provider turn-on route above. The row-15 test "the overlay's settings writes stay inside the managed policy" (modelRecommendation.test.ts) covers the refusal at the settings layer only, not the route's answer.Proposed fix, same as above. Answer a policy refusal (
ServerSettingsErrorwith operationwrite-managed-settingoruse-disallowed-provider) with 403 and the locked setting or provider. Add a route test withManagedPolicy.layerTest()and a policy that locks the field.The impact today is still none, because Lazurio installs no policy file.
Agent: environment a480495c-25e0-4e51-828b-1dbf1b77d62f · bot c59bfd74-62a6-4eaa-88dd-5e19f1b3032e