Skip to main content

ic_auth_wire/
lib.rs

1//! Controlled portable-session transport. No endpoint installation, authority,
2//! cryptography, session storage or delivery/retry policy is supplied here.
3pub mod model;
4pub use ic_wire as wire;
5use ic_wire::{Limits, List, Text};
6use model::{LogoutResult, PortableCredential};
7
8/// Admission narrowing accompanies the exact opaque signed credential.
9#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
10#[cfg_attr(feature = "typescript", derive(ic_wire::Wire))]
11pub struct SessionInput {
12    pub credential: PortableCredential,
13    pub scopes: List<Text<64>, 16>,
14    pub ttl_secs: Option<u64>,
15}
16/// A receiver's authenticated local reply, never a transferable authorization.
17#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
18#[cfg_attr(feature = "typescript", derive(ic_wire::Wire))]
19pub struct SessionView {
20    pub caller: ic_wire::Bytes<29>,
21    pub issuer: ic_wire::Bytes<29>,
22    pub subject: ic_wire::Bytes<29>,
23    pub expires_at_ns: u64,
24}
25const CREDENTIAL_LIMITS: Limits = Limits {
26    bytes: 524288,
27    allocation: 2097152,
28    nodes: 65536,
29    depth: 32,
30};
31const REPLY_LIMITS: Limits = Limits {
32    bytes: 4096,
33    allocation: 16384,
34    nodes: 128,
35    depth: 8,
36};
37const EMPTY_LIMITS: Limits = Limits {
38    bytes: 11,
39    allocation: 128,
40    nodes: 8,
41    depth: 4,
42};
43
44/// Data-envelope identity, not a callable issuer method or signing format.
45pub struct CredentialEnvelope;
46impl CredentialEnvelope {
47    pub const ID: u64 = 0x415554480001;
48    pub const NAME: &'static str = "credential";
49    pub const REQUEST_LIMITS: Limits = CREDENTIAL_LIMITS;
50    pub const RESPONSE_LIMITS: Limits = CREDENTIAL_LIMITS;
51    pub fn encode_request(value: &PortableCredential) -> Result<Vec<u8>, ic_wire::Error> {
52        ic_wire::native::encode_request(Self::ID, value, Self::REQUEST_LIMITS)
53    }
54    pub fn decode_request(bytes: &[u8]) -> Result<PortableCredential, ic_wire::Error> {
55        ic_wire::native::decode_request(Self::ID, bytes, Self::REQUEST_LIMITS)
56    }
57    pub fn encode_response(value: &PortableCredential) -> Result<Vec<u8>, ic_wire::Error> {
58        ic_wire::native::encode_response(Self::ID, value, Self::RESPONSE_LIMITS)
59    }
60    pub fn decode_response(bytes: &[u8]) -> Result<PortableCredential, ic_wire::Error> {
61        ic_wire::native::decode_response(Self::ID, bytes, Self::RESPONSE_LIMITS)
62    }
63}
64/// Controlled admission contract; consumers bind it to their own update export.
65pub struct EstablishSession;
66impl EstablishSession {
67    pub const ID: u64 = 0x415554480012;
68    pub const NAME: &'static str = "establish_portable_session";
69    pub const REQUEST_LIMITS: Limits = CREDENTIAL_LIMITS;
70    pub const RESPONSE_LIMITS: Limits = REPLY_LIMITS;
71    pub fn encode_request(value: &SessionInput) -> Result<Vec<u8>, ic_wire::Error> {
72        ic_wire::native::encode_request(Self::ID, value, Self::REQUEST_LIMITS)
73    }
74    pub fn decode_request(bytes: &[u8]) -> Result<SessionInput, ic_wire::Error> {
75        ic_wire::native::decode_request(Self::ID, bytes, Self::REQUEST_LIMITS)
76    }
77    pub fn encode_response(
78        value: &Result<SessionView, model::AdmissionRefusal>,
79    ) -> Result<Vec<u8>, ic_wire::Error> {
80        ic_wire::native::encode_response(Self::ID, value, Self::RESPONSE_LIMITS)
81    }
82    pub fn decode_response(
83        bytes: &[u8],
84    ) -> Result<Result<SessionView, model::AdmissionRefusal>, ic_wire::Error> {
85        ic_wire::native::decode_response(Self::ID, bytes, Self::RESPONSE_LIMITS)
86    }
87}
88/// Proof-free local read contract; the runtime caller selects the session.
89pub struct ReadSession;
90impl ReadSession {
91    pub const ID: u64 = 0x415554480003;
92    pub const NAME: &'static str = "portable_session_read";
93    pub const REQUEST_LIMITS: Limits = EMPTY_LIMITS;
94    pub const RESPONSE_LIMITS: Limits = REPLY_LIMITS;
95    pub fn encode_request(value: &()) -> Result<Vec<u8>, ic_wire::Error> {
96        ic_wire::native::encode_request(Self::ID, value, Self::REQUEST_LIMITS)
97    }
98    pub fn decode_request(bytes: &[u8]) -> Result<(), ic_wire::Error> {
99        ic_wire::native::decode_request(Self::ID, bytes, Self::REQUEST_LIMITS)
100    }
101    pub fn encode_response(
102        value: &Result<SessionView, Text<256>>,
103    ) -> Result<Vec<u8>, ic_wire::Error> {
104        ic_wire::native::encode_response(Self::ID, value, Self::RESPONSE_LIMITS)
105    }
106    pub fn decode_response(bytes: &[u8]) -> Result<Result<SessionView, Text<256>>, ic_wire::Error> {
107        ic_wire::native::decode_response(Self::ID, bytes, Self::RESPONSE_LIMITS)
108    }
109}
110/// Caller-authenticated logout; no submitted proof or caller identity is trusted.
111pub struct Logout;
112impl Logout {
113    pub const ID: u64 = 0x415554480004;
114    pub const NAME: &'static str = "logout_portable_session";
115    pub const REQUEST_LIMITS: Limits = EMPTY_LIMITS;
116    pub const RESPONSE_LIMITS: Limits = REPLY_LIMITS;
117    pub fn encode_request(value: &()) -> Result<Vec<u8>, ic_wire::Error> {
118        ic_wire::native::encode_request(Self::ID, value, Self::REQUEST_LIMITS)
119    }
120    pub fn decode_request(bytes: &[u8]) -> Result<(), ic_wire::Error> {
121        ic_wire::native::decode_request(Self::ID, bytes, Self::REQUEST_LIMITS)
122    }
123    pub fn encode_response(value: &LogoutResult) -> Result<Vec<u8>, ic_wire::Error> {
124        ic_wire::native::encode_response(Self::ID, value, Self::RESPONSE_LIMITS)
125    }
126    pub fn decode_response(bytes: &[u8]) -> Result<LogoutResult, ic_wire::Error> {
127        ic_wire::native::decode_response(Self::ID, bytes, Self::RESPONSE_LIMITS)
128    }
129}