use crate::dto::{prelude::*, rpc::RootRequestMetadata};
#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub enum DelegationAudience {
Canister(Principal),
CanicSubnet(Principal),
Project(String),
}
#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct DelegatedRoleGrant {
pub target: CanisterRole,
pub scopes: Vec<String>,
}
#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub enum RootProof {
IcCanisterSignatureV1(IcCanisterSignatureProofV1),
}
#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub enum IssuerProof {
IcCanisterSignatureV1(IcCanisterSignatureProofV1),
}
#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct IcCanisterSignatureProofV1 {
pub signature_cbor: Vec<u8>,
pub public_key_der: Vec<u8>,
}
#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub enum IssuerProofAlgorithm {
IcCanisterSignatureV1,
}
#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub enum IssuerProofBinding {
IcCanisterSignatureV1 { seed_hash: [u8; 32] },
}
#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct DelegationCert {
pub root_pid: Principal,
pub issuer_pid: Principal,
pub issuer_proof_alg: IssuerProofAlgorithm,
pub issuer_proof_binding_hash: [u8; 32],
pub issuer_proof_binding: IssuerProofBinding,
pub issuer_signer_generation: Option<u64>,
pub issued_at_ns: u64,
pub not_before_ns: u64,
pub expires_at_ns: u64,
pub max_token_ttl_ns: u64,
pub aud: DelegationAudience,
pub grants: Vec<DelegatedRoleGrant>,
}
#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct DelegationProof {
pub cert: DelegationCert,
pub root_proof: RootProof,
}
#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct ActiveDelegationProof {
pub proof: DelegationProof,
pub cert_hash: [u8; 32],
pub not_before_ns: u64,
pub expires_at_ns: u64,
pub refresh_after_ns: u64,
pub installed_at_ns: u64,
pub installed_by: Principal,
}
#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct InstallActiveDelegationProofRequest {
pub proof: DelegationProof,
}
#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct InstallActiveDelegationProofResponse {
pub active_proof: ActiveDelegationProof,
}
#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct DelegatedTokenClaims {
pub subject: Principal,
pub issuer_pid: Principal,
pub cert_hash: [u8; 32],
pub issued_at_ns: u64,
pub expires_at_ns: u64,
pub aud: DelegationAudience,
pub grants: Vec<DelegatedRoleGrant>,
pub nonce: [u8; 16],
#[serde(default)]
pub ext: Option<Vec<u8>>,
}
#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct DelegatedToken {
pub claims: DelegatedTokenClaims,
pub proof: DelegationProof,
pub issuer_proof: IssuerProof,
}
#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct AuthRequestMetadata {
pub request_id: [u8; 32],
pub ttl_ns: u64,
}
#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct DelegationProofIssueRequest {
#[serde(default)]
pub metadata: Option<AuthRequestMetadata>,
pub issuer_pid: Principal,
pub aud: DelegationAudience,
pub grants: Vec<DelegatedRoleGrant>,
pub cert_ttl_ns: u64,
}
#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct DelegationProofPrepareResponse {
pub cert: DelegationCert,
pub cert_hash: [u8; 32],
pub retrieval_expires_at_ns: u64,
}
#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct DelegationProofGetRequest {
pub cert_hash: [u8; 32],
}
#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct DelegatedTokenPrepareRequest {
#[serde(default)]
pub metadata: Option<AuthRequestMetadata>,
pub subject: Principal,
pub aud: DelegationAudience,
pub grants: Vec<DelegatedRoleGrant>,
pub ttl_ns: u64,
#[serde(default)]
pub ext: Option<Vec<u8>>,
}
#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct DelegatedTokenPrepareResponse {
pub claims: DelegatedTokenClaims,
pub claims_hash: [u8; 32],
pub retrieval_expires_at_ns: u64,
}
#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct DelegatedTokenGetRequest {
pub claims_hash: [u8; 32],
}
#[derive(CandidType, Clone, Debug, Deserialize)]
pub struct RoleAttestationRequest {
pub subject: Principal,
pub role: CanisterRole,
#[serde(default)]
pub subnet_id: Option<Principal>,
pub audience: Principal,
pub ttl_ns: u64,
pub epoch: u64,
#[serde(default)]
pub metadata: Option<RootRequestMetadata>,
}
#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct RoleAttestation {
pub subject: Principal,
pub role: CanisterRole,
#[serde(default)]
pub subnet_id: Option<Principal>,
pub audience: Principal,
pub issued_at_ns: u64,
pub expires_at_ns: u64,
pub epoch: u64,
}
#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct RoleAttestationPrepareResponse {
pub payload: RoleAttestation,
pub payload_hash: [u8; 32],
pub retrieval_expires_at_ns: u64,
}
#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct RoleAttestationGetRequest {
pub payload_hash: [u8; 32],
}
#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct SignedRoleAttestation {
pub payload: RoleAttestation,
pub root_proof: RootProof,
}
#[cfg(test)]
mod tests {
#[test]
fn auth_dtos_remain_passive_boundary_types() {
let source = include_str!("auth.rs");
let production_source = source
.split("#[cfg(test)]")
.next()
.expect("production source exists");
for marker in [
"impl DelegatedToken",
"impl DelegatedTokenClaims",
"impl RoleAttestation",
"impl SignedRoleAttestation",
"fn verify",
"fn sign",
"fn resolve",
"fn replay",
"fn consume",
"fn policy",
"fn validate",
] {
assert!(
!production_source.contains(marker),
"auth DTOs must stay passive; found marker `{marker}`"
);
}
}
}