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.
File Location
Section titled “File Location”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.jsonPut 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.
Policy from Your Pia Server
Section titled “Policy from Your Pia Server”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.
Which Source Wins
Section titled “Which Source Wins”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:
enforcefrom the serverenforcefrompolicy.json- the user’s own value
defaultsfrom the serverdefaultsfrompolicy.json- Pia’s built-in default
File Format
Section titled “File Format”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,enforcewins.
Supported Settings
Section titled “Supported Settings”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 |
Governing the assistant
Section titled “Governing the assistant”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 |
Settings the Server Cannot Manage
Section titled “Settings the Server Cannot Manage”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.
Example
Section titled “Example”{ "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.
Rolling Out
Section titled “Rolling Out”- Create or edit
policy.jsonat 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. - Validate the JSON.
- Have users close and reopen Pia.
Settings under enforce appear grayed out in Pia’s settings UI; defaults appear normally.