Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type CompiledRule ¶
type CompiledRule struct {
Raw Rule
// contains filtered or unexported fields
}
CompiledRule is an Rule prepared for matching. For prefix rules the trailing "*" is stripped once at compile-time so the hot path only does prefix comparisons.
Raw is the source rule as declared in configuration; the prefix internals stay unexported because they are matcher implementation detail callers should not depend on.
type Config ¶
type Config struct {
// Action applied when no rule matches the request path
DefaultPolicy Policy `yaml:"defaultPolicy" mapstructure:"defaultPolicy" jsonschema:"required,enum=allow,enum=deny"`
// Path-keyed allow/deny rules. Path matching prefers exact paths, then the longest matching prefix
Rules []Rule `yaml:"rules" mapstructure:"rules"`
}
Config is the file-shape configuration for the middleware.
DefaultPolicy applies when no rule matches the request path. It must be PolicyAllow or PolicyDeny — the empty string is rejected by NewMatcher so callers make an explicit choice.
func LoadConfigFromFile ¶
LoadConfigFromFile reads an Config from the YAML file at path.
Expected file shape:
defaultPolicy: allow # or "deny"
rules:
- path: "/api/foo/*"
allow: [admin]
deny: [visitor]
LoadConfigFromFile only decodes the YAML; semantic errors (empty paths, duplicate paths, an unknown DefaultPolicy) surface from NewMatcher. Keeping load and validation separate lets callers inspect the raw decoded shape before committing to a matcher.
type Decision ¶
type Decision struct {
Outcome Outcome
Rule *CompiledRule
Roles []string
Authed bool
}
Decision is the result of evaluating a single request against an Matcher. Rule is nil when no rule matched (the default policy applied); Roles and Authed are the values returned by the extractor.
type Matcher ¶
type Matcher struct {
// contains filtered or unexported fields
}
Matcher is a validated, compiled Config ready to drive the middleware. Build one via NewMatcher and pass it to RBAC.
Matcher is safe for concurrent use: it is read-only after construction.
func NewMatcher ¶
NewMatcher validates cfg and compiles it into a matcher.
Returns an error when:
- cfg.DefaultPolicy is neither PolicyAllow nor PolicyDeny (including the zero-value empty string).
- any Rule has an empty Path.
- two rules share the same exact path or the same prefix.
All validation errors surface here so callers can fail fast at service startup rather than at request time.
type Outcome ¶
type Outcome string
Outcome is the terminal classification of a request. It drives both the HTTP response (allow → pass-through, deny → 403, unauthenticated → 401) and the log label.
type Policy ¶
type Policy string
Policy is the fallback action applied when no Rule matches the request path. Encoded as a string so YAML / JSON configuration decodes directly without a custom unmarshaler.
type RolesExtractor ¶
RolesExtractor pulls the set of roles attached to a request, along with an authenticated flag that drives the 401-vs-403 distinction on denial.
"Roles" is a deliberately broad label: any string the caller wants to match against AllowRoles / DenyRoles fits — IAM roles, group memberships, OAuth scopes, custom claim values, and so on. The RBAC package name commits to role-shaped vocabulary; the extractor stays agnostic about where the values come from.
Contract:
- roles may be nil or empty for an authenticated caller with no matching roles; the middleware treats len(roles) == 0 as "no positive matches" rather than as unauthenticated.
- authenticated reflects whether the request carries a trusted identity at all. An extractor that cannot tell the difference should return true whenever it returns any roles, and false only on a confirmed absence of identity.
- the extractor must not mutate the request.
type Rule ¶
type Rule struct {
// Exact request path (e.g. "/api/foo/GetBar") or a prefix ending in
// '*' (e.g. "/api/foo/*"). The '*' suffix matches the empty string and any suffix.
Path string `yaml:"path" mapstructure:"path" jsonschema:"required,pattern=^/,minLength=1"`
// Roles granted access. Empty or omitted means "no positive constraint" — useful for deny-only rules.
AllowRoles []string `yaml:"allowRoles" mapstructure:"allowRoles" jsonschema:"uniqueItems,minLength=1"`
// Roles denied access. Evaluated before allowRoles; a match here rejects regardless of allowRoles.
DenyRoles []string `yaml:"denyRoles" mapstructure:"denyRoles" jsonschema:"uniqueItems,minLength=1"`
}
Rule declares allow/deny role lists for a single path pattern.
Path is either an exact request path (e.g. "/api/foo/GetBar") or a prefix ending in "*" (e.g. "/api/foo/*"). The "*" matches the empty string and any suffix: "/api/foo/*" matches both "/api/foo" and "/api/foo/anything".
Semantics applied to (AllowRoles, DenyRoles) against the request's roles:
pass iff (len(AllowRoles) == 0 || roles ∩ AllowRoles ≠ ∅)
&& roles ∩ DenyRoles == ∅
An empty AllowRoles list means "no positive constraint" — useful for deny-only rules. An empty DenyRoles list means "no explicit exclusions". Both empty means "this path is gated by having a matching rule at all", which is only meaningful when DefaultPolicy is PolicyDeny.