policyguard

package
v0.1.160 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 13, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package policyguard wraps a toolboxv0.ToolboxServer with policy decision point (PDP) enforcement. Every CallTool request hits the PDP first; a deny short-circuits with the PDP's reason as a tool- level error (NOT a transport error — the model should be able to see and reason about the refusal).

Three-layer defense recap:

  1. canonical registry — refuses commands routed to other toolboxes
  2. policy guard (this package) — refuses tool calls per policy
  3. OS sandbox — refuses syscalls outside the manifest's grant

The PDP layer is BETWEEN the canonical registry (which decides "should this be in this toolbox?") and the OS sandbox (which decides "can this syscall happen?"). It's the layer that says "even though git owns this and even though the sandbox would allow it, the operator's policy doesn't allow this caller to invoke it right now."

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Guard

type Guard struct {
	toolboxv0.UnimplementedToolboxServer
	// contains filtered or unexported fields
}

Guard wraps a ToolboxServer with PDP enforcement. Identity / ListTools / list-style RPCs pass through unmolested — those are "what does this toolbox claim it can do" and don't mutate state. CallTool, ReadResource, and GetPrompt pass through the PDP because they're side-effecting (or at least information-disclosing).

func New

func New(inner toolboxv0.ToolboxServer, pdp policy.PDP, toolboxName string) *Guard

New wraps inner. If pdp is nil, an AllowAllPDP is substituted — the wrapper is then a no-op. This makes Guard always-safe-to- install: code paths that haven't migrated their config to a real PDP get the same behavior they had before.

Without scoped-auth wiring, every CallTool consults the PDP. To enable the two-level scoped-auth fast path, use NewWithScopedAuth or set the secret/audience via the With* helpers.

func NewWithScopedAuth added in v0.1.160

func NewWithScopedAuth(inner toolboxv0.ToolboxServer, pdp policy.PDP, toolboxName string, secret []byte, audienceID string) *Guard

NewWithScopedAuth is the explicit constructor for the two-level model: pdp is the inner enforcer (defense layer 2), secret is the HMAC key for verifying gateway tokens (defense layer 1).

audienceID should be the plugin's canonical identity ("publisher/name:version"); tokens minted for a different audience are rejected.

func (*Guard) CallTool

CallTool is the load-bearing authorization gate. Two paths:

  1. **Fast path** (when scoped-auth is wired AND a token rides on the request): verify the token's signature, expiry, audience, action, resource, and caveats. Valid → trust the gateway's pre-evaluation, stamp the verified ScopedAuthorization on ctx for handler visibility, dispatch to inner. The PDP is NOT consulted on this path.

  2. **Defense path** (when scoped-auth is unwired OR token is missing/invalid): full PDP evaluation. Same behavior as the one-level model. Token-invalid logs a warning so operators see "scoped-auth verify failed" events without breaking the call (the PDP catches abuse).

Refused calls return a CallToolResponse with the deny reason in Error — the SAME envelope a tool that refused itself would produce. The model sees an actionable refusal, not a transport error or a panic-style disconnect.

func (*Guard) DescribeTool added in v0.1.158

DescribeTool is the per-tool spec half of the two-phase API. Same trust class as ListTools — pass through unmolested. The PDP gates the actual side-effecting RPC (CallTool) below; describing a tool is not itself a privileged operation.

func (*Guard) GetPrompt

GetPrompt is also gated — prompts may template in private context (paths, secrets) that the operator wants to deny per caller.

func (*Guard) Identity

func (*Guard) ListPrompts

func (*Guard) ListToolSummaries added in v0.1.158

ListToolSummaries is the lightweight catalog half of the two-phase API. Same trust class as ListTools — pass through unmolested.

func (*Guard) ListTools

func (*Guard) ReadResource

ReadResource is policy-gated for the same reason CallTool is — the resource URI may name a sensitive file the operator wants to keep out of agent context. PDP key for ReadResource: Tool is the URI string. Rules can match on the URI prefix via the suffix-match shorthand (e.g. Tool="config.yaml" matches any URI ending in /config.yaml).

func (*Guard) WithAudience added in v0.1.160

func (g *Guard) WithAudience(audienceID string) *Guard

WithAudience binds the verifier to a specific audience identity. Tokens whose audience doesn't match are rejected.

func (*Guard) WithCaveatVerifiers added in v0.1.160

func (g *Guard) WithCaveatVerifiers(verifiers map[string]policy.CaveatVerifier) *Guard

WithCaveatVerifiers registers caveat verifiers consulted at token-verify time. Unknown caveat keys reject by default; register only the keys the operator's tool policies produce.

func (*Guard) WithIdentity

func (g *Guard) WithIdentity(identity map[string]any) *Guard

WithIdentity attaches a constant attribution map to every PDP request this Guard makes. Useful when the host knows it's wrapping a toolbox for a specific agent or session.

func (*Guard) WithScopedAuthSecret added in v0.1.160

func (g *Guard) WithScopedAuthSecret(secret []byte) *Guard

WithScopedAuthSecret replaces the verifier secret (e.g. for rotation). Returns the receiver for chaining.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL