openidauthzen 0.1.0-alpha.1

OpenID AuthZEN Authorization API 1.0 — Policy Decision and Enforcement Points for Rust
Documentation
//! Core data types for the [Authorization API 1.0][authzen].
//!
//! This module defines the four entities that make up an access evaluation
//! request ([`Subject`], [`Resource`], [`Action`], [`Context`]) and the
//! [`Decision`] returned by the PDP.
//!
//! [authzen]: https://openid.net/specs/authorization-api-1_0.html

use serde::{Deserialize, Serialize};

/// The entity requesting access ([AuthZEN §5.1]).
///
/// Represents a user, service account, or machine identity initiating
/// an authorization request. The `type` and `id` fields are required
/// for access evaluation requests; for search requests the `id` field
/// SHOULD be omitted.
///
/// [AuthZEN §5.1]: https://openid.net/specs/authorization-api-1_0.html#section-5.1
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Subject {
    /// The type of subject (e.g. `"user"`, `"service_account"`). Required.
    #[serde(rename = "type")]
    pub subject_type: String,
    /// The unique identifier of the subject. Required for evaluation
    /// requests; omit for subject search requests.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub id: Option<String>,
    /// Additional attributes describing the subject (e.g. department,
    /// device identifier, IP address).
    #[serde(skip_serializing_if = "Option::is_none")]
    pub properties: Option<serde_json::Value>,
}

/// The target being accessed ([AuthZEN §5.2]).
///
/// Represents the object, document, API endpoint, or other entity
/// that the subject is attempting to access. The `type` and `id` fields
/// are required for access evaluation requests; for search requests the
/// `id` field SHOULD be omitted.
///
/// [AuthZEN §5.2]: https://openid.net/specs/authorization-api-1_0.html#section-5.2
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Resource {
    /// The type of resource (e.g. `"document"`, `"endpoint"`). Required.
    #[serde(rename = "type")]
    pub resource_type: String,
    /// The unique identifier of the resource. Required for evaluation
    /// requests; omit for resource search requests.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub id: Option<String>,
    /// Additional attributes describing the resource (e.g. owner,
    /// sensitivity level, tags).
    #[serde(skip_serializing_if = "Option::is_none")]
    pub properties: Option<serde_json::Value>,
}

/// The operation being requested ([AuthZEN §5.3]).
///
/// Describes what the subject wants to do with the resource.
///
/// [AuthZEN §5.3]: https://openid.net/specs/authorization-api-1_0.html#section-5.3
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Action {
    /// The name of the action (e.g. `"read"`, `"write"`, `"delete"`). Required.
    pub name: String,
    /// Additional attributes describing the action.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub properties: Option<serde_json::Value>,
}

/// Environmental context for an access evaluation request ([AuthZEN §5.4]).
///
/// A free-form JSON object carrying contextual information relevant to the
/// authorization decision — timestamps, location, schema references, etc.
/// The specification does not prescribe a fixed structure.
///
/// [AuthZEN §5.4]: https://openid.net/specs/authorization-api-1_0.html#section-5.4
pub type Context = serde_json::Map<String, serde_json::Value>;

/// An authorization decision returned by the PDP ([AuthZEN §5.5]).
///
/// Contains a boolean `decision` (`true` = permit, `false` = deny) and
/// an optional `context` with additional information such as reasons,
/// obligations, or authentication requirements.
///
/// A `200` HTTP response with `{ "decision": false }` is a normal deny —
/// distinct from HTTP error codes that indicate request processing failures.
///
/// [AuthZEN §5.5]: https://openid.net/specs/authorization-api-1_0.html#section-5.5
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Decision {
    /// `true` for permit, `false` for deny. Required.
    pub decision: bool,
    /// Additional decision context (reasons, obligations, etc.).
    #[serde(skip_serializing_if = "Option::is_none")]
    pub context: Option<serde_json::Value>,
}