Custom Schemas For Application Configuration Profiles

noahdowd
Contributor

I created a couple of custom schemas in JSON for this new feature. Just cause I'm excited about it! I learned JSON schemas today to do this, so they might be a little basic but maybe someone will find them useful.
Enterprise Connect:

{
    "$schema": "http://json-schema.org/schema#",

    "definitions": {
        "share": {
            "type": "object",
            "properties": {
                "path": {"type": "string"}
            }
        }
    },

    "type": "object",
    "properties": {
        "adRealm": {"type": "string", "default": ""},
        "alwaysGetNewTicket": {"type": "boolean", "default": "false"},
        "checkForNetworkServer": {"type": "string", "default": ""},
        "checkForNetworkType": {"type": "boolean", "default": "false"},
        "checkShowLegacyCertificates": {"type": "boolean", "default": "false"},
        "connectDelay": {"type": "integer", "default": 0, "minimum": 0},
        "connectionCompletedScriptPath": {"type": "string", "default": ""},
        "connectReminderNagInterval": {"type": "integer", "default": 86400, "minimum": 0},
        "connectReminderTime": {"type": "integer", "minimum": 0},
        "dailyReconnectTime": {"type": "integer", "default": 86400, "minimum": 0},
        "debugMode": {"type": "boolean", "default": "false"},
        "destroyKerbTicketUponCardRemoval": {"type": "boolean", "default": "true"},
        "disablePasswordExpirationChecking": {"type": "boolean"},
        "disablePasswordFunctions": {"type": "boolean", "default": "false"},
        "managedshares": {
            "type": "array",
            "items": {"$ref": "#/definitions/share"},
            "default": []
        },
        "mountNetworkHomeDirectory": {"type": "boolean", "default": "false"},
        "orgLogoPath": {"type": "string"},
        "orgUsernameLabel": {"type": "string"},
        "passwordChangeScriptPath": {"type": "string"},
        "passwordChangeURL": {"type": "string"},
        "passwordExpireOverride": {"type": "integer", "minimum": 0},
        "passwordNotificationDays": {"type": "integer", "default": 15, "minimum": 0},
        "preferredDC": {"type": "string"},
        "prepopulatedUsername": {"type": "string", "default": ""},
        "pwReqComplexity": {"type": "boolean", "default": "false"},
        "pwReqComplexityDisableUnicode": {"type": "boolean", "default": "false"},
        "pwReqHistoryCount": {"type": "integer", "minimum": 0},
        "pwReqLength": {"type": "integer", "minimum": 0},
        "pwReqMinimumPasswordAge": {"type": "integer", "minimum": 0},
        "pwReqText": {"type": "string", "default": ""},
        "runAuditScript": {"type": "boolean"},
        "runAuditScriptPath": {"type": "string"},
        "runPasswordChangeScriptOnLocalPasswordSync": {"type": "boolean", "default": "true"},
        "runPeriodicStateCheck": {"type": "boolean", "default": "true"},
        "setupReminderNagInterval": {"type": "integer", "default": 86400, "minimum": 0},
        "shareMountWaitSeconds": {"type": "integer", "default": 0, "minimum": 0},
        "showKeychainIdentities": {"type": "boolean", "default": "false"},
        "showMenuExtra": {"type": "boolean", "default": "true"},
        "showUsernameWithSmartcard": {"type": "boolean", "default": "false"},
        "smartCardMode": {"type": "boolean", "default": "false"},
        "syncLocalPassword": {"type": "boolean"}
    }
}

And Firefox:

