Skip to content

Project policy demo

This is a complete, realistic project-scoped policy workspace for the local LLM Content Moderation project. It contains two custom Rust/WASM plugins:

  • custom.project.model_boundary is an enforcement plugin on proxy.pre. It reads the request body through the bounded request.body.read host capability and rejects providers or models outside the project’s allowlist.
  • custom.project.usage_observer is an observe-only plugin on request.end. It never blocks traffic and emits a project.model_usage event tagged with the provider, model, outcome, and agent ID.

guardian.config.toml combines them with the required project membership bootstrap and the existing authorization gate. The project is selected by its human name; the CLI resolves and prints its canonical UUID/URN before using the project-scoped Gateway APIs.

From the repository root:

Terminal window
cargo build -p guardian-plugin
cd docs/examples/project-policy-demo
CLI=../../../target/debug/guardian-plugin
MODEL=plugins/model-boundary/guardian.plugin.toml
OBSERVER=plugins/usage-observer/guardian.plugin.toml
MEMBERSHIP=builtins/project-membership/guardian.plugin.toml
AUTHORIZATION=builtins/authorization/guardian.plugin.toml
$CLI --manifest "$MODEL" build
$CLI --manifest "$MODEL" validate
$CLI --manifest "$OBSERVER" build
$CLI --manifest "$OBSERVER" validate

These commands are local only. Validation prints each artifact digest and the Guardian host imports found in the binary. The enforcement plugin should import guardian_host_read_request_body_v1; the observer intentionally has no host capability imports.

The digests currently recorded in guardian.config.toml are from these exact sources. If you edit either plugin, copy the new artifact_sha256 printed by validate into that plugin’s configuration entry before planning.

For the current Zsh session:

Terminal window
autoload -Uz compinit
compinit
eval "$($CLI completion zsh)"

For the current Bash session:

Terminal window
eval "$($CLI completion bash)"

Once guardian-plugin is on PATH, the corresponding eval line can be added to .zshrc or .bashrc using guardian-plugin in place of $CLI. Completion covers commands, nested configuration operations, global flags, option values, and manifest paths directly from the same Clap command definition used by the CLI.

2. Publish definitions without changing project state

Section titled “2. Publish definitions without changing project state”

When using the repository local stack, obtain the same token used by the local Console and export it for guardian-plugin:

Terminal window
eval "$(../../../scripts/local-govstudio-stack.sh token)"

For another deployment, set GUARDIAN_CONTROL_PLANE_TOKEN to an appropriate control-plane bearer token directly.

Then ensure the two premade definitions and publish each custom package:

Terminal window
$CLI --manifest "$MEMBERSHIP" publish
$CLI --manifest "$AUTHORIZATION" publish
$CLI --manifest "$MODEL" publish
$CLI --manifest "$OBSERVER" publish

For premade plugins, publish validates the manifest and ensures the builtin definition without an artifact upload. For custom plugins, it builds and validates the WASM, uploads the immutable artifact, and ensures its definition. Every invocation prints configuration_state=unchanged: it does not create a global draft and it does not create or activate a project configuration. Publishing all four definitions first makes the complete desired configuration resolvable during validation and planning, including on a fresh local stack.

From the repository root, scripts/local-govstudio-stack.sh plugin-smoke automates both publishes plus configuration validation and planning. It intentionally never applies the plan.

3. Validate and plan the exact project scope

Section titled “3. Validate and plan the exact project scope”

Use either plugin manifest for the Control Plane connection; the configuration file contains the complete desired state:

Terminal window
$CLI \
--manifest "$MODEL" \
--configuration-manifest guardian.config.toml \
configuration validate
$CLI \
--manifest "$MODEL" \
--configuration-manifest guardian.config.toml \
configuration plan --detailed-exitcode

The detailed plan exits 2 when it finds changes and 0 when the exact project scope already matches. It should show additions for the two custom plugins while leaving the global configuration out of the comparison.

For machine-readable output, add the global options before configuration:

Terminal window
$CLI --output json --no-color \
--manifest "$MODEL" \
--configuration-manifest guardian.config.toml \
configuration plan

No apply is performed by this demo setup. To review the plan and approve it interactively yourself:

Terminal window
$CLI \
--manifest "$MODEL" \
--configuration-manifest guardian.config.toml \
configuration apply

Afterward, these commands inspect only the same resolved project scope:

Terminal window
$CLI --manifest "$MODEL" --configuration-manifest guardian.config.toml configuration show
$CLI --manifest "$MODEL" --configuration-manifest guardian.config.toml configuration history --limit 10
$CLI --manifest "$MODEL" --configuration-manifest guardian.config.toml configuration rollback

The legacy deploy command remains available for compatibility, but it creates a global draft configuration. For this project-first workflow, use publish for artifacts/definitions and configuration for all desired-state operations.