# OpenWork Desktop App Policies: Controlling Local Model Access and Version Control

> Discover OpenWork desktop app policies for controlling local LLM access with allowCustomProviders and allowZenModel flags. Learn about version control enforcement via allowedDesktopVersions.

- Repository: [Different AI/openwork](https://github.com/different-ai/openwork)
- Tags: how-to-guide
- Published: 2026-08-04

---

**OpenWork desktop app policies allow administrators to restrict local LLM access via `allowCustomProviders` and `allowZenModel` flags, while version control is enforced through the `allowedDesktopVersions` whitelist in the Den control-plane.**

The `different-ai/openwork` repository implements granular desktop policies through its Den control-plane, giving organizations precise control over client capabilities. These policies govern everything from local model connectivity to application versioning, ensuring enterprise compliance while maintaining flexibility. Understanding these OpenWork desktop app policies is essential for administrators managing secure AI coding environments.

## Local Model Access Policies

Administrators can restrict access to local and self-hosted language models using two primary boolean flags defined in the `desktopPolicyDefinitions` catalog. Both follow an *allow-style* convention where `false` equals restricted and `true` equals allowed.

### Blocking Custom Providers with `allowCustomProviders`

The `allowCustomProviders` policy controls whether users may add providers not managed by OpenWork Cloud, such as self-hosted Ollama instances or other local LLMs. By default, this is set to `true`.

When set to `false`, the desktop app hides the "Add custom provider" screen in the UI. Any attempts to connect a local model are rejected with a user notice stating that the organization disabled custom providers. The client checks this flag via the `calculateEffectiveDesktopPolicy` helper before rendering provider selection dialogs.

### Restricting Built-in Zen Models with `allowZenModel`

The `allowZenModel` policy governs access to the built-in OpenCode Zen models that ship bundled with the desktop client. Like custom providers, this defaults to `true`.

If an administrator sets this to `false`, the dropdown listing Zen models disappears from the interface. The app displays a user notice indicating that the admin has disabled OpenCode models. This restriction is enforced in the same policy calculation flow located in [`packages/types/src/den/desktop-policies.ts`](https://github.com/different-ai/openwork/blob/main/packages/types/src/den/desktop-policies.ts) (lines 24-45).

## Version Control and Update Policies

Beyond model access, OpenWork desktop policies include strict version governance through the `DesktopConfig` schema, which extends base policy values with versioning and workspace controls.

### Whitelisting Client Versions with `allowedDesktopVersions`

The `allowedDesktopVersions` field accepts an array of semver strings (e.g., `"1.2.3"`) that define which desktop client versions may be installed or run. When undefined (the default), all versions are permitted.

During initialization, the client checks the current version against this whitelist. If the version is not present in the array, the startup banner refuses to launch the UI and displays an error stating the version is blocked by the organization's desktop policy. This enforcement occurs before the main application window renders.

### Workspace and Settings Restrictions

The `desktopConfigSchema` (lines 119-139) defines additional governance flags:

- **`allowMultipleWorkspaces`**: Controls whether users may create more than one workspace locally. Defaults to `true`.
- **`allowControlSettings`**: Determines if the user can open the Settings panel to change desktop-app configuration. Defaults to `true`.

## Policy Implementation and Enforcement

Policies are not static configuration files but dynamic rules calculated server-side and enforced client-side upon every login.

### How Policies Are Calculated and Applied

The enforcement flow follows four distinct steps:

1. **Administration**: Organization admins create or edit policies via the `DesktopPolicyEditorScreen` component in the Den web UI.
2. **Distribution**: The policy document (JSON) is stored in the database and passed to the desktop client during the authentication handshake.
3. **Calculation**: The client calls `calculateEffectiveDesktopPolicy` (lines 200-226), which merges default policies with organization-wide settings and any user-specific assignments.
4. **Enforcement**: UI components inspect the resulting booleans (e.g., `allowCustomProviders`, `allowZenModel`) and either render the feature or display a `userNotice` derived from the policy definitions.

```typescript
// Conceptual flow from packages/types/src/den/desktop-policies.ts
interface DesktopPolicy {
  allowCustomProviders?: boolean;  // default: true
  allowZenModel?: boolean;         // default: true
}

interface DesktopConfig extends DesktopPolicy {
  allowedDesktopVersions?: string[]; // semver whitelist, e.g., ["1.2.0", "1.2.1"]
  allowMultipleWorkspaces?: boolean;
  allowControlSettings?: boolean;
}

// Merges defaults with org and assignment policies (lines 200-226)
const effectivePolicy = calculateEffectiveDesktopPolicy(
  defaults,
  orgPolicy,
  userAssignments
);

```

### Key Source Files and Architecture

| File | Role |
|------|------|
| [`packages/types/src/den/desktop-policies.ts`](https://github.com/different-ai/openwork/blob/main/packages/types/src/den/desktop-policies.ts) | Central catalog containing `desktopPolicyDefinitions`, schemas, and `calculateEffectiveDesktopPolicy` |
| `ee/apps/den-web/app/(den)/dashboard/_components/desktop-policy-editor-screen.tsx` | React component for policy administration |
| [`packages/types/src/den/desktop-policies.ts`](https://github.com/different-ai/openwork/blob/main/packages/types/src/den/desktop-policies.ts) (lines 119-139) | `desktopConfigSchema` definition extending policies with version controls |

## Summary

- **`allowCustomProviders`**: Set to `false` to block connections to self-hosted/local LLMs like Ollama by hiding the custom provider UI.
- **`allowZenModel`**: Set to `false` to remove access to the bundled OpenCode Zen models.
- **`allowedDesktopVersions`**: Enforces a semver whitelist for permitted client versions, blocking startup of non-compliant installations.
- **`calculateEffectiveDesktopPolicy`**: The core function (lines 200-226) that merges default, organizational, and assigned policies into the final effective configuration.
- All policy definitions and schemas reside in [`packages/types/src/den/desktop-policies.ts`](https://github.com/different-ai/openwork/blob/main/packages/types/src/den/desktop-policies.ts).

## Frequently Asked Questions

### How do I prevent users from connecting to local Ollama instances?

Set the `allowCustomProviders` policy to `false` in the Den control-plane. This removes the "Add custom provider" screen from the desktop UI and rejects any local model connection attempts with an organizational notice.

### What happens when a desktop version is not in the allowed list?

The client validates the current application version against the `allowedDesktopVersions` array during startup. If the version is absent from the whitelist, the initialization sequence halts and displays an error banner stating the version is blocked by organizational policy.

### Can users override desktop policies on their local machine?

No. Policies are calculated server-side via `calculateEffectiveDesktopPolicy` and transmitted to the client upon login. The merged policy object is read-only on the client, preventing local tampering with restrictions like `allowCustomProviders` or `allowedDesktopVersions`.

### Where are the policy schema definitions located?

All policy keys, TypeScript interfaces, and default values are defined in [`packages/types/src/den/desktop-policies.ts`](https://github.com/different-ai/openwork/blob/main/packages/types/src/den/desktop-policies.ts). This file contains the `desktopPolicyDefinitions` catalog, the `desktopConfigSchema` extension (lines 119-139), and the policy calculation logic (lines 200-226).