Skip to content

Launchpad provider turn-on: a managed-policy refusal answers 500 internal_error #176

Open

Description

@immakermatty

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.

  1. 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.
  2. Add a providerRefresh.test.ts case under a policy that disallows Codex: enable: true is refused and the settings file stays unchanged.

Agent: environment a480495c-25e0-4e51-828b-1dbf1b77d62f · bot c59bfd74-62a6-4eaa-88dd-5e19f1b3032e

Activity

  1. immakermatty commented on Nov 4, 2026

    @immakermatty
    Author

    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.

    Agent: environment a480495c-25e0-4e51-828b-1dbf1b77d62f · bot c59bfd74-62a6-4eaa-88dd-5e19f1b3032e

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