auth

package
v0.18.18 Latest Latest
Warning

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

Go to latest
Published: Sep 3, 2026 License: AGPL-3.0 Imports: 24 Imported by: 0

Documentation

Overview

Package auth provides authentication and authorization for Wadjet's HTTP API.

Supports three authentication methods:

  • API keys: Simple bearer tokens for internal tools (Grafana, ETL pipelines)
  • JWT: HMAC-SHA256 or RSA-signed tokens for service-to-service auth
  • mTLS: Client certificate authentication for zero-trust deployments

Authorization is role-based with table-level granularity.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrNoCredentials = errors.New("no credentials provided")
	ErrUnauthorized  = errors.New("unauthorized")
)

Errors returned by authentication.

View Source
var ColumnActions = []string{"allow", "mask", "deny"}

ColumnActions lists the actions a policy's `columns:` map accepts, in the order an error message should offer them.

Functions

func ContextWithIdentity

func ContextWithIdentity(ctx context.Context, id *Identity) context.Context

ContextWithIdentity returns a new context with the given identity.

func ContextWithRowFilters

func ContextWithRowFilters(ctx context.Context, filters RowFilters) context.Context

ContextWithRowFilters returns a context carrying row filter predicates.

func ContextWithTableDecisions

func ContextWithTableDecisions(ctx context.Context, decisions TableDecisions) context.Context

ContextWithTableDecisions returns a context carrying ABAC table decisions.

func EnforcePlanPolicies

func EnforcePlanPolicies(ctx context.Context, provider *Provider, selectInfo *plansql.SelectInfo, plan *logical.Node, protocol string) (*logical.Node, error)

EnforcePlanPolicies applies ABAC to a query at plan level: table-access denial, row-filter injection, and column deny/mask injection for every table the SELECT references. It is THE shared enforcement path — the embedded engine (wadjet.DB.Query) and the coordinator's native-DAG executor (Coordinator.ExecuteSQL) both call it with the same inputs, so an identity sees identical policy behavior regardless of which execution path answers.

No-ops (returns the plan unchanged) when the provider is nil/disabled, no identity is attached to ctx, or the provider has no evaluator — matching the embedded engine's historical behavior. protocol labels the evaluation environment for policy conditions and audit.

func LoadClientCA

func LoadClientCA(caFile string) (*x509.CertPool, error)

LoadClientCA loads a CA certificate pool for verifying client certificates. Used when building the tls.Config for the HTTP server.

func Middleware

func Middleware(authn *Authenticator, logger *slog.Logger) func(http.Handler) http.Handler

Middleware returns HTTP middleware that authenticates requests. Health check endpoint is always allowed without auth.

func New

func New(cfg Config) (*Authenticator, *Authorizer)

New creates an Authenticator and Authorizer from configuration.

func NewTLSConfig

func NewTLSConfig(serverCertFile, serverKeyFile string, clientCA *x509.CertPool) (*tls.Config, error)

NewTLSConfig creates a tls.Config for the server with mTLS client verification. serverCert and serverKey are paths to the server's TLS certificate and key. clientCA is the CA pool for verifying client certificates.

func ProviderMiddleware

func ProviderMiddleware(provider *Provider, logger *slog.Logger) func(http.Handler) http.Handler

ProviderMiddleware returns HTTP middleware that reads the current Authenticator from a Provider on every request. This enables hot-reload: when auth config changes, the Provider is atomically updated and subsequent requests see the new config with zero downtime.

func RateLimitMiddleware

func RateLimitMiddleware(rl *RateLimiter, logger *slog.Logger) func(http.Handler) http.Handler

RateLimitMiddleware returns HTTP middleware that enforces per-identity rate limits. Unauthenticated requests use the remote address as identity.

func RequirePermission

func RequirePermission(provider *Provider, ctx context.Context, perm string) error

RequirePermission enforces that the caller in ctx holds perm, but only when the provider is present and auth is enabled. It is the gate for privileged DDL (e.g. CREATE/DROP/ALTER ALERT) that has no per-row ABAC surface of its own. Fail-closed contract: with auth enabled, a missing identity or an identity lacking perm is rejected; with auth absent/disabled it returns nil (dev/embedded, nothing to enforce).

func StampDefiner

func StampDefiner(ctx context.Context, provider *Provider, snap IdentitySnapshot) (context.Context, bool)

