AuthZEN Cert Scenario October 2026
Olivier Informational [Page]
Workgroup:
OpenID AuthZEN
Published:
Author:
A. Olivier
Cerbos

AuthZEN Authorization API 1.0 - Certification Scenario

Abstract

This document defines the conformance certification scenario for Policy Decision Points (PDPs) implementing the AuthZEN Authorization API 1.0. It specifies a minimal fixture and a set of certification levels -- Basic, Batch, Search, and Discovery -- that verify protocol conformance: that a PDP correctly accepts well-formed requests and returns correctly structured responses per the specification. The scenario does not judge the implementer's own policy logic, which is out of scope. To confirm that a PDP genuinely evaluates requests rather than returning canned responses, the harness validates decision values only for the small, fixed set of cases mandated by the fixture.

▲

Table of Contents

1. Introduction

This document defines the conformance certification scenario for Policy Decision Points (PDPs) implementing the AuthZEN Authorization API 1.0 [AUTHZEN] specification.

The certification verifies protocol conformance: that the PDP correctly accepts well-formed requests and returns correctly structured responses per the specification. It does not judge the implementer's own policy logic -- whether a PDP permits or denies an arbitrary request is a function of that policy and is out of scope.

There is one deliberate, bounded exception. To confirm that a PDP genuinely evaluates requests rather than returning canned responses, the harness validates the actual decision values for a small, fixed set of cases -- but only those mandated by the fixture policy defined in Section 4.4, never the implementer's own rules. Every other request uses fixture identifiers but has only its response structure checked.

To exercise the protocol, the PDP under test must be loaded with this minimal policy and dataset so that the harness can receive real responses. This scenario defines the required fixture in Section 4. The fixture is deliberately small -- it exists to give the PDP something to evaluate, not to exercise the implementer's own policy logic.

2. Notational Conventions

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.

3. Certification Levels

A PDP MAY certify at one or more of the following levels. Each level has sub-levels that distinguish tests using only required identifier fields (Core) from tests that require properties evaluation (Properties):

Table 1
Level Sub-level APIs Covered Description
Basic Core Access Evaluation Single decision using required fields only
Basic Properties Access Evaluation Single decision using entity properties
Batch Core Access Evaluations Multiple decisions using required fields only
Batch Properties Access Evaluations Multiple decisions using entity properties and default value merging
Search Core Subject, Resource, Action Search Discovery using required fields only
Search Properties Subject, Resource, Action Search Discovery using entity properties
Discovery — PDP Metadata Well-known configuration endpoint

Prerequisites:

3.1. Test ID Matrix

Table 2
Certification Sub-level Tests
Basic Core Section 5.2.1, Section 5.2.2, Section 5.2.3, Section 5.2.8, Section 5.2.9, Section 5.3, Section 5.4, Section 5.5, Section 5.6
Basic Properties Section 5.2.4, Section 5.2.5, Section 5.2.6, Section 5.2.7
Batch Core Section 6.2.1, Section 6.2.2, Section 6.2.5, Section 6.2.6, Section 6.3, Section 6.4
Batch Properties Section 6.2.3, Section 6.2.4, Section 6.2.7
Search Core Section 7.2.1, Section 7.2.2, Section 7.2.3, Section 7.3.1, Section 7.3.2, Section 7.3.3, Section 7.4.1, Section 7.4.2, Section 7.5, Section 7.6, Section 7.7
Search Properties Section 7.2.4, Section 7.3.4, Section 7.4.3
Discovery Section 9

The response format, error handling, header handling, and idempotency requirements (Section 5.3, Section 5.4, Section 5.5, Section 5.6) and the transport requirements (Section 8) apply to all certification sub-levels.

4. Required Fixture

The PDP under test MUST be configured with the following minimal fixture so that the harness can exercise all API endpoints against known entity identifiers and receive valid responses.

4.1. Subjects

The PDP MUST recognise the following subjects:

Table 3
Subject ID Subject Type Properties
alice user  
bob user role: "admin"

4.2. Resources

The PDP MUST recognise the following resources:

Table 4
Resource ID Resource Type Properties
record-1 record status: "active"
record-2 record status: "archived"

4.3. Actions

The PDP MUST recognise the following action names:

Table 5
Action Name Properties
read  
write  
delete soft: true or false

4.4. Required Policy Behaviour

The PDP MUST implement a policy such that:

Core (identifier fields only):

  1. For subject alice performing action read on resource record-1: the decision MUST be true.

  2. For subject alice performing action write on resource record-1: the decision MUST be true.

  3. For subject bob performing action read on resource record-1: the decision MUST be true.

  4. For subject bob performing action write on resource record-1: the decision MUST be false.

Properties (require properties evaluation):

  1. For subject alice performing action write on a resource with properties.status = "archived": the decision MUST be false.

  2. For a subject with properties.role = "admin" performing action write on a resource with properties.status = "archived": the decision MUST be true.

  3. For subject alice performing action delete with properties.soft = true on resource record-1: the decision MUST be true.

  4. For subject alice performing action delete with properties.soft = false on resource record-1: the decision MUST be false.

Rules 1–4 use only identifier fields. Rules 5–8 require the PDP to evaluate properties values passed in the request.

