token_verification/
token_verification.rs1use biscuit_auth::macros::biscuit;
2use hessra_token::{
3 add_service_node_attenuation, biscuit_key_from_string, decode_token, encode_token,
4 verify_service_chain_token, verify_token, KeyPair, ServiceNode, TokenError,
5};
6use std::sync::Arc;
7fn main() -> Result<(), TokenError> {
8 let root_keypair = Arc::new(KeyPair::new());
10 let token_base64 = generate_example_token(root_keypair.clone())?;
11 println!("Generated token: {}\n", token_base64);
12
13 println!("Example 1: Basic verification");
15 verify_token(&token_base64, root_keypair.public(), "alice", "resource1")?;
16 println!("✅ Basic verification successful\n");
17
18 println!("Example 2: Service chain verification");
20
21 let service1_keypair = KeyPair::new();
23 let service1_pk_hex = hex::encode(service1_keypair.public().to_bytes());
24 let service1_public_key = format!("ed25519/{}", service1_pk_hex);
25
26 let service2_keypair = KeyPair::new();
27 let service2_pk_hex = hex::encode(service2_keypair.public().to_bytes());
28 let service2_public_key = format!("ed25519/{}", service2_pk_hex);
29
30 let service_nodes = vec![
32 ServiceNode {
33 component: "node1".to_string(),
34 public_key: service1_public_key.clone(),
35 },
36 ServiceNode {
37 component: "node2".to_string(),
38 public_key: service2_public_key.clone(),
39 },
40 ];
41
42 let chain_token = generate_service_chain_token(
44 root_keypair.clone(),
45 service1_public_key,
46 service2_public_key,
47 )?;
48
49 let attenuated_token = add_service_node_attenuation(
51 decode_token(&chain_token)?,
52 root_keypair.public(),
53 "resource1",
54 &service1_keypair,
55 )?;
56
57 let attenuated_token2 = add_service_node_attenuation(
59 attenuated_token,
60 root_keypair.public(),
61 "resource1",
62 &service2_keypair,
63 )?;
64
65 verify_service_chain_token(
67 &encode_token(&attenuated_token2),
68 root_keypair.public(),
69 "alice",
70 "resource1",
71 service_nodes,
72 None,
73 )?;
74 println!("✅ Service chain verification successful\n");
75
76 println!("Example 3: Verification with key from string");
78
79 let pk_hex = hex::encode(root_keypair.public().to_bytes());
81 let pk_str = format!("ed25519/{}", pk_hex);
82 let parsed_pk = biscuit_key_from_string(pk_str)?;
83
84 verify_token(&token_base64, parsed_pk, "alice", "resource1")?;
86 println!("✅ Verification with key from string successful");
87
88 Ok(())
89}
90
91fn generate_example_token(keypair: Arc<KeyPair>) -> Result<String, TokenError> {
93 let biscuit_builder = biscuit!(
95 r#"
96 // Grant rights to alice for resource1
97 right("alice", "resource1", "read");
98 right("alice", "resource1", "write");
99 "#
100 );
101
102 let biscuit = biscuit_builder
104 .build(&keypair)
105 .map_err(TokenError::biscuit_error)?;
106
107 let token_bytes = biscuit.to_vec().map_err(TokenError::biscuit_error)?;
108
109 Ok(encode_token(&token_bytes))
111}
112
113fn generate_service_chain_token(
115 root_keypair: Arc<KeyPair>,
116 service1_public_key: String,
117 service2_public_key: String,
118) -> Result<String, TokenError> {
119 let biscuit_builder = biscuit!(
121 r#"
122 // Basic rights
123 right("alice", "resource1", "read");
124 right("alice", "resource1", "write");
125
126 // Service nodes
127 node($s, "node1") <- service($s) trusting authority, {node1_public_key};
128 node($s, "node2") <- service($s) trusting authority, {node2_public_key};
129 "#,
130 node1_public_key = biscuit_key_from_string(service1_public_key)?,
131 node2_public_key = biscuit_key_from_string(service2_public_key)?,
132 );
133
134 let biscuit = biscuit_builder
136 .build(&root_keypair)
137 .map_err(TokenError::biscuit_error)?;
138
139 let token_bytes = biscuit.to_vec().map_err(TokenError::biscuit_error)?;
140
141 Ok(encode_token(&token_bytes))
143}