Deploying MacWhisper with MDM

MacWhisper reads its MDM configuration from one of two places, in this order:

  1. Managed preferences (recommended): a configuration profile whose payload domain is com.goodsnooze.MacWhisper. This is the standard "custom settings" / "application preferences" payload in Jamf, Kandji, Mosyle, Intune and similar. Changes push to every Mac automatically, and the values are read-only for the user. Available from MacWhisper 15.0.1.
  2. A license file at ~/Library/Application Support/MacWhisper/mdmlicense.plist, for MDMs that can only deploy files or scripts.

Both use the same keys. If both are present, the managed preferences win and the file is ignored. Either way the license is validated on launch.


Configuration profile (managed preferences)

Put the keys from the tables below at the top level of a payload with PayloadType com.goodsnooze.MacWhisper. Everything the file supports is supported here too, including the aiServices array. A minimal user-scope profile:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>PayloadContent</key>
    <array>
        <dict>
            <key>PayloadType</key>
            <string>com.goodsnooze.MacWhisper</string>
            <key>PayloadIdentifier</key>
            <string>com.goodsnooze.MacWhisper.settings</string>
            <key>PayloadUUID</key>
            <string>6F1B2C3D-4E5F-4A6B-8C7D-9E0F1A2B3C4D</string>
            <key>PayloadVersion</key>
            <integer>1</integer>
            <key>PayloadDisplayName</key>
            <string>MacWhisper settings</string>

            <key>licenseKey</key>
            <string>xxxxxxxxx-xxxxxxxx-xxxxxxx-xxxxxxxx</string>
            <key>allowsAppUpdates</key>
            <false/>
            <key>allowsRemoteTranslation</key>
            <true/>
            <key>allowsCloudTranscription</key>
            <true/>
            <key>allowsAddingAIServices</key>
            <true/>
        </dict>
    </array>
    <key>PayloadDisplayName</key>
    <string>MacWhisper MDM configuration</string>
    <key>PayloadIdentifier</key>
    <string>com.goodsnooze.MacWhisper.mdm</string>
    <key>PayloadOrganization</key>
    <string>Your organisation</string>
    <key>PayloadScope</key>
    <string>User</string>
    <key>PayloadType</key>
    <string>Configuration</string>
    <key>PayloadUUID</key>
    <string>0A1B2C3D-4E5F-4A6B-8C7D-9E0F1A2B3C4E</string>
    <key>PayloadVersion</key>
    <integer>1</integer>
</dict>
</plist>

Most MDMs will generate this for you if you upload a plain plist containing just the MacWhisper keys and point it at the com.goodsnooze.MacWhisper domain.

Checking that it arrived

Open MacWhisper > Settings > MDM. The "Loaded From" row shows where the active configuration came from:

  • Managed preferences (configuration profile): the profile is installed and its values are enforced. This is what you want.
  • App preferences (not managed, users can change it): the values reached the app's preference domain but not as a managed profile, for example from a "set once" payload or defaults write. The configuration works, but users can change it.
  • mdmlicense.plist in Application Support: no profile was found; the file method is in use.

License file

If a user has a MacWhisper license file at the following location it will be read on launch (unless a configuration profile is present):

~/Library/Application\ Support/MacWhisper/mdmlicense.plist

Here is a complete mdmlicense.plist example file:

