approval

package
v0.3.1 Latest Latest
Warning

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

Go to latest
Published: Aug 2, 2026 License: Apache-2.0 Imports: 13 Imported by: 0

Documentation

Index

Constants

View Source
const (
	ModeStrict   = permission.ModeStrict
	ModeBalanced = permission.ModeBalanced
	ModeAuto     = permission.ModeAuto
	ModeTrust    = permission.ModeTrust
)
View Source
const (
	ChoiceAllowOnce    = permission.ChoiceAllowOnce
	ChoiceAllowSession = permission.ChoiceAllowSession
	ChoiceAllowAlways  = permission.ChoiceAllowAlways
	ChoiceDeny         = permission.ChoiceDeny
)

Variables

This section is empty.

Functions

func CheckDangerousPath added in v0.1.3

func CheckDangerousPath(workspace string, req permission.Request) string

CheckDangerousPath classifies a permission request's target path:

reason != ""  → force-ask. Mode auto-pass and stored approvals are
                bypassed; the approver is invoked with the "restricted"
                option set (Allow Once / Deny only). Two flavours of
                path qualify:

                  leak-class (read or write): SSH keys, AWS / gcloud
                  credentials, .netrc, .pgpass — auto-allowing once
                  would let later turns silently re-read them.

                  implant-class (write only): shell rc, .git/hooks,
                  .gitconfig, .mcp.json, .claude.json, .ssh / .aws /
                  .gnupg dirs, IDE & agent loader configs. A single
                  Allow Always would propagate the implant forever.

reason == ""  → clean. The request falls through to the regular
                permission pipeline.

We deliberately do NOT hard-deny anything: the model is cooperative, the user can see the prompt, and a one-time Allow Once is a fine answer to "yes, look at my ~/.ssh/config to debug auth". The cost of asking is one click; the cost of a wrong hard-deny is the user can't get help at all.

All comparisons are case-insensitive (macOS / Windows filesystems collapse case) and check both the raw user-supplied path AND the symlink-resolved path. Both forms are needed because dotfiles can be symlinked in either direction:

~/.bashrc → ~/dotfiles/bashrc  (chezmoi / stow):
  raw matches forceAskBasenames[".bashrc"];
  resolved would miss (.bashrc basename gone).

project/innocent → /etc/passwd  (attacker):
  raw would miss;
  resolved catches the real target.

func DestructiveCommandWarning added in v0.1.3

func DestructiveCommandWarning(cmd string) string

DestructiveCommandWarning returns a short warning string when cmd matches a known destructive pattern, or "" otherwise. The returned phrase is the noun phrase only (e.g. "may overwrite remote history") — the caller adds any label / icon / styling. Returns the FIRST match, so order patterns from most specific to least.

Types

type ApproverFunc

type ApproverFunc = permission.Approver

type AuditEntry

type AuditEntry = permission.AuditEntry

type Capability

type Capability = permission.Capability

type Choice

type Choice = permission.Choice

type CommandCategory

type CommandCategory string
const (
	CommandCategoryInfo    CommandCategory = "info"
	CommandCategoryPrompt  CommandCategory = "prompt"
	CommandCategorySession CommandCategory = "session"
	CommandCategoryConfig  CommandCategory = "config"
	CommandCategoryPlan    CommandCategory = "plan"
	CommandCategoryExit    CommandCategory = "exit"
)

func NormalizeCommandCategory

func NormalizeCommandCategory(raw string) CommandCategory

type CommandRequest

type CommandRequest struct {
	Name      string
	Category  CommandCategory
	NeedsIdle bool
	IsRunning bool
	Summary   string
	Preview   string
}

type Engine

type Engine struct {
	// contains filtered or unexported fields
}

func NewEngine

func NewEngine(cwd string, mode Mode, rules *RuleSet, onAudit func(AuditEntry)) (*Engine, error)

func (*Engine) ApproveCommand

func (e *Engine) ApproveCommand(_ context.Context, req CommandRequest) error

