Skip to content

Enterprise Policy

Pia applies an enterprise policy at startup. IT administrators use it to set defaults or lock specific settings on managed devices. A policy can come from two sources: a policy.json file on the device, or a policy an administrator publishes for the user’s group on a Pia server.

Pia looks for policy.json in three places and uses the first one that exists. The three files are never merged.

%ProgramFiles%\Pia.Wpf\current\policy.json (the folder Pia.exe runs from)
%ProgramFiles%\Pia.Wpf\policy.json (the install root)
C:\ProgramData\Pia.Wpf\policy.json

Put the file at the install root, next to the launcher users start Pia from. The folder Pia.exe runs from is replaced whenever Pia updates itself, so a policy left there is gone after the next update.

Standard users can read these folders; only administrators can write to them. Users can’t override the file from inside Pia.

An administrator can publish the same document for a whole group in the Pia server’s admin console, and it reaches the client with the ordinary sync. A server-published policy has the same two sections, defaults and enforce, and they mean exactly what they mean in a file. Nothing else in this reference changes.

Three things are worth knowing about a server-published policy:

  • It is cached on the device. The policy keeps applying after a restart and while the device is offline, and there is no expiry — a policy the server last confirmed days ago still applies.
  • It takes effect at the next start. A policy the administrator publishes while Pia is running is picked up by the next sync and applied the next time Pia starts. That is the designed behaviour, not a delay to work around.
  • Signing out clears it. Pia discards the cached server policy on sign-out, so the next person to sign in on that machine does not inherit the previous user’s group policy.

A sign-in method missing from allowedSyncProviders is hidden in the setup wizard and the account settings, and a sign-in through it is refused with “This sign-in method is disabled by your organization’s policy.” Anyone already signed in with a method the policy no longer allows is signed out the next time Pia starts: their session is ended on the server as well, and sync stays off until they sign in again. Signing out also discards the cached server policy, so the next sign-in is unconstrained again — pin allowedSyncProviders in policy.json to refuse a method outright.

A server-published policy outranks the device’s policy.json on any key both of them set. Within one source, enforce overrides whatever the user chose, while defaults only fill in where the user has not chosen. The full order, first match wins:

  1. enforce from the server
  2. enforce from policy.json
  3. the user’s own value
  4. defaults from the server
  5. defaults from policy.json
  6. Pia’s built-in default

A policy has two top-level sections, both shaped like Pia’s user-settings schema:

  • defaults — a starting value, applied while the user’s setting still matches Pia’s built-in default, or still matches a value the policy set earlier.
  • enforce — pinned values. The corresponding controls in Pia’s settings UI are disabled so the user can’t change them. If the same property appears in both sections, enforce wins.

All property names use camelCase. Unknown properties are ignored. Invalid JSON is logged as a warning and the policy is not applied — check the application log if a policy doesn’t seem to take effect.

Property Type Default Description
theme "System" | "Dark" | "Light" "System" UI theme
uiLanguage "EN" | "DE" | "FR" "EN" Interface language
targetLanguage "EN" | "DE" | "FR" unset Default output language for Optimize
targetSpeechLanguage "Auto" | "EN" | "DE" | "FR" "Auto" Speech recognition language
defaultOutputAction "CopyToClipboard" | "AutoType" | "PasteToPreviousWindow" "CopyToClipboard" What happens after Optimize finishes
autoTypeDelayMs integer 10 AutoType delay in milliseconds
defaultTemplateId GUID unset Default optimization template
whisperModel "Tiny" | "Base" | "Small" | "Medium" | "Large" "Base" Speech-to-text model size
ttsEnabled bool false Enable text-to-speech
ttsVoiceModelKey string "en_US-lessac-medium" TTS voice identifier
startMinimized bool false Launch hidden in the system tray
launchAtStartup bool true Start Pia when Windows starts
sttBackend "Parakeet" | "Whisper" "Parakeet" Speech-to-text engine
autoUpdateEnabled bool true Allow auto-update on launch
syncEnabled bool false Enable Pia Cloud sync
serverUrl string unset Pia Cloud server URL (for self-hosting)
trustSelfSignedCertificates bool false Accept self-signed TLS certificates from the configured Pia server (its host and port) only, never from other hosts
allowedSyncProviders string[] unset (all allowed) Sign-in methods users may use: "local", "google", "microsoft", "entraid". See Policy from Your Pia Server
useSameProviderForAllModes bool true Use one AI provider across Optimize/Assistant
modeProviderDefaults object {} Map of conversation mode to AI provider GUID
privacy object see below Privacy settings (nested)

privacy is a nested object:

