AOS Hub / Docs

Manage packages with APM

apm consumes signed registry metadata and manages generation-based package profiles. User packages, machine-wide runtime packages, configuration generations, and A/B image generations are separate scopes. The distinction is important: --system does not simply make a normal user install global.

#Establish package policy first

Before installing a package, configure and verify its source as described in Configure package registries. Registry signatures and the signed store graph authenticate the publisher and exact closure bytes; they do not establish that a program is benign.

For packages that activate services, inspect the signed permissions and local policy described in Understand the package sandbox. On measured-boot systems, Secure Boot and package trust explains how the image-baked registry anchors and PCR 15 measurements connect package admission to the boot chain.

#Manage user packages

User scope is the default; there is no --user flag. Stock images do not yet provision writable per-user APM configuration, a per-user profile directory, or unprivileged Nix-store mutation. The commands in this section require an account whose writable XDG directories and /var/lib/profiles/per-user/$USER have been provisioned by the operator. Use the system-scope desired-package workflow on a stock host.

apm install nginx --registry acme --dry-run
apm install nginx --registry acme

apm list --installed
apm files nginx
apm depends nginx

Installed executables are under:

/var/lib/profiles/per-user/$USER/current/bin

That directory is not added to the default shell PATH. Invoke a binary by its full path or configure the profile path in the user's shell environment:

export PATH="/var/lib/profiles/per-user/$USER/current/bin:$PATH"

Refresh metadata before checking for upgrades:

apm update
apm list --upgradable
apm upgrade --dry-run
apm upgrade

apm update synchronizes metadata; it does not install packages. apm upgrade uses the already-synchronized metadata and does not update it implicitly.

Remove a package after reviewing the dependency plan:

apm remove nginx --dry-run --autoremove
apm remove nginx --autoremove

Hold and unhold keep a package out of ordinary upgrade selection:

apm hold nginx
apm unhold nginx

Install, remove, and upgrade create numbered profile generations. Rollback repoints current to an existing generation:

apm rollback --list
apm rollback --generation N --dry-run
apm rollback --generation N

#Manage machine-wide packages

Ordinary machine-wide packages are reconciled from an authoritative desired file. Create desired.toml:

packages = ["nginx", "curl"]

Preview and apply the complete set:

apm update --system
apm install --system --from ./desired.toml --dry-run
apm install --system --from ./desired.toml --yes

The explicit update makes the preview predictable: dry-run never refreshes metadata. When applying additions, reconciliation also attempts an update and falls back to cached metadata with a warning if that update fails. A change with no additions does not refresh metadata.

The list is declarative. Explicit packages omitted from the next file are removed during reconciliation, including packages made unreachable by that change. To remove nginx, delete it from packages and run the same command again. There is no apm remove --system command.

The desired format can also carry package configuration and credential input. APM checks those inputs before mutating the package profile. Prefer systemd system-credential references; if a separately managed desired file contains bytes, protect it as secret state. Evaluated host.nix contains only opaque secretRef handles, never those bytes.

Machine-wide runtime package generations are stored separately from the OS:

/var/lib/profiles/system-packages

Prune old machine-wide package and configuration generations together with:

apm clean --system --generations --keep 3
apm gc

The latest keep window and the active generation of each independent profile are retained. Image generations are not affected.

#Distinguish a sysroot install

This command has a narrower meaning than its spelling suggests:

apm install aos --system --registry acme

It selects exactly one registry package marked sysroot = true, verifies its authenticated OTA payload, and stages it as the next A/B image generation. It is not the command for installing an ordinary package globally, and it does not replace the running root before reboot.

Always preview a selected sysroot install:

apm install aos --system --registry acme --dry-run
apm install aos --system --registry acme --yes

Image and configuration state are separate:

/var/lib/profiles/image    A/B image generations
/var/lib/profiles/system   configuration generations

For ordinary OS rollout, use the controlled update and rollback procedure in Upgrade and roll back a host.

#Confirmation and safety controls

Install, remove, and user-package upgrade operations prompt before mutation unless --yes, [settings].assume_yes, or --dry-run applies. System upgrade and rollback have their own behavior; lead automation with --dry-run rather than relying on a prompt.

The sysroot lock prevents a runtime package from diverging from dependencies owned by the active OS. --ignore-sysroot-lock bypasses that protection and is for targeted recovery, not routine package management. Prefer a specific package name over the all form when a recovery procedure requires it.

#Default state and cache paths

StateUser scopeSystem scope
Profile/var/lib/profiles/per-user/$USERRuntime packages: /var/lib/profiles/system-packages; configuration: /var/lib/profiles/system; image: /var/lib/profiles/image
Registry clones~/.local/share/apm/registries/var/lib/apm/registries
Synchronized metadata~/.local/share/apm/remote/var/lib/apm/remote
NAR and cache data~/.cache/apm/var/lib/apm/cache
Writable trust pins~/.config/apm/trusted-keys.d/var/lib/apm/trusted-keys.d

Use apm --json ... when consuming package results in automation. Normal human-facing output is not a stable machine interface.

User XDG paths honor the corresponding XDG_* variables. Test and recovery environments can also redirect roots with AOS_ROOT, AOS_PROFILE_ROOT, and the documented system-config override.