{
    "$schema": "http://json-schema.org/schema#",

    "definitions": {
        "bookmark": {
            "type": "object",
            "properties": {
                "Folder": {"type": "string"},
                "URL": {"type": "string"},
                "Title": {"type": "string"},
                "Favicon": {"type": "string"},
                "Placement": {"type": "string"}
            }
        }
    },

    "type": "object",
    "properties": {
        "DisableSetDesktopBackground": {"type": "boolean", "default": "true"},
        "Preferences": {
            "type": "object",
            "properties": {
                "app.update.auto": {"type": "boolean", "default": "true"},
                "security.default_personal_cert": {"type": "string", "default": "Ask Every Time"}
              }
        },
        "DisableProfileImport": {"type": "boolean", "default": "true"},
        "DisableSecurityBypass": {
            "type": "object",
            "properties": {
               "InvalidCertificate": {"type": "boolean", "default": "true"},
               "SafeBrowsing": {"type": "boolean", "default": "true"}
            }
       },
        "DNSOverHTTPS":{
            "type": "object",
            "properties": {
               "Enabled": {"type": "boolean", "default": "false"},
               "Locked": { "type": "boolean", "default": "true"},
               "ProviderURL": { "type": "string", "default": "URL_TO_ALTERNATE_PROVIDER" }
           }
        },
        "CaptivePortal": { "type": "boolean", "default": "false" },
        "DisableAppUpdate": { "type": "boolean", "default": "true" },
        "DefaultDownloadDirectory": { "type": "string", "default": "${home}/Downloads" },
        "DontCheckDefaultBrowser": { "type": "boolean", "default": "true" },
        "SSLVersionMin": { "type": "string", "default": "tls1.2" },
        "Certificates":{
            "type": "object",
            "properties": {
               "Install": {
                "type": "array",
                "items": {"type": "string"},
                "default": ["cert1.der","cert2.pem"]
               },
               "ImportEnterpriseRoots": { "type": "boolean", "default": "true" }
            }
        },
        "Homepage":{
            "type": "object",
            "properties": {
               "URL": { "type": "string", "default": "http://example.com" },
               "Additional": {
                "type": "array",
                    "items": {"type": "string"},
                    "default": ["https://www.example.com/extra-home1.htm","https://www.example.com/extra-home2.htm","https://www.example.com/extra-home3.htm"]
                },
               "Locked": { "type": "boolean", "default": "true" },
                "StartPage": { "type": "string", "default": "homepage"}
            }
        },
        "DisableFormHistory": { "type": "boolean", "default": "true" },
        "SupportMenu":{
            "type": "object",
            "properties": {
               "Title": { "type": "string", "default": "Click here for help" },
               "URL": { "type": "string", "default": "http://example.edu/" },
               "AccessKey": { "type": "string", "default": "C" }
            }
        },
        "DisableSafeMode": { "type": "boolean", "default": "true" },
        "ExtensionUpdate": { "type": "boolean", "default": "false" },
        "DisableSystemAddonUpdate": { "type": "boolean", "default": "true" },
        "DisableFirefoxScreenshots": { "type": "boolean", "default": "true"},
        "FlashPlugin":{
            "type": "object",
            "properties": {
                "Allow": {
                    "type": "array",
                    "items": {"type": "string"},
                    "default": ["https://www.example.com"]
                },
               "Block": {
                    "type": "array",
                    "items": {"type": "string"},
                    "default": ["https://www.example.org"]
                },
               "Default": { "type": "boolean", "default": "true" },
               "Locked": { "type": "boolean", "default": "true" }
            }
        },
        "DisableFirefoxAccounts": { "type": "boolean", "default": "true" },
        "ExtensionSettings":{
            "type": "object",
            "properties": {
               "*":{
                "type": "object",
                "properties": {
                      "blocked_install_message": {"type": "string", "default": "Custom error message"},
                      "install_sources": {
                            "type": "array",
                            "items": {"type": "string"},
                            "default": ["https://addons.mozilla.org/"]
                      },
                      "installation_mode": {"type": "string", "default": "blocked"}
                }
               },
               "uBlock0@raymondhill.net":{
                "type": "object",
                "properties": {
                      "installation_mode": {"type": "string", "default": "force_installed"},
                      "install_url": {"type": "string", "default": "https://addons.mozilla.org/firefox/downloads/latest/ublock-origin/latest.xpi"}
                }
               }
            }
        },
        "DisplayBookmarksToolbar": { "type": "boolean", "default": "true" },
        "HardwareAcceleration": { "type": "boolean", "default": "false" },
        "DisablePrivateBrowsing": { "type": "boolean", "default": "true" },
        "EnterprisePoliciesEnabled": { "type": "boolean", "default": "false" },

        "Bookmarks": {
            "type": "array",
            "items": {"$ref": "#/definitions/bookmark"},
            "default": [{"Folder":"Example1Folder","URL":"https://www.example.org","Title":"Example1","Favicon":"https://www.example.org/favicon.ico","Placement":"toolbar"},{"Folder":"Example2Folder","URL":"https://www.example.com","Title":"Example2","Favicon":"https://www.example.com/favicon.ico","Placement":"menu"}]
        },
        "NetworkPrediction": { "type": "boolean", "default": "false" },
        "EnableTrackingProtection":{
            "type": "object",
            "properties": {
               "Fingerprinting": { "type": "boolean", "default": "true" },
               "Value": { "type": "boolean", "default": "true" },
               "Locked": { "type": "boolean", "default": "true" },
               "Cryptomining": { "type": "boolean", "default": "true" }
            }
        },
        "OverrideFirstRunPage": {"type": "string", "default": "https://www.example.com"},
        "Extensions":{
            "type": "object",
            "properties": {
               "Install": {
                "type": "array",
                "items": {"type": "string"},
                "default": ["https://addons.mozilla.org/firefox/downloads/file/1053714/ghostery_privacy_ad_blocker-8.2.4-an+fx.xpi"]
               },
               "Uninstall": {
                "type": "array",
                "items": {"type": "string"},
                "default": []
                },
               "Locked":
               {
                "type": "array",
                "items": {"type": "string"},
                "default": ["firefox@ghostery.com"]
                }
            }
        },
        "Authentication":{
            "type": "object",
            "properties": {
               "NTLM": {
                "type": "array",
                "items": {"type": "string"},
                "default": ["mydomain.com","https://myotherdomain.com"]
                },
               "Delegated": {
                "type": "array",
                "items": {"type": "string"},
                "default": ["mydomain.com","https://myotherdomain.com"]
               },
               "AllowNonFQDN":{
                "type": "object",
                "properties": {
                    "SPNEGO": { "type": "boolean", "default": "true" },
                    "NTLM": { "type": "boolean", "default": "true" }
                }
               },
               "AllowProxies":{
                "type": "object",
                "properties": {
                      "SPNEGO": { "type": "boolean", "default": "true" },
                      "NTLM": { "type": "boolean", "default": "true" }
                    }
               },
               "Locked": { "type": "boolean", "default": "true" },
               "SPNEGO": {
                "type": "array",
                "items": {"type": "string"},
                "default": ["mydomain.com","https://myotherdomain.com"]
                }
           }
        },
        "Proxy":{
            "type": "object",
            "properties": {
               "SocksVersion": {"type": "string", "default": "4"},
               "Mode": {"type": "string", "default": "manual"},
               "HTTPProxy": {"type": "string", "default": "proxy.example.com:80"},
            "Locked": { "type": "boolean", "default": "true" }
            }
        },
        "SecurityDevices":{
            "type": "object",
            "properties": {
               "NAME_OF_DEVICE": {"type": "string", "default": "PATH_TO_LIBRARY_FOR_DEVICE"}
            }
        },
        "OverridePostUpdatePage": {"type": "string", "default": ""},
        "BlockAboutSupport": { "type": "boolean", "default": "true" },
        "LocalFileLinks": {
            "type": "array",
            "items": {"type": "string"},
            "default": ["http://example.org","http://example.edu"]
        },
        "Permissions":{
            "type": "object",
            "properties": {
               "Camera":{
                "type": "object",
                "properties": {
                      "Allow": {
                        "type": "array",
                        "items": {"type": "string"},
                        "default": ["https://example.org"]
                        },
                      "BlockNewRequests": { "type": "boolean", "default": "true" },
                      "Block": {
                        "type": "array",
                        "items": {"type": "string"},
                        "default": ["https://example.edu"]
                        },
                      "Locked": { "type": "boolean", "default": "true" }
                    }
               },
               "Microphone":{
                "type": "object",
                "properties": {
                      "Allow": {
                        "type": "array",
                        "items": {"type": "string"},
                        "default": ["https://example.org"]
                        },
                      "BlockNewRequests": { "type": "boolean", "default": "true" },
                      "Block": {
                      "type": "array",
                      "items": {"type": "string"},
                      "default": ["https://example.edu"]
                      },
                      "Locked": { "type": "boolean", "default": "true" }
                    }
               },
               "Location":{
                "type": "object",
                "properties": {
                      "Allow": {
                        "type": "array",
                        "items": {"type": "string"},
                        "default": ["https://example.org"]
                        },
                      "BlockNewRequests": { "type": "boolean", "default": "true" },
                      "Block": {
                      "type": "array",
                      "items": {"type": "string"},
                      "default": ["https://example.edu"]
                      },
                      "Locked": { "type": "boolean", "default": "true" }
                    }
               },
               "Notifications":{
                "type": "object",
                "properties": {
                      "Allow": {
                        "type": "array",
                        "items": {"type": "string"},
                        "default": ["https://example.org"]
                        },
                      "BlockNewRequests": { "type": "boolean", "default": "true" },
                      "Block": {
                      "type": "array",
                      "items": {"type": "string"},
                      "default": ["https://example.edu"]
                      },
                      "Locked": { "type": "boolean", "default": "true" }
                    }
               }
            }
        } ,
        "PasswordManagerEnabled": { "type": "boolean", "default": "false" },
        "NoDefaultBookmarks": { "type": "boolean", "default": "true" },
        "FirefoxHome":{
            "type": "object",
            "properties": {
               "TopSites": { "type": "boolean", "default": "true" },
               "Pocket": { "type": "boolean", "default": "false" },
               "Search": { "type": "boolean", "default": "true" },
               "Snippets": { "type": "boolean", "default": "false" },
               "Locked": { "type": "boolean", "default": "true" },
               "Highlights": { "type": "boolean", "default": "true" }
            }
        },
        "DisableFeedbackCommands": { "type": "boolean", "default": "true" },
        "DisablePasswordReveal": { "type": "boolean", "default": "true" },
        "AppUpdateURL": {"type": "string", "default": "https://www.example.com/update.xml"},
        "DisableTelemetry": { "type": "boolean", "default": "true" },
        "DisableDeveloperTools": { "type": "boolean", "default": "true" },
        "SearchBar": {"type": "string", "default": "separate"},
        "WebsiteFilter":{
            "type": "object",
            "properties": {
               "Block": {
                "type": "array",
                "items": {"type": "string"},
                "default": ["<all_urls>"]
               },
               "Exceptions": {
                    "type": "array",
                    "items": {"type": "string"},
                    "default": ["https://www.google.com/*","https://www.yahoo.com/*"]
                }
            }
        },
        "DisableFirefoxStudies": { "type": "boolean", "default": "true" },
        "DownloadDirectory": {"type": "string", "default": "${home}/Downloads"},
        "BlockAboutConfig": { "type": "boolean", "default": "true" },
        "DisableMasterPasswordCreation": { "type": "boolean", "default": "true" },
        "SanitizeOnShutdown": { "type": "boolean", "default": "true" },
        "InstallAddonsPermission":{
            "type": "object",
            "properties": {
               "Allow": {
                "type": "array",
                "items": {"type": "string"},
                "default": ["https://example.org","https://example.edu"]
               },
               "Default": { "type": "boolean", "default": "false" }
            }
        },
        "DisablePocket": { "type": "boolean", "default": "true" },
        "DisableBuiltinPDFViewer": { "type": "boolean", "default": "true" },
        "DisableProfileRefresh": { "type": "boolean", "default": "true" },
        "NewTabPage": { "type": "boolean", "default": "false" },
        "OfferToSaveLoginsDefault": { "type": "boolean", "default": "false" },
        "OfferToSaveLogins": { "type": "boolean", "default": "false" },
        "SSLVersionMax": {"type": "string", "default": "tls1.3"},
        "BlockAboutAddons": { "type": "boolean", "default": "true" },
        "RequestedLocales": {
            "type": "array",
            "items": {"type": "string"},
            "default": ["de","en-US"]
        },
        "BlockAboutProfiles": { "type": "boolean", "default": "true" },
        "Cookies":{
            "type": "object",
            "properties": {
               "Locked": { "type": "boolean", "default": "true" },
               "ExpireAtSessionEnd": { "type": "boolean", "default": "true" },
               "Default": { "type": "boolean", "default": "false" },
               "Allow": {
                "type": "array",
                "items": {"type": "string"},
                "default": ["https://www.example.org/"]
               },
               "RejectTracker": { "type": "boolean", "default": "true" },
               "Block": {
                "type": "array",
                "items": {"type": "string"},
                "default": ["https://www.example.edu/"]
               },
               "AcceptThirdParty": {"type": "string", "default": "never"}
            }
        },
        "DisableForgetButton": { "type": "boolean", "default": "true" },
        "PopupBlocking":{
            "type": "object",
            "properties": {
               "Allow": {
                "type": "array",
                "items": {"type": "string"},
                "default": ["https://www.example.org","https://www.example.edu"]
               },
               "Default": { "type": "boolean", "default": "true" },
               "Locked": { "type": "boolean", "default": "true" }
            }
        }
    } 
}
63 REPLIES 63

