Documentation
¶
Overview ¶
Package mapper compiles validated FGA mapping configurations into an executable Mapping and evaluates JSON events against it, producing OpenFGA relationship tuples.
Mapping configurations are defined in YAML with three core components:
- Expr (github.com/expr-lang/expr) for conditional logic, data extraction, and variable binding
- Expr interpolation ({{ expr }}) for constructing tuple field strings (user, relation, object)
- Iterators for fan-out from a single event to multiple tuples
Basic usage:
m, err := mapper.Compile(yamlBytes) result, err := m.Evaluate(ctx, event)
Compile is a one-shot convenience. To compile many sources with the same configuration, build a Compiler once and reuse it:
compiler := mapper.NewCompiler()
m, err := compiler.Compile(yamlBytes)
m, err = compiler.CompileFile("mapping.yaml")
The compiler enforces safety limits: an evaluation timeout, a maximum number of tuples per event, and a maximum number of rules per configuration file. The tunable limits are set via functional options passed to Compile or NewCompiler:
m, err := mapper.Compile(yamlBytes, mapper.WithTimeout(50*time.Millisecond), mapper.WithTrace(true))
Parsing and validation are delegated to the language package.
Index ¶
- Constants
- type Category
- type Compiler
- type Conflict
- type ConflictError
- type ConflictKind
- type Diagnostic
- type Diagnostics
- type EvalError
- type FilteredTestRun
- type Mapping
- func (m *Mapping) Evaluate(ctx context.Context, event map[string]any) (*Result, error)
- func (m *Mapping) RuleCount() int
- func (m *Mapping) Rules() []RuleSummary
- func (m *Mapping) RunTests(ctx context.Context) []TestResult
- func (m *Mapping) RunTestsFiltered(ctx context.Context, filter string, failFast bool) FilteredTestRun
- func (m *Mapping) TestCount() int
- func (m *Mapping) Version() string
- type Option
- type Position
- type PostProcessResult
- type Result
- type RuleStatus
- type RuleSummary
- type RuleTrace
- type Severity
- type TestResult
- type Trace
- type Tuple
- type TupleFilter
- type TupleFilterOperation
- type TupleFilterTemplate
- type TupleTemplate
- type ValidationError
Constants ¶
const ( // DefaultTimeout is the maximum duration for a single Evaluate() call. DefaultTimeout = 3 * time.Second // DefaultMaxTuples is the maximum number of tuples a single event can produce. DefaultMaxTuples = 40 )
const DefaultMaxIteratorItems = 1000
DefaultMaxIteratorItems is the default cap on the number of items an iterator source array may contain per evaluation. Override per-compile with WithMaxIteratorItems.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Category ¶
type Category string
Category classifies which stage of the pipeline produced a diagnostic.
const ( // CategoryValidation covers structural validation and YAML parse errors. CategoryValidation Category = "validation" // CategoryEval covers expression compilation and evaluation errors. CategoryEval Category = "eval" // CategoryConflict covers write/delete conflicts detected during evaluation. CategoryConflict Category = "conflict" // CategoryUnknown covers errors that could not be classified. CategoryUnknown Category = "unknown" )
type Compiler ¶
type Compiler struct {
// contains filtered or unexported fields
}
Compiler holds configuration policy and compiles mapping YAML into Mappings.
func NewCompiler ¶
NewCompiler creates a Compiler with default settings, applying any options.
func (*Compiler) Compile ¶
Compile parses and validates a YAML mapping configuration, returning an immutable Mapping ready for evaluation.
func (*Compiler) CompileFile ¶
CompileFile reads a YAML mapping file from disk and compiles it.
func (*Compiler) CompileReader ¶
CompileReader reads a YAML mapping from r and compiles it. It is a convenience over reading the stream into memory and calling Compile.
type Conflict ¶
Conflict describes an unsatisfiable set of desired states on a single (User, Relation, Object) key.
type ConflictError ¶
type ConflictError struct {
Conflict
Condition string // write/delete conflicts: the write tuple's condition, if any
Kind ConflictKind
}
ConflictError represents a runtime conflict on a single relationship (URO). OpenFGA identifies a relationship by (user, relation, object) only, so any URO carrying more than one incompatible desired state produces an invalid Write batch and is rejected here instead.
func (*ConflictError) Error ¶
func (e *ConflictError) Error() string
type ConflictKind ¶
type ConflictKind int
ConflictKind classifies why a set of desired states on one URO cannot be satisfied in a single OpenFGA Write batch.
const ( // ConflictWriteDelete is a write and a delete targeting the same URO. ConflictWriteDelete ConflictKind = iota // ConflictCompetingWrites is two writes on the same URO whose condition or // context differ, i.e. two incompatible desired states for one relationship. ConflictCompetingWrites )
type Diagnostic ¶
type Diagnostic struct {
Severity Severity `json:"severity"`
Category Category `json:"category"`
Field string `json:"field,omitempty"` // YAML field path or tuple field name
Message string `json:"message"` // human-readable description
Position language.Position `json:"position,omitzero"` // zero value = unknown, omitted from JSON
}
Diagnostic is a structured representation of a single error suitable for rendering in any consumer (CLI, IDE, browser editor, API response).
type Diagnostics ¶
type Diagnostics []Diagnostic
Diagnostics is a named slice of Diagnostic values. It satisfies fmt.Stringer, so fmt.Println(diags) and fmt.Sprintf("%v", diags) produce the grouped human-readable output rather than Go's default slice representation. JSON marshalling is unaffected — it encodes as a JSON array.
func DiagnosticsFrom ¶
func DiagnosticsFrom(err error) Diagnostics
DiagnosticsFrom extracts all structured diagnostics from an error tree. Handles errors.Join trees, wrapped errors, and all mapper error types. Returns nil for nil errors.
func (Diagnostics) String ¶
func (d Diagnostics) String() string
String renders diagnostics as a human-readable multi-line string grouped by category, satisfying fmt.Stringer.
type EvalError ¶
type EvalError struct {
Expression string
RuleName string // populated during evaluation before wrapping; empty if unknown
Field string // tuple field name ("user", "relation", "object"); set for compile-time interpolation errors
Position language.Position // source location; set for compile-time interpolation errors; zero = unknown
Err error
}
EvalError represents an Expr expression evaluation error.
type FilteredTestRun ¶
type FilteredTestRun struct {
// Results contains outcomes for tests that were executed.
Results []TestResult
// Filtered is the number of tests skipped because they did not match the --run filter.
Filtered int
// Skipped is the number of matching tests that were not run because fail-fast triggered.
Skipped int
}
FilteredTestRun holds the outcome of a filtered test execution.
func (FilteredTestRun) NotRun ¶
func (r FilteredTestRun) NotRun() int
NotRun returns the total number of tests that did not execute (filtered + skipped).
func (FilteredTestRun) Stopped ¶
func (r FilteredTestRun) Stopped() bool
Stopped reports whether fail-fast actually prevented matching tests from running.
type Mapping ¶
type Mapping struct {
// contains filtered or unexported fields
}
Mapping is a compiled mapping configuration ready to evaluate events. It is immutable and safe for concurrent use across multiple goroutines. Each Evaluate() call operates independently with its own evaluation state.
func Compile ¶
Compile is a one-shot convenience that builds a Compiler with the given options and compiles src in a single call. Use NewCompiler directly when compiling multiple sources with the same configuration.
func (*Mapping) Evaluate ¶
Evaluate runs all rules against the given event and returns the result.
For each rule:
- Evaluate variables (sequential, with access to input and prior variables)
- Evaluate rule when guard (skip rule if false)
- Fan-out via iterator (or single pass if no iterator), rendering tuples per item
After all rules:
- Deduplicate tuples and detect write/delete conflicts
- Enforce maxTuples limit
func (*Mapping) Rules ¶
func (m *Mapping) Rules() []RuleSummary
Rules returns a read-only summary of each rule's tuple templates for static analysis (e.g., model validation). The returned values are copies — callers cannot mutate the compiled mapping's internal state.
func (*Mapping) RunTests ¶
func (m *Mapping) RunTests(ctx context.Context) []TestResult
RunTests executes the embedded test cases from the mapping configuration and returns results for each case.
func (*Mapping) RunTestsFiltered ¶
func (m *Mapping) RunTestsFiltered(ctx context.Context, filter string, failFast bool) FilteredTestRun
RunTestsFiltered executes embedded test cases with optional name filtering and fail-fast support.
filter is a case-sensitive substring; empty string runs all tests. If failFast is true, execution stops after the first failure or error.
type Option ¶
type Option func(*Compiler)
Option configures a Compiler. Options are applied by NewCompiler and by the one-shot Compile facade. An option that receives an invalid value records the error on the Compiler; that error is surfaced from Compile rather than panicking.
func WithMaxIteratorItems ¶
WithMaxIteratorItems overrides the default cap on the number of items an iterator source array may contain per evaluation. The count must be positive; a non-positive value is recorded as an error and surfaced from Compile.
func WithMaxRules ¶
WithMaxRules overrides the default cap on the number of rules a single mapping file may declare, enforced during validation (within Compile). The count must be positive; a non-positive value is recorded as an error and surfaced from Compile.
func WithMaxTuples ¶
WithMaxTuples overrides the default maximum tuples per event. The count must be positive; a non-positive value is recorded as an error and surfaced from Compile.
func WithTimeout ¶
WithTimeout overrides the default evaluation timeout per Evaluate() call. The duration must be positive; a non-positive value is recorded as an error and surfaced from Compile.
type Position ¶
Position is a source location within a mapping file. It is an alias for language.Position so SDK callers handling the mapper error path (EvalError, Diagnostic) can name it without importing the language package; the two are the same type.
type PostProcessResult ¶
type PostProcessResult struct {
RemovedTuples []Tuple // the duplicate tuples that were removed
Conflicts []Conflict // all write/delete conflicts detected (empty if none)
}
PostProcessResult holds metadata from tuple post-processing (dedup + conflict detection). Populated on the Trace only when tracing is enabled.
type Result ¶
type Result struct {
Tuples []Tuple `json:"tuples"`
TupleFilterOperations []TupleFilterOperation `json:"tuple_filter_operations,omitempty"`
Trace *Trace `json:"trace,omitempty"` // nil unless tracing is enabled on the Compiler
}
Result is the output of Mapping.Evaluate.
type RuleStatus ¶
type RuleStatus string
RuleStatus represents the outcome of evaluating a single rule.
const ( // RuleMatched indicates the rule's when guard evaluated to true and the rule produced tuples. RuleMatched RuleStatus = "matched" // RuleSkipped indicates the rule's when guard evaluated to false and the rule was skipped. RuleSkipped RuleStatus = "skipped" // RuleErrored indicates an error occurred while evaluating the rule. RuleErrored RuleStatus = "error" )
type RuleSummary ¶
type RuleSummary struct {
Name string
Tuples []TupleTemplate
IteratorTuples []TupleTemplate
TupleFilters []TupleFilterTemplate
}
RuleSummary is a read-only view of a rule's tuple templates for static analysis. It carries mapper-owned template types (not the language package's parse structs), exposing only the fields needed to validate a mapping against an authorization model — no source positions or other internal parse state leak through.
type RuleTrace ¶
type RuleTrace struct {
Name string
Status RuleStatus
Error error // populated only when Status == RuleErrored
EmittedN int
FilterN int // number of rendered tuple filters (0 if rule has no tuple_filters)
}
RuleTrace records evaluation details for a single rule.
type Severity ¶
type Severity string
Severity represents the severity of a diagnostic.
const ( // SeverityError indicates a fatal error that prevents compilation or evaluation. SeverityError Severity = "error" )
type TestResult ¶
type TestResult struct {
Name string
Passed bool
// Expected is the set of tuples the test case declared.
Expected []language.Tuple
// Actual is the set of tuples evaluation produced.
Actual []language.Tuple
// ExpectedTupleFilters is the set of tuple filters the test case declared.
ExpectedTupleFilters []language.TupleFilter
// ActualTupleFilters is the set of tuple filters evaluation produced.
ActualTupleFilters []language.TupleFilter
// Error is populated if the test failed due to an evaluation error.
Error error
// Duration is the wall time taken to evaluate this test case.
Duration time.Duration
// Trace holds rule-level execution details; nil unless the mapping was compiled with WithTrace(true).
Trace *Trace
// Input is the event that was evaluated, preserved for display in verbose failure output.
Input map[string]any
}
TestResult captures the outcome of a single embedded test case.
type Trace ¶
type Trace struct {
Rules []RuleTrace
Duration time.Duration
PostProcess *PostProcessResult // nil unless dedup or conflicts occurred
}
Trace holds execution trace data for debugging rule evaluation. Populated only when WithTrace(true) is set on the Compiler.
type Tuple ¶
Tuple is an OpenFGA relationship tuple produced by evaluation. It is an alias for language.Tuple so SDK callers can name it without a second import; the two are the same type.
type TupleFilter ¶
type TupleFilter = language.TupleFilter
TupleFilter is a rendered tuple filter produced by evaluation. It is an alias for language.TupleFilter so SDK callers can name it without a second import; the two are the same type.
type TupleFilterOperation ¶
type TupleFilterOperation struct {
Filters []TupleFilter `json:"filters"`
Tuples []Tuple `json:"tuples"`
}
TupleFilterOperation groups a rule's rendered filters with its desired-state tuples. One per rule that has tuple_filters. The consumer uses these to drive read-diff-write against FGA.
type TupleFilterTemplate ¶
TupleFilterTemplate is the pre-render shape of a tuple filter for static analysis. Empty fields are wildcards; interpolated fields cannot be validated statically.
type TupleTemplate ¶
type TupleTemplate struct {
User string
Relation string
Object string
Condition string // FGA condition name (empty if none)
Context map[string]string // FGA context keys → interpolation templates (nil if none)
}
TupleTemplate is the pre-render shape of a tuple, exposing only the fields a static analyzer needs to check a mapping against an authorization model. The User, Relation, and Object fields may still contain {{ }} interpolation; a fully interpolated field cannot be validated statically and is skipped by the analyzer.
type ValidationError ¶
type ValidationError = language.ValidationError
ValidationError is a structural validation error carrying a source Position. It is an alias for language.ValidationError so SDK callers can branch on the mapper error surface (alongside EvalError and ConflictError) without a second import; the two are the same type.