# How OpenWork Desktop App Policies Restrict Access to Local Models

> Discover how OpenWork desktop app policies restrict local model access. Learn about the allowCustomProviders flag and its impact on disabling Ollama and other non-cloud providers.

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

---

**OpenWork desktop app policies restrict access to local models through the `allowCustomProviders` flag, which filters provider lists and blocks additions of non-cloud providers like Ollama when disabled by an organization.**

The OpenWork repository implements a comprehensive desktop policy system that gives organizations granular control over AI provider access. By manipulating boolean flags defined in the type definitions, administrators can disable user access to locally-hosted models while maintaining cloud provider functionality.

## Understanding the Desktop Policy Configuration

The policy catalog is centralized in **[`packages/types/src/den/desktop-policies.ts`](https://github.com/different-ai/openwork/blob/main/packages/types/src/den/desktop-policies.ts)**, which exports the schema for all desktop restrictions. The critical flag for local model access is `allowCustomProviders`, which defaults to `true` but can be overridden by organizational policy.

```ts
// packages/types/src/den/desktop-policies.ts
export const desktopPolicyDefinitions = [
  {
    id: "allowCustomProviders",
    name: "Custom providers",
    description:
      "Allow users to add and use models that are not deployed through OpenWork Cloud.",
    userNotice:
      "Your organization administrator has disabled adding custom providers.",
    defaultValue: true,
  },
] as const;

```

When an administrator sets `allowCustomProviders` to `false`, the application treats all non-cloud providers as restricted. This directly impacts local model integrations such as Ollama, LM Studio, or any self-hosted LLM endpoint configured through the custom provider interface.

## Policy Enforcement Architecture

The restriction mechanism operates through three coordinated layers: policy retrieval, runtime validation, and UI filtering.

### Reading Effective Policies

The desktop client retrieves the calculated policy object via the `getDesktopPolicies` capability. This capability bridges the Deno backend with the React frontend, providing the current organizational settings to the policy enforcement layer.

### Runtime Restriction Checks

The `checkDesktopAppRestriction` utility serves as the gatekeeper throughout the application. This function accepts a restriction identifier and returns a boolean indicating whether the feature is permitted under current policies.

```ts
// Example usage in provider authentication flow
const restrictToCloud = options.checkDesktopAppRestriction({
  restriction: "allowCustomProviders",
});

```

When `allowCustomProviders` evaluates to `false`, this checker returns a restriction flag that propagates through the provider management system.

### Provider Filtering Logic

The **[`apps/app/src/react-app/domains/connections/provider-auth/store.ts`](https://github.com/different-ai/openwork/blob/main/apps/app/src/react-app/domains/connections/provider-auth/store.ts)** file implements the filtering logic that determines which providers appear in the UI. The `getProviderAuthProviders` function iterates through available providers and validates each against `isProviderAllowedByDesktopPolicy`.

```ts
// apps/app/src/react-app/domains/connections/provider-auth/store.ts
const getProviderAuthProviders = (): ProviderAuthProvider[] => {
  const merged = new Map<string, ProviderAuthProvider>();
  const restrictToCloud = options.checkDesktopAppRestriction({
    restriction: "allowCustomProviders",
  });

  for (const provider of options.providers()) {
    const id = provider.id?.trim();
    if (!id) continue;
    
    if (
      !isProviderAllowedByDesktopPolicy({
        providerId: id,
        restrictToCloud,
        checkRestriction: options.checkDesktopAppRestriction,
      })
    ) {
      continue; // Provider hidden due to policy restriction
    }
    merged.set(id, { … });
  }
  // …
};

```

## Blocking Local Model Access in Practice

When users attempt to add new local providers, the application enforces policies through `assertProviderAllowedByDesktopPolicy`. This function throws an error before the provider configuration reaches the backend, ensuring complete restriction of local model access.

```ts
const assertProviderAllowedByDesktopPolicy = (providerId: string) => {
  const restrictToCloud = options.checkDesktopAppRestriction({
    restriction: "allowCustomProviders",
  });
  
  if (
    !isProviderAllowedByDesktopPolicy({
      providerId,
      restrictToCloud,
      checkRestriction: options.checkDesktopAppRestriction,
    })
  ) {
    throw new Error(`${providerId} is blocked by your organization desktop policy.`);
  }
};

```

The UI layer consumes these restrictions to display appropriate messaging. When `allowCustomProviders` is disabled, the interface renders the `userNotice` defined in the policy definition, informing users that their organization has restricted custom provider additions.

```tsx
import { useDesktopAppRestriction } from "@/app/cloud/desktop-app-restrictions";

function ProviderPicker() {
  const { checkDesktopAppRestriction } = useDesktopAppRestriction();
  const allowCustom = checkDesktopAppRestriction({ 
    restriction: "allowCustomProviders" 
  });

  if (!allowCustom) {
    return (
      <Alert variant="warning">
        Your organization administrator has disabled adding custom providers.
      </Alert>
    );
  }
  
  return <ProviderList />;
}

```

## Summary

- **Policy Definition**: The `allowCustomProviders` boolean in [`desktop-policies.ts`](https://github.com/different-ai/openwork/blob/main/desktop-policies.ts) controls access to local models, defaulting to `true` but overridable by organizational policy.
- **Runtime Enforcement**: The `checkDesktopAppRestriction` utility evaluates policy states and feeds the restriction flag into provider management functions.
- **Provider Filtering**: `isProviderAllowedByDesktopPolicy` in the connection domain filters local providers from the UI when restrictions are active.
- **Addition Blocking**: `assertProviderAllowedByDesktopPolicy` prevents the persistence of new local provider configurations, throwing errors before backend commit.
- **User Experience**: Restricted states trigger the display of the `userNotice` string defined in the policy catalog, providing clear administrative messaging.

## Frequently Asked Questions

### What is the default behavior for local models in OpenWork?

By default, OpenWork allows local model access because the `allowCustomProviders` policy defaults to `true` in [`desktop-policies.ts`](https://github.com/different-ai/openwork/blob/main/desktop-policies.ts). Organizations must explicitly override this setting to restrict users to cloud-only providers.

### How does OpenWork distinguish between cloud and local providers?

The system identifies local providers through the `isProviderAllowedByDesktopPolicy` function, which checks the `restrictToCloud` flag passed from `checkDesktopAppRestriction`. Providers not explicitly classified as cloud providers are treated as custom/local and filtered when the policy is disabled.

### Can users bypass desktop app policy restrictions?

No, users cannot bypass these restrictions because policy enforcement occurs at multiple layers: the UI filters visible providers, the store layer blocks additions through `assertProviderAllowedByDesktopPolicy`, and the backend validates against the effective policy retrieved via `getDesktopPolicies`.

### Where are the policy definitions stored in the codebase?

The canonical policy definitions reside in **[`packages/types/src/den/desktop-policies.ts`](https://github.com/different-ai/openwork/blob/main/packages/types/src/den/desktop-policies.ts)**, while the enforcement logic is implemented in **[`apps/app/src/react-app/domains/connections/provider-auth/store.ts`](https://github.com/different-ai/openwork/blob/main/apps/app/src/react-app/domains/connections/provider-auth/store.ts)** and the reconciliation utilities in **[`apps/app/src/react-app/domains/connections/policy-provider-reconcile.ts`](https://github.com/different-ai/openwork/blob/main/apps/app/src/react-app/domains/connections/policy-provider-reconcile.ts)**.