Skip to main content

Policies

Policies are YAML, evaluated deterministically and locally.

apiVersion: guard.unveilr.ai/v1alpha1
kind: Policy
metadata:
name: protect-production
spec:
rules:
- id: protect-iam
description: Agents may not perform dangerous IAM changes.
match:
action.provider: aws
action.name: [iam:PassRole, iam:AttachRolePolicy, iam:PutRolePolicy]
effect: deny

Effects

Ordered by increasing restriction:

EffectMeaning
allowForward the call
redactForward with matched content removed
sanitizeForward with content normalised
scoped_tokenSubstitute a narrowed credential
require_approvalHold pending a human decision
step_upDemand stronger authentication
denyRefuse

Some effects need infrastructure a local binary does not have. require_approval and step_up need somewhere to route the request and someone to answer it; scoped_token needs a broker. Locally these degrade rather than silently passing — see Open source vs Enterprise.

Combination is forbid-overrides

The most restrictive matching effect wins, so adding a policy can never widen access.

That property is worth internalising, because it makes policy composition safe to reason about: you never have to check whether a new rule accidentally unlocked something. It can only ever restrict further.

Unknown effects fail closed

An effect the binary does not recognise is resolved as the most restrictive effect it knows, not ignored.

This matters more than it sounds. A typo — denny for deny — becomes a block, not a silently skipped rule. And it is what makes it safe for a newer build to introduce an effect an older one has never heard of: the old build refuses rather than waving the call through.

Testing

unveilr policy test --server <id> --tool <name> --args '{"path":"/etc/passwd"}'

Deterministic, needs no agent, and is the intended way to develop a policy. There is no model in the decision path, so a test result is the decision you will get in production against the same inputs.

Schema stability

apiVersion: guard.unveilr.ai/v1alpha1. Pre-1.0, and may change before 1.0 — breaking changes are documented. The v1alpha1 suffix is the honest signal, not a formality.