//! Generated by `trust-tasks-codegen` — do not edit by hand.
//!
//! Spec slug: `vault/release`. Version: `0.1`.
#[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())
}
}
}
///`ConsumerContext`
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "title": "ConsumerContext",
/// "type": "object",
/// "properties": {
/// "deviceId": {
/// "description": "Device-binding id assigned at registration. The maintainer cross-checks this against the authenticated transport identity.",
/// "type": "string",
/// "minLength": 1
/// },
/// "lastUserVerificationAt": {
/// "description": "Most recent local user-verification on the consumer device (WebAuthn UV, biometric unlock). The maintainer's policy may require this to be within N seconds.",
/// "type": "string",
/// "format": "date-time"
/// },
/// "networkClass": {
/// "description": "Producer-supplied network classification. Advisory.",
/// "type": "string",
/// "enum": [
/// "unknown",
/// "home",
/// "corp",
/// "public",
/// "vpn"
/// ]
/// }
/// },
/// "additionalProperties": false
///}
/// ```
/// </details>
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(deny_unknown_fields)]
pub struct ConsumerContext {
///Device-binding id assigned at registration. The maintainer cross-checks this against the authenticated transport identity.
#[serde(
rename = "deviceId",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub device_id: ::std::option::Option<ConsumerContextDeviceId>,
///Most recent local user-verification on the consumer device (WebAuthn UV, biometric unlock). The maintainer's policy may require this to be within N seconds.
#[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>>,
///Producer-supplied network classification. Advisory.
#[serde(
rename = "networkClass",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub network_class: ::std::option::Option<ConsumerContextNetworkClass>,
}
impl ::std::convert::From<&ConsumerContext> for ConsumerContext {
fn from(value: &ConsumerContext) -> Self {
value.clone()
}
}
impl ::std::default::Default for ConsumerContext {
fn default() -> Self {
Self {
device_id: Default::default(),
last_user_verification_at: Default::default(),
network_class: Default::default(),
}
}
}
///Device-binding id assigned at registration. The maintainer cross-checks this against the authenticated transport identity.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "description": "Device-binding id assigned at registration. The maintainer cross-checks this against the authenticated transport identity.",
/// "type": "string",
/// "minLength": 1
///}
/// ```
/// </details>
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct ConsumerContextDeviceId(::std::string::String);
impl ::std::ops::Deref for ConsumerContextDeviceId {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<ConsumerContextDeviceId> for ::std::string::String {
fn from(value: ConsumerContextDeviceId) -> Self {
value.0
}
}
impl ::std::convert::From<&ConsumerContextDeviceId> for ConsumerContextDeviceId {
fn from(value: &ConsumerContextDeviceId) -> Self {
value.clone()
}
}
impl ::std::str::FromStr for ConsumerContextDeviceId {
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 ConsumerContextDeviceId {
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 ConsumerContextDeviceId {
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 ConsumerContextDeviceId {
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 ConsumerContextDeviceId {
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())
})
}
}
///Producer-supplied network classification. Advisory.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "description": "Producer-supplied network classification. Advisory.",
/// "type": "string",
/// "enum": [
/// "unknown",
/// "home",
/// "corp",
/// "public",
/// "vpn"
/// ]
///}
/// ```
/// </details>
#[derive(
::serde::Deserialize,
::serde::Serialize,
Clone,
Copy,
Debug,
Eq,
Hash,
Ord,
PartialEq,
PartialOrd,
)]
pub enum ConsumerContextNetworkClass {
#[serde(rename = "unknown")]
Unknown,
#[serde(rename = "home")]
Home,
#[serde(rename = "corp")]
Corp,
#[serde(rename = "public")]
Public,
#[serde(rename = "vpn")]
Vpn,
}
impl ::std::convert::From<&Self> for ConsumerContextNetworkClass {
fn from(value: &ConsumerContextNetworkClass) -> Self {
value.clone()
}
}
impl ::std::fmt::Display for ConsumerContextNetworkClass {
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 ConsumerContextNetworkClass {
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 ConsumerContextNetworkClass {
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 ConsumerContextNetworkClass {
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 ConsumerContextNetworkClass {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
/**DIDComm v2 authcrypt JWE (ECDH-1PU + A256CBC-HS512, X25519/P-256 key agreement). Sender authentication is the JWE's `skid` — the producer's DID#keyAgreement. The maintainer's keyAgreement key is the recipient. Cleartext is JCS-canonical JSON of the variant's payload type.
M2A is the only implementation today; this is also the canonical default for new code.*/
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "title": "DidcommAuthcryptEnvelope",
/// "description": "DIDComm v2 authcrypt JWE (ECDH-1PU + A256CBC-HS512, X25519/P-256 key agreement). Sender authentication is the JWE's `skid` — the producer's DID#keyAgreement. The maintainer's keyAgreement key is the recipient. Cleartext is JCS-canonical JSON of the variant's payload type.\n\nM2A is the only implementation today; this is also the canonical default for new code.",
/// "type": "object",
/// "required": [
/// "envelope",
/// "jwe"
/// ],
/// "properties": {
/// "envelope": {
/// "const": "didcomm-authcrypt"
/// },
/// "jwe": {
/// "description": "Compact DIDComm v2 JWE (base64url-encoded, dot-separated). Unpacks via the framework's standard DIDComm machinery; cleartext is the payload-specific JSON.",
/// "type": "string",
/// "minLength": 1
/// }
/// },
/// "additionalProperties": false
///}
/// ```
/// </details>
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(deny_unknown_fields)]
pub struct DidcommAuthcryptEnvelope {
pub envelope: ::serde_json::Value,
///Compact DIDComm v2 JWE (base64url-encoded, dot-separated). Unpacks via the framework's standard DIDComm machinery; cleartext is the payload-specific JSON.
pub jwe: DidcommAuthcryptEnvelopeJwe,
}
impl ::std::convert::From<&DidcommAuthcryptEnvelope> for DidcommAuthcryptEnvelope {
fn from(value: &DidcommAuthcryptEnvelope) -> Self {
value.clone()
}
}
///Compact DIDComm v2 JWE (base64url-encoded, dot-separated). Unpacks via the framework's standard DIDComm machinery; cleartext is the payload-specific JSON.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "description": "Compact DIDComm v2 JWE (base64url-encoded, dot-separated). Unpacks via the framework's standard DIDComm machinery; cleartext is the payload-specific JSON.",
/// "type": "string",
/// "minLength": 1
///}
/// ```
/// </details>
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct DidcommAuthcryptEnvelopeJwe(::std::string::String);
impl ::std::ops::Deref for DidcommAuthcryptEnvelopeJwe {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<DidcommAuthcryptEnvelopeJwe> for ::std::string::String {
fn from(value: DidcommAuthcryptEnvelopeJwe) -> Self {
value.0
}
}
impl ::std::convert::From<&DidcommAuthcryptEnvelopeJwe> for DidcommAuthcryptEnvelopeJwe {
fn from(value: &DidcommAuthcryptEnvelopeJwe) -> Self {
value.clone()
}
}
impl ::std::str::FromStr for DidcommAuthcryptEnvelopeJwe {
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 DidcommAuthcryptEnvelopeJwe {
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 DidcommAuthcryptEnvelopeJwe {
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 DidcommAuthcryptEnvelopeJwe {
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 DidcommAuthcryptEnvelopeJwe {
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.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "title": "Ext",
/// "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.",
/// "type": "object",
/// "minProperties": 1,
/// "additionalProperties": true,
/// "propertyNames": {
/// "pattern": "^[a-z][a-z0-9-]*(\\.[a-z0-9-]+)+$"
/// }
///}
/// ```
/// </details>
#[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<&Ext> for Ext {
fn from(value: &Ext) -> Self {
value.clone()
}
}
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`
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "type": "string",
/// "pattern": "^[a-z][a-z0-9-]*(\\.[a-z0-9-]+)+$"
///}
/// ```
/// </details>
#[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::convert::From<&ExtKey> for ExtKey {
fn from(value: &ExtKey) -> Self {
value.clone()
}
}
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())
})
}
}
/**OpenPGP-style ASCII-armored HPKE bundle — the existing OpenVTC sealed-transfer wire form (X25519-HKDF-SHA256 KEM + ChaCha20-Poly1305 AEAD, framed in armor with Bundle-Id / Digest-Algo headers and a CRC24 checksum). Producer assertion (`did-signed` / `attested` / `pinned-only`) is the integrity / authenticity anchor.
No open-source implementation reads this yet outside vta-sdk's `sealed_transfer` crate; new code SHOULD prefer the DIDComm variant. Defined here for parity with the existing offline-bundle / cross-VTA workflows that the design plan reserves for M5+.*/
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "title": "HpkeArmoredEnvelope",
/// "description": "OpenPGP-style ASCII-armored HPKE bundle — the existing OpenVTC sealed-transfer wire form (X25519-HKDF-SHA256 KEM + ChaCha20-Poly1305 AEAD, framed in armor with Bundle-Id / Digest-Algo headers and a CRC24 checksum). Producer assertion (`did-signed` / `attested` / `pinned-only`) is the integrity / authenticity anchor.\n\nNo open-source implementation reads this yet outside vta-sdk's `sealed_transfer` crate; new code SHOULD prefer the DIDComm variant. Defined here for parity with the existing offline-bundle / cross-VTA workflows that the design plan reserves for M5+.",
/// "type": "object",
/// "required": [
/// "armored",
/// "envelope",
/// "recipientKeyId"
/// ],
/// "properties": {
/// "armored": {
/// "description": "ASCII-armored bundle text. Multi-line base64 with framing headers + CRC24.",
/// "type": "string",
/// "minLength": 1
/// },
/// "envelope": {
/// "const": "hpke-armored"
/// },
/// "producerAssertion": {
/// "description": "Producer-assertion mode per the sealed-transfer framework. `did-signed` = Ed25519 signature by issuer; `attested` = TEE attestation quote (e.g. Nitro); `pinned-only` = OOB SHA-256 digest only (dev/test, NOT for production).",
/// "default": "did-signed",
/// "type": "string",
/// "enum": [
/// "did-signed",
/// "attested",
/// "pinned-only"
/// ]
/// },
/// "recipientKeyId": {
/// "description": "did:key identifier of the X25519 public key the envelope was sealed to. The recipient uses this to select the matching private key.",
/// "type": "string",
/// "minLength": 1
/// }
/// },
/// "additionalProperties": false
///}
/// ```
/// </details>
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(deny_unknown_fields)]
pub struct HpkeArmoredEnvelope {
///ASCII-armored bundle text. Multi-line base64 with framing headers + CRC24.
pub armored: HpkeArmoredEnvelopeArmored,
pub envelope: ::serde_json::Value,
///Producer-assertion mode per the sealed-transfer framework. `did-signed` = Ed25519 signature by issuer; `attested` = TEE attestation quote (e.g. Nitro); `pinned-only` = OOB SHA-256 digest only (dev/test, NOT for production).
#[serde(
rename = "producerAssertion",
default = "defaults::hpke_armored_envelope_producer_assertion"
)]
pub producer_assertion: HpkeArmoredEnvelopeProducerAssertion,
///did:key identifier of the X25519 public key the envelope was sealed to. The recipient uses this to select the matching private key.
#[serde(rename = "recipientKeyId")]
pub recipient_key_id: HpkeArmoredEnvelopeRecipientKeyId,
}
impl ::std::convert::From<&HpkeArmoredEnvelope> for HpkeArmoredEnvelope {
fn from(value: &HpkeArmoredEnvelope) -> Self {
value.clone()
}
}
///ASCII-armored bundle text. Multi-line base64 with framing headers + CRC24.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "description": "ASCII-armored bundle text. Multi-line base64 with framing headers + CRC24.",
/// "type": "string",
/// "minLength": 1
///}
/// ```
/// </details>
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct HpkeArmoredEnvelopeArmored(::std::string::String);
impl ::std::ops::Deref for HpkeArmoredEnvelopeArmored {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<HpkeArmoredEnvelopeArmored> for ::std::string::String {
fn from(value: HpkeArmoredEnvelopeArmored) -> Self {
value.0
}
}
impl ::std::convert::From<&HpkeArmoredEnvelopeArmored> for HpkeArmoredEnvelopeArmored {
fn from(value: &HpkeArmoredEnvelopeArmored) -> Self {
value.clone()
}
}
impl ::std::str::FromStr for HpkeArmoredEnvelopeArmored {
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 HpkeArmoredEnvelopeArmored {
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 HpkeArmoredEnvelopeArmored {
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 HpkeArmoredEnvelopeArmored {
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 HpkeArmoredEnvelopeArmored {
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())
})
}
}
///Producer-assertion mode per the sealed-transfer framework. `did-signed` = Ed25519 signature by issuer; `attested` = TEE attestation quote (e.g. Nitro); `pinned-only` = OOB SHA-256 digest only (dev/test, NOT for production).
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "description": "Producer-assertion mode per the sealed-transfer framework. `did-signed` = Ed25519 signature by issuer; `attested` = TEE attestation quote (e.g. Nitro); `pinned-only` = OOB SHA-256 digest only (dev/test, NOT for production).",
/// "default": "did-signed",
/// "type": "string",
/// "enum": [
/// "did-signed",
/// "attested",
/// "pinned-only"
/// ]
///}
/// ```
/// </details>
#[derive(
::serde::Deserialize,
::serde::Serialize,
Clone,
Copy,
Debug,
Eq,
Hash,
Ord,
PartialEq,
PartialOrd,
)]
pub enum HpkeArmoredEnvelopeProducerAssertion {
#[serde(rename = "did-signed")]
DidSigned,
#[serde(rename = "attested")]
Attested,
#[serde(rename = "pinned-only")]
PinnedOnly,
}
impl ::std::convert::From<&Self> for HpkeArmoredEnvelopeProducerAssertion {
fn from(value: &HpkeArmoredEnvelopeProducerAssertion) -> Self {
value.clone()
}
}
impl ::std::fmt::Display for HpkeArmoredEnvelopeProducerAssertion {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
match *self {
Self::DidSigned => f.write_str("did-signed"),
Self::Attested => f.write_str("attested"),
Self::PinnedOnly => f.write_str("pinned-only"),
}
}
}
impl ::std::str::FromStr for HpkeArmoredEnvelopeProducerAssertion {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
match value {
"did-signed" => Ok(Self::DidSigned),
"attested" => Ok(Self::Attested),
"pinned-only" => Ok(Self::PinnedOnly),
_ => Err("invalid value".into()),
}
}
}
impl ::std::convert::TryFrom<&str> for HpkeArmoredEnvelopeProducerAssertion {
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 HpkeArmoredEnvelopeProducerAssertion {
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 HpkeArmoredEnvelopeProducerAssertion {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::default::Default for HpkeArmoredEnvelopeProducerAssertion {
fn default() -> Self {
HpkeArmoredEnvelopeProducerAssertion::DidSigned
}
}
///did:key identifier of the X25519 public key the envelope was sealed to. The recipient uses this to select the matching private key.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "description": "did:key identifier of the X25519 public key the envelope was sealed to. The recipient uses this to select the matching private key.",
/// "type": "string",
/// "minLength": 1
///}
/// ```
/// </details>
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct HpkeArmoredEnvelopeRecipientKeyId(::std::string::String);
impl ::std::ops::Deref for HpkeArmoredEnvelopeRecipientKeyId {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<HpkeArmoredEnvelopeRecipientKeyId> for ::std::string::String {
fn from(value: HpkeArmoredEnvelopeRecipientKeyId) -> Self {
value.0
}
}
impl ::std::convert::From<&HpkeArmoredEnvelopeRecipientKeyId>
for HpkeArmoredEnvelopeRecipientKeyId
{
fn from(value: &HpkeArmoredEnvelopeRecipientKeyId) -> Self {
value.clone()
}
}
impl ::std::str::FromStr for HpkeArmoredEnvelopeRecipientKeyId {
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 HpkeArmoredEnvelopeRecipientKeyId {
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 HpkeArmoredEnvelopeRecipientKeyId {
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 HpkeArmoredEnvelopeRecipientKeyId {
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 HpkeArmoredEnvelopeRecipientKeyId {
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())
})
}
}
///Consumer requests that the maintainer release the cleartext secret material of a vault entry. The response carries the secret in a pluggable cipher envelope (see vault/_shared/0.1/sealed-envelope); the cleartext shape is `vault/_shared/0.1/vault-secret#/$defs/VaultSecret`. This is the fallback when proxy-login is not viable (`vault/proxy-login:not_proxyable`) or when the consumer needs the raw secret for a flow the maintainer cannot perform (e.g. autofill into a desktop app, copy-to-clipboard for offline use).
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "$id": "https://trusttasks.org/spec/vault/release/0.1",
/// "title": "Payload",
/// "description": "Consumer requests that the maintainer release the cleartext secret material of a vault entry. The response carries the secret in a pluggable cipher envelope (see vault/_shared/0.1/sealed-envelope); the cleartext shape is `vault/_shared/0.1/vault-secret#/$defs/VaultSecret`. This is the fallback when proxy-login is not viable (`vault/proxy-login:not_proxyable`) or when the consumer needs the raw secret for a flow the maintainer cannot perform (e.g. autofill into a desktop app, copy-to-clipboard for offline use).",
/// "type": "object",
/// "required": [
/// "entryId"
/// ],
/// "properties": {
/// "consumerContext": {
/// "description": "Caller's situational context — fed to the policy engine.",
/// "$ref": "#/definitions/ConsumerContext"
/// },
/// "entryId": {
/// "type": "string",
/// "minLength": 1
/// },
/// "ext": {
/// "$ref": "#/definitions/Ext"
/// },
/// "stepUpProof": {
/// "description": "Step-up proof on retry after step_up_required.",
/// "$ref": "#/definitions/StepUpProof"
/// },
/// "target": {
/// "description": "Optional — for entries with multiple targets, indicates which one the consumer is acting against. The maintainer's policy may decide release based on the target (e.g. release for web origin allowed, release for iOS app denied).",
/// "$ref": "#/definitions/SiteTarget"
/// },
/// "ttlSecondsHint": {
/// "description": "Consumer's requested cache TTL for the released secret. The maintainer MAY cap this; the consumer MUST honour the maintainer's decision.",
/// "type": "integer",
/// "maximum": 600.0,
/// "minimum": 1.0
/// }
/// },
/// "additionalProperties": false
///}
/// ```
/// </details>
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(deny_unknown_fields)]
pub struct Payload {
///Caller's situational context — fed to the policy engine.
#[serde(
rename = "consumerContext",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub consumer_context: ::std::option::Option<ConsumerContext>,
#[serde(rename = "entryId")]
pub entry_id: PayloadEntryId,
#[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
pub ext: ::std::option::Option<Ext>,
///Step-up proof on retry after step_up_required.
#[serde(
rename = "stepUpProof",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub step_up_proof: ::std::option::Option<StepUpProof>,
///Optional — for entries with multiple targets, indicates which one the consumer is acting against. The maintainer's policy may decide release based on the target (e.g. release for web origin allowed, release for iOS app denied).
#[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
pub target: ::std::option::Option<SiteTarget>,
///Consumer's requested cache TTL for the released secret. The maintainer MAY cap this; the consumer MUST honour the maintainer's decision.
#[serde(
rename = "ttlSecondsHint",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub ttl_seconds_hint: ::std::option::Option<::std::num::NonZeroU64>,
}
impl ::std::convert::From<&Payload> for Payload {
fn from(value: &Payload) -> Self {
value.clone()
}
}
///`PayloadEntryId`
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "type": "string",
/// "minLength": 1
///}
/// ```
/// </details>
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct PayloadEntryId(::std::string::String);
impl ::std::ops::Deref for PayloadEntryId {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<PayloadEntryId> for ::std::string::String {
fn from(value: PayloadEntryId) -> Self {
value.0
}
}
impl ::std::convert::From<&PayloadEntryId> for PayloadEntryId {
fn from(value: &PayloadEntryId) -> Self {
value.clone()
}
}
impl ::std::str::FromStr for PayloadEntryId {
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 PayloadEntryId {
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 PayloadEntryId {
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 PayloadEntryId {
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 PayloadEntryId {
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())
})
}
}
///`Response`
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "title": "Response",
/// "type": "object",
/// "required": [
/// "sealedSecret",
/// "secretKind",
/// "ttlSeconds"
/// ],
/// "properties": {
/// "ext": {
/// "$ref": "#/definitions/Ext"
/// },
/// "sealedSecret": {
/// "description": "Pluggable cipher envelope. Cleartext is a `vault/_shared/0.1/vault-secret#/$defs/VaultSecret`. Consumers reject envelope kinds they don't implement with `vault/release:envelope_unsupported`.",
/// "$ref": "#/definitions/SealedEnvelope"
/// },
/// "secretKind": {
/// "description": "Discriminator so the consumer can pre-allocate the right type before unsealing.",
/// "$ref": "#/definitions/SecretKind"
/// },
/// "ttlSeconds": {
/// "description": "Cache TTL the consumer MUST enforce — wipe the cleartext after this many seconds, even if the user has not finished interacting with it.",
/// "type": "integer",
/// "maximum": 600.0,
/// "minimum": 1.0
/// }
/// },
/// "additionalProperties": false,
/// "$anchor": "response"
///}
/// ```
/// </details>
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(deny_unknown_fields)]
pub struct Response {
#[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
pub ext: ::std::option::Option<Ext>,
///Pluggable cipher envelope. Cleartext is a `vault/_shared/0.1/vault-secret#/$defs/VaultSecret`. Consumers reject envelope kinds they don't implement with `vault/release:envelope_unsupported`.
#[serde(rename = "sealedSecret")]
pub sealed_secret: SealedEnvelope,
///Discriminator so the consumer can pre-allocate the right type before unsealing.
#[serde(rename = "secretKind")]
pub secret_kind: SecretKind,
///Cache TTL the consumer MUST enforce — wipe the cleartext after this many seconds, even if the user has not finished interacting with it.
#[serde(rename = "ttlSeconds")]
pub ttl_seconds: ::std::num::NonZeroU64,
}
impl ::std::convert::From<&Response> for Response {
fn from(value: &Response) -> Self {
value.clone()
}
}
///Discriminated by `envelope`. Exactly one variant matches per document.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "title": "SealedEnvelope",
/// "description": "Discriminated by `envelope`. Exactly one variant matches per document.",
/// "oneOf": [
/// {
/// "$ref": "#/definitions/DidcommAuthcryptEnvelope"
/// },
/// {
/// "$ref": "#/definitions/HpkeArmoredEnvelope"
/// },
/// {
/// "$ref": "#/definitions/TspMessageEnvelope"
/// }
/// ]
///}
/// ```
/// </details>
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(untagged)]
pub enum SealedEnvelope {
DidcommAuthcryptEnvelope(DidcommAuthcryptEnvelope),
HpkeArmoredEnvelope(HpkeArmoredEnvelope),
TspMessageEnvelope(TspMessageEnvelope),
}
impl ::std::convert::From<&Self> for SealedEnvelope {
fn from(value: &SealedEnvelope) -> Self {
value.clone()
}
}
impl ::std::convert::From<DidcommAuthcryptEnvelope> for SealedEnvelope {
fn from(value: DidcommAuthcryptEnvelope) -> Self {
Self::DidcommAuthcryptEnvelope(value)
}
}
impl ::std::convert::From<HpkeArmoredEnvelope> for SealedEnvelope {
fn from(value: HpkeArmoredEnvelope) -> Self {
Self::HpkeArmoredEnvelope(value)
}
}
impl ::std::convert::From<TspMessageEnvelope> for SealedEnvelope {
fn from(value: TspMessageEnvelope) -> Self {
Self::TspMessageEnvelope(value)
}
}
/**Discriminator for the secret type stored in the entry. Definitions:
- `password` — username + password (+ optional TOTP seed).
- `passkey` — WebAuthn discoverable credential (private key + rpId + userHandle).
- `oauth-tokens` — OAuth 2.0 refresh + access token bundle for a specific provider.
- `did-self-issued` — Self-Issued OpenID Provider v2 (SIOP) credential: the entry points at a DID + signing key already managed by the VTA.
- `didcomm-peer` — DIDComm peer identity used to authenticate against a DIDComm-speaking relying party.
- `bearer-token` — opaque bearer token carried in a maintainer-named header (covers API tokens, long-lived JWTs, personal-access tokens).
- `ssh-key` — SSH private key + comment.
- `custom` — arbitrary structured fields; release-time consumer responsible for interpretation.*/
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "title": "SecretKind",
/// "description": "Discriminator for the secret type stored in the entry. Definitions:\n- `password` — username + password (+ optional TOTP seed).\n- `passkey` — WebAuthn discoverable credential (private key + rpId + userHandle).\n- `oauth-tokens` — OAuth 2.0 refresh + access token bundle for a specific provider.\n- `did-self-issued` — Self-Issued OpenID Provider v2 (SIOP) credential: the entry points at a DID + signing key already managed by the VTA.\n- `didcomm-peer` — DIDComm peer identity used to authenticate against a DIDComm-speaking relying party.\n- `bearer-token` — opaque bearer token carried in a maintainer-named header (covers API tokens, long-lived JWTs, personal-access tokens).\n- `ssh-key` — SSH private key + comment.\n- `custom` — arbitrary structured fields; release-time consumer responsible for interpretation.",
/// "type": "string",
/// "enum": [
/// "password",
/// "passkey",
/// "oauth-tokens",
/// "did-self-issued",
/// "didcomm-peer",
/// "bearer-token",
/// "ssh-key",
/// "custom"
/// ]
///}
/// ```
/// </details>
#[derive(
::serde::Deserialize,
::serde::Serialize,
Clone,
Copy,
Debug,
Eq,
Hash,
Ord,
PartialEq,
PartialOrd,
)]
pub enum SecretKind {
#[serde(rename = "password")]
Password,
#[serde(rename = "passkey")]
Passkey,
#[serde(rename = "oauth-tokens")]
OauthTokens,
#[serde(rename = "did-self-issued")]
DidSelfIssued,
#[serde(rename = "didcomm-peer")]
DidcommPeer,
#[serde(rename = "bearer-token")]
BearerToken,
#[serde(rename = "ssh-key")]
SshKey,
#[serde(rename = "custom")]
Custom,
}
impl ::std::convert::From<&Self> for SecretKind {
fn from(value: &SecretKind) -> Self {
value.clone()
}
}
impl ::std::fmt::Display for SecretKind {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
match *self {
Self::Password => f.write_str("password"),
Self::Passkey => f.write_str("passkey"),
Self::OauthTokens => f.write_str("oauth-tokens"),
Self::DidSelfIssued => f.write_str("did-self-issued"),
Self::DidcommPeer => f.write_str("didcomm-peer"),
Self::BearerToken => f.write_str("bearer-token"),
Self::SshKey => f.write_str("ssh-key"),
Self::Custom => f.write_str("custom"),
}
}
}
impl ::std::str::FromStr for SecretKind {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
match value {
"password" => Ok(Self::Password),
"passkey" => Ok(Self::Passkey),
"oauth-tokens" => Ok(Self::OauthTokens),
"did-self-issued" => Ok(Self::DidSelfIssued),
"didcomm-peer" => Ok(Self::DidcommPeer),
"bearer-token" => Ok(Self::BearerToken),
"ssh-key" => Ok(Self::SshKey),
"custom" => Ok(Self::Custom),
_ => Err("invalid value".into()),
}
}
}
impl ::std::convert::TryFrom<&str> for SecretKind {
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 SecretKind {
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 SecretKind {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
///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.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "title": "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": [
/// {
/// "title": "WebOrigin",
/// "type": "object",
/// "required": [
/// "kind",
/// "origin"
/// ],
/// "properties": {
/// "kind": {
/// "const": "web-origin"
/// },
/// "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.",
/// "type": "string",
/// "format": "uri"
/// }
/// },
/// "additionalProperties": false
/// },
/// {
/// "title": "Did",
/// "type": "object",
/// "required": [
/// "did",
/// "kind"
/// ],
/// "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.",
/// "type": "string",
/// "minLength": 1
/// },
/// "kind": {
/// "const": "did"
/// }
/// },
/// "additionalProperties": false
/// },
/// {
/// "title": "IosApp",
/// "type": "object",
/// "required": [
/// "bundleId",
/// "kind"
/// ],
/// "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).",
/// "type": "string",
/// "minLength": 1,
/// "pattern": "^[A-Za-z0-9.-]+$"
/// },
/// "kind": {
/// "const": "ios-app"
/// },
/// "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.",
/// "type": "string",
/// "minLength": 1,
/// "pattern": "^[A-Z0-9]+$"
/// }
/// },
/// "additionalProperties": false
/// },
/// {
/// "title": "AndroidApp",
/// "type": "object",
/// "required": [
/// "kind",
/// "packageName",
/// "sha256CertFingerprints"
/// ],
/// "properties": {
/// "kind": {
/// "const": "android-app"
/// },
/// "packageName": {
/// "description": "Android package name in reverse-DNS form (e.g. \"com.github.android\").",
/// "type": "string",
/// "minLength": 1,
/// "pattern": "^[A-Za-z][A-Za-z0-9_]*(\\.[A-Za-z][A-Za-z0-9_]*)+$"
/// },
/// "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).",
/// "type": "array",
/// "items": {
/// "type": "string",
/// "pattern": "^[0-9A-F]{2}(:[0-9A-F]{2}){31}$"
/// },
/// "minItems": 1,
/// "uniqueItems": true
/// }
/// },
/// "additionalProperties": false
/// }
/// ]
///}
/// ```
/// </details>
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(tag = "kind", deny_unknown_fields)]
pub enum SiteTarget {
///WebOrigin
#[serde(rename = "web-origin")]
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 = "ios-app")]
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 = "android-app")]
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>,
},
}
impl ::std::convert::From<&Self> for SiteTarget {
fn from(value: &SiteTarget) -> Self {
value.clone()
}
}
///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).
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "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).",
/// "type": "string",
/// "minLength": 1,
/// "pattern": "^[A-Za-z0-9.-]+$"
///}
/// ```
/// </details>
#[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::convert::From<&SiteTargetBundleId> for SiteTargetBundleId {
fn from(value: &SiteTargetBundleId) -> Self {
value.clone()
}
}
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.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "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.",
/// "type": "string",
/// "minLength": 1
///}
/// ```
/// </details>
#[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::convert::From<&SiteTargetDid> for SiteTargetDid {
fn from(value: &SiteTargetDid) -> Self {
value.clone()
}
}
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").
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "description": "Android package name in reverse-DNS form (e.g. \"com.github.android\").",
/// "type": "string",
/// "minLength": 1,
/// "pattern": "^[A-Za-z][A-Za-z0-9_]*(\\.[A-Za-z][A-Za-z0-9_]*)+$"
///}
/// ```
/// </details>
#[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::convert::From<&SiteTargetPackageName> for SiteTargetPackageName {
fn from(value: &SiteTargetPackageName) -> Self {
value.clone()
}
}
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`
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "type": "string",
/// "pattern": "^[0-9A-F]{2}(:[0-9A-F]{2}){31}$"
///}
/// ```
/// </details>
#[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::convert::From<&SiteTargetSha256CertFingerprintsItem>
for SiteTargetSha256CertFingerprintsItem
{
fn from(value: &SiteTargetSha256CertFingerprintsItem) -> Self {
value.clone()
}
}
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.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "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.",
/// "type": "string",
/// "minLength": 1,
/// "pattern": "^[A-Z0-9]+$"
///}
/// ```
/// </details>
#[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::convert::From<&SiteTargetTeamId> for SiteTargetTeamId {
fn from(value: &SiteTargetTeamId) -> Self {
value.clone()
}
}
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())
})
}
}
///`StepUpProof`
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "title": "StepUpProof",
/// "type": "object",
/// "required": [
/// "challengeId",
/// "kind",
/// "proof"
/// ],
/// "properties": {
/// "challengeId": {
/// "description": "Maintainer-issued challenge id the proof responds to.",
/// "type": "string",
/// "minLength": 1
/// },
/// "kind": {
/// "type": "string",
/// "enum": [
/// "webauthn-uv",
/// "push-approval",
/// "totp"
/// ]
/// },
/// "proof": {
/// "description": "Format depends on kind: WebAuthn assertion (base64url), DIDComm approval-response message id, or 6–8-digit TOTP code.",
/// "type": "string"
/// }
/// },
/// "additionalProperties": false
///}
/// ```
/// </details>
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(deny_unknown_fields)]
pub struct StepUpProof {
///Maintainer-issued challenge id the proof responds to.
#[serde(rename = "challengeId")]
pub challenge_id: StepUpProofChallengeId,
pub kind: StepUpProofKind,
///Format depends on kind: WebAuthn assertion (base64url), DIDComm approval-response message id, or 6–8-digit TOTP code.
pub proof: ::std::string::String,
}
impl ::std::convert::From<&StepUpProof> for StepUpProof {
fn from(value: &StepUpProof) -> Self {
value.clone()
}
}
///Maintainer-issued challenge id the proof responds to.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "description": "Maintainer-issued challenge id the proof responds to.",
/// "type": "string",
/// "minLength": 1
///}
/// ```
/// </details>
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct StepUpProofChallengeId(::std::string::String);
impl ::std::ops::Deref for StepUpProofChallengeId {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<StepUpProofChallengeId> for ::std::string::String {
fn from(value: StepUpProofChallengeId) -> Self {
value.0
}
}
impl ::std::convert::From<&StepUpProofChallengeId> for StepUpProofChallengeId {
fn from(value: &StepUpProofChallengeId) -> Self {
value.clone()
}
}
impl ::std::str::FromStr for StepUpProofChallengeId {
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 StepUpProofChallengeId {
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 StepUpProofChallengeId {
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 StepUpProofChallengeId {
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 StepUpProofChallengeId {
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())
})
}
}
///`StepUpProofKind`
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "type": "string",
/// "enum": [
/// "webauthn-uv",
/// "push-approval",
/// "totp"
/// ]
///}
/// ```
/// </details>
#[derive(
::serde::Deserialize,
::serde::Serialize,
Clone,
Copy,
Debug,
Eq,
Hash,
Ord,
PartialEq,
PartialOrd,
)]
pub enum StepUpProofKind {
#[serde(rename = "webauthn-uv")]
WebauthnUv,
#[serde(rename = "push-approval")]
PushApproval,
#[serde(rename = "totp")]
Totp,
}
impl ::std::convert::From<&Self> for StepUpProofKind {
fn from(value: &StepUpProofKind) -> Self {
value.clone()
}
}
impl ::std::fmt::Display for StepUpProofKind {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
match *self {
Self::WebauthnUv => f.write_str("webauthn-uv"),
Self::PushApproval => f.write_str("push-approval"),
Self::Totp => f.write_str("totp"),
}
}
}
impl ::std::str::FromStr for StepUpProofKind {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
match value {
"webauthn-uv" => Ok(Self::WebauthnUv),
"push-approval" => Ok(Self::PushApproval),
"totp" => Ok(Self::Totp),
_ => Err("invalid value".into()),
}
}
}
impl ::std::convert::TryFrom<&str> for StepUpProofKind {
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 StepUpProofKind {
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 StepUpProofKind {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
///Trust Spanning Protocol message (https://trustoverip.github.io/tswg-tsp-specification/). Reserved variant; no OpenVTC component reads or emits this today. Listed in the union so implementations can declare intent to use TSP in discovery and so consumers reject `tsp-message` envelopes explicitly (`envelope_unsupported`) until they're wired up — rather than silently failing in DIDComm parsing.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "title": "TspMessageEnvelope",
/// "description": "Trust Spanning Protocol message (https://trustoverip.github.io/tswg-tsp-specification/). Reserved variant; no OpenVTC component reads or emits this today. Listed in the union so implementations can declare intent to use TSP in discovery and so consumers reject `tsp-message` envelopes explicitly (`envelope_unsupported`) until they're wired up — rather than silently failing in DIDComm parsing.",
/// "type": "object",
/// "required": [
/// "envelope",
/// "message"
/// ],
/// "properties": {
/// "envelope": {
/// "const": "tsp-message"
/// },
/// "message": {
/// "description": "Base64url-encoded TSP message bytes. Format reference: https://trustoverip.github.io/tswg-tsp-specification/#message-format",
/// "type": "string",
/// "minLength": 1
/// }
/// },
/// "additionalProperties": false
///}
/// ```
/// </details>
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(deny_unknown_fields)]
pub struct TspMessageEnvelope {
pub envelope: ::serde_json::Value,
///Base64url-encoded TSP message bytes. Format reference: https://trustoverip.github.io/tswg-tsp-specification/#message-format
pub message: TspMessageEnvelopeMessage,
}
impl ::std::convert::From<&TspMessageEnvelope> for TspMessageEnvelope {
fn from(value: &TspMessageEnvelope) -> Self {
value.clone()
}
}
///Base64url-encoded TSP message bytes. Format reference: https://trustoverip.github.io/tswg-tsp-specification/#message-format
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "description": "Base64url-encoded TSP message bytes. Format reference: https://trustoverip.github.io/tswg-tsp-specification/#message-format",
/// "type": "string",
/// "minLength": 1
///}
/// ```
/// </details>
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct TspMessageEnvelopeMessage(::std::string::String);
impl ::std::ops::Deref for TspMessageEnvelopeMessage {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<TspMessageEnvelopeMessage> for ::std::string::String {
fn from(value: TspMessageEnvelopeMessage) -> Self {
value.0
}
}
impl ::std::convert::From<&TspMessageEnvelopeMessage> for TspMessageEnvelopeMessage {
fn from(value: &TspMessageEnvelopeMessage) -> Self {
value.clone()
}
}
impl ::std::str::FromStr for TspMessageEnvelopeMessage {
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 TspMessageEnvelopeMessage {
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 TspMessageEnvelopeMessage {
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 TspMessageEnvelopeMessage {
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 TspMessageEnvelopeMessage {
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())
})
}
}
/// Generation of default values for serde.
pub mod defaults {
pub(super) fn hpke_armored_envelope_producer_assertion(
) -> super::HpkeArmoredEnvelopeProducerAssertion {
super::HpkeArmoredEnvelopeProducerAssertion::DidSigned
}
}
impl crate::Payload for Payload {
const TYPE_URI: &'static str = "https://trusttasks.org/spec/vault/release/0.1";
const IS_PROOF_REQUIRED: bool = true;
}
impl crate::Payload for Response {
const TYPE_URI: &'static str = "https://trusttasks.org/spec/vault/release/0.1#response";
const IS_PROOF_REQUIRED: bool = true;
}
#[cfg(feature = "validate")]
impl crate::validate::ValidatedPayload for Payload {
const SCHEMA_JSON: &'static str = "{\n \"$defs\": {\n \"ConsumerContext\": {\n \"additionalProperties\": false,\n \"properties\": {\n \"deviceId\": {\n \"description\": \"Device-binding id assigned at registration. The maintainer cross-checks this against the authenticated transport identity.\",\n \"minLength\": 1,\n \"type\": \"string\"\n },\n \"lastUserVerificationAt\": {\n \"description\": \"Most recent local user-verification on the consumer device (WebAuthn UV, biometric unlock). The maintainer's policy may require this to be within N seconds.\",\n \"format\": \"date-time\",\n \"type\": \"string\"\n },\n \"networkClass\": {\n \"description\": \"Producer-supplied network classification. Advisory.\",\n \"enum\": [\n \"unknown\",\n \"home\",\n \"corp\",\n \"public\",\n \"vpn\"\n ],\n \"type\": \"string\"\n }\n },\n \"title\": \"ConsumerContext\",\n \"type\": \"object\"\n },\n \"DidcommAuthcryptEnvelope\": {\n \"additionalProperties\": false,\n \"description\": \"DIDComm v2 authcrypt JWE (ECDH-1PU + A256CBC-HS512, X25519/P-256 key agreement). Sender authentication is the JWE's `skid` — the producer's DID#keyAgreement. The maintainer's keyAgreement key is the recipient. Cleartext is JCS-canonical JSON of the variant's payload type.\\n\\nM2A is the only implementation today; this is also the canonical default for new code.\",\n \"properties\": {\n \"envelope\": {\n \"const\": \"didcomm-authcrypt\"\n },\n \"jwe\": {\n \"description\": \"Compact DIDComm v2 JWE (base64url-encoded, dot-separated). Unpacks via the framework's standard DIDComm machinery; cleartext is the payload-specific JSON.\",\n \"minLength\": 1,\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"envelope\",\n \"jwe\"\n ],\n \"title\": \"DidcommAuthcryptEnvelope\",\n \"type\": \"object\"\n },\n \"Ext\": {\n \"additionalProperties\": true,\n \"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.\",\n \"minProperties\": 1,\n \"propertyNames\": {\n \"pattern\": \"^[a-z][a-z0-9-]*(\\\\.[a-z0-9-]+)+$\"\n },\n \"title\": \"Ext\",\n \"type\": \"object\"\n },\n \"HpkeArmoredEnvelope\": {\n \"additionalProperties\": false,\n \"description\": \"OpenPGP-style ASCII-armored HPKE bundle — the existing OpenVTC sealed-transfer wire form (X25519-HKDF-SHA256 KEM + ChaCha20-Poly1305 AEAD, framed in armor with Bundle-Id / Digest-Algo headers and a CRC24 checksum). Producer assertion (`did-signed` / `attested` / `pinned-only`) is the integrity / authenticity anchor.\\n\\nNo open-source implementation reads this yet outside vta-sdk's `sealed_transfer` crate; new code SHOULD prefer the DIDComm variant. Defined here for parity with the existing offline-bundle / cross-VTA workflows that the design plan reserves for M5+.\",\n \"properties\": {\n \"armored\": {\n \"description\": \"ASCII-armored bundle text. Multi-line base64 with framing headers + CRC24.\",\n \"minLength\": 1,\n \"type\": \"string\"\n },\n \"envelope\": {\n \"const\": \"hpke-armored\"\n },\n \"producerAssertion\": {\n \"default\": \"did-signed\",\n \"description\": \"Producer-assertion mode per the sealed-transfer framework. `did-signed` = Ed25519 signature by issuer; `attested` = TEE attestation quote (e.g. Nitro); `pinned-only` = OOB SHA-256 digest only (dev/test, NOT for production).\",\n \"enum\": [\n \"did-signed\",\n \"attested\",\n \"pinned-only\"\n ],\n \"type\": \"string\"\n },\n \"recipientKeyId\": {\n \"description\": \"did:key identifier of the X25519 public key the envelope was sealed to. The recipient uses this to select the matching private key.\",\n \"minLength\": 1,\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"envelope\",\n \"armored\",\n \"recipientKeyId\"\n ],\n \"title\": \"HpkeArmoredEnvelope\",\n \"type\": \"object\"\n },\n \"Response\": {\n \"$anchor\": \"response\",\n \"additionalProperties\": false,\n \"properties\": {\n \"ext\": {\n \"$ref\": \"#/$defs/Ext\"\n },\n \"sealedSecret\": {\n \"$ref\": \"#/$defs/SealedEnvelope\",\n \"description\": \"Pluggable cipher envelope. Cleartext is a `vault/_shared/0.1/vault-secret#/$defs/VaultSecret`. Consumers reject envelope kinds they don't implement with `vault/release:envelope_unsupported`.\"\n },\n \"secretKind\": {\n \"$ref\": \"#/$defs/SecretKind\",\n \"description\": \"Discriminator so the consumer can pre-allocate the right type before unsealing.\"\n },\n \"ttlSeconds\": {\n \"description\": \"Cache TTL the consumer MUST enforce — wipe the cleartext after this many seconds, even if the user has not finished interacting with it.\",\n \"maximum\": 600,\n \"minimum\": 1,\n \"type\": \"integer\"\n }\n },\n \"required\": [\n \"sealedSecret\",\n \"secretKind\",\n \"ttlSeconds\"\n ],\n \"title\": \"Vault Release — response payload\",\n \"type\": \"object\"\n },\n \"SealedEnvelope\": {\n \"description\": \"Discriminated by `envelope`. Exactly one variant matches per document.\",\n \"oneOf\": [\n {\n \"$ref\": \"#/$defs/DidcommAuthcryptEnvelope\"\n },\n {\n \"$ref\": \"#/$defs/HpkeArmoredEnvelope\"\n },\n {\n \"$ref\": \"#/$defs/TspMessageEnvelope\"\n }\n ],\n \"title\": \"SealedEnvelope\"\n },\n \"SecretKind\": {\n \"description\": \"Discriminator for the secret type stored in the entry. Definitions:\\n- `password` — username + password (+ optional TOTP seed).\\n- `passkey` — WebAuthn discoverable credential (private key + rpId + userHandle).\\n- `oauth-tokens` — OAuth 2.0 refresh + access token bundle for a specific provider.\\n- `did-self-issued` — Self-Issued OpenID Provider v2 (SIOP) credential: the entry points at a DID + signing key already managed by the VTA.\\n- `didcomm-peer` — DIDComm peer identity used to authenticate against a DIDComm-speaking relying party.\\n- `bearer-token` — opaque bearer token carried in a maintainer-named header (covers API tokens, long-lived JWTs, personal-access tokens).\\n- `ssh-key` — SSH private key + comment.\\n- `custom` — arbitrary structured fields; release-time consumer responsible for interpretation.\",\n \"enum\": [\n \"password\",\n \"passkey\",\n \"oauth-tokens\",\n \"did-self-issued\",\n \"didcomm-peer\",\n \"bearer-token\",\n \"ssh-key\",\n \"custom\"\n ],\n \"title\": \"SecretKind\",\n \"type\": \"string\"\n },\n \"SiteTarget\": {\n \"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.\",\n \"oneOf\": [\n {\n \"additionalProperties\": false,\n \"properties\": {\n \"kind\": {\n \"const\": \"web-origin\"\n },\n \"origin\": {\n \"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.\",\n \"format\": \"uri\",\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"kind\",\n \"origin\"\n ],\n \"title\": \"WebOrigin\",\n \"type\": \"object\"\n },\n {\n \"additionalProperties\": false,\n \"properties\": {\n \"did\": {\n \"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.\",\n \"minLength\": 1,\n \"type\": \"string\"\n },\n \"kind\": {\n \"const\": \"did\"\n }\n },\n \"required\": [\n \"kind\",\n \"did\"\n ],\n \"title\": \"Did\",\n \"type\": \"object\"\n },\n {\n \"additionalProperties\": false,\n \"properties\": {\n \"bundleId\": {\n \"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).\",\n \"minLength\": 1,\n \"pattern\": \"^[A-Za-z0-9.-]+$\",\n \"type\": \"string\"\n },\n \"kind\": {\n \"const\": \"ios-app\"\n },\n \"teamId\": {\n \"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.\",\n \"minLength\": 1,\n \"pattern\": \"^[A-Z0-9]+$\",\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"kind\",\n \"bundleId\"\n ],\n \"title\": \"IosApp\",\n \"type\": \"object\"\n },\n {\n \"additionalProperties\": false,\n \"properties\": {\n \"kind\": {\n \"const\": \"android-app\"\n },\n \"packageName\": {\n \"description\": \"Android package name in reverse-DNS form (e.g. \\\"com.github.android\\\").\",\n \"minLength\": 1,\n \"pattern\": \"^[A-Za-z][A-Za-z0-9_]*(\\\\.[A-Za-z][A-Za-z0-9_]*)+$\",\n \"type\": \"string\"\n },\n \"sha256CertFingerprints\": {\n \"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).\",\n \"items\": {\n \"pattern\": \"^[0-9A-F]{2}(:[0-9A-F]{2}){31}$\",\n \"type\": \"string\"\n },\n \"minItems\": 1,\n \"type\": \"array\",\n \"uniqueItems\": true\n }\n },\n \"required\": [\n \"kind\",\n \"packageName\",\n \"sha256CertFingerprints\"\n ],\n \"title\": \"AndroidApp\",\n \"type\": \"object\"\n }\n ],\n \"title\": \"SiteTarget\"\n },\n \"StepUpProof\": {\n \"additionalProperties\": false,\n \"properties\": {\n \"challengeId\": {\n \"description\": \"Maintainer-issued challenge id the proof responds to.\",\n \"minLength\": 1,\n \"type\": \"string\"\n },\n \"kind\": {\n \"enum\": [\n \"webauthn-uv\",\n \"push-approval\",\n \"totp\"\n ],\n \"type\": \"string\"\n },\n \"proof\": {\n \"description\": \"Format depends on kind: WebAuthn assertion (base64url), DIDComm approval-response message id, or 6–8-digit TOTP code.\",\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"kind\",\n \"proof\",\n \"challengeId\"\n ],\n \"title\": \"StepUpProof\",\n \"type\": \"object\"\n },\n \"TspMessageEnvelope\": {\n \"additionalProperties\": false,\n \"description\": \"Trust Spanning Protocol message (https://trustoverip.github.io/tswg-tsp-specification/). Reserved variant; no OpenVTC component reads or emits this today. Listed in the union so implementations can declare intent to use TSP in discovery and so consumers reject `tsp-message` envelopes explicitly (`envelope_unsupported`) until they're wired up — rather than silently failing in DIDComm parsing.\",\n \"properties\": {\n \"envelope\": {\n \"const\": \"tsp-message\"\n },\n \"message\": {\n \"description\": \"Base64url-encoded TSP message bytes. Format reference: https://trustoverip.github.io/tswg-tsp-specification/#message-format\",\n \"minLength\": 1,\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"envelope\",\n \"message\"\n ],\n \"title\": \"TspMessageEnvelope\",\n \"type\": \"object\"\n }\n },\n \"$id\": \"https://trusttasks.org/spec/vault/release/0.1\",\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"additionalProperties\": false,\n \"description\": \"Consumer requests that the maintainer release the cleartext secret material of a vault entry. The response carries the secret in a pluggable cipher envelope (see vault/_shared/0.1/sealed-envelope); the cleartext shape is `vault/_shared/0.1/vault-secret#/$defs/VaultSecret`. This is the fallback when proxy-login is not viable (`vault/proxy-login:not_proxyable`) or when the consumer needs the raw secret for a flow the maintainer cannot perform (e.g. autofill into a desktop app, copy-to-clipboard for offline use).\",\n \"properties\": {\n \"consumerContext\": {\n \"$ref\": \"#/$defs/ConsumerContext\",\n \"description\": \"Caller's situational context — fed to the policy engine.\"\n },\n \"entryId\": {\n \"minLength\": 1,\n \"type\": \"string\"\n },\n \"ext\": {\n \"$ref\": \"#/$defs/Ext\"\n },\n \"stepUpProof\": {\n \"$ref\": \"#/$defs/StepUpProof\",\n \"description\": \"Step-up proof on retry after step_up_required.\"\n },\n \"target\": {\n \"$ref\": \"#/$defs/SiteTarget\",\n \"description\": \"Optional — for entries with multiple targets, indicates which one the consumer is acting against. The maintainer's policy may decide release based on the target (e.g. release for web origin allowed, release for iOS app denied).\"\n },\n \"ttlSecondsHint\": {\n \"description\": \"Consumer's requested cache TTL for the released secret. The maintainer MAY cap this; the consumer MUST honour the maintainer's decision.\",\n \"maximum\": 600,\n \"minimum\": 1,\n \"type\": \"integer\"\n }\n },\n \"required\": [\n \"entryId\"\n ],\n \"title\": \"Vault Release — payload\",\n \"type\": \"object\"\n}\n";
}