enforcement

package
v0.1.0-alpha Latest Latest
Warning

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

Go to latest
Published: Jul 27, 2026 License: Apache-2.0 Imports: 29 Imported by: 0

Documentation

Overview

Package enforcement implements the endpoint side of AntiFlock's signed plan transaction. OS mutation is delegated to a least-privilege Driver; this package owns validation, ordering, verification, replay defense, and rollback.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrPlanReplay     = errors.New("plan replay or revision conflict")
	ErrPlanInProgress = errors.New("plan execution is already in progress")
	ErrPlanRejected   = errors.New("plan was rejected")
)
View Source
var ErrNftablesApplyDisabled = errors.New("nftables apply is disabled")

Functions

func SignExecutionResult

func SignExecutionResult(result *antiflockv1.PlanExecutionResult, keyID string, privateKey ed25519.PrivateKey, signedAt time.Time) error

SignExecutionResult applies the deterministic protobuf signing contract for antiflock.plan-result.v1. It mutates only NodeSignature.

func VerifyExecutionResult

func VerifyExecutionResult(result *antiflockv1.PlanExecutionResult, publicKey ed25519.PublicKey) error

Types

type CheckObservation

type CheckObservation struct {
	Outcome     antiflockv1.CheckOutcome
	ReasonCode  string
	SafeMessage string
	Evidence    []*antiflockv1.EvidenceReference
}

CheckObservation is supplied by a local deterministic check implementation. The enforcer validates its evidence before a required pass can commit.

type Config

type Config struct {
	DeploymentID       string
	NodeID             string
	PlanKeyID          string
	PlanPublicKey      ed25519.PublicKey
	NodeKeyID          string
	NodePrivateKey     ed25519.PrivateKey
	Capabilities       *antiflockv1.CapabilityManifest
	Driver             Driver
	StateStore         StateStore
	Clock              func() time.Time
	MaximumEvidenceAge time.Duration
	RollbackTimeout    time.Duration
}

type Driver

Driver is the only mutation boundary. Tests and simulations should provide an in-memory implementation; production implementations belong in isolated, least-privilege platform adapters.

type Enforcer

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

func New

func New(config Config) (*Enforcer, error)

func (*Enforcer) Apply

func (enforcer *Enforcer) Apply(ctx context.Context, input *antiflockv1.Plan) (*antiflockv1.PlanExecutionResult, error)

Apply executes one plan serially. Invalid plans return a signed REJECTED result together with ErrPlanRejected; transaction failures are represented by a terminal signed result and do not expose raw driver errors.

type FileStateStore

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

FileStateStore is the Linux durable replay boundary for plan execution. It uses an OS lock across processes and atomically persists every reservation before any driver mutation. An interrupted in-progress reservation remains fail-closed and requires operator recovery; it is never silently retried.

func NewFileStateStore

func NewFileStateStore(directory string) (*FileStateStore, error)

NewFileStateStore creates or validates a private Linux state directory. The resolved path and its final component must not traverse a symlink.

func (*FileStateStore) Complete

func (store *FileStateStore) Complete(ctx context.Context, result *antiflockv1.PlanExecutionResult) error

func (*FileStateStore) Reserve

func (store *FileStateStore) Reserve(ctx context.Context, reservation Reservation) (*antiflockv1.PlanExecutionResult, error)

func (*FileStateStore) Revisions

func (store *FileStateStore) Revisions(ctx context.Context) (uint64, uint64, error)

Revisions reads the durable monotonic revision floor under the OS lock.

type MemoryStateStore

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

func NewMemoryStateStore

func NewMemoryStateStore(lastPolicyRevision, lastPlanRevision uint64) *MemoryStateStore

func (*MemoryStateStore) Complete

func (store *MemoryStateStore) Complete(ctx context.Context, result *antiflockv1.PlanExecutionResult) error

func (*MemoryStateStore) Reserve

func (store *MemoryStateStore) Reserve(ctx context.Context, reservation Reservation) (*antiflockv1.PlanExecutionResult, error)

func (*MemoryStateStore) Revisions

func (store *MemoryStateStore) Revisions() (uint64, uint64)

type NftablesAdapter

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

NftablesAdapter renders an isolated fail-closed output table. It never flushes or replaces an existing table. Rollback deletes only a table that this adapter instance successfully created.

func NewNftablesAdapter

func NewNftablesAdapter(runner NftablesRunner, config NftablesConfig) (*NftablesAdapter, error)

func (*NftablesAdapter) Apply

Apply crosses the nft process boundary only when EnableApply was explicitly set at construction. Dry-run rendering is always available.

func (*NftablesAdapter) DryRunApply

func (adapter *NftablesAdapter) DryRunApply(operation *antiflockv1.PlanOperation) (NftablesCommand, error)

DryRunApply renders the only supported firewall action. Recovery entries must be literal IP addresses or CIDRs; hostnames require a separately verified resolver-to-address preparation step and therefore fail closed.

func (*NftablesAdapter) DryRunRollback

func (adapter *NftablesAdapter) DryRunRollback(operation *antiflockv1.PlanOperation) (NftablesCommand, error)

func (*NftablesAdapter) Rollback

func (adapter *NftablesAdapter) Rollback(ctx context.Context, operation *antiflockv1.PlanOperation) (OperationObservation, error)

Rollback refuses to delete a table unless this process observed its own successful creation. Crash recovery requires a durable ownership record and is intentionally left to the agent state integration.

type NftablesCommand

type NftablesCommand struct {
	Executable string   `json:"executable"`
	Arguments  []string `json:"arguments"`
	Input      string   `json:"input"`
}

NftablesCommand is a reviewable, shell-free dry run. Arguments and input are passed separately to the executor.

type NftablesConfig

type NftablesConfig struct {
	Executable  string
	TableName   string
	EnableApply bool
}

type NftablesExecRunner

type NftablesExecRunner struct{}

NftablesExecRunner invokes exactly a trusted system nft binary with -f -. It discards command output so provider or host details cannot be copied into safe API messages.

func (NftablesExecRunner) Run

func (NftablesExecRunner) Run(ctx context.Context, executable string, arguments []string, input []byte) error

type NftablesRunner

type NftablesRunner interface {
	Run(context.Context, string, []string, []byte) error
}

NftablesRunner is the explicit privileged-process boundary. Implementations receive a prevalidated nft batch on stdin and must never invoke a shell.

type OperationObservation

type OperationObservation struct {
	Succeeded   bool
	ReasonCode  string
	SafeMessage string
}

OperationObservation contains no raw command output. A Driver must sanitize provider and operating-system errors before setting SafeMessage.

type Reservation

type Reservation struct {
	PlanID         string
	Fingerprint    string
	PolicyRevision uint64
	PlanRevision   uint64
}

Reservation is the replay-safe identity of executable plan content.

type StateStore

StateStore atomically reserves a monotonic plan before mutation and records its terminal signed result. MemoryStateStore is only for tests and simulation; Linux enforcement should use FileStateStore so replay defense survives restart.

Jump to

Keyboard shortcuts

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