pub struct TenantPolicy { /* private fields */ }Expand description
Canonical administrator-signed capability policy for one subject.
Implementations§
Source§impl TenantPolicy
impl TenantPolicy
Sourcepub fn issue(
issuer: &AccessIssuer,
subject: &Principal,
spec: PolicySpec,
) -> Result<Self, AccessError>
pub fn issue( issuer: &AccessIssuer, subject: &Principal, spec: PolicySpec, ) -> Result<Self, AccessError>
Issue and sign a canonical default-deny policy.
Examples found in repository?
examples/enterprise_access.rs (lines 84-100)
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}Sourcepub fn subject_id(&self) -> &str
pub fn subject_id(&self) -> &str
Subject identifier authenticated by the signature.
Authorization epoch carried by this policy.
Sourcepub fn policy_hash(&self) -> [u8; 32]
pub fn policy_hash(&self) -> [u8; 32]
Domain-separated hash used to link policy revisions.
Sourcepub fn decode(
bytes: &[u8],
limits: &AccessValidationPolicy,
) -> Result<Self, AccessError>
pub fn decode( bytes: &[u8], limits: &AccessValidationPolicy, ) -> Result<Self, AccessError>
Decode, structurally validate, and verify signature math.
Sourcepub fn verify<'a>(
&'a self,
trusted: &TrustedIssuer,
expected_tenant: &str,
expected_subject: &str,
now: u64,
minimum_revision: u64,
minimum_authorization_epoch: u64,
) -> Result<VerifiedPolicy<'a>, AccessError>
pub fn verify<'a>( &'a self, trusted: &TrustedIssuer, expected_tenant: &str, expected_subject: &str, now: u64, minimum_revision: u64, minimum_authorization_epoch: u64, ) -> Result<VerifiedPolicy<'a>, AccessError>
Verify trust, routing, freshness, and time before policy evaluation.
Examples found in repository?
examples/enterprise_access.rs (line 101)
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 Clone for TenantPolicy
impl Clone for TenantPolicy
Source§fn clone(&self) -> TenantPolicy
fn clone(&self) -> TenantPolicy
Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
Performs copy-assignment from
source. Read moreSource§impl Debug for TenantPolicy
impl Debug for TenantPolicy
impl Eq for TenantPolicy
Source§impl PartialEq for TenantPolicy
impl PartialEq for TenantPolicy
impl StructuralPartialEq for TenantPolicy
Auto Trait Implementations§
impl Freeze for TenantPolicy
impl RefUnwindSafe for TenantPolicy
impl Send for TenantPolicy
impl Sync for TenantPolicy
impl Unpin for TenantPolicy
impl UnsafeUnpin for TenantPolicy
impl UnwindSafe for TenantPolicy
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more