Generate Apple mobileconfig configuration profiles
Project description
pymobileconfig
Generate Apple mobileconfig configuration profiles from Python.
Installation
pip install pymobileconfig
Quick Start
from pathlib import Path
from pymobileconfig import Profile, TrustedCertificate, SCEP, ManagedAppConfig
profile = (
Profile(display_name="MDM Device Certificates", organisation="Acme Corp")
.add(TrustedCertificate(
display_name="Acme Root CA",
certificate=Path("root_ca.crt"), # PEM path, PEM bytes, or DER bytes
))
.add(SCEP(
display_name="Backend Certificate",
url="https://ca.acme.com:9000/scep/scep",
challenge="your-scep-challenge",
subject=[("CN", "MY-DEVICE-001"), ("OU", "backend"), ("O", "Acme Corp")],
keychain_access_groups=["$(AppIdentifierPrefix)com.acme.deviceclient"],
))
.add(ManagedAppConfig(
display_name="App Configuration",
config={"api_base_url": "https://api.acme.com:8443"},
))
)
profile.write("device-enrollment.mobileconfig")
Payloads
TrustedCertificate
Installs a trusted root or intermediate CA certificate.
| Parameter | Type | Description |
|---|---|---|
display_name |
str |
Label shown in Settings |
certificate |
bytes | Path |
PEM or DER bytes, or path to a PEM file |
SCEP
SCEP certificate enrolment — used for Intune-managed device certificates.
| Parameter | Type | Default | Description |
|---|---|---|---|
display_name |
str |
— | Label shown in Settings |
url |
str |
— | SCEP endpoint URL |
challenge |
str |
— | SCEP challenge password |
subject |
list |
— | X.509 subject as [("CN", "..."), ("OU", "...")] |
name |
str |
"scep" |
SCEP CA identifier |
key_type |
str |
"RSA" |
Key algorithm |
key_size |
int |
2048 |
Key size in bits |
key_usage |
int |
5 |
Key usage bitmask (1=signing, 4=encipherment) |
retries |
int |
3 |
Enrolment retry count |
retry_delay |
int |
10 |
Seconds between retries |
keychain_access_groups |
list[str] |
[] |
Keychain access groups for the enrolled cert |
PKCS12
Installs a PKCS#12 certificate and private key bundle into the device keychain.
Appropriate for delivering shared server certificates where the same key is
intentionally distributed to multiple devices (e.g. a device server cert
shared across a fleet). For per-device identity certificates, use SCEP instead
— the private key never leaves the device's Secure Enclave.
| Parameter | Type | Default | Description |
|---|---|---|---|
display_name |
str |
— | Label shown in Settings |
pkcs12 |
bytes | Path |
— | Raw .p12 / .pfx bytes, or path to file |
password |
str |
"" |
Passphrase for the PKCS#12 bundle |
ManagedAppConfig
Delivers key-value configuration to an app via
UserDefaults(suiteName: "com.apple.configuration.managed").
Supports standard plist types: str, int, float, bool, list, dict, bytes.
Do not store secrets here — values are readable in plaintext by the app.
| Parameter | Type | Description |
|---|---|---|
display_name |
str |
Payload label |
config |
dict |
Key-value pairs to deliver to the app |
Profile
| Parameter | Type | Default | Description |
|---|---|---|---|
display_name |
str |
— | Profile name shown in Settings |
organisation |
str |
— | Organisation name |
description |
str |
"" |
Optional description |
identifier |
str |
auto | Reverse-DNS identifier (auto-generated if omitted) |
removal_disallowed |
bool |
False |
Prevent user removal |
Methods
profile.add(payload)— add a payload, returnsselffor chainingprofile.dumps()— serialise to XML plistbytesprofile.write(path)— write mobileconfig to a file
Production Deployment via Intune
For production, standard payload types (trusted cert, SCEP) are configured directly in Intune without needing a mobileconfig file:
- Trusted certificate: Devices → Configuration → iOS/iPadOS → Trusted certificate
- SCEP profile: Devices → Configuration → iOS/iPadOS → SCEP certificate
- App configuration: Apps → App configuration policies → Managed devices
pymobileconfig is most useful for development testing (serving a profile
over HTTP for manual install) and for non-standard payload types that Intune
has no built-in UI for.
Reading Managed App Config in Swift
let defaults = UserDefaults(suiteName: "com.apple.configuration.managed")
let apiURL = defaults?.string(forKey: "api_base_url") ?? "https://fallback.example.com"
Development
git clone https://github.com/ZippyManaic/pymobileconfig
cd pymobileconfig
pip install -e ".[dev]"
pytest
Licence
MIT
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pymobileconfig-0.3.1.tar.gz.
File metadata
- Download URL: pymobileconfig-0.3.1.tar.gz
- Upload date:
- Size: 11.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
15b1cd1d86df4c3d5dc4cde7fa0ec735f946c1213088529b64aab1ee70d5a980
|
|
| MD5 |
965573c6d02cb47b749256e15071738c
|
|
| BLAKE2b-256 |
1ad8119d21a0fa942d7b2b7dc77159e17030c7e9d41ac88800218708555f5fad
|
Provenance
The following attestation bundles were made for pymobileconfig-0.3.1.tar.gz:
Publisher:
publish.yml on ZippyManaic/pymobileconfig
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pymobileconfig-0.3.1.tar.gz -
Subject digest:
15b1cd1d86df4c3d5dc4cde7fa0ec735f946c1213088529b64aab1ee70d5a980 - Sigstore transparency entry: 1091406400
- Sigstore integration time:
-
Permalink:
ZippyManaic/pymobileconfig@64382f9f97c04f57926d361b507a92f17659089a -
Branch / Tag:
refs/tags/v0.3.1 - Owner: https://github.com/ZippyManaic
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@64382f9f97c04f57926d361b507a92f17659089a -
Trigger Event:
push
-
Statement type:
File details
Details for the file pymobileconfig-0.3.1-py3-none-any.whl.
File metadata
- Download URL: pymobileconfig-0.3.1-py3-none-any.whl
- Upload date:
- Size: 10.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f824e1bec3e704d18dae8bb1f1dd295dd0bbc49d5efa2577d2b85ed9ce33c202
|
|
| MD5 |
5530bc73ca11953cceeb0d871c8e95b7
|
|
| BLAKE2b-256 |
67228b62ffc90b831db77d8fec045cf7d38b312dc194f1421c3b97620e8f1966
|
Provenance
The following attestation bundles were made for pymobileconfig-0.3.1-py3-none-any.whl:
Publisher:
publish.yml on ZippyManaic/pymobileconfig
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pymobileconfig-0.3.1-py3-none-any.whl -
Subject digest:
f824e1bec3e704d18dae8bb1f1dd295dd0bbc49d5efa2577d2b85ed9ce33c202 - Sigstore transparency entry: 1091406410
- Sigstore integration time:
-
Permalink:
ZippyManaic/pymobileconfig@64382f9f97c04f57926d361b507a92f17659089a -
Branch / Tag:
refs/tags/v0.3.1 - Owner: https://github.com/ZippyManaic
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@64382f9f97c04f57926d361b507a92f17659089a -
Trigger Event:
push
-
Statement type: