authzen

package module
v0.0.0-...-bf6ee12 Latest Latest
Warning

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

Go to latest
Published: Jun 20, 2026 License: MIT Imports: 3 Imported by: 0

README

authzen

CI Go Reference Go Report Card License

A clean, dependency-light Go implementation of the OpenID AuthZEN Authorization API 1.0 — the standard for how a Policy Enforcement Point (PEP) asks a Policy Decision Point (PDP) "is this subject allowed to perform this action on this resource?"

Status: the root module targets the Authorization API 1.0 Final Specification (approved 2026-01-12).

What is AuthZEN?

AuthZEN standardizes the contract between a PEP (the application enforcing access) and a PDP (the service that decides). It defines a transport- agnostic information model — Subject, Resource, Action, Context, Decision — and a normative HTTPS + JSON binding for four families of APIs:

API Spec section What it answers
Access Evaluation §6 One decision: may subject do action on resource?
Access Evaluations (batch) §7 Many decisions in one round trip (boxcarred).
Subject / Resource / Action Search §8 Discovery: who/what/which satisfies a relation.
Metadata §9 The PDP's .well-known configuration document.

A policy deny is a successful response (decision: false), never an error — a distinction this library preserves end to end.

Features

  • Conformant core types — the request/response payloads and their exact JSON encoding for §5–§9, with Validate helpers that enforce every REQUIRED field mandated by the spec's MUST rules.
  • HTTP client (PEP)client package: Evaluate, EvaluateBatch, the three Search APIs, and metadata discovery over the normative HTTPS + JSON binding, with pluggable auth (static bearer token or per-request hook).
  • HTTP server (PDP)server package: implement a small PDP interface and get a ready http.Handler that wires the standard routes, validates input, and applies the §10.1 transport and error-mapping rules (including optional batch-semantic handling).
  • gRPC binding — the nested grpc module: an AIP-designed gRPC profile of the API with committed, generated stubs (see grpc/README.md).
  • CLI — a cmd/authzen command-line PEP for scripting and CI gating, built only on the standard library and the in-repo client; see CLI below.
  • Minimal dependencies — see the philosophy callout below.
Minimal-dependency philosophy

The root module has zero external dependencies — it builds on the Go standard library alone (net/http, encoding/json, ...). Anything that would pull in a heavier dependency tree is isolated in its own module: the gRPC binding (which needs grpc/protobuf/buf) lives in the nested grpc module so those dependencies never leak into consumers of the core. Depend on github.com/SCKelemen/authzen for the types, client, and server; opt in to github.com/SCKelemen/authzen/grpc only if you want gRPC.

Module layout

This repository contains two Go modules:

github.com/SCKelemen/authzen          # root module — ZERO external deps
├── *.go                              # core information model (§5–§9) + validation
├── client/                           # PEP: HTTPS + JSON client
├── server/                           # PDP: http.Handler + PDP interface
├── cmd/authzen/                      # CLI (PEP for scripting/CI)
└── docs/SPEC_NOTES.md                # engineering reference for the spec

github.com/SCKelemen/authzen/grpc     # nested module — grpc + protobuf + buf
├── proto/authzen/v1/                 # proto source
├── gen/authzen/v1/                   # generated Go (committed)
├── conv.go / server.go / client.go   # proto <-> core, PDP adapter, PEP wrapper
└── README.md                         # gRPC binding docs

The nested module uses a replace github.com/SCKelemen/authzen => ../ directive so the binding always builds against the local core.

Install

# Core types, HTTP client, and HTTP server (zero-dependency root module):
go get github.com/SCKelemen/authzen

# gRPC binding (nested module, only if you want gRPC):
go get github.com/SCKelemen/authzen/grpc

Requires Go 1.26 or newer (go 1.26 in go.mod).

Quickstart

Client (PEP)
package main

import (
	"context"
	"fmt"
	"log"

	authzen "github.com/SCKelemen/authzen"
	"github.com/SCKelemen/authzen/client"
)

func main() {
	c := client.New("https://pdp.example.com",
		client.WithBearerToken("ey...")) // OAuth 2.0 bearer (RECOMMENDED, §11.2)

	resp, err := c.Evaluate(context.Background(), &authzen.EvaluationRequest{
		Subject:  &authzen.Subject{Type: "user", ID: "alice@example.com"},
		Action:   &authzen.Action{Name: "can_read"},
		Resource: &authzen.Resource{Type: "todo", ID: "1"},
	})
	if err != nil {
		log.Fatal(err)
	}

	// A deny is a successful response with Decision == false, not an error.
	fmt.Println("allowed:", resp.Decision)
}
Server (PDP)
package main

import (
	"context"
	"log"

	authzen "github.com/SCKelemen/authzen"
	"github.com/SCKelemen/authzen/server"
)

// myPDP is your decision logic. It only sees requests that already passed the
// package's structural validation (REQUIRED fields present).
type myPDP struct{}

func (myPDP) Evaluate(ctx context.Context, req *authzen.EvaluationRequest) (*authzen.EvaluationResponse, error) {
	allow := req.Action.Name == "can_read" // your policy here
	return &authzen.EvaluationResponse{Decision: allow}, nil
}

func (myPDP) SearchSubjects(ctx context.Context, req *authzen.SubjectSearchRequest) (*authzen.SubjectSearchResponse, error) {
	return &authzen.SubjectSearchResponse{}, nil
}
func (myPDP) SearchResources(ctx context.Context, req *authzen.ResourceSearchRequest) (*authzen.ResourceSearchResponse, error) {
	return &authzen.ResourceSearchResponse{}, nil
}
func (myPDP) SearchActions(ctx context.Context, req *authzen.ActionSearchRequest) (*authzen.ActionSearchResponse, error) {
	return &authzen.ActionSearchResponse{}, nil
}

