compile

package
v0.1.0 Latest Latest
Warning

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

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

Documentation

Overview

Package compile turns a policy document into an immutable generation: the route table, permits, rate rules and compiled body and header schemas that every request is decided against.

A published generation is shared by concurrent requests, so the package exposes it only through read-only methods; nothing outside may change one. Compiling has no side effects: it never reads storage or the network, and it takes time only from the trusted clock it also owns. It imports only policy and fault. Any gateway package may call it.

Index

Constants

View Source
const (
	RateAlgorithm    = "sliding-window"
	RateKeySubject   = "subject"
	RateKeyAddress   = "client_address"
	MaxRateCount     = 1_000_000
	MaxRateWindowSec = 86_400
	// Subject and public-address cardinality is untrusted. A full table fails
	// closed; expired counters are swept without resetting live quotas.
	MaxCounters = 262144
	// SweepInterval is how many admissions pass between removals of expired
	// counters.
	SweepInterval = 1024
)
View Source
const (
	SchemaBody schemaKind = iota
	SchemaHeaders
)

Variables

View Source
var ProcessStart = time.Now()

ProcessStart anchors this process's monotonic clock to the wall clock once, at startup. It is never changed.

Functions

func CanonicalPath

func CanonicalPath(r *http.Request) (string, bool)

CanonicalPath returns the single path interpretation used for matching and forwarding. Any encoding whose meaning could differ between the gateway and an upstream is rejected rather than normalised.

func CompileModule

func CompileModule(c module.Control, op module.Operation, raw json.RawMessage) (check module.Check, err error)

CompileModule calls c's Compile, turning a panic into an error.

func CompileSchema

func CompileSchema(raw json.RawMessage, kind schemaKind, field string) (*jsonschema.Schema, map[string]any, error)

CompileSchema accepts a JSON Schema 2020-12 document only if every keyword in it belongs to the supported subset, then compiles it with the library. Checking the subset first means no keyword is ever silently ignored. It also returns the decoded root object.

func DeadlineNow

func DeadlineNow() time.Time

DeadlineNow is trustedNow for setting a deadline: a provisional base's or an override's. It first keeps any lead the wall clock has over the monotonic estimate, so a deadline set from a wall clock that is ahead is still reached after its own period if that clock is later set back. The cost is that, once the lead is kept, later timestamps stay that far ahead until a restart, and that restart waits for real time to pass them (the high-water check); the deadline's own record already carries the lead. Other readings, including every request, never raise it, so a brief forward step with no new deadline leaves no trace.

func DenyAll

func DenyAll(p policy.Policy) bool

DenyAll reports whether the policy can admit no request at all: it holds no permits, so no authenticated request can pass RBAC, and no operation is both allowed and public. Only such a policy may become the first base of an installation or the base that ends a recovery.

func GenerationID

func GenerationID(p policy.Policy, revision int64, notAfter time.Time, overrides []int64) string

GenerationID identifies a generation by its base revision, the overrides applied to it (as "+o<id>.<id>…") and a digest of the compiled document and deadline. A generation without overrides keeps the form "r<revision>-…".

func IsCanonical

func IsCanonical(path string) bool

func IsGatewayHeader

func IsGatewayHeader(name string) bool

IsGatewayHeader reports whether only the gateway may set the named header.

func IsLoopbackDial

func IsLoopbackDial(dial string) bool

IsLoopbackDial accepts only literal loopback addresses, so a destination can neither be resolved through DNS nor expanded from request placeholders.

func TrustedNow

func TrustedNow() time.Time

TrustedNow is the time against which every persisted deadline is decided and every controller timestamp is taken; see trustedTime.

func TrustedTime

func TrustedTime(wall time.Time, elapsed time.Duration) time.Time

TrustedTime returns the later of the wall clock reading wall and the wall time the monotonic clock implies after elapsed since processStart, advanced by the wall clock's largest lead when a deadline was set. A deadline has passed once either clock reaches it: a wall clock set back cannot extend it, and neither can a monotonic clock that stood still across a system suspend. A wall clock set forward ends deadlines early, which is the safe direction. The monotonic estimate is anchored at process start, not at each publication, so republishing after a wall clock change cannot move a deadline either.

Types

type Answer

type Answer struct {
	Allowed   bool
	Check     string
	Code      string
	Operation string // empty when no operation matched
	API       string
	Public    bool
	Forwarded string // the path an allowed request reaches its upstream with
	Roles     []string
	Ignored   []string
	// NotChecked lists the checks this answer could not make.
	NotChecked []string
}