talkingmoose
Moderator
Moderator

I absolutely love this!

You're doing exactly as I'd hoped when I first learned of this feature internally, which is the community would help build manifests and share them with others. You've also given some very interesting examples of what these manifests can do too.

We're planning to provide a lot more next week to help the Jamf community discover and use management manifests. Stay tuned.

And thanks for sharing!

noahdowd
Contributor

Hey no problem! Here's one for Safari. I'm definitely getting better at this. Still some room for improvement of course.

{
    "$schema": "http://json-schema.org/schema#",

    "type": "object",
    "properties": {
        "HomePage": {
            "type": "string",
            "title": "Homepage",
            "description": "Homepage URL",
            "default": ""
        },
        "NewWindowBehavior": {
            "type": "number",
            "title": "Contents of new windows",
            "description": "1 = Homepage, 2 = Empty Page, 3 = Same Page As Current Window, 4 = Bookmarks",
            "default": 0,
            "enum": [0, 1, 2, 3, 4]
        },
        "NewTabBehavior": {
            "type": "number",
            "title": "Contents of new tabs",
            "description": "1 = Homepage, 2 = Empty Page, 3 = Same Page As Current Window, 4 = Bookmarks",
            "default": 0,
            "enum": [0, 1, 2, 3, 4]
        },
        "TabCreationPolicy": {
            "type": "number",
            "title": "Open pages in tabs instead of windows",
            "description": "0 = Never, 1 = Automatically, 2 = Always",
            "enum": [0, 1, 2]
        },
        "CommandClickMakesTabs": {
            "type": "boolean",
            "title": "Command-click opens a link in a new tab",
            "default": "true"
        },
        "OpenNewTabsInFront": {
            "type": "boolean",
            "title": "When a new tab or window opens, make it active",
            "default": "false"
        },
        "HistoryAgeInDaysLimit": {
            "type": "number",
            "title": "Remove history items",
            "description": "Number of days to retain history",
            "enum": [1, 7, 14, 30, 365, 365000]
        },
        "DownloadsPath": {
            "type": "string",
            "title": "Downloads location",
            "description": "File system path (can start with ~) where downloaded files will be saved.",
            "default": "~/Downloads"
        },
        "DownloadsClearingPolicy": {
            "type": "number",
            "title": "Remove download list items",
            "description": "0 = Manually, 1 = When Safari quits, 2 = Upon successful download",
            "enum": [0, 1, 2]
        },
        "AutoOpenSafeDownloads": {
            "type": "boolean",
            "title": "Open "safe" files after downloading",
            "description": ""Safe" files include movies, pictures, sounds, PDF and text documents, and archives.",
            "default": "true"
        },
        "ConfirmClosingMultiplePages": {
            "type": "boolean",
            "title": "Confirm closing multiple pages",
            "default": "true"
        },
        "DefaultBrowserPromptingState2": {
            "type": "number",
            "title": "Suppress default web browser prompt",
            "enum": [1]
        },

        "BookmarksMenuIncludesBookmarksToolbar": {
            "type": "boolean",
            "title": "Bookmarks Menu includes Bookmarks Bar",
            "default": "false"
        },
        "BookmarksMenuIncludesAddressBook": {
            "type": "boolean",
            "title": "Bookmarks Menu includes Contacts",
            "default": "false"
        },
        "BookmarksMenuIncludesRendezvous": {
            "type": "boolean",
            "title": "Bookmarks Menu includes Bonjour",
            "default": "false"
        },
        "BookmarksCollectionsIncludeAddressBook": {
            "type": "boolean",
            "title": "Bookmark Collections include Contacts",
            "default": "true"
        },
        "BookmarksCollectionsIncludeRendezvous": {
            "type": "boolean",
            "title": "Bookmark Collections include Bonjour",
            "default": "true"
        },

        "AutoFillFromAddressBook": {
            "type": "boolean",
            "title": "AutoFill web forms using information from contacts",
            "default": "true"
        },
        "AutoFillPasswords": {
            "type": "boolean",
            "title": "AutoFill user names and passwords",
            "default": "false"
        },
        "com.apple.Safari.ContentPageGroupIdentifier.WebKit2ApplePayEnabled": {
            "type": "boolean",
            "title": "AutoFill credit card and Apple Pay data",
            "default": "true"
        },
        "AutoFillMiscellaneousForms": {
            "type": "boolean",
            "title": "AutoFill other forms",
            "default": "true"
        },

        "com.apple.Safari.ContentPageGroupIdentifier.WebKit2PluginsEnabled": {
            "type": "boolean",
            "title": "Enable Plug-ins",
            "default": "true"
        },
        "com.apple.Safari.ContentPageGroupIdentifier.WebKit2JavaEnabled": {
            "type": "boolean",
            "title": "Enable Java",
            "default": "true"
        },
        "com.apple.Safari.ContentPageGroupIdentifier.WebKit2JavaScriptEnabled": {
            "type": "boolean",
            "title": "Enable JavaScript",
            "default": "true"
        },
        "com.apple.Safari.ContentPageGroupIdentifier.WebKit2JavaScriptCanOpenWindowsAutomatically": {
            "type": "boolean",
            "title": "Allow JavaScript to open windows automatically",
            "default": "false"
        },
        "AskBeforeSubmittingInsecureForms": {
            "type": "boolean",
            "title": "Ask before submitting insecure forms",
            "default": "true"
        },

        "com.apple.Safari.ContentPageGroupIdentifier.WebKit2PrivateBrowsingEnabled": {
            "type": "boolean",
            "title": "Private browsing",
            "default": "false"
        },
        "BlockStoragePolicy": {
            "type": "number",
            "title": "Block cookies and website data",
            "description": "0 = Always, 1 = Never, 2 = Third parties except sites you visit, 3 = All third parties",
            "enum": [0, 1, 2, 3]
        },
        "SendDoNotTrackHTTPHeader": {
            "type": "boolean",
            "title": "Website tracking",
            "description": "Prevent cross-site tracking",
            "default": "true"
        },

        "ExtensionsEnabled": {
            "type": "boolean",
            "title": "Enable Extensions",
            "default": "true"
        },
        "DidDisableIndividualExtensionsAfterRemovingOnOffSwitchIfNecessary": {
            "type": "boolean",
            "title": "Disable Extensions immediately",
            "default": "false"
        },
        "LocalFileRestrictionsEnabled": {
            "type": "boolean",
            "title": "Enable local file restrictions",
            "default": "true"
        },      

        "CanPromptForPushNotifications": {
            "type": "boolean",
            "title": "Allow Notifications",
            "default": "true"
        },

        "com.apple.Safari.ContentPageGroupIdentifier.WebKit2LoadsImagesAutomatically": {
            "type": "boolean",
            "title": "Display images",
            "default": "true"
        },
        "com.apple.Safari.ContentPageGroupIdentifier.WebKit2TabsToLinks": {
            "type": "boolean",
            "title": "Press Tab to highlight each item on a webpage",
            "default": "false"
        },
        "IncludeDevelopMenu": {
            "type": "boolean",
            "title": "Show Develop menu in menu bar",
            "default": "false"
        },
        "com.apple.Safari.ContentPageGroupIdentifier.WebKit2DefaultTextEncodingName": {
            "type": "string",
            "title": "Default text encoding",
            "description": "The name of the text encoding to use for webpages that don't specify a text encoding. See http://www.iana.org/assignments/character-sets",
            "examples": ["US-ASCII", "macintosh", "Adobe-Standard-Encoding"]
        },
        "com.apple.Safari.ContentPageGroupIdentifier.WebKit2MinimumFontSize": {
            "type": "number",
            "title": "Never use fonts smaller than:",
            "minimum": 1,
            "default": 9
        },
        "com.apple.Safari.ContentPageGroupIdentifier.WebKit2StandardFontFamily": {
            "type": "string",
            "title": "Default font",
            "description": "Font family to use when a webpage does not specify a font.",
            "examples": ["Helvetica", "Verdana", "Times"]
        },
        "com.apple.Safari.ContentPageGroupIdentifier.WebKit2DefaultFontSize": {
            "type": "number",
            "title": "Default font size",
            "description": "Font size to use when a webpage does not specify a font size.",
            "minimum": 1,
            "default": 9
        },
        "com.apple.Safari.ContentPageGroupIdentifier.WebKit2FixedFontFamily": {
            "type": "string",
            "title": "Default fixed-width font family",
            "description": "Font family to use when a webpage specifies fixed-width font."
        },
        "com.apple.Safari.ContentPageGroupIdentifier.WebKit2DefaultFixedFontSize": {
            "type": "number",
            "title": "Default fixed-width font size",
            "description": "Font size to use when a webpage specifies fixed-width font.",
            "minimum": 1,
            "default": 9
        },
        "DefaultDatabaseQuota": {
            "type": "number",
            "title": "Default space for database storage",
            "description": "In bytes",
            "enum": [0, 1048576, 5242880, 10485760, 52428800, 104857600, 524288000],
            "default": 5242880
        },
        "com.apple.Safari.ContentPageGroupIdentifier.WebKit2ShouldPrintBackgrounds": {
            "type": "boolean",
            "title": "Print backgrounds",
            "default": "false"
        },
        "PrintHeadersAndFooters": {
            "type": "boolean",
            "title": "Print headers and footers",
            "default": "true"
        }
    }
}