<?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 <plist version="1.0">
 <dict>
 <key>licenseKey</key>
 <string>xxxxxxxxx-xxxxxxxx-xxxxxxx-xxxxxxxx</string>
 <key>allowsRemoteTranslation</key>
 <true/>
 <key>allowsCloudTranscription</key>
 <true/>
 <key>allowsAddingAIServices</key>
 <true/>
 <key>allowsAppUpdates</key>
 <true/>
 
 <!-- AI Services Configuration (optional, available from MacWhisper v12.14+) -->
 <!-- MDM-configured AI services appear as "MDM Managed" and cannot be edited/deleted by users -->
 <key>aiServices</key>
 <array>
     <!-- OpenAI: ChatGPT models for AI Assistant -->
     <!-- Required: type, uniqueId, model, apiKey -->
     <dict>
         <key>type</key>
         <string>openAI</string>
         <key>uniqueId</key>
         <string>550e8400-e29b-41d4-a716-446655440001</string>
         <key>model</key>
         <string>gpt-4o-mini</string>
         <key>apiKey</key>
         <string>sk-your-openai-api-key-here</string>
     </dict>
     
     <!-- Anthropic: Claude models for AI Assistant -->
     <!-- Required: type, uniqueId, model, apiKey -->
     <dict>
         <key>type</key>
         <string>anthropic</string>
         <key>uniqueId</key>
         <string>550e8400-e29b-41d4-a716-446655440002</string>
         <key>model</key>
         <string>claude-3-5-sonnet-latest</string>
         <key>apiKey</key>
         <string>sk-ant-your-anthropic-api-key-here</string>
     </dict>
     
     <!-- Azure OpenAI Service: Microsoft-hosted OpenAI models -->
     <!-- Required: type, uniqueId, deploymentURL, apiVersion, apiKey -->
     <dict>
         <key>type</key>
         <string>azure</string>
         <key>uniqueId</key>
         <string>550e8400-e29b-41d4-a716-446655440000</string>
         <key>deploymentURL</key>
         <string>https://mycompany.openai.azure.com/openai/deployments/gpt-4o/chat/completions</string>
         <key>apiVersion</key>
         <string>2024-02-15-preview</string>
         <key>apiKey</key>
         <string>your-azure-api-key-here</string>
     </dict>
     
     <!-- Groq -->
     <!-- Required: type, uniqueId, model, apiKey -->
     <dict>
         <key>type</key>
         <string>groq</string>
         <key>uniqueId</key>
         <string>550e8400-e29b-41d4-a716-446655440004</string>
         <key>model</key>
         <string>llama-3.3-70b-versatile</string>
         <key>apiKey</key>
         <string>gsk_your-groq-api-key-here</string>
     </dict>
     
     <!-- OpenRouter -->
     <!-- Required: type, uniqueId, model, apiKey -->
     <dict>
         <key>type</key>
         <string>openRouter</string>
         <key>uniqueId</key>
         <string>550e8400-e29b-41d4-a716-446655440005</string>
         <key>model</key>
         <string>meta-llama/llama-3.1-70b-instruct</string>
         <key>apiKey</key>
         <string>sk-or-your-openrouter-api-key-here</string>
     </dict>
     
     <!-- xAI: Grok models -->
     <!-- Required: type, uniqueId, model, apiKey -->
     <dict>
         <key>type</key>
         <string>xAI</string>
         <key>uniqueId</key>
         <string>550e8400-e29b-41d4-a716-446655440006</string>
         <key>model</key>
         <string>grok-beta</string>
         <key>apiKey</key>
         <string>xai-your-xai-api-key-here</string>
     </dict>
     
     <!-- Deepseek -->
     <!-- Required: type, uniqueId, model, apiKey -->
     <dict>
         <key>type</key>
         <string>deepseek</string>
         <key>uniqueId</key>
         <string>550e8400-e29b-41d4-a716-446655440007</string>
         <key>model</key>
         <string>deepseek-chat</string>
         <key>apiKey</key>
         <string>sk-your-deepseek-api-key-here</string>
     </dict>
     
     <!-- Google Gemini -->
     <!-- Required: type, uniqueId, model, apiKey -->
     <dict>
         <key>type</key>
         <string>gemini</string>
         <key>uniqueId</key>
         <string>550e8400-e29b-41d4-a716-446655440008</string>
         <key>model</key>
         <string>gemini-1.5-flash</string>
         <key>apiKey</key>
         <string>your-gemini-api-key-here</string>
     </dict>
     
     <!-- Ollama: Self-hosted open models -->
     <!-- Required: type, uniqueId, baseURL, model -->
     <!-- Note: No apiKey needed for local deployment -->
     <dict>
         <key>type</key>
         <string>ollama</string>
         <key>uniqueId</key>
         <string>550e8400-e29b-41d4-a716-446655440003</string>
         <key>baseURL</key>
         <string>http://localhost:11434</string>
         <key>model</key>
         <string>llama3.2</string>
     </dict>
     
     <!-- LMStudio: Self-hosted models via LMStudio app -->
     <!-- Required: type, uniqueId, baseURL, model -->
     <!-- Note: No apiKey needed for local deployment -->
     <dict>
         <key>type</key>
         <string>lmstudio</string>
         <key>uniqueId</key>
         <string>550e8400-e29b-41d4-a716-446655440009</string>
         <key>baseURL</key>
         <string>http://localhost:1234/v1</string>
         <key>model</key>
         <string>local-model</string>
     </dict>
     
     <!-- Custom: Any OpenAI-compatible API endpoint -->
     <!-- Required: type, uniqueId, name, baseURL, model -->
     <!-- Optional: apiKey (only if endpoint requires authentication) -->
     <dict>
         <key>type</key>
         <string>custom</string>
         <key>uniqueId</key>
         <string>550e8400-e29b-41d4-a716-446655440010</string>
         <key>name</key>
         <string>Corporate LLM Server</string>
         <key>baseURL</key>
         <string>https://llm.company.com/v1</string>
         <key>model</key>
         <string>company-llm-model</string>
         <key>apiKey</key>
         <string>custom-api-key-here</string>
     </dict>
 </array>
 </dict>
 </plist>

