Skip to navigation

Install and Run APF

View as Markdown

This page builds APF from source and starts the two APF services, apf-policy-service and apf-policy-gateway, with the signed demo bundle. Choose the run mode that matches your goal. To run APF on Kubernetes with the Helm chart, refer to Kubernetes.

Run modeUse it forSecurity posture
Native processesFast local iteration.Development only. Loopback, dev keys, and OpenShell caller authentication turned off.
Container stackLocal development in Docker.Development only. Dev keys, hardened containers, and nothing published on the host.
systemd servicesA host that runs APF next to an OpenShell gateway.Production-oriented. Caller authentication and TLS are required.

Make sure you meet the Prerequisites before you start.

Build APF

Clone the repository and build the three binaries:

git clone https://github.com/NVIDIA/agent-policy-fabric.git apf
cd apf
cargo build --release -p apf-policy-service -p apf-policy-gateway -p apf-compile

The binaries land in target/release/. The first build downloads the pinned Rust toolchain and compiles the committed protobuf sources with protoc.

Set an Audit Directory

Both services refuse to start without an audit log directory, because they enforce policy and must record what they did. Each service reads the directory from --audit-log-dir or the APF_AUDIT_LOG_DIR environment variable and creates it if it is missing.

The native development task, mise run dev-native, and the sample service configuration in the repository do not set an audit directory yet. Set APF_AUDIT_LOG_DIR yourself for native processes as shown below. The container stack sets the audit directory for you. Refer to The Shipped Configurations Do Not Start.

Run APF

Run both services as background processes. Their sockets, counter store, and audit files live under $APF_HOME, so later pages can find them from any terminal. These commands follow the repository’s dev-native task, with an audit directory added and the gateway flags it no longer accepts removed.

export APF_HOME="$HOME/apf-dev"
export SOCK_DIR="$APF_HOME/run"
export APF_AUDIT_LOG_DIR="$APF_HOME/audit"
mkdir -p "$SOCK_DIR"
./target/release/apf-policy-service serve \
--socket "$SOCK_DIR/policy-service.sock" \
--http-addr 127.0.0.1:19200 \
--http-bearer-token-file examples/dev-keys/http-bearer-token.dev \
--bundle-path examples/demo-bundle/demo-bundle.yaml \
--trust-root-dir examples/dev-keys \
--counter-store "$SOCK_DIR/counter" \
--document-key-id apf-dev \
--document-signing-key examples/dev-keys/apf-dev.seed \
--policy-source local &
until curl -sf http://127.0.0.1:19200/healthz >/dev/null; do sleep 0.2; done
./target/release/apf-policy-gateway \
--socket "$SOCK_DIR/policy-gateway.sock" \
--policy-service-socket "$SOCK_DIR/policy-service.sock" \
--document-key-id apf-dev \
--jwks-url http://127.0.0.1:19200/.well-known/jwks.json \
--openshell-interceptor-addr 127.0.0.1:18202 \
--openshell-interceptor-allow-insecure-transport \
--openshell-middleware-addr 127.0.0.1:9099 \
--openshell-middleware-allow-insecure-transport &

The gateway starts after the policy service is healthy because it connects to the policy service socket and fetches the policy set at startup. It logs a warning for each OpenShell listener that runs without TLS or caller authentication. Stop both services with kill %1 %2, or close the shell.

The counter store in $SOCK_DIR/counter remembers the highest bundle revision the policy service accepted, so a restart with an older bundle is refused. To start over from the demo bundle, stop both services and delete $APF_HOME.

mise run dev-native does not work on main yet. It passes --trust-root-dir and --counter-store to apf-policy-gateway, which no longer accepts them, and it does not set an audit directory. Refer to The Shipped Configurations Do Not Start.

Set Up Each Terminal

The walkthroughs that follow assume the native processes. They run commands from the repository root in more than one terminal. Run this in every new terminal so the paths resolve:

cd <path to your APF clone>
export APF_HOME="$HOME/apf-dev"
export SOCK_DIR="$APF_HOME/run"
export APF_AUDIT_LOG_DIR="$APF_HOME/audit"
export WORK="$HOME/apf-work"

WORK holds your own copy of the bundle, created in Your First Signed Policy.

Verify the Installation

These checks assume the native processes. With the container stack, mise run dev has already run equivalent checks in its smoke suite, and nothing is published on the host. To run a check yourself, run it inside the stack’s network namespace, for example docker compose -f deploy/docker/compose.yaml exec policy-service curl -s http://127.0.0.1:19200/healthz. The stack generates its own bearer token, at /etc/apf/secrets/http-bearer-token in the policy service container.

Check the policy service health and readiness. These routes need no token.

curl -s http://127.0.0.1:19200/healthz
curl -s http://127.0.0.1:19200/readyz
{"status":"ok","version":"0.1.0"}
{"status":"ok"}

Confirm the JWKS endpoint publishes the document signing key that the gateway uses to verify provenance tokens:

curl -s http://127.0.0.1:19200/.well-known/jwks.json

The response lists one OKP key with "crv":"Ed25519" and "kid":"apf-dev".

List the sandbox policy documents the service projects from the demo bundle. This route requires the HTTP bearer token:

curl -s -H "Authorization: Bearer $(cat examples/dev-keys/http-bearer-token.dev)" \
http://127.0.0.1:19200/v1/documents/openshell.sandbox.v1
{"names":["default"]}

Finally, confirm both services are writing audit records. With native processes:

ls "$APF_AUDIT_LOG_DIR"
apf-policy-gateway-audit.jsonl
apf-policy-gateway-interceptor-audit.jsonl
apf-policy-gateway-middleware-audit.jsonl
apf-policy-service-audit.jsonl

With the container stack, the files are in the apf-audit volume. The stack runs without the OpenShell listeners, so it writes only the policy service and gateway files:

docker compose -f deploy/docker/compose.yaml exec policy-gateway ls /var/log/apf/audit
apf-policy-gateway-audit.jsonl
apf-policy-service-audit.jsonl

The policy service file starts with a policy_service_startup record, a policy_verification record for the demo bundle, and a policy_activation record. Refer to Access Audit Events.

Next Steps

APF is running but nothing calls it yet. Continue with Add APF to OpenShell to register the interceptor and middleware with an OpenShell gateway.