noahdowd
Contributor

Better Firefox one:

{
    "$schema": "http://json-schema.org/schema#",
    "title": "org.mozilla.firefox",

    "definitions": {
        "bookmark": {
            "type": "object",
            "title": "Bookmark",
            "properties": {
                "Folder": {"type": "string", "title": "Folder"},
                "URL": {"type": "string", "title": "URL"},
                "Title": {"type": "string", "title": "Title"},
                "Favicon": {"type": "string", "title": "Favicon"},
                "Placement": {"type": "string", "title": "Placement"}
            }
        },
        "extension": {
            "type": "object",
            "title": "Extension",
            "properties": {
                "installation_mode": {
                    "type": "string",
                    "title": "Installation Mode",
                    "default": "blocked",
                    "enum": ["allowed", "blocked", "force_installed", "normal_installed"]
                },
                "install_url": {
                    "type": "string",
                    "description": "The location of the extension to be installed.",
                    "title": "Install URL"      
                },
                "install_sources": {
                    "type": "array",
                    "title": "Install Sources",
                    "items": {"type": "string", "title": "URL"}
                },
                "blocked_install_message": {
                    "type": "string",
                    "title": "Blocked Install Message",
                    "description": "Error message to display to users if they're blocked from installing an extension."
                }
            }
        }
    },

    "type": "object",
    "properties": {
        "DisableSetDesktopBackground": {
            "type": "boolean",
            "title": "Disable Desktop Background",
            "default": "true"
        },
        "Preferences": {
            "type": "object",
            "title": "Preferences",
            "properties": {
                "app.update.auto": {"type": "boolean", "title": "Enable Auto Update", "default": "true"},
                "security.default_personal_cert": {"type": "string", "title": "Default Personal Certificate", "default": "Ask Every Time"}
              }
        },
        "DisableProfileImport": {"type": "boolean", "title": "Disable Profile Importing", "default": "true"},
        "DisableSecurityBypass": {
            "type": "object",
            "title": "Security Bypass Settings",
            "properties": {
               "InvalidCertificate": {"type": "boolean", "title": "Disable Invalid SSL Cert Bypass", "default": "true"},
               "SafeBrowsing": {"type": "boolean", "title": "Allow Safe Browsing", "default": "true"}
            }
       },
        "DNSOverHTTPS":{
            "type": "object",
            "title": "DNS Over HTTPS",
            "properties": {
               "Enabled": {"type": "boolean", "title": "Enabled", "default": "false"},
               "Locked": { "type": "boolean", "title": "Locked", "default": "true"},
               "ProviderURL": { "type": "string", "title": "Provider URL", "default": "URL_TO_ALTERNATE_PROVIDER" }
           }
        },
        "CaptivePortal": { "type": "boolean", "title": "Captive Portal", "default": "false" },
        "DisableAppUpdate": { "type": "boolean", "title": "Disable App Update", "default": "true" },
        "DefaultDownloadDirectory": { "type": "string", "title": "Default Download Directory", "default": "${home}/Downloads" },
        "DontCheckDefaultBrowser": { "type": "boolean", "title": "Don't Check Default Browser", "default": "true" },
        "Certificates":{
            "type": "object",
            "title": "Certificates",
            "properties": {
               "Install": {
                "type": "array",
                "title": "Install",
                "items": {"type": "string"},
                "default": ["cert1.der","cert2.pem"]
               },
               "ImportEnterpriseRoots": { "type": "boolean", "title": "Import Enterprise Root CAs", "default": "true" }
            }
        },
        "Homepage":{
            "type": "object",
            "title": "Homepage",
            "properties": {
               "URL": { "type": "string", "title": "URL", "default": "http://example.com" },
               "Additional": {
                "type": "array",
                "title": "Additional Tabs",
                    "items": {"type": "string", "title": "URL"},
                    "default": ["https://www.example.com/extra-home1.htm","https://www.example.com/extra-home2.htm","https://www.example.com/extra-home3.htm"]
                },
               "Locked": { "type": "boolean", "title": "Locked", "default": "true" },
                "StartPage": { "type": "string", "title": "Start Page", "default": "homepage", "enum": ["none", "homepage", "previous-session"]}
            }
        },
        "DisableFormHistory": { "type": "boolean", "title": "Disable Form History", "description": "Turn off saving information on web forms and the search bar.", "default": "true" },
        "SupportMenu":{
            "type": "object",
            "title": "Support Menu",
            "description": "Add a menuitem to the help menu for specifying support information.",
            "properties": {
               "Title": { "type": "string", "title": "Window Title", "default": "Click here for help" },
               "URL": { "type": "string", "title": "URL", "default": "http://example.edu/" },
               "AccessKey": { "type": "string", "title": "Keyboard Key to Access", "default": "C" }
            }
        },
        "DisableSafeMode": { "type": "boolean", "title": "Disable Safe Mode", "default": "true" },
        "ExtensionUpdate": { "type": "boolean", "title": "Allow Extension Updates", "default": "false" },
        "DisableSystemAddonUpdate": { "type": "boolean", "title": "Disable System Add-On Updates", "default": "true" },
        "DisableFirefoxScreenshots": { "type": "boolean", "title": "Disable Firefox Screenshots", "default": "true"},
        "FlashPlugin":{
            "type": "object",
            "title": "Adobe Flash Plugin",
            "properties": {
                "Allow": {
                    "type": "array",
                    "title": "Allow",
                    "items": {"type": "string", "title": "URL"},
                    "default": ["https://www.example.com"]
                },
               "Block": {
                    "type": "array",
                    "title": "Block",
                    "items": {"type": "string", "title": "URL"},
                    "default": ["https://www.example.org"]
                },
               "Default": { "type": "boolean", "title": "Default", "default": "true" },
               "Locked": { "type": "boolean", "title": "Locked", "default": "true" }
            }
        },
        "DisableFirefoxAccounts": { "type": "boolean", "title": "Disable Firefox Accounts", "default": "true" },
        "ExtensionSettings":{
            "type": "array",
            "title": "Extension Settings",
            "items": [{
                "type": "object",
                "title": "Extension",
                "properties": {
                    "*": {
                        "type": "object",
                        "title": "All Extensions",
                        "properties": {
                            "blocked_install_message": {
                                "type": "string",
                                "title": "Blocked Install Message",
                                "default": "Custom error message"
                            },
                            "install_sources": {
                                "type": "array",
                                "title": "Install Source URLs",
                                "items": {"type": "string", "title": "URL"},
                                "default": ["https://addons.mozilla.org/"]
                            },
                            "installation_mode": {
                                "type": "string",
                                "title": "Installation Mode", 
                                "default": "blocked", 
                                "enum": ["allowed", "blocked", "force_installed", "normal_installed"]
                            },
                            "allowed_types": {
                                "type": "array",
                                "title": "Allowed Types",
                                "items": {"type": "string", "enum": ["extension", "theme", "dictionary", "langpack"]}
                            }
                        }
                    }
                }
            }],
            "additionalItems": {"$ref": "#/definitions/extension"}
        },
        "DisplayBookmarksToolbar": { "type": "boolean", "title": "Display Bookmarks Toolbar", "default": "true" },
        "HardwareAcceleration": { "type": "boolean", "title": "Enable Hardware Acceleration", "default": "false" },
        "DisablePrivateBrowsing": { "type": "boolean", "title": "Disable Private Browsing", "default": "true" },
        "EnterprisePoliciesEnabled": { "type": "boolean", "title": "Enable Enterprise Policies", "description": "Enable policy support on macOS.", "default": "false" },

        "Bookmarks": {
            "type": "array",
            "title": "Bookmarks",
            "items": {"$ref": "#/definitions/bookmark"},
            "default": [{"Folder":"Example1Folder","URL":"https://www.example.org","Title":"Example1","Favicon":"https://www.example.org/favicon.ico","Placement":"toolbar"},{"Folder":"Example2Folder","URL":"https://www.example.com","Title":"Example2","Favicon":"https://www.example.com/favicon.ico","Placement":"menu"}]
        },
        "NetworkPrediction": { "type": "boolean", "title": "Network Prediction", "description": "Enable or disable network prediction (DNS prefetching).", "default": "false" },
        "EnableTrackingProtection":{
            "type": "object",
            "title": "Tracking Protection",
            "properties": {
               "Fingerprinting": { "type": "boolean", "title": "Fingerprinting", "default": "true" },
               "Value": { "type": "boolean", "title": "Trackers", "default": "true" },
               "Locked": { "type": "boolean", "title": "Locked", "default": "true" },
               "Cryptomining": { "type": "boolean", "title": "Cryptomining", "default": "true" }
            }
        },
        "OverrideFirstRunPage": {"type": "string", "title": "First Run Page", "default": "https://www.example.com"},
        "Extensions":{
            "type": "object",
            "title": "Extensions",
            "properties": {
               "Install": {
                "type": "array",
                "title": "Install",
                "items": {"type": "string", "title": "URL"},
                "default": ["https://addons.mozilla.org/firefox/downloads/file/1053714/ghostery_privacy_ad_blocker-8.2.4-an+fx.xpi"]
               },
               "Uninstall": {
                "type": "array",
                "title": "Uninstall",
                "items": {"type": "string", "title": "Extension ID"},
                "default": []
                },
               "Locked":
               {
                "type": "array",
                "title": "Locked",
                "items": {"type": "string", "title": "Extension ID"},
                "default": ["firefox@ghostery.com"]
                }
            }
        },
        "Authentication":{
            "type": "object",
            "title": "Authentication",
            "properties": {
               "NTLM": {
                "type": "array",
                "title": "NTLM",
                "items": {"type": "string", "title": "Domain"},
                "default": ["mydomain.com","https://myotherdomain.com"]
                },
               "Delegated": {
                "type": "array",
                "title": "Delegated",
                "items": {"type": "string", "title": "Domain"},
                "default": ["mydomain.com","https://myotherdomain.com"]
               },
               "AllowNonFQDN":{
                "type": "object",
                "title": "Allow Non-FQDN",
                "properties": {
                    "SPNEGO": { "type": "boolean", "title": "SPNEGO", "default": "true" },
                    "NTLM": { "type": "boolean", "title": "NTLM", "default": "true" }
                }
               },
               "AllowProxies":{
                "type": "object",
                "title": "Allow Proxies",
                "properties": {
                      "SPNEGO": { "type": "boolean", "title": "SPNEGO", "default": "true" },
                      "NTLM": { "type": "boolean", "title": "NTLM", "default": "true" }
                    }
               },
               "Locked": { "type": "boolean", "title": "Locked", "default": "true" },
               "SPNEGO": {
                "type": "array",
                "title": "SPNEGO",
                "items": {"type": "string", "title": "Domain"},
                "default": ["mydomain.com","https://myotherdomain.com"]
                }
           }
        },
        "Proxy":{
            "type": "object",
            "title": "Proxy",
            "properties": {
               "Mode": {"type": "string", "title": "Mode", "default": "manual", "enum": ["none", "system", "manual", "autoDetect", "autoConfig"]},
               "Locked": { "type": "boolean", "default": "true" },
               "HTTPProxy": {"type": "string", "title": "HTTP Proxy", "default": "https://httpproxy.example.com"},
               "UseHTTPProxyForAllProtocols": {
                    "type": "boolean",
                    "title": "Use HTTP Proxy For All Protocols",
                    "default": "false"
                },
                "SSLProxy": {
                    "type": "string",
                    "title": "SSL Proxy",
                    "default": "https://sslproxy.example.com"
                },
                "FTPProxy": {
                    "type": "string",
                    "title": "FTP Proxy",
                    "default": "https://ftpproxy.example.com"
                },
                "SOCKSProxy": {
                    "type": "string",
                    "title": "SOCKS Proxy",
                    "default": "https://socksproxy.example.com"
                },
                "SOCKSVersion": {"type": "string", "title": "Socks Version", "default": "4", "enum": ["4", "5"]},
                "Passthrough": {
                    "type": "array",
                    "title": "Passthrough",
                    "items": {"type": "string", "title": "URL or IP"},
                    "default": ["<local>"]
                },
                "AutoConfigURL": {
                    "type": "string",
                    "title": "Auto Config URL",
                    "description": "URL for proxy configuration (only used if Mode is autoConfig)."
                },
                "AutoLogin": {
                    "type": "boolean",
                    "title": "Auto Login",
                    "description": "Do not prompt for authentication if password is saved.",
                    "default": "false"
                },
                "UseProxyForDNS": {
                    "type": "boolean",
                    "title": "Use Proxy For DNS",
                    "description": "Use proxy DNS when using SOCKS v5.",
                    "default": "false"
                }
            }
        },
        "SecurityDevices":{
            "type": "array",
            "title": "Security Devices",
            "description": "Install PKCS #11 modules.",
            "items": {
                "type": "object",
                "properties": {
                   "key": {"type": "string", "title": "Device Name"},
                   "value": {
                       "type": "string",
                       "title": "Device",
                       "default": "PATH_TO_LIBRARY_FOR_DEVICE"
                    },
                   "propertyNames": {"type": "string"}
                }
            }
        },
        "OverridePostUpdatePage": {"type": "string", "title": "Post-Update Page", "default": ""},
        "BlockAboutSupport": { "type": "boolean", "title": "Block About Support", "description": "Block access to Troubleshooting Information (about:support).", "default": "true" },
        "LocalFileLinks": {
            "type": "array",
            "title": "Local File Links",
            "description": "Enable linking to local files by origin.",
            "items": {"type": "string", "title": "URL"},
            "default": ["http://example.org","http://example.edu"]
        },
        "Permissions":{
            "type": "object",
            "title": "Permissions",
            "properties": {
               "Camera":{
                "type": "object",
                "title": "Camera",
                "properties": {
                      "Allow": {
                        "type": "array",
                        "title": "Allow",
                        "items": {"type": "string", "title": "URL"},
                        "default": ["https://example.org"]
                        },
                      "BlockNewRequests": { "type": "boolean", "title": "Block New Requests", "default": "true" },
                      "Block": {
                        "type": "array",
                        "title": "Block",
                        "items": {"type": "string", "title": "URL"},
                        "default": ["https://example.edu"]
                        },
                      "Locked": { "type": "boolean", "title": "Locked", "default": "true" }
                    }
               },
               "Microphone":{
                "type": "object",
                "title": "Microphone",
                "properties": {
                      "Allow": {
                        "type": "array",
                        "title": "Allow",
                        "items": {"type": "string", "title": "URL"},
                        "default": ["https://example.org"]
                        },
                      "BlockNewRequests": { "type": "boolean", "title": "Block New Requests", "default": "true" },
                      "Block": {
                      "type": "array",
                      "title": "Block",
                      "items": {"type": "string", "title":"URL"},
                      "default": ["https://example.edu"]
                      },
                      "Locked": { "type": "boolean", "title":"Locked", "default": "true" }
                    }
               },
               "Location":{
                "type": "object",
                "title": "Location",
                "properties": {
                      "Allow": {
                        "type": "array",
                        "title": "Allow",
                        "items": {"type": "string", "title": "URL"},
                        "default": ["https://example.org"]
                        },
                      "BlockNewRequests": { "type": "boolean", "title": "Block New Requests", "default": "true" },
                      "Block": {
                      "type": "array",
                      "title": "Block",
                      "items": {"type": "string", "title": "URL"},
                      "default": ["https://example.edu"]
                      },
                      "Locked": { "type": "boolean", "title": "Locked", "default": "true" }
                    }
               },
               "Notifications":{
                "type": "object",
                "title": "Notifications",
                "properties": {
                      "Allow": {
                        "type": "array",
                        "title": "Allow",
                        "items": {"type": "string", "title": "URL"},
                        "default": ["https://example.org"]
                        },
                      "BlockNewRequests": { "type": "boolean", "title": "Block New Requests", "default": "true" },
                      "Block": {
                      "type": "array",
                      "title": "Block",
                      "items": {"type": "string", "title": "URL"},
                      "default": ["https://example.edu"]
                      },
                      "Locked": { "type": "boolean", "title": "Locked", "default": "true" }
                    }
               }
            }
        } ,
        "PasswordManagerEnabled": { "type": "boolean", "title": "Password Manager Enabled", "default": "false" },
        "NoDefaultBookmarks": { "type": "boolean", "title": "No Default Bookmarks", "default": "true" },
        "FirefoxHome":{
            "type": "object",
            "title": "Firefox Home",
            "properties": {
               "TopSites": { "type": "boolean", "title": "Top Sites", "default": "true" },
               "Pocket": { "type": "boolean", "title": "Pocket", "default": "false" },
               "Search": { "type": "boolean", "title": "Search", "default": "true" },
               "Snippets": { "type": "boolean", "title": "Snippets", "default": "false" },
               "Locked": { "type": "boolean", "title": "Locked", "default": "true" },
               "Highlights": { "type": "boolean", "title": "Highlights", "default": "true" }
            }
        },
        "DisableFeedbackCommands": { "type": "boolean", "title": "Disable Feedback Commands", "description": "Disable the menus for reporting sites.", "default": "true" },
        "DisablePasswordReveal": { "type": "boolean", "title": "Disable Password Reveal", "default": "true" },
        "AppUpdateURL": {"type": "string", "title": "App Update URL", "default": "https://www.example.com/update.xml"},
        "DisableTelemetry": { "type": "boolean", "title": "Disable Telemetry", "default": "true" },
        "DisableDeveloperTools": { "type": "boolean", "title": "Disable Developer Tools", "default": "true" },
        "SearchBar": {"type": "string", "title": "Search Bar", "default": "separate", "enum": ["unified", "separate"]},
        "WebsiteFilter":{
            "type": "object",
            "title": "Website Filter",
            "properties": {
               "Block": {
                "type": "array",
                "title": "Block", 
                "items": {"type": "string", "title": "URL" },
                "default": ["<all_urls>"]
               },
               "Exceptions": {
                    "type": "array",
                    "title": "Exceptions",
                    "items": {"type": "string", "title": "URL"},
                    "default": ["https://www.google.com/*","https://www.yahoo.com/*"]
                }
            }
        },
        "DisableFirefoxStudies": { "type": "boolean", "title": "Disable Firefox Studies", "description": "Disable Firefox studies (Shield).", "default": "true" },
        "DownloadDirectory": {"type": "string", "title": "Download Directory", "default": "${home}/Downloads"},
        "BlockAboutConfig": { "type": "boolean", "title": "Block About Config", "description": "Block access to about:config.", "default": "true" },
        "DisableMasterPasswordCreation": { "type": "boolean", "title": "Disable Master Password Creation", "default": "true" },
        "SanitizeOnShutdown": { "type": "boolean", "title": "Sanitize On Shutdown", "description": "Clear all data on shutdown.", "default": "true" },
        "InstallAddonsPermission":{
            "type": "object",
            "title": "Install Addons Permissions",
            "properties": {
               "Allow": {
                "type": "array",
                "title": "Allow", 
                "items": {"type": "string", "title": "URL"},
                "default": ["https://example.org","https://example.edu"]
               },
               "Default": { "type": "boolean", "title": "Set As Default", "default": "false" }
            }
        },
        "DisablePocket": { "type": "boolean", "title": "Disable Pocket", "description": "Remove Pocket in the Firefox UI.", "default": "true" },
        "DisableBuiltinPDFViewer": { "type": "boolean", "title": "Disable Built-in PDF Viewer", "default": "true" },
        "DisableProfileRefresh": { "type": "boolean", "title": "Disable Profile Refresh", "description": "Disable the Refresh Firefox button on about:support and support.mozilla.org", "default": "true" },
        "NewTabPage": { "type": "boolean", "title": "New Tab Page", "default": "false" },
        "OfferToSaveLoginsDefault": { "type": "boolean", "title": "Offer To Save Logins - Default Value", "description": "Sets the default value of signon.rememberSignons without locking it.", "default": "false" },
        "OfferToSaveLogins": { "type": "boolean", "title": "Offer To Save Logins", "default": "false" },
        "SSLVersionMin": {"type": "string", "title": "SSL Version Minimum", "default": "tls1.3", "enum": ["tls1", "tls1.1", "tls1.2", "tls1.3"]},
        "SSLVersionMax": {"type": "string", "title": "SSL Version Maximum", "default": "tls1.3", "enum": ["tls1", "tls1.1", "tls1.2", "tls1.3"]},
        "BlockAboutAddons": { "type": "boolean", "title": "Block About Addons", "description": "Block access to the Add-ons Manager (about:addons).", "default": "true" },
        "RequestedLocales": {
            "type": "array",
            "title": "Requested Locales",
            "items": {"type": "string", "title": "Locale"},
            "default": ["de","en-US"]
        },
        "BlockAboutProfiles": { "type": "boolean", "title": "Block About Profiles", "description": "Block access to About Profiles (about:profiles).", "default": "true" },
        "Cookies":{
            "type": "object",
            "title": "Cookies",
            "properties": {
               "Locked": { "type": "boolean", "title": "Locked", "default": "true" },
               "ExpireAtSessionEnd": { "type": "boolean", "title": "Expire At Session End", "default": "true" },
               "Default": { "type": "boolean", "title": "Default", "default": "false" },
               "Allow": {
                "type": "array",
                "title": "Allow", 
                "items": {"type": "string", "title": "URL"},
                "default": ["https://www.example.org/"]
               },
               "RejectTracker": { "type": "boolean", "title": "Reject Tracker", "default": "true" },
               "Block": {
                "type": "array",
                "title": "Block", 
                "items": {"type": "string", "title": "URL"},
                "default": ["https://www.example.edu/"]
               },
               "AcceptThirdParty": {"type": "string", "title": "Accept Third Party", "default": "never", "enum": ["always", "never", "from-visited"]}
            }
        },
        "DisableForgetButton": { "type": "boolean", "title": "Disable Forget Button", "default": "true" },
        "PopupBlocking":{
            "type": "object",
            "title": "Popup Blocking", 
            "properties": {
               "Allow": {
                "type": "array",
                "title": "Allow", 
                "items": {"type": "string", "title": "URL"},
                "default": ["https://www.example.org","https://www.example.edu"]
               },
               "Default": { "type": "boolean", "title": "Default", "default": "true" },
               "Locked": { "type": "boolean", "title": "Locked", "default": "true" }
            }
        }
    } 
}