StampDefiner stamps snap's identity onto ctx for definer's-rights execution (e.g. a scheduled alert query running as its creator) and reports whether the definer is attributed — i.e. whether a real identity was recorded.

  • provider nil / auth disabled: ctx is returned unchanged with true — there is no policy to enforce (dev/embedded).
  • auth enabled: snap.ToIdentity() is ALWAYS stamped, even for an empty (legacy) snapshot. This is deliberate: EnforcePlanPolicies fail-OPENS on a nil identity, so stamping a non-nil role-less identity instead routes an unattributed alert into ABAC default-deny (fail closed) rather than unfiltered execution. attributed is false in that case so the caller can warn that the alert needs recreating under an identity.

Types

type APIKeyDef

type APIKeyDef struct {
	Key        string            `yaml:"key"`        // the bearer token value
	Name       string            `yaml:"name"`       // human label
	Role       string            `yaml:"role"`       // role name reference
	Attributes map[string]string `yaml:"attributes"` // optional ABAC attributes
}

APIKeyDef defines an API key in configuration.

type AccessControlPolicy

type AccessControlPolicy struct {
	Name    string       `yaml:"name" json:"name"`
	Version int          `yaml:"version" json:"version"`
	Rules   []PolicyRule `yaml:"rules" json:"rules"`
	Enabled bool         `yaml:"enabled" json:"enabled"`
}

AccessControlPolicy groups related rules.

func MigrateRBACToABAC

func MigrateRBACToABAC(roles []RoleConfig, cellPolicies []PolicyConfig) ([]AccessControlPolicy, error)

MigrateRBACToABAC converts legacy RBAC role and policy configs into equivalent ABAC policies. This runs at startup when ABACPolicies is empty but Roles/Policies are populated, providing full backward compatibility.

It is THE shipped enforcement path for a `policies:` block — the obligations it emits are what auth.EnforcePlanPolicies injects into the plan — so it reads column actions through the same ParseColumnAction as ParsePolicies and fails on the same inputs (#802). Its own switch previously matched "deny" and "mask" case-sensitively and dropped everything else, which turned both a typo AND a capitalised `Mask` into no obligation at all: a silent grant on the very path that enforces.

type AccessPolicy

type AccessPolicy struct {
	Table      string                  // table name this policy applies to
	Role       string                  // role name this policy applies to
	Columns    map[string]ColumnPolicy // column name -> policy
	MaskValues map[string]CellMaskFunc // column name -> custom mask function (optional)
	RowFilter  string                  // SQL predicate appended to WHERE clause (e.g. "region = 'us'")
}

AccessPolicy defines cell-level access control for a table. Policies are evaluated per-role to filter rows and mask/deny columns.

func (*AccessPolicy) ApplyToRow

func (p *AccessPolicy) ApplyToRow(row map[string]any) map[string]any

ApplyToRow applies column policies to a single result row. Returns the filtered row with masked/denied columns handled.

func (*AccessPolicy) ApplyToRows

func (p *AccessPolicy) ApplyToRows(rows []map[string]any) []map[string]any

ApplyToRows applies column policies to all result rows.

type Action

type Action string

Action is the operation being performed.

const (
	ActionRead     Action = "read"
	ActionWrite    Action = "write"
	ActionAdmin    Action = "admin"
	ActionCreate   Action = "create"
	ActionDrop     Action = "drop"
	ActionDescribe Action = "describe"
)

type Attributes

type Attributes map[string]any

Attributes is a string-keyed bag of values carried by subjects, resources, and environments.

func (Attributes) Get

func (a Attributes) Get(key string) any

Get returns the value for a key, or nil if not present.

func (Attributes) GetString

func (a Attributes) GetString(key string) string

GetString returns the string value for a key, or "" if not present or not a string.

type AuditLogger

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

AuditLogger records security-relevant events for compliance and forensics.

func NewAuditLogger

func NewAuditLogger(logger *slog.Logger) *AuditLogger

NewAuditLogger creates an audit logger that writes structured security events.

func (*AuditLogger) LogAccessDenied

func (a *AuditLogger) LogAccessDenied(identity *Identity, resource, reason string)

LogAccessDenied records authorization failures.

func (*AuditLogger) LogAuthFailure

func (a *AuditLogger) LogAuthFailure(remoteAddr, path, reason string)

LogAuthFailure records authentication failures.

func (*AuditLogger) LogColumnPolicy

func (a *AuditLogger) LogColumnPolicy(identity *Identity, table string, masked, denied []string)

LogColumnPolicy records when columns are masked or denied.

func (*AuditLogger) LogQuery

func (a *AuditLogger) LogQuery(identity *Identity, sql string, tables []string, elapsed time.Duration, err error)

LogQuery records a query execution with identity context.

func (*AuditLogger) LogRowFilterApplied

func (a *AuditLogger) LogRowFilterApplied(identity *Identity, table, filter string)

LogRowFilterApplied records when a row filter is injected into a query plan.

type Authenticator

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

Authenticator verifies caller identity from HTTP requests.

func (*Authenticator) Authenticate

func (a *Authenticator) Authenticate(r *http.Request) (*Identity, error)

Authenticate extracts and verifies identity from an HTTP request. It tries methods in order: mTLS (from TLS state), API key (Bearer token), JWT (Bearer token).

func (*Authenticator) AuthenticateToken

func (a *Authenticator) AuthenticateToken(token string) (*Identity, error)

AuthenticateToken verifies identity from a raw bearer token (API key or JWT). Used by non-HTTP frontends (pgwire, gRPC) where there is no http.Request.

func (*Authenticator) Enabled

func (a *Authenticator) Enabled() bool

Enabled returns true if authentication is configured.

type Authorizer

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

Authorizer checks whether an identity has permission to perform operations.

func (*Authorizer) CanAccessTable

func (a *Authorizer) CanAccessTable(id *Identity, tableName string) bool

CanAccessTable checks whether the identity's role grants access to a table.

func (*Authorizer) FilterTables

func (a *Authorizer) FilterTables(id *Identity, tables []string) []string

FilterTables returns only tables the identity is allowed to see.

func (*Authorizer) HasPermission

func (a *Authorizer) HasPermission(id *Identity, perm string) bool

HasPermission checks whether the identity has the given permission. Valid permissions: "read", "write", "admin".

type CellMaskFunc

type CellMaskFunc func(val any) any

CellMaskFunc replaces a cell value with a masked version. Receives the original value and returns the masked value.

type ColumnDecision

type ColumnDecision struct {
	Column   string `json:"column"`
	Allowed  bool   `json:"allowed"`
	MaskFunc string `json:"mask_func,omitempty"`
	MaskExpr string `json:"mask_expr,omitempty"`
}

ColumnDecision describes the access decision for a single column.

type ColumnPolicy

type ColumnPolicy int

ColumnPolicy defines how a column is handled for a given role.

const (
	// ColumnAllow permits full access to the column value.
	ColumnAllow ColumnPolicy = iota
	// ColumnMask replaces the value with a redacted placeholder.
	ColumnMask
	// ColumnDeny removes the column from results entirely.
	ColumnDeny
)

func ParseColumnAction added in v0.18.14

func ParseColumnAction(column, action string) (ColumnPolicy, error)

ParseColumnAction maps one YAML column action to its ColumnPolicy.

An unrecognised action is an ERROR, not a default. Before #802 the default arm returned ColumnAllow, so `columns: {src_ip: "***REDACTED***"}` — the spelling every version of docs/security.md recommended — parsed to a full grant, and an operator who believed a PII column was masked was served it in the clear. A column-access control that cannot be understood must refuse to load: loud beats plausible, and a security control never degrades to a grant.

type Condition

type Condition struct {
	Attribute string `yaml:"attribute" json:"attribute"`
	Op        string `yaml:"op" json:"op"` // eq, neq, in, not_in, gt, lt, gte, lte, contains, exists
	Value     any    `yaml:"value" json:"value"`
}

Condition is a single predicate in a policy rule. Attribute uses dot-path notation: "subject.role", "resource.name", "env.source_ip".

type Config

type Config struct {
	Enabled bool         `yaml:"enabled"`
	APIKeys []APIKeyDef  `yaml:"api_keys"`
	JWT     JWTConfig    `yaml:"jwt"`
	MTLS    MTLSConfig   `yaml:"mtls"`
	Roles   []RoleConfig `yaml:"roles"`
}

Config holds authentication configuration.

type Decision

type Decision struct {
	Allowed     bool
	Effect      Effect
	MatchedRule string
	Obligations []Obligation
	Reason      string
}

Decision is the outcome of a single policy evaluation.

type Effect

type Effect int

Effect is the outcome of a policy rule.

const (
	EffectAllow Effect = iota
	EffectDeny
)

func (Effect) String

func (e Effect) String() string

String returns "allow" or "deny".

type Environment

type Environment struct {
	Time     time.Time
	SourceIP string
	Protocol string // "http", "pgwire", "grpc"
	Custom   Attributes
}

Environment carries contextual attributes for policy evaluation.

type Identity

type Identity struct {
	Name       string     // human-readable label (e.g. "grafana-prod", "alice@example.com")
	Role       string     // resolved role name
	Method     string     // how they authenticated: "apikey", "jwt", "mtls"
	Tables     []string   // allowed tables from role (["*"] = all)
	Perms      []string   // allowed permissions from role
	Attributes Attributes // extended attributes for ABAC (from JWT claims, mTLS cert, config)
}

Identity represents an authenticated caller.

func IdentityFromContext

func IdentityFromContext(ctx context.Context) *Identity

IdentityFromContext extracts the authenticated identity from a request context. Returns nil if no identity is present (auth disabled or unauthenticated).

func (*Identity) String

func (id *Identity) String() string

String returns a human-readable representation of the identity.

func (*Identity) ToSubject

func (id *Identity) ToSubject() Subject

ToSubject creates a Subject from an Identity for ABAC evaluation.

type IdentitySnapshot

type IdentitySnapshot struct {
	Name       string            `json:"name,omitempty"`
	Role       string            `json:"role,omitempty"`
	Method     string            `json:"method,omitempty"`
	Attributes map[string]string `json:"attributes,omitempty"`
}

IdentitySnapshot is the persistable subset of an Identity sufficient to re-establish its ABAC subject later (see Identity.ToSubject, which keys on role/name/method plus attributes). It is stored with definer's-rights resources — an alert runs under its creator's identity on every scheduled tick, so the creator's role and attributes must survive in the catalog. Tables/Perms are intentionally omitted: they gate RBAC operations (table access, DDL) that the scheduled-query path does not perform — that path applies only ABAC plan enforcement, which reads role/attributes.

func SnapshotIdentity

func SnapshotIdentity(ctx context.Context) IdentitySnapshot

SnapshotIdentity captures the identity in ctx as an IdentitySnapshot. The zero snapshot (all fields empty) means no identity was present — callers persisting it record "no definer", which the scheduler treats fail-closed.

func (IdentitySnapshot) Empty

func (s IdentitySnapshot) Empty() bool

Empty reports whether the snapshot carries no usable identity — either no definer was recorded (pre-definer-rights alert) or it was created with no authenticated identity. Enforcement treats an empty snapshot fail-closed.

func (IdentitySnapshot) ToIdentity

func (s IdentitySnapshot) ToIdentity() *Identity

ToIdentity reconstructs an *Identity for context stamping. Attributes are widened back to the Attributes (map[string]any) shape ToSubject expects.

type JWTConfig

type JWTConfig struct {
	Enabled       bool   `yaml:"enabled"`
	Secret        string `yaml:"secret"`          // HMAC-SHA256 secret
	PublicKeyFile string `yaml:"public_key_file"` // PEM file path for RSA verification
	RoleClaim     string `yaml:"role_claim"`      // JWT claim containing role (default: "role")
	Issuer        string `yaml:"issuer"`          // expected issuer (optional)
}

JWTConfig holds JWT verification configuration.

type JWTVerifier

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

JWTVerifier validates JWT tokens and extracts identities.

func NewJWTVerifier

func NewJWTVerifier(cfg JWTConfig, roles map[string]*RoleDef) (*JWTVerifier, error)

NewJWTVerifier creates a JWT verifier from configuration.

func (*JWTVerifier) Verify

func (v *JWTVerifier) Verify(tokenStr string) (*Identity, error)

Verify validates a JWT token string and returns the identity.

type MTLSConfig

type MTLSConfig struct {
	Enabled     bool              `yaml:"enabled"`
	CAFile      string            `yaml:"ca_file"`      // CA certificate PEM file for verifying client certs
	RoleMap     map[string]string `yaml:"role_map"`     // CN or SAN -> role mapping
	DefaultRole string            `yaml:"default_role"` // role for valid certs not in role_map
}

MTLSConfig holds mTLS authentication configuration.

type MTLSVerifier

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

MTLSVerifier authenticates clients via TLS client certificates.

func NewMTLSVerifier

func NewMTLSVerifier(cfg MTLSConfig, roles map[string]*RoleDef) *MTLSVerifier

NewMTLSVerifier creates an mTLS verifier from configuration.

func (*MTLSVerifier) Verify

func (v *MTLSVerifier) Verify(cert *x509.Certificate) (*Identity, error)

Verify extracts identity from a verified client certificate. The TLS handshake (certificate chain validation) is handled by Go's TLS stack via tls.Config.ClientAuth + ClientCAs. This method maps the verified cert to a role.

type Obligation

type Obligation struct {
	Type     string `yaml:"type" json:"type"`           // mask_column, deny_column, row_filter, query_limit
	Target   string `yaml:"target" json:"target"`       // column name, table name
	Value    string `yaml:"value" json:"value"`         // SQL predicate, mask expression
	MaskFunc string `yaml:"mask_func" json:"mask_func"` // redact, hash, nullify, partial
}

Obligation is a side-effect applied when a rule matches.

type PolicyConfig

type PolicyConfig struct {
	Table     string            `yaml:"table"`
	Role      string            `yaml:"role"`
	Columns   map[string]string `yaml:"columns"`    // column name -> "allow", "mask", "deny"
	RowFilter string            `yaml:"row_filter"` // SQL WHERE predicate
}

PolicyConfig is the YAML representation of cell-level access policies.

type PolicyEvaluator

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

PolicyEvaluator evaluates access control policies using deny-overrides.

func NewPolicyEvaluator

func NewPolicyEvaluator(policies []AccessControlPolicy) *PolicyEvaluator

NewPolicyEvaluator creates an evaluator from a set of policies.

func (*PolicyEvaluator) Evaluate

func (pe *PolicyEvaluator) Evaluate(subject Subject, resource Resource, action Action, env Environment) Decision

Evaluate runs deny-overrides policy evaluation.

Algorithm:

  1. Collect all rules whose conditions match the request context.
  2. If ANY matching rule has Effect=Deny, result is Deny (highest-priority deny cited).
  3. If no deny matches and at least one Allow matches, result is Allow. Obligations are merged from all matching Allow rules.
  4. If no rules match at all, default is Deny (closed-world assumption).

func (*PolicyEvaluator) EvaluateTableAccess

func (pe *PolicyEvaluator) EvaluateTableAccess(subject Subject, tableName string, action Action, env Environment) *TableDecision

EvaluateTableAccess evaluates table-level access and collects column/row obligations.

type PolicyRule

type PolicyRule struct {
	ID          string       `yaml:"id" json:"id"`
	Description string       `yaml:"description" json:"description"`
	Effect      Effect       `yaml:"-" json:"-"`
	EffectStr   string       `yaml:"effect" json:"effect"`     // "allow" or "deny" for serialization
	Priority    int          `yaml:"priority" json:"priority"` // lower = higher priority
	Subjects    []Condition  `yaml:"subjects" json:"subjects"`
	Resources   []Condition  `yaml:"resources" json:"resources"`
	Actions     []Action     `yaml:"actions" json:"actions"`
	Environment []Condition  `yaml:"environment" json:"environment"`
	Obligations []Obligation `yaml:"obligations" json:"obligations"`
}

PolicyRule is one rule within an access control policy.

type PolicySet

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

PolicySet holds all access policies, indexed by table+role.

func NewPolicySet

func NewPolicySet() *PolicySet

NewPolicySet creates an empty policy set.

func ParsePolicies

func ParsePolicies(configs []PolicyConfig) (*PolicySet, error)

ParsePolicies converts YAML policy configs into a PolicySet. It fails on the first unrecognised column action, naming the table, role, column and the value it could not read (#802).

func (*PolicySet) Add

func (ps *PolicySet) Add(p *AccessPolicy)

Add registers an access policy.

func (*PolicySet) Lookup

func (ps *PolicySet) Lookup(table, role string) *AccessPolicy

Lookup returns the policy for a given table and role, or nil if none exists.

type Provider

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

Provider wraps Authenticator, Authorizer, PolicySet, and PolicyEvaluator behind an atomic pointer so they can be swapped on config reload without locks.

func NewProvider

func NewProvider(authn *Authenticator, authz *Authorizer, policies *PolicySet, logger *slog.Logger) *Provider

NewProvider creates a Provider from initial auth components. Any parameter may be nil (auth disabled).

func (*Provider) Authenticator

func (p *Provider) Authenticator() *Authenticator

Authenticator returns the current Authenticator. Lock-free.

func (*Provider) Authorizer

func (p *Provider) Authorizer() *Authorizer

Authorizer returns the current Authorizer. Lock-free.

func (*Provider) Enabled

func (p *Provider) Enabled() bool

Enabled returns whether authentication is currently active. Lock-free.

func (*Provider) Evaluator

func (p *Provider) Evaluator() *PolicyEvaluator

Evaluator returns the current ABAC PolicyEvaluator. Lock-free.

func (*Provider) Policies

func (p *Provider) Policies() *PolicySet

Policies returns the current PolicySet. Lock-free.

func (*Provider) Update

func (p *Provider) Update(authn *Authenticator, authz *Authorizer, policies *PolicySet)

Update atomically replaces all auth components.

func (*Provider) UpdateFromConfig

func (p *Provider) UpdateFromConfig(cfg Config, policyCfgs []PolicyConfig, abacPolicies ...AccessControlPolicy) error

UpdateFromConfig rebuilds auth from a Config and atomically swaps. If abacPolicies is non-empty, builds an ABAC evaluator. Otherwise, if RBAC roles and cell policies are present, auto-migrates them to ABAC.

A policy this cannot read returns an error and swaps NOTHING: the provider keeps the state it already had. That matters most on hot reload, where the alternative to refusing an unreadable `columns:` action is installing a weaker policy set than the operator asked for (#802).

func (*Provider) UpdateWithEvaluator

func (p *Provider) UpdateWithEvaluator(authn *Authenticator, authz *Authorizer, policies *PolicySet, evaluator *PolicyEvaluator)

UpdateWithEvaluator atomically replaces all auth components including the ABAC evaluator.

type RateLimitConfig

type RateLimitConfig struct {
	RequestsPerSecond float64       // max requests per second per identity
	Burst             int           // max burst size (token bucket capacity)
	CleanupInterval   time.Duration // how often to evict idle entries (default 5m)
}

RateLimitConfig configures per-identity rate limiting.

type RateLimiter

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

RateLimiter tracks per-identity request rates.

func NewRateLimiter

func NewRateLimiter(cfg RateLimitConfig) *RateLimiter

NewRateLimiter creates a new per-identity rate limiter.

func (*RateLimiter) Allow

func (rl *RateLimiter) Allow(identity string) bool

Allow checks if the identity is within its rate limit.

type Resource

type Resource struct {
	Type       string     // "table", "column", "function"
	Name       string     // e.g. "events", "users.ssn"
	Attributes Attributes // e.g. {"classification": "SECRET", "owner": "alice"}
}

Resource describes what is being accessed.

type RoleConfig

type RoleConfig struct {
	Name   string   `yaml:"name"`   // e.g. "admin", "reader", "analyst"
	Tables []string `yaml:"tables"` // table names or "*" for all
	Allow  []string `yaml:"allow"`  // permissions: "read", "write", "admin"
}

RoleConfig defines a role in configuration.

type RoleDef

type RoleDef struct {
	Name   string
	Tables []string
	Perms  []string
}

RoleDef is the resolved definition of a role.

type RowFilters

type RowFilters map[string]string

RowFilters is a map of table name → SQL predicate for row-level security.

func RowFiltersFromContext

func RowFiltersFromContext(ctx context.Context) RowFilters

RowFiltersFromContext extracts row filter predicates from context.

type SerializedDecision

type SerializedDecision struct {
	Allowed        bool                      `json:"allowed"`
	TableDecisions map[string]*TableDecision `json:"table_decisions,omitempty"`
	MaxScanBytes   int64                     `json:"max_scan_bytes,omitempty"`
	MaxScanRows    int64                     `json:"max_scan_rows,omitempty"`
}

SerializedDecision is the pre-evaluated policy decision that travels with distributed tasks. Workers enforce these without access to policies.

type Subject

type Subject struct {
	Identity   *Identity
	Attributes Attributes // merged from JWT claims, mTLS cert fields, config, API key def
}

Subject represents the authenticated caller with attributes for policy evaluation.

type TableDecision

type TableDecision struct {
	Allowed   bool             `json:"allowed"`
	Columns   []ColumnDecision `json:"columns,omitempty"`
	RowFilter string           `json:"row_filter,omitempty"`
	Reason    string           `json:"reason,omitempty"`
	RuleID    string           `json:"rule_id,omitempty"`
}

TableDecision is the fully-resolved access decision for a table.

type TableDecisions

type TableDecisions map[string]*TableDecision

TableDecisions maps table names to their ABAC-evaluated access decisions.

func TableDecisionsFromContext

func TableDecisionsFromContext(ctx context.Context) TableDecisions

TableDecisionsFromContext extracts ABAC table decisions from context.

Jump to

Keyboard shortcuts

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