Documentation
¶
Overview ¶
Package approval provides a transport-agnostic approval bridge for pausing framework operations until a host explicitly allows or denies them.
Canto owns the durable approval state machine, policy composition, and circuit-breaker plumbing. Hosts own product policy: which tools, arguments, users, paths, or command strings are safe enough to allow automatically. Use PolicyFunc for local deterministic policies, such as a command classifier in an interactive host. Return handled=false to leave the request for HITL resolution instead of forcing an automated allow or deny.
Index ¶
- Variables
- func DefaultClassifierPrompt(sess *session.Session, req Request) (string, error)
- type Chain
- type ClassifierPolicy
- type Decision
- type Gate
- func (m *Gate) IsTripped() bool
- func (m *Gate) Pending() []string
- func (m *Gate) Request(ctx context.Context, sess *session.Session, toolName string, args string, ...) (Result, error)
- func (m *Gate) ResetBreaker()
- func (m *Gate) Resolve(requestID string, decision Decision, reason string) error
- func (m *Gate) WithAuditLogger(logger audit.Logger) *Gate
- func (m *Gate) WithThreshold(n int) *Gate
- type Policy
- type PolicyFunc
- type Request
- type Requirement
- type Result
Examples ¶
Constants ¶
This section is empty.
Variables ¶
Functions ¶
Types ¶
type Chain ¶
type Chain []Policy
Chain composes multiple policies in order.
Later policies can override earlier ones by returning handled=true. If no policy handles the request, the chain returns handled=false.
type ClassifierPolicy ¶
type ClassifierPolicy struct {
// contains filtered or unexported fields
}
ClassifierPolicy uses an LLM classifier to make automated approval decisions.
func NewClassifierPolicy ¶
func NewClassifierPolicy(classifier llm.Classifier, labels []string) *ClassifierPolicy
NewClassifierPolicy creates a new policy backed by an LLM classifier.
func (*ClassifierPolicy) Decide ¶
func (p *ClassifierPolicy) Decide( ctx context.Context, sess *session.Session, req Request, ) (Result, bool, error)
Decide implements Policy.
func (*ClassifierPolicy) WithPromptBuilder ¶
func (p *ClassifierPolicy) WithPromptBuilder( builder func(*session.Session, Request) (string, error), ) *ClassifierPolicy
WithPromptBuilder configures a custom prompt builder for the classifier.
type Gate ¶
type Gate struct {
// contains filtered or unexported fields
}
Gate coordinates tool approval requests across automated policies and human-in-the-loop (HITL) resolution. It includes a circuit breaker that disables automated policies after N consecutive denials.
func (*Gate) ResetBreaker ¶
func (m *Gate) ResetBreaker()
ResetBreaker clears the circuit breaker state.
func (*Gate) WithAuditLogger ¶
WithAuditLogger configures an append-only security audit logger.
func (*Gate) WithThreshold ¶
WithThreshold configures the circuit breaker threshold.
type Policy ¶
type PolicyFunc ¶
PolicyFunc adapts a function into a Policy.
Example (ShellClassifierSeam) ¶
package main
import (
"context"
"fmt"
"strings"
"github.com/nijaru/canto/approval"
"github.com/nijaru/canto/session"
)
func main() {
// A host can provide this policy without Canto owning the
// command heuristics. The example is deliberately tiny: real products can
// parse POSIX shell, check cwd/path policy, and inspect user trust state.
shellPolicy := approval.PolicyFunc(
func(
ctx context.Context,
sess *session.Session,
req approval.Request,
) (approval.Result, bool, error) {
if req.Tool != "bash" {
return approval.Result{}, false, nil
}
if strings.HasPrefix(req.Resource, "git status") {
return approval.Result{
Decision: approval.DecisionAllow,
Reason: "host classifier allows read-only git status",
}, true, nil
}
return approval.Result{}, false, nil
},
)
manager := approval.NewGate(shellPolicy)
sess := session.New("s")
res, err := manager.Request(
context.Background(),
sess,
"bash",
`{"command":"git status --short"}`,
approval.Requirement{
Category: "execute",
Operation: "exec",
Resource: "git status --short",
},
)
fmt.Println(res.Decision, res.Automated, err == nil)
}
Output: allow true true