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 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
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

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 settingsserverUrl, 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.