Run Microsoft Intune on an immutable Linux host.
intuneme provisions and manages a systemd-nspawn container running Ubuntu 24.04 with Intune Portal, the Microsoft Identity Broker, and Microsoft Edge. The container handles enrollment, compliance, and corporate resource access while making minimal changes to the host.
The container boots a full systemd instance with its own D-Bus session, gnome-keyring, and user services. The host provides display access (X11/Wayland), audio (PipeWire), and GPU acceleration through individual socket bind mounts. A dedicated ~/Intune directory on the host serves as the container user's home, persisting enrollment state, browser profiles, and downloads across container rebuilds.
Host Container (systemd-nspawn)
──────────────────── ────────────────────────────
~/Intune/ ──────────────bind──→ /home/<user>/
/tmp/.X11-unix ─────────bind──→ /tmp/.X11-unix
/run/user/$UID/wayland-0 bind──→ /run/host-wayland
/run/user/$UID/pipewire-0 bind─→ /run/host-pipewire
Xauthority file ────────bind──→ /run/host-xauthority
/dev/dri ───────────────bind──→ /dev/dri
/dev/video* ────────────bind──→ /dev/video* (if present)
/dev/media* ────────────bind──→ /dev/media* (if present)
intuneme CLI systemd (PID 1)
└─ broker-proxy (opt-in) ─D-Bus─→ ├─ microsoft-identity-broker
├─ microsoft-identity-device-broker
├─ intune-agent (timer)
├─ gnome-keyring-daemon
└─ intune-portal / microsoft-edge
By default, the identity broker only runs inside the container. If you want host-side apps like Microsoft Edge or VS Code to authenticate via your Intune enrollment, enable the broker proxy:
intuneme config broker-proxy enable
intuneme stop && intuneme startThis starts a D-Bus forwarding proxy on the host session bus that relays com.microsoft.identity.broker1 calls to the container's broker. Host apps using MSAL (Edge, VS Code, etc.) will transparently use the container's enrollment for SSO and conditional access — no changes needed on the app side.
To disable:
intuneme config broker-proxy disable
intuneme stop && intuneme startWhen enabled, intuneme start also creates a login session inside the container (for gnome-keyring and the broker's user services) and intuneme status shows the proxy state.
The host needs:
- systemd-nspawn and machinectl (package:
systemd-container) - podman (used to pull and extract the OCI base image)
- A graphical session (X11 or Wayland)
On Debian/Ubuntu:
sudo apt install systemd-container podmango install github.com/frostyard/intuneme@latestOr build from source:
git clone https://github.com/frostyard/intuneme.git
cd intuneme
go build -o intuneme .# 1. Provision the container (pulls image, installs Edge, configures services)
intuneme init
# 2. Boot the container
intuneme start
# 3. Open a shell inside the container
intuneme shell
# 4. Inside the container — enroll in Intune
intune-portal
# 5. Inside the container — browse corporate resources
microsoft-edge
# 6. Inside the container - manage Yubikeys
ykmanA Quick Settings toggle lets you start/stop the container and open a shell without touching the terminal.
intuneme extension installLog out and back in to activate. The toggle appears in Quick Settings with the container's current state. Clicking it starts or stops the container, and the popup menu shows status details and an "Open Shell" shortcut.
The extension monitors container state via D-Bus signals from systemd-machined for instant updates, with periodic polling as a fallback. Requires GNOME Shell 47+.
| Command | Description |
|---|---|
intuneme init |
Pull the OCI image, extract rootfs, install Edge, configure user/PAM/services |
intuneme start |
Boot the container |
intuneme shell |
Open an interactive shell (real logind session with D-Bus and keyring) |
intuneme stop |
Shut down the container |
intuneme status |
Show whether the container is initialized and running |
intuneme recreate |
Upgrade the container image, preserving enrollment state |
intuneme destroy |
Stop the container, remove the rootfs, clean enrollment state |
intuneme config broker-proxy enable |
Enable the host-side broker proxy for SSO |
intuneme config broker-proxy disable |
Disable the broker proxy |
intuneme extension install |
Install the GNOME Shell Quick Settings extension |
--root <path>— Override the data directory (default:~/.local/share/intuneme/)--force— Force re-initialization (withinit)
- Checks that
systemd-nspawn,machinectl, andpodmanare installed - Creates
~/Intuneon the host - Pulls
ghcr.io/frostyard/ubuntu-intune:latest - Extracts the rootfs into
~/.local/share/intuneme/rootfs/ - Configures a
rendergroup matching the host for GPU access - Creates a container user matching your host UID/GID
- Enables the system identity device broker service
- Applies configuration: hostname, broker display override, login profile script, Edge wrapper
- Installs a polkit rule so
sudoandwheelgroup members can use machinectl without repeated password prompts - On SELinux systems (Fedora, Bazzite): relabels the rootfs as
container_file_tand installs a policy module grantingsystemd-machinedthe PTY access needed formachinectl shell - Saves configuration to
~/.local/share/intuneme/config.toml
~/.local/share/intuneme/
├── rootfs/ # Ubuntu 24.04 rootfs with Intune + Edge
├── runtime/ # Bind-mounted as /run/user/<uid> in container (broker proxy)
└── config.toml # machine name, rootfs path, host UID, broker_proxy flag
~/Intune/ # Container user's home (persists across rebuilds)
├── .config/intune/ # Enrollment state
├── .config/ # Edge profile, app config
├── .local/ # Keyring, broker state
├── Downloads/ # Downloads, file exchange with host
└── ...
When a new container image is released, use recreate to upgrade without losing your Intune enrollment:
intuneme recreate
intuneme startThis stops the running container, backs up the password hash and device enrollment database, pulls the new image, re-provisions, and restores the backed-up state. No re-enrollment needed.
If you need to start fresh with Intune:
intuneme destroy
intuneme init
intuneme start
intuneme shell
# Inside: intune-portaldestroy removes the rootfs and cleans Intune enrollment state from ~/Intune. Your other files in ~/Intune (Downloads, etc.) are preserved.
intuneme shell fails on Fedora/Bazzite (SELinux)
intuneme init handles this automatically: it relabels the rootfs and installs a policy module for systemd-machined. If you upgraded from an older install and didn't re-run init, use the provided script: bash scripts/fix-selinux.sh.
intune-portal crashes with "No authorization protocol specified"
The XAUTHORITY file isn't being forwarded. Check that your host has an Xauthority file in $XAUTHORITY or /run/user/$UID/ (patterns: .mutter-Xwaylandauth.*, xauth_*).
intune-portal shows error 1001 or "UI web navigation failed" The identity broker services aren't running. Inside the container:
sudo systemctl status microsoft-identity-device-broker
systemctl --user status microsoft-identity-brokerCompliance check fails The intune-agent timer may not be running. Inside the container:
systemctl --user start intune-agent.timer
/opt/microsoft/intune/bin/intune-agentEdge crashes with "Trace/breakpoint trap"
Try launching with a fresh profile first: microsoft-edge --user-data-dir=/tmp/edge-test. If that works, the issue is a corrupted profile — move ~/.config/microsoft-edge/ aside and restart Edge.
No sound in Edge
Check that PipeWire is forwarded. The host needs a PipeWire socket at /run/user/$UID/pipewire-0. Inside the container, verify $PIPEWIRE_REMOTE is set.
Webcam not available in Teams/Edge
Video devices are detected at intuneme start and are not hot-plugged. If you connect a USB webcam after the container is already running, restart it with intuneme stop && intuneme start to pick up the new device.
mkosi-intune builds the entire rootfs from scratch with mkosi and debootstrap. intuneme uses a pre-built OCI image which is faster to set up. Both approaches run a booted nspawn container with Edge inside.
MIT