func main() {
	h := server.NewHandler(myPDP{}, server.WithMetadata(&authzen.Metadata{
		PolicyDecisionPoint:      "https://pdp.example.com",
		AccessEvaluationEndpoint: "https://pdp.example.com/access/v1/evaluation",
	}))

	// server.NewServer returns a production-hardened *http.Server — it sets
	// ReadHeaderTimeout, ReadTimeout, WriteTimeout, IdleTimeout, and a TLS 1.2
	// minimum, unlike the unbounded zero-value server behind
	// http.ListenAndServe (which is open to slowloris / slow-read DoS). Serve
	// over TLS in production with srv.ListenAndServeTLS.
	srv := server.NewServer(":8080", h)
	log.Fatal(srv.ListenAndServe())
}

The handler serves the standard routes (/access/v1/evaluation, /access/v1/evaluations, /access/v1/search/{subject,resource,action}, and /.well-known/authzen-configuration). Batch evaluation works out of the box: if your PDP does not implement the optional BatchEvaluator interface, the handler loops Evaluate while honoring the requested evaluations_semantic (execute_all, deny_on_first_deny, permit_on_first_permit).

CLI

cmd/authzen is a command-line PEP over the HTTPS + JSON binding. It is a thin wrapper over the client package, depends only on the standard library, and exposes the four API families as subcommands: evaluate (§6), evaluations (§7), search (§8), and discover (§9). Every command takes the shared flags --url (required), --token, --timeout, and --json.

# Install:
go install github.com/SCKelemen/authzen/cmd/authzen@latest

# Single evaluation — prints "allow" or "deny":
authzen evaluate \
  --url https://pdp.example.com \
  --subject-type user --subject-id alice@example.com \
  --action can_read \
  --resource-type todo --resource-id 1

# Gate a script/CI step on a deny (exit non-zero only on deny):
authzen evaluate --url https://pdp.example.com \
  --subject-type user --subject-id alice@example.com \
  --action can_delete --resource-type todo --resource-id 1 \
  --deny-exit-code 3

# Send a full request document (or "-" for stdin), with bearer auth and raw JSON:
authzen evaluate --url https://pdp.example.com \
  --token "ey..." --json --request ./request.json

# Fetch and summarize the PDP metadata document:
authzen discover --url https://pdp.example.com

A deny is a successful call and exits 0 unless --deny-exit-code N is given; transport/API errors exit 1, and usage errors exit 2. Run authzen <command> --help for the full flag list.

gRPC

The gRPC binding lives in the nested grpc module. See grpc/README.md for the proto schema, the AIP design notes, the gRPC ↔ HTTP status-code mapping, and server/client examples.

import (
	authzen "github.com/SCKelemen/authzen"
	authzengrpc "github.com/SCKelemen/authzen/grpc"
)

client := authzengrpc.NewClient(conn) // conn is a *grpc.ClientConn
resp, err := client.Evaluate(ctx, authzen.EvaluationRequest{
	Subject:  &authzen.Subject{Type: "user", ID: "alice@example.com"},
	Action:   &authzen.Action{Name: "can_read"},
	Resource: &authzen.Resource{Type: "todo", ID: "1"},
})

Conformance & spec coverage

The library tracks the Authorization API 1.0 Final Specification. The core types follow the field names, JSON shapes, and required/optional rules of the spec exactly; docs/SPEC_NOTES.md is the engineering reference that maps each implementation decision back to a spec section.

Spec area Section Core types / validation HTTP client HTTP server gRPC
Information model (Subject/Resource/Action/Context) §5
Access Evaluation §6
Access Evaluations (batch) §7
Subject / Resource / Action Search §8
Metadata (.well-known) §9
Transport (HTTPS + JSON, error mapping) §10 n/a

The gRPC binding is a non-normative profile (the spec permits additional bindings as profiles); it mirrors the HTTP/JSON semantics. Interop fixtures are drawn from the spec's own JSON examples and the AuthZEN interop "Todo" scenario.

Testing

Both modules are tested independently. From the repository root:

# Root module (zero-dependency core, client, server):
go test ./...

# gRPC module (nested):
cd grpc && go test ./...

CI runs the full gate on every push and pull request — gofmt, go vet, staticcheck, go build, and go test -race -cover for both modules, plus buf lint and a buf generate + git diff check that fails if the committed generated stubs drift. govulncheck also runs against both modules and reports known vulnerabilities (informational; it does not gate the build). The CI toolchain is pinned to a patched Go release for the stdlib security fixes. See .github/workflows/ci.yml.

To regenerate the gRPC stubs after editing the protos:

cd grpc
make generate   # buf generate -> gen/   (requires buf + protoc-gen-go[-grpc])
make check      # buf lint + go vet + build + test

License