mm2270
Legendary Contributor III

Hey @noahdowd, thanks for posting these custom schemas! These are very cool, and illustrate how useful this new feature can be in the product. Of course, thanks also go to Jamf for adding the feature in in the first place.

But I need to ask, given the complexity of the last schema you just posted above on Firefox, are you using some kind of tool to build these, or are you hand crafting them? I ask because after seeing some of the ones you posted earlier, I began looking into it and starting working on one for NoMAD, which, once I feel it's done I'll post here. Maybe this thread can serve as an initial placeholder for new Custom Application schemas until there's a better repository for them. But I've been making the one I'm working on by hand, and I gotta say, it's a TON of work! Plus, since I'm a total noob on JSON, I have to keep checking my work through an online JSON validator, which tells me if I've formatted something wrong and can correct it.

So, how are you making these? I'd love to find some way to speed up the process if possible. If there isn't one, that's fine, but its just good for anyone else coming here to note that these aren't exactly easy to create if you aren't that familiar with their structure at first.

noahdowd
Contributor

Haha nope all by hand! Just BBEdit and this JSON schema validator.
I'm adding things like titles, descriptions, and enums as I learn about them. A tool would be great!

mm2270
Legendary Contributor III

Ah, ok. Good to know. :) I'm also using BBEdit for my tooling, though I was using a different online JSON validator. Thanks for the link to that one. Good to have options!

