---
title: Security
description: WendyOS security posture — architecture, control status, threat model, and disclosure
---

## Security Posture

WendyOS is built with security as a core design requirement: mutual TLS on every CLI↔agent and
cloud connection, post-quantum cryptography for data in transit, zero-trust certificate-based
device enrollment, sandboxed apps with explicit entitlements, and a
[published threat model](../security/threat-model/).

Every control below is either already running in production code or is tracked with an
explicit work item. Where a control is still in progress or planned, this page says so.

## Architecture

WendyOS components communicate across clearly defined trust boundaries. The CLI and mobile app
reach the agent only through authenticated channels; containers are isolated from the host with
explicit entitlements; and cloud connectivity requires a certificate issued by Wendy's PKI.

```
┌──────────────────────────────────────────────────────────┐
│  Wendy Device (Edge)                                     │
│                                                          │
│  ┌─────────────┐    gRPC mTLS     ┌──────────────────┐  │
│  │  wendy CLI  │◄────────────────►│  wendy-agent     │  │
│  │  (user)     │                  │  (root daemon)   │  │
│  └─────────────┘                  │                  │  │
│                                   │  ┌─────────────┐ │  │
│  ┌─────────────┐    BLE L2CAP     │  │ containerd  │ │  │
│  │  Mobile App │◄────────────────►│  │ (containers)│ │  │
│  │  (user)     │   mTLS (post)    │  └─────────────┘ │  │
│  └─────────────┘                  │                  │  │
│                                   │  ┌─────────────┐ │  │
│                                   │  │ OCI Registry│ │  │
│                                   │  │ :5000       │ │  │
│                                   └──────────────────┘  │
│                                          │               │
│                          ┌───────────────┼──────────────┐│
│                          │D-Bus          │gRPC TLS      ││
│                   ┌──────▼──────┐ ┌─────▼────────────┐ ││
│                   │NetworkMgr / │ │ Wendy Cloud       │ ││
│                   │BlueZ        │ │ (pki-core, tunnel)│ ││
│                   └─────────────┘ └──────────────────┘ ││
└──────────────────────────────────────────────────────────┘
```

**Provisioning and mTLS transition.** Unprovisioned devices accept a plaintext channel by
design — provisioning is the mitigation. The provisioning window is time-bounded and warned to
operators; pre-enrollment at imaging time eliminates it entirely. Once provisioned, all
communication moves to mTLS on port 50052, and the plaintext port is shut down.

**Container isolation.** Apps run as non-root (`appuser`, UID 1000) inside containerd with a
baseline seccomp profile, explicit capability grants, and entitlement-gated access to hardware,
Bluetooth (D-Bus proxied), and host networking. No entitlement, no access.

## Software Bill of Materials & build provenance

Every WendyOS release includes SPDX SBOMs for each shipped binary, Swift packages, and the whole-repo source tree. Release archives for the `wendy` CLI and `wendy-agent` also carry Sigstore-backed SLSA build provenance and SBOM attestations, verifiable without managing signing keys.

See [Verifying release artifacts](../security/verification/) for verification steps.

› **Status:** SBOM and provenance are shipped. Reproducible builds and dedicated signing keys are in progress.

## Artifact signature verification

The agent enforces **ML-DSA65 detached-signature verification** on three artifact classes:

| Artifact | Signed over | Verified against |
|---|---|---|
| Agent update binary | SHA256 digest of the binary | Wendy build-embedded public key (`DefaultVerifier`) |
| Container image | SHA256 digest of the OCI image config | Per-org publisher key from provisioning/PKI |
| Driver add-on | SHA256 digest of the `.raw` image | Wendy build-embedded public key (`DefaultVerifier`) |

Verification behaviour:
- **Disabled** (no key embedded): verification is a fail-safe no-op; the install or run proceeds as if the check does not exist.
- **Enabled** (key present): an unsigned artifact returns `FailedPrecondition`; a tampered or invalid signature returns `DataLoss`. The install or container run is refused in both cases.
- **Corrupt key at init**: the agent panics at startup — it never silently degrades to an accept-all state.

As of this release the embedded keys are placeholder stubs (verification is dormant). The checks become active automatically once the cross-repo signing pipeline and pinned keys are deployed.

Driver add-ons are the one place where "dormant" is not the same as "no consequence": a
driver add-on is kernel code, so while the key is a stub, installing one loads an
unsigned out-of-tree module and **taints the running kernel** (flags `4096` + `8192` =
`12288`). The agent logs a warning naming the add-on each time. One case does not
degrade: add-ons seeded from the config partition are refused outright rather than
installed unverified, because that path runs at boot with no operator present to accept
the risk. See [Managing drivers](../device/managing-drivers/).

