Policies & inheritance
Three levels of policy (tenant / group / device), 10 sections, 150+ settings. How the merge works, and how the agent applies it.
Three-level inheritance
A device's effective policy is computed by merging three layers in order:
Tenant default policy ← base for everything
+
Group policy override ← overrides tenant where set
+
Device policy override ← overrides group where set
=
Effective policy ← what the agent actually appliesMerging is section-aware: each of the 10 sections (security, apps, display, ...) merges independently. If a group sets security.camera_disabled = true, that value wins for that section — but the tenant's apps.hidden_packages list still applies.
Arrays do notmerge — the most specific level's array replaces higher levels entirely. This prevents accidental blacklist union.
The 10 policy sections
security— password quality, camera, screen capture, keyguard, FRP, MTE, content protectionapps— hidden packages, blocked uninstall, suspended packages, default permission policydisplay— orientation lock, brightness mode, screen timeoutlockdown— status bar, gesture navigationrestrictions— 54 UserManager DISALLOW_* toggles (bluetooth, WiFi, NFC, SMS, etc.)network— VPN, proxy, WiFi SSID allowlist, private DNS, NFC, 802.1Xbranding— wallpaper URL, device name template, support messagesusb— storage block/allow, data signalingkiosk— lock task packages, web kiosk URL, status bar, settings accesssystem— auto time/timezone, update windows, backupagent— heartbeat interval, screenshot quality, compliance interval, log level
Full schema: Policy JSON schema reference.
How an edit propagates
- Admin clicks Save in the policy editor
- API validates the JSON against the policy schema (rejects on invalid)
- API writes a new row to
policieswith an incremented version - API computes effective policy for every affected device (tenant, group, or device-scoped)
- API publishes
policy_updateMQTT command with the merged JSON to each device - Agent receives, calls
PolicyEngine.applyPolicy(), runs 75+ DPM calls - Agent publishes compliance report to
vela/{id}/policy_report - Console shows updated compliance status within ~5 seconds
Policy diff viewer
Every save creates a new version. The Historytab on any policy shows a side-by-side diff of what changed between versions — not a raw JSON diff, but a human-readable summary like "Camera disabled: false → true".
Click Revert to version N to roll back. This creates version N+1 with the old values (policy history is append-only).
Policy templates
The console ships with built-in templates you can use as starting points:
- Kiosk (single app) — lock task mode, hide status bar, disable settings
- Kiosk (web) — fullscreen WebView locked to a URL
- Digital signage — screen always on, auto-rotate, wallpaper + playlist hooks
- VDI thin client — Citrix/Horizon/AVD allowlisted, restricted user settings
- Shared desktop — minimal restrictions for browser + office use
Example: tenant-wide security baseline
{
"version": 3,
"security": {
"password_complexity": "medium",
"password_min_length": 6,
"screen_capture_disabled": true,
"factory_reset_protection": true,
"max_failed_attempts": 10
},
"restrictions": {
"install_unknown_sources": true,
"config_credentials": true
},
"agent": {
"heartbeat_interval_seconds": 60,
"log_level": "info"
}
}Every device in the tenant gets these values unless a group or device override supplies a different value. Creating a "Kiosk" group that sets kiosk.web_url = "https://signage.app" does not disturb the security settings.
AI-ready schema
The API exposes GET /api/v1/policies/schema which returns the full JSON Schema describing every policy field, type, and allowed values. This is what drives the console policy editor — and it also means an LLM can generate a valid policy from natural language:
curl https://api.velaos.ch/api/v1/policies/schema \
-H "X-API-Key: vela_live_sk_..."Next steps
- Full policy JSON schema
- Policy editor walkthrough
- Compliance engine — automated rule evaluation