In looking at your most recent one, you gave me some ideas on how to better structure the data so I can sort of "group" related items together in more logical sections. I wasn't happy about how each setting was on it's own line and taking up so much space in the final UI. I'd like to put related items, such as naming the menu items for example, in a grouping so they make more sense. I might try to copy off of what you've done. Again, thanks for posting these!

jhuls
Contributor III

So could someone explain to those of us who might be considered at times to be slow behind the wheel(so to speak anyways) what is this JSON schema thing you speak of? What does this accomplish?

mm2270
Legendary Contributor III

@jhuls Valid question. I'm not a JSON person, so I'm only just learning about it. JSON stands for JavaScript Object Notation. It's an open standard for data exchange. But more importantly, what Jamf added in Jamf Pro version 10.19 is a way for us to create JSON schemas that can be used with their relatively new Application & Custom Settings payload.

2d5e0af095874fecbf0c41ba018673c7

Once configured, instead of using just the couple of ones that Jamf provides out of the box win their own repository for their own products (Jamf Connect, etc.) and Microsoft Office & AutoUpdate, you can choose Custom Schema now from the list.

7d5eea1177664a18be7002982a5c1276

Once you do that, you get a few tabs that show up, one called "Schema" that let's you paste in custom JSON formatted text, that can define the options available in a nice GUI way to set up preferences. This is basically another way of creating a Config Profile for something like a 3rd party application. We've always been able to upload a crafted plist with the values we need, and have Jamf Pro read it in, but it's not easily editable in that format, whereas with the new JSON schema, we can add/remove keys, make changes to the values on the fly and so on, without needing to edit a plist file and re-upload it.

