Introducing pv-xconnect: A Service Mesh for Container-to-Container Communication
We are excited to announce pv-xconnect, a new service mesh that enables secure, mediated communication between Pantavisor containers. This feature has landed on master in pantavisor/pantavisor PR #621, with Yocto layer support in meta-pantavisor PR #190.
The Problem
Containers on embedded devices often need to talk to each other — a UI container needs GPU access, a management app needs to query a network service, an orchestrator needs to control system daemons. Traditional approaches (shared volumes, host networking) break isolation and create security gaps.
The Solution: Pantavisor as Security Broker
pv-xconnect is a dedicated mediation daemon that sits between containers. Instead of containers discovering and connecting to each other directly, Pantavisor owns the service graph and injects the right resources into the right namespaces at runtime.
Containers declare what they provide and what they need — Pantavisor does the rest.
Five Service Types
pv-xconnect supports five distinct communication patterns:
| Type | Use Case | How It Works |
|---|---|---|
| Unix | Raw IPC, custom protocols | Socket proxy with namespace injection, supports FD passing |
| REST | HTTP APIs between containers | HTTP-over-Unix-socket with identity headers (X-PV-Client, X-PV-Role) |
| D-Bus | System services (NetworkManager, etc.) | Policy-aware proxy with role-to-UID mapping and interface filtering |
| DRM | GPU and display access | Device node injection (/dev/dri/card0, renderD128) |
| Wayland | GUI rendering | Compositor socket mediation for isolated UI containers |
How It Works
Provider containers declare services in services.json:
{
"#spec": "service-manifest-xconnect@1",
"services": [
{"name": "my-api", "type": "rest", "socket": "/run/my-api.sock"}
]
}
Consumer containers request services in args.json:
{
"PV_SERVICES_REQUIRED": [
{"name": "my-api", "target": "/run/pv/services/my-api.sock"}
]
}
pv-xconnect reconciles the graph continuously: when a provider starts, it automatically connects waiting consumers. When containers restart, connections are re-established.
New Shell Tools: pvcontrol and pvcurl
Two new utilities make it easy to inspect and manage the service mesh:
# Query the service mesh topology
pvcontrol graph ls
# List managed daemons
pvcontrol daemons ls
# Query container status
pvcontrol ls
# Low-level API access
pvcurl --unix-socket /run/pantavisor/pv/pv-ctrl http://localhost/xconnect-graph
11 Example Containers
The meta-pantavisor layer ships with ready-to-build example containers covering every service type:
| Pattern | Provider | Consumer(s) |
|---|---|---|
| Unix socket | pv-example-unix-server |
pv-example-unix-client |
| REST API | pv-example-rest-server |
pv-example-rest-client |
| D-Bus | pv-example-dbus-server |
pv-example-dbus-client |
| DRM/GPU | pv-example-drm-provider |
pv-example-drm-master, pv-example-drm-render |
| Wayland | pv-example-wayland-server |
pv-example-wayland-client |
Build and test with the appengine Docker workflow:
# Build appengine + examples
./kas-container build .github/configs/release/docker-x86_64-scarthgap.yaml \
--target pv-example-unix-server \
--target pv-example-unix-client \
--target pantavisor-appengine
# Load and run
docker load < build/tmp-scarthgap/deploy/images/docker-x86_64/pantavisor-appengine-docker.tar
docker run --name pva-test -d --privileged \
-v $(pwd)/pvtx.d:/usr/lib/pantavisor/pvtx.d \
-v storage-test:/var/pantavisor/storage \
--entrypoint /bin/sh pantavisor-appengine:latest -c "sleep infinity"
docker exec pva-test sh -c 'pv-appengine &'
# Verify
docker exec pva-test pvcontrol graph ls
Security Model
The design follows a zero-trust principle:
- No direct container-to-container paths — all communication goes through pv-xconnect
- Role-based access control — D-Bus policies enforce per-role permissions via UID mapping
- Identity injection — REST services receive authenticated caller identity in HTTP headers
- Namespace isolation — resources are injected into specific mount/network namespaces only
- Declarative graph — the service mesh topology is defined in the Pantavisor state, versioned and auditable
What is Coming Next
The xconnect landing is the foundation for several features currently in development:
-
Auto-Recovery (PR #610) — Automatic container restart with configurable policies (always, on-failure, unless-stopped) and exponential backoff. Containers recover from crashes without rebooting the device.
-
Container Lifecycle Control (PR #612) — REST API for stopping, starting, and restarting individual containers at runtime (
PUT /containers/{name}), with rich status queries including PID, uptime, and service mesh info. -
IPAM Networking (PR #613) — IP Address Management for container networking with bridge pools, automatic IP allocation, NAT, and hostname configuration. Containers get proper network identities.
-
Ingress Routing (PR #616) — TCP (L4) and HTTP (L7) ingress plugins for routing external traffic to containers, completing the networking story.
Get Started
- Source: pantavisor/pantavisor (master)
- Yocto layer: pantavisor/meta-pantavisor (feature/xconnect-landing)
- Spec: XCONNECT.md
- Examples: EXAMPLES.md
We would love to hear your feedback — try it out and let us know what you think!