AOS Hub / Docs

Understand the package sandbox

AOS applies runtime confinement to systemd services published through a package's expose contract. The contract contains the units, privilege manifest, configuration interface, and supporting artifacts that APM verifies and activates as one package target.

The sandbox limits what an authorized package can do after activation. It does not establish where the package came from or whether its publisher is trusted; configure that boundary through package registries.

#Know when the sandbox applies

The package sandbox applies only to workload services activated from verified expose metadata. A package without expose has no APM-managed service, and running an executable directly from a user or system profile does not put that process inside the service sandbox.

Each exposed package has one lifecycle target:

aos-pkg-<package-name>.target

The target owns the package's workload units and generated host-side helpers. APM activates and removes the target as part of the machine-wide package generation transaction. A unit explicitly marked for manual start is installed but is not pulled into the target automatically.

#Start from default denial

An empty or omitted permission manifest selects the least-privilege defaults. A confined service receives:

  • its own package-backed root and private temporary directories;
  • a private dynamic identity and user namespace where compatible;
  • a private network namespace;
  • an empty capability bounding set;
  • closed device access except for explicitly generated necessities;
  • a restricted named syscall profile;
  • systemd filesystem, kernel, home, and privilege hardening;
  • Landlock filesystem restrictions inherited across service execution; and
  • generated TCP policy where ports are declared.

The package payload is the immutable lower layer of a per-service volatile overlay. Writable state belongs in generated service directories or paths explicitly granted by policy, not in the payload.

The actual generated unit is authoritative. The manifest, rendered unit, and host policy are cross-checked during activation so a package cannot advertise a narrow permission list while installing broader service directives.

#Read the privilege gradient

Permissions widen the default boundary. APM computes the result rather than letting the package choose its own label:

LabelMeaning
sandboxedThe exposed workload retains the default boundary with no declared holes
sandboxed-with-holes (...)The listed grants weaken the default, but a meaningful boundary remains
unconfinedRoot-equivalent grants make the package target a lifecycle wrapper rather than a security boundary

CAP_SYS_ADMIN, privileged users, and writable system locations are root-equivalent and force unconfined. Software such as k3s may legitimately need that authority, but its workload isolation then comes from its own pod or container model rather than the APM package sandbox.

Inspect both the signed request and the local policy decision before adding a package to the desired machine-wide set:

apm info PACKAGE --system --permissions
apm policy PACKAGE --system

Do not infer confinement from a package description or service name.

#Review each permission

The effective privilege is the package request intersected with host policy. The main permissions are:

PermissionEffect
networkSelects a private, private-outbound, or host network model
tcp-bind and tcp-connectGrants exact TCP ports to generated Landlock and eBPF policy
capabilitiesAdds named Linux capabilities to the service boundary
devicesOpens exact device nodes through the generated device policy
host-pathsBind-mounts named host paths read-only or read-write and extends filesystem policy
cgroup-delegateAllows the service to manage descendant cgroups
privileged-usersDisables the private user-identity model
static-usersUses authenticated named non-root service accounts instead of only dynamic identities
kernel-modulesRequests a host helper to load an allowlisted signed module
syscallsSelects a named restricted, system-service, or privileged syscall profile
security-labelSelects the package's generated MAC label, subject to host policy

Host networking is a significant downgrade. The process shares the host network namespace, so per-package network identity cannot provide the same separation. Filesystem, capability, syscall, credential, and other hardening may still remain.

A read-write host path can be equivalent to full host authority when it covers system configuration, service control, credentials, devices, or another security-sensitive location. APM labels writable system locations unconfined; operators should apply the same reasoning to application paths that carry powerful control data.

#Understand host-fulfilled permissions

Some effects cannot be performed safely by the confined workload. AOS renders narrow host-side services under the package target for approved kernel modules, sysctls, firewall entries, network setup, MAC policy, and eBPF policy.

These helpers do not give the workload their own privileges. For example, a package requesting kernel-modules does not receive CAP_SYS_MODULE; an allowlisted host helper loads the named module. Enabling the package target activates the helper, and disabling it removes reversible effects through the same lifecycle boundary.

Review host-side permissions especially carefully. Kernel modules execute in the kernel, global sysctls affect other services, and firewall changes alter host exposure beyond the workload namespace.

#Distinguish store-backed and verity-backed roots

Normal confined services use a volatile RootDirectory= overlay backed by the authenticated Nix store payload. Registry verification establishes the payload identity when APM imports the closure, and the store is exposed read-only to the workload.

An exposed package can instead publish a signed dm-verity root image. The service uses RootImage= with the authenticated root hash and signature. This adds block-by-block integrity checking while the service runs and is not available for a package whose permissions require unconfined rendering.

A non-verity workload has authenticated admission and a read-only package root, but not dm-verity verification of every block read at runtime. The read-only view constrains the workload; it does not defend against an attacker who already controls the host or its writable Nix-store backing. Choose a signed package root image when that stronger property is required.

#Understand package measurement

On measured-boot systems, activation extends PCR 15 for every explicitly installed machine-wide package with expose metadata. The event binds:

H(package name || version || root digest || permission-manifest digest)

The event log is written to /run/log/aos-packages.cel. A verifier replays it, checks the quote, and compares each tuple with the signed registry catalog. This connects the active exposed-package set and its privilege declarations to the boot measurements in PCRs 7, 11, and 12.

PCR 15 does not produce an individual package event for:

  • user-profile packages;
  • downloaded but inactive packages;
  • implicit closure members; or
  • arbitrary objects already in /nix/store.

Those bytes remain covered by the signed store realization graph. PCR 15 answers which exposed roots and manifests were activated, not which files have ever existed on the machine.

#Keep configuration and secrets separate

Package configuration is evaluated from a typed, signed package interface and materialized with the configuration generation. Secrets are supplied through opaque references and systemd credentials. Permission to read one credential does not imply access to another package's credentials or general secret storage.

Do not place secret bytes in a package option intended for Nix evaluation, an environment variable rendered into a unit, or a store-backed file. See Manage secrets on AOS for the supported runtime paths.

#Verify the active sandbox

Start with APM's signed metadata and policy view:

apm info PACKAGE --system --permissions
apm policy PACKAGE --system
apm list --installed --system

After activation, inspect the exact target and workload units:

systemctl status aos-pkg-PACKAGE.target
systemctl cat PACKAGE.service
systemctl show PACKAGE.service \
  -p RootDirectory \
  -p RootImage \
  -p PrivateNetwork \
  -p PrivateUsers \
  -p CapabilityBoundingSet \
  -p DevicePolicy \
  -p SystemCallFilter

Check service logs and behavior in addition to static settings. A generated sandbox can be internally consistent while the application is unhealthy or while an intentionally granted privilege is broader than the deployment wants.

For remote attestation, use the public verifier described in Use the AOS command-line tools. A raw PCR value without the CEL event log, quote identity, and signed policy is not sufficient evidence.

#Know what the sandbox does not prove

The package sandbox does not prove:

  • that the package publisher is trustworthy;
  • that reviewed source produced the published bytes;
  • that the program contains no vulnerabilities;
  • that a package labeled unconfined is isolated;
  • that a directly executed profile binary is confined; or
  • that admission-time hashing provides dm-verity runtime integrity.

Use registry verification, provenance review, local permission policy, runtime confinement, measured boot, monitoring, and recovery as distinct, complementary controls.