Initial commit

This commit is contained in:
2026-04-20 09:09:50 -07:00
commit 585871e874
15 changed files with 1252 additions and 0 deletions
+94
View File
@@ -0,0 +1,94 @@
# vesperprofiled-config-schema
Schema definitions package for VesperOS configuration profiles.
Installed at `/usr/share/vesperprofiled/schema/profile.schema.yml`.
---
## What this package does
`vesperprofiled` reads this schema at startup to determine which payload types and fields are valid for the current installation. Any `.vconfig` profile containing a payload type not listed in `allowed-payload-types` will be **rejected at install time** with a clear error.
Shipping the schema separately from the daemon means:
- **Independent updates** — schema additions (new payload types, new optional fields) don't require rebuilding or reflashing the daemon binary.
- **OEM restriction** — OEMs building VesperOS-based products can ship a trimmed schema that only exposes the configuration surface their platform supports. A digital signage OEM might allow only `wifi`, `cert`, `kiosk`, and `mdm`. An enterprise desktop OEM might allow everything except `kiosk` and `asam`.
- **Schema versioning** — the `schema-version` field is checked by the daemon at startup. A newer daemon with an older schema is always fine. An older daemon with a newer schema logs a warning and falls back to its compiled-in defaults.
---
## OEM customisation
To restrict available payload types, create a replacement Debian package:
**1. Copy and trim the schema**
```bash
cp /usr/share/vesperprofiled/schema/profile.schema.yml \
my-schema/profile.schema.yml
# Edit my-schema/profile.schema.yml:
# - Remove payload type entries from allowed-payload-types
# - Remove their blocks from the payloads: section
# - Bump schema-version if you consider this a new schema variant
```
**2. Create your package**
`debian/control`:
```
Package: my-vesperos-config-schema
Architecture: all
Depends: ${misc:Depends}
Provides: vesperprofiled-config-schema
Conflicts: vesperprofiled-config-schema
Replaces: vesperprofiled-config-schema
Description: Trimmed VesperOS profile schema for My Product
Only allows: wifi, cert, mdm, kiosk, passcode, restrictions.
```
`debian/rules`:
```makefile
#!/usr/bin/make -f
%:
dh $@
override_dh_auto_install:
install -Dm 0644 profile.schema.yml \
debian/my-vesperos-config-schema/usr/share/vesperprofiled/schema/profile.schema.yml
```
**3. Add to your product package list**
```makefile
# In your VesperOS device makefile or product.mk:
PRODUCT_PACKAGES += my-vesperos-config-schema
```
Because your package `Provides: vesperprofiled-config-schema` and `Conflicts: vesperprofiled-config-schema`, `apt` will automatically use yours in place of the default when both are available.
---
## Schema versioning
The `schema-version` field in the YAML file follows `MAJOR.MINOR.PATCH`:
- **PATCH** — non-breaking: new optional fields added to existing payload types.
- **MINOR** — new payload types added to `allowed-payload-types`. Older daemons that don't know the new type will accept profiles containing it but log a warning and skip the unknown payload.
- **MAJOR** — breaking: required fields renamed, payload types removed, or semantics changed. Daemons older than this MAJOR version must not run with a schema of a higher MAJOR version.
---
## Building the package
```bash
dpkg-buildpackage -us -uc -b -A # Architecture: all, no signing
```
---
## Files installed
```
/usr/share/vesperprofiled/schema/profile.schema.yml
```
@@ -0,0 +1,8 @@
vesperprofiled-config-schema (1.0.0-1) trixie; urgency=medium
* Initial release. Schema version 1.0.0.
* All 55 payload types defined with required/optional field lists.
* Signing requirements, singleton constraints, and allowed-payload-types
list all configurable by OEMs via a replacement package.
-- oxmc <packages@oxmc.me> Sun, 19 Apr 2026 00:00:00 +0000
+8
View File
@@ -0,0 +1,8 @@
vesperprofiled-config-schema (1.0.0-1) trixie; urgency=medium
* Initial release. Schema version 1.0.0.
* All 55 payload types defined with required/optional field lists.
* Signing requirements, singleton constraints, and allowed-payload-types
list all configurable by OEMs via a replacement package.
-- oxmc <packages@oxmc.me> Sun, 19 Apr 2026 00:00:00 +0000
+29
View File
@@ -0,0 +1,29 @@
Source: vesperprofiled-config-schema
Section: admin
Priority: optional
Maintainer: oxmc <packages@oxmc.me>
Build-Depends: debhelper-compat (= 13)
Standards-Version: 4.7.0
Homepage: https://vesperos.oxmc.me
Vcs-Git: https://git.oxmc.me/vesperos/vesperprofiled-config-schema.git
Package: vesperprofiled-config-schema
Architecture: all
Depends: ${misc:Depends}
Breaks: vesperprofiled (<< 1.0.0)
Description: VesperOS configuration profile schema definitions
Provides the YAML schema file that defines which .vconfig payload types
and fields are valid on this VesperOS installation. vesperprofiled reads
this schema at startup and rejects profiles containing payload types not
listed in it.
.
Shipping the schema as a separate package allows:
- Independent schema updates without rebuilding the daemon binary.
- OEM customisation: replace this package with a trimmed version that
only lists the payload types your platform supports.
- Schema versioning: the daemon checks schema-version compatibility
at startup and refuses to run with an incompatible schema.
.
OEMs: create your own package that Provides: vesperprofiled-config-schema
and contains a customised profile.schema.yml with only the payload types
your build supports.
+1
View File
@@ -0,0 +1 @@
vesperprofiled-config-schema
+2
View File
@@ -0,0 +1,2 @@
vesperprofiled-config-schema_1.0.0-1_all.deb admin optional
vesperprofiled-config-schema_1.0.0-1_amd64.buildinfo admin optional
Vendored Executable
+10
View File
@@ -0,0 +1,10 @@
#!/usr/bin/make -f
%:
dh $@
override_dh_auto_build:
# Architecture: all — nothing to compile
override_dh_auto_install:
install -Dm 0644 schema/profile.schema.yml \
debian/vesperprofiled-config-schema/usr/share/vesperprofiled/schema/profile.schema.yml
+1
View File
@@ -0,0 +1 @@
3.0 (native)
+2
View File
@@ -0,0 +1,2 @@
misc:Depends=
misc:Pre-Depends=
+25
View File
@@ -0,0 +1,25 @@
Package: vesperprofiled-config-schema
Version: 1.0.0-1
Architecture: all
Maintainer: oxmc <packages@oxmc.me>
Installed-Size: 28
Breaks: vesperprofiled (<< 1.0.0)
Section: admin
Priority: optional
Homepage: https://vesperos.oxmc.me
Description: VesperOS configuration profile schema definitions
Provides the YAML schema file that defines which .vconfig payload types
and fields are valid on this VesperOS installation. vesperprofiled reads
this schema at startup and rejects profiles containing payload types not
listed in it.
.
Shipping the schema as a separate package allows:
- Independent schema updates without rebuilding the daemon binary.
- OEM customisation: replace this package with a trimmed version that
only lists the payload types your platform supports.
- Schema versioning: the daemon checks schema-version compatibility
at startup and refuses to run with an incompatible schema.
.
OEMs: create your own package that Provides: vesperprofiled-config-schema
and contains a customised profile.schema.yml with only the payload types
your build supports.
+2
View File
@@ -0,0 +1,2 @@
322df8776e639e12f6265a6e6232b229 usr/share/doc/vesperprofiled-config-schema/changelog.Debian.gz
82842e0a3dce5dec15cc6e954cb23ba5 usr/share/vesperprofiled/schema/profile.schema.yml
@@ -0,0 +1,535 @@
# =============================================================================
# VesperOS Configuration Profile Schema
# Package : vesperprofiled-config-schema
# Version : 1.0.0
# Installed at: /usr/share/vesperprofiled/schema/profile.schema.yml
#
# vesperprofiled reads this file at startup to determine which payload
# types and fields are valid for this installation. OEMs may ship a
# trimmed version of this schema to restrict which payloads their build
# supports — only payload types listed here will be accepted.
#
# Schema versioning:
# schema-version — incremented when fields are added or removed.
# vesperprofiled checks that its own compiled-in schema-version matches
# or is compatible with the installed schema package version.
# Compatibility rule: daemon >= schema version (newer daemon, older schema ok).
#
# OEM customisation:
# To restrict available payload types, create a trimmed copy of this file
# and ship it as your own vesperprofiled-config-schema package with a
# custom Provides: field. Remove entire payload blocks for unsupported types.
# The daemon will reject any profile containing an unlisted payload type.
# =============================================================================
schema-version: "1.0.0"
# ---------------------------------------------------------------------------
# Allowed payload types for this schema version.
# Remove entries to restrict what profiles may contain on this platform.
# ---------------------------------------------------------------------------
allowed-payload-types:
- mdm
- scep
- pkcs12
- cert
- cert-preference
- cert-transparency
- wifi
- ethernet
- vpn
- vpn-per-app
- email
- exchange
- caldav
- calendar-subscription
- carddav
- ldap
- passcode
- restrictions
- kiosk
- asam
- proxy-http
- dns-proxy
- domains
- network-usage-rules
- cellular
- web-filter
- web-clip
- font
- notifications
- sso
- active-directory
- ad-certificate
- time-server
- software-update
- firewall
- privacy
- parental-controls
- removal-password
- identification
- google-account
- home-screen
- desktop
- screensaver
- global-preferences
- shared-device
- education
- airprint
- airplay
- airplay-security
- system-policy
- system-policy-rule
- smartcard
- kernel-extension-policy
- media-management
- full-disk-encryption
- fde-escrow
- first-boot
- setup-assistant # alias for first-boot; always include alongside first-boot
# ---------------------------------------------------------------------------
# Signing requirements by payload type.
# Payloads listed here REQUIRE a signed (CMS/PKCS#7) profile envelope.
# Unsigned profiles containing any of these types will be rejected.
# ---------------------------------------------------------------------------
signing-required:
- mdm
- removal-password
- kiosk
- asam
# ---------------------------------------------------------------------------
# Singleton payload types.
# Only one instance of each of these is permitted per profile.
# ---------------------------------------------------------------------------
singletons:
- mdm
- passcode
- restrictions
- kiosk
- asam
- proxy-http
- web-filter
- global-preferences
- shared-device
- parental-controls
- removal-password
- identification
- home-screen
- airplay-security
- system-policy
- first-boot
- setup-assistant
# ---------------------------------------------------------------------------
# Payload field definitions.
# Each entry documents the fields for one payload type.
# The daemon uses this for validation — unknown fields in a profile
# are logged as warnings but do not block installation.
# Required fields that are missing will block installation.
# ---------------------------------------------------------------------------
payloads:
# ── Top-level profile fields ─────────────────────────────────────────────
profile:
required: [id, uuid, version]
optional:
version: { type: integer, value: 1 }
id: { type: string, pattern: "reverse-dns" }
uuid: { type: string, pattern: "uuid-v4" }
scope: { type: enum, values: [system, user], default: user }
meta: { type: object }
lifecycle: { type: object }
consent: { type: object }
lifecycle:
optional:
removal: { type: enum, values: [free, locked, password], default: free }
expires-at: { type: string, pattern: "iso8601" }
expires-after: { type: integer, description: "Seconds from install" }
ota-refresh-after: { type: string, pattern: "iso8601" }
# ── MDM ──────────────────────────────────────────────────────────────────
mdm:
required: [server-url, identity-cert-uuid, access-rights, push-topic]
optional:
checkin-url: { type: string }
sign-messages: { type: boolean, default: false }
checkout-on-removal: { type: boolean, default: false }
use-development-push: { type: boolean, default: false }
capabilities: { type: array }
# ── SCEP ─────────────────────────────────────────────────────────────────
scep:
required: [url, challenge]
optional:
instance-name: { type: string }
subject: { type: array }
key: { type: object }
san: { type: object }
ca-fingerprint: { type: string, encoding: base64 }
retries: { type: integer, default: 3 }
retry-delay-seconds: { type: integer, default: 10 }
# ── Certificates ─────────────────────────────────────────────────────────
pkcs12:
required: [data]
optional:
password: { type: string }
all-apps-access: { type: boolean, default: false }
cert:
required: [data]
cert-preference:
required: [name, cert-uuid]
# ── Wi-Fi ────────────────────────────────────────────────────────────────
wifi:
required: [ssid]
optional:
hidden: { type: boolean, default: false }
auto-join: { type: boolean, default: true }
security: { type: object }
mac-address-mode: { type: enum, values: [hardware, random], default: hardware }
hotspot: { type: object }
proxy: { type: object }
eap: { type: object }
qos-marking: { type: object }
# ── Ethernet ─────────────────────────────────────────────────────────────
ethernet:
optional:
interface: { type: string, default: first-active }
eap: { type: object }
# ── VPN ──────────────────────────────────────────────────────────────────
vpn:
optional:
display-name: { type: string }
full-tunnel: { type: boolean, default: false }
on-demand: { type: object }
ikev2: { type: object }
l2tp: { type: object }
custom: { type: object }
vpn-per-app:
required: [vpn-uuid]
optional:
app-mappings: { type: array }
browser-domains: { type: array }
# ── Mail accounts ─────────────────────────────────────────────────────────
email:
required: [account, incoming, outgoing]
optional:
smime: { type: object }
restrictions: { type: object }
exchange:
required: [server, account]
optional:
sync: { type: object }
smime: { type: object }
restrictions: { type: object }
caldav:
required: [host, username]
optional:
description: { type: string }
port: { type: integer }
ssl: { type: boolean, default: true }
principal-url: { type: string }
password: { type: string }
use-oauth: { type: boolean, default: false }
calendar-subscription:
required: [url]
optional:
description: { type: string }
username: { type: string }
password: { type: string }
ssl: { type: boolean, default: true }
carddav:
required: [host, username]
optional:
description: { type: string }
port: { type: integer }
ssl: { type: boolean, default: true }
principal-url: { type: string }
password: { type: string }
use-oauth: { type: boolean, default: false }
# ── Directory ─────────────────────────────────────────────────────────────
ldap:
required: [host]
optional:
description: { type: string }
ssl: { type: boolean, default: true }
username: { type: string }
password: { type: string }
search-settings: { type: array }
# ── Security policies ─────────────────────────────────────────────────────
passcode:
optional:
require: { type: boolean, default: true }
allow-simple: { type: boolean, default: true }
require-alphanumeric: { type: boolean, default: false }
min-length: { type: integer, default: 6 }
min-complex-chars: { type: integer, default: 0 }
expiry: { type: object }
lockout: { type: object }
force-change-at-next-login: { type: boolean, default: false }
custom-regex: { type: object }
restrictions:
optional:
apps: { type: object }
hardware: { type: object }
network: { type: object }
cloud: { type: object }
browser: { type: object }
content-ratings: { type: object }
sharing: { type: object }
open-in: { type: object }
user: { type: object }
input: { type: object }
kiosk:
required: [app]
optional:
hardware: { type: object }
accessibility:{ type: object }
asam:
required: [allowed-apps]
removal-password:
required: [password]
# ── Network ───────────────────────────────────────────────────────────────
proxy-http:
required: [proxy]
dns-proxy:
required: [app-bundle-id]
optional:
extension-bundle-id: { type: string }
config: { type: object }
domains:
optional:
email-domains: { type: array }
web-domains: { type: array }
tracking-relaxed-domains: { type: array }
network-usage-rules:
required: [rules]
cellular:
optional:
attach-apn: { type: object }
apns: { type: array }
# ── Content filtering ─────────────────────────────────────────────────────
web-filter:
required: [mode]
optional:
built-in: { type: object }
plugin: { type: object }
# ── UI shortcuts ──────────────────────────────────────────────────────────
web-clip:
required: [label, url]
optional:
removable: { type: boolean, default: true }
full-screen: { type: boolean, default: false }
icon: { type: string, encoding: base64 }
target-app: { type: string }
font:
required: [font-name, data]
# ── Device experience ─────────────────────────────────────────────────────
notifications:
required: [apps]
sso:
optional:
display-name: { type: string }
kerberos: { type: object }
identification:
optional:
full-name: { type: string }
email: { type: string }
username: { type: string }
password: { type: string }
prompt: { type: string }
google-account:
required: [address]
optional:
description: { type: string }
display-name: { type: string }
services: { type: object }
home-screen:
optional:
dock: { type: array }
pages: { type: array }
desktop:
optional:
wallpaper: { type: object }
screensaver:
optional:
module: { type: string }
idle-seconds: { type: integer, default: 300 }
locked: { type: boolean, default: false }
# ── Enterprise / desktop ──────────────────────────────────────────────────
active-directory:
required: [server]
optional:
admin-username: { type: string }
admin-password: { type: string }
computer-name: { type: string }
organizational-unit: { type: string }
user-experience: { type: object }
password-policy: { type: object }
mobile-accounts: { type: object }
local-admin-groups: { type: array }
uid-mapping: { type: string }
gid-mapping: { type: string }
trust-change-interval-days: { type: integer }
restrict-ddns-interfaces: { type: array }
allow-multi-domain-auth: { type: boolean }
ad-certificate:
required: [server, template, authority]
optional:
acquisition: { type: enum, values: [rpc, http], default: rpc }
description: { type: string }
key: { type: object }
renewal: { type: object }
prompt-for-credentials: { type: boolean, default: false }
cert-transparency:
optional:
disabled: { type: object }
required: { type: object }
time-server:
required: [server]
software-update:
optional:
catalog-url: { type: string }
automatic: { type: object }
deferral: { type: object }
allow-pre-release: { type: boolean, default: false }
require-admin-to-install: { type: boolean, default: false }
firewall:
optional:
enabled: { type: boolean, default: false }
block-all-incoming: { type: boolean, default: false }
stealth-mode: { type: boolean, default: false }
apps: { type: array }
privacy:
required: [services]
parental-controls:
optional:
apps: { type: object }
web: { type: object }
time-limits: { type: object }
content: { type: object }
global-preferences:
optional:
multi-session-enabled: { type: boolean, default: false }
shared-device:
optional:
enabled: { type: boolean, default: true }
temporary-session: { type: object }
user-session: { type: object }
quota-mb: { type: integer }
education:
required: [organization]
optional:
resource-cert-uuid: { type: string }
device-groups: { type: array }
users: { type: array }
departments: { type: array }
# ── AirPlay / AirPrint ────────────────────────────────────────────────────
airprint:
required: [printers]
airplay:
optional:
allowlist: { type: array }
passwords: { type: array }
airplay-security:
required: [security, access]
optional:
password: { type: string }
# ── macOS / desktop system policy ─────────────────────────────────────────
system-policy:
optional:
gatekeeper-enabled: { type: boolean, default: true }
allow-identified-developers: { type: boolean, default: true }
system-policy-rule:
required: [rules]
smartcard:
optional:
on-token-removal: { type: enum, values: [none, lock, logout], default: none }
cert-trust: { type: enum, values: [off, basic, ocsp, hard], default: off }
enabled: { type: boolean, default: true }
enforce: { type: boolean, default: false }
user-pairing: { type: boolean, default: true }
one-card-per-user: { type: boolean, default: false }
allow-unmapped-users: { type: boolean, default: true }
kernel-extension-policy:
optional:
allow-user-approvals: { type: boolean, default: false }
allowed-extensions: { type: array }
media-management:
required: [media]
full-disk-encryption:
optional:
state: { type: enum, values: [on, off], default: off }
defer: { type: object }
recovery-key:{ type: object }
escrow-cert: { type: string, encoding: base64 }
cert-uuid: { type: string }
fde-escrow:
required: [location, encrypt-cert-uuid]
optional:
device-key: { type: string, default: serial-number }
# ── First boot ────────────────────────────────────────────────────────────
first-boot:
optional:
skip: { type: array, description: "Pane names to skip on first boot" }
setup-assistant:
optional:
skip: { type: array, description: "Alias for first-boot — same fields" }
+535
View File
@@ -0,0 +1,535 @@
# =============================================================================
# VesperOS Configuration Profile Schema
# Package : vesperprofiled-config-schema
# Version : 1.0.0
# Installed at: /usr/share/vesperprofiled/schema/profile.schema.yml
#
# vesperprofiled reads this file at startup to determine which payload
# types and fields are valid for this installation. OEMs may ship a
# trimmed version of this schema to restrict which payloads their build
# supports — only payload types listed here will be accepted.
#
# Schema versioning:
# schema-version — incremented when fields are added or removed.
# vesperprofiled checks that its own compiled-in schema-version matches
# or is compatible with the installed schema package version.
# Compatibility rule: daemon >= schema version (newer daemon, older schema ok).
#
# OEM customisation:
# To restrict available payload types, create a trimmed copy of this file
# and ship it as your own vesperprofiled-config-schema package with a
# custom Provides: field. Remove entire payload blocks for unsupported types.
# The daemon will reject any profile containing an unlisted payload type.
# =============================================================================
schema-version: "1.0.0"
# ---------------------------------------------------------------------------
# Allowed payload types for this schema version.
# Remove entries to restrict what profiles may contain on this platform.
# ---------------------------------------------------------------------------
allowed-payload-types:
- mdm
- scep
- pkcs12
- cert
- cert-preference
- cert-transparency
- wifi
- ethernet
- vpn
- vpn-per-app
- email
- exchange
- caldav
- calendar-subscription
- carddav
- ldap
- passcode
- restrictions
- kiosk
- asam
- proxy-http
- dns-proxy
- domains
- network-usage-rules
- cellular
- web-filter
- web-clip
- font
- notifications
- sso
- active-directory
- ad-certificate
- time-server
- software-update
- firewall
- privacy
- parental-controls
- removal-password
- identification
- google-account
- home-screen
- desktop
- screensaver
- global-preferences
- shared-device
- education
- airprint
- airplay
- airplay-security
- system-policy
- system-policy-rule
- smartcard
- kernel-extension-policy
- media-management
- full-disk-encryption
- fde-escrow
- first-boot
- setup-assistant # alias for first-boot; always include alongside first-boot
# ---------------------------------------------------------------------------
# Signing requirements by payload type.
# Payloads listed here REQUIRE a signed (CMS/PKCS#7) profile envelope.
# Unsigned profiles containing any of these types will be rejected.
# ---------------------------------------------------------------------------
signing-required:
- mdm
- removal-password
- kiosk
- asam
# ---------------------------------------------------------------------------
# Singleton payload types.
# Only one instance of each of these is permitted per profile.
# ---------------------------------------------------------------------------
singletons:
- mdm
- passcode
- restrictions
- kiosk
- asam
- proxy-http
- web-filter
- global-preferences
- shared-device
- parental-controls
- removal-password
- identification
- home-screen
- airplay-security
- system-policy
- first-boot
- setup-assistant
# ---------------------------------------------------------------------------
# Payload field definitions.
# Each entry documents the fields for one payload type.
# The daemon uses this for validation — unknown fields in a profile
# are logged as warnings but do not block installation.
# Required fields that are missing will block installation.
# ---------------------------------------------------------------------------
payloads:
# ── Top-level profile fields ─────────────────────────────────────────────
profile:
required: [id, uuid, version]
optional:
version: { type: integer, value: 1 }
id: { type: string, pattern: "reverse-dns" }
uuid: { type: string, pattern: "uuid-v4" }
scope: { type: enum, values: [system, user], default: user }
meta: { type: object }
lifecycle: { type: object }
consent: { type: object }
lifecycle:
optional:
removal: { type: enum, values: [free, locked, password], default: free }
expires-at: { type: string, pattern: "iso8601" }
expires-after: { type: integer, description: "Seconds from install" }
ota-refresh-after: { type: string, pattern: "iso8601" }
# ── MDM ──────────────────────────────────────────────────────────────────
mdm:
required: [server-url, identity-cert-uuid, access-rights, push-topic]
optional:
checkin-url: { type: string }
sign-messages: { type: boolean, default: false }
checkout-on-removal: { type: boolean, default: false }
use-development-push: { type: boolean, default: false }
capabilities: { type: array }
# ── SCEP ─────────────────────────────────────────────────────────────────
scep:
required: [url, challenge]
optional:
instance-name: { type: string }
subject: { type: array }
key: { type: object }
san: { type: object }
ca-fingerprint: { type: string, encoding: base64 }
retries: { type: integer, default: 3 }
retry-delay-seconds: { type: integer, default: 10 }
# ── Certificates ─────────────────────────────────────────────────────────
pkcs12:
required: [data]
optional:
password: { type: string }
all-apps-access: { type: boolean, default: false }
cert:
required: [data]
cert-preference:
required: [name, cert-uuid]
# ── Wi-Fi ────────────────────────────────────────────────────────────────
wifi:
required: [ssid]
optional:
hidden: { type: boolean, default: false }
auto-join: { type: boolean, default: true }
security: { type: object }
mac-address-mode: { type: enum, values: [hardware, random], default: hardware }
hotspot: { type: object }
proxy: { type: object }
eap: { type: object }
qos-marking: { type: object }
# ── Ethernet ─────────────────────────────────────────────────────────────
ethernet:
optional:
interface: { type: string, default: first-active }
eap: { type: object }
# ── VPN ──────────────────────────────────────────────────────────────────
vpn:
optional:
display-name: { type: string }
full-tunnel: { type: boolean, default: false }
on-demand: { type: object }
ikev2: { type: object }
l2tp: { type: object }
custom: { type: object }
vpn-per-app:
required: [vpn-uuid]
optional:
app-mappings: { type: array }
browser-domains: { type: array }
# ── Mail accounts ─────────────────────────────────────────────────────────
email:
required: [account, incoming, outgoing]
optional:
smime: { type: object }
restrictions: { type: object }
exchange:
required: [server, account]
optional:
sync: { type: object }
smime: { type: object }
restrictions: { type: object }
caldav:
required: [host, username]
optional:
description: { type: string }
port: { type: integer }
ssl: { type: boolean, default: true }
principal-url: { type: string }
password: { type: string }
use-oauth: { type: boolean, default: false }
calendar-subscription:
required: [url]
optional:
description: { type: string }
username: { type: string }
password: { type: string }
ssl: { type: boolean, default: true }
carddav:
required: [host, username]
optional:
description: { type: string }
port: { type: integer }
ssl: { type: boolean, default: true }
principal-url: { type: string }
password: { type: string }
use-oauth: { type: boolean, default: false }
# ── Directory ─────────────────────────────────────────────────────────────
ldap:
required: [host]
optional:
description: { type: string }
ssl: { type: boolean, default: true }
username: { type: string }
password: { type: string }
search-settings: { type: array }
# ── Security policies ─────────────────────────────────────────────────────
passcode:
optional:
require: { type: boolean, default: true }
allow-simple: { type: boolean, default: true }
require-alphanumeric: { type: boolean, default: false }
min-length: { type: integer, default: 6 }
min-complex-chars: { type: integer, default: 0 }
expiry: { type: object }
lockout: { type: object }
force-change-at-next-login: { type: boolean, default: false }
custom-regex: { type: object }
restrictions:
optional:
apps: { type: object }
hardware: { type: object }
network: { type: object }
cloud: { type: object }
browser: { type: object }
content-ratings: { type: object }
sharing: { type: object }
open-in: { type: object }
user: { type: object }
input: { type: object }
kiosk:
required: [app]
optional:
hardware: { type: object }
accessibility:{ type: object }
asam:
required: [allowed-apps]
removal-password:
required: [password]
# ── Network ───────────────────────────────────────────────────────────────
proxy-http:
required: [proxy]
dns-proxy:
required: [app-bundle-id]
optional:
extension-bundle-id: { type: string }
config: { type: object }
domains:
optional:
email-domains: { type: array }
web-domains: { type: array }
tracking-relaxed-domains: { type: array }
network-usage-rules:
required: [rules]
cellular:
optional:
attach-apn: { type: object }
apns: { type: array }
# ── Content filtering ─────────────────────────────────────────────────────
web-filter:
required: [mode]
optional:
built-in: { type: object }
plugin: { type: object }
# ── UI shortcuts ──────────────────────────────────────────────────────────
web-clip:
required: [label, url]
optional:
removable: { type: boolean, default: true }
full-screen: { type: boolean, default: false }
icon: { type: string, encoding: base64 }
target-app: { type: string }
font:
required: [font-name, data]
# ── Device experience ─────────────────────────────────────────────────────
notifications:
required: [apps]
sso:
optional:
display-name: { type: string }
kerberos: { type: object }
identification:
optional:
full-name: { type: string }
email: { type: string }
username: { type: string }
password: { type: string }
prompt: { type: string }
google-account:
required: [address]
optional:
description: { type: string }
display-name: { type: string }
services: { type: object }
home-screen:
optional:
dock: { type: array }
pages: { type: array }
desktop:
optional:
wallpaper: { type: object }
screensaver:
optional:
module: { type: string }
idle-seconds: { type: integer, default: 300 }
locked: { type: boolean, default: false }
# ── Enterprise / desktop ──────────────────────────────────────────────────
active-directory:
required: [server]
optional:
admin-username: { type: string }
admin-password: { type: string }
computer-name: { type: string }
organizational-unit: { type: string }
user-experience: { type: object }
password-policy: { type: object }
mobile-accounts: { type: object }
local-admin-groups: { type: array }
uid-mapping: { type: string }
gid-mapping: { type: string }
trust-change-interval-days: { type: integer }
restrict-ddns-interfaces: { type: array }
allow-multi-domain-auth: { type: boolean }
ad-certificate:
required: [server, template, authority]
optional:
acquisition: { type: enum, values: [rpc, http], default: rpc }
description: { type: string }
key: { type: object }
renewal: { type: object }
prompt-for-credentials: { type: boolean, default: false }
cert-transparency:
optional:
disabled: { type: object }
required: { type: object }
time-server:
required: [server]
software-update:
optional:
catalog-url: { type: string }
automatic: { type: object }
deferral: { type: object }
allow-pre-release: { type: boolean, default: false }
require-admin-to-install: { type: boolean, default: false }
firewall:
optional:
enabled: { type: boolean, default: false }
block-all-incoming: { type: boolean, default: false }
stealth-mode: { type: boolean, default: false }
apps: { type: array }
privacy:
required: [services]
parental-controls:
optional:
apps: { type: object }
web: { type: object }
time-limits: { type: object }
content: { type: object }
global-preferences:
optional:
multi-session-enabled: { type: boolean, default: false }
shared-device:
optional:
enabled: { type: boolean, default: true }
temporary-session: { type: object }
user-session: { type: object }
quota-mb: { type: integer }
education:
required: [organization]
optional:
resource-cert-uuid: { type: string }
device-groups: { type: array }
users: { type: array }
departments: { type: array }
# ── AirPlay / AirPrint ────────────────────────────────────────────────────
airprint:
required: [printers]
airplay:
optional:
allowlist: { type: array }
passwords: { type: array }
airplay-security:
required: [security, access]
optional:
password: { type: string }
# ── macOS / desktop system policy ─────────────────────────────────────────
system-policy:
optional:
gatekeeper-enabled: { type: boolean, default: true }
allow-identified-developers: { type: boolean, default: true }
system-policy-rule:
required: [rules]
smartcard:
optional:
on-token-removal: { type: enum, values: [none, lock, logout], default: none }
cert-trust: { type: enum, values: [off, basic, ocsp, hard], default: off }
enabled: { type: boolean, default: true }
enforce: { type: boolean, default: false }
user-pairing: { type: boolean, default: true }
one-card-per-user: { type: boolean, default: false }
allow-unmapped-users: { type: boolean, default: true }
kernel-extension-policy:
optional:
allow-user-approvals: { type: boolean, default: false }
allowed-extensions: { type: array }
media-management:
required: [media]
full-disk-encryption:
optional:
state: { type: enum, values: [on, off], default: off }
defer: { type: object }
recovery-key:{ type: object }
escrow-cert: { type: string, encoding: base64 }
cert-uuid: { type: string }
fde-escrow:
required: [location, encrypt-cert-uuid]
optional:
device-key: { type: string, default: serial-number }
# ── First boot ────────────────────────────────────────────────────────────
first-boot:
optional:
skip: { type: array, description: "Pane names to skip on first boot" }
setup-assistant:
optional:
skip: { type: array, description: "Alias for first-boot — same fields" }