Fields listed in the plist will be hidden from configuration within the app (i.e. the corresponding Settings toggle will not be shown). Setting a field to false disables the feature entirely. Omitting a key makes that feature user-configurable.



Required*

key Description value
licenseKey The license key associated with your MDM purchase String

Functionality

allowsCloudTranscription Allow users to use cloud transcription services such as OpenAI, ElevenLabs and Deepgram Bool
allowsAddingAIServices Allow users to setup AI Services Bool
allowsRemoteTranslation Allow users to use remote translation services such as DeepL. Does not currently disable use of Apple's Translate API. Bool
allowsAppUpdates Whether MacWhisper may check for and offer updates. Set to false on Macs where users cannot install updates themselves (for example non-admin users): the update checker is never started, and every "Check for Updates" button, the automatic-update setting and the "Update Available" sidebar button are hidden. Omit or set to true to keep updates on. With updates off, you are responsible for rolling out new versions through your MDM. Available from MacWhisper 15.0.1. Bool
allowAnalytics Whether the app may send anonymous usage analytics. Defaults to true. Bool

MacWhisper uses Sparkle for updates, and Sparkle reads its own SUEnableAutomaticChecks and SUAutomaticallyUpdate keys from the same com.goodsnooze.MacWhisper domain. Those only control Sparkle's scheduled check; MacWhisper's own update buttons are not affected by them. Use allowsAppUpdates instead, which covers everything.


Features

playSoundOnCompleteTranscription Whether to play a sound when a transcription completes Bool
shouldShowTranscriptWithSentences Show the transcript split up by sentences Bool
showTimestampInSegment Show timestamps in the segment view Bool
showTimestampMilliseconds Show milliseconds in the segment view Bool
shouldAlsoSaveVideoToWhisperFile Save video files to a .whisper file when saving Bool
enableSpeakerDetection Enable automatic speaker recognition (with supported models) Bool
removeDuplicatedSegments Automatically remove duplicated segments Bool
shouldLaunchOnLogin Will add MacWhisper to the system Login Items Bool
aiServices Allows preconfigured AI Services to be added. See the plist example above. Array

If you are interested in deploying MacWhisper in your organisation and you have more questions or features you would want to configure, please reach out to support@macwhisper.com and we'd be happy to see what we can do!

Did this answer your question? Thanks for the feedback There was a problem submitting your feedback. Please try again later.