func (*Engine) ApproveHook

func (e *Engine) ApproveHook(ctx context.Context, req HookRequest) error

func (*Engine) AsToolGate added in v0.1.3

func (e *Engine) AsToolGate() agentcore.ToolGate

AsToolGate adapts the approval Engine to agentcore.ToolGate. The kernel is permission-agnostic; the harness owns the policy.

The adapter extracts permission.Metadata from the tool when the tool implements the optional PermissionMetadata accessor — this keeps the kernel independent of the permission package while letting harness tools advertise their capability/key/summary hints.

func (*Engine) Decide added in v0.1.0

func (e *Engine) Decide(ctx context.Context, req permission.Request) (*permission.Decision, error)

Decide routes a tool permission request. Two tools are intercepted before the agentcore engine runs: exit_plan_mode in plan mode is surfaced through the standard approver path with the plan content as preview, and ask_user runs its question dialog here with the answers returned via UpdatedArgs. Dangerous paths (credential files, shell rc, .git/hooks, IDE/agent loader configs, ...) bypass mode auto-pass and stored approvals; the approver is invoked with Allow Once / Deny only so a single Allow Always cannot turn into a persistent backdoor. Nothing is hard-denied — the model is cooperative and the user is in the loop.

All other tools delegate to the agentcore permission engine.

func (*Engine) FilesystemRoots added in v0.3.0

func (e *Engine) FilesystemRoots() FilesystemRoots

FilesystemRoots returns the engine's current read/write roots, letting a caller capture them before a temporary change (e.g. entering a worktree) and restore them afterwards.

func (*Engine) Mode

func (e *Engine) Mode() Mode

func (*Engine) PlanMode

func (e *Engine) PlanMode() bool

func (*Engine) SetApprover

func (e *Engine) SetApprover(fn ApproverFunc)

func (*Engine) SetFilesystemRoots

func (e *Engine) SetFilesystemRoots(roots FilesystemRoots)

func (*Engine) SetInteract added in v0.3.0

func (e *Engine) SetInteract(fn InteractFunc)

SetInteract installs the UI callback that runs ask_user dialogs. Headless runs leave it nil; the tool then executes without a backfilled response and degrades to its "make your best judgment" text.

func (*Engine) SetMode

func (e *Engine) SetMode(mode Mode)

func (*Engine) SetPlanContentProvider added in v0.1.3

func (e *Engine) SetPlanContentProvider(fn func() (string, error))

SetPlanContentProvider registers a callback that returns the current plan file content. The plan-exit interception in Decide reads from it to surface the plan in the approval prompt's preview field. plan.Manager wires this on enter / clears it on exit.

func (*Engine) SetPlanMode

func (e *Engine) SetPlanMode(active bool)

func (*Engine) SetSkillAllows

func (e *Engine) SetSkillAllows(rawTools []string)

type FilesystemRoots

type FilesystemRoots = permission.FilesystemRoots

type HookRequest

type HookRequest struct {
	Event    string
	Tool     string
	Command  string
	Blocking bool
}

type InteractFunc added in v0.3.0

type InteractFunc func(ctx context.Context, args json.RawMessage) (updated json.RawMessage, err error)

InteractFunc collects a user interaction for a tool call at gate time and returns the call's arguments with the outcome backfilled (ask_user answer injection). A nil updated value with a nil error means no interaction took place — the call proceeds with its original arguments and the tool's own degraded path explains why. The engine stays format-agnostic: parsing the questions and building the backfill both live with the UI / tool side.

type Mode

type Mode = permission.Mode

func ParseMode

func ParseMode(raw string) (Mode, error)

type Prompt

type Prompt = permission.Prompt

type Rule

type Rule = permission.Rule

type RuleSet

type RuleSet = permission.RuleSet

func ParseRuleSet

func ParseRuleSet(allow, deny []string) (*RuleSet, error)

Jump to

Keyboard shortcuts

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