Documentation
¶
Overview ¶
Package approval provides a unified interface for tool execution approval across multiple channels (Gateway WebSocket, Telegram, Discord, Slack, TTY).
Index ¶
- func ApprovalTargetFromContext(ctx context.Context) string
- func WithApprovalTarget(ctx context.Context, target string) context.Context
- type ApprovalRequest
- type ApprovalResponse
- type CompositeProvider
- func (c *CompositeProvider) CanHandle(_ string) bool
- func (c *CompositeProvider) Register(p Provider)
- func (c *CompositeProvider) RequestApproval(ctx context.Context, req ApprovalRequest) (ApprovalResponse, error)
- func (c *CompositeProvider) SetP2PFallback(p Provider)
- func (c *CompositeProvider) SetTTYFallback(p Provider)
- type GatewayApprover
- type GatewayProvider
- type GrantStore
- func (s *GrantStore) CleanExpired() int
- func (s *GrantStore) Grant(sessionKey, toolName string)
- func (s *GrantStore) IsGranted(sessionKey, toolName string) bool
- func (s *GrantStore) Revoke(sessionKey, toolName string)
- func (s *GrantStore) RevokeSession(sessionKey string)
- func (s *GrantStore) SetTTL(ttl time.Duration)
- type HeadlessProvider
- type Provider
- type TTYProvider
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ApprovalTargetFromContext ¶
ApprovalTargetFromContext retrieves the approval routing target from the context. Returns empty string if no target is set.
func WithApprovalTarget ¶
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 ¶
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.