role-system 1.1.1

A flexible and powerful role-based access control (RBAC) library for Rust applications
Documentation
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
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
# Security Integration Guide


This guide covers secure integration practices for the Role System library.

## Table of Contents


- [Authentication vs Authorization]#authentication-vs-authorization
- [JWT Integration]#jwt-integration
- [Input Validation]#input-validation
- [Error Handling]#error-handling
- [Session Management]#session-management
- [Security Headers]#security-headers
- [Audit Logging]#audit-logging
- [Best Practices]#best-practices

## Authentication vs Authorization


**Understanding the Distinction:**

- **Authentication**: Verifying the identity of a user/subject ("Who are you?")
- **Authorization**: Determining what actions a user can perform ("What can you do?")

The Role System library focuses on **authorization**. You must implement secure authentication separately.

### Integration Pattern


```rust
// 1. Authenticate the user (your responsibility)
let user_id = authenticate_user(jwt_token)?;

// 2. Use Role System for authorization (our responsibility)
let subject = Subject::user(user_id);
let resource = Resource::new_checked("document", "file")?;
let permission = Permission::new("read", "document");

let authorized = role_system.check_permission(&subject, &permission, &resource);
```

## JWT Integration


### ⚠️ Security Warning


**NEVER use the JWT examples from the middleware directory in production!** They are mock implementations that accept hardcoded tokens.

### Secure JWT Implementation


```rust
use jsonwebtoken::{decode, encode, Header, Algorithm, Validation, EncodingKey, DecodingKey};
use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize)]

struct Claims {
    sub: String,
    roles: Vec<String>,
    exp: usize,
    iat: usize,
    iss: String,
    aud: String,
}

fn decode_jwt_secure(token: &str, secret: &[u8]) -> Result<Claims, jsonwebtoken::errors::Error> {
    let validation = Validation {
        algorithms: vec![Algorithm::HS256],
        validate_exp: true,
        validate_iat: true,
        iss: Some("your-issuer".to_string()),
        aud: Some(vec!["your-audience".to_string()]),
        ..Default::default()
    };

    let decoding_key = DecodingKey::from_secret(secret);
    let token_data = decode::<Claims>(token, &decoding_key, &validation)?;
    Ok(token_data.claims)
}
```

### Required JWT Validations


1. **Signature Verification**: Use proper cryptographic algorithms (HS256, RS256, etc.)
2. **Expiration Check**: Validate `exp` claim
3. **Not Before Check**: Validate `nbf` claim if present
4. **Issued At Check**: Validate `iat` claim
5. **Issuer Verification**: Validate `iss` claim
6. **Audience Verification**: Validate `aud` claim

## Input Validation


### Resource Creation


```rust
use role_system::{Resource, Error};

// Use the secure constructor
let resource = Resource::new_checked(user_input_id, user_input_type)?;

// The library validates against:
// - Path traversal attempts ("../", "..")
// - Null characters (\0)
// - Invalid UTF-8 sequences
```

### Permission Validation


```rust
use role_system::Permission;

// Built-in validation prevents:
// - Empty actions or resources
// - Path traversal in resource names
// - Null bytes in permission strings
let permission = Permission::parse("read:documents")?;
```

## Error Handling


### Secure Error Responses


```rust
use role_system::Error;

fn handle_permission_error(error: Error) -> HttpResponse {
    match error {
        Error::PermissionDenied(_) => {
            // Log security event (without sensitive details)
            log::warn!("Permission denied for operation");

            // Return generic error to client
            HttpResponse::Forbidden().json(json!({
                "error": "Access denied",
                "code": "PERMISSION_DENIED"
            }))
        },
        Error::ValidationError { field, reason, .. } => {
            // Log validation failure
            log::warn!("Validation failed for field '{}': {}", field, reason);

            // Return validation error (safe to expose)
            HttpResponse::BadRequest().json(json!({
                "error": "Invalid input",
                "field": field,
                "code": "VALIDATION_ERROR"
            }))
        },
        _ => {
            // Log internal error
            log::error!("Internal error: {}", error);

            // Return generic error
            HttpResponse::InternalServerError().json(json!({
                "error": "Internal server error",
                "code": "INTERNAL_ERROR"
            }))
        }
    }
}
```

### Error Logging Security


**Do not log sensitive information:**

- User passwords or tokens
- Permission details in public logs
- Full stack traces to external services

**Do log security events:**

- Failed authentication attempts
- Permission denials
- Unusual access patterns
- System errors (in secure logs)

## Session Management


### Token Lifecycle


```rust
use std::time::{SystemTime, UNIX_EPOCH};

struct SecureSession {
    user_id: String,
    roles: Vec<String>,
    issued_at: u64,
    expires_at: u64,
    session_id: String,
}

impl SecureSession {
    fn is_valid(&self) -> bool {
        let now = SystemTime::now()
            .duration_since(UNIX_EPOCH)
            .unwrap()
            .as_secs();

        now < self.expires_at
    }

    fn should_refresh(&self) -> bool {
        let now = SystemTime::now()
            .duration_since(UNIX_EPOCH)
            .unwrap()
            .as_secs();

        // Refresh if more than half the session time has passed
        let session_duration = self.expires_at - self.issued_at;
        now > self.issued_at + (session_duration / 2)
    }
}
```

### Session Security


1. **Short Expiration Times**: Max 1-4 hours for sensitive applications
2. **Automatic Refresh**: Refresh tokens before expiration
3. **Secure Storage**: Store session tokens in HTTP-only cookies
4. **Session Invalidation**: Implement logout and session revocation
5. **Concurrent Session Limits**: Prevent session hijacking

## Security Headers


### Required Headers


