ruleexec

package
v0.1.0 Latest Latest
Warning

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

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

Documentation

Index

Constants

View Source
const (
	DefaultMaxSteps      = 10000
	DefaultMaxIterations = 1000
	DefaultMaxDepth      = 64
	DefaultMaxNesting    = 64
)

Default budgets (to be published with the scheme spec; see docs/database-scheme-design.md §7).

Variables

This section is empty.

Functions

func CheckStaticBounds

func CheckStaticBounds(f Flow, b *Budget) error

CheckStaticBounds walks a flow BEFORE execution and enforces two zero-cost structural rules:

  1. loop nesting is forbidden (a while/for must not appear inside another loop, even transitively through if/retry/seq) -- this eliminates iteration-explosion by construction;
  2. statically-visible loop/retry bounds must fit the budget.

if <-> while nesting remains allowed (if inside a loop, or a loop inside an if branch).

func EvalCondition

func EvalCondition(c Condition, ctx map[string]any, b *Budget, depth int) (bool, error)

EvalCondition evaluates a condition against a context map with a budget. Depth is tracked to prevent nesting-based abuse.

func GenSignerCert

func GenSignerCert(dir string) (certPath, keyPath string, cert *x509.Certificate, err error)

GenSignerCert creates a self-signed signer certificate and key for rule signing (PKCS#7). Returns PEM file paths and the parsed cert.

func GenerateSelectSQL

func GenerateSelectSQL(raw json.RawMessage) (string, error)

GenerateSelectSQL renders the MySQL SQL for a database-v1 query:SELECT rule (v1 contract: exactly one table). The params must already have passed Validate (rule.go); this function is the "translator" that turns the structured contract into SQL.

func MapHTTPRequest

func MapHTTPRequest(ctx *pki.PluginContext) map[string]any

MapHTTPRequest converts gateway-core PluginContext facts (including the optional HTTP request fields) into the request map consumed by rule conditions: request.method / request.path / request.query / request.headers plus target/client_cn/agent_id/roles.

HTTP-facing gateways populate ctx.Method/Path/Query/Headers; the TCP admission path only provides Target/ClientCN/Roles/AgentId.

func PublishManifestJSON

func PublishManifestJSON(m *PublishManifest) (string, error)

PublishManifestJSON renders the manifest for output.

func RegisterRulePluginsFromDir

func RegisterRulePluginsFromDir(reg *pki.PluginRegistry, dir string, trustRoots []*x509.Certificate, handler OpHandler) ([]string, error)

RegisterRulePluginsFromDir loads signed rules from a published rule directory (outDir/<scheme>/default.json [+ .p7s], as produced by PublishRules) and registers one RulePlugin per scheme into reg. Returns the registered scheme list. Any signature or validation failure aborts the whole registration (fail-closed).

func RunFlow

func RunFlow(f Flow, ctx *FlowContext, b *Budget) error

RunFlow executes a flow with the given budget.

func ValidateStructure

func ValidateStructure(r *Rule) error

ValidateStructure performs schema-level validation of a rule: field formats, condition operators, flow step kinds and nesting.

Types

type Budget

type Budget struct {
	MaxSteps      int64
	MaxIterations int64
	MaxDepth      int
	MaxNesting    int
	Deadline      time.Time
	// contains filtered or unexported fields
}

Budget enforces the execution budget for conditions and flows.

func BudgetFromDefaults

func BudgetFromDefaults(d *BudgetDefaults) *Budget

BudgetFromDefaults builds a Budget from published defaults.

func NewBudget

func NewBudget() *Budget

NewBudget returns a budget with the specification defaults.

func (*Budget) Enter

func (b *Budget) Enter(depth int) error

Enter tracks recursion/nesting depth.

func (*Budget) Exit

func (b *Budget) Exit()

Exit leaves a nesting level.

func (*Budget) Iteration

func (b *Budget) Iteration() error

Iteration charges one loop iteration (accumulated across all loops).

func (*Budget) Iterations

func (b *Budget) Iterations() int64

Iterations returns the current iteration count.

func (*Budget) Stats

func (b *Budget) Stats() (steps, iterations int64)

Stats returns the current counters (for audit output).

func (*Budget) Step

func (b *Budget) Step() error

Step charges one execution step.

func (*Budget) Steps

func (b *Budget) Steps() int64

Steps returns the current step count.

type BudgetDefaults

type BudgetDefaults struct {
	MaxSteps      int   `json:"max_steps"`
	MaxIterations int   `json:"max_iterations"`
	MaxDepth      int   `json:"max_depth"`
	MaxNesting    int   `json:"max_nesting"`
	WallClockMs   int64 `json:"wall_clock_ms"`
}

BudgetDefaults is the published execution budget, distributed with the scheme spec (see budget-defaults.json and docs/database-scheme-design.md §7). Implementations MUST NOT relax these values.

func LoadBudgetDefaults

func LoadBudgetDefaults(path string) (*BudgetDefaults, error)

LoadBudgetDefaults reads a published budget-defaults.json.

type BudgetError

type BudgetError struct {
	Kind BudgetKind
	Used int64
	Max  int64
}

BudgetError is returned when an execution budget is exceeded.

func (*BudgetError) Error

func (e *BudgetError) Error() string

type BudgetKind

type BudgetKind int

BudgetKind identifies which budget was exceeded.

const (
	KindSteps BudgetKind = iota
	KindIterations
	KindDepth
	KindNesting
	KindTimeout
)

func (BudgetKind) String

func (k BudgetKind) String() string

type Condition

type Condition struct {
	Op     string      `json:"op"`
	Path   string      `json:"path,omitempty"`
	Value  any         `json:"value,omitempty"`
	Window []string    `json:"window,omitempty"` // time-in / between
	Items  []Condition `json:"items,omitempty"`  // and / or / not
}

Condition is the structured condition AST (the "mini language"). Leaf ops compare a resolved path against a value; and/or/not combine sub-conditions.

type Constraint

type Constraint struct {
	Scheme string          `json:"scheme"`
	ID     string          `json:"id"`
	Params json.RawMessage `json:"params,omitempty"`
}

Constraint references a registered constraint type.

type Decision

type Decision struct {
	Allow      bool
	Reason     string
	Steps      int64
	Iterations int64
}

Decision is the phase-two outcome.

type DecisionInput

type DecisionInput struct {
	AgentID       string
	PrincipalID   string
	Mode          string
	EffectiveCaps []string
	Request       map[string]any
	Now           time.Time
}

DecisionInput mirrors the facts a gateway phase-two plugin receives after AIC validation: EffectiveCaps (P∩C) plus request context (see gateway-core AdmissionResult.EffectiveCaps).

type Flow

type Flow struct {
	Steps []Step `json:"steps"`
}

Flow is the minimal workflow AST (Python/C-style flow control).

type FlowContext

type FlowContext struct {
	Vars    map[string]any
	Request map[string]any
	Handler OpHandler
}

FlowContext carries task-local variables, the request facts, and the operation handler (the gateway's fixed capability executor).

type HTTPGateway

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

HTTPGateway is the reference "rule -> gateway -> mysql-api" chain: it simulates the gateway admission path (mTLS identity via X-Client-CN), runs the phase-two rule plugin, generates SQL from the rule params, and executes it against the database.

func NewHTTPGateway

func NewHTTPGateway(plugins map[string]*RulePlugin, exec SQLExecutor) *HTTPGateway

NewHTTPGateway builds a gateway with per-user rules and an executor.

func (*HTTPGateway) Handler

func (g *HTTPGateway) Handler() http.Handler

Handler exposes the HTTP handler (for httptest or a real server).

type OpHandler

type OpHandler func(op string, vars, req map[string]any) (map[string]any, error)

OpHandler executes a named operation (e.g. "db:select"). The returned map is merged into task variables.

type PhaseTwo

type PhaseTwo interface {
	Decide(in DecisionInput) (*Decision, error)
}

PhaseTwo is the policy-executor contract the gateway phase-two plugin slot expects (per-scheme routing after EffectiveCaps).

type PublishManifest

type PublishManifest struct {
	Schemes map[string]SchemePublish `json:"schemes"`
}

PublishManifest is the publication manifest.

func PublishRules

func PublishRules(rulesDir, outDir, certPath, keyPath string) (*PublishManifest, error)

PublishRules publishes rule files from rulesDir into outDir:

rulesDir/<scheme>/v<maj>.<min>.json

Each rule is validated (structure) and PKCS#7 signed. default.json is published as a byte-identical copy of the highest minor version, so its .p7s detached signature stays valid without re-signing. certPath/keyPath are the signer certificate/key (PEM).

type Rule

type Rule struct {
	RuleID      string          `json:"rule_id"`
	Version     string          `json:"version"`
	Scheme      string          `json:"scheme"`
	Capability  string          `json:"capability"`
	Params      json.RawMessage `json:"params"`
	Conditions  *Condition      `json:"conditions,omitempty"`
	Roles       []string        `json:"roles,omitempty"`
	Constraints []Constraint    `json:"constraints,omitempty"`
	Flow        *Flow           `json:"flow,omitempty"`
}

Rule is the signed rule file format (draft, see docs/database-scheme-design.md §8).

func LoadRule

func LoadRule(path string) (*Rule, error)

LoadRule reads a rule file.

func LoadRuleBytes

func LoadRuleBytes(data []byte) (*Rule, error)

LoadRuleBytes parses a rule from JSON bytes.

func (*Rule) Validate

func (r *Rule) Validate(reg *register.Registry) error

Validate checks the rule against a scheme registry and the database-v1 params contract.

type RuleExecutor

type RuleExecutor struct {
	Rule    *Rule
	Budget  *Budget
	Handler OpHandler
}

RuleExecutor binds a signed rule to the phase-two contract.

func (*RuleExecutor) Decide

func (e *RuleExecutor) Decide(in DecisionInput) (*Decision, error)

Decide validates the rule structure, runs the static bounds pre-check, evaluates the conditions against the request, and runs the flow. Authorization itself stays in the AIC layer; this executor only implements the rule's conditions and orchestration.

type RulePlugin

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

RulePlugin adapts a signed rule to the gateway-core phase-two plugin slot (CapabilityPlugin). The admission pipeline calls Execute once per effective capability whose scheme matches Scheme(); a PluginDeny or error denies the connection (fail-closed).

func LoadRulePlugin

func LoadRulePlugin(rulePath string, trustRoots []*x509.Certificate, handler OpHandler) (*RulePlugin, error)

LoadRulePlugin loads a published (PKCS#7 signed) rule file and builds the gateway phase-two plugin for it. Signature verification is mandatory (fail-closed): a tampered or unsigned rule is rejected. A fresh execution budget is created per plugin so that counters are never shared across executions.

func NewRulePlugin

func NewRulePlugin(scheme string, rule *Rule, budget *Budget, handler OpHandler) *RulePlugin

NewRulePlugin builds a phase-two plugin executing rule for scheme.

func (*RulePlugin) Execute

func (p *RulePlugin) Execute(cap *pki.Capability, ctx *pki.PluginContext) (*pki.PluginResult, error)

Execute maps gateway-core PluginContext facts into a DecisionInput and runs the rule executor (structure -> static bounds -> conditions -> flow). Authorization stays in the AIC layer; this implements the rule's conditions and orchestration only.

func (*RulePlugin) Scheme

func (p *RulePlugin) Scheme() string

Scheme returns the capability scheme this plugin serves.

type RuleVersion

type RuleVersion struct{ Major, Minor int }

RuleVersion is a parsed v<major>.<minor>.json version.

type SQLExecutor

type SQLExecutor func(sql string) ([]map[string]any, error)

SQLExecutor runs a generated SQL statement and returns rows as JSON objects. The real implementation talks to MySQL; tests inject a fake.

func DBExecutor

func DBExecutor(db *sql.DB) SQLExecutor

DBExecutor adapts a *sql.DB to SQLExecutor (real MySQL/MariaDB).

type SchemePublish

type SchemePublish struct {
	Latest string   `json:"latest"`
	Files  []string `json:"files"`
}

SchemePublish describes one published rule scheme.

type Step

type Step struct {
	Name       string     `json:"name,omitempty"`
	Kind       string     `json:"kind"`
	Op         string     `json:"op,omitempty"`
	Condition  *Condition `json:"condition,omitempty"`
	Then       []Step     `json:"then,omitempty"`
	Else       []Step     `json:"else,omitempty"`
	Var        string     `json:"var,omitempty"`
	From       int        `json:"from,omitempty"`
	To         int        `json:"to,omitempty"`
	MaxRetries int        `json:"max_retries,omitempty"`
	Steps      []Step     `json:"steps,omitempty"`
	Do         []Step     `json:"do,omitempty"`
}

Step kinds: op | if | while | for | retry | seq | break | continue

Jump to

Keyboard shortcuts

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