Ir al contenido
↑↓Navigate↵SelectescClose

Policy Obligations

Policy decision and obligation wire contract used by the PDP

Esta página aún no está disponible en tu idioma.

This page is the source of truth for the policy decision schema consumed by nexus and, optionally, Aegis for classification ceiling checks. It documents the wire contract of the vortex-policy-core crate.

A policy decision point (PDP) answers: given this subject, action, resource, and context, should the action be allowed, and with what obligations?

The PDP does not replace authentication, service scopes, or tenant-boundary checks. Those coarse checks prove who the caller is and whether the caller may reach a service surface at all. The PDP evaluates contextual authorization and data-handling rules after identity has been established.

Field Type Required Notes
query_id u128 ULID string yes For correlation in audit.
tenant_id string yes
action string yes e.g. gateway.request, model.load, config.update.
subject PolicySubject yes The caller: user, API key, service identity.
resource PolicyResource yes What is being acted on.
context map<string, cbor> yes Free-form request-time attributes (classification, model id, token estimate, etc.). For gateway.request queries this includes classification_tiers: the org’s ordered classification vocabulary (list of label strings, low to high) that the PDP uses to rank labels.
Field Type Notes
kind string user, api_key, service.
id string Stable identifier.
attrs map<string, cbor> Role, clearance, groups. max_classification lives here.
Field Type Notes
kind string request, model, provider_key, audit_event, endpoint, export.
id string?
attrs map<string, cbor> classification lives here for request resources.

For gateway.request queries the resource describes the gateway’s routed endpoint set. kind is endpoint, id is the primary (first) candidate’s endpoint key, and attrs carry classification, the primary candidate’s provider and model, and candidate_endpoints: the ordered list of every endpoint the gateway may dispatch the request to, fallbacks included, each entry a map with provider and model keys. The gateway evaluates policy once per request over this full candidate set, before any provider credential is fetched; a deny prevents dispatch to every candidate. The policy.decision audit event echoes candidate_endpoints when present.

Field Type Required Notes
query_id u128 ULID string yes Echoes PolicyQuery.query_id.
effect Effect yes See below.
obligations [Obligation] yes May be empty.
reason_code string? no Enum-like stable key, e.g. classification_ceiling_exceeded.
policy_id string? no The rule that produced this decision. Thin PDP uses thin.classification_ceiling; full policy services use stable product policy ids.
evaluated_at_unix_nanos u64 yes
  • allow
  • deny

There is no permit_with_condition effect. Conditions are expressed as obligations that the caller must apply; if the caller cannot apply them, the caller denies itself.

Field Type Notes
kind string One of the kinds below.
params map<string, cbor> Kind-specific.

The caller applies obligations before performing the action. If an obligation cannot be applied, the caller treats the decision as deny.

Supported obligation kinds:

Kind Params Applied by Notes
redact { fields: [string], strategy: "hash" | "asterisk" | "drop" } Gateway (pre-provider), Ingest (pre-write) Redacts named fields.
classify { tier: string } Gateway Sets or raises the request’s classification. Never lowers.
block {} Any caller Stop processing and return an error. Equivalent to effect: deny but routed as a policy-authored stop.
audit_tag { tags: [string] } Any caller Adds tags to the emitted audit event.
rate_limit { tokens_per_minute: u32 } Gateway Applies an additional rate limit for this request.
route_constraint { allowed_providers: [string] } Gateway Restricts routing to the named providers.

New obligation kinds are a non-breaking change only if consumers that do not recognize a kind treat the decision as deny by default (the “unknown obligation means deny” rule).

Classification vocabularies are tenant configuration, carried on every query rather than held by the PDP. The PDP ranks the resource classification and the subject max_classification within the classification_tiers list from the query context and fails closed:

Condition Decision
classification_tiers missing or invalid deny, reason classification_vocabulary_missing
Request label or ceiling missing deny, reason classification_label_missing
Either label not defined by the vocabulary deny, reason classification_label_unknown
Request label outranks the ceiling deny, reason classification_ceiling_exceeded

PolicyQuery and PolicyDecision are encoded with deterministic CBOR, using the same deterministic-map rules as the audit event contract. Cross-process transport is gRPC.

Every PDP evaluation MUST produce an audit event of kind policy.decision. The event attributes include query_id, effect, action, resource_kind, resource_id, reason_code, policy_id, and a compact obligation summary. Denied decisions are represented by effect = "deny" rather than by a separate event kind.