approval

package
v0.5.0 Latest Latest
Warning

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

Go to latest
Published: Mar 9, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package approval provides a unified interface for tool execution approval across multiple channels (Gateway WebSocket, Telegram, Discord, Slack, TTY).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ApprovalTargetFromContext

func ApprovalTargetFromContext(ctx context.Context) string

ApprovalTargetFromContext retrieves the approval routing target from the context. Returns empty string if no target is set.

func WithApprovalTarget

func WithApprovalTarget(ctx context.Context, target string) context.Context

WithApprovalTarget sets an explicit approval routing target in the context. This overrides the session key for approval routing, allowing automation systems (cron, background) to route approval requests to the originating channel.

Types

type ApprovalRequest

type ApprovalRequest struct {
	ID         string
	ToolName   string
	SessionKey string
	Params     map[string]interface{}
	Summary    string // Human-readable description of what the tool will do
	CreatedAt  time.Time
}

ApprovalRequest represents a request for tool execution approval.

type ApprovalResponse

type ApprovalResponse struct {
	Approved    bool
	AlwaysAllow bool
}

ApprovalResponse carries the result of an approval request.

type CompositeProvider

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

CompositeProvider routes approval requests to the appropriate provider based on session key prefix. Falls back to TTY, then denies (fail-closed). P2P sessions ("p2p:..." keys) use a dedicated fallback and are never routed to HeadlessProvider to prevent remote peers from auto-approving.

func NewCompositeProvider

func NewCompositeProvider() *CompositeProvider

NewCompositeProvider creates a new CompositeProvider.

func (*CompositeProvider) CanHandle

func (c *CompositeProvider) CanHandle(_ string) bool

CanHandle always returns true; CompositeProvider accepts all requests and routes internally.

func (*CompositeProvider) Register

func (c *CompositeProvider) Register(p Provider)

Register appends a provider to the routing chain.

func (*CompositeProvider) RequestApproval

func (c *CompositeProvider) RequestApproval(ctx context.Context, req ApprovalRequest) (ApprovalResponse, error)

RequestApproval routes the request to the first provider whose CanHandle returns true. P2P sessions ("p2p:..." keys) use a dedicated fallback instead of the TTY fallback to ensure HeadlessProvider never auto-approves remote peer requests. If no provider matches, denies (fail-closed).

func (*CompositeProvider) SetP2PFallback

func (c *CompositeProvider) SetP2PFallback(p Provider)

SetP2PFallback sets a dedicated approval provider for P2P sessions. P2P sessions are never routed to the TTY fallback when it is a HeadlessProvider, preventing remote peers from auto-approving.

func (*CompositeProvider) SetTTYFallback

func (c *CompositeProvider) SetTTYFallback(p Provider)

SetTTYFallback sets the TTY provider used when no other provider matches.

type GatewayApprover

type GatewayApprover interface {
	HasCompanions() bool
	RequestApproval(ctx context.Context, message string) (ApprovalResponse, error)
}

GatewayApprover abstracts the gateway.Server methods needed for approval.

type GatewayProvider

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

GatewayProvider routes approval requests to companion apps via WebSocket.

func NewGatewayProvider

func NewGatewayProvider(gw GatewayApprover) *GatewayProvider

NewGatewayProvider creates a GatewayProvider backed by the given gateway.

func (*GatewayProvider) CanHandle

func (g *GatewayProvider) CanHandle(_ string) bool

CanHandle returns true when at least one companion is connected.

func (*GatewayProvider) RequestApproval

func (g *GatewayProvider) RequestApproval(ctx context.Context, req ApprovalRequest) (ApprovalResponse, error)

RequestApproval sends the approval request to connected companions.

type GrantStore

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

GrantStore tracks per-session, per-tool "always allow" grants in memory. Grants are cleared on application restart (no persistence). An optional TTL causes grants to expire automatically.

func NewGrantStore

func NewGrantStore() *GrantStore

NewGrantStore creates an empty GrantStore with no TTL.

func (*GrantStore) CleanExpired

func (s *GrantStore) CleanExpired() int

CleanExpired removes all grants that have exceeded the TTL. Returns the number of entries removed. No-op when TTL is zero.

func (*GrantStore) Grant

func (s *GrantStore) Grant(sessionKey, toolName string)

Grant records an approval for the given session and tool.

func (*GrantStore) IsGranted

func (s *GrantStore) IsGranted(sessionKey, toolName string) bool

IsGranted reports whether the tool has a valid (non-expired) grant.

func (*GrantStore) Revoke

func (s *GrantStore) Revoke(sessionKey, toolName string)

Revoke removes a single tool grant for the given session.

func (*GrantStore) RevokeSession

func (s *GrantStore) RevokeSession(sessionKey string)

RevokeSession removes all grants for the given session.

func (*GrantStore) SetTTL

func (s *GrantStore) SetTTL(ttl time.Duration)

SetTTL sets the time-to-live for grants. Zero disables expiry.

type HeadlessProvider

type HeadlessProvider struct{}

HeadlessProvider auto-approves all tool execution requests. Intended for headless (Docker) environments where no TTY or companion is available. Every approval is logged at WARN level for audit.

func (*HeadlessProvider) CanHandle

func (h *HeadlessProvider) CanHandle(_ string) bool

CanHandle always returns false. HeadlessProvider is used as a TTY fallback slot, not prefix-matched by session key.

func (*HeadlessProvider) RequestApproval

func (h *HeadlessProvider) RequestApproval(_ context.Context, req ApprovalRequest) (ApprovalResponse, error)

RequestApproval always approves and logs a warning for audit trail.

type Provider

type Provider interface {
	// RequestApproval sends an approval request and blocks until approved/denied or context is cancelled.
	RequestApproval(ctx context.Context, req ApprovalRequest) (ApprovalResponse, error)

	// CanHandle reports whether this provider can handle the given session key.
	CanHandle(sessionKey string) bool
}

Provider defines the interface for approval request handling.

type TTYProvider

type TTYProvider struct{}

TTYProvider prompts the user via the terminal (stdin) for approval. CanHandle always returns false because TTY is a special fallback, not prefix-matched by session key.

func (*TTYProvider) CanHandle

func (t *TTYProvider) CanHandle(_ string) bool

CanHandle always returns false. TTY is used as a fallback only.

func (*TTYProvider) RequestApproval

func (t *TTYProvider) RequestApproval(_ context.Context, req ApprovalRequest) (ApprovalResponse, error)

RequestApproval prompts the user on stderr and reads y/a/N from stdin. "y" or "yes" approves once; "a" or "always" approves and grants persistent access for the tool in this session.

Jump to

Keyboard shortcuts

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