These eight decisions are the only decision values the harness validates. All other requests to the PDP use fixture entity identifiers but the harness only validates response structure, not the decision value.

How the PDP implements this policy is entirely at the implementer's discretion. The fixture could be a single hard-coded rule, a full RBAC model, or anything in between.

4.5. Search Fixture Requirements (Search Certification Only)

For Search certification, the fixture MUST be configured such that:

The requirements below are labelled S1–S6 to distinguish them from the decision rules in Section 4.4 (which are referenced as "decision rule N").

Core:

  • S1 — A Subject Search for subjects of type user who can perform read on resource record-1 MUST return a non-empty results array that includes at least alice and bob.

  • S2 — A Resource Search for resources of type record that subject alice can perform read on MUST return a non-empty results array that includes at least record-1.

  • S3 — An Action Search for subject alice on resource record-1 MUST return a non-empty results array that includes at least read and write (per decision rules 1 and 2).

Properties:

  • S4 — A Subject Search for subjects of type user who can perform write on resource record-2 with properties.status = "archived" MUST return a non-empty results array that includes at least bob (per decision rule 6).

  • S5 — A Resource Search for resources of type record that subject bob with properties.role = "admin" can perform write on MUST return a non-empty results array that includes at least record-2 (per decision rule 6).

  • S6 — An Action Search for subject bob with properties.role = "admin" on resource record-2 with properties.status = "archived" MUST return a non-empty results array that includes at least write (per decision rule 6).

  • Note: delete is excluded from the Properties Action Search fixture. Action Search omits the action key from requests per the spec, so action.properties.soft cannot be provided. Action Search results return action names only, without constraining properties.

These conditions ensure the harness can validate that search responses contain structurally valid, non-empty result sets. The harness validates that the expected entities appear in the results but does not reject additional results.

4.6. Fixture Notes

  • Rules 1-4 use identifier fields only. The harness sends type, id, and name without properties. The PDP may resolve attributes internally or the policy may not require them.

  • Rules 5-8 require properties. The harness sends properties on subject, resource, and/or action. The PDP MUST evaluate these values to produce the correct decision.

  • The context field is not required for fixture decisions. The eight required decisions in Section 4.4 MUST hold regardless of whether context is present or absent in the request.

  • Additional entities are permitted. The PDP MAY have additional subjects, resources, actions, and policies beyond the fixture. The harness only sends requests using the fixture identifiers defined above.

5. Basic Certification: Access Evaluation API

5.1. Endpoint

The PDP MUST expose the Access Evaluation API at:

POST /access/v1/evaluation

Or at a path discoverable via the PDP metadata endpoint (see Section 9).

5.2. Request Acceptance

The PDP MUST accept a valid Access Evaluation request containing subject, action, and resource and return an HTTP 200 response.

Core (Basic Core certification):

5.2.1. Fixture request -- permit decision

Request:

{
  "subject": { "type": "user", "id": "alice" },
  "action": { "name": "read" },
  "resource": { "type": "record", "id": "record-1" }
}

Expected: HTTP 200. Response body:

{
  "decision": true
}

This is a fixture request (Section 4.4, rule 1). The harness validates both the response structure and the decision value.

5.2.2. Fixture request -- deny decision

Request:

{
  "subject": { "type": "user", "id": "bob" },
  "action": { "name": "write" },
  "resource": { "type": "record", "id": "record-1" }
}

Expected: HTTP 200. Response body:

{
  "decision": false
}

This is a fixture request (Section 4.4, rule 4). The harness validates both the response structure and the decision value.

5.2.3. Request with optional context

The PDP MUST accept a request that includes the optional context field without error. The fixture decision MUST NOT change.

Request:

{
  "subject": { "type": "user", "id": "alice" },
  "action": { "name": "read" },
  "resource": { "type": "record", "id": "record-1" },
  "context": {
    "time": "2025-06-27T18:03-07:00",
    "ip": "192.168.1.1"
  }
}

Expected: HTTP 200, "decision": true.

Properties (Basic Properties certification):

5.2.4. Fixture request -- deny based on properties

The PDP MUST evaluate properties values passed in the request. This test validates rule 5 from Section 4.4.

Request:

{
  "subject": { "type": "user", "id": "alice" },
  "action": { "name": "write" },
  "resource": {
    "type": "record",
    "id": "record-2",
    "properties": {
      "status": "archived"
    }
  }
}

Expected: HTTP 200. Response body:

{
  "decision": false
}

This is a fixture request (Section 4.4, rule 5). The harness validates both the response structure and the decision value. The deny is based on properties.status being "archived", not on the resource identifier.

5.2.5. Fixture request -- permit based on subject properties

The PDP MUST evaluate properties on the subject. This test validates rule 6 from Section 4.4.

Request:

{
  "subject": {
    "type": "user",
    "id": "bob",
    "properties": {
      "role": "admin"
    }
  },
  "action": { "name": "write" },
  "resource": {
    "type": "record",
    "id": "record-2",
    "properties": {
      "status": "archived"
    }
  }
}

Expected: HTTP 200. Response body:

{
  "decision": true
}

