policy

package
v0.8.59 Latest Latest
Warning

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

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

Documentation

Overview

Package policy is the action-gate's auto-approve layer (docs/action-gate-spec.md §"Policy layer"). The default posture is prompt-everything; an operator opts INTO automation by adding scoped, expiring, counted auto-approve rules for a specific link (from→to→topic) + action-type. Two hard guarantees:

  • Destructive actions are NEVER auto-approved — Consume filters on the request's Tier, so no rule can become a wipe-the-drive bypass.
  • Rules are bounded (count + TTL) and revocable; creating/removing one is privileged and ledgered by the caller (a blanket auto-approve is itself a bypass vector).

It imports internal/link for ActionRequest/Tier; link must not import this package (the api layer wires the two together).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Rule

type Rule struct {
	From      string    `json:"from"`
	To        string    `json:"to"`
	Action    string    `json:"action"`
	MaxCount  int       `json:"max_count"` // <=0 = unlimited within the TTL window
	Used      int       `json:"used"`
	ExpiresAt time.Time `json:"expires_at,omitempty"` // zero = no expiry
	CreatedAt time.Time `json:"created_at"`
	CreatedBy string    `json:"created_by,omitempty"`
}

Rule auto-approves a specific action-type over a link (from→to), up to MaxCount times, until ExpiresAt. It is topic-agnostic: the link grant (which is per-topic) already gates which channels exist, so the operator-facing rule is scoped to the meaningful unit — the link + action-type. It never covers destructive actions (enforced at Consume — the tier is a property of each request, not the rule).

func Consume

func Consume(ar link.ActionRequest) (Rule, bool, error)

Consume finds a live rule that auto-approves ar and spends one unit of its budget (persisted), returning the rule + true. It returns false — meaning the caller must queue the action for human approval — when no rule matches, the matching rule is expired/exhausted, OR the action is destructive (which no rule may ever auto-approve). Expired matches are pruned.

func (Rule) Key

func (r Rule) Key() string

Key is the rule's unique identity (from, to, action).

func (Rule) Remaining

func (r Rule) Remaining() int

Remaining is the budget left (-1 = unlimited within the TTL).

type Store

type Store struct {
	Rules map[string]Rule `json:"rules"`
}

Store is the per-daemon set of auto-approve rules. Persisted atomically; mirrors internal/link's grant store.

func Load

func Load() (*Store, error)

Load returns a consistent snapshot of the store (empty when none exists yet).

func Update

func Update(fn func(*Store) error) (*Store, error)

Update runs fn against the store under a process-wide lock and persists the result atomically. Use it for every read-modify-write.

func (*Store) Add

func (s *Store) Add(r Rule, ttl time.Duration) Rule

Add inserts or replaces a rule (keyed by from/to/topic/action), stamping CreatedAt and computing ExpiresAt from ttl (ttl<=0 = no expiry). Used resets.

func (*Store) List

func (s *Store) List() []Rule

List returns every rule (newest first), pruning expired ones as it goes.

func (*Store) Remove

func (s *Store) Remove(from, to, action string) bool

Remove deletes a rule by its parts. Returns false when no such rule exists.

Jump to

Keyboard shortcuts

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