Deployment isolation for a deliberately malicious agent
Plan Auditor's normal mode assumes the AI agent may be wrong or overconfident but does not have an OS security boundary from the deterministic supervisor. If the agent process itself is deliberately malicious, a same-user Python lock/HMAC setup is not a sufficient root of trust: the process can ignore cooperative lock files and may be able to read same-user key material.
Required boundary
For that threat model, run the verifier under a different OS/container identity:
- Supervisor identity owns the external HMAC key and Plan Auditor control state. Neither the implementing agent nor the code executing behavioral checks may read the key or trusted control state.
- Agent identity gets only the repository/product write permissions needed for implementation. It must not be able to modify the supervisor executable, key file, service configuration or host approval source.
- Check-execution identity/container runs project-controlled verification code with neither the supervisor's OS identity nor any key-file access. The trusted supervisor checks the results and authenticates evidence after that code finishes. Simply running the verifier as another user but letting its child checks inherit that user's file permissions is NOT sufficient isolation.
- The supervisor receives read access to product state plus the narrowly scoped
writes required for
.plan-auditorevidence/seals/registry. - Host request activation is performed by the trusted/user side, not by the untrusted agent identity.
- The final audit runs after cooperating agent processes are quiescent. For a
hostile agent, the OS/container boundary—not
audit.freeze.lock—prevents concurrent mutation of trusted control state.
Linux example boundary
A privileged hostile-agent deployment needs three distinct roles, for example
pa-agent, pa-check, and pa-supervisor. Keep the HMAC key in a file
readable only by pa-supervisor; the externally isolated pa-check worker
must not be able to open it. Start the supervisor service with:
PLAN_AUDITOR_HMAC_KEY_FILE=/var/lib/plan-auditor/keys/project.key
The key file must be outside the workspace and be private to the trusted supervisor. Since 2.4.5, the stock CLI offers an opt-in Linux privilege drop for each behavioral check (not a container sandbox). The supervisor must run as root; the untrusted check executes as a dedicated, unprivileged OS user.
A minimal trusted-host layout is:
# Run once as a trusted administrator. The workspace and all ancestors must
# be root-owned. A writable workspace directory must have the sticky bit.
sudo useradd --system --no-create-home --shell /usr/sbin/nologin pa-check
sudo install -d -o root -g root -m 1777 /srv/pa-workspace
sudo install -d -o root -g root -m 0700 /srv/pa-workspace/.plan-auditor
sudo install -d -o root -g root -m 0700 /var/lib/plan-auditor/keys
# Provision a strong, random project.key through a trusted mechanism,
# owned by root, mode 0600. Never commit or print the key.
The parent directories of the key file must be root-owned and not writable by group/other. Place the trusted Plan Auditor installation and Python entry point outside the agent-writable workspace, also owned by root. Configure a host-owned service or root-run invocation:
sudo env \
PLAN_AUDITOR_HMAC_KEY_FILE=/var/lib/plan-auditor/keys/project.key \
PLAN_AUDITOR_CHECK_ISOLATION=required \
PLAN_AUDITOR_CHECK_UID="$(id -u pa-check)" \
PLAN_AUDITOR_CHECK_GID="$(id -g pa-check)" \
/usr/local/bin/plan-auditor audit /srv/pa-workspace
The path /usr/local/bin/plan-auditor is illustrative; it must point to a
trusted root-managed installation. The host must separately activate and seal
its authoritative plan and retain ownership of .plan-auditor; the agent must
not control the supervisor service's environment. The check identity must not
be root and must not have access to the HMAC file or control-state directory.
This mode rejects unsupported platforms, non-root supervisors, invalid IDs, world/group-readable key files, insecure key parents, and writable workspace ancestors without root ownership and sticky-bit protection. A failure stops the check with a nonzero result; it never silently falls back to same-user execution. Ordinary installations without these variables retain the documented default, which does not protect against a deliberately malicious same-user process.
This is a Linux user-permissions boundary, not a namespace, seccomp, resource quota, or network sandbox. Host operators may additionally put the untrusted check identity in a separately restricted container/VM and must not grant it sensitive groups, writable privileged paths, ambient capabilities or sudo rights.
Container/VM boundary
For stronger isolation, place the deterministic supervisor in a separate container/VM. Mount product state read-only for the final audit when practical, and mount only the Plan Auditor control-state directory writable by the supervisor. Do not share the HMAC secret with the agent container.
Windows boundary
Use a distinct Windows account/service identity for the supervisor and ACL the key file so the agent account cannot read it. The same principle applies: a process running under the same account is not considered isolated merely because it is a different PID.
What this changes
This deployment boundary upgrades the external-HMAC/freeze controls from
workspace tamper detection to a meaningful adversarial boundary. Without it, the
project intentionally makes the narrower claim documented in threat-model.md:
it detects buggy/overconfident agent behavior and workspace tampering within the
stated same-user trust assumptions; it is not a kernel sandbox.