This is a fixture request (Section 4.4, rule 6). The harness validates both the response structure and the decision value. The permit is based on subject.properties.role being "admin", which overrides the archived resource constraint from rule 5.

5.2.6. Fixture request -- permit based on action properties

The PDP MUST evaluate properties on the action. This test validates rule 7 from Section 4.4.

Request:

{
  "subject": { "type": "user", "id": "alice" },
  "action": {
    "name": "delete",
    "properties": {
      "soft": true
    }
  },
  "resource": { "type": "record", "id": "record-1" }
}

Expected: HTTP 200. Response body:

{
  "decision": true
}

This is a fixture request (Section 4.4, rule 7). Soft delete is permitted.

5.2.7. Fixture request -- deny based on action properties

This test validates rule 8 from Section 4.4.

Request:

{
  "subject": { "type": "user", "id": "alice" },
  "action": {
    "name": "delete",
    "properties": {
      "soft": false
    }
  },
  "resource": { "type": "record", "id": "record-1" }
}

Expected: HTTP 200. Response body:

{
  "decision": false
}

This is a fixture request (Section 4.4, rule 8). Hard delete is denied.

Core (continued — structural tests for Basic Core certification):

5.2.8. Request with additional properties

The PDP MUST accept a request where entities include additional properties beyond those required by the fixture.

Request:

{
  "subject": {
    "type": "user",
    "id": "alice",
    "properties": {
      "department": "Sales",
      "role": "manager"
    }
  },
  "action": {
    "name": "read",
    "properties": {
      "method": "GET"
    }
  },
  "resource": {
    "type": "record",
    "id": "record-1",
    "properties": {
      "status": "active",
      "owner": "bob"
    }
  }
}

Expected: HTTP 200, "decision": true.

5.2.9. Request with unknown fields

Per the specification's forward-compatibility requirement, the PDP MUST ignore unrecognised fields in the request body without error.

Request:

{
  "subject": { "type": "user", "id": "alice" },
  "action": { "name": "read" },
  "resource": { "type": "record", "id": "record-1" },
  "foo": "bar",
  "futureField": { "nested": true }
}

Expected: HTTP 200, "decision": true.

5.3. Response Format

5.3.1. Decision field is required

The response MUST contain a decision field with a boolean value.

The harness validates:

  • The response body is valid JSON.

  • The decision field is present.

  • The decision field is a boolean (true or false).

5.3.2. Response context is permitted

The PDP MAY include a context field in the response. If present, it MUST be a JSON object. The harness does not validate the contents of the response context.

5.4. Error Handling

5.4.1. Missing required fields

The PDP MUST return HTTP 400 when a required field is missing from the request.

Request (missing subject):

{
  "action": { "name": "read" },
  "resource": { "type": "record", "id": "record-1" }
}

Expected: HTTP 400.

Request (missing action):

{
  "subject": { "type": "user", "id": "alice" },
  "resource": { "type": "record", "id": "record-1" }
}

Expected: HTTP 400.

Request (missing resource):

{
  "subject": { "type": "user", "id": "alice" },
  "action": { "name": "read" }
}

Expected: HTTP 400.

5.4.2. Missing required sub-fields

The PDP MUST return HTTP 400 when a required sub-field is missing.

Request (subject missing type):

{
  "subject": { "id": "alice" },
  "action": { "name": "read" },
  "resource": { "type": "record", "id": "record-1" }
}

Expected: HTTP 400.

Request (subject missing id):

{
  "subject": { "type": "user" },
  "action": { "name": "read" },
  "resource": { "type": "record", "id": "record-1" }
}

Expected: HTTP 400.

Request (action missing name):

{
  "subject": { "type": "user", "id": "alice" },
  "action": {},
  "resource": { "type": "record", "id": "record-1" }
}

Expected: HTTP 400.

Request (resource missing type):

{
  "subject": { "type": "user", "id": "alice" },
  "action": { "name": "read" },
  "resource": { "id": "record-1" }
}

Expected: HTTP 400.

Request (resource missing id):

{
  "subject": { "type": "user", "id": "alice" },
  "action": { "name": "read" },
  "resource": { "type": "record" }
}

Expected: HTTP 400.

5.4.3. Invalid content type

The PDP MUST return HTTP 400 when the request Content-Type is not application/json.

5.4.4. Malformed JSON

The PDP MUST return HTTP 400 when the request body is not valid JSON.

5.4.5. Empty request body

The PDP MUST return HTTP 400 when the request body is empty.

5.4.6. Invalid field types

The PDP MUST return HTTP 400 when a field has an invalid type.

Request (subject is string instead of object):

{
  "subject": "alice",
  "action": { "name": "read" },
  "resource": { "type": "record", "id": "record-1" }
}

Expected: HTTP 400.

Request (action.name is number instead of string):

{
  "subject": { "type": "user", "id": "alice" },
  "action": { "name": 123 },
  "resource": { "type": "record", "id": "record-1" }
}

Expected: HTTP 400.

5.5. Header Handling

5.5.1. X-Request-ID echo

If the request includes an X-Request-ID header, the PDP MUST include the same X-Request-ID value in the response headers.

5.5.2. X-Request-ID absent

