-
Notifications
You must be signed in to change notification settings - Fork 0
docs: add embedded policy enforcement guide for local PDP #34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,179 @@ | ||||||||||||||||||
| --- | ||||||||||||||||||
| title: Embedded Policy Enforcement | ||||||||||||||||||
| description: How to use the local PDP for in-process policy evaluation in your agents. | ||||||||||||||||||
| --- | ||||||||||||||||||
|
|
||||||||||||||||||
| # Embedded Policy Enforcement | ||||||||||||||||||
|
|
||||||||||||||||||
| The **Local Policy Decision Point (PDP)** evaluates policy decisions inside your agent process — no external service calls needed. It pulls policy bundles from the CapiscIO registry and evaluates them using an embedded [OPA](https://www.openpolicyagent.org/) engine. | ||||||||||||||||||
|
|
||||||||||||||||||
| ## Why Embedded? | ||||||||||||||||||
|
|
||||||||||||||||||
| | Feature | Remote PDP | Local PDP | | ||||||||||||||||||
| |---------|-----------|-----------| | ||||||||||||||||||
| | Latency | Network round-trip per decision | Sub-millisecond | | ||||||||||||||||||
| | Availability | Depends on network | Always available | | ||||||||||||||||||
| | Offline support | ❌ | ✅ (last-known-good policy) | | ||||||||||||||||||
| | Setup | API calls | 3 environment variables | | ||||||||||||||||||
|
|
||||||||||||||||||
| ## Quick Start (Go) | ||||||||||||||||||
|
|
||||||||||||||||||
| ### Environment Variables | ||||||||||||||||||
|
|
||||||||||||||||||
| Set these in your agent's environment: | ||||||||||||||||||
|
|
||||||||||||||||||
| ```bash | ||||||||||||||||||
| export CAPISCIO_BUNDLE_URL=https://api.capisc.io/v1/bundles/<your-org-id> | ||||||||||||||||||
| export CAPISCIO_API_KEY=<your-api-key> | ||||||||||||||||||
| export CAPISCIO_ENFORCEMENT_MODE=EM-OBSERVE # Start in observe mode | ||||||||||||||||||
| ``` | ||||||||||||||||||
|
|
||||||||||||||||||
| ### Initialize the PDP | ||||||||||||||||||
|
|
||||||||||||||||||
| ```go | ||||||||||||||||||
| import "github.com/capiscio/capiscio-core/v2/pkg/pdp" | ||||||||||||||||||
|
|
||||||||||||||||||
| // One-line setup from environment variables | ||||||||||||||||||
| localPDP, err := pdp.NewLocalPDPFromEnv(ctx) | ||||||||||||||||||
| if err != nil { | ||||||||||||||||||
| log.Fatal(err) | ||||||||||||||||||
| } | ||||||||||||||||||
| defer localPDP.Stop() | ||||||||||||||||||
|
|
||||||||||||||||||
| // localPDP.Client implements pip.PDPClient | ||||||||||||||||||
| // localPDP.Manager handles background refresh | ||||||||||||||||||
| ``` | ||||||||||||||||||
|
|
||||||||||||||||||
| ### Evaluate a Policy Decision | ||||||||||||||||||
|
|
||||||||||||||||||
| ```go | ||||||||||||||||||
| import "github.com/capiscio/capiscio-core/v2/pkg/pip" | ||||||||||||||||||
|
|
||||||||||||||||||
| resp, err := localPDP.Client.Evaluate(ctx, &pip.DecisionRequest{ | ||||||||||||||||||
| PIPVersion: pip.PIPVersion, | ||||||||||||||||||
| Subject: pip.SubjectAttributes{ | ||||||||||||||||||
| DID: incomingAgent.DID, | ||||||||||||||||||
| TrustLevel: incomingAgent.Badge.TrustLevel, | ||||||||||||||||||
| }, | ||||||||||||||||||
| Action: pip.ActionAttributes{ | ||||||||||||||||||
| Operation: "message/send", | ||||||||||||||||||
| }, | ||||||||||||||||||
| Resource: pip.ResourceAttributes{ | ||||||||||||||||||
| Identifier: "my-agent", | ||||||||||||||||||
| }, | ||||||||||||||||||
| Context: pip.ContextAttributes{ | ||||||||||||||||||
| EnforcementMode: "EM-OBSERVE", | ||||||||||||||||||
| }, | ||||||||||||||||||
| }) | ||||||||||||||||||
|
|
||||||||||||||||||
| if resp.Decision == "deny" { | ||||||||||||||||||
|
||||||||||||||||||
| if resp.Decision == "deny" { | |
| if resp.Decision == "DENY" { |
Copilot
AI
Mar 22, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This staleness section omits EM-DELEGATE, even though it’s listed as a supported mode above. For consistency with the enforcement-mode reference (and the existing Policy Enforcement docs), document EM-DELEGATE staleness behavior explicitly (it likely matches EM-GUARD if it’s fail-open on bundle staleness).
| - **EM-OBSERVE / EM-GUARD**: Continue evaluating with the last-known-good bundle | |
| - **EM-OBSERVE / EM-GUARD / EM-DELEGATE**: Continue evaluating with the last-known-good bundle |
Copilot
AI
Mar 22, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Env var names here (CAPISCIO_POLL_INTERVAL, CAPISCIO_MAX_AGE) differ from the existing embedded-PDP docs (CAPISCIO_BUNDLE_POLL_INTERVAL, CAPISCIO_BUNDLE_STALENESS_THRESHOLD). If these are the same concepts, consider aligning the names or adding a short note clarifying why the local PDP uses different variables to avoid reader confusion.
| !!! note | |
| In other embedded-PDP documentation you may see the variables | |
| `CAPISCIO_BUNDLE_POLL_INTERVAL` and `CAPISCIO_BUNDLE_STALENESS_THRESHOLD` | |
| used for bundle polling frequency and staleness. In the local in-process PDP, | |
| these concepts are configured via `CAPISCIO_POLL_INTERVAL` and | |
| `CAPISCIO_MAX_AGE` as shown above. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the Go example,
respis used without checkingerrfirst. Please show error handling (and ideally a nilrespcheck) before inspecting the decision, so readers don’t copy a panic-prone pattern.