```rust
use actix_web::HttpResponse;

fn add_security_headers(mut response: HttpResponse) -> HttpResponse {
    response.headers_mut().insert(
        "X-Content-Type-Options",
        "nosniff".parse().unwrap()
    );
    response.headers_mut().insert(
        "X-Frame-Options",
        "DENY".parse().unwrap()
    );
    response.headers_mut().insert(
        "X-XSS-Protection",
        "1; mode=block".parse().unwrap()
    );
    response.headers_mut().insert(
        "Strict-Transport-Security",
        "max-age=31536000; includeSubDomains".parse().unwrap()
    );
    response.headers_mut().insert(
        "Content-Security-Policy",
        "default-src 'self'".parse().unwrap()
    );

    response
}
```

## Audit Logging


### Security Event Logging


```rust
use serde_json::json;
use tracing::{info, warn, error};

fn log_permission_check(
    subject: &Subject,
    permission: &Permission,
    resource: &Resource,
    granted: bool,
    request_id: &str,
) {
    let event = json!({
        "event_type": "permission_check",
        "subject_id": subject.id(),
        "subject_type": subject.subject_type(),
        "permission": permission.to_string(),
        "resource_id": resource.id(),
        "resource_type": resource.resource_type(),
        "granted": granted,
        "timestamp": chrono::Utc::now().to_rfc3339(),
        "request_id": request_id,
    });

    if granted {
        info!("Permission granted: {}", event);
    } else {
        warn!("Permission denied: {}", event);
    }
}

fn log_role_assignment(
    subject: &Subject,
    role: &Role,
    granted_by: &str,
    request_id: &str,
) {
    let event = json!({
        "event_type": "role_assignment",
        "subject_id": subject.id(),
        "role_name": role.name(),
        "granted_by": granted_by,
        "timestamp": chrono::Utc::now().to_rfc3339(),
        "request_id": request_id,
    });

    info!("Role assigned: {}", event);
}
```

### Audit Requirements


For compliance (SOX, GDPR, HIPAA), ensure you log:

1. **Authentication Events**: Login, logout, failed attempts
2. **Authorization Events**: Permission grants/denials
3. **Administrative Actions**: Role assignments, system changes
4. **Data Access**: Sensitive resource access
5. **System Events**: Errors, security violations

## Best Practices


### 1. Principle of Least Privilege


```rust
// Good: Specific permissions
let read_permission = Permission::new("read", "user_profile");
let edit_permission = Permission::new("edit", "own_profile");

// Bad: Overly broad permissions
let admin_permission = Permission::new("*", "*");
```

### 2. Defense in Depth


```rust
// Layer 1: Authentication
let user = authenticate_jwt(&token)?;

// Layer 2: Rate limiting
rate_limiter.check_rate_limit(&user.id)?;

// Layer 3: Authorization
let authorized = role_system.check_permission(&user.subject, &permission, &resource);

// Layer 4: Resource-level validation
validate_resource_access(&resource, &user)?;
```

### 3. Secure Configuration


```rust
use role_system::RoleSystemBuilder;

let role_system = RoleSystemBuilder::new()
    .with_storage(secure_storage)
    .with_cache_ttl(300) // 5 minutes
    .with_max_role_depth(5) // Prevent deep hierarchies
    .with_audit_logging(true)
    .build()?;
```

### 4. Input Sanitization


```rust
fn sanitize_input(input: &str) -> Result<String, Error> {
    // Remove null bytes
    let clean = input.replace('\0', "");

    // Check length
    if clean.len() > 1000 {
        return Err(Error::ValidationError {
            field: "input".to_string(),
            reason: "Input too long".to_string(),
            invalid_value: Some(clean),
        });
    }

    // Validate UTF-8
    if !clean.is_ascii() {
        return Err(Error::ValidationError {
            field: "input".to_string(),
            reason: "Invalid characters".to_string(),
            invalid_value: Some(clean),
        });
    }

    Ok(clean)
}
```

### 5. Secure Defaults


- Use HTTPS in production
- Enable audit logging
- Set conservative cache TTLs
- Limit role hierarchy depth
- Use strong authentication
- Implement rate limiting
- Validate all inputs
- Log security events

### 6. Regular Security Reviews


- Review role assignments quarterly
- Audit permission grants monthly
- Monitor for unusual access patterns
- Update dependencies regularly
- Conduct penetration testing
- Review security logs daily

## Common Vulnerabilities


### Avoid These Patterns


```rust
// ❌ Never do this - exposes system to path traversal
let resource = Resource::new("../../../etc/passwd", "file");

// ❌ Never do this - accepts any token
fn decode_jwt_insecure(token: &str) -> Claims {
    // This is what the examples do - DO NOT USE
    Claims { sub: "user".to_string(), ..Default::default() }
}

// ❌ Never do this - logs sensitive data
log::info!("User {} failed to access {}", password, secret_resource);

// ❌ Never do this - generic admin permission
let admin_role = Role::new("admin").add_permission(Permission::new("*", "*"));
```

### Secure Alternatives


```rust
// ✅ Use validated resource creation
let resource = Resource::new_checked(sanitized_id, sanitized_type)?;

// ✅ Use proper JWT validation
let claims = decode_jwt_secure(&token, &secret_key)?;

// ✅ Log security events safely
log::warn!("Permission denied for user {} on resource type {}",
    user_id, resource.resource_type());

// ✅ Use specific permissions
let admin_role = Role::new("admin")
    .add_permission(Permission::new("manage", "users"))
    .add_permission(Permission::new("read", "system_logs"));
```

## Support


For security questions or to report vulnerabilities:

- Email: <security@role-system.dev>
- Security Policy: See [SECURITY.md]../SECURITY.md
- Documentation: [docs/]./README.md

---

**Remember**: Security is a shared responsibility. This library provides authorization tools, but you must implement authentication, secure communication, and proper deployment practices.