Here are some screenshots that show how the one I'm working on looks once it's imported and you click on the "Properties" tab. This is for the application NoMAD.

5955a75aa4464e1191564fa5e20ef5c5

afa22b47b1c84047b7ae937a4b197f9f

67f852d17a3640499dd0784ec128432f

331115c8c09c41e8be8f3e32a83287a6

d0e210f58524408abfbf9acce576f47c

8a0721a709194a07b9a49d07578211d9

..and there's more that I'm not showing here, like all the custom icon paths and so on, just because it's too many images. Basically, all the options that are normally in a plist file with keys and values will show up as GUI objects that you can set, and then when saved, the Config Profile is written out so it applies whatever settings you've chosen/set.

Another cool thing with this is that you have a way of adding/removing keys right in the UI. So for example, let's say you don't care about setting the certificate options, specifically the "Get Certificate Automatically" and "Exportable Private Key" items. You can just click the top Add/Remove Properties button and then uncheck those items from the list and they will get removed from both the UI and the final Config Profile.

9d67d6a7a73343b982e2fe7f546c1150

Pretty cool!

So hopefully that helps to explain a little of why we're discussing this. Again, this is new in 10.19. I'm testing it out under the 10.20 beta because my Jamf cloud instance isn't scheduled to be upgraded until this weekend I believe.

jhuls
Contributor III

@mm2270 Thanks a ton for that explanation. We're still on 10.17.1 ourselves but hoping to upgrade in the next couple weeks. This looks like a practical feature to definitely look forward to.

mthakur
Contributor

@mm2270 I agree this is a significant step forward, but it appears to shift the complexity from writing plist files to ... writing JSON files ... with a text editor ... by Jamf admins ... at end user organizations.

What would be ideal, though, is if third party app developers themselves created these JSON files and maintained them over time, and perhaps Jamf Pro could import them.

Admittedly, this approach would open up security concerns (which potentially could be fixed in part by signing the JSON files), but it would have the huge advantage of placing the burden squarely where it belongs, namely on the app developers and MDM providers themselves.

Edited to add: See this link for a fine example of a third party app developer — Microsoft — doing exactly that:
Simplifying Microsoft Edge configuration profiles for Jamf Pro

mm2270
Legendary Contributor III

@mthakur You'll get no disagreement from me on that. You're right that it does shift this to writing JSON instead of xml or hand crafting .mobileconfig files. I kind of said as much above in my earlier post, that this is definitely NOT for the novice admin.

However, this feature is an attempt to partially fulfill this one, I think. Specifically, if you look at the mock up done by @milesleacy here, it's not all that dissimilar, but it DOES require building the framework in JSON to even be able to use a simple add/remove approach like what he mocked up.
So, while it's not the simple GUI approach we might have all hoped for, I feel it's at least a step in the right direction.
It's a first step, and I think is designed to work in conjunction with some of the other changes Jamf is making around Config Profiles, like the sliders for On/Off states they introduced in a couple of payloads, which will help avoid placing options that we don't even want into a profile.
Eventually it'll all get there, but it's going to take some time and iterations to achieve it.

