Security model

How VelaOS protects the device, the network, and the fleet. Device Owner privileges, mTLS, RBAC, encryption-at-rest, and the full audit chain.

The four layers

1. Device Owner mode on Android

The VelaOS Agent runs as Device Owner— Android's highest privilege level for MDM apps. This grants access to 75+ DevicePolicyManager APIs without root. It's set at provisioning time viadpm set-device-owner and cannot be changed later without a factory reset.

Device Owner is a one-way door. Once set, only a factory reset removes it. This is by design — it prevents attackers from demoting the agent.

2. Mutual TLS for every MQTT connection

During enrollment, the cloud issues each device a unique X.509 certificate signed by the tenant's CA. Every MQTT connection to mqtt.velaos.ch:8883 presents this cert. The broker validates the chain and enforces topic ACLs based on the CN (which is the device UUID).

Private keys are generated on-device in the Android KeyStore (hardware-backed on Pi 5 via the platform's TEE when available). They never leave the device.

3. Role-based access control on the console

VelaOS ships four roles with 12 atomic permissions:

  • tenant_admin — all permissions
  • site_admin (operator) — device management + app deployment, no user/org management
  • helpdesk — read devices + reboot/screenshot/logs, no policy changes
  • readonly — view-only

Permissions: device.approve, device.move, device.reboot, device.wipe,device.logs, group.manage, policy.manage, app.upload,app.deploy, ota.deploy, user.manage, org.settings.

4. Encryption at rest

  • Agent side — SecurePrefs (enrollment config, cached policy) encrypted with AES-256-GCM backed by Android KeyStore
  • Cloud side — Postgres transparent encryption via Supabase; TOTP secrets and API key hashes use per-tenant derived keys
  • Storage — APKs, logs, screenshots, OTA images all stored with server-side encryption; accessed via 1-hour presigned URLs

What an attacker cannot do

  • Impersonate a device — would need the per-device private key which is hardware-sealed
  • Read another device's topics — MQTT ACLs scope every device to its own UUID namespace
  • Access the API with a stolen cookie — cookies are httpOnly + Secure + SameSite=Strict; CSRF tokens required on mutations
  • Get a real API key into logs — keys are hashed with SHA-256 server-side, never logged
  • Downgrade the agent to an exploitable version — versionCode monotonic enforcement
  • Factory reset without token — resets require an admin-issued reset token

Audit trail

Every mutation writes an audit_log row with:

  • Timestamp, tenant ID, user ID (or API key ID), IP address
  • Action name (e.g. device.reboot, policy.manage)
  • Target (e.g. device:abc-123)
  • Structured details (JSON, sanitized)

Retention: 365 days by default, configurable. Exportable via the Audit Log page or API.

Compliance certifications (roadmap)

  • SOC 2 Type II — planned for v3.0 GA
  • ISO 27001 — planned 2027
  • GDPR — data hosted in EU (Frankfurt/eu-central-2), DPA available today

Next steps

Was this helpful?
Updated 2026-04-14Edit on GitHub