token_attenuation/
token_attenuation.rs1use biscuit_auth::macros::biscuit;
2use hessra_token::{
3 add_service_node_attenuation, decode_token, encode_token, verify_token, KeyPair, TokenError,
4};
5
6fn main() -> Result<(), TokenError> {
7 let (token_base64, root_keypair) = generate_example_token()?;
9 println!("Original token: {}\n", token_base64);
10
11 let service_keypair = KeyPair::new();
13
14 let token_bytes = decode_token(&token_base64)?;
16
17 println!("Adding service node attenuation...");
19 let attenuated_token = add_service_node_attenuation(
20 token_bytes,
21 root_keypair.public(),
22 "my-service",
23 &service_keypair,
24 )?;
25
26 let attenuated_token_base64 = encode_token(&attenuated_token);
28 println!("Attenuated token: {}\n", attenuated_token_base64);
29
30 println!("Verifying attenuated token...");
32 verify_token(
33 &attenuated_token_base64,
34 root_keypair.public(),
35 "alice",
36 "resource1",
37 )?;
38 println!("✅ Verification successful for attenuated token");
39
40 println!("\nCreating a chain of attenuations...");
42 let token_with_chain = create_attenuation_chain(&token_base64, &root_keypair)?;
43 println!("Token with attenuation chain: {}", token_with_chain);
44
45 println!("\nVerifying token with attenuation chain...");
47 verify_token(
48 &token_with_chain,
49 root_keypair.public(),
50 "alice",
51 "resource1",
52 )?;
53 println!("✅ Verification successful for token with attenuation chain");
54
55 Ok(())
56}
57
58fn generate_example_token() -> Result<(String, KeyPair), TokenError> {
60 let keypair = KeyPair::new();
62
63 let biscuit_builder = biscuit!(
65 r#"
66 // Grant rights to alice for resource1
67 right("alice", "resource1", "read");
68 right("alice", "resource1", "write");
69 "#
70 );
71
72 let biscuit = biscuit_builder
74 .build(&keypair)
75 .map_err(TokenError::biscuit_error)?;
76
77 let token_bytes = biscuit.to_vec().map_err(TokenError::biscuit_error)?;
78
79 Ok((encode_token(&token_bytes), keypair))
81}
82
83fn create_attenuation_chain(
85 token_base64: &str,
86 root_keypair: &KeyPair,
87) -> Result<String, TokenError> {
88 let mut token_bytes = decode_token(token_base64)?;
90
91 let service_names = ["service-1", "service-2", "service-3"];
93
94 for service_name in service_names.iter() {
96 println!(" Adding attestation for {}", service_name);
97
98 let service_keypair = KeyPair::new();
100
101 token_bytes = add_service_node_attenuation(
103 token_bytes,
104 root_keypair.public(),
105 service_name,
106 &service_keypair,
107 )?;
108 }
109
110 Ok(encode_token(&token_bytes))
112}