Licensed under the BearWare 1.0 license — see LICENSE. BearWare 1.0 is an MIT-compatible permissive license used across the github.com/SCKelemen/* repositories.

Copyright 2025 Samuel Kelemen.

Documentation

Overview

Package authzen provides the core information model and message types for the OpenID AuthZEN Authorization API 1.0, the foundation on which a compliant Policy Decision Point (PDP) or Policy Enforcement Point (PEP) is built.

The package is transport-agnostic: it defines the request and response payloads (and their JSON encoding) for the Access Evaluation API (Section 6), the Access Evaluations / batch API (Section 7), the Subject, Resource, and Action Search APIs (Section 8), and the PDP metadata document (Section 9). It does not implement any HTTP, gRPC, or CLI binding; those live in separate packages.

All types follow the field names, JSON shapes, and required/optional rules of the specification exactly. Validation helpers enforce the REQUIRED fields mandated by the spec's MUST rules.

OpenID AuthZEN Authorization API 1.0 (Final Specification, 2026-01-12). https://openid.net/specs/authorization-api-1_0.html

Index

Constants

View Source
const (
	// DefaultEvaluationPath is the default path of the Access Evaluation API.
	DefaultEvaluationPath = "/access/v1/evaluation"
	// DefaultEvaluationsPath is the default path of the Access Evaluations
	// (batch) API.
	DefaultEvaluationsPath = "/access/v1/evaluations"
	// DefaultSearchSubjectPath is the default path of the Subject Search API.
	DefaultSearchSubjectPath = "/access/v1/search/subject"
	// DefaultSearchResourcePath is the default path of the Resource Search API.
	DefaultSearchResourcePath = "/access/v1/search/resource"
	// DefaultSearchActionPath is the default path of the Action Search API.
	DefaultSearchActionPath = "/access/v1/search/action"
)

Default request paths for the AuthZEN APIs in the normative HTTPS + JSON binding. A PEP MUST use the URL advertised by the corresponding metadata parameter when present, and SHOULD otherwise form the URL by appending these default paths to the PDP base URL (policy_decision_point).

OpenID AuthZEN Authorization API 1.0, Section 10.1 (Transport), Table 1. https://openid.net/specs/authorization-api-1_0.html

View Source
const (
	// WellKnownConfigurationSuffix is the registered well-known URI suffix for
	// the PDP configuration document.
	WellKnownConfigurationSuffix = "authzen-configuration"
	// WellKnownConfigurationPath is the default path of the PDP metadata
	// document, retrieved with HTTP GET.
	WellKnownConfigurationPath = "/.well-known/authzen-configuration"
)

Well-known metadata location constants.

OpenID AuthZEN Authorization API 1.0, Section 9.2 (Obtaining metadata) and Section 12.2 (Well-Known URI registration). https://openid.net/specs/authorization-api-1_0.html

Variables

View Source
var (
	// ErrMissingType indicates a required "type" field was empty.
	ErrMissingType = errors.New(`authzen: missing required field "type"`)
	// ErrMissingID indicates a required "id" field was empty.
	ErrMissingID = errors.New(`authzen: missing required field "id"`)
	// ErrMissingName indicates a required "name" field was empty.
	ErrMissingName = errors.New(`authzen: missing required field "name"`)
	// ErrMissingSubject indicates a required "subject" object was absent.
	ErrMissingSubject = errors.New(`authzen: missing required field "subject"`)
	// ErrMissingAction indicates a required "action" object was absent.
	ErrMissingAction = errors.New(`authzen: missing required field "action"`)
	// ErrMissingResource indicates a required "resource" object was absent.
	ErrMissingResource = errors.New(`authzen: missing required field "resource"`)
	// ErrMissingEvaluationFields indicates a batch member resolves to a
	// request that is missing a subject, action, or resource even after
	// top-level defaults are applied.
	ErrMissingEvaluationFields = errors.New(`authzen: evaluation is missing subject, action, or resource`)
	// ErrInvalidSemantic indicates options.evaluations_semantic held a value
	// other than the three defined by the specification.
	ErrInvalidSemantic = errors.New("authzen: invalid evaluations_semantic")
)

Sentinel errors returned (wrapped) by the Validate methods when a REQUIRED field defined by the specification is missing or invalid. Callers can test for them with errors.Is.

The specification mandates that a missing required attribute MUST be rejected (in the HTTPS binding, with HTTP 400).

OpenID AuthZEN Authorization API 1.0, Section 10.1.1 (JSON Serialization) and Section 8 (Required vs optional fields). https://openid.net/specs/authorization-api-1_0.html

Functions

This section is empty.

Types

type Action

type Action struct {
	// Name is the name of the action. REQUIRED.
	Name string `json:"name"`
	// Properties holds additional action parameters. OPTIONAL.
	Properties map[string]any `json:"properties,omitempty"`
}

Action is the verb or operation the subject wishes to perform on the resource. Properties carries any parameters of the action.

OpenID AuthZEN Authorization API 1.0, Section 5.3 (Action). https://openid.net/specs/authorization-api-1_0.html

func (*Action) Validate

func (a *Action) Validate() error

Validate reports whether the Action carries the field REQUIRED by the specification: a non-empty name.

OpenID AuthZEN Authorization API 1.0, Section 5.3 (Action). https://openid.net/specs/authorization-api-1_0.html

type ActionSearchRequest

type ActionSearchRequest struct {
	// Subject is the principal. REQUIRED.
	Subject *Subject `json:"subject,omitempty"`
	// Resource is the target. REQUIRED.
	Resource *Resource `json:"resource,omitempty"`
	// Context carries optional environment/request attributes. OPTIONAL.
	Context Context `json:"context,omitempty"`
	// Page carries pagination parameters. OPTIONAL.
	Page *Page `json:"page,omitempty"`
}

ActionSearchRequest is the body of an Action Search request, asking which actions the subject may perform on the resource. The action key is omitted from the request payload entirely.

OpenID AuthZEN Authorization API 1.0, Section 8.6 (Action Search). https://openid.net/specs/authorization-api-1_0.html

func (*ActionSearchRequest) Validate

func (r *ActionSearchRequest) Validate() error

Validate checks the fields REQUIRED for an Action Search: a valid subject and a valid resource. No action is part of an Action Search request.

OpenID AuthZEN Authorization API 1.0, Section 8.6 (Action Search). https://openid.net/specs/authorization-api-1_0.html

type ActionSearchResponse

type ActionSearchResponse struct {
	// Page carries pagination metadata. OPTIONAL (but MUST be present when the
	// result set is incomplete).
	Page *PageResponse `json:"page,omitempty"`
	// Results holds the authorized actions. REQUIRED.
	Results []Action `json:"results"`
	// Context carries optional, implementation-specific information. OPTIONAL.
	Context map[string]any `json:"context,omitempty"`
}

ActionSearchResponse is the body of an Action Search response. results holds zero or more actions; page and context are optional.

OpenID AuthZEN Authorization API 1.0, Section 8.3 (Search response) and Section 8.6. https://openid.net/specs/authorization-api-1_0.html

func (ActionSearchResponse) MarshalJSON

func (r ActionSearchResponse) MarshalJSON() ([]byte, error)

MarshalJSON encodes the response, normalizing a nil Results slice to an empty array so the REQUIRED results key is serialized as [] rather than JSON null, matching the specification's response examples.

OpenID AuthZEN Authorization API 1.0, Section 8.3 (Search response) and Section 8.6. https://openid.net/specs/authorization-api-1_0.html

type Context

type Context map[string]any

Context is a free-form set of environment or request attributes (for example time, location, or PEP capabilities). The specification defines no required keys.

OpenID AuthZEN Authorization API 1.0, Section 5.4 (Context). https://openid.net/specs/authorization-api-1_0.html

type EvaluationError

type EvaluationError struct {
	// Status is an implementation-specific status code (for example an HTTP
	// status such as 404).
	Status int `json:"status"`
	// Message is a human-readable description of the failure.
	Message string `json:"message"`
}

EvaluationError is a typed helper for the non-normative per-evaluation error object that a PDP may place inside a decision context to explain why an individual decision failed (most often within a batch response). It is not an HTTP transport error; transport errors are reported with HTTP status codes.

OpenID AuthZEN Authorization API 1.0, Section 7.2.1 (Errors in batch). https://openid.net/specs/authorization-api-1_0.html

type EvaluationRequest

type EvaluationRequest struct {
	// Subject is the principal. REQUIRED for a standalone evaluation.
	Subject *Subject `json:"subject,omitempty"`
	// Action is the operation. REQUIRED for a standalone evaluation.
	Action *Action `json:"action,omitempty"`
	// Resource is the target. REQUIRED for a standalone evaluation.
	Resource *Resource `json:"resource,omitempty"`
	// Context carries optional environment/request attributes. OPTIONAL.
	Context Context `json:"context,omitempty"`
}

EvaluationRequest is the body of an Access Evaluation request: it asks whether the subject may perform the action on the resource within the optional context. It is also the element type of the Access Evaluations batch array (Section 7.1), where individual fields may be omitted and inherited from the top-level defaults; the fields are therefore pointers so that omission can be distinguished from a zero value on the wire.

OpenID AuthZEN Authorization API 1.0, Section 6.1 (Access Evaluation Request). https://openid.net/specs/authorization-api-1_0.html#name-access-evaluation-request

func (*EvaluationRequest) Validate

func (r *EvaluationRequest) Validate() error

Validate reports whether the request carries the subject, action, and resource REQUIRED by the specification, each with its own required fields.

OpenID AuthZEN Authorization API 1.0, Section 6.1 (Access Evaluation Request). https://openid.net/specs/authorization-api-1_0.html#name-access-evaluation-request

type EvaluationResponse

type EvaluationResponse struct {
	// Decision is true to permit and false to deny the request. REQUIRED.
	Decision bool `json:"decision"`
	// Context carries optional, implementation-specific reasons or advice.
	// OPTIONAL.
	Context map[string]any `json:"context,omitempty"`
}

EvaluationResponse is the body of an Access Evaluation response. The decision is REQUIRED (true permits, false denies; a deny is fail-safe/closed). The context is OPTIONAL and carries reasons, advice/obligations, UI hints, or step-up instructions whose semantics are implementation-specific.

OpenID AuthZEN Authorization API 1.0, Section 6.2 (Access Evaluation Response) and Section 5.5 (Decision). https://openid.net/specs/authorization-api-1_0.html#name-access-evaluation-response

type EvaluationsRequest

type EvaluationsRequest struct {
	// Subject is the top-level default subject. Conditionally REQUIRED: any
	// member that omits its subject inherits this value.
	Subject *Subject `json:"subject,omitempty"`
	// Action is the top-level default action. Conditionally REQUIRED.
	Action *Action `json:"action,omitempty"`
	// Resource is the top-level default resource. Conditionally REQUIRED.
	Resource *Resource `json:"resource,omitempty"`
	// Context is the top-level default context. OPTIONAL.
	Context Context `json:"context,omitempty"`
	// Evaluations holds the discrete sub-requests. OPTIONAL; when absent or
	// empty the request is treated as a single evaluation.
	Evaluations []EvaluationRequest `json:"evaluations,omitempty"`
	// Options carries execution metadata such as evaluations_semantic.
	// OPTIONAL.
	Options *Options `json:"options,omitempty"`
}

EvaluationsRequest is the body of an Access Evaluations (batch) request. The top-level subject, action, resource, and context provide default values for every member of the evaluations array; a key set inside a member overrides the corresponding default. When evaluations is absent or empty, the request behaves identically to a single Access Evaluation request.

OpenID AuthZEN Authorization API 1.0, Section 7.1 (Access Evaluations Request). https://openid.net/specs/authorization-api-1_0.html#name-access-evaluations-request

func (*EvaluationsRequest) Resolved

func (r *EvaluationsRequest) Resolved() []EvaluationRequest

Resolved returns the fully specified evaluation requests implied by the batch, applying the top-level subject/action/resource/context defaults to every member that omits them. A member's own value always overrides the default. When Evaluations is absent or empty, a single request built from the top-level fields is returned, matching the backwards-compatible behavior in Section 7.1.1.

OpenID AuthZEN Authorization API 1.0, Section 7.1.1 (Defaulting rules). https://openid.net/specs/authorization-api-1_0.html

func (*EvaluationsRequest) Validate

func (r *EvaluationsRequest) Validate() error

Validate checks that every evaluation, after the top-level defaults are applied, carries a valid subject, action, and resource, and that any supplied options.evaluations_semantic is one of the defined values. It implements the REQUIRED-field rules of Section 7.1.1.

OpenID AuthZEN Authorization API 1.0, Section 7.1 (Access Evaluations Request). https://openid.net/specs/authorization-api-1_0.html#name-access-evaluations-request

type EvaluationsResponse

type EvaluationsResponse struct {
	// Decision, when non-nil, selects the single-decision backwards-compatible
	// response shape of Section 6.2 (true permits, false denies). It is set for
	// a request that omits the evaluations array; leave it nil for a batch
	// response. OPTIONAL.
	Decision *bool
	// Context carries the optional, implementation-specific decision context
	// accompanying a single-decision response (Section 6.2). It is only emitted
	// in the single-decision mode. OPTIONAL.
	Context map[string]any
	// Evaluations holds the per-request decisions in request order for a batch
	// response (Section 7.2).
	Evaluations []EvaluationResponse
}

EvaluationsResponse is the body of an Access Evaluations (batch) response. The evaluations array holds the decisions in the same order as the request's evaluations array; for the short-circuit semantics it may be shorter, ending at the deciding element.

For backwards compatibility, a request that carries no (or an empty) evaluations array MUST be answered with the single Access Evaluation response shape of Section 6.2 — a top-level {"decision":...,"context":...} object — rather than the {"evaluations":[...]} batch shape. This type encodes both shapes: when Decision is non-nil the value marshals in the single-decision mode; otherwise it marshals the (batch) evaluations array.

OpenID AuthZEN Authorization API 1.0, Section 7.1 (Access Evaluations Request, backwards compatibility), Section 7.2 (Access Evaluations Response), and Section 6.2 (Access Evaluation Response). https://openid.net/specs/authorization-api-1_0.html#name-access-evaluations-response

func SingleDecision

func SingleDecision(decision bool, ctx map[string]any) EvaluationsResponse

SingleDecision builds an EvaluationsResponse in the backwards-compatible single-decision mode (Section 6.2), as required when the originating request carried no evaluations array (Section 7.1).

OpenID AuthZEN Authorization API 1.0, Section 7.1 and Section 6.2. https://openid.net/specs/authorization-api-1_0.html

func (EvaluationsResponse) MarshalJSON

func (r EvaluationsResponse) MarshalJSON() ([]byte, error)

MarshalJSON encodes the response in one of two shapes. When Decision is non-nil it emits the single Access Evaluation response object of Section 6.2, {"decision":...,"context":...}, and omits the evaluations array entirely. Otherwise it emits the batch shape, {"evaluations":[...]}, normalizing a nil slice to an empty array so the key is never serialized as JSON null.

OpenID AuthZEN Authorization API 1.0, Section 7.2 (Access Evaluations Response) and Section 6.2 (Access Evaluation Response). https://openid.net/specs/authorization-api-1_0.html#name-access-evaluations-response

func (*EvaluationsResponse) UnmarshalJSON

func (r *EvaluationsResponse) UnmarshalJSON(data []byte) error

UnmarshalJSON decodes either response shape. When an evaluations array is present (batch mode, Section 7.2) it is decoded into Evaluations and a nil array is normalized to an empty slice. Otherwise the body is treated as a single Access Evaluation response (Section 6.2) and decoded into Decision and Context.

OpenID AuthZEN Authorization API 1.0, Section 7.2 (Access Evaluations Response) and Section 6.2 (Access Evaluation Response). https://openid.net/specs/authorization-api-1_0.html#name-access-evaluations-response

type EvaluationsSemantic

type EvaluationsSemantic string

EvaluationsSemantic selects how a PDP executes the members of a batch request and which decisions it returns.

OpenID AuthZEN Authorization API 1.0, Section 7.1.2.1 (evaluations_semantic). https://openid.net/specs/authorization-api-1_0.html

const (
	// SemanticExecuteAll executes every evaluation (possibly in parallel) and
	// returns all results in request order. This is the default when
	// options.evaluations_semantic is omitted.
	//
	// OpenID AuthZEN Authorization API 1.0, Section 7.1.2.1.
	// https://openid.net/specs/authorization-api-1_0.html
	SemanticExecuteAll EvaluationsSemantic = "execute_all"

	// SemanticDenyOnFirstDeny short-circuits on the first denial or failure and
	// returns the results up to and including that deny (logical AND).
	//
	// OpenID AuthZEN Authorization API 1.0, Section 7.1.2.1.
	// https://openid.net/specs/authorization-api-1_0.html
	SemanticDenyOnFirstDeny EvaluationsSemantic = "deny_on_first_deny"

	// SemanticPermitOnFirstPermit short-circuits on the first permit and
	// returns the results up to and including that permit (logical OR).
	//
	// OpenID AuthZEN Authorization API 1.0, Section 7.1.2.1.
	// https://openid.net/specs/authorization-api-1_0.html
	SemanticPermitOnFirstPermit EvaluationsSemantic = "permit_on_first_permit"
)

type Metadata

type Metadata struct {
	// PolicyDecisionPoint is the base URL of the PDP. REQUIRED. It MUST equal
	// the identifier the well-known URL was derived from, else the PEP discards
	// the document.
	PolicyDecisionPoint string `json:"policy_decision_point"`
	// AccessEvaluationEndpoint is the URL of the Access Evaluation API.
	// REQUIRED.
	AccessEvaluationEndpoint string `json:"access_evaluation_endpoint"`
	// AccessEvaluationsEndpoint is the URL of the Access Evaluations (batch)
	// API. OPTIONAL; absence signals batch is unsupported.
	AccessEvaluationsEndpoint string `json:"access_evaluations_endpoint,omitempty"`
	// SearchSubjectEndpoint is the URL of the Subject Search API. OPTIONAL.
	SearchSubjectEndpoint string `json:"search_subject_endpoint,omitempty"`
	// SearchResourceEndpoint is the URL of the Resource Search API. OPTIONAL.
	SearchResourceEndpoint string `json:"search_resource_endpoint,omitempty"`
	// SearchActionEndpoint is the URL of the Action Search API. OPTIONAL.
	SearchActionEndpoint string `json:"search_action_endpoint,omitempty"`
	// Capabilities is a JSON array of registered IANA URNs describing
	// PDP-specific capabilities. OPTIONAL.
	Capabilities []string `json:"capabilities,omitempty"`
	// SignedMetadata is a JWT asserting the other parameters as claims; it MUST
	// contain an iss claim and, where supported, takes precedence over the
	// plain JSON values. OPTIONAL.
	SignedMetadata string `json:"signed_metadata,omitempty"`
}

Metadata is the PDP configuration document published at /.well-known/authzen-configuration. It advertises the PDP base URL and the endpoints the PDP supports; an absent endpoint parameter signals that the corresponding API is unsupported. Parameters with no value are omitted rather than serialized as null, and unknown parameters MUST be ignored by the PEP.

OpenID AuthZEN Authorization API 1.0, Section 9.1 (Metadata) and Section 12.1.3 (PDP Metadata registry). https://openid.net/specs/authorization-api-1_0.html

type Options

type Options struct {
	// EvaluationsSemantic selects the batch execution semantic. OPTIONAL;
	// absence means SemanticExecuteAll.
	EvaluationsSemantic EvaluationsSemantic
	// Additional holds any implementation-specific options keys other than
	// evaluations_semantic. OPTIONAL.
	Additional map[string]any
}

Options carries PEP-supplied execution metadata for a batch request. The specification defines evaluations_semantic and permits arbitrary additional keys, which are preserved in Additional.

OpenID AuthZEN Authorization API 1.0, Section 7.1.2 (options). https://openid.net/specs/authorization-api-1_0.html

func (Options) MarshalJSON

func (o Options) MarshalJSON() ([]byte, error)

MarshalJSON encodes the Options as a single JSON object, merging the evaluations_semantic key (when set) with any Additional keys.

OpenID AuthZEN Authorization API 1.0, Section 7.1.2 (options). https://openid.net/specs/authorization-api-1_0.html

func (*Options) UnmarshalJSON

func (o *Options) UnmarshalJSON(data []byte) error

UnmarshalJSON decodes a JSON options object, extracting evaluations_semantic and retaining every other key in Additional.

OpenID AuthZEN Authorization API 1.0, Section 7.1.2 (options). https://openid.net/specs/authorization-api-1_0.html

type Page

type Page struct {
	// Token is the opaque cursor from a previous response's next_token.
	// OPTIONAL.
	Token string `json:"token,omitempty"`
	// Limit is the maximum number of results to return (non-negative).
	// OPTIONAL.
	Limit int `json:"limit,omitempty"`
	// Properties holds implementation-specific paging hints such as sorting or
	// filtering. OPTIONAL.
	Properties map[string]any `json:"properties,omitempty"`
}

Page is the pagination object sent in a Search request. The first request omits token; subsequent requests repeat the opaque next_token returned by the PDP until it is the empty string. When a token is supplied, all other request parameters MUST be identical to the prior request.

OpenID AuthZEN Authorization API 1.0, Section 8.2.1 (Request page object). https://openid.net/specs/authorization-api-1_0.html

type PageResponse

type PageResponse struct {
	// NextToken is the opaque cursor for the next page. REQUIRED when the page
	// object is present; an empty string indicates the end of results.
	NextToken string `json:"next_token"`
	// Count is the number of results in this response (non-negative). OPTIONAL.
	Count int `json:"count,omitempty"`
	// Total is the total number of matching results at request time, which is
	// not guaranteed to be stable (non-negative). OPTIONAL.
	Total int `json:"total,omitempty"`
	// Properties holds implementation-specific paging metadata. OPTIONAL.
	Properties map[string]any `json:"properties,omitempty"`
}

PageResponse is the pagination object returned in a Search response. It is RECOMMENDED to be the first key of the response and MUST be present when the response is not the complete result set.

OpenID AuthZEN Authorization API 1.0, Section 8.2.2 (Response page object). https://openid.net/specs/authorization-api-1_0.html

type ReasonContext

type ReasonContext struct {
	// ReasonAdmin holds administrator-facing explanations keyed by code.
	// OPTIONAL.
	ReasonAdmin Reasons `json:"reason_admin,omitempty"`
	// ReasonUser holds user-facing explanations keyed by code. OPTIONAL.
	ReasonUser Reasons `json:"reason_user,omitempty"`
}

ReasonContext is a typed helper for the non-normative decision-context convention that splits explanations into an administrator-facing and a user-facing map, each keyed by a code (for example an HTTP status code). It is provided for convenience; the decision context is a free-form object and implementations are free to use other shapes.

OpenID AuthZEN Authorization API 1.0, Section 5.5 (Decision), Figure 11. https://openid.net/specs/authorization-api-1_0.html

type Reasons

type Reasons map[string]string

Reasons is a map of code to human-readable explanation, used by the non-normative reason_admin and reason_user decision-context conventions illustrated by the specification.

OpenID AuthZEN Authorization API 1.0, Section 5.5 (Decision), Figure 11. https://openid.net/specs/authorization-api-1_0.html

type Resource

type Resource struct {
	// Type is the type of the resource. REQUIRED.
	Type string `json:"type"`
	// ID is the unique identifier of the resource, scoped to Type. REQUIRED for
	// an evaluation, but omitted for a Resource Search query (Section 8.5); the
	// id is therefore omitempty on the wire and enforced by Validate where it
	// is required.
	ID string `json:"id,omitempty"`
	// Properties holds additional resource attributes/metadata, which may be
	// nested objects. OPTIONAL.
	Properties map[string]any `json:"properties,omitempty"`
}

Resource is the target of the requested access (the object being protected). The type/id pair uniquely identifies the resource, and properties carries any additional, possibly nested, attributes.

OpenID AuthZEN Authorization API 1.0, Section 5.2 (Resource). https://openid.net/specs/authorization-api-1_0.html

func (*Resource) Validate

func (r *Resource) Validate() error

Validate reports whether the Resource carries the fields REQUIRED by the specification: a non-empty type and id.

OpenID AuthZEN Authorization API 1.0, Section 5.2 (Resource). https://openid.net/specs/authorization-api-1_0.html

type ResourceSearchRequest

type ResourceSearchRequest struct {
	// Subject is the principal. REQUIRED.
	Subject *Subject `json:"subject,omitempty"`
	// Action is the operation being tested. REQUIRED.
	Action *Action `json:"action,omitempty"`
	// Resource identifies the type of resource being searched for. REQUIRED
	// (type only).
	Resource *Resource `json:"resource,omitempty"`
	// Context carries optional environment/request attributes. OPTIONAL.
	Context Context `json:"context,omitempty"`
	// Page carries pagination parameters. OPTIONAL.
	Page *Page `json:"page,omitempty"`
}

ResourceSearchRequest is the body of a Resource Search request, asking which resources of the given type the subject may perform the action on. The resource's id SHOULD be omitted and MUST be ignored by the PDP if present.

OpenID AuthZEN Authorization API 1.0, Section 8.5 (Resource Search). https://openid.net/specs/authorization-api-1_0.html

func (*ResourceSearchRequest) Validate

func (r *ResourceSearchRequest) Validate() error

Validate checks the fields REQUIRED for a Resource Search: a valid subject, a valid action, and a resource with a type. The resource's id is not required and is not validated here.

OpenID AuthZEN Authorization API 1.0, Section 8.5 (Resource Search). https://openid.net/specs/authorization-api-1_0.html

type ResourceSearchResponse

type ResourceSearchResponse struct {
	// Page carries pagination metadata. OPTIONAL (but MUST be present when the
	// result set is incomplete).
	Page *PageResponse `json:"page,omitempty"`
	// Results holds the authorized resources. REQUIRED.
	Results []Resource `json:"results"`
	// Context carries optional, implementation-specific information. OPTIONAL.
	Context map[string]any `json:"context,omitempty"`
}

ResourceSearchResponse is the body of a Resource Search response. results holds zero or more resources (only of the searched type); page and context are optional.

OpenID AuthZEN Authorization API 1.0, Section 8.3 (Search response) and Section 8.5. https://openid.net/specs/authorization-api-1_0.html

func (ResourceSearchResponse) MarshalJSON

func (r ResourceSearchResponse) MarshalJSON() ([]byte, error)

MarshalJSON encodes the response, normalizing a nil Results slice to an empty array so the REQUIRED results key is serialized as [] rather than JSON null, matching the specification's response examples.

OpenID AuthZEN Authorization API 1.0, Section 8.3 (Search response) and Section 8.5. https://openid.net/specs/authorization-api-1_0.html

type Subject

type Subject struct {
	// Type is the type of the subject. REQUIRED.
	Type string `json:"type"`
	// ID is the unique identifier of the subject, scoped to Type. REQUIRED for
	// an evaluation, but omitted for a Subject Search query (Section 8.4); the
	// id is therefore omitempty on the wire and enforced by Validate where it
	// is required.
	ID string `json:"id,omitempty"`
	// Properties holds additional subject attributes (simple or complex
	// values). OPTIONAL.
	Properties map[string]any `json:"properties,omitempty"`
}

Subject is the principal (user, service, device, ...) whose access is being evaluated. The type/id pair uniquely identifies the subject, and properties carries any additional attributes (for example department, group memberships, device_id, or ip_address).

OpenID AuthZEN Authorization API 1.0, Section 5.1 (Subject). https://openid.net/specs/authorization-api-1_0.html

func (*Subject) Validate

func (s *Subject) Validate() error

Validate reports whether the Subject carries the fields REQUIRED by the specification: a non-empty type and id. It returns a *ValidationError wrapping a package sentinel error otherwise.

OpenID AuthZEN Authorization API 1.0, Section 5.1 (Subject). https://openid.net/specs/authorization-api-1_0.html

type SubjectSearchRequest

type SubjectSearchRequest struct {
	// Subject identifies the type of subject being searched for. REQUIRED
	// (type only).
	Subject *Subject `json:"subject,omitempty"`
	// Action is the operation being tested. REQUIRED.
	Action *Action `json:"action,omitempty"`
	// Resource is the target of the operation. REQUIRED.
	Resource *Resource `json:"resource,omitempty"`
	// Context carries optional environment/request attributes. OPTIONAL.
	Context Context `json:"context,omitempty"`
	// Page carries pagination parameters. OPTIONAL.
	Page *Page `json:"page,omitempty"`
}

SubjectSearchRequest is the body of a Subject Search request, asking which subjects of the given type may perform the action on the resource. The subject's id SHOULD be omitted and MUST be ignored by the PDP if present.

OpenID AuthZEN Authorization API 1.0, Section 8.4 (Subject Search). https://openid.net/specs/authorization-api-1_0.html

func (*SubjectSearchRequest) Validate

func (r *SubjectSearchRequest) Validate() error

Validate checks the fields REQUIRED for a Subject Search: a subject with a type, a valid action, and a valid resource. The subject's id is not required and is not validated here.

OpenID AuthZEN Authorization API 1.0, Section 8.4 (Subject Search). https://openid.net/specs/authorization-api-1_0.html

type SubjectSearchResponse

type SubjectSearchResponse struct {
	// Page carries pagination metadata. OPTIONAL (but MUST be present when the
	// result set is incomplete).
	Page *PageResponse `json:"page,omitempty"`
	// Results holds the authorized subjects. REQUIRED.
	Results []Subject `json:"results"`
	// Context carries optional, implementation-specific information. OPTIONAL.
	Context map[string]any `json:"context,omitempty"`
}

SubjectSearchResponse is the body of a Subject Search response. results holds zero or more subjects (only of the searched type); page and context are optional. The page field is declared first because the specification RECOMMENDS it as the first key.

OpenID AuthZEN Authorization API 1.0, Section 8.3 (Search response) and Section 8.4. https://openid.net/specs/authorization-api-1_0.html

func (SubjectSearchResponse) MarshalJSON

func (r SubjectSearchResponse) MarshalJSON() ([]byte, error)

MarshalJSON encodes the response, normalizing a nil Results slice to an empty array so the REQUIRED results key is serialized as [] rather than JSON null, matching the specification's response examples.

OpenID AuthZEN Authorization API 1.0, Section 8.3 (Search response) and Section 8.4. https://openid.net/specs/authorization-api-1_0.html

type ValidationError

type ValidationError struct {
	// Field is the dotted JSON path of the offending field, for example
	// "subject.type" or "evaluations[2].resource.id".
	Field string
	// Err is the underlying sentinel error describing the failure.
	Err error
}

ValidationError reports a specific field that failed validation. It wraps one of the package sentinel errors so that errors.Is and errors.As can be used to distinguish the cause while still surfacing the offending field path.

OpenID AuthZEN Authorization API 1.0, Section 10.1.1 (JSON Serialization). https://openid.net/specs/authorization-api-1_0.html

func (*ValidationError) Error

func (e *ValidationError) Error() string

Error implements the error interface.

OpenID AuthZEN Authorization API 1.0, Section 10.1.1 (JSON Serialization). https://openid.net/specs/authorization-api-1_0.html

func (*ValidationError) Unwrap

func (e *ValidationError) Unwrap() error

Unwrap returns the wrapped sentinel error, enabling errors.Is matching.

OpenID AuthZEN Authorization API 1.0, Section 10.1.1 (JSON Serialization). https://openid.net/specs/authorization-api-1_0.html

Directories

Path Synopsis
Package accessrequest implements the OpenID AuthZEN Access Request and Approval Profile, an extension profile of the AuthZEN Authorization API that lets a Policy Enforcement Point (PEP) submit an access request when an authorization decision is denied but requestable.
Package accessrequest implements the OpenID AuthZEN Access Request and Approval Profile, an extension profile of the AuthZEN Authorization API that lets a Policy Enforcement Point (PEP) submit an access request when an authorization decision is denied but requestable.
Package approval implements the "aarp" approval-workflow extension for the OpenID AuthZEN Authorization API 1.0: asynchronous, human-in-the-loop access decisions that are not yet resolved at evaluation time (a PENDING decision).
Package approval implements the "aarp" approval-workflow extension for the OpenID AuthZEN Authorization API 1.0: asynchronous, human-in-the-loop access decisions that are not yet resolved at evaluation time (a PENDING decision).
Package client implements a Policy Enforcement Point (PEP) client for the OpenID AuthZEN Authorization API 1.0 over the normative HTTPS + JSON binding.
Package client implements a Policy Enforcement Point (PEP) client for the OpenID AuthZEN Authorization API 1.0 over the normative HTTPS + JSON binding.
cmd
authzen command
Command authzen is a command-line Policy Enforcement Point (PEP) for the OpenID AuthZEN Authorization API 1.0.
Command authzen is a command-line Policy Enforcement Point (PEP) for the OpenID AuthZEN Authorization API 1.0.
Package interop hosts the AuthZEN 1.0 interoperability conformance harness.
Package interop hosts the AuthZEN 1.0 interoperability conformance harness.
Package mcp is a non-normative AuthZEN profile for Model Context Protocol (MCP) authorization.
Package mcp is a non-normative AuthZEN profile for Model Context Protocol (MCP) authorization.
Package server implements a Policy Decision Point (PDP) for the OpenID AuthZEN Authorization API 1.0 over the normative HTTPS + JSON binding.
Package server implements a Policy Decision Point (PDP) for the OpenID AuthZEN Authorization API 1.0 over the normative HTTPS + JSON binding.

Jump to

Keyboard shortcuts

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