AI Provider Admin Controls
Workbench | Preview
This feature is in preview. Preview features are unsupported and may face breaking changes in a future release. Any issues found in the feature will be addressed during the regular release schedule; they will not result in immediate patches or hotfixes.
We encourage customers to try these features and we welcome any feedback via Posit Support, but we recommend that the feature not be used in production until it is in general availability (i.e., officially released as a full feature). To provide feedback, please email your Posit Customer Success representative or sales@posit.co and specify that you are trialing this feature.
You can define two settings in /etc/rstudio/profiles to supply an AI-provider configuration for your users. Both point at a JSON file in the providers.json schema, and Posit Workbench resolves each per user at session launch and applies it to RStudio Pro and Positron Pro sessions.
| Setting | Effect |
|---|---|
ai-providers-enforced |
Constrains the AI providers and models available. Users cannot override it. |
ai-providers-default |
Supplies a starting configuration. Users can override it in their own providers.json. |
The two are separate channels and resolve independently. Posit Assistant applies the default configuration first and the enforced configuration last, so setting both gives your users a working starting point plus the constraints they cannot escape. Neither setting is required, and setting one does not imply the other.
Like other profile settings, both are scoped with a global section ([*]), per-group sections ([@groupname]), and per-user sections ([username]), where the more specific scope wins. See User and Group Profiles for the full profiles syntax.
ai-providers-enforced
| Property | Value |
|---|---|
| Type | path to a JSON file (in the providers.json schema) |
| Default | unset (no enforced configuration) |
Path to a JSON file that supplies the AI-provider configuration. Workbench resolves this setting per user at session launch and forwards the file’s contents to the session as a providers.json-schema configuration. Use this setting to constrain which AI providers and models are available. You can also supply provider connection settings, configure provider discovery, and define custom providers.
Path resolution for ai-providers-enforced mirrors positron-enforced-settings. A relative path resolves against the directory that contains the profiles file (/etc/rstudio/ by default). Workbench uses an absolute path as-is.
Set globally, one configuration governs every user:
/etc/rstudio/profiles
[*]
ai-providers-enforced = /etc/rstudio/ai-providers-enforced/default.jsonTo vary the configuration by group or by user, see Sections and precedence.
ai-providers-default
| Property | Value |
|---|---|
| Type | path to a JSON file (in the providers.json schema) |
| Default | unset (no default configuration) |
Path to a JSON file that supplies a starting AI-provider configuration. Workbench resolves this setting per user at session launch and forwards the file’s contents to the session, unmodified. Use it to give users a working configuration out of the box (a pre-configured internal gateway, a preferred model) without preventing them from changing it.
Path resolution is identical to ai-providers-enforced: a relative path resolves against the directory that contains the profiles file (/etc/rstudio/ by default), and Workbench uses an absolute path as-is.
/etc/rstudio/profiles
[*]
ai-providers-default = /etc/rstudio/ai-providers/default.jsonHow it interacts with the other settings
Three sources can configure a provider. Posit Assistant applies them in this order, each overriding the one before it:
ai-providers-default, from this setting.- The user’s own
~/.posit/ai/providers.json. ai-providers-enforced, which overrides both.
So a user can override anything ai-providers-default sets, and nothing they do overrides ai-providers-enforced. Setting the same field in both admin settings is not a conflict. The default one is what the user starts from, and the enforced one is what they end up with.
The named ai-providers-* profile settings (such as ai-providers-anthropic-enabled) are enforcement, not defaults. They are overlaid onto ai-providers-enforced only, and never onto ai-providers-default.
Sections and precedence
Like all profile settings, ai-providers-enforced and ai-providers-default are set within sections that target users by scope:
| Section | Applies to |
|---|---|
[*] |
All users |
[@groupname] |
Members of the named group |
[username] |
A single user |
Workbench reads the file top to bottom and applies every section that matches the user. When more than one sets the same setting, the last in file order wins, and Workbench uses that file whole rather than merging the two. Each setting is scoped separately, so a narrower ai-providers-default does not displace a broader ai-providers-enforced, or the other way around.
/etc/rstudio/profiles
[*]
ai-providers-enforced = /etc/rstudio/ai-providers-enforced/default.json
[@data-scientists]
ai-providers-enforced = /etc/rstudio/ai-providers-enforced/data-scientists.json
[jsmith]
ai-providers-enforced = /etc/rstudio/ai-providers-enforced/jsmith.jsonIn this example, a user in no listed group gets default.json, a data-scientists member gets data-scientists.json, and jsmith gets jsmith.json even when also in data-scientists. If a user matches several [@groupname] sections, the last one in the file wins.
Because Workbench uses the replacing file whole, a later matching section drops every setting the earlier file made rather than adding to it. Workbench logs each such replacement to rserver.log, naming both files, so this is visible when a group-level restriction unexpectedly stops applying.
The providers.json schema
The file that ai-providers-enforced or ai-providers-default points to must follow the providers.json schema in posit-dev/ai-lib (packages/ai-config/providers.schema.json). The file is a JSON object with a top-level providers object that contains one entry per provider ID:
/etc/rstudio/ai-providers-enforced/default.json
{
"providers": {
"anthropic": { "enabled": true },
"openai": { "enabled": false }
}
}Provider IDs
Each entry under providers corresponds to one of the following recognized provider IDs: anthropic, openai, openai-compatible, gemini, google-vertex, bedrock, snowflake-cortex, databricks, ms-foundry, copilot, positai, deepseek, ollama, lmstudio, openrouter, and custom. The special default ID supplies a fallback for providers not named explicitly. It accepts only enabled.
Provider fields
All fields are optional. An omitted field imposes no constraint.
| Field | Type | Description |
|---|---|---|
enabled |
boolean | Whether the provider is available to users |
baseUrl |
string | Overrides the provider’s default API base URL |
customHeaders |
object | Additional HTTP headers sent with each request to the provider |
models |
object | Constrains and augments the models offered for the provider (see Model fields) |
Model fields
The models object on a provider entry (for example providers.anthropic.models) accepts:
| Field | Type | Description |
|---|---|---|
allow |
array of strings | Restrict the models offered for the provider to these exact model IDs |
deny |
array of strings | Block these exact model IDs |
discovery |
"auto" or "off" |
Whether to auto-discover the provider’s models. Set to "off" when supplying a fixed model list through custom |
custom |
array of objects | Define custom model entries. Each requires at least id, name, maxContextLength, supportsTools, supportsImages, supportsToolResultImages, and supportsWebSearch |
Provider-specific credentials
Some providers take an additional object that carries connection or credential settings.
| Provider | Object | Fields |
|---|---|---|
bedrock |
aws |
profile, region |
google-vertex |
googleCloud |
project, location |
snowflake-cortex |
snowflake |
account, home, host |
Example
The following configuration disables all providers except two: one with a restricted model list, and one with a custom base URL and connection headers:
/etc/rstudio/ai-providers-enforced/default.json
{
"providers": {
"default": { "enabled": false },
"anthropic": {
"enabled": true,
"models": {
"allow": ["claude-sonnet-4-5", "claude-opus-4-1"]
}
},
"openai-compatible": {
"enabled": true,
"baseUrl": "https://llm.internal.example.com/v1",
"customHeaders": {
"X-Org-Id": "research"
}
}
}
}Applying changes
After editing /etc/rstudio/profiles or any file it references, reload Workbench to apply the changes:
Terminal
sudo rstudio-server reloadYou do not need a full restart. Reloading re-reads the entire profiles file and any file that ai-providers-enforced or ai-providers-default references. Sessions launched after the reload use the updated settings. Running sessions keep their launch-time configuration. If Workbench cannot read the referenced file or the file contains invalid JSON, Workbench rejects the reload and keeps the previously loaded configuration. See Reloading configuration values for more about the reload command.
Helm chart configuration
On Kubernetes deployments that use the Workbench Helm chart, there is no host filesystem to place these files on. Supply both the profiles setting and the JSON file itself through config.server in values.yaml. Add each JSON file as its own config.server entry, then point the setting at it from config.server.profiles:
values.yaml
config:
server:
ai-providers-enforced.json: |
{
"providers": {
"anthropic": { "enabled": true },
"openai": { "enabled": false }
}
}
ai-providers-default.json: |
{
"providers": {
"anthropic": { "enabled": true }
}
}
profiles:
"*":
ai-providers-enforced: ai-providers-enforced.json
ai-providers-default: ai-providers-default.jsonThe chart mounts every config.server entry into the same server configuration directory, so both JSON files land alongside the rendered profiles file. Referencing them with relative paths (rather than absolute ones) lets each setting resolve against that directory automatically, without hard-coding the chart’s mount path.
See the Configuration files section of the Helm chart README for how config.server entries map to files on disk and how config.server.profiles maps to /etc/rstudio/profiles.