› **Note:** `CreateContainer` and `CreateContainerWithProgress` do not yet pass through the image-signature gate. `wendy run` carries the image signature via the `WENDY_IMAGE_SIGNATURE_PATH` environment variable.

## Control Status

| Control | Status | Target |
|---------|--------|--------|
| CLI↔agent mTLS (port 50052) | ✅ Shipped | — |
| Post-quantum data-in-transit | ✅ Shipped | — |
| Zero-trust cloud enrollment (PKI) | ✅ Shipped | — |
| CLI device/org pinning on set-default | ✅ Shipped | — |
| Container seccomp baseline | ✅ Shipped | — |
| CAP_NET_ADMIN gated behind explicit host-admin entitlement | ✅ Shipped | — |
| D-Bus proxy hard-fail (no silent unfiltered fallback) | ✅ Shipped | — |
| containerd socket bind-mount denied | ✅ Shipped | — |
| Browser isolation for OCI registry contents (Content Security Policy) | ✅ Implemented | Next release |
| Default PID limits per container (fork-bomb guard) | ✅ Shipped | — |
| Hook command injection fix; debug port bound to loopback | ✅ Shipped | — |
| SBOM / SLSA provenance | ✅ Shipped | — |
| Container image signature verification (ML-DSA65, key not yet embedded) | 🛠 In progress | Q3 2026 |
| Signed agent updates (ML-DSA65, key not yet embedded) | 🛠 In progress | Q3 2026 |
| Signed OS updates | 🛠 In progress | Q3 2026 |
| Reproducible builds / dedicated signing keys | 🛠 In progress | Q3 2026 |
| Cloud CA pinning in firmware | 🛠 In progress | Q3 2026 |
| Certificate revocation (OCSP/CRL) | 🛠 In progress | Q3 2026 |
| Operator-scoped permissions in developer certificates | 🛠 In progress | Q3 2026 |
| Hardware-backed key protection / root of trust (HSM/TPM) | 🛠 In progress | — |
| Container user namespaces (UID remap) | 📋 Planned | — |
| Audit logging (tamper-evident, remote sink) | 📋 Planned | — |
| Enrollment token ECDH protection | 📋 Planned | — |
| Default network mode bridge/CNI | 📋 Planned | — |
| Secure-boot lockdown via fuse burning (supported platforms) | 📋 Planned | — |

For the full STRIDE analysis behind these controls — threat IDs, severity ratings, existing
mitigations, and recommended hardening — see the
[WendyOS Threat Model](../security/threat-model/).

## Trust & Disclosure

### Vulnerability Disclosure

Report vulnerabilities to **security@wendy.dev** rather than filing a public issue. We take all
reports seriously, respond promptly, and keep you updated through remediation.

We do not currently offer a formal bug-bounty program, but responsible disclosure is always
recognized and credited where the reporter consents.

### Compliance

We are actively working toward **SOC 2** compliance. This is in progress — we are not yet
certified — and we will update this page as we reach milestones. If you have specific compliance
or due-diligence requirements, reach out to **security@wendy.dev**.

### Supply Chain

SBOM generation and SLSA build provenance ship today — see [Verifying release artifacts](../security/verification/). Reproducible builds and dedicated artifact-signing keys are under active development (🛠 In progress); ML-DSA65 signature verification for container images and agent binaries is wired in the agent but dormant until those keys are deployed.

Until the signing keys are deployed: container images are verified by SHA256 digest; agent updates require a valid mTLS
connection to submit.

### Security Changelog

Unreleased:

- OCI registry responses use `Content-Security-Policy: default-src 'none'; sandbox` to isolate publisher-supplied content opened in a browser, including an HTML media type. Image bytes, media types and content digests are preserved.

Controls shipped in recent releases:

- D-Bus proxy hard-fail — container start refused when `xdg-dbus-proxy` is absent; raw host socket never mounted
- `/run/containerd/*` bind mounts denied in the container spec builder
- `CAP_NET_ADMIN` separated from host networking; requires explicit `host-admin` entitlement
- Baseline seccomp profile applied to all containers (blocks `ptrace`, `unshare`, `clone(CLONE_NEWUSER)`, `kexec`, kernel-module loading)
- Default PID limit (4096) applied to every container regardless of manifest declarations
- Hook command injection fix — hooks execute via `exec.Command`, not `sh -c`
- Debug port (`debugpy`) bound to loopback `127.0.0.1:5678`, not `0.0.0.0`
- CLI pins device organization and cloud host on `set-default`; subsequent connections verify the pin

## Stay Updated

Security features are announced on our [blog](https://wendy.dev/blog) and in our
[Discord community](https://discord.gg/xYeUxq9TXv).
