Enterprise · IT administration
Admin Guide
This guide is for IT administrators deploying Parleq to a fleet of Macs via MDM. If you are a developer looking for the complete managed-key schema, see the Managed Configuration reference instead.
Why deploy Parleq centrally?
Parleq is a local-first dictation tool: speech transcription runs on the Mac itself, and cleanup is routed to whichever LLM provider your organization has already vetted and contracted with. There is no Parleq cloud service, no audio stored on Parleq servers, and no telemetry sent to Parleq. That posture means you review one vendor (your LLM provider) rather than two. Deploying Parleq via MDM adds one more layer: your MDM profile pins the LLM provider, restricts the model list, disables optional features your security review requires off, and prevents users from changing any of it. The result is a governed dictation workflow that satisfies the same procurement checklist as other enterprise tools — without a vendor admin portal, a licensing key system, or a phone-home compliance check. Pins are enforced while the configuration profile is installed: on supervised (DEP-enrolled) Macs the profile is non-removable; on unsupervised machines a local administrator can remove the profile, so use supervised enrollment where you need a hard guarantee.
Deployment workflow
- 1.
Get the sample profile.
Download
config/parleq-managed-example.mobileconfigfrom the repo. It is a fully-formed.mobileconfigwith every supported key commented and explained. You can use it as-is for testing, or trim it to the subset of keys you want to manage. - 2.
Customize for your organization.
Open the file in a text editor and set the keys relevant to your deployment. Replace both
REPLACE-WITH-A-NEW-UUIDplaceholders with fresh UUIDs (runuuidgenin Terminal) and replace thecom.exampleidentifiers with your organization’s reverse-DNS prefix. Any key you omit is not managed — Parleq uses the user’s stored preference or the built-in default. See the full key reference for all available keys and their semantics. - 3.
Upload and scope in your MDM.
All MDMs that speak the macOS MDM protocol accept the same
.mobileconfigformat:- Jamf Pro: Computers → Configuration Profiles → New → Application & Custom Settings payload (or upload the raw file).
- Kandji: Library → Custom Profile → upload the
.mobileconfig. - Mosyle: Apple Configurator → General → Custom Configuration Profile.
- Intune: Devices → macOS → Configuration profiles → Create → Templates → Custom.
- Workspace ONE, Addigy, JumpCloud: follow each platform’s equivalent Custom Profile workflow.
Assign the profile to a device group, smart group, or individual machines. The MDM pushes it on the next check-in (typically within a few minutes).
- 4.
Verify the deployment.
Settings take effect on Parleq’s next launch after MDM check-in. Two ways to confirm:
- In-app: Settings → Privacy & Features → View managed configuration…. The Compliance Audit dialog lists every managed-eligible key with source (Managed / User / Default). Use the Copy snapshot button to export the full state as JSON for your records.
- Terminal:
sudo plutil -p "/Library/Managed Preferences/com.parleq.app.plist"
Common deployment patterns
Azure-only org
You have an Azure OpenAI deployment and want all Parleq traffic to go there. Pin the provider, restrict the model list to the deployments you have provisioned, and disable the custom model entry so users can’t route around the list.
<key>cleanupProvider</key>
<string>azure</string>
<key>cleanupAllowedModels</key>
<array>
<string>gpt-4o</string>
<string>gpt-4o-mini</string>
</array>
<key>customModelEntryEnabled</key>
<false/> Bedrock-only org
Your org uses AWS and routes LLM calls through Bedrock for data-residency and IAM auditability. Pin to Bedrock, restrict to the Claude family, and (optionally) disable the reference-window feature if screenshot-to-LLM is not in scope.
<key>cleanupProvider</key>
<string>bedrock</string>
<key>cleanupAllowedModels</key>
<array>
<string>anthropic.claude-sonnet-4-5</string>
<string>anthropic.claude-3-5-haiku-20241022-v1:0</string>
</array>
<key>customModelEntryEnabled</key>
<false/>
<key>imageReferenceEnabled</key>
<false/> Auth-mode lockdown
Your security policy requires federated identity throughout — no static API keys on developer laptops. Force Entra ID for Azure and AWS SSO for Bedrock, and globally disable all API-key auth paths so users cannot use personal credentials even if they were previously stored in the Keychain.
<!-- Master switch: hides API-key entry UI AND blocks static-key auth at runtime -->
<key>staticApiKeysAllowed</key>
<false/>
<!-- Force Azure to use Entra ID (az login) -->
<key>azureAuthMode</key>
<string>azureAd</string>
<!-- Force Bedrock to use AWS SSO -->
<key>bedrockAuthMode</key>
<string>sso</string>
With this configuration: the Azure credentials card shows a pinned “Microsoft Entra ID” label and hides the API key row; the Bedrock card shows a pinned “AWS CLI session (SSO)” label and hides the static-credentials and Bedrock-API-key rows; Gemini, OpenAI direct, and Bedrock bearer cards all hide their key-entry buttons and show an “Auth disabled by org” badge in the card header. Federated-auth controls (“Auth uses your local az login session”, aws sso login) remain fully accessible. Runtime enforcement: Parleq will refuse to use any static-key auth path even if credentials are already stored in the Keychain — previously-stored keys are not deleted, but they are not used while the policy is active. The provider picker annotates Gemini, OpenAI direct, and Bedrock bearer with “(disabled by your organization)” so users understand why cleanup is unavailable for those providers. Removing the MDM profile and restarting Parleq immediately restores access to all previously-stored credentials.
Provider availability under staticApiKeysAllowed: false:
| Provider | Auth mode | Available? |
|---|---|---|
| gemini | API key (only option) | Blocked |
| openai | API key (only option) | Blocked |
| bedrock-bearer | Bedrock API key (only option) | Blocked |
| vertex | serviceAccount (JSON key) | Blocked |
| vertex | adc (gcloud ADC) | Available |
| azure | apiKey | Blocked |
| azure | azureAd (Entra ID) | Available |
| bedrock | static / bedrockApiKey | Blocked |
| bedrock | sso (AWS SSO) | Available |
Compliance-first lockdown
Maximally locked: no screenshots, no file references, no custom models, auto-update managed centrally, logging policy documented for auditors, and updates fetched from an internal mirror after your security team’s review.
<key>imageReferenceEnabled</key>
<false/>
<key>fileReferenceEnabled</key>
<false/>
<key>customModelEntryEnabled</key>
<false/>
<key>autoUpdateEnabled</key>
<false/>
<key>loggingMode</key>
<string>lengthOnly</string>
<key>sparkleUpdateFeedURL</key>
<string>https://internal-mirror.example.com/parleq/appcast.xml</string> Verification checklist
After deploying, confirm policy uptake with the following steps. Run these on a test machine before wide deployment.
| What to check | How to verify |
|---|---|
| MDM profile installed | System Settings → Privacy & Security → Profiles (macOS 13+), or sudo profiles list in Terminal. |
| Preferences plist written | sudo plutil -p "/Library/Managed Preferences/com.parleq.app.plist" — shows every key and value pushed by the profile. |
| Keys detected by app | Settings → Privacy & Features → View managed configuration…. Every managed key should show source=Managed (orange badge). Copy the snapshot as JSON for your records. |
| Settings toggles locked | Open Settings → Privacy & Features. Managed toggles should be greyed out and show a lock icon with “Managed by your organization.” |
| Provider/model picker restricted | Open Settings → Cleanup Model. If cleanupProvider is pinned, only that provider should appear. If cleanupAllowedModels is set, only the listed models should be visible. |
| Startup log confirms keys | tail -30 ~/.parleq/app.log | grep "managed config" — should show the count and key=value pairs of every managed key Parleq detected. |
Signed-app and notarization posture
The statements below are what IT departments and security reviewers typically need before adding an app to their approved list. They apply to every released build of Parleq.
Code signature
Every Parleq release is signed with Apple Developer ID. The current signing Team ID is N7S8GXC725. Admins can verify this independently via Apple’s developer registry or by running codesign -dv --verbose=4 /Applications/Parleq.app 2>&1 | grep TeamIdentifier on a downloaded build.
Notarization
Every Parleq release is submitted to Apple’s notarization service before distribution. Notarized builds pass Gatekeeper automatically on macOS 10.15+ without requiring users to right-click-open or change security preferences. You can verify notarization on a downloaded build: spctl --assess --type exec --verbose /Applications/Parleq.app should print accepted.
Sparkle update integrity
Parleq uses the Sparkle update framework. Every downloaded update is verified against an Ed25519 public key (SUPublicEDKey) embedded in the app’s Info.plist. The matching private key is held exclusively by the maintainer and is never part of the repo or any build artifact. This means:
- No one other than the maintainer can push a signed update, regardless of what the MDM-managed
sparkleUpdateFeedURLpoints at. - If an attacker controls the appcast URL (whether via DNS spoofing or a compromised managed-config profile), they can only serve an appcast. They cannot produce a binary that passes the EdDSA signature check.
- Sparkle verifies the signature before the downloaded binary touches disk. A tampered binary is rejected before execution.
Third-party dependencies
Parleq has no third-party SDKs that phone home. The full dependency manifest is published in THIRD_PARTY_LICENSES.md. Dependencies are: Sparkle (update delivery), Soto (AWS SDK for Bedrock), swift-log (structured logging), and FluidAudio (on-device speech recognition). None of these make network requests except when explicitly invoked: Sparkle during update checks, Soto during Bedrock cleanup calls, and FluidAudio downloads its speech model from Hugging Face on first launch (~150 MB, one-time). There is no analytics, crash-reporting, or feature-flag SDK.
Managed configuration is local-only
Parleq reads managed-configuration values from /Library/Managed Preferences/com.parleq.app.plist at startup. It never sends policy state to an external service, never reports compliance status to a Parleq endpoint, and never validates policy against a remote server. The Compliance Audit dialog (Settings → Privacy & Features → View managed configuration…) exports state to the local clipboard for IT verification — the user decides whether to share it with IT; Parleq does not collect it automatically.
Testing without an MDM
To validate a profile on a single Mac without enrolling it in your MDM, write the managed-preferences plist directly as root. See the full recipe in the Managed Configuration reference → Local testing without an MDM.
Related resources
- Managed Configuration key reference — full schema with all 32 supported keys, types, and semantics.
- Sample
.mobileconfig— ready-to-customize profile with every key commented. - Issue #39 — tracking managed-configuration feature additions and future schema expansions.
-
THIRD_PARTY_LICENSES.md— full dependency audit for security review.