If the request does not include an X-Request-ID header, the PDP MUST NOT fail. The PDP MAY generate its own X-Request-ID in the response.

5.6. Idempotency

The harness sends the same fixture request multiple times consecutively. The PDP MUST return the same decision value each time.

6. Batch Certification: Access Evaluations API

Batch Core certification requires Basic Core as a prerequisite. Batch Properties certification requires Basic Properties as a prerequisite.

6.1. Endpoint

The PDP MUST expose the Access Evaluations API at:

POST /access/v1/evaluations

Or at a path discoverable via the PDP metadata endpoint.

6.2. Request Acceptance

Core (Batch Core certification):

6.2.1. Batch request with evaluations array

Request:

{
  "subject": { "type": "user", "id": "alice" },
  "action": { "name": "read" },
  "evaluations": [
    {
      "resource": { "type": "record", "id": "record-1" }
    },
    {
      "resource": { "type": "record", "id": "record-2" }
    }
  ]
}

Expected: HTTP 200 with a response body containing an evaluations array of two decision objects. Each object MUST contain a decision boolean.

{
  "evaluations": [
    { "decision": <boolean> },
    { "decision": <boolean> }
  ]
}

This case validates response structure only: the harness asserts that evaluations is an array of two objects, each containing a decision boolean. It does not assert the decision values. The first evaluation (alice/read/record-1) corresponds to fixture rule 1 (Section 4.4) and the second (alice/read/record-2) is unspecified by the fixture and therefore implementer-defined. Decision values in batch responses are validated separately in Section 6.2.2.

6.2.2. Batch with fixture decisions validated

Request:

{
  "subject": { "type": "user", "id": "bob" },
  "resource": { "type": "record", "id": "record-1" },
  "evaluations": [
    {
      "action": { "name": "read" }
    },
    {
      "action": { "name": "write" }
    }
  ]
}

Expected: HTTP 200.

{
  "evaluations": [
    { "decision": true },
    { "decision": false }
  ]
}

The harness validates both structure and decision values because both requests correspond to fixture rules (Section 4.4, rules 3 and 4). This also validates response ordering -- read (permit) must be first, write (deny) must be second.

Properties (Batch Properties certification):

6.2.3. Batch with properties validated

This test validates that the PDP evaluates properties values in batch requests (Section 4.4, rules 2 and 5).

Request:

{
  "subject": { "type": "user", "id": "alice" },
  "action": { "name": "write" },
  "evaluations": [
    {
      "resource": {
        "type": "record",
        "id": "record-1",
        "properties": { "status": "active" }
      }
    },
    {
      "resource": {
        "type": "record",
        "id": "record-2",
        "properties": { "status": "archived" }
      }
    }
  ]
}

Expected: HTTP 200.

{
  "evaluations": [
    { "decision": true },
    { "decision": false }
  ]
}

The first evaluation permits (alice can write to active records). The second evaluation denies (rule 5: archived status blocks write). This validates that properties are evaluated per-item in the batch.

6.2.4. Batch with subject properties validated

This test validates that the PDP evaluates subject properties in batch requests (Section 4.4, rules 5 and 6).

Request:

{
  "action": { "name": "write" },
  "resource": {
    "type": "record",
    "id": "record-2",
    "properties": { "status": "archived" }
  },
  "evaluations": [
    {
      "subject": { "type": "user", "id": "alice" }
    },
    {
      "subject": {
        "type": "user",
        "id": "bob",
        "properties": { "role": "admin" }
      }
    }
  ]
}

Expected: HTTP 200.

{
  "evaluations": [
    { "decision": false },
    { "decision": true }
  ]
}

The first evaluation denies (rule 5: alice cannot write to archived). The second evaluation permits (rule 6: admin role overrides archived constraint). This validates that subject properties are evaluated per-item in the batch.

Core (continued — Batch Core certification):

6.2.5. Batch with fully specified evaluations (no defaults)

Request:

{
  "evaluations": [
    {
      "subject": { "type": "user", "id": "alice" },
      "action": { "name": "read" },
      "resource": { "type": "record", "id": "record-1" }
    },
    {
      "subject": { "type": "user", "id": "bob" },
      "action": { "name": "write" },
      "resource": { "type": "record", "id": "record-1" }
    }
  ]
}

Expected: HTTP 200. Evaluations array of two elements with decisions true and false respectively.

{
  "evaluations": [
    { "decision": true },
    { "decision": false }
  ]
}

6.2.6. Batch with context inheritance

Top-level context applies to all evaluations unless overridden per-evaluation.

Request:

{
  "subject": { "type": "user", "id": "alice" },
  "action": { "name": "read" },
  "context": {
    "time": "2025-06-27T18:03-07:00"
  },
  "evaluations": [
    {
      "resource": { "type": "record", "id": "record-1" }
    },
    {
      "resource": { "type": "record", "id": "record-2" },
      "context": {
        "time": "2025-06-27T19:00-07:00",
        "source": "batch-override"
      }
    }
  ]
}

Expected: HTTP 200 with two evaluations. The harness validates that the request is accepted; the decision values are not validated (not fixture rules).

{
  "evaluations": [
    { "decision": <boolean> },
    { "decision": <boolean> }
  ]
}