Answer is a question's decision. Check and Code name the refusing check (route, access, blocked, role, forward) and its error code; both are empty when the request would be allowed.

type BodyRule

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

BodyRule is a compiled body declaration.

func (*BodyRule) MaxBytes

func (b *BodyRule) MaxBytes() int64

MaxBytes is the largest body the operation accepts.

func (*BodyRule) Validate

func (b *BodyRule) Validate(document any) error

Validate checks a decoded body against the operation's schema.

type CORS

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

CORS is an API's compiled browser access.

func (*CORS) Preflight

func (c *CORS) Preflight(origin, method string, requested []string) http.Header

Preflight returns the headers that allow a preflight from origin for method with the requested headers (Access-Control-Request-Headers field lines), or nil when the origin, the method or any requested header is not allowed.

func (*CORS) Response

func (c *CORS) Response(origin string) http.Header

Response returns the headers an actual request from origin gets, or nil when the origin is not allowed.

type ControlChange

type ControlChange struct {
	Control string `json:"control"`
	Target  string `json:"target"`
}

ControlChange names one control and the target it applies to. It is the identity by which a candidate's effect on enforcement is reported, and by which a temporary override will be compared with a candidate.

func PolicyChanges

func PolicyChanges(before, after policy.Policy) []ControlChange

PolicyChanges lists, in a stable order, every control target whose definition differs between two complete policies: an upstream, API, operation (route, method, access, authentication, body and header rules), its rate rule, a role or a permit (role and operation).

type Destination

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

Destination is where an admitted request goes: its upstream's address and the path it is forwarded with. Only Rule.Destination makes one, after the rewritten path passed the canonical-path check, so a forwarder bound to a Destination cannot be handed an unchecked path.

func (Destination) Dial

func (d Destination) Dial() string

Dial is the upstream's loopback address.

func (Destination) Path

func (d Destination) Path() string

Path is the canonical path the request is forwarded with.

type Generation

type Generation struct {
	ID       string
	Revision int64
	Profile  string
	// Overrides lists, in order, the temporary overrides applied to the base
	// revision.
	Overrides []int64
	// NotAfter, when set, is the earliest persisted deadline the generation
	// depends on (a provisional base's confirmation deadline or an override's
	// expiry), after which it must no longer admit requests even if the
	// controller has not yet replaced it.
	NotAfter time.Time
	// contains filtered or unexported fields
}

Generation is an immutable compiled effective policy. Requests capture one generation and never observe another.

func Compile

func Compile(p policy.Policy, revision int64, notAfter time.Time) (*Generation, error)

Compile validates a complete policy and builds its generation. It either returns a complete generation or an error; it never returns a partial one. It has no side effects. A non-zero notAfter is the earliest persisted deadline the generation depends on.

func (*Generation) Authorise

func (g *Generation) Authorise(asserted []string, r *Rule) (roles, ignored []string, reason string)

Authorise retains only declared roles from already verified claims. Unknown roles are returned for audit; a subject name never creates a permission.

func (*Generation) Conditioned

func (g *Generation) Conditioned(path, method string) bool

Conditioned reports whether the method on the path's target has conditioned operations, so the operation depends on host and headers.

func (*Generation) Decide

func (g *Generation) Decide(q Question, blocked func() bool) Answer

Decide answers q with g. blocked reports whether the account asked about is on the blocked list; it is asked only for a protected operation.

func (*Generation) Expired

func (g *Generation) Expired(now time.Time) bool

Expired reports whether the generation's earliest deadline has passed at now, a reading of trustedNow.

func (*Generation) Match

func (g *Generation) Match(path, method string, in Inbound) (*target, *Rule)

Match selects the most specific target for a canonical path, then the method on that target only, then among that method's operations the one with the most conditions the request meets, else the unconditioned one. A less specific target is never consulted for a missing method. When the method has only conditioned operations and none holds, no target matches.

func (*Generation) Preflight

func (g *Generation) Preflight(path, method string, in Inbound) (*Rule, bool)

Preflight returns the rule a CORS preflight's requested method selects on the path, as Match would for the actual request, and whether the path's target has an operation of an API with browser access; only then does the gateway answer the preflight.

func (*Generation) Roles

func (g *Generation) Roles() []string