mscottblake
Valued Contributor

A couple of us have been writing these up and posting them to GitHub.
https://github.com/MScottBlake/jamf-custom-schemas
https://github.com/chrisgrande/jamf-profile-schemas
https://github.com/joshua-d-miller/JAMF-JSON-Schema

Chris and I have talked a bit about creating a new team to host these to cut down on duplication of work. @mm2270, I can vouch for how much work the NoMAD one is and I wouldn't wish it on anyone since it's already working (as far as I can tell).

Now that I see you were also working on NoMAD, it's making me want to go create a team now...

Standby while I go get something started.

mscottblake
Valued Contributor

We now have a team setup in GitHub at https://github.com/Jamf-Custom-Profile-Schemas so we can group all of the custom schemas in one place and hopefully reduce duplicated effort.

mm2270
Legendary Contributor III

Haha, and just as I finished (mostly) the NoMAD one I was working on. In looking at yours I can see it uses more advanced options overall in some places. Well, it was a good exercise for me to learn a bit about JSON anyway. I like how yours uses a "Configured/Not Configured" drop down for each item. I didn't even know that was an option (again, noob at JSON that I am). So I can learn from that for the next go around.

I'll check out the other ones too. Glad there's a more central place for these for the moment. Jamf should probably add a place here where they can be uploaded and hosted too, kind of like with Extension Attributes and other resources.

mscottblake
Valued Contributor

Yeah, I agree that they should, but in the absence of that, I hope this way works.

mscottblake
Valued Contributor

I'm just going to leave this here: https://github.com/BIG-RAT/Managed-App-Schema-Builder

noahdowd
Contributor

@mscottblake Oh wow this is great! I'm learning so much from looking these over. Thanks!

Not applicable

@mscottblake amazing work and thanks for the github. I've myself created one where I store my creations. I use your custom schema for NoMAD and it helps a lot !
I've created one for the notifications : link

mscottblake
Valued Contributor

@bp.studer I invited you to the team so you can include your stuff in the central repo. If anyone else wants the same, let me know and I can get you an invite.

a_hebert
New Contributor III

@mscottblake I have one for blacklist/whitelist extensions in Chrome. https://github.com/Ahebrt76/Jamf-Schemas-

lawinski
New Contributor III

Hey there I created a schema for Munki (here).
Feel free to upload and expand it. I haven't pushed it to git yet.

EDIT: Somebody already has a better one.

seanism
New Contributor III

Anyone create any schema's for Google Chrome?

mscottblake
Valued Contributor

@seanism I have not and do not plan to do so. Since Chrome is developed by a corporation, it is my hope that they will embrace the technology. My focus is on open source software.

slashnext
New Contributor II

how we can read this custom schema in our machine once it is deployed successfully?

mm2270
Legendary Contributor III

@slashnext The custom schema itself doesn't get deployed to any machines. It gets imported into Jamf Pro to create a GUI for you to use to set settings that get deployed to your machines. The settings themselves are no different in the end than any other configuration profile plist.

jorge_
New Contributor III

@mm2270 I was able to upload this into a configuration profile for testing. Would you mind sharing how I can blacklist all extensions by default, then whitelist a only a select few with firefox? I am able to do something similar with chrome, but still trying to figure out firefox.

a_hebert
New Contributor III

@jorge.blandon Here is a link to a Git where many jsons are for different programs
https://github.com/Jamf-Custom-Profile-Schemas

HNTIT
Contributor II

Has Anyone Created a Chrome one yet

sam_clark
New Contributor III

Great thread. I wanted to post a default for those not familiar with JSON. You can copy/paste after finding out which value types and values you need for your custom domain settings. I found this especially easy using ProfileCreator and looking at the raw XML values then converting it to JSON.

This should save time exporting and creating new profiles with ProfileCreator while still using ProfileCreator as the reference for some application specific custom settings - ie use that GUI to find the settings you want then port it to a JSON schema so you can keep it up-to-date in Jamf Pro.

{

        "$schema": "http://json-schema.org/schema#",

    "type": "object",
    "properties": {

        "keyNameString": {
            "type": "string",
            "title": "This String",
            "description": "Enter the string value",
            "default": "myString"
        },

        "keyNameNumber": {
            "type": "number",
            "title": "This Number",
            "description": "This number is an array of choices. The default is 0",
            "default": 0,
            "enum": [0, 1, 2, 3, 4]
        },

        "keyNameBoolean": {
            "type": "boolean",
            "title": "This Boolean",
            "description": "This boolean is true or false. The default is false.",
            "default": "false"

        }

    }

}

EDIT: Larger template here - https://github.com/j-samuel-clark/jamf-scripts/blob/master/jsonSchemaTemplate.json

jbisgett
Contributor II

I see there is one for NoMAD, but what about NoMAD Login?

mscottblake
Valued Contributor

@jbisgett I've been meaning to work toward creating one, but I haven't had a lot of time lately. Check back once in a while and there will be one eventually.

djrory
Contributor

I'm still having a little trouble with this. I am trying to enable the "Turn on new meeting experience" checkbox in the Teams settings. I cannot simply replace the file because it contains other important user settings.
I've found the file and the key.

/Users/r[USER]/Library/Application Support/Microsoft/Teams/desktop-config.json

and

{"appPreferenceSettings":{"callingMWEnabledPreferenceKey":true}

but I am having trouble making it work.

I tried using the tool found here to no avail. I built the following schema, uploaded it to the custom settings payload then deployed to a test device but it had no effect.
914ed311979e467abd6d3e07389cedf3

Am I approaching this the wrong way? Can someone point me in the right direction?
230359a579dc4790bc58b6273bc21c10

556c970bf0394beebb8b99416fce8302

djrory
Contributor

Would it be simpler to just edit the JSON with a script to change the value to TRUE?

prbsparx
Contributor II

Maybe a group of us can work on developing a script that can be added to Xcode/build tools to generate a basic JSON Schema for all the preferences available in source code. I assume there's a way to scan the source code for defaults.

mm2270
Legendary Contributor III

@djrory The problem, I think, is that you're using a custom application schema to (try to) update the settings in a json file, which isn't what this is used for. What the custom schemas ultimately do is give you a simple GUI interface for configuring and sending out Configuration Profiles, which are just xml/plist files. IOW, I don't believe a Config Profile can affect a json file on the local machine. You'll probably have to directly manipulate the json file settings and see if it works to apply the change. If it does, there's likely a way it can be scripted.

Either that, or keep digging and investigating to see if there's an actual plist setting and value that stores that same item. If you find one, then using a Custom Application Schema would make sense.

jfraniuk
New Contributor

Hello, I have the following Schema setup where I want to bock all Chrome Extensions except the ones our School has approved. I attached a picture of what we have for a Schema.
3feb5145841d4a3c97edb8a406203157

Then in Properties I have the extension ID set to under Add/Remove key hoping to block them all and then I am adding the Extension ID of the ones we want to allow. However it is not working when I test with a test account on a laptop and I have it scoped to the test account and the laptop being used. Even just for testing the I took the one Key I had with the out and then just left the one extension ID I wanted to allow in there, but set to block and was still able to add it. I was hoping to block Chrome extensions this way instead of using a plist as we have done that before and it works. Any advice would be great. Hope I posted this in the right area.

Santosh
New Contributor III

Great thread.Do we have a similar JSON file for Microsoft Office/Office 365 aswell ?

sdagley
Esteemed Contributor II

@Santosh There are already built-in configurations for Microsoft in the Application & Custom Settings editor. Select Source->Jamf Repository and then the Preference Domain popup will list several com.microsoft domains to choose from.

Santosh
New Contributor III

@sdagley correct.
c83b25e565b2475aa149392fabfa6609
that's what i understood for the JAMF Documentation. We are using JAMF PRO 10.19 Under Application & Custom Settings editor,when i Select Source as Jamf Repository i dont see any Preference domain as popup