Skip to content

Enforced connection fields can be overridden by a user's environment variables #10

Description

@melissa-barca

Enforced connection fields can be overridden by a user's environment variables

Summary

The POSIT_AI_PROVIDERS_ENFORCED overlay is meant to be non-overridable. That holds for enablement and for connection fields set through config files, but not for the connection fields that have an environment-variable mapping. A user who sets an ordinary environment variable in their own shell (POSITAI_AUTH_HOST, ANTHROPIC_BASE_URL, OPENAI_BASE_URL, AWS_REGION, and the others in CONNECTION_ENV_MAPPINGS) overrides the enforced value for that field.

Admins set the ENFORCED overlay precisely to lock these fields, so a per-user workaround defeats the control's purpose.

Root cause

Connection config and enablement resolve on two different paths.

Enablement folds every source, enforced first, in resolveEnabled ("first defined wins," enforced on top) — sound.

Connection config takes a longer path in buildCatalog:

resolveConnection(id, block)        // merges sources; enforced wins here
  -> applyEnvOverlay(id, ..., envVars)   // runs AFTER, unconditionally

applyEnvOverlay (build-catalog.ts:289) applies the environment overlay after the enforced merge, and its own contract states "Env vars have the highest precedence: env > file (providers.json) > defaults" (build-catalog.ts:285). The envVars it reads is plain process.env, injected by the node seam (load-catalog.ts:42), the same object for every user. The mapped variables in CONNECTION_ENV_MAPPINGS (build-catalog.ts:51) are ordinary environment variables, not the sealed POSIT_AI_PROVIDERS_ENFORCED fragment. Nothing between process.env and the overlay distinguishes an admin-set variable from a user-set one.

The layering is inverted: the environment overlay represents user/host intent but is applied above the admin's enforced layer.

The existing test "enforced connection can never be overridden by lower sources" (__tests__/resolve-catalog.test.ts:74) only exercises file and default sources with envVars: {}, so it never covers the environment path where the invariant fails.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingpositronaffects positron or will be worked on by Positron team (if added to Positron project board)

    Type

    Fields

    No fields configured for Bug.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions