Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,24 @@ changes (see [SECURITY.md](SECURITY.md)).
`--ca-step-ca-provisioner`, `--ca-step-ca-provisioner-key-file`,
`--ca-step-ca-ca-cert`. Validates the Plugin pattern on a second
upstream signer.
- `POST /access/v1/search/{subject,resource,action}` — AuthZEN 1.0
§5.3 Search APIs in a candidate-set variant. Each endpoint takes
an explicit list of candidates for the dimension being searched
(`subjects` / `resources` / `actions`) plus the two other
fully-specified dimensions, runs every candidate through the same
Cedar PDP path as `POST /access/v1/evaluation`, and returns those
whose decision is `allow`. The spec's pattern shape
(`subject: {type: "user"}` with no id) is rejected because Cedar
has no global principal directory and §5.3.2 expressly tells PDPs
to error when they cannot resolve the search space - a
candidate-list refinement is the honest take on that contract.
Pagination via offset/size with an `offset:N` continuation token,
per-candidate cap of `MaxSearchCandidates = 100` (same rationale
as the batch endpoint), audit row per evaluation tagged with the
search dimension + index. The discovery document at
`/.well-known/authzen-configuration` now advertises all three
endpoints. Moves `docs/conformance-authzen.md` §4.3 from
`deferred` to `partial`.
- Federation pump now consumes peers via `GET /v1/spiffe-bundle`
(SPIFFE Trust Domain Format), falling back to `GET /v1/bundle`
PEM when the peer returns 404 - so a freshly-built omega still
Expand Down
221 changes: 221 additions & 0 deletions api/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,93 @@ paths:
"503":
$ref: "#/components/responses/NotLeader"

/access/v1/search/subject:
post:
tags: [authzen, leader-only]
operationId: searchSubject
summary: AuthZEN 1.0 Subject Search (candidate-set variant).
description: |
Searches a caller-supplied list of subject candidates against
a fully specified `(action, resource)` pair and returns those
whose decision is `allow`. Omega does not maintain a global
principal directory, so the caller supplies the candidates
explicitly; the spec's §5.3.2 expressly allows the PDP to
error when it cannot resolve the search space, and a
candidate list is a strict refinement of that contract.
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/SubjectSearchRequest"
responses:
"200":
description: Matched subjects.
content:
application/json:
schema:
$ref: "#/components/schemas/SubjectSearchResponse"
"400":
$ref: "#/components/responses/BadRequest"
"503":
$ref: "#/components/responses/NotLeader"

/access/v1/search/resource:
post:
tags: [authzen, leader-only]
operationId: searchResource
summary: AuthZEN 1.0 Resource Search (candidate-set variant).
description: |
Searches a caller-supplied list of resource candidates against
a fully specified `(subject, action)` pair and returns those
whose decision is `allow`. Same candidate-set rationale as
Subject Search.
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/ResourceSearchRequest"
responses:
"200":
description: Matched resources.
content:
application/json:
schema:
$ref: "#/components/schemas/ResourceSearchResponse"
"400":
$ref: "#/components/responses/BadRequest"
"503":
$ref: "#/components/responses/NotLeader"

/access/v1/search/action:
post:
tags: [authzen, leader-only]
operationId: searchAction
summary: AuthZEN 1.0 Action Search (candidate-set variant).
description: |
Searches a caller-supplied list of action candidates against
a fully specified `(subject, resource)` pair and returns those
whose decision is `allow`. Same candidate-set rationale as
Subject Search.
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/ActionSearchRequest"
responses:
"200":
description: Matched actions.
content:
application/json:
schema:
$ref: "#/components/schemas/ActionSearchResponse"
"400":
$ref: "#/components/responses/BadRequest"
"503":
$ref: "#/components/responses/NotLeader"

/v1/oidc/exchange:
post:
tags: [oidc-federation, leader-only]
Expand Down Expand Up @@ -867,6 +954,9 @@ components:
- policy_decision_point
- access_evaluation_endpoint
- access_evaluations_endpoint
- subject_search_endpoint
- resource_search_endpoint
- action_search_endpoint
properties:
policy_decision_point:
type: string
Expand All @@ -880,6 +970,137 @@ components:
type: string
format: uri
description: Absolute URL of the batch endpoint `POST /access/v1/evaluations`.
subject_search_endpoint:
type: string
format: uri
description: Absolute URL of `POST /access/v1/search/subject`.
resource_search_endpoint:
type: string
format: uri
description: Absolute URL of `POST /access/v1/search/resource`.
action_search_endpoint:
type: string
format: uri
description: Absolute URL of `POST /access/v1/search/action`.

SearchPage:
type: object
additionalProperties: false
properties:
size:
type: integer
description: Page size echoed back (or selected by omega when omitted).
offset:
type: integer
description: Offset into the matched-candidate list.
next_token:
type: string
description: |
Opaque continuation token (`offset:N` today). Present
only when more matches remain.

SubjectSearchRequest:
type: object
additionalProperties: false
required: [subjects, action, resource]
properties:
subjects:
type: array
Comment thread
kanywst marked this conversation as resolved.
maxItems: 100
description: |
Caller-supplied candidate subjects to test. omega does not
enumerate principals on its own; the spec's §5.3.2 allows
the PDP to error when it cannot resolve the search space,
and a candidate list refines that contract into something
useful. Capped at 100 (`MaxSearchCandidates`) for the
same hash-chain-mutex reason as the batch endpoint.
items:
$ref: "#/components/schemas/EvalEntity"
action:
$ref: "#/components/schemas/EvalAction"
resource:
$ref: "#/components/schemas/EvalEntity"
context:
type: object
additionalProperties: true
page:
$ref: "#/components/schemas/SearchPage"

SubjectSearchResponse:
type: object
additionalProperties: false
required: [results]
properties:
results:
type: array
items:
$ref: "#/components/schemas/EvalEntity"
page:
$ref: "#/components/schemas/SearchPage"

ResourceSearchRequest:
type: object
additionalProperties: false
required: [resources, subject, action]
properties:
resources:
type: array
Comment thread
kanywst marked this conversation as resolved.
maxItems: 100
items:
$ref: "#/components/schemas/EvalEntity"
subject:
$ref: "#/components/schemas/EvalEntity"
action:
$ref: "#/components/schemas/EvalAction"
context:
type: object
additionalProperties: true
page:
$ref: "#/components/schemas/SearchPage"

ResourceSearchResponse:
type: object
additionalProperties: false
required: [results]
properties:
results:
type: array
items:
$ref: "#/components/schemas/EvalEntity"
page:
$ref: "#/components/schemas/SearchPage"

ActionSearchRequest:
type: object
additionalProperties: false
required: [actions, subject, resource]
properties:
actions:
type: array
Comment thread
kanywst marked this conversation as resolved.
maxItems: 100
items:
$ref: "#/components/schemas/EvalAction"
subject:
$ref: "#/components/schemas/EvalEntity"
resource:
$ref: "#/components/schemas/EvalEntity"
context:
type: object
additionalProperties: true
page:
$ref: "#/components/schemas/SearchPage"

ActionSearchResponse:
type: object
additionalProperties: false
required: [results]
properties:
results:
type: array
items:
$ref: "#/components/schemas/EvalAction"
page:
$ref: "#/components/schemas/SearchPage"

OIDCDiscoveryResponse:
type: object
Expand Down
4 changes: 2 additions & 2 deletions docs/conformance-authzen.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ Spec version audited:
| --- | --- | --- | --- |
| 4.1 | A request carries exactly one subject, one action, one resource | implemented | enforced by the JSON schema in `api/openapi.yaml` (single-decision endpoint) |
| 4.2 | Batch requests use top-level defaults + per-entry overrides | implemented | merged in `mergeBatchEval`; missing required field after merge returns 400 |
| 4.3 | Search requests partially specify the request | deferred | the Search APIs in §5.3 are not yet implemented |
| 4.3 | Search requests partially specify the request | partial | `POST /access/v1/search/{subject,resource,action}` ship in a candidate-set variant: the dimension being searched arrives as an explicit list (`subjects`/`resources`/`actions`) and the other two are fully specified. The spec's `{type: "user"}` pattern shape with no id is rejected because omega's PDP (Cedar) has no global principal directory and §5.3.2 expressly tells PDPs to error when they cannot resolve the search space. A full enumeration mode would require an entity store on the omega side, tracked as a follow-up |

## §5 — Endpoints

Expand Down Expand Up @@ -91,7 +91,7 @@ Spec version audited:

| Section | Requirement | Status | omega notes |
| --- | --- | --- | --- |
| 8 | Discovery document advertises supported endpoints | implemented | `GET /.well-known/authzen-configuration` returns `policy_decision_point` + `access_evaluation_endpoint` + `access_evaluations_endpoint`. The PDP base is `--issuer-url` (canonical, validated `https`); the handler returns `404` when `--issuer-url` is not set so the PDP base cannot be sourced from a spoofed `Host` header. The three Search API endpoints are intentionally omitted because omega does not implement them - per §8 an absent field signals "not implemented" |
| 8 | Discovery document advertises supported endpoints | implemented | `GET /.well-known/authzen-configuration` returns the five endpoint fields: `policy_decision_point`, `access_evaluation_endpoint`, `access_evaluations_endpoint`, `subject_search_endpoint`, `resource_search_endpoint`, `action_search_endpoint`. The PDP base is `--issuer-url` (canonical, validated `https`); the handler returns `404` when `--issuer-url` is not set so the PDP base cannot be sourced from a spoofed `Host` header |

## §9 — Security considerations

Expand Down
Loading
Loading