Roles lists, sorted, the roles the generation's policy declares.

func (*Generation) Rules

func (g *Generation) Rules() []*Rule

Rules lists every compiled endpoint rule of a generation once.

type Inbound

type Inbound struct {
	Host   string
	Header http.Header
}

Inbound is what a request offers to conditions: its Host value as received (any case, any port) and its header fields.

type ModuleCheck

type ModuleCheck struct {
	ID    string
	Check module.Check
}

ModuleCheck is one module's compiled check.

type Question

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

Question is a checked request description. Only NewQuestion makes one, so every question has passed the request handler's own input checks.

func NewQuestion

func NewQuestion(method, path, host string, headers map[string]string, roles []string) (q Question, field string)

NewQuestion checks a request description: the method, the path in the form the handler accepts, the roles standing for a verified token's, and the host and headers conditions select by. field names the refused input.

type RateRule

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

RateRule is a compiled rate rule: at most count requests per window milliseconds for each verified subject or each direct client address.

func CompileRate

func CompileRate(rule policy.RateRule, field string) (*RateRule, error)

func (*RateRule) Count

func (r *RateRule) Count() int64

Count is the number of requests allowed per window.

func (*RateRule) Window

func (r *RateRule) Window() int64

Window is the window length in milliseconds.

type ResponseRule

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

ResponseRule is an API's compiled response header rule.

func (*ResponseRule) Apply

func (r *ResponseRule) Apply(h http.Header, tls bool)

Apply removes the listed headers and adds each security header the response does not already have. Strict-Transport-Security is added only to a response sent over TLS.

func (*ResponseRule) HSTS

func (r *ResponseRule) HSTS() bool

HSTS reports whether the API asks for Strict-Transport-Security.

type Rule

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

func (*Rule) API

func (r *Rule) API() string

API is the policy API the operation belongs to.

func (*Rule) AddressAllowed

func (r *Rule) AddressAllowed(address string) bool

AddressAllowed reports whether the API's allow list admits the client address; an address that does not parse is never admitted by a list.

func (*Rule) Body

func (r *Rule) Body() *BodyRule

Body is the compiled body rule; nil when the operation accepts no body.

func (*Rule) CORS

func (r *Rule) CORS() *CORS

CORS is the browser access of the rule's API; nil when it has none.

func (*Rule) Checks

func (r *Rule) Checks(phase module.Phase) []ModuleCheck

Checks returns the module checks of the rule that run in phase, in ID order; none for a module not configured for the operation.

func (*Rule) Counter

func (r *Rule) Counter() string

Counter is the operation whose rate counter the rule counts on: its own, or for a conditioned operation its unconditioned sibling's.

func (*Rule) Destination

func (r *Rule) Destination(path string) (d Destination, ok bool)

Destination returns where a request admitted on the canonical inbound path is forwarded. The path is the inbound path without the strip prefix, after the add prefix ("/" when nothing is left), and must be canonical again; otherwise ok is false and the request must not be forwarded.

func (*Rule) Dial

func (r *Rule) Dial() string

Dial is the loopback address of that upstream.

func (*Rule) Headers

func (r *Rule) Headers() *headerRule

Headers is the compiled header schema; nil when there is none.

func (*Rule) Operation

func (r *Rule) Operation() string

Operation is the policy operation the rule enforces.

func (*Rule) Permitted

func (r *Rule) Permitted() bool

Permitted reports whether the operation's access flag allows requests.

func (*Rule) PreflightRate

func (r *Rule) PreflightRate() *RateRule

PreflightRate is the rate rule that limits CORS preflights to the rule's API, per client address; nil when no public operation has one.

func (*Rule) Public

func (r *Rule) Public() bool

Public reports an operation declared auth "none": no token is read.

func (*Rule) Rate

func (r *Rule) Rate() *RateRule

Rate is the compiled rate rule; nil when the operation has no rate limit.

func (*Rule) RateKey

func (r *Rule) RateKey() string

RateKey says whether the rate limit counts per subject or per peer address.

func (*Rule) Response

func (r *Rule) Response() *ResponseRule

Response is the response header rule of the rule's API; nil when it has none.

func (*Rule) Roles

func (r *Rule) Roles() []string

Roles lists, sorted, the roles holding a permit for the operation.

func (*Rule) Upstream

func (r *Rule) Upstream() string

Upstream is the ID of the upstream the operation is bound to.

Jump to

Keyboard shortcuts

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