policy

package
v0.7.2 Latest Latest
Warning

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

Go to latest
Published: Aug 19, 2026 License: GPL-3.0 Imports: 5 Imported by: 0

Documentation

Overview

Package policy decides whether a live resource query is permitted by the cluster owner's agent configuration.

This is a second gate, independent of Kubernetes RBAC. RBAC answers "may this ServiceAccount read the resource"; this answers "did the cluster owner agree that the Kubexa platform may read it". Both must say yes.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func MatchesName

func MatchesName(name string, patterns []string) bool

MatchesName reports whether an object name satisfies the name patterns a Decision carried out. The executor calls it once per LIST row, because a LIST carries no name at decision time.

It is a package function over patterns rather than a Policy method taking a namespace, and that is the whole point. A method would walk the rule list a second time, and when the namespace it received differed from the one Decide was evaluated against it could select a MORE PERMISSIVE rule than the one that authorized the query -- admitting a row a direct get is denied. Passing the authorizing rule's patterns through the Decision makes one rule selection per query, so there is no second selection to diverge.

Types

type Decision

type Decision struct {
	Allowed bool
	// RedactSecrets tells the executor whether to strip Secret values.
	RedactSecrets bool
	// LabelSelector and FieldSelector come from the matching rule and are
	// ANDed with whatever the request carried.
	LabelSelector string
	FieldSelector string
	// NamePatterns are the authorizing rule's name patterns. The executor
	// filters LIST rows against these via MatchesName, so row filtering uses
	// the same rule that permitted the query -- see MatchesName's comment for
	// why re-consulting the policy per row would be a data-exposure bug.
	NamePatterns []string
	// WildcardRule reports that the authorizing rule was a wildcard
	// (resources: ["*"]) rather than one naming this resource. It changes
	// nothing about what is permitted; it tells the caller that ref.Resource
	// was chosen by the requester, not by the owner's config, so anything
	// keyed on it must stay bounded. The executor uses it to decide whether
	// the resource is safe to use as a Prometheus label -- see metrics.go.
	WildcardRule bool
	// Reason explains a denial in terms the operator can act on. Empty when
	// allowed.
	Reason string
}

Decision is the outcome of evaluating one query against the policy.

type Policy

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

Policy is an immutable, compiled rule set. It is built once at startup and never mutated: the agent has no config hot-reload, and a policy that can change at runtime is a policy nobody can reason about.

func Compile

func Compile(root *pkgconfig.Config) (*Policy, error)

Compile builds a Policy from the agent's root configuration, resolving the inheritance from collect.state described in pkg/config/query.go.

func (*Policy) AllowsAnyGet

func (p *Policy) AllowsAnyGet(group, version, resource string) bool

AllowsAnyGet reports whether any rule grants get on this resource, in any namespace. See AllowsAnyList for why this is coarser than Decide.

func (*Policy) AllowsAnyList

func (p *Policy) AllowsAnyList(group, version, resource string) bool

AllowsAnyList reports whether any rule grants list on this resource, in any namespace. It answers the catalog's question -- "could a query for this type ever succeed" -- and is deliberately coarser than Decide: a per-GVR boolean cannot express a namespace-scoped policy, so Decide stays authoritative at request time.

A wildcard rule changes this coarseness's scale, not its shape: even a namespace-scoped wildcard answers true for every GVR the capability reporter discovers, so the published catalogue reads as "policy allows this" cluster-wide, while Decide still refuses every namespace but the one the rule names.

func (*Policy) Decide

func (p *Policy) Decide(ref Ref, verb Verb, namespace, name string) Decision

Decide evaluates one query.

Rules are evaluated in configuration order and the FIRST match decides the whole outcome. Because no rule can deny, first-match-wins gives the same allow/deny answer as treating the rules as additive; the ordering exists so that when two rules match, it is unambiguous whose selectors apply.

name is empty for a LIST. A name pattern therefore cannot deny a LIST here; the executor applies it to the returned rows instead.

func (*Policy) UnredactedWildcardRuleIDs added in v0.6.0

func (p *Policy) UnredactedWildcardRuleIDs() []string

UnredactedWildcardRuleIDs names the wildcard rules whose grant includes readable Secret values -- the exact condition the startup warning in cmd/agent fires on, expressed here so it can be tested.

A wildcard rule covers secrets like everything else; with redact_secrets off, their values leave the cluster. Either half alone is a deliberate choice an operator may well have made, so nothing is reported unless both hold. Redaction on returns nothing: the wildcard is then no wider than the operator asked for.

func (*Policy) WildcardRuleIDs added in v0.6.0

func (p *Policy) WildcardRuleIDs() []string

WildcardRuleIDs names the compiled rules that permit every resource.

It exists for one caller: the startup warning in cmd/agent. A wildcard rule covers secrets like everything else, and paired with unredacted Secret values that is the widest read policy this agent can hold -- not something an operator should first learn from a screen. A disabled policy permits nothing, so it reports nothing.

type Ref

type Ref struct {
	Group    string // "" for the core group
	Version  string
	Resource string // plural
}

Ref names one API resource the way the dynamic client addresses it.

type Verb

type Verb string

Verb is the operation a query performs. The set is closed: this path is read-only and nothing here requests a verb the agent's ClusterRole lacks.

const (
	VerbList Verb = "list"
	VerbGet  Verb = "get"
)

Jump to

Keyboard shortcuts

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