pdp

package
v2.7.1 Latest Latest
Warning

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

Go to latest
Published: May 14, 2026 License: Apache-2.0 Imports: 15 Imported by: 0

Documentation

Overview

Package pdp implements the Policy Decision Point for local policy evaluation. It provides bundle fetching, OPA-based evaluation, and background refresh management.

Index

Constants

View Source
const (
	// DefaultPollInterval is the base interval between bundle refresh attempts.
	DefaultPollInterval = 30 * time.Second

	// DefaultMaxAge is the maximum acceptable bundle age before it's considered stale.
	DefaultMaxAge = 10 * time.Minute
)

Variables

This section is empty.

Functions

This section is empty.

Types

type BundleClient

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

BundleClient pulls OPA policy bundles from the capiscio-server bundle endpoint.

func NewBundleClient

func NewBundleClient(bundleURL, apiKey string, opts ...BundleClientOption) (*BundleClient, error)

NewBundleClient creates a new bundle pull client. The bundleURL should include the full path, e.g. "https://api.capisc.io/v1/bundles/{workspace_id}". The apiKey is sent as X-Capiscio-Registry-Key header.

func (*BundleClient) BundleURL

func (bc *BundleClient) BundleURL() string

BundleURL returns the configured bundle endpoint URL.

func (*BundleClient) Fetch

func (bc *BundleClient) Fetch(ctx context.Context) (*BundleContents, error)

Fetch pulls the current bundle from the server. Returns the parsed bundle contents or an error if the fetch fails. A nil bundle with a nil error is NOT a valid return — always returns one or the other.

type BundleClientOption

type BundleClientOption func(*BundleClient)

BundleClientOption configures a BundleClient.

func WithBundleHTTPClient

func WithBundleHTTPClient(c *http.Client) BundleClientOption

WithBundleHTTPClient sets a custom HTTP client for the bundle client. A nil value is ignored.

func WithBundleLogger

func WithBundleLogger(l *slog.Logger) BundleClientOption

WithBundleLogger sets the logger for the bundle client. A nil value is ignored.

type BundleContents

type BundleContents struct {
	Modules  map[string]string      `json:"modules"`            // filename → Rego source
	Data     map[string]interface{} `json:"data"`               // OPA data document
	Revision string                 `json:"revision,omitempty"` // content-addressable revision hash
}

BundleContents holds the compiled policy bundle from the capiscio-server. This mirrors the server's bundle format to allow in-process OPA evaluation.

type BundleManager

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

BundleManager handles background polling, hot-swapping, and staleness detection for OPA policy bundles. It coordinates BundleClient (pull) and OPALocalClient (evaluate).

Staleness behavior per enforcement mode (PM-mandated):

  • EM-OBSERVE: Stale bundles are evaluated; violations logged, never blocked.
  • EM-GUARD: Stale bundles ARE still evaluated (allow with warning).
  • EM-STRICT: Stale bundles are discarded; all requests denied until fresh bundle loaded.

func NewBundleManager

func NewBundleManager(client *BundleClient, evaluator *OPALocalClient, opts ...BundleManagerOption) *BundleManager

NewBundleManager creates a new bundle refresh manager. The manager coordinates periodic bundle fetching (via BundleClient) and hot-swapping into the local evaluator (via OPALocalClient).

func (*BundleManager) Evaluate

Evaluate runs a policy decision through the local OPA evaluator and applies bundle staleness checks per enforcement mode (RFC-005 Appendix B §B.4).

Staleness is checked after OPA evaluation succeeds — this preserves the distinction between PDP failure (error return) and stale-but-functional data (synthetic DENY). If the bundle is stale:

  • EM-STRICT: returns a synthetic DENY with error_code BUNDLE_STALE.
  • EM-OBSERVE/EM-GUARD/EM-DELEGATE: emits TelemetryBundleStale, returns the OPA result.

This implements pip.PDPClient so it can be used directly by the PEP gateway.

func (*BundleManager) IsStale

func (m *BundleManager) IsStale() bool

IsStale reports whether the current bundle has exceeded the max age threshold. Returns true if no bundle is loaded.

func (*BundleManager) RefreshNow

func (m *BundleManager) RefreshNow(ctx context.Context) error

RefreshNow triggers an immediate bundle fetch and load, outside the polling loop. Returns an error if the fetch or load fails.

func (*BundleManager) Start

func (m *BundleManager) Start(ctx context.Context)

Start begins background bundle polling. Returns immediately. Call Stop to terminate the polling goroutine.

func (*BundleManager) Stop

func (m *BundleManager) Stop()

Stop terminates background polling. Safe to call multiple times.

type BundleManagerOption

type BundleManagerOption func(*BundleManager)

BundleManagerOption configures a BundleManager.

func WithEnforcementMode

func WithEnforcementMode(em pip.EnforcementMode) BundleManagerOption

WithEnforcementMode sets the enforcement mode for staleness behavior.

func WithManagerLogger

func WithManagerLogger(l *slog.Logger) BundleManagerOption

WithManagerLogger sets the logger for the bundle manager.

func WithMaxAge

func WithMaxAge(d time.Duration) BundleManagerOption

WithMaxAge sets the maximum acceptable bundle age before staleness.

func WithPollInterval

func WithPollInterval(d time.Duration) BundleManagerOption

WithPollInterval sets the base polling interval.

type OPALocalClient

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

OPALocalClient implements pip.PDPClient using an embedded OPA evaluator. It evaluates policy decisions in-process using Rego modules and data pulled from the capiscio-server bundle endpoint.

Thread-safety: Evaluate takes a read lock, LoadBundle takes a write lock. Multiple concurrent evaluations proceed without blocking each other.

func NewOPALocalClient

func NewOPALocalClient(opts ...OPALocalOption) *OPALocalClient

NewOPALocalClient creates a new local OPA evaluator. The client starts without a loaded policy — call LoadBundle before evaluating.

func (*OPALocalClient) BundleAge

func (c *OPALocalClient) BundleAge() time.Duration

BundleAge returns the duration since the last bundle was loaded. Returns 0 if no bundle has been loaded.

func (*OPALocalClient) Evaluate

Evaluate sends a PIP decision request through the local OPA evaluator. Returns an error if no bundle is loaded (the PEP handles this per enforcement mode).

func (*OPALocalClient) HasBundle

func (c *OPALocalClient) HasBundle() bool

HasBundle reports whether a policy bundle is currently loaded.

func (*OPALocalClient) LoadBundle

func (c *OPALocalClient) LoadBundle(ctx context.Context, modules map[string]string, data map[string]interface{}) error

LoadBundle compiles Rego modules and data into a prepared query. This takes a write lock and atomically replaces the current prepared query. Callers should use BundleContents from a successful BundleClient.Fetch.

type OPALocalOption

type OPALocalOption func(*OPALocalClient)

OPALocalOption configures an OPALocalClient.

func WithOPALogger

func WithOPALogger(l *slog.Logger) OPALocalOption

WithOPALogger sets the logger for the OPA evaluator.

Jump to

Keyboard shortcuts

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