Properties (continued — Batch Properties certification):

6.2.7. Batch with top-level default inheritance

Per the specification, the top-level subject, action, and resource keys provide default values for each evaluation. An evaluation that omits one of these keys inherits the entire top-level value; an evaluation that provides a key overrides the top-level default at the entity level (whole-object replacement). Because subject, action, and resource are required for a valid evaluation, any key absent from an evaluation object MUST be supplied at the top level. There is no sub-field merging: a per-evaluation entity either is complete or is absent (inherited whole).

Request:

{
  "subject": { "type": "user", "id": "alice" },
  "action": { "name": "write" },
  "resource": { "type": "record", "id": "record-1", "properties": { "status": "active" } },
  "evaluations": [
    {},
    {
      "resource": {
        "type": "record",
        "id": "record-2",
        "properties": { "status": "archived" }
      }
    }
  ]
}

Expected: HTTP 200.

{
  "evaluations": [
    { "decision": true },
    { "decision": false }
  ]
}

The first evaluation is empty ({}), so it inherits the entire top-level subject, action, and resource — alice writing the active resource record-1. Alice can write to active records (decision rule 2), so the decision is true. The second evaluation supplies a complete resource, replacing the top-level default wholesale with the archived record-2. Alice cannot write to archived records (decision rule 5), so the decision is false. This validates entity-level default inheritance and whole-object override.

6.3. Response Format

6.3.1. Response array length matches request

The evaluations array in the response MUST have the same number of elements as the evaluations array in the request.

6.3.2. Response ordering

The evaluations array in the response MUST be in the same order as the evaluations array in the request.

6.3.3. Each evaluation contains a decision

Each element in the response evaluations array MUST contain a decision field with a boolean value. Each element MAY contain a context field.

6.3.4. Top-level decision field

When the response contains an evaluations array, the top-level decision field SHOULD be omitted. If present, the harness ignores it.

6.4. Error Handling

6.4.1. Evaluation-level errors (execute_all semantic)

This test exercises the default execute_all evaluation semantic, under which the PDP executes every evaluation in the array and returns all results in request order. Per the specification, a failed evaluation under execute_all may be denoted by "decision": false, optionally with a reason code in that item's context. The harness pins the semantic explicitly via options.evaluations_semantic and treats this denotation as the expected behavior for certification.

For an otherwise valid batch payload in which a single evaluation is missing a required field, the PDP MUST return HTTP 200 with an evaluations array matching the request cardinality and ordering (Section 6.3.1, Section 6.3.2), and MUST denote the failed item with "decision": false (it MAY include error details in that item's context).

  • Note: The specification permits, but does not require, this decision: false denotation for per-item failures under execute_all, and it separately requires a 400 Bad Request when a required attribute is omitted from a (whole) request. This scenario adopts the per-item execute_all interpretation for failures inside an otherwise valid batch; transport-level or whole-payload failures (for example malformed JSON, or a request that is invalid at the top level) remain HTTP error responses as defined in Section 5.4. The short-circuit semantics (deny_on_first_deny, permit_on_first_permit) are out of scope for this test.

Request (second evaluation missing resource):

{
  "subject": { "type": "user", "id": "alice" },
  "action": { "name": "read" },
  "options": { "evaluations_semantic": "execute_all" },
  "evaluations": [
    {
      "resource": { "type": "record", "id": "record-1" }
    },
    {}
  ]
}

Expected: HTTP 200 with two evaluations. The second evaluation MUST have "decision": false.

{
  "evaluations": [
    { "decision": true },
    { "decision": false, "context": <context> }
  ]
}

6.4.2. Missing evaluations array (backwards-compatible)

Per the specification, if the evaluations array is not present, the Access Evaluations endpoint behaves in a backwards-compatible manner with the single Access Evaluation API. The PDP MUST accept a valid request with subject, action, and resource at the top level and return an Access Evaluation response.

Request (missing evaluations):

{
  "subject": { "type": "user", "id": "alice" },
  "action": { "name": "read" },
  "resource": { "type": "record", "id": "record-1" }
}

Expected: HTTP 200. Response body:

{
  "decision": true
}

This is a fixture request (Section 4.4, rule 1). The harness validates both the response structure and the decision value.

6.4.3. Empty evaluations array (backwards-compatible)

Per the specification, if the evaluations array is empty, the Access Evaluations endpoint behaves in a backwards-compatible manner with the single Access Evaluation API. The PDP MUST accept a valid request with subject, action, and resource at the top level and return an Access Evaluation response.

Request (empty evaluations):

{
  "subject": { "type": "user", "id": "alice" },
  "action": { "name": "read" },
  "resource": { "type": "record", "id": "record-1" },
  "evaluations": []
}

Expected: HTTP 200. Response body:

{
  "decision": true
}

This is a fixture request (Section 4.4, rule 1). The harness validates both the response structure and the decision value.

7. Search Certification

7.1. Endpoints

The PDP MUST expose the following Search APIs:

POST /access/v1/search/subject
POST /access/v1/search/resource
POST /access/v1/search/action

Or at paths discoverable via the PDP metadata endpoint.

Core (Search Core certification):

7.2.1. Valid subject search request with non-empty results

Request:

{
  "subject": { "type": "user" },
  "action": { "name": "read" },
  "resource": { "type": "record", "id": "record-1" }
}

Expected: HTTP 200 with a results array. Per the fixture (Section 4.5), the results MUST include at least:

{
  "results": [
    { "type": "user", "id": "alice" },
    { "type": "user", "id": "bob" }
  ]
}

The harness validates:

  • HTTP 200 response.

  • results is an array.

  • Each element contains type and id.

  • Each element's type matches the requested type (user).

  • alice and bob appear in the results.

  • Additional results beyond alice and bob are permitted.

7.2.2. Subject search with context

The PDP MUST accept a Subject Search request that includes the optional context field without error. Per Section 4.6, context does not affect fixture decisions, so the results MUST match those of Section 7.2.1.

Request:

{
  "subject": { "type": "user" },
  "action": { "name": "read" },
  "resource": { "type": "record", "id": "record-1" },
  "context": {
    "time": "2025-06-27T18:03-07:00",
    "ip": "192.168.1.1"
  }
}

Expected: HTTP 200 with a results array including at least alice and bob, identical to Section 7.2.1.

7.2.3. Subject search with subject id present

Per the specification, subject.id SHOULD be omitted from Subject Search requests, but if present it MUST be ignored. The harness sends a Subject Search request that includes a subject.id and asserts the PDP ignores it: the result set MUST be identical to the equivalent request without subject.id (Section 7.2.1).

Request:

{
  "subject": { "type": "user", "id": "alice" },
  "action": { "name": "read" },
  "resource": { "type": "record", "id": "record-1" }
}

Expected: HTTP 200 with a results array including at least alice and bob, identical to Section 7.2.1. The presence of subject.id MUST NOT change the result set (in particular, bob MUST still be returned even though alice's id was supplied).

Properties (Search Properties certification):

7.2.4. Subject search with resource properties — fixture validated

Request:

{
  "subject": { "type": "user" },
  "action": { "name": "write" },
  "resource": {
    "type": "record",
    "id": "record-2",
    "properties": { "status": "archived" }
  }
}

Expected: HTTP 200 with a results array. Per the fixture (Section 4.5), the results MUST include at least bob. Validates search requirement S4 (derived from decision rule 6).

{
  "results": [
    { "type": "user", "id": "bob" }
  ]
}

Core (Search Core certification):

7.3.1. Valid resource search request with non-empty results

Request:

{
  "subject": { "type": "user", "id": "alice" },
  "action": { "name": "read" },
  "resource": { "type": "record" }
}

Expected: HTTP 200 with a results array. Per the fixture (Section 4.5), the results MUST include at least:

{
  "results": [
    { "type": "record", "id": "record-1" }
  ]
}

The harness validates:

  • HTTP 200 response.

  • results is an array.

  • Each element contains type and id.

  • Each element's type matches the requested type (record).

  • record-1 appears in the results.

  • Additional results are permitted.

7.3.2. Resource search with context

The PDP MUST accept a Resource Search request that includes the optional context field without error. Per Section 4.6, context does not affect fixture decisions, so the results MUST match those of Section 7.3.1.

Request:

{
  "subject": { "type": "user", "id": "alice" },
  "action": { "name": "read" },
  "resource": { "type": "record" },
  "context": {
    "time": "2025-06-27T18:03-07:00",
    "ip": "192.168.1.1"
  }
}

Expected: HTTP 200 with a results array including at least record-1, identical to Section 7.3.1.

7.3.3. Resource search with resource id present

Per the specification, resource.id SHOULD be omitted from Resource Search requests, but if present it MUST be ignored. The harness sends a Resource Search request that includes a resource.id and asserts the PDP ignores it: the result set MUST be identical to the equivalent request without resource.id (Section 7.3.1).

Request:

{
  "subject": { "type": "user", "id": "alice" },
  "action": { "name": "read" },
  "resource": { "type": "record", "id": "record-1" }
}

Expected: HTTP 200 with a results array including at least record-1, identical to Section 7.3.1. The presence of resource.id MUST NOT constrain or change the result set.

Properties (Search Properties certification):

7.3.4. Resource search with subject properties — fixture validated

Request:

{
  "subject": {
    "type": "user",
    "id": "bob",
    "properties": { "role": "admin" }
  },
  "action": { "name": "write" },
  "resource": { "type": "record" }
}

Expected: HTTP 200 with a results array. Per the fixture (Section 4.5), the results MUST include at least record-2. Validates search requirement S5 (derived from decision rule 6).

{
  "results": [
    { "type": "record", "id": "record-2" }
  ]
}

Core (Search Core certification):

7.4.1. Valid action search request with non-empty results

Note: the action field is omitted entirely from Action Search requests.

Request:

{
  "subject": { "type": "user", "id": "alice" },
  "resource": { "type": "record", "id": "record-1" }
}

Expected: HTTP 200 with a results array. Per the fixture (Section 4.5), the results MUST include at least:

{
  "results": [
    { "name": "read" },
    { "name": "write" }
  ]
}

The harness validates:

  • HTTP 200 response.

  • results is an array.

  • Each element contains a name field.

  • read and write appear in the results (per decision rules 1 and 2).

  • Additional results are permitted.

7.4.2. Action search with context

The PDP MUST accept an Action Search request that includes the optional context field without error. Per Section 4.6, context does not affect fixture decisions, so the results MUST match those of Section 7.4.1.

Request:

{
  "subject": { "type": "user", "id": "alice" },
  "resource": { "type": "record", "id": "record-1" },
  "context": {
    "time": "2025-06-27T18:03-07:00",
    "ip": "192.168.1.1"
  }
}

Expected: HTTP 200 with a results array including at least read and write, identical to Section 7.4.1.

Properties (Search Properties certification):

7.4.3. Action search with properties — fixture validated

Request:

{
  "subject": {
    "type": "user",
    "id": "bob",
    "properties": { "role": "admin" }
  },
  "resource": {
    "type": "record",
    "id": "record-2",
    "properties": { "status": "archived" }
  }
}

Expected: HTTP 200 with a results array. Per the fixture (Section 4.5), the results MUST include at least write. Validates search requirement S6 (derived from decision rule 6).

{
  "results": [
    { "name": "write" }
  ]
}

7.5. Pagination

7.5.1. Request with page limit

The PDP MUST accept a search request that includes a page object with a limit field.

Request:

{
  "subject": { "type": "user" },
  "action": { "name": "read" },
  "resource": { "type": "record", "id": "record-1" },
  "page": {
    "limit": 1
  }
}

Expected: HTTP 200 with a results array. If the PDP supports pagination, the response MAY include a page object.

The harness validates:

  • HTTP 200 response.

  • results is an array.

  • If page is present in the response, it MUST be an object.

  • If page.next_token is present, it MUST be a string.

7.5.2. Request with page token

If the PDP returned a non-empty next_token in a previous response, the harness sends a follow-up request with that token.

Request:

{
  "subject": { "type": "user" },
  "action": { "name": "read" },
  "resource": { "type": "record", "id": "record-1" },
  "page": {
    "token": "<next_token from previous response>"
  }
}

Expected: HTTP 200 with a results array.

The harness validates:

  • HTTP 200 response.

  • results is an array.

  • page is present and is an object.

  • page.next_token is present and is a string.

  • If more results exist, page.next_token is a non-empty string.

  • If no more results exist, page.next_token is an empty string.

7.5.3. Pagination response format

If the PDP returns paginated results, the response page object:

  • MUST contain next_token (string). Empty string signals end of results.

  • MAY contain count (number of results in this response).

  • MAY contain total (total number of matching results).

  • MAY contain properties (implementation-specific metadata).

7.5.4. Pagination is optional

The PDP MAY support pagination on search endpoints. If it does not support pagination, it MUST:

  • Return all results in a single response.

  • Accept requests containing a page object without error (ignoring it).

  • Omit the page object from the response, or return page.next_token as an empty string.

  • Note: The certification harness does not require PDPs to demonstrate multi-page result sets. The fixture is deliberately small, so PDPs that support pagination are unlikely to produce multiple pages. The harness validates only that the PDP accepts pagination parameters and returns structurally valid responses.

7.6. Empty results

The PDP MUST return an empty results array (not an error) when no entities match the search criteria. This applies both when the entity identifier is unknown and when the entity type itself is unrecognised by the PDP, and it applies to all three search endpoints (Subject, Resource, and Action Search). The examples below illustrate the requirement against a representative endpoint; the same behaviour is required of the other two.

7.6.1. Unknown entity identifier

The example below is an Action Search (the action key is omitted) whose input subject identifier does not exist in the fixture.

Request (Action Search, unknown subject identifier):

{
  "subject": { "type": "user", "id": "nonexistent-user" },
  "resource": { "type": "record", "id": "record-1" }
}

Expected:

{
  "results": []
}

7.6.2. Unknown entity type

The PDP MUST return an empty results array (not HTTP 400) when the search specifies an entity type the PDP does not recognise. The example below is a Subject Search whose searched-for subject type does not exist in the fixture.

Request (Subject Search, unrecognised subject type):

{
  "subject": { "type": "spaceship" },
  "action": { "name": "read" },
  "resource": { "type": "record", "id": "record-1" }
}

Expected:

{
  "results": []
}

7.7. Search Error Handling

7.7.1. Missing required fields

The PDP MUST return HTTP 400 when a required field is missing from a search request.

Subject Search (missing action):

{
  "subject": { "type": "user" },
  "resource": { "type": "record", "id": "record-1" }
}

Expected: HTTP 400.

Resource Search (missing subject):

{
  "action": { "name": "read" },
  "resource": { "type": "record" }
}

Expected: HTTP 400.

Action Search (missing resource):

{
  "subject": { "type": "user", "id": "alice" }
}

Expected: HTTP 400.

7.7.2. Missing required sub-fields

In each search the searched-for entity legitimately omits its id (that is what the search resolves), while every input entity MUST be fully identified. The required sub-field therefore differs by endpoint, so the same request body can be valid against one endpoint and invalid against another — the endpoint determines which entity is the input.

Subject Search (input resource missing id): the subject is the search target, so resource is an input and MUST carry an id.

{
  "subject": { "type": "user" },
  "action": { "name": "read" },
  "resource": { "type": "record" }
}

Expected: HTTP 400.

Resource Search (input subject missing id): the resource is the search target, so subject is an input and MUST carry an id.

{
  "subject": { "type": "user" },
  "action": { "name": "read" },
  "resource": { "type": "record" }
}

Expected: HTTP 400.

Action Search (input subject missing id): the action is the search target (and action is omitted entirely), so both subject and resource are inputs and MUST carry an id.

{
  "subject": { "type": "user" },
  "resource": { "type": "record", "id": "record-1" }
}

Expected: HTTP 400.

8. Transport Requirements

These requirements apply to all certification levels.

  1. The PDP MUST accept HTTPS requests with Content-Type: application/json.

  2. Successful evaluation and search responses MUST return HTTP 200 with Content-Type: application/json.

  3. Missing required fields MUST return HTTP 400.

  4. The PDP MUST echo the X-Request-ID header if present in the request.

  5. The PDP MUST ignore unknown fields in the request body.

9. Discovery Certification: PDP Metadata

Discovery is an independent certification level. It is not a prerequisite for Basic, Batch, or Search certification. A PDP that does not expose the metadata endpoint can still certify at other levels by using default paths (see Section 9.6).

9.1. Metadata Endpoint

The PDP SHOULD expose a metadata endpoint at the well-known URI derived from the PDP base URL by inserting /.well-known/authzen-configuration between the host and any existing path/query components.

For a PDP base URL with no path component, this is:

GET /.well-known/authzen-configuration

For example, a PDP base URL scoped by tenant path may expose:

GET /.well-known/authzen-configuration/tenant1

9.2. Metadata Response Format

If exposed, the response MUST be HTTP 200 with Content-Type: application/json.

Example response:

{
  "policy_decision_point": "https://pdp.example.com",
  "access_evaluation_endpoint": "https://pdp.example.com/access/v1/evaluation",
  "access_evaluations_endpoint": "https://pdp.example.com/access/v1/evaluations",
  "search_subject_endpoint": "https://pdp.example.com/access/v1/search/subject",
  "search_resource_endpoint": "https://pdp.example.com/access/v1/search/resource",
  "search_action_endpoint": "https://pdp.example.com/access/v1/search/action",
  "signed_metadata": "eyJhbGciOiJSUzI1NiIs..."
}

9.3. Required Metadata Fields

The response MUST include:

  • policy_decision_point -- Base URL of the PDP (HTTPS, no query string or fragment).

  • access_evaluation_endpoint -- URL for the Access Evaluation API.

9.4. Optional Metadata Fields

The response MAY include:

  • access_evaluations_endpoint -- URL for the Access Evaluations API.

  • search_subject_endpoint -- URL for the Subject Search API.

  • search_resource_endpoint -- URL for the Resource Search API.

  • search_action_endpoint -- URL for the Action Search API.

  • capabilities -- Array of capability URNs supported by the PDP.

  • signed_metadata -- A JSON Web Token (JWT) [RFC7519] containing metadata claims. If present, it MUST be digitally signed or MACed using JSON Web Signature (JWS) [RFC7515] and MUST contain an iss (issuer) claim. Metadata values in the signed token take precedence over plain JSON values in the response.

9.5. Metadata Validation

The harness validates:

  • HTTP 200 response with Content-Type: application/json.

  • Response body is valid JSON.

  • policy_decision_point is present and matches the base URL used for discovery.

  • access_evaluation_endpoint is present and is a valid HTTPS URL.

  • If access_evaluations_endpoint is present, it is a valid HTTPS URL.

  • If search_*_endpoint fields are present, they are valid HTTPS URLs.

  • If capabilities is present, it is an array of strings.

  • If signed_metadata is present, it is a valid JWT string with a verifiable signature and contains an iss claim.

9.6. Metadata Endpoint Unavailable

For Discovery certification: the metadata endpoint MUST be available. An HTTP 404 response is a certification failure.

For other certification levels (Basic, Batch, Search): if the metadata endpoint is not available (HTTP 404), the harness falls back to the default paths defined in the specification:

  • /access/v1/evaluation

  • /access/v1/evaluations

  • /access/v1/search/subject

  • /access/v1/search/resource

  • /access/v1/search/action

10. Normative References

[AUTHZEN]
Gazitt, O., Brossard, D., and A. Tulshibagwale, "Authorization API 1.0", , <https://openid.github.io/authzen/>.
[RFC2119]
Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, , <https://www.rfc-editor.org/rfc/rfc2119>.
[RFC7515]
Jones, M., Bradley, J., and N. Sakimura, "JSON Web Signature (JWS)", RFC 7515, DOI 10.17487/RFC7515, , <https://www.rfc-editor.org/rfc/rfc7515>.
[RFC7519]
Jones, M., Bradley, J., and N. Sakimura, "JSON Web Token (JWT)", RFC 7519, DOI 10.17487/RFC7519, , <https://www.rfc-editor.org/rfc/rfc7519>.
[RFC8174]
Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, , <https://www.rfc-editor.org/rfc/rfc8174>.

Author's Address

Alex Olivier
Cerbos