//! Generated by `trust-tasks-codegen` — do not edit by hand.
//!
//! Spec slug: `policy/evaluate`. Version: `0.4`.
/// Why this specification version is deprecated (SPEC "Superseded and
/// Withdrawn Versions"), or `None` while it is current.
pub const DEPRECATION: Option<&str> = None;
#[allow(unused_imports)]
use serde::{Deserialize, Serialize};
/// Error types.
pub mod error {
/// Error from a `TryFrom` or `FromStr` implementation.
pub struct ConversionError(::std::borrow::Cow<'static, str>);
impl ::std::error::Error for ConversionError {}
impl ::std::fmt::Display for ConversionError {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> Result<(), ::std::fmt::Error> {
::std::fmt::Display::fmt(&self.0, f)
}
}
impl ::std::fmt::Debug for ConversionError {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> Result<(), ::std::fmt::Error> {
::std::fmt::Debug::fmt(&self.0, f)
}
}
impl From<&'static str> for ConversionError {
fn from(value: &'static str) -> Self {
Self(value.into())
}
}
impl From<String> for ConversionError {
fn from(value: String) -> Self {
Self(value.into())
}
}
}
///Discriminator: is this consumer a user-driven Companion or a headless Service?
///
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(tag = "kind", deny_unknown_fields)]
#[non_exhaustive]
pub enum ConsumerKind {
///Companion
#[serde(rename = "companion")]
Companion {
#[serde(rename = "formFactor")]
form_factor: ConsumerKindFormFactor,
},
///Service
#[serde(rename = "service")]
Service {
#[serde(rename = "serviceKind")]
service_kind: ConsumerKindServiceKind,
},
}
///`ConsumerKindFormFactor`
///
#[derive(
::serde::Deserialize,
::serde::Serialize,
Clone,
Copy,
Debug,
Eq,
Hash,
Ord,
PartialEq,
PartialOrd,
)]
#[non_exhaustive]
pub enum ConsumerKindFormFactor {
#[serde(rename = "browser")]
Browser,
#[serde(rename = "mobile")]
Mobile,
#[serde(rename = "desktop")]
Desktop,
}
impl ::std::fmt::Display for ConsumerKindFormFactor {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
match *self {
Self::Browser => f.write_str("browser"),
Self::Mobile => f.write_str("mobile"),
Self::Desktop => f.write_str("desktop"),
}
}
}
impl ::std::str::FromStr for ConsumerKindFormFactor {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
match value {
"browser" => Ok(Self::Browser),
"mobile" => Ok(Self::Mobile),
"desktop" => Ok(Self::Desktop),
_ => Err("invalid value".into()),
}
}
}
impl ::std::convert::TryFrom<&str> for ConsumerKindFormFactor {
type Error = self::error::ConversionError;
fn try_from(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<&::std::string::String> for ConsumerKindFormFactor {
type Error = self::error::ConversionError;
fn try_from(
value: &::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<::std::string::String> for ConsumerKindFormFactor {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
///`ConsumerKindServiceKind`
///
#[derive(
::serde::Deserialize,
::serde::Serialize,
Clone,
Copy,
Debug,
Eq,
Hash,
Ord,
PartialEq,
PartialOrd,
)]
#[non_exhaustive]
pub enum ConsumerKindServiceKind {
#[serde(rename = "mediator")]
Mediator,
#[serde(rename = "aiAgent")]
AiAgent,
#[serde(rename = "daemon")]
Daemon,
}
impl ::std::fmt::Display for ConsumerKindServiceKind {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
match *self {
Self::Mediator => f.write_str("mediator"),
Self::AiAgent => f.write_str("aiAgent"),
Self::Daemon => f.write_str("daemon"),
}
}
}
impl ::std::str::FromStr for ConsumerKindServiceKind {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
match value {
"mediator" => Ok(Self::Mediator),
"aiAgent" => Ok(Self::AiAgent),
"daemon" => Ok(Self::Daemon),
_ => Err("invalid value".into()),
}
}
}
impl ::std::convert::TryFrom<&str> for ConsumerKindServiceKind {
type Error = self::error::ConversionError;
fn try_from(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<&::std::string::String> for ConsumerKindServiceKind {
type Error = self::error::ConversionError;
fn try_from(
value: &::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<::std::string::String> for ConsumerKindServiceKind {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
/**
A cryptographic digest as a multibase-encoded multihash — the encoding the W3C Verifiable Credentials Data Model 2.0 defines for `digestMultibase`, and the one `did:webvh` uses for its SCID and entry hashes.
Multihash carries the hash algorithm in-band, so the value is self-describing and the wire format survives an algorithm change without a schema revision; multibase does the same for the base encoding, so a verifier never infers base58 from base64url by context. A bare hex string or a `sha-256:`-style prefix hard-codes one algorithm into the wire contract and is non-conforming here.
This definition constrains the *encoding only*. What the digest is computed over is stated by each referencing field, because it differs legitimately: a digest over a JSON document is taken over its RFC 8785 (JCS) canonicalization, while a digest over an opaque artifact is taken over its bytes. A field whose input is a JSON document and which does not name a canonicalization is not reproducible.
Restricted to the two multibase headers W3C Controlled Identifiers 1.0 §2.4 normatively requires — `z` (base58btc) and `u` (base64url-no-pad). CID permits others but states that "interoperability is not guaranteed between implementations using such values", and a registry whose purpose is interoperability should not mint digests a conforming verifier may be unable to read. The alphabets are enforced rather than assumed: base58btc excludes 0, O, I and l, and an earlier permissive pattern let three published examples carry digests that were not valid base58 at all. base58btc is RECOMMENDED, for consistency with `did:key` and `did:webvh`.*/
///
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct DigestMultibase(::std::string::String);
impl ::std::ops::Deref for DigestMultibase {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<DigestMultibase> for ::std::string::String {
fn from(value: DigestMultibase) -> Self {
value.0
}
}
impl ::std::str::FromStr for DigestMultibase {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
if value.chars().count() < 16usize {
return Err("shorter than 16 characters".into());
}
static PATTERN: ::std::sync::LazyLock<::regress::Regex> =
::std::sync::LazyLock::new(|| {
::regress::Regex::new("^(z[1-9A-HJ-NP-Za-km-z]+|u[A-Za-z0-9_-]+)$").unwrap()
});
if PATTERN.find(value).is_none() {
return Err(
"doesn't match pattern \"^(z[1-9A-HJ-NP-Za-km-z]+|u[A-Za-z0-9_-]+)$\"".into(),
);
}
Ok(Self(value.to_string()))
}
}
impl ::std::convert::TryFrom<&str> for DigestMultibase {
type Error = self::error::ConversionError;
fn try_from(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<&::std::string::String> for DigestMultibase {
type Error = self::error::ConversionError;
fn try_from(
value: &::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<::std::string::String> for DigestMultibase {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl<'de> ::serde::Deserialize<'de> for DigestMultibase {
fn deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error>
where
D: ::serde::Deserializer<'de>,
{
::std::string::String::deserialize(deserializer)?
.parse()
.map_err(|e: self::error::ConversionError| {
<D::Error as ::serde::de::Error>::custom(e.to_string())
})
}
}
///Vendor-namespaced extension object per SPEC.md §4.5.1. Each immediate key MUST be a reverse-DNS namespace; structure under each namespace is opaque to the framework.
///
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(transparent)]
pub struct Ext(pub ::std::collections::HashMap<ExtKey, ::serde_json::Value>);
impl ::std::ops::Deref for Ext {
type Target = ::std::collections::HashMap<ExtKey, ::serde_json::Value>;
fn deref(&self) -> &::std::collections::HashMap<ExtKey, ::serde_json::Value> {
&self.0
}
}
impl ::std::convert::From<Ext> for ::std::collections::HashMap<ExtKey, ::serde_json::Value> {
fn from(value: Ext) -> Self {
value.0
}
}
impl ::std::convert::From<::std::collections::HashMap<ExtKey, ::serde_json::Value>> for Ext {
fn from(value: ::std::collections::HashMap<ExtKey, ::serde_json::Value>) -> Self {
Self(value)
}
}
///`ExtKey`
///
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct ExtKey(::std::string::String);
impl ::std::ops::Deref for ExtKey {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<ExtKey> for ::std::string::String {
fn from(value: ExtKey) -> Self {
value.0
}
}
impl ::std::str::FromStr for ExtKey {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
static PATTERN: ::std::sync::LazyLock<::regress::Regex> =
::std::sync::LazyLock::new(|| {
::regress::Regex::new("^[a-z][a-z0-9-]*(\\.[a-z0-9-]+)+$").unwrap()
});
if PATTERN.find(value).is_none() {
return Err("doesn't match pattern \"^[a-z][a-z0-9-]*(\\.[a-z0-9-]+)+$\"".into());
}
Ok(Self(value.to_string()))
}
}
impl ::std::convert::TryFrom<&str> for ExtKey {
type Error = self::error::ConversionError;
fn try_from(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<&::std::string::String> for ExtKey {
type Error = self::error::ConversionError;
fn try_from(
value: &::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<::std::string::String> for ExtKey {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl<'de> ::serde::Deserialize<'de> for ExtKey {
fn deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error>
where
D: ::serde::Deserializer<'de>,
{
::std::string::String::deserialize(deserializer)?
.parse()
.map_err(|e: self::error::ConversionError| {
<D::Error as ::serde::de::Error>::custom(e.to_string())
})
}
}
///Dry-run a policy decision against a synthetic PolicyInput. Returns the policy decision plus a trace of which policy modules matched and which rules fired. Used by the policy-editor UI to verify changes before save and by admins to diagnose unexpected outcomes. 0.3 evaluates against the generalised PolicyInput (any Trust Task, carrying typeUri + side-effect/exposure classes) and can return the `requireConsent` decision.
///
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct Payload {
///Optional — when supplied, evaluate as if this Rego source were active (e.g. preview a pending upsert). The candidate is layered into the evaluator at the priority specified by `candidatePriority` (default 1000) for this call only.
#[serde(
rename = "candidateModule",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub candidate_module: ::std::option::Option<::std::string::String>,
#[serde(
rename = "candidatePriority",
default = "defaults::default_u64::<i64, 1000>"
)]
pub candidate_priority: i64,
#[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
pub ext: ::std::option::Option<Ext>,
#[serde(rename = "includeTrace", default)]
pub include_trace: bool,
pub input: PolicyInput,
}
impl Payload {
pub fn builder() -> builder::Payload {
Default::default()
}
}
///`PolicyDecision`
///
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct PolicyDecision {
pub decision: PolicyDecisionDecision,
///Human-readable explanation for diagnostic display.
#[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
pub explanation: ::std::option::Option<PolicyDecisionExplanation>,
///Vault-flow-specific. When decision == "allow" for a proxy-login/release request, whether the maintainer should proxy-login or release-for-fill. Default: proxy. Ignored for other task kinds.
#[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
pub mode: ::std::option::Option<PolicyDecisionMode>,
#[serde(
rename = "requireConsent",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub require_consent: ::std::option::Option<PolicyDecisionRequireConsent>,
#[serde(
rename = "stepUp",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub step_up: ::std::option::Option<PolicyDecisionStepUp>,
///When decision == "allow", maximum lifetime of any issued session blob / released secret.
#[serde(
rename = "ttlSecondsCap",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub ttl_seconds_cap: ::std::option::Option<::std::num::NonZeroU64>,
}
impl PolicyDecision {
pub fn builder() -> builder::PolicyDecision {
Default::default()
}
}
///`PolicyDecisionDecision`
///
#[derive(
::serde::Deserialize,
::serde::Serialize,
Clone,
Copy,
Debug,
Eq,
Hash,
Ord,
PartialEq,
PartialOrd,
)]
#[non_exhaustive]
pub enum PolicyDecisionDecision {
#[serde(rename = "allow")]
Allow,
#[serde(rename = "deny")]
Deny,
#[serde(rename = "requireStepUp")]
RequireStepUp,
#[serde(rename = "requireConsent")]
RequireConsent,
}
impl ::std::fmt::Display for PolicyDecisionDecision {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
match *self {
Self::Allow => f.write_str("allow"),
Self::Deny => f.write_str("deny"),
Self::RequireStepUp => f.write_str("requireStepUp"),
Self::RequireConsent => f.write_str("requireConsent"),
}
}
}
impl ::std::str::FromStr for PolicyDecisionDecision {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
match value {
"allow" => Ok(Self::Allow),
"deny" => Ok(Self::Deny),
"requireStepUp" => Ok(Self::RequireStepUp),
"requireConsent" => Ok(Self::RequireConsent),
_ => Err("invalid value".into()),
}
}
}
impl ::std::convert::TryFrom<&str> for PolicyDecisionDecision {
type Error = self::error::ConversionError;
fn try_from(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<&::std::string::String> for PolicyDecisionDecision {
type Error = self::error::ConversionError;
fn try_from(
value: &::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<::std::string::String> for PolicyDecisionDecision {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
///Human-readable explanation for diagnostic display.
///
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct PolicyDecisionExplanation(::std::string::String);
impl ::std::ops::Deref for PolicyDecisionExplanation {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<PolicyDecisionExplanation> for ::std::string::String {
fn from(value: PolicyDecisionExplanation) -> Self {
value.0
}
}
impl ::std::str::FromStr for PolicyDecisionExplanation {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
if value.chars().count() > 1024usize {
return Err("longer than 1024 characters".into());
}
Ok(Self(value.to_string()))
}
}
impl ::std::convert::TryFrom<&str> for PolicyDecisionExplanation {
type Error = self::error::ConversionError;
fn try_from(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<&::std::string::String> for PolicyDecisionExplanation {
type Error = self::error::ConversionError;
fn try_from(
value: &::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<::std::string::String> for PolicyDecisionExplanation {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl<'de> ::serde::Deserialize<'de> for PolicyDecisionExplanation {
fn deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error>
where
D: ::serde::Deserializer<'de>,
{
::std::string::String::deserialize(deserializer)?
.parse()
.map_err(|e: self::error::ConversionError| {
<D::Error as ::serde::de::Error>::custom(e.to_string())
})
}
}
///Vault-flow-specific. When decision == "allow" for a proxy-login/release request, whether the maintainer should proxy-login or release-for-fill. Default: proxy. Ignored for other task kinds.
///
#[derive(
::serde::Deserialize,
::serde::Serialize,
Clone,
Copy,
Debug,
Eq,
Hash,
Ord,
PartialEq,
PartialOrd,
)]
#[non_exhaustive]
pub enum PolicyDecisionMode {
#[serde(rename = "proxy")]
Proxy,
#[serde(rename = "fill")]
Fill,
}
impl ::std::fmt::Display for PolicyDecisionMode {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
match *self {
Self::Proxy => f.write_str("proxy"),
Self::Fill => f.write_str("fill"),
}
}
}
impl ::std::str::FromStr for PolicyDecisionMode {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
match value {
"proxy" => Ok(Self::Proxy),
"fill" => Ok(Self::Fill),
_ => Err("invalid value".into()),
}
}
}
impl ::std::convert::TryFrom<&str> for PolicyDecisionMode {
type Error = self::error::ConversionError;
fn try_from(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<&::std::string::String> for PolicyDecisionMode {
type Error = self::error::ConversionError;
fn try_from(
value: &::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<::std::string::String> for PolicyDecisionMode {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
///When decision == "requireConsent", the approver constraint the enforcement point MUST satisfy — a signed consent decision from the named set, bound to the request's payloadDigest — before executing.
///
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct PolicyDecisionRequireConsent {
///Named set of enrolled approver devices permitted to approve this task (resolved by the enforcement point against its device registry).
#[serde(rename = "approverSet")]
pub approver_set: ::std::string::String,
///REQUIRED, with no default: whether the requester may approve its own request is the community's choice, not this schema's (SPEC §6.6 rule 5). When true, the device that issued the request MUST NOT be accepted as the approver — forcing cross-device approval so a compromised requesting device cannot self-approve.
#[serde(rename = "excludeRequester")]
pub exclude_requester: bool,
///REQUIRED, with no default: the quorum is the community's choice, not this schema's (SPEC §6.6 rule 5), and an omitted quorum is malformedRequest rather than one. Number of distinct approvers from the set required before the task may execute.
#[serde(rename = "minApprovals")]
pub min_approvals: ::std::num::NonZeroU64,
}
impl PolicyDecisionRequireConsent {
pub fn builder() -> builder::PolicyDecisionRequireConsent {
Default::default()
}
}
///When decision == "requireStepUp", which method to demand.
///
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct PolicyDecisionStepUp {
pub method: PolicyDecisionStepUpMethod,
#[serde(
rename = "ttlSeconds",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub ttl_seconds: ::std::option::Option<::std::num::NonZeroU64>,
}
impl PolicyDecisionStepUp {
pub fn builder() -> builder::PolicyDecisionStepUp {
Default::default()
}
}
///`PolicyDecisionStepUpMethod`
///
#[derive(
::serde::Deserialize,
::serde::Serialize,
Clone,
Copy,
Debug,
Eq,
Hash,
Ord,
PartialEq,
PartialOrd,
)]
#[non_exhaustive]
pub enum PolicyDecisionStepUpMethod {
#[serde(rename = "webauthnUv")]
WebauthnUv,
#[serde(rename = "pushApproval")]
PushApproval,
#[serde(rename = "totp")]
Totp,
}
impl ::std::fmt::Display for PolicyDecisionStepUpMethod {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
match *self {
Self::WebauthnUv => f.write_str("webauthnUv"),
Self::PushApproval => f.write_str("pushApproval"),
Self::Totp => f.write_str("totp"),
}
}
}
impl ::std::str::FromStr for PolicyDecisionStepUpMethod {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
match value {
"webauthnUv" => Ok(Self::WebauthnUv),
"pushApproval" => Ok(Self::PushApproval),
"totp" => Ok(Self::Totp),
_ => Err("invalid value".into()),
}
}
}
impl ::std::convert::TryFrom<&str> for PolicyDecisionStepUpMethod {
type Error = self::error::ConversionError;
fn try_from(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<&::std::string::String> for PolicyDecisionStepUpMethod {
type Error = self::error::ConversionError;
fn try_from(
value: &::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<::std::string::String> for PolicyDecisionStepUpMethod {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
///The structured input fed to a policy evaluator before dispatching a task. Generalised in 0.3 from the vault-flow triad to any Trust Task: `request.typeUri` identifies the task and `request.sideEffects` / `request.exposure` carry the authoritative SPEC §7.3 classifications the evaluator derives from the compiled handler.
///
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct PolicyInput {
pub consumer: PolicyInputConsumer,
#[serde(rename = "contextId")]
pub context_id: PolicyInputContextId,
pub request: PolicyInputRequest,
pub site: SiteTarget,
}
impl PolicyInput {
pub fn builder() -> builder::PolicyInput {
Default::default()
}
}
///`PolicyInputConsumer`
///
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct PolicyInputConsumer {
#[serde(
rename = "deviceId",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub device_id: ::std::option::Option<::std::string::String>,
pub did: ::std::string::String,
#[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
pub kind: ::std::option::Option<ConsumerKind>,
#[serde(
rename = "lastUserVerificationAt",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub last_user_verification_at: ::std::option::Option<::chrono::DateTime<::chrono::offset::Utc>>,
#[serde(
rename = "networkClass",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub network_class: ::std::option::Option<PolicyInputConsumerNetworkClass>,
}
impl PolicyInputConsumer {
pub fn builder() -> builder::PolicyInputConsumer {
Default::default()
}
}
///`PolicyInputConsumerNetworkClass`
///
#[derive(
::serde::Deserialize,
::serde::Serialize,
Clone,
Copy,
Debug,
Eq,
Hash,
Ord,
PartialEq,
PartialOrd,
)]
#[non_exhaustive]
pub enum PolicyInputConsumerNetworkClass {
#[serde(rename = "unknown")]
Unknown,
#[serde(rename = "home")]
Home,
#[serde(rename = "corp")]
Corp,
#[serde(rename = "public")]
Public,
#[serde(rename = "vpn")]
Vpn,
}
impl ::std::fmt::Display for PolicyInputConsumerNetworkClass {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
match *self {
Self::Unknown => f.write_str("unknown"),
Self::Home => f.write_str("home"),
Self::Corp => f.write_str("corp"),
Self::Public => f.write_str("public"),
Self::Vpn => f.write_str("vpn"),
}
}
}
impl ::std::str::FromStr for PolicyInputConsumerNetworkClass {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
match value {
"unknown" => Ok(Self::Unknown),
"home" => Ok(Self::Home),
"corp" => Ok(Self::Corp),
"public" => Ok(Self::Public),
"vpn" => Ok(Self::Vpn),
_ => Err("invalid value".into()),
}
}
}
impl ::std::convert::TryFrom<&str> for PolicyInputConsumerNetworkClass {
type Error = self::error::ConversionError;
fn try_from(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<&::std::string::String> for PolicyInputConsumerNetworkClass {
type Error = self::error::ConversionError;
fn try_from(
value: &::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<::std::string::String> for PolicyInputConsumerNetworkClass {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
///`PolicyInputContextId`
///
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct PolicyInputContextId(::std::string::String);
impl ::std::ops::Deref for PolicyInputContextId {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<PolicyInputContextId> for ::std::string::String {
fn from(value: PolicyInputContextId) -> Self {
value.0
}
}
impl ::std::str::FromStr for PolicyInputContextId {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
if value.chars().count() < 1usize {
return Err("shorter than 1 characters".into());
}
Ok(Self(value.to_string()))
}
}
impl ::std::convert::TryFrom<&str> for PolicyInputContextId {
type Error = self::error::ConversionError;
fn try_from(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<&::std::string::String> for PolicyInputContextId {
type Error = self::error::ConversionError;
fn try_from(
value: &::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<::std::string::String> for PolicyInputContextId {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl<'de> ::serde::Deserialize<'de> for PolicyInputContextId {
fn deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error>
where
D: ::serde::Deserializer<'de>,
{
::std::string::String::deserialize(deserializer)?
.parse()
.map_err(|e: self::error::ConversionError| {
<D::Error as ::serde::de::Error>::custom(e.to_string())
})
}
}
///`PolicyInputRequest`
///
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct PolicyInputRequest {
pub exposure: PolicyInputRequestExposure,
///Optional coarse category retained from 0.2 (`proxyLogin` | `release` | `stepUpResponse` | …) for policies that switch on it. `typeUri` is authoritative in 0.3.
#[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
pub kind: ::std::option::Option<::std::string::String>,
///Multibase-encoded multihash over the RFC 8785 (JCS) canonicalization of the payload, salted with the request challenge, present when a delegated-execution consent flow must bind approval to this exact payload. Absent when no consent binding is in play.
#[serde(
rename = "payloadDigest",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub payload_digest: ::std::option::Option<DigestMultibase>,
///Authoritative integrity class (SPEC §7.3 item 13). The evaluator MUST derive this from the compiled handler it is about to invoke, not from the wire — the registry's declared value is advisory only.
#[serde(rename = "sideEffects")]
pub side_effects: PolicyInputRequestSideEffects,
///The identifier the task acts on — the value at the spec's `subjectPath` (usually a DID). The evaluator checks the consumer's authority to act on this subject. Absent for subjectless tasks (discovery, list).
#[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
pub subject: ::std::option::Option<::std::string::String>,
///Type URI of the task being authorized — the evaluator's primary discriminator (e.g. https://trusttasks.org/spec/did-management/did/delete/0.1).
#[serde(rename = "typeUri")]
pub type_uri: ::std::string::String,
}
impl PolicyInputRequest {
pub fn builder() -> builder::PolicyInputRequest {
Default::default()
}
}
///Authoritative exposure class (SPEC §7.3 item 14), likewise derived from the compiled handler. `discloses` is the sensitivity of returned data; `actsAsSubject` is whether the subject's authority is exercised.
///
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct PolicyInputRequestExposure {
#[serde(rename = "actsAsSubject")]
pub acts_as_subject: bool,
pub discloses: PolicyInputRequestExposureDiscloses,
}
impl PolicyInputRequestExposure {
pub fn builder() -> builder::PolicyInputRequestExposure {
Default::default()
}
}
///`PolicyInputRequestExposureDiscloses`
///
#[derive(
::serde::Deserialize,
::serde::Serialize,
Clone,
Copy,
Debug,
Eq,
Hash,
Ord,
PartialEq,
PartialOrd,
)]
#[non_exhaustive]
pub enum PolicyInputRequestExposureDiscloses {
#[serde(rename = "none")]
None,
#[serde(rename = "metadata")]
Metadata,
#[serde(rename = "secret")]
Secret,
}
impl ::std::fmt::Display for PolicyInputRequestExposureDiscloses {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
match *self {
Self::None => f.write_str("none"),
Self::Metadata => f.write_str("metadata"),
Self::Secret => f.write_str("secret"),
}
}
}
impl ::std::str::FromStr for PolicyInputRequestExposureDiscloses {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
match value {
"none" => Ok(Self::None),
"metadata" => Ok(Self::Metadata),
"secret" => Ok(Self::Secret),
_ => Err("invalid value".into()),
}
}
}
impl ::std::convert::TryFrom<&str> for PolicyInputRequestExposureDiscloses {
type Error = self::error::ConversionError;
fn try_from(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<&::std::string::String> for PolicyInputRequestExposureDiscloses {
type Error = self::error::ConversionError;
fn try_from(
value: &::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<::std::string::String> for PolicyInputRequestExposureDiscloses {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
///Authoritative integrity class (SPEC §7.3 item 13). The evaluator MUST derive this from the compiled handler it is about to invoke, not from the wire — the registry's declared value is advisory only.
///
#[derive(
::serde::Deserialize,
::serde::Serialize,
Clone,
Copy,
Debug,
Eq,
Hash,
Ord,
PartialEq,
PartialOrd,
)]
#[non_exhaustive]
pub enum PolicyInputRequestSideEffects {
#[serde(rename = "none")]
None,
#[serde(rename = "mutating")]
Mutating,
#[serde(rename = "destructive")]
Destructive,
}
impl ::std::fmt::Display for PolicyInputRequestSideEffects {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
match *self {
Self::None => f.write_str("none"),
Self::Mutating => f.write_str("mutating"),
Self::Destructive => f.write_str("destructive"),
}
}
}
impl ::std::str::FromStr for PolicyInputRequestSideEffects {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
match value {
"none" => Ok(Self::None),
"mutating" => Ok(Self::Mutating),
"destructive" => Ok(Self::Destructive),
_ => Err("invalid value".into()),
}
}
}
impl ::std::convert::TryFrom<&str> for PolicyInputRequestSideEffects {
type Error = self::error::ConversionError;
fn try_from(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<&::std::string::String> for PolicyInputRequestSideEffects {
type Error = self::error::ConversionError;
fn try_from(
value: &::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<::std::string::String> for PolicyInputRequestSideEffects {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
///`Response`
///
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct Response {
pub decision: PolicyDecision,
#[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
pub ext: ::std::option::Option<Ext>,
///Ids (or `candidate` for the dry-run module) of the policies that returned a non-null decision, in evaluation order. The first is the winning policy.
#[serde(
rename = "matchedPolicies",
default,
skip_serializing_if = "::std::vec::Vec::is_empty"
)]
pub matched_policies: ::std::vec::Vec<::std::string::String>,
///Rego evaluator trace lines when `includeTrace: true`. Maintainer-defined format; primarily for human debugging.
#[serde(default, skip_serializing_if = "::std::vec::Vec::is_empty")]
pub trace: ::std::vec::Vec<ResponseTraceItem>,
}
impl Response {
pub fn builder() -> builder::Response {
Default::default()
}
}
///`ResponseTraceItem`
///
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct ResponseTraceItem(::std::string::String);
impl ::std::ops::Deref for ResponseTraceItem {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<ResponseTraceItem> for ::std::string::String {
fn from(value: ResponseTraceItem) -> Self {
value.0
}
}
impl ::std::str::FromStr for ResponseTraceItem {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
if value.chars().count() > 1024usize {
return Err("longer than 1024 characters".into());
}
Ok(Self(value.to_string()))
}
}
impl ::std::convert::TryFrom<&str> for ResponseTraceItem {
type Error = self::error::ConversionError;
fn try_from(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<&::std::string::String> for ResponseTraceItem {
type Error = self::error::ConversionError;
fn try_from(
value: &::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<::std::string::String> for ResponseTraceItem {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl<'de> ::serde::Deserialize<'de> for ResponseTraceItem {
fn deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error>
where
D: ::serde::Deserializer<'de>,
{
::std::string::String::deserialize(deserializer)?
.parse()
.map_err(|e: self::error::ConversionError| {
<D::Error as ::serde::de::Error>::custom(e.to_string())
})
}
}
///A single binding target for a vault entry. Tagged union over the discriminator `kind`. A VaultEntry's `targets` array MAY mix any number of these.
///
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(tag = "kind", deny_unknown_fields)]
#[non_exhaustive]
pub enum SiteTarget {
///WebOrigin
#[serde(rename = "webOrigin")]
WebOrigin {
///Web origin per RFC 6454 (scheme + host + optional port), e.g. "https://github.com". Compared by exact string equality after canonicalisation (lowercase host, default port elided). Consumers wanting subdomain coverage SHOULD add multiple targets, not encode a wildcard.
origin: ::std::string::String,
},
///Did
#[serde(rename = "did")]
Did {
///DID identifying the relying party (e.g. did:web:rp.example). The vault maintainer is responsible for any DID resolution required to act on this entry.
did: SiteTargetDid,
},
///IosApp
#[serde(rename = "iosApp")]
IosApp {
///iOS bundle identifier in reverse-DNS form (e.g. "com.github.stwalkerster.codehub"). Compared by exact string equality. Matches when an iOS Companion identifies the requesting app via its bundle id (typically via the OS Credential Manager integration).
#[serde(rename = "bundleId")]
bundle_id: SiteTargetBundleId,
///Optional Apple Developer Team identifier (10-character alphanumeric). When supplied, the maintainer SHOULD also verify the team id of the requesting app before matching — defense in depth against bundle-id squatting on jailbroken devices.
#[serde(
rename = "teamId",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
team_id: ::std::option::Option<SiteTargetTeamId>,
},
///AndroidApp
#[serde(rename = "androidApp")]
AndroidApp {
///Android package name in reverse-DNS form (e.g. "com.github.android").
#[serde(rename = "packageName")]
package_name: SiteTargetPackageName,
///SHA-256 fingerprints of the app's signing certificates, in colon-separated hex (the format `apksigner` and the Play Console emit). At least one fingerprint MUST be present. The maintainer matches when ANY of the provided fingerprints matches the requesting app's signature — this supports apps signed by multiple keys (e.g. during certificate rotation via Play App Signing).
#[serde(rename = "sha256CertFingerprints")]
sha256_cert_fingerprints: Vec<SiteTargetSha256CertFingerprintsItem>,
},
}
///iOS bundle identifier in reverse-DNS form (e.g. "com.github.stwalkerster.codehub"). Compared by exact string equality. Matches when an iOS Companion identifies the requesting app via its bundle id (typically via the OS Credential Manager integration).
///
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct SiteTargetBundleId(::std::string::String);
impl ::std::ops::Deref for SiteTargetBundleId {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<SiteTargetBundleId> for ::std::string::String {
fn from(value: SiteTargetBundleId) -> Self {
value.0
}
}
impl ::std::str::FromStr for SiteTargetBundleId {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
if value.chars().count() < 1usize {
return Err("shorter than 1 characters".into());
}
static PATTERN: ::std::sync::LazyLock<::regress::Regex> =
::std::sync::LazyLock::new(|| ::regress::Regex::new("^[A-Za-z0-9.-]+$").unwrap());
if PATTERN.find(value).is_none() {
return Err("doesn't match pattern \"^[A-Za-z0-9.-]+$\"".into());
}
Ok(Self(value.to_string()))
}
}
impl ::std::convert::TryFrom<&str> for SiteTargetBundleId {
type Error = self::error::ConversionError;
fn try_from(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<&::std::string::String> for SiteTargetBundleId {
type Error = self::error::ConversionError;
fn try_from(
value: &::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<::std::string::String> for SiteTargetBundleId {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl<'de> ::serde::Deserialize<'de> for SiteTargetBundleId {
fn deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error>
where
D: ::serde::Deserializer<'de>,
{
::std::string::String::deserialize(deserializer)?
.parse()
.map_err(|e: self::error::ConversionError| {
<D::Error as ::serde::de::Error>::custom(e.to_string())
})
}
}
///DID identifying the relying party (e.g. did:web:rp.example). The vault maintainer is responsible for any DID resolution required to act on this entry.
///
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct SiteTargetDid(::std::string::String);
impl ::std::ops::Deref for SiteTargetDid {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<SiteTargetDid> for ::std::string::String {
fn from(value: SiteTargetDid) -> Self {
value.0
}
}
impl ::std::str::FromStr for SiteTargetDid {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
if value.chars().count() < 1usize {
return Err("shorter than 1 characters".into());
}
Ok(Self(value.to_string()))
}
}
impl ::std::convert::TryFrom<&str> for SiteTargetDid {
type Error = self::error::ConversionError;
fn try_from(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<&::std::string::String> for SiteTargetDid {
type Error = self::error::ConversionError;
fn try_from(
value: &::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<::std::string::String> for SiteTargetDid {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl<'de> ::serde::Deserialize<'de> for SiteTargetDid {
fn deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error>
where
D: ::serde::Deserializer<'de>,
{
::std::string::String::deserialize(deserializer)?
.parse()
.map_err(|e: self::error::ConversionError| {
<D::Error as ::serde::de::Error>::custom(e.to_string())
})
}
}
///Android package name in reverse-DNS form (e.g. "com.github.android").
///
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct SiteTargetPackageName(::std::string::String);
impl ::std::ops::Deref for SiteTargetPackageName {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<SiteTargetPackageName> for ::std::string::String {
fn from(value: SiteTargetPackageName) -> Self {
value.0
}
}
impl ::std::str::FromStr for SiteTargetPackageName {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
if value.chars().count() < 1usize {
return Err("shorter than 1 characters".into());
}
static PATTERN: ::std::sync::LazyLock<::regress::Regex> =
::std::sync::LazyLock::new(|| {
::regress::Regex::new("^[A-Za-z][A-Za-z0-9_]*(\\.[A-Za-z][A-Za-z0-9_]*)+$").unwrap()
});
if PATTERN.find(value).is_none() {
return Err(
"doesn't match pattern \"^[A-Za-z][A-Za-z0-9_]*(\\.[A-Za-z][A-Za-z0-9_]*)+$\""
.into(),
);
}
Ok(Self(value.to_string()))
}
}
impl ::std::convert::TryFrom<&str> for SiteTargetPackageName {
type Error = self::error::ConversionError;
fn try_from(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<&::std::string::String> for SiteTargetPackageName {
type Error = self::error::ConversionError;
fn try_from(
value: &::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<::std::string::String> for SiteTargetPackageName {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl<'de> ::serde::Deserialize<'de> for SiteTargetPackageName {
fn deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error>
where
D: ::serde::Deserializer<'de>,
{
::std::string::String::deserialize(deserializer)?
.parse()
.map_err(|e: self::error::ConversionError| {
<D::Error as ::serde::de::Error>::custom(e.to_string())
})
}
}
///`SiteTargetSha256CertFingerprintsItem`
///
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct SiteTargetSha256CertFingerprintsItem(::std::string::String);
impl ::std::ops::Deref for SiteTargetSha256CertFingerprintsItem {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<SiteTargetSha256CertFingerprintsItem> for ::std::string::String {
fn from(value: SiteTargetSha256CertFingerprintsItem) -> Self {
value.0
}
}
impl ::std::str::FromStr for SiteTargetSha256CertFingerprintsItem {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
static PATTERN: ::std::sync::LazyLock<::regress::Regex> =
::std::sync::LazyLock::new(|| {
::regress::Regex::new("^[0-9A-F]{2}(:[0-9A-F]{2}){31}$").unwrap()
});
if PATTERN.find(value).is_none() {
return Err("doesn't match pattern \"^[0-9A-F]{2}(:[0-9A-F]{2}){31}$\"".into());
}
Ok(Self(value.to_string()))
}
}
impl ::std::convert::TryFrom<&str> for SiteTargetSha256CertFingerprintsItem {
type Error = self::error::ConversionError;
fn try_from(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<&::std::string::String> for SiteTargetSha256CertFingerprintsItem {
type Error = self::error::ConversionError;
fn try_from(
value: &::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<::std::string::String> for SiteTargetSha256CertFingerprintsItem {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl<'de> ::serde::Deserialize<'de> for SiteTargetSha256CertFingerprintsItem {
fn deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error>
where
D: ::serde::Deserializer<'de>,
{
::std::string::String::deserialize(deserializer)?
.parse()
.map_err(|e: self::error::ConversionError| {
<D::Error as ::serde::de::Error>::custom(e.to_string())
})
}
}
///Optional Apple Developer Team identifier (10-character alphanumeric). When supplied, the maintainer SHOULD also verify the team id of the requesting app before matching — defense in depth against bundle-id squatting on jailbroken devices.
///
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct SiteTargetTeamId(::std::string::String);
impl ::std::ops::Deref for SiteTargetTeamId {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<SiteTargetTeamId> for ::std::string::String {
fn from(value: SiteTargetTeamId) -> Self {
value.0
}
}
impl ::std::str::FromStr for SiteTargetTeamId {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
if value.chars().count() < 1usize {
return Err("shorter than 1 characters".into());
}
static PATTERN: ::std::sync::LazyLock<::regress::Regex> =
::std::sync::LazyLock::new(|| ::regress::Regex::new("^[A-Z0-9]+$").unwrap());
if PATTERN.find(value).is_none() {
return Err("doesn't match pattern \"^[A-Z0-9]+$\"".into());
}
Ok(Self(value.to_string()))
}
}
impl ::std::convert::TryFrom<&str> for SiteTargetTeamId {
type Error = self::error::ConversionError;
fn try_from(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<&::std::string::String> for SiteTargetTeamId {
type Error = self::error::ConversionError;
fn try_from(
value: &::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<::std::string::String> for SiteTargetTeamId {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl<'de> ::serde::Deserialize<'de> for SiteTargetTeamId {
fn deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error>
where
D: ::serde::Deserializer<'de>,
{
::std::string::String::deserialize(deserializer)?
.parse()
.map_err(|e: self::error::ConversionError| {
<D::Error as ::serde::de::Error>::custom(e.to_string())
})
}
}
/// Types for composing complex structures.
pub mod builder {
#[derive(Clone, Debug)]
pub struct Payload {
candidate_module: ::std::result::Result<
::std::option::Option<::std::string::String>,
::std::string::String,
>,
candidate_priority: ::std::result::Result<i64, ::std::string::String>,
ext: ::std::result::Result<::std::option::Option<super::Ext>, ::std::string::String>,
include_trace: ::std::result::Result<bool, ::std::string::String>,
input: ::std::result::Result<super::PolicyInput, ::std::string::String>,
}
impl ::std::default::Default for Payload {
fn default() -> Self {
Self {
candidate_module: Ok(Default::default()),
candidate_priority: Ok(super::defaults::default_u64::<i64, 1000>()),
ext: Ok(Default::default()),
include_trace: Ok(Default::default()),
input: Err("no value supplied for input".to_string()),
}
}
}
impl Payload {
pub fn candidate_module<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<::std::string::String>>,
T::Error: ::std::fmt::Display,
{
self.candidate_module = value
.try_into()
.map_err(|e| format!("error converting supplied value for candidate_module: {e}"));
self
}
pub fn candidate_priority<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<i64>,
T::Error: ::std::fmt::Display,
{
self.candidate_priority = value.try_into().map_err(|e| {
format!("error converting supplied value for candidate_priority: {e}")
});
self
}
pub fn ext<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<super::Ext>>,
T::Error: ::std::fmt::Display,
{
self.ext = value
.try_into()
.map_err(|e| format!("error converting supplied value for ext: {e}"));
self
}
pub fn include_trace<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<bool>,
T::Error: ::std::fmt::Display,
{
self.include_trace = value
.try_into()
.map_err(|e| format!("error converting supplied value for include_trace: {e}"));
self
}
pub fn input<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::PolicyInput>,
T::Error: ::std::fmt::Display,
{
self.input = value
.try_into()
.map_err(|e| format!("error converting supplied value for input: {e}"));
self
}
}
impl ::std::convert::TryFrom<Payload> for super::Payload {
type Error = super::error::ConversionError;
fn try_from(value: Payload) -> ::std::result::Result<Self, super::error::ConversionError> {
Ok(Self {
candidate_module: value.candidate_module?,
candidate_priority: value.candidate_priority?,
ext: value.ext?,
include_trace: value.include_trace?,
input: value.input?,
})
}
}
impl ::std::convert::From<super::Payload> for Payload {
fn from(value: super::Payload) -> Self {
Self {
candidate_module: Ok(value.candidate_module),
candidate_priority: Ok(value.candidate_priority),
ext: Ok(value.ext),
include_trace: Ok(value.include_trace),
input: Ok(value.input),
}
}
}
#[derive(Clone, Debug)]
pub struct PolicyDecision {
decision: ::std::result::Result<super::PolicyDecisionDecision, ::std::string::String>,
explanation: ::std::result::Result<
::std::option::Option<super::PolicyDecisionExplanation>,
::std::string::String,
>,
mode: ::std::result::Result<
::std::option::Option<super::PolicyDecisionMode>,
::std::string::String,
>,
require_consent: ::std::result::Result<
::std::option::Option<super::PolicyDecisionRequireConsent>,
::std::string::String,
>,
step_up: ::std::result::Result<
::std::option::Option<super::PolicyDecisionStepUp>,
::std::string::String,
>,
ttl_seconds_cap: ::std::result::Result<
::std::option::Option<::std::num::NonZeroU64>,
::std::string::String,
>,
}
impl ::std::default::Default for PolicyDecision {
fn default() -> Self {
Self {
decision: Err("no value supplied for decision".to_string()),
explanation: Ok(Default::default()),
mode: Ok(Default::default()),
require_consent: Ok(Default::default()),
step_up: Ok(Default::default()),
ttl_seconds_cap: Ok(Default::default()),
}
}
}
impl PolicyDecision {
pub fn decision<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::PolicyDecisionDecision>,
T::Error: ::std::fmt::Display,
{
self.decision = value
.try_into()
.map_err(|e| format!("error converting supplied value for decision: {e}"));
self
}
pub fn explanation<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<super::PolicyDecisionExplanation>>,
T::Error: ::std::fmt::Display,
{
self.explanation = value
.try_into()
.map_err(|e| format!("error converting supplied value for explanation: {e}"));
self
}
pub fn mode<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<super::PolicyDecisionMode>>,
T::Error: ::std::fmt::Display,
{
self.mode = value
.try_into()
.map_err(|e| format!("error converting supplied value for mode: {e}"));
self
}
pub fn require_consent<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<super::PolicyDecisionRequireConsent>>,
T::Error: ::std::fmt::Display,
{
self.require_consent = value
.try_into()
.map_err(|e| format!("error converting supplied value for require_consent: {e}"));
self
}
pub fn step_up<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<super::PolicyDecisionStepUp>>,
T::Error: ::std::fmt::Display,
{
self.step_up = value
.try_into()
.map_err(|e| format!("error converting supplied value for step_up: {e}"));
self
}
pub fn ttl_seconds_cap<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<::std::num::NonZeroU64>>,
T::Error: ::std::fmt::Display,
{
self.ttl_seconds_cap = value
.try_into()
.map_err(|e| format!("error converting supplied value for ttl_seconds_cap: {e}"));
self
}
}
impl ::std::convert::TryFrom<PolicyDecision> for super::PolicyDecision {
type Error = super::error::ConversionError;
fn try_from(
value: PolicyDecision,
) -> ::std::result::Result<Self, super::error::ConversionError> {
Ok(Self {
decision: value.decision?,
explanation: value.explanation?,
mode: value.mode?,
require_consent: value.require_consent?,
step_up: value.step_up?,
ttl_seconds_cap: value.ttl_seconds_cap?,
})
}
}
impl ::std::convert::From<super::PolicyDecision> for PolicyDecision {
fn from(value: super::PolicyDecision) -> Self {
Self {
decision: Ok(value.decision),
explanation: Ok(value.explanation),
mode: Ok(value.mode),
require_consent: Ok(value.require_consent),
step_up: Ok(value.step_up),
ttl_seconds_cap: Ok(value.ttl_seconds_cap),
}
}
}
#[derive(Clone, Debug)]
pub struct PolicyDecisionRequireConsent {
approver_set: ::std::result::Result<::std::string::String, ::std::string::String>,
exclude_requester: ::std::result::Result<bool, ::std::string::String>,
min_approvals: ::std::result::Result<::std::num::NonZeroU64, ::std::string::String>,
}
impl ::std::default::Default for PolicyDecisionRequireConsent {
fn default() -> Self {
Self {
approver_set: Err("no value supplied for approver_set".to_string()),
exclude_requester: Err("no value supplied for exclude_requester".to_string()),
min_approvals: Err("no value supplied for min_approvals".to_string()),
}
}
}
impl PolicyDecisionRequireConsent {
pub fn approver_set<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::string::String>,
T::Error: ::std::fmt::Display,
{
self.approver_set = value
.try_into()
.map_err(|e| format!("error converting supplied value for approver_set: {e}"));
self
}
pub fn exclude_requester<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<bool>,
T::Error: ::std::fmt::Display,
{
self.exclude_requester = value
.try_into()
.map_err(|e| format!("error converting supplied value for exclude_requester: {e}"));
self
}
pub fn min_approvals<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::num::NonZeroU64>,
T::Error: ::std::fmt::Display,
{
self.min_approvals = value
.try_into()
.map_err(|e| format!("error converting supplied value for min_approvals: {e}"));
self
}
}
impl ::std::convert::TryFrom<PolicyDecisionRequireConsent> for super::PolicyDecisionRequireConsent {
type Error = super::error::ConversionError;
fn try_from(
value: PolicyDecisionRequireConsent,
) -> ::std::result::Result<Self, super::error::ConversionError> {
Ok(Self {
approver_set: value.approver_set?,
exclude_requester: value.exclude_requester?,
min_approvals: value.min_approvals?,
})
}
}
impl ::std::convert::From<super::PolicyDecisionRequireConsent> for PolicyDecisionRequireConsent {
fn from(value: super::PolicyDecisionRequireConsent) -> Self {
Self {
approver_set: Ok(value.approver_set),
exclude_requester: Ok(value.exclude_requester),
min_approvals: Ok(value.min_approvals),
}
}
}
#[derive(Clone, Debug)]
pub struct PolicyDecisionStepUp {
method: ::std::result::Result<super::PolicyDecisionStepUpMethod, ::std::string::String>,
ttl_seconds: ::std::result::Result<
::std::option::Option<::std::num::NonZeroU64>,
::std::string::String,
>,
}
impl ::std::default::Default for PolicyDecisionStepUp {
fn default() -> Self {
Self {
method: Err("no value supplied for method".to_string()),
ttl_seconds: Ok(Default::default()),
}
}
}
impl PolicyDecisionStepUp {
pub fn method<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::PolicyDecisionStepUpMethod>,
T::Error: ::std::fmt::Display,
{
self.method = value
.try_into()
.map_err(|e| format!("error converting supplied value for method: {e}"));
self
}
pub fn ttl_seconds<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<::std::num::NonZeroU64>>,
T::Error: ::std::fmt::Display,
{
self.ttl_seconds = value
.try_into()
.map_err(|e| format!("error converting supplied value for ttl_seconds: {e}"));
self
}
}
impl ::std::convert::TryFrom<PolicyDecisionStepUp> for super::PolicyDecisionStepUp {
type Error = super::error::ConversionError;
fn try_from(
value: PolicyDecisionStepUp,
) -> ::std::result::Result<Self, super::error::ConversionError> {
Ok(Self {
method: value.method?,
ttl_seconds: value.ttl_seconds?,
})
}
}
impl ::std::convert::From<super::PolicyDecisionStepUp> for PolicyDecisionStepUp {
fn from(value: super::PolicyDecisionStepUp) -> Self {
Self {
method: Ok(value.method),
ttl_seconds: Ok(value.ttl_seconds),
}
}
}
#[derive(Clone, Debug)]
pub struct PolicyInput {
consumer: ::std::result::Result<super::PolicyInputConsumer, ::std::string::String>,
context_id: ::std::result::Result<super::PolicyInputContextId, ::std::string::String>,
request: ::std::result::Result<super::PolicyInputRequest, ::std::string::String>,
site: ::std::result::Result<super::SiteTarget, ::std::string::String>,
}
impl ::std::default::Default for PolicyInput {
fn default() -> Self {
Self {
consumer: Err("no value supplied for consumer".to_string()),
context_id: Err("no value supplied for context_id".to_string()),
request: Err("no value supplied for request".to_string()),
site: Err("no value supplied for site".to_string()),
}
}
}
impl PolicyInput {
pub fn consumer<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::PolicyInputConsumer>,
T::Error: ::std::fmt::Display,
{
self.consumer = value
.try_into()
.map_err(|e| format!("error converting supplied value for consumer: {e}"));
self
}
pub fn context_id<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::PolicyInputContextId>,
T::Error: ::std::fmt::Display,
{
self.context_id = value
.try_into()
.map_err(|e| format!("error converting supplied value for context_id: {e}"));
self
}
pub fn request<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::PolicyInputRequest>,
T::Error: ::std::fmt::Display,
{
self.request = value
.try_into()
.map_err(|e| format!("error converting supplied value for request: {e}"));
self
}
pub fn site<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::SiteTarget>,
T::Error: ::std::fmt::Display,
{
self.site = value
.try_into()
.map_err(|e| format!("error converting supplied value for site: {e}"));
self
}
}
impl ::std::convert::TryFrom<PolicyInput> for super::PolicyInput {
type Error = super::error::ConversionError;
fn try_from(
value: PolicyInput,
) -> ::std::result::Result<Self, super::error::ConversionError> {
Ok(Self {
consumer: value.consumer?,
context_id: value.context_id?,
request: value.request?,
site: value.site?,
})
}
}
impl ::std::convert::From<super::PolicyInput> for PolicyInput {
fn from(value: super::PolicyInput) -> Self {
Self {
consumer: Ok(value.consumer),
context_id: Ok(value.context_id),
request: Ok(value.request),
site: Ok(value.site),
}
}
}
#[derive(Clone, Debug)]
pub struct PolicyInputConsumer {
device_id: ::std::result::Result<
::std::option::Option<::std::string::String>,
::std::string::String,
>,
did: ::std::result::Result<::std::string::String, ::std::string::String>,
kind: ::std::result::Result<
::std::option::Option<super::ConsumerKind>,
::std::string::String,
>,
last_user_verification_at: ::std::result::Result<
::std::option::Option<::chrono::DateTime<::chrono::offset::Utc>>,
::std::string::String,
>,
network_class: ::std::result::Result<
::std::option::Option<super::PolicyInputConsumerNetworkClass>,
::std::string::String,
>,
}
impl ::std::default::Default for PolicyInputConsumer {
fn default() -> Self {
Self {
device_id: Ok(Default::default()),
did: Err("no value supplied for did".to_string()),
kind: Ok(Default::default()),
last_user_verification_at: Ok(Default::default()),
network_class: Ok(Default::default()),
}
}
}
impl PolicyInputConsumer {
pub fn device_id<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<::std::string::String>>,
T::Error: ::std::fmt::Display,
{
self.device_id = value
.try_into()
.map_err(|e| format!("error converting supplied value for device_id: {e}"));
self
}
pub fn did<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::string::String>,
T::Error: ::std::fmt::Display,
{
self.did = value
.try_into()
.map_err(|e| format!("error converting supplied value for did: {e}"));
self
}
pub fn kind<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<super::ConsumerKind>>,
T::Error: ::std::fmt::Display,
{
self.kind = value
.try_into()
.map_err(|e| format!("error converting supplied value for kind: {e}"));
self
}
pub fn last_user_verification_at<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<
::std::option::Option<::chrono::DateTime<::chrono::offset::Utc>>,
>,
T::Error: ::std::fmt::Display,
{
self.last_user_verification_at = value.try_into().map_err(|e| {
format!("error converting supplied value for last_user_verification_at: {e}")
});
self
}
pub fn network_class<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<
::std::option::Option<super::PolicyInputConsumerNetworkClass>,
>,
T::Error: ::std::fmt::Display,
{
self.network_class = value
.try_into()
.map_err(|e| format!("error converting supplied value for network_class: {e}"));
self
}
}
impl ::std::convert::TryFrom<PolicyInputConsumer> for super::PolicyInputConsumer {
type Error = super::error::ConversionError;
fn try_from(
value: PolicyInputConsumer,
) -> ::std::result::Result<Self, super::error::ConversionError> {
Ok(Self {
device_id: value.device_id?,
did: value.did?,
kind: value.kind?,
last_user_verification_at: value.last_user_verification_at?,
network_class: value.network_class?,
})
}
}
impl ::std::convert::From<super::PolicyInputConsumer> for PolicyInputConsumer {
fn from(value: super::PolicyInputConsumer) -> Self {
Self {
device_id: Ok(value.device_id),
did: Ok(value.did),
kind: Ok(value.kind),
last_user_verification_at: Ok(value.last_user_verification_at),
network_class: Ok(value.network_class),
}
}
}
#[derive(Clone, Debug)]
pub struct PolicyInputRequest {
exposure: ::std::result::Result<super::PolicyInputRequestExposure, ::std::string::String>,
kind: ::std::result::Result<
::std::option::Option<::std::string::String>,
::std::string::String,
>,
payload_digest: ::std::result::Result<
::std::option::Option<super::DigestMultibase>,
::std::string::String,
>,
side_effects:
::std::result::Result<super::PolicyInputRequestSideEffects, ::std::string::String>,
subject: ::std::result::Result<
::std::option::Option<::std::string::String>,
::std::string::String,
>,
type_uri: ::std::result::Result<::std::string::String, ::std::string::String>,
}
impl ::std::default::Default for PolicyInputRequest {
fn default() -> Self {
Self {
exposure: Err("no value supplied for exposure".to_string()),
kind: Ok(Default::default()),
payload_digest: Ok(Default::default()),
side_effects: Err("no value supplied for side_effects".to_string()),
subject: Ok(Default::default()),
type_uri: Err("no value supplied for type_uri".to_string()),
}
}
}
impl PolicyInputRequest {
pub fn exposure<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::PolicyInputRequestExposure>,
T::Error: ::std::fmt::Display,
{
self.exposure = value
.try_into()
.map_err(|e| format!("error converting supplied value for exposure: {e}"));
self
}
pub fn kind<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<::std::string::String>>,
T::Error: ::std::fmt::Display,
{
self.kind = value
.try_into()
.map_err(|e| format!("error converting supplied value for kind: {e}"));
self
}
pub fn payload_digest<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<super::DigestMultibase>>,
T::Error: ::std::fmt::Display,
{
self.payload_digest = value
.try_into()
.map_err(|e| format!("error converting supplied value for payload_digest: {e}"));
self
}
pub fn side_effects<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::PolicyInputRequestSideEffects>,
T::Error: ::std::fmt::Display,
{
self.side_effects = value
.try_into()
.map_err(|e| format!("error converting supplied value for side_effects: {e}"));
self
}
pub fn subject<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<::std::string::String>>,
T::Error: ::std::fmt::Display,
{
self.subject = value
.try_into()
.map_err(|e| format!("error converting supplied value for subject: {e}"));
self
}
pub fn type_uri<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::string::String>,
T::Error: ::std::fmt::Display,
{
self.type_uri = value
.try_into()
.map_err(|e| format!("error converting supplied value for type_uri: {e}"));
self
}
}
impl ::std::convert::TryFrom<PolicyInputRequest> for super::PolicyInputRequest {
type Error = super::error::ConversionError;
fn try_from(
value: PolicyInputRequest,
) -> ::std::result::Result<Self, super::error::ConversionError> {
Ok(Self {
exposure: value.exposure?,
kind: value.kind?,
payload_digest: value.payload_digest?,
side_effects: value.side_effects?,
subject: value.subject?,
type_uri: value.type_uri?,
})
}
}
impl ::std::convert::From<super::PolicyInputRequest> for PolicyInputRequest {
fn from(value: super::PolicyInputRequest) -> Self {
Self {
exposure: Ok(value.exposure),
kind: Ok(value.kind),
payload_digest: Ok(value.payload_digest),
side_effects: Ok(value.side_effects),
subject: Ok(value.subject),
type_uri: Ok(value.type_uri),
}
}
}
#[derive(Clone, Debug)]
pub struct PolicyInputRequestExposure {
acts_as_subject: ::std::result::Result<bool, ::std::string::String>,
discloses: ::std::result::Result<
super::PolicyInputRequestExposureDiscloses,
::std::string::String,
>,
}
impl ::std::default::Default for PolicyInputRequestExposure {
fn default() -> Self {
Self {
acts_as_subject: Err("no value supplied for acts_as_subject".to_string()),
discloses: Err("no value supplied for discloses".to_string()),
}
}
}
impl PolicyInputRequestExposure {
pub fn acts_as_subject<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<bool>,
T::Error: ::std::fmt::Display,
{
self.acts_as_subject = value
.try_into()
.map_err(|e| format!("error converting supplied value for acts_as_subject: {e}"));
self
}
pub fn discloses<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::PolicyInputRequestExposureDiscloses>,
T::Error: ::std::fmt::Display,
{
self.discloses = value
.try_into()
.map_err(|e| format!("error converting supplied value for discloses: {e}"));
self
}
}
impl ::std::convert::TryFrom<PolicyInputRequestExposure> for super::PolicyInputRequestExposure {
type Error = super::error::ConversionError;
fn try_from(
value: PolicyInputRequestExposure,
) -> ::std::result::Result<Self, super::error::ConversionError> {
Ok(Self {
acts_as_subject: value.acts_as_subject?,
discloses: value.discloses?,
})
}
}
impl ::std::convert::From<super::PolicyInputRequestExposure> for PolicyInputRequestExposure {
fn from(value: super::PolicyInputRequestExposure) -> Self {
Self {
acts_as_subject: Ok(value.acts_as_subject),
discloses: Ok(value.discloses),
}
}
}
#[derive(Clone, Debug)]
pub struct Response {
decision: ::std::result::Result<super::PolicyDecision, ::std::string::String>,
ext: ::std::result::Result<::std::option::Option<super::Ext>, ::std::string::String>,
matched_policies:
::std::result::Result<::std::vec::Vec<::std::string::String>, ::std::string::String>,
trace:
::std::result::Result<::std::vec::Vec<super::ResponseTraceItem>, ::std::string::String>,
}
impl ::std::default::Default for Response {
fn default() -> Self {
Self {
decision: Err("no value supplied for decision".to_string()),
ext: Ok(Default::default()),
matched_policies: Ok(Default::default()),
trace: Ok(Default::default()),
}
}
}
impl Response {
pub fn decision<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::PolicyDecision>,
T::Error: ::std::fmt::Display,
{
self.decision = value
.try_into()
.map_err(|e| format!("error converting supplied value for decision: {e}"));
self
}
pub fn ext<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<super::Ext>>,
T::Error: ::std::fmt::Display,
{
self.ext = value
.try_into()
.map_err(|e| format!("error converting supplied value for ext: {e}"));
self
}
pub fn matched_policies<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::vec::Vec<::std::string::String>>,
T::Error: ::std::fmt::Display,
{
self.matched_policies = value
.try_into()
.map_err(|e| format!("error converting supplied value for matched_policies: {e}"));
self
}
pub fn trace<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::vec::Vec<super::ResponseTraceItem>>,
T::Error: ::std::fmt::Display,
{
self.trace = value
.try_into()
.map_err(|e| format!("error converting supplied value for trace: {e}"));
self
}
}
impl ::std::convert::TryFrom<Response> for super::Response {
type Error = super::error::ConversionError;
fn try_from(value: Response) -> ::std::result::Result<Self, super::error::ConversionError> {
Ok(Self {
decision: value.decision?,
ext: value.ext?,
matched_policies: value.matched_policies?,
trace: value.trace?,
})
}
}
impl ::std::convert::From<super::Response> for Response {
fn from(value: super::Response) -> Self {
Self {
decision: Ok(value.decision),
ext: Ok(value.ext),
matched_policies: Ok(value.matched_policies),
trace: Ok(value.trace),
}
}
}
}
/// Generation of default values for serde.
pub mod defaults {
pub(super) fn default_u64<T, const V: u64>() -> T
where
T: ::std::convert::TryFrom<u64>,
<T as ::std::convert::TryFrom<u64>>::Error: ::std::fmt::Debug,
{
T::try_from(V).unwrap()
}
}
impl crate::Payload for Payload {
const TYPE_URI: &'static str = "https://trusttasks.org/spec/policy/evaluate/0.4";
const IS_RECIPIENT_REQUIRED: bool = true;
const PAYLOAD_SCHEMA: Option<&'static str> = Some(
"{\"$defs\":{\"ConsumerKind\":{\"description\":\"Discriminator: is this consumer a user-driven Companion or a headless Service?\",\"oneOf\":[{\"additionalProperties\":false,\"properties\":{\"formFactor\":{\"enum\":[\"browser\",\"mobile\",\"desktop\"],\"type\":\"string\"},\"kind\":{\"const\":\"companion\"}},\"required\":[\"kind\",\"formFactor\"],\"title\":\"Companion\",\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"kind\":{\"const\":\"service\"},\"serviceKind\":{\"enum\":[\"mediator\",\"aiAgent\",\"daemon\"],\"type\":\"string\"}},\"required\":[\"kind\",\"serviceKind\"],\"title\":\"Service\",\"type\":\"object\"}],\"title\":\"ConsumerKind\"},\"DigestMultibase\":{\"description\":\"A cryptographic digest as a multibase-encoded multihash — the encoding the W3C Verifiable Credentials Data Model 2.0 defines for `digestMultibase`, and the one `did:webvh` uses for its SCID and entry hashes.\\n\\nMultihash carries the hash algorithm in-band, so the value is self-describing and the wire format survives an algorithm change without a schema revision; multibase does the same for the base encoding, so a verifier never infers base58 from base64url by context. A bare hex string or a `sha-256:`-style prefix hard-codes one algorithm into the wire contract and is non-conforming here.\\n\\nThis definition constrains the *encoding only*. What the digest is computed over is stated by each referencing field, because it differs legitimately: a digest over a JSON document is taken over its RFC 8785 (JCS) canonicalization, while a digest over an opaque artifact is taken over its bytes. A field whose input is a JSON document and which does not name a canonicalization is not reproducible.\\n\\nRestricted to the two multibase headers W3C Controlled Identifiers 1.0 §2.4 normatively requires — `z` (base58btc) and `u` (base64url-no-pad). CID permits others but states that \\\"interoperability is not guaranteed between implementations using such values\\\", and a registry whose purpose is interoperability should not mint digests a conforming verifier may be unable to read. The alphabets are enforced rather than assumed: base58btc excludes 0, O, I and l, and an earlier permissive pattern let three published examples carry digests that were not valid base58 at all. base58btc is RECOMMENDED, for consistency with `did:key` and `did:webvh`.\",\"examples\":[\"zQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR\"],\"minLength\":16,\"pattern\":\"^(z[1-9A-HJ-NP-Za-km-z]+|u[A-Za-z0-9_-]+)$\",\"title\":\"DigestMultibase\",\"type\":\"string\"},\"Ext\":{\"additionalProperties\":true,\"description\":\"Vendor-namespaced extension object per SPEC.md §4.5.1. Each immediate key MUST be a reverse-DNS namespace; structure under each namespace is opaque to the framework.\",\"minProperties\":1,\"propertyNames\":{\"pattern\":\"^[a-z][a-z0-9-]*(\\\\.[a-z0-9-]+)+$\"},\"title\":\"Ext\",\"type\":\"object\"},\"PolicyDecision\":{\"additionalProperties\":false,\"properties\":{\"decision\":{\"enum\":[\"allow\",\"deny\",\"requireStepUp\",\"requireConsent\"],\"type\":\"string\"},\"explanation\":{\"description\":\"Human-readable explanation for diagnostic display.\",\"maxLength\":1024,\"type\":\"string\"},\"mode\":{\"description\":\"Vault-flow-specific. When decision == \\\"allow\\\" for a proxy-login/release request, whether the maintainer should proxy-login or release-for-fill. Default: proxy. Ignored for other task kinds.\",\"enum\":[\"proxy\",\"fill\"],\"type\":\"string\"},\"requireConsent\":{\"additionalProperties\":false,\"description\":\"When decision == \\\"requireConsent\\\", the approver constraint the enforcement point MUST satisfy — a signed consent decision from the named set, bound to the request's payloadDigest — before executing.\",\"properties\":{\"approverSet\":{\"description\":\"Named set of enrolled approver devices permitted to approve this task (resolved by the enforcement point against its device registry).\",\"type\":\"string\"},\"excludeRequester\":{\"description\":\"REQUIRED, with no default: whether the requester may approve its own request is the community's choice, not this schema's (SPEC §6.6 rule 5). When true, the device that issued the request MUST NOT be accepted as the approver — forcing cross-device approval so a compromised requesting device cannot self-approve.\",\"type\":\"boolean\"},\"minApprovals\":{\"description\":\"REQUIRED, with no default: the quorum is the community's choice, not this schema's (SPEC §6.6 rule 5), and an omitted quorum is malformedRequest rather than one. Number of distinct approvers from the set required before the task may execute.\",\"minimum\":1,\"type\":\"integer\"}},\"required\":[\"approverSet\",\"excludeRequester\",\"minApprovals\"],\"type\":\"object\"},\"stepUp\":{\"additionalProperties\":false,\"description\":\"When decision == \\\"requireStepUp\\\", which method to demand.\",\"properties\":{\"method\":{\"enum\":[\"webauthnUv\",\"pushApproval\",\"totp\"],\"type\":\"string\"},\"ttlSeconds\":{\"minimum\":1,\"type\":\"integer\"}},\"required\":[\"method\"],\"type\":\"object\"},\"ttlSecondsCap\":{\"description\":\"When decision == \\\"allow\\\", maximum lifetime of any issued session blob / released secret.\",\"maximum\":86400,\"minimum\":1,\"type\":\"integer\"}},\"required\":[\"decision\"],\"title\":\"PolicyDecision\",\"type\":\"object\"},\"PolicyInput\":{\"additionalProperties\":false,\"description\":\"The structured input fed to a policy evaluator before dispatching a task. Generalised in 0.3 from the vault-flow triad to any Trust Task: `request.typeUri` identifies the task and `request.sideEffects` / `request.exposure` carry the authoritative SPEC §7.3 classifications the evaluator derives from the compiled handler.\",\"properties\":{\"consumer\":{\"additionalProperties\":false,\"properties\":{\"deviceId\":{\"type\":\"string\"},\"did\":{\"type\":\"string\"},\"kind\":{\"$ref\":\"#/$defs/ConsumerKind\"},\"lastUserVerificationAt\":{\"format\":\"date-time\",\"type\":\"string\"},\"networkClass\":{\"enum\":[\"unknown\",\"home\",\"corp\",\"public\",\"vpn\"],\"type\":\"string\"}},\"required\":[\"did\"],\"type\":\"object\"},\"contextId\":{\"minLength\":1,\"type\":\"string\"},\"request\":{\"additionalProperties\":false,\"properties\":{\"exposure\":{\"additionalProperties\":false,\"description\":\"Authoritative exposure class (SPEC §7.3 item 14), likewise derived from the compiled handler. `discloses` is the sensitivity of returned data; `actsAsSubject` is whether the subject's authority is exercised.\",\"properties\":{\"actsAsSubject\":{\"type\":\"boolean\"},\"discloses\":{\"enum\":[\"none\",\"metadata\",\"secret\"],\"type\":\"string\"}},\"required\":[\"discloses\",\"actsAsSubject\"],\"type\":\"object\"},\"kind\":{\"description\":\"Optional coarse category retained from 0.2 (`proxyLogin` | `release` | `stepUpResponse` | …) for policies that switch on it. `typeUri` is authoritative in 0.3.\",\"type\":\"string\"},\"payloadDigest\":{\"$ref\":\"#/$defs/DigestMultibase\",\"description\":\"Multibase-encoded multihash over the RFC 8785 (JCS) canonicalization of the payload, salted with the request challenge, present when a delegated-execution consent flow must bind approval to this exact payload. Absent when no consent binding is in play.\"},\"sideEffects\":{\"description\":\"Authoritative integrity class (SPEC §7.3 item 13). The evaluator MUST derive this from the compiled handler it is about to invoke, not from the wire — the registry's declared value is advisory only.\",\"enum\":[\"none\",\"mutating\",\"destructive\"],\"type\":\"string\"},\"subject\":{\"description\":\"The identifier the task acts on — the value at the spec's `subjectPath` (usually a DID). The evaluator checks the consumer's authority to act on this subject. Absent for subjectless tasks (discovery, list).\",\"type\":\"string\"},\"typeUri\":{\"description\":\"Type URI of the task being authorized — the evaluator's primary discriminator (e.g. https://trusttasks.org/spec/did-management/did/delete/0.1).\",\"type\":\"string\"}},\"required\":[\"typeUri\",\"sideEffects\",\"exposure\"],\"type\":\"object\"},\"site\":{\"$ref\":\"#/$defs/SiteTarget\"}},\"required\":[\"request\",\"site\",\"contextId\",\"consumer\"],\"title\":\"PolicyInput\",\"type\":\"object\"},\"Response\":{\"$anchor\":\"response\",\"additionalProperties\":false,\"properties\":{\"decision\":{\"$ref\":\"#/$defs/PolicyDecision\"},\"ext\":{\"$ref\":\"#/$defs/Ext\"},\"matchedPolicies\":{\"description\":\"Ids (or `candidate` for the dry-run module) of the policies that returned a non-null decision, in evaluation order. The first is the winning policy.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"trace\":{\"description\":\"Rego evaluator trace lines when `includeTrace: true`. Maintainer-defined format; primarily for human debugging.\",\"items\":{\"maxLength\":1024,\"type\":\"string\"},\"type\":\"array\"}},\"required\":[\"decision\"],\"title\":\"Policy Evaluate — response payload\",\"type\":\"object\"},\"SiteTarget\":{\"description\":\"A single binding target for a vault entry. Tagged union over the discriminator `kind`. A VaultEntry's `targets` array MAY mix any number of these.\",\"oneOf\":[{\"additionalProperties\":false,\"properties\":{\"kind\":{\"const\":\"webOrigin\"},\"origin\":{\"description\":\"Web origin per RFC 6454 (scheme + host + optional port), e.g. \\\"https://github.com\\\". Compared by exact string equality after canonicalisation (lowercase host, default port elided). Consumers wanting subdomain coverage SHOULD add multiple targets, not encode a wildcard.\",\"format\":\"uri\",\"type\":\"string\"}},\"required\":[\"kind\",\"origin\"],\"title\":\"WebOrigin\",\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"did\":{\"description\":\"DID identifying the relying party (e.g. did:web:rp.example). The vault maintainer is responsible for any DID resolution required to act on this entry.\",\"minLength\":1,\"type\":\"string\"},\"kind\":{\"const\":\"did\"}},\"required\":[\"kind\",\"did\"],\"title\":\"Did\",\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"bundleId\":{\"description\":\"iOS bundle identifier in reverse-DNS form (e.g. \\\"com.github.stwalkerster.codehub\\\"). Compared by exact string equality. Matches when an iOS Companion identifies the requesting app via its bundle id (typically via the OS Credential Manager integration).\",\"minLength\":1,\"pattern\":\"^[A-Za-z0-9.-]+$\",\"type\":\"string\"},\"kind\":{\"const\":\"iosApp\"},\"teamId\":{\"description\":\"Optional Apple Developer Team identifier (10-character alphanumeric). When supplied, the maintainer SHOULD also verify the team id of the requesting app before matching — defense in depth against bundle-id squatting on jailbroken devices.\",\"minLength\":1,\"pattern\":\"^[A-Z0-9]+$\",\"type\":\"string\"}},\"required\":[\"kind\",\"bundleId\"],\"title\":\"IosApp\",\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"kind\":{\"const\":\"androidApp\"},\"packageName\":{\"description\":\"Android package name in reverse-DNS form (e.g. \\\"com.github.android\\\").\",\"minLength\":1,\"pattern\":\"^[A-Za-z][A-Za-z0-9_]*(\\\\.[A-Za-z][A-Za-z0-9_]*)+$\",\"type\":\"string\"},\"sha256CertFingerprints\":{\"description\":\"SHA-256 fingerprints of the app's signing certificates, in colon-separated hex (the format `apksigner` and the Play Console emit). At least one fingerprint MUST be present. The maintainer matches when ANY of the provided fingerprints matches the requesting app's signature — this supports apps signed by multiple keys (e.g. during certificate rotation via Play App Signing).\",\"items\":{\"pattern\":\"^[0-9A-F]{2}(:[0-9A-F]{2}){31}$\",\"type\":\"string\"},\"minItems\":1,\"type\":\"array\",\"uniqueItems\":true}},\"required\":[\"kind\",\"packageName\",\"sha256CertFingerprints\"],\"title\":\"AndroidApp\",\"type\":\"object\"}],\"title\":\"SiteTarget\"}},\"$id\":\"https://trusttasks.org/spec/policy/evaluate/0.4\",\"$schema\":\"https://json-schema.org/draft/2020-12/schema\",\"additionalProperties\":false,\"description\":\"Dry-run a policy decision against a synthetic PolicyInput. Returns the policy decision plus a trace of which policy modules matched and which rules fired. Used by the policy-editor UI to verify changes before save and by admins to diagnose unexpected outcomes. 0.3 evaluates against the generalised PolicyInput (any Trust Task, carrying typeUri + side-effect/exposure classes) and can return the `requireConsent` decision.\",\"properties\":{\"candidateModule\":{\"description\":\"Optional — when supplied, evaluate as if this Rego source were active (e.g. preview a pending upsert). The candidate is layered into the evaluator at the priority specified by `candidatePriority` (default 1000) for this call only.\",\"type\":\"string\"},\"candidatePriority\":{\"default\":1000,\"maximum\":1000,\"minimum\":0,\"type\":\"integer\"},\"ext\":{\"$ref\":\"#/$defs/Ext\"},\"includeTrace\":{\"default\":false,\"type\":\"boolean\"},\"input\":{\"$ref\":\"#/$defs/PolicyInput\"}},\"required\":[\"input\"],\"title\":\"Policy Evaluate — payload\",\"type\":\"object\"}\n",
);
}
impl crate::Payload for Response {
const TYPE_URI: &'static str = "https://trusttasks.org/spec/policy/evaluate/0.4#response";
const IS_RECIPIENT_REQUIRED: bool = true;
const PAYLOAD_SCHEMA: Option<&'static str> = Some(
"{\"$defs\":{\"ConsumerKind\":{\"description\":\"Discriminator: is this consumer a user-driven Companion or a headless Service?\",\"oneOf\":[{\"additionalProperties\":false,\"properties\":{\"formFactor\":{\"enum\":[\"browser\",\"mobile\",\"desktop\"],\"type\":\"string\"},\"kind\":{\"const\":\"companion\"}},\"required\":[\"kind\",\"formFactor\"],\"title\":\"Companion\",\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"kind\":{\"const\":\"service\"},\"serviceKind\":{\"enum\":[\"mediator\",\"aiAgent\",\"daemon\"],\"type\":\"string\"}},\"required\":[\"kind\",\"serviceKind\"],\"title\":\"Service\",\"type\":\"object\"}],\"title\":\"ConsumerKind\"},\"DigestMultibase\":{\"description\":\"A cryptographic digest as a multibase-encoded multihash — the encoding the W3C Verifiable Credentials Data Model 2.0 defines for `digestMultibase`, and the one `did:webvh` uses for its SCID and entry hashes.\\n\\nMultihash carries the hash algorithm in-band, so the value is self-describing and the wire format survives an algorithm change without a schema revision; multibase does the same for the base encoding, so a verifier never infers base58 from base64url by context. A bare hex string or a `sha-256:`-style prefix hard-codes one algorithm into the wire contract and is non-conforming here.\\n\\nThis definition constrains the *encoding only*. What the digest is computed over is stated by each referencing field, because it differs legitimately: a digest over a JSON document is taken over its RFC 8785 (JCS) canonicalization, while a digest over an opaque artifact is taken over its bytes. A field whose input is a JSON document and which does not name a canonicalization is not reproducible.\\n\\nRestricted to the two multibase headers W3C Controlled Identifiers 1.0 §2.4 normatively requires — `z` (base58btc) and `u` (base64url-no-pad). CID permits others but states that \\\"interoperability is not guaranteed between implementations using such values\\\", and a registry whose purpose is interoperability should not mint digests a conforming verifier may be unable to read. The alphabets are enforced rather than assumed: base58btc excludes 0, O, I and l, and an earlier permissive pattern let three published examples carry digests that were not valid base58 at all. base58btc is RECOMMENDED, for consistency with `did:key` and `did:webvh`.\",\"examples\":[\"zQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR\"],\"minLength\":16,\"pattern\":\"^(z[1-9A-HJ-NP-Za-km-z]+|u[A-Za-z0-9_-]+)$\",\"title\":\"DigestMultibase\",\"type\":\"string\"},\"Ext\":{\"additionalProperties\":true,\"description\":\"Vendor-namespaced extension object per SPEC.md §4.5.1. Each immediate key MUST be a reverse-DNS namespace; structure under each namespace is opaque to the framework.\",\"minProperties\":1,\"propertyNames\":{\"pattern\":\"^[a-z][a-z0-9-]*(\\\\.[a-z0-9-]+)+$\"},\"title\":\"Ext\",\"type\":\"object\"},\"PolicyDecision\":{\"additionalProperties\":false,\"properties\":{\"decision\":{\"enum\":[\"allow\",\"deny\",\"requireStepUp\",\"requireConsent\"],\"type\":\"string\"},\"explanation\":{\"description\":\"Human-readable explanation for diagnostic display.\",\"maxLength\":1024,\"type\":\"string\"},\"mode\":{\"description\":\"Vault-flow-specific. When decision == \\\"allow\\\" for a proxy-login/release request, whether the maintainer should proxy-login or release-for-fill. Default: proxy. Ignored for other task kinds.\",\"enum\":[\"proxy\",\"fill\"],\"type\":\"string\"},\"requireConsent\":{\"additionalProperties\":false,\"description\":\"When decision == \\\"requireConsent\\\", the approver constraint the enforcement point MUST satisfy — a signed consent decision from the named set, bound to the request's payloadDigest — before executing.\",\"properties\":{\"approverSet\":{\"description\":\"Named set of enrolled approver devices permitted to approve this task (resolved by the enforcement point against its device registry).\",\"type\":\"string\"},\"excludeRequester\":{\"description\":\"REQUIRED, with no default: whether the requester may approve its own request is the community's choice, not this schema's (SPEC §6.6 rule 5). When true, the device that issued the request MUST NOT be accepted as the approver — forcing cross-device approval so a compromised requesting device cannot self-approve.\",\"type\":\"boolean\"},\"minApprovals\":{\"description\":\"REQUIRED, with no default: the quorum is the community's choice, not this schema's (SPEC §6.6 rule 5), and an omitted quorum is malformedRequest rather than one. Number of distinct approvers from the set required before the task may execute.\",\"minimum\":1,\"type\":\"integer\"}},\"required\":[\"approverSet\",\"excludeRequester\",\"minApprovals\"],\"type\":\"object\"},\"stepUp\":{\"additionalProperties\":false,\"description\":\"When decision == \\\"requireStepUp\\\", which method to demand.\",\"properties\":{\"method\":{\"enum\":[\"webauthnUv\",\"pushApproval\",\"totp\"],\"type\":\"string\"},\"ttlSeconds\":{\"minimum\":1,\"type\":\"integer\"}},\"required\":[\"method\"],\"type\":\"object\"},\"ttlSecondsCap\":{\"description\":\"When decision == \\\"allow\\\", maximum lifetime of any issued session blob / released secret.\",\"maximum\":86400,\"minimum\":1,\"type\":\"integer\"}},\"required\":[\"decision\"],\"title\":\"PolicyDecision\",\"type\":\"object\"},\"PolicyInput\":{\"additionalProperties\":false,\"description\":\"The structured input fed to a policy evaluator before dispatching a task. Generalised in 0.3 from the vault-flow triad to any Trust Task: `request.typeUri` identifies the task and `request.sideEffects` / `request.exposure` carry the authoritative SPEC §7.3 classifications the evaluator derives from the compiled handler.\",\"properties\":{\"consumer\":{\"additionalProperties\":false,\"properties\":{\"deviceId\":{\"type\":\"string\"},\"did\":{\"type\":\"string\"},\"kind\":{\"$ref\":\"#/$defs/ConsumerKind\"},\"lastUserVerificationAt\":{\"format\":\"date-time\",\"type\":\"string\"},\"networkClass\":{\"enum\":[\"unknown\",\"home\",\"corp\",\"public\",\"vpn\"],\"type\":\"string\"}},\"required\":[\"did\"],\"type\":\"object\"},\"contextId\":{\"minLength\":1,\"type\":\"string\"},\"request\":{\"additionalProperties\":false,\"properties\":{\"exposure\":{\"additionalProperties\":false,\"description\":\"Authoritative exposure class (SPEC §7.3 item 14), likewise derived from the compiled handler. `discloses` is the sensitivity of returned data; `actsAsSubject` is whether the subject's authority is exercised.\",\"properties\":{\"actsAsSubject\":{\"type\":\"boolean\"},\"discloses\":{\"enum\":[\"none\",\"metadata\",\"secret\"],\"type\":\"string\"}},\"required\":[\"discloses\",\"actsAsSubject\"],\"type\":\"object\"},\"kind\":{\"description\":\"Optional coarse category retained from 0.2 (`proxyLogin` | `release` | `stepUpResponse` | …) for policies that switch on it. `typeUri` is authoritative in 0.3.\",\"type\":\"string\"},\"payloadDigest\":{\"$ref\":\"#/$defs/DigestMultibase\",\"description\":\"Multibase-encoded multihash over the RFC 8785 (JCS) canonicalization of the payload, salted with the request challenge, present when a delegated-execution consent flow must bind approval to this exact payload. Absent when no consent binding is in play.\"},\"sideEffects\":{\"description\":\"Authoritative integrity class (SPEC §7.3 item 13). The evaluator MUST derive this from the compiled handler it is about to invoke, not from the wire — the registry's declared value is advisory only.\",\"enum\":[\"none\",\"mutating\",\"destructive\"],\"type\":\"string\"},\"subject\":{\"description\":\"The identifier the task acts on — the value at the spec's `subjectPath` (usually a DID). The evaluator checks the consumer's authority to act on this subject. Absent for subjectless tasks (discovery, list).\",\"type\":\"string\"},\"typeUri\":{\"description\":\"Type URI of the task being authorized — the evaluator's primary discriminator (e.g. https://trusttasks.org/spec/did-management/did/delete/0.1).\",\"type\":\"string\"}},\"required\":[\"typeUri\",\"sideEffects\",\"exposure\"],\"type\":\"object\"},\"site\":{\"$ref\":\"#/$defs/SiteTarget\"}},\"required\":[\"request\",\"site\",\"contextId\",\"consumer\"],\"title\":\"PolicyInput\",\"type\":\"object\"},\"Response\":{\"$anchor\":\"response\",\"additionalProperties\":false,\"properties\":{\"decision\":{\"$ref\":\"#/$defs/PolicyDecision\"},\"ext\":{\"$ref\":\"#/$defs/Ext\"},\"matchedPolicies\":{\"description\":\"Ids (or `candidate` for the dry-run module) of the policies that returned a non-null decision, in evaluation order. The first is the winning policy.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"trace\":{\"description\":\"Rego evaluator trace lines when `includeTrace: true`. Maintainer-defined format; primarily for human debugging.\",\"items\":{\"maxLength\":1024,\"type\":\"string\"},\"type\":\"array\"}},\"required\":[\"decision\"],\"title\":\"Policy Evaluate — response payload\",\"type\":\"object\"},\"SiteTarget\":{\"description\":\"A single binding target for a vault entry. Tagged union over the discriminator `kind`. A VaultEntry's `targets` array MAY mix any number of these.\",\"oneOf\":[{\"additionalProperties\":false,\"properties\":{\"kind\":{\"const\":\"webOrigin\"},\"origin\":{\"description\":\"Web origin per RFC 6454 (scheme + host + optional port), e.g. \\\"https://github.com\\\". Compared by exact string equality after canonicalisation (lowercase host, default port elided). Consumers wanting subdomain coverage SHOULD add multiple targets, not encode a wildcard.\",\"format\":\"uri\",\"type\":\"string\"}},\"required\":[\"kind\",\"origin\"],\"title\":\"WebOrigin\",\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"did\":{\"description\":\"DID identifying the relying party (e.g. did:web:rp.example). The vault maintainer is responsible for any DID resolution required to act on this entry.\",\"minLength\":1,\"type\":\"string\"},\"kind\":{\"const\":\"did\"}},\"required\":[\"kind\",\"did\"],\"title\":\"Did\",\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"bundleId\":{\"description\":\"iOS bundle identifier in reverse-DNS form (e.g. \\\"com.github.stwalkerster.codehub\\\"). Compared by exact string equality. Matches when an iOS Companion identifies the requesting app via its bundle id (typically via the OS Credential Manager integration).\",\"minLength\":1,\"pattern\":\"^[A-Za-z0-9.-]+$\",\"type\":\"string\"},\"kind\":{\"const\":\"iosApp\"},\"teamId\":{\"description\":\"Optional Apple Developer Team identifier (10-character alphanumeric). When supplied, the maintainer SHOULD also verify the team id of the requesting app before matching — defense in depth against bundle-id squatting on jailbroken devices.\",\"minLength\":1,\"pattern\":\"^[A-Z0-9]+$\",\"type\":\"string\"}},\"required\":[\"kind\",\"bundleId\"],\"title\":\"IosApp\",\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"kind\":{\"const\":\"androidApp\"},\"packageName\":{\"description\":\"Android package name in reverse-DNS form (e.g. \\\"com.github.android\\\").\",\"minLength\":1,\"pattern\":\"^[A-Za-z][A-Za-z0-9_]*(\\\\.[A-Za-z][A-Za-z0-9_]*)+$\",\"type\":\"string\"},\"sha256CertFingerprints\":{\"description\":\"SHA-256 fingerprints of the app's signing certificates, in colon-separated hex (the format `apksigner` and the Play Console emit). At least one fingerprint MUST be present. The maintainer matches when ANY of the provided fingerprints matches the requesting app's signature — this supports apps signed by multiple keys (e.g. during certificate rotation via Play App Signing).\",\"items\":{\"pattern\":\"^[0-9A-F]{2}(:[0-9A-F]{2}){31}$\",\"type\":\"string\"},\"minItems\":1,\"type\":\"array\",\"uniqueItems\":true}},\"required\":[\"kind\",\"packageName\",\"sha256CertFingerprints\"],\"title\":\"AndroidApp\",\"type\":\"object\"}],\"title\":\"SiteTarget\"}},\"$ref\":\"#/$defs/Response\",\"$schema\":\"https://json-schema.org/draft/2020-12/schema\"}\n",
);
}
impl crate::RequestPayload for Payload {
type Response = Response;
}
/// The earlier `MAJOR.MINOR` of this slug that this version declares it
/// extends (front matter `extends`, SPEC §5.2 "Declared extension"), or
/// `None`. Only the direct declaration; walk a chain with
/// [`crate::extension::extends_for`].
pub const EXTENDS: Option<&str> = None;
/// The extended error codes this specification declares (SPEC §7.3 item 9,
/// §8.5), in declaration order. Empty when it declares none.
pub const ERROR_CODES: &[crate::DeclaredErrorCode] = &[error_codes::CANDIDATE_REGO_INVALID];
/// One constant per extended error code this specification declares
/// (SPEC §7.3 item 9), named for its local part.
///
/// Emit these rather than a string literal: the code is read from the
/// specification, so it cannot name a code the specification never
/// declared.
pub mod error_codes {
/// `policy/evaluate:candidateRegoInvalid`
///
/// The supplied `candidateModule` failed parsing.
///
/// Declared `retryable: false`.
/// Declares a `detailsSchema` for the error's `details` member.
pub const CANDIDATE_REGO_INVALID: crate::DeclaredErrorCode = crate::DeclaredErrorCode {
code: "policy/evaluate:candidateRegoInvalid",
retryable: false,
details_schema: ::core::option::Option::Some(
"{\"additionalProperties\":false,\"properties\":{\"column\":{\"minimum\":1,\"type\":\"integer\"},\"line\":{\"minimum\":1,\"type\":\"integer\"},\"message\":{\"type\":\"string\"}},\"type\":\"object\"}",
),
};
}