1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
//! # beep-authz
//!
//! A Rust authorization library with SpiceDB integration for fine-grained permissions.
//!
//! This crate provides a high-level, type-safe interface to [SpiceDB](https://github.com/authzed/spicedb),
//! a Google Zanzibar-inspired authorization system. It enables relationship-based access control
//! (ReBAC) for your Rust applications with minimal boilerplate.
//!
//! ## Features
//!
//! - **SpiceDB Integration** - Native support for SpiceDB/AuthZed with gRPC
//! - **Type Safety** - Strongly-typed permissions and objects
//! - **Async/Await** - Built on Tokio for high-performance async operations
//! - **Easy to Use** - Simple API for checking permissions
//!
//! ## Quick Start
//!
//! ```no_run
//! use authz::{SpiceDbRepository, SpiceDbConfig, SpiceDbObject, Permissions};
//!
//! #[tokio::main]
//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
//! // Configure connection to SpiceDB
//! let config = SpiceDbConfig {
//! endpoint: "localhost:50051".to_string(),
//! token: Some("your-preshared-key".to_string()),
//! };
//!
//! // Create repository
//! let authz = SpiceDbRepository::new(config).await?;
//!
//! // Check permissions
//! let result = authz.check_permissions(
//! SpiceDbObject::Channel("channel-123".to_string()),
//! Permissions::ViewChannels,
//! SpiceDbObject::User("user-456".to_string()),
//! ).await;
//!
//! if result.has_permissions() {
//! println!("Access granted!");
//! } else {
//! println!("Access denied!");
//! }
//!
//! Ok(())
//! }
//! ```
//!
//! ## Permission Checking
//!
//! The main functionality is provided by [`SpiceDbRepository`], which offers two methods
//! for checking permissions:
//!
//! - [`SpiceDbRepository::check_permissions`] - High-level, type-safe API
//! - [`SpiceDbRepository::check_permissions_raw`] - Lower-level API for advanced use cases
//!
//! ## Permission Types
//!
//! The [`Permissions`] enum defines all available permission types:
//!
//! - Administrator, ManageServer, ManageRoles
//! - CreateInvitation, ManageChannels, ManageWebhooks
//! - ViewChannels, SendMessages, AttachFiles
//! - ManageNicknames, ChangeNickname, ManageMessages
//!
//! ## Object Types
//!
//! The [`SpiceDbObject`] enum represents different resource types:
//!
//! - `Server` - A server/workspace
//! - `Channel` - A communication channel
//! - `User` - A user/subject
//! - `PermissionOverride` - A permission override rule
//!
//! ## Configuration
//!
//! Configure your SpiceDB connection using [`SpiceDbConfig`], which supports:
//! - Manual configuration
//! - Environment variables (`SPICEDB_ENDPOINT`, `SPICEDB_TOKEN`)
//! - Command-line arguments (via clap)
//!
//! ## Error Handling
//!
//! The crate defines [`AuthorizationError`] for authorization failures:
//! - `Unauthorized` - Permission denied
//! - `ConnectionError` - Failed to connect to SpiceDB
//!
//! ## Examples
//!
//! ### Checking Administrative Access
//!
//! ```no_run
//! # use authz::{SpiceDbRepository, SpiceDbObject, Permissions};
//! # async fn example(repo: SpiceDbRepository) {
//! let is_admin = repo.check_permissions(
//! SpiceDbObject::Server("my-server".to_string()),
//! Permissions::Administrator,
//! SpiceDbObject::User("user-123".to_string()),
//! ).await.has_permissions();
//!
//! if is_admin {
//! // Grant full access
//! }
//! # }
//! ```
//!
//! ### Using Result for Error Propagation
//!
//! ```no_run
//! # use authz::{SpiceDbRepository, SpiceDbObject, Permissions, AuthorizationError};
//! # async fn example(repo: SpiceDbRepository) -> Result<(), AuthorizationError> {
//! repo.check_permissions(
//! SpiceDbObject::Channel("private".to_string()),
//! Permissions::SendMessages,
//! SpiceDbObject::User("user-456".to_string()),
//! ).await.result()?;
//!
//! // Code here only runs if permission is granted
//! println!("User can send messages");
//! # Ok(())
//! # }
//! ```
// Include the generated protobuf code
// Re-export commonly used types for convenience
pub use ;
use Error;
/// Configuration module for SpiceDB connection settings.
///
/// Contains [`SpiceDbConfig`] for configuring endpoint and authentication.
/// gRPC authentication interceptor for SpiceDB.
///
/// Internal module that handles token-based authentication for gRPC requests.
/// Object type definitions for SpiceDB resources.
///
/// Contains [`SpiceDbObject`] enum representing different resource types.
/// Permission types and authorization result handling.
///
/// Contains [`Permissions`] enum and [`AuthorizationResult`] for working with
/// permission check results.
/// SpiceDB repository and client implementation.
///
/// Contains [`SpiceDbRepository`] which provides the main API for checking permissions.
// Re-export main types for convenience
pub use SpiceDbConfig;
pub use SpiceDbObject;
pub use ;
pub use SpiceDbRepository;
/// Errors that can occur during authorization operations.
///
/// # Variants
///
/// - [`Unauthorized`](AuthorizationError::Unauthorized) - The subject does not have permission to access the resource
/// - [`ConnectionError`](AuthorizationError::ConnectionError) - Failed to establish or maintain connection to SpiceDB