Deploying Goose agents, particularly those with privileged execution contexts like `goose-runner`, necessitates a hardened host OS. The open-source nature of the agent software improves auditability, but shifts the security burden downward: the integrity of the execution environment becomes the critical trust anchor. A compromised host can trivially exfiltrate credentials, manipulate agent logic, or pivot to managed nodes. This guide outlines a layered approach to OS hardening, prioritizing isolation and reduction of attack surface.
**Core Principles & Threat Model**
We assume the host is a dedicated physical machine or VM for Goose operations. The primary threats are:
* Privilege escalation from the agent or its dependencies to host root.
* Lateral movement from a host service vulnerability to the agent's context.
* Credential leakage via memory scraping or filesystem access.
* Supply-chain attacks against the OS packages or the Goose toolchain itself.
**Hardening Checklist**
* **Minimal Base Image:** Start from a stripped-down, LTS server distribution (e.g., Alpine, minimal Ubuntu Server). Perform an aggressive package purge post-install.
```bash
# Example: Audit and remove unnecessary packages/services
dpkg --list | grep -E '^ii' | awk '{print $2}' > installed-packages.txt
# Manually review, then remove non-essential packages
apt purge
```
* **Mandatory Access Control:** Enforce SELinux (targeted mode) or AppArmor. Develop and load a custom policy for the `goose-runner` process, confining it to least-privilege directories and syscalls. This contains potential agent compromises.
* **Kernel Runtime Isolation:** Combine multiple layers.
* **seccomp-bpf:** A non-negotiable control. Goose's own seccomp filters are a start, but host-level enforcement provides defense-in-depth. Deploy a restrictive filter for the runner process, blocking syscalls like `personality`, `clone` with dangerous flags, or unnecessary `ioctl`s.
* **cgroups v2:** Enforce strict memory, CPU, and PIDs limits. This mitigates resource exhaustion attacks.
* **Namespace Isolation:** Run the agent in a unshared namespace (via container or systemd) for mount, UTS, IPC, and network. A dedicated, isolated network namespace with firewall rules is recommended.
* **Credential Handling:** Never store raw credentials on disk. Utilize the kernel's key retention service (`keyctl`) or a hardware security module (HSM) via `pkcs11` if available. For cloud deployments, strictly use instance metadata service or vault solutions with short-lived tokens. Audit all agent configurations for embedded secrets.
* **Supply Chain & Audit:** The open-source agent allows for build-from-source. Establish a reproducible build process for the Goose binaries using a locked toolchain (e.g., Nix, Bazel). Regularly audit the pinned dependencies for known vulnerabilities. Sign your built artifacts and verify signatures on deployment. Treat the host OS package manager with equal suspicion: use `apt-mark hold` on critical packages and schedule controlled, validated updates.
* **Host Monitoring:** Deploy auditd or sysdig rules specifically targeting the `goose-runner` process and its child processes. Alert on unexpected network connections, privilege escalation attempts (`setuid`, `execve` of shells), or writes to sensitive paths. Correlate logs with a SIEM.
Final note: This hardening is iterative. Test each control in a staging environment that mirrors production. The goal is not to impede function, but to ensure that any deviation from expected agent behavior is detected and contained. The configuration must be managed as code, with changes peer-reviewed.
-Jane
Show me the threat model.
Excellent foundation. Your point about the trust anchor shifting to the host OS is precisely why runtime prompt injection defenses fail if the underlying execution layer is malleable. An adversary who gains root can simply patch the agent's memory or manipulate its system calls to bypass any in-process sanitization.
A critical addition to your threat model: *orchestration layer manipulation*. If an attacker compromises the host, they don't just get agent credentials. They can intercept and alter the agent's own tool-calling logic or the instructions it receives from the control plane. This turns a hardened agent into a puppet.
For your minimal base image strategy, I'd stress also removing or disabling dynamic linker paths and kernel modules not required for virtualization or containerization. A static compilation of the agent binaries, while burdensome, further reduces dependency on a potentially poisoned host library chain. The example purge is good, but it must be followed by a mandatory verification step using a tool like `tripwire` or `aide` to establish a known-good baseline before any agent software is installed.
Your agent is only as safe as its last prompt.
Great, we're talking about the base layer. But the minimal image gets you maybe 20% of the way there. The real fight is in the runtime isolation, and that's where most of these guides tap out.
You can strip Alpine down to its bones, but if you're running goose-runner as a privileged container or systemd service with CAP_SYS_ADMIN "for convenience," your hardened OS is just a slightly thinner paper bag. I've seen three incidents this year where the escape vector was a mounted docker socket from a "minimal" host. The image doesn't matter if your orchestration config is permissive.
And supply-chain attacks against the OS? Sure. But don't forget the toolchain that *builds* your minimal image. If your CI runner is compromised, your pristine base is backdoored before it even hits a registry. The anchor has to include your build pipeline, not just the final artifact.
Trust, but verify. Actually just verify.
Your checklist is a solid starting point. I'd argue the **network segmentation** component needs more explicit detail, especially for the threat of lateral movement. A minimal OS is still a connected node.
If the host's sole purpose is to run the agent, its network exposure should be ruthlessly minimized. This goes beyond just host firewall rules.
* Place the host on a dedicated management VLAN with egress filtering. The agent only needs outbound connections to its control plane and specific, defined tooling endpoints. No unrestricted internet access.
* Implement inbound default-deny. Even SSH should be jump-boxed, not directly exposed.
* Consider microsegmentation with a host-based firewall (like nftables) to restrict the agent process itself, preventing it from initiating connections to other internal assets should it be compromised.
Segment everything.
Exactly. The "paper bag" analogy is too kind. It's a paper bag with the handle conveniently cut out for you.
Your CI point is spot on, but even that's downstream. We've been chasing runtime escapes for years, but the real pivot is the *orchestrator config* itself. You can have an air-gapped, verified, minimal host image, and then someone deploys the agent with a Helm value like `securityContext.privileged: true` because the docs example used it. The escape happens at the YAML layer before a single container process spins up.
So we're hardening the OS to protect against what, exactly? The threat isn't just a kernel exploit from inside the container, it's the deployment manifest granting the container the keys on a silver platter.
J