Property Type Default Description
tokenizationEnabled bool true Replace PII with tokens before sending text to the AI

These are the ones worth pinning on managed devices, because they decide what Pia may do on its own. See Tool Permissions and Agent Runs.

Property Type Default Description
assistantFilesFolder string unset The only folder the assistant may touch
assistantFileToolsEnabled bool true Allow reading and writing files in that folder
assistantGitToolsEnabled bool true Allow git commands in that folder
agentRunAutoApproveBuiltInWrites bool false Skip approval for Pia’s own write tools during agent runs and voice mode
chatHistoryEnabled bool true Store assistant chats on the device
chatHistoryRetentionDays integer 30 Delete chats not opened for this many days
enableMeetingDiarization bool true Split meeting transcripts by speaker
meetingSpeakerNaming bool true Let the consent sentence and a rename give a speaker a name, and add the attendee list to summaries and saved notes

With meetingSpeakerNaming set to false, every speaker keeps a label such as Speaker 1. Renaming is switched off in both transcript windows, summaries get no participant list, the save-to-vault form isn’t pre-filled with attendees, and the note of a scheduled meeting lists none. A consent sentence still counts, but the name in it goes into the consent record only, and the sentence itself stays out of the transcript. Users see the setting as Name speakers in Settings → Assistant → Meeting, locked when you set it under enforce.

Set these under enforce, so users can’t loosen them.

Property Type Default Description
allowedProviderTypes string[] unset (all allowed) Provider types users may use: "OpenAI", "AzureOpenAI", "Ollama", "OpenRouter", "OpenAICompatible", "Mistral", "VLlm", "Anthropic". Case doesn’t matter
allowedProviderEndpoints string[] unset (all allowed) Addresses providers may use: an exact host, or *.domain for its subdomains
allowProviderWebSearch bool true Allow the providers’ own web search
allowLocalMcpServers bool true Allow MCP servers that run on the device

Leaving allowedProviderTypes or allowedProviderEndpoints out, or setting it to null or [], allows everything. Pia Cloud is never limited by either of them.

A provider type missing from allowedProviderTypes is not offered in the provider dialog or the setup wizard. A provider of that type the user already has can’t be saved, and Pia refuses every request to it before anything is sent: the chat shows a message, and a background run ends with an error. The reason given is “Your organization’s policy does not allow this provider type.”

An entry in allowedProviderEndpoints is an exact host such as llm.corp.example, or a pattern such as *.example.com, which covers every subdomain of example.com but not example.com itself. An entry written as a URL counts by its host. An address the list doesn’t cover can’t be saved, and the dialog says “Your organization’s policy does not allow this address.” Pia fetches no models from it and refuses requests to it.

allowProviderWebSearch set to false keeps the providers’ own web search off: OpenAI, OpenRouter, Anthropic and Mistral agents. The user’s choice stays saved, and Enable web search is locked. Pia Cloud is not affected, because its search runs on the server.

allowLocalMcpServers set to false locks Add server, refuses saving and testing a server, and stops local servers that are running. Each one says “Your organization’s policy does not allow local MCP servers on this device.” Once local servers are allowed again, Pia starts the ones that are switched on by itself. MCP servers the administrator distributes as plugins are not affected.

Two groups of keys are off limits. The first is refused only from a server-published policy; the second is refused from both sources.

The connection settings — serverUrl, syncEnabled and trustSelfSignedCertificates. These are what Pia needs in order to reach the server in the first place, and because a server-published policy outranks the device file, one wrong value could disconnect an entire group with no remaining way to correct it remotely. All three can still be pinned in the device’s policy.json, and that is how you constrain a device before it has ever reached a server.

Pia’s own bookkeeping — sign-in credentials, sync cursors and ETags, encryption state, schema and migration markers, window geometry and draft text. Pia ignores these keys wherever they are set, in the file as well as from the server, and logs a warning naming the key.

{
"defaults": {
"uiLanguage": "DE",
"targetLanguage": "DE",
"whisperModel": "Small"
},
"enforce": {
"theme": "Dark",
"serverUrl": "https://pia.corp.example.com",
"syncEnabled": true
}
}

In this example, German is the starting language but users can switch to English or French. The theme is pinned to Dark, sync is mandatory, and the Pia Cloud URL is locked to the company’s self-hosted server. serverUrl and syncEnabled only work in a device policy.json — a server-published policy cannot set either of them.

  1. Create or edit policy.json at Pia’s install root on each managed device (e.g. via your endpoint management system), or publish the document for a whole group from the Pia server’s admin console.
  2. Validate the JSON.
  3. Have users close and reopen Pia.

Settings under enforce appear grayed out in Pia’s settings UI; defaults appear normally.