Skip to main content

PrincipalKeypair

Struct PrincipalKeypair 

Source
pub struct PrincipalKeypair { /* private fields */ }
Expand description

Client-held encryption and signing keys for one principal.

Implementations§

Source§

impl PrincipalKeypair

Source

pub fn generate( tenant_id: impl Into<String>, principal_id: impl Into<String>, kind: PrincipalKind, key_epoch: u64, ) -> Result<Self, AccessError>

Generate independent X25519 and Ed25519 keys using operating-system entropy.

Examples found in repository?
examples/enterprise_access.rs (line 13)
11fn main() -> Result<(), Box<dyn std::error::Error>> {
12    let issuer = AccessIssuer::generate("acme-admin")?;
13    let alice = PrincipalKeypair::generate("acme", "alice", PrincipalKind::User, 1)?;
14    let admin = PrincipalKeypair::generate("acme", "admin", PrincipalKind::Administrator, 1)?;
15
16    let alice_audit = RoleKeypair::generate("acme", "audit", "alice-audit", 1)?;
17    let tenant_audit = RoleKeypair::generate("acme", "audit", "tenant-audit", 1)?;
18
19    let alice_grant = AccessGrant::issue(
20        &issuer,
21        alice.principal(),
22        &alice_audit,
23        GrantSpec {
24            grant_id: "alice-audit-v1".into(),
25            scope: "audit".into(),
26            permissions: Permissions::READ | Permissions::WRITE,
27            authorization_epoch: 1,
28            not_before: 1,
29            not_after: u64::MAX,
30        },
31    )?;
32    let admin_grant = AccessGrant::issue(
33        &issuer,
34        admin.principal(),
35        &tenant_audit,
36        GrantSpec {
37            grant_id: "admin-audit-v1".into(),
38            scope: "audit".into(),
39            permissions: Permissions::READ | Permissions::OBSERVE,
40            authorization_epoch: 1,
41            not_before: 1,
42            not_after: u64::MAX,
43        },
44    )?;
45
46    let alice_state = RevocationState::issue(
47        &issuer,
48        "acme",
49        "alice",
50        "audit",
51        RevocationSpec {
52            revision: 1,
53            minimum_authorization_epoch: 1,
54            minimum_role_key_epoch: 1,
55            issued_at: 1,
56        },
57    )?;
58    let admin_state = RevocationState::issue(
59        &issuer,
60        "acme",
61        "admin",
62        "audit",
63        RevocationSpec {
64            revision: 1,
65            minimum_authorization_epoch: 1,
66            minimum_role_key_epoch: 1,
67            issued_at: 1,
68        },
69    )?;
70    let trusted = issuer.trusted();
71    let alice_role = alice_grant.open_role(
72        &alice,
73        &trusted,
74        100,
75        &alice_state.verify(&trusted, "acme", "alice", "audit")?,
76    )?;
77    let admin_role = admin_grant.open_role(
78        &admin,
79        &trusted,
80        100,
81        &admin_state.verify(&trusted, "acme", "admin", "audit")?,
82    )?;
83
84    let policy = TenantPolicy::issue(
85        &issuer,
86        alice.principal(),
87        PolicySpec {
88            revision: 1,
89            previous_hash: [0; 32],
90            authorization_epoch: 1,
91            issued_at: 1,
92            not_before: 1,
93            not_after: u64::MAX,
94            rules: vec![CapabilityRule::new(
95                CapabilityKind::Mcp,
96                "github",
97                Effect::Allow,
98            )?],
99        },
100    )?;
101    let verified = policy.verify(&trusted, "acme", "alice", 100, 1, 1)?;
102    assert_eq!(
103        verified.decision(CapabilityKind::Mcp, "github"),
104        Decision::Allow
105    );
106    assert_eq!(
107        verified.decision(CapabilityKind::Skill, "deploy"),
108        Decision::Deny
109    );
110
111    let author = Author::generate()?;
112    let event = AuditEvent {
113        tenant_id: "acme".into(),
114        subject_id: "alice".into(),
115        session_id: "session-42".into(),
116        sequence: 1,
117        timestamp: 100,
118        kind: AuditEventKind::Request,
119        media_type: "application/json".into(),
120        body: br#"{"tool":"github.search","query":"private"}"#.to_vec(),
121    };
122    let record = seal_audit_event(
123        &author,
124        AuditContext {
125            tenant_id: "acme".into(),
126            subject_id: "alice".into(),
127            stream_id: "session-42".into(),
128            epoch: 1,
129            sequence: 1,
130        },
131        &event,
132        &alice_role,
133        &admin_role,
134        fastest_payload_suite(),
135    )?;
136
137    assert_eq!(
138        open_audit_event(&record, &alice_role, author.public_key())?,
139        event
140    );
141    assert_eq!(
142        open_audit_event(&record, &admin_role, author.public_key())?,
143        event
144    );
145    println!("user and tenant administrator opened the encrypted audit event");
146    Ok(())
147}
Source

pub fn from_secret_bytes( tenant_id: impl Into<String>, principal_id: impl Into<String>, kind: PrincipalKind, key_epoch: u64, wrapping_secret: [u8; 32], signing_seed: [u8; 32], ) -> Result<Self, AccessError>

Restore deterministic client keys from two 32-byte secrets.

Source

pub const fn principal(&self) -> &Principal

Public principal descriptor.

Examples found in repository?
examples/enterprise_access.rs (line 21)
11fn main() -> Result<(), Box<dyn std::error::Error>> {
12    let issuer = AccessIssuer::generate("acme-admin")?;
13    let alice = PrincipalKeypair::generate("acme", "alice", PrincipalKind::User, 1)?;
14    let admin = PrincipalKeypair::generate("acme", "admin", PrincipalKind::Administrator, 1)?;
15
16    let alice_audit = RoleKeypair::generate("acme", "audit", "alice-audit", 1)?;
17    let tenant_audit = RoleKeypair::generate("acme", "audit", "tenant-audit", 1)?;
18
19    let alice_grant = AccessGrant::issue(
20        &issuer,
21        alice.principal(),
22        &alice_audit,
23        GrantSpec {
24            grant_id: "alice-audit-v1".into(),
25            scope: "audit".into(),
26            permissions: Permissions::READ | Permissions::WRITE,
27            authorization_epoch: 1,
28            not_before: 1,
29            not_after: u64::MAX,
30        },
31    )?;
32    let admin_grant = AccessGrant::issue(
33        &issuer,
34        admin.principal(),
35        &tenant_audit,
36        GrantSpec {
37            grant_id: "admin-audit-v1".into(),
38            scope: "audit".into(),
39            permissions: Permissions::READ | Permissions::OBSERVE,
40            authorization_epoch: 1,
41            not_before: 1,
42            not_after: u64::MAX,
43        },
44    )?;
45
46    let alice_state = RevocationState::issue(
47        &issuer,
48        "acme",
49        "alice",
50        "audit",
51        RevocationSpec {
52            revision: 1,
53            minimum_authorization_epoch: 1,
54            minimum_role_key_epoch: 1,
55            issued_at: 1,
56        },
57    )?;
58    let admin_state = RevocationState::issue(
59        &issuer,
60        "acme",
61        "admin",
62        "audit",
63        RevocationSpec {
64            revision: 1,
65            minimum_authorization_epoch: 1,
66            minimum_role_key_epoch: 1,
67            issued_at: 1,
68        },
69    )?;
70    let trusted = issuer.trusted();
71    let alice_role = alice_grant.open_role(
72        &alice,
73        &trusted,
74        100,
75        &alice_state.verify(&trusted, "acme", "alice", "audit")?,
76    )?;
77    let admin_role = admin_grant.open_role(
78        &admin,
79        &trusted,
80        100,
81        &admin_state.verify(&trusted, "acme", "admin", "audit")?,
82    )?;
83
84    let policy = TenantPolicy::issue(
85        &issuer,
86        alice.principal(),
87        PolicySpec {
88            revision: 1,
89            previous_hash: [0; 32],
90            authorization_epoch: 1,
91            issued_at: 1,
92            not_before: 1,
93            not_after: u64::MAX,
94            rules: vec![CapabilityRule::new(
95                CapabilityKind::Mcp,
96                "github",
97                Effect::Allow,
98            )?],
99        },
100    )?;
101    let verified = policy.verify(&trusted, "acme", "alice", 100, 1, 1)?;
102    assert_eq!(
103        verified.decision(CapabilityKind::Mcp, "github"),
104        Decision::Allow
105    );
106    assert_eq!(
107        verified.decision(CapabilityKind::Skill, "deploy"),
108        Decision::Deny
109    );
110
111    let author = Author::generate()?;
112    let event = AuditEvent {
113        tenant_id: "acme".into(),
114        subject_id: "alice".into(),
115        session_id: "session-42".into(),
116        sequence: 1,
117        timestamp: 100,
118        kind: AuditEventKind::Request,
119        media_type: "application/json".into(),
120        body: br#"{"tool":"github.search","query":"private"}"#.to_vec(),
121    };
122    let record = seal_audit_event(
123        &author,
124        AuditContext {
125            tenant_id: "acme".into(),
126            subject_id: "alice".into(),
127            stream_id: "session-42".into(),
128            epoch: 1,
129            sequence: 1,
130        },
131        &event,
132        &alice_role,
133        &admin_role,
134        fastest_payload_suite(),
135    )?;
136
137    assert_eq!(
138        open_audit_event(&record, &alice_role, author.public_key())?,
139        event
140    );
141    assert_eq!(
142        open_audit_event(&record, &admin_role, author.public_key())?,
143        event
144    );
145    println!("user and tenant administrator opened the encrypted audit event");
146    Ok(())
147}

Trait Implementations§

Source§

impl Debug for PrincipalKeypair

Available on crate feature client only.
Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.