use scim_server::{
auth::{
AuthenticatedRequestContext, AuthenticationValidator, Credential, LinearCredential,
Unauthenticated,
},
providers::StandardResourceProvider,
resource::{IsolationLevel, ResourceProvider, TenantContext, TenantPermissions},
storage::InMemoryStorage,
};
use serde_json::json;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("🔐 Compile-Time Authentication Example");
println!("{}", "=".repeat(60));
println!("\n🏗️ Step 1: Setting up authentication system");
let validator = setup_authentication_system().await;
println!("\n🛡️ Step 2: Compile-time authentication safety");
demonstrate_compile_time_safety(&validator).await?;
println!("\n🔄 Step 3: Linear credential lifecycle");
demonstrate_linear_credentials(&validator).await?;
println!("\n📊 Step 4: Type-safe provider operations");
demonstrate_authenticated_operations(&validator).await?;
println!("\n❌ Step 5: Impossible states (compile-time prevention)");
demonstrate_impossible_states();
println!("\n✅ Compile-time authentication example completed!");
println!("All authentication is enforced at compile time with zero runtime cost.");
Ok(())
}
async fn setup_authentication_system() -> AuthenticationValidator {
let validator = AuthenticationValidator::new();
let enterprise_permissions = TenantPermissions {
can_create: true,
can_read: true,
can_update: true,
can_delete: true,
can_list: true,
max_users: Some(1000),
max_groups: Some(100),
};
let enterprise_tenant = TenantContext::new(
"enterprise-corp".to_string(),
"enterprise-client-123".to_string(),
)
.with_isolation_level(IsolationLevel::Strict)
.with_permissions(enterprise_permissions);
validator
.register_credential("ent-secure-key-456", enterprise_tenant)
.await;
let startup_permissions = TenantPermissions {
can_create: true,
can_read: true,
can_update: true,
can_delete: false, can_list: true,
max_users: Some(50),
max_groups: Some(10),
};
let startup_tenant =
TenantContext::new("startup-inc".to_string(), "startup-client-789".to_string())
.with_isolation_level(IsolationLevel::Standard)
.with_permissions(startup_permissions);
validator
.register_credential("startup-api-key", startup_tenant)
.await;
println!("✅ Registered 2 tenant credentials");
println!(" - enterprise-corp: Full permissions, 1000 user limit");
println!(" - startup-inc: No delete, 50 user limit");
validator
}
async fn demonstrate_compile_time_safety(
validator: &AuthenticationValidator,
) -> Result<(), Box<dyn std::error::Error>> {
println!("🔍 Testing compile-time authentication guarantees...");
let raw_credential = Credential::<Unauthenticated>::new("ent-secure-key-456");
println!(
" ✅ Created unauthenticated credential: {}",
raw_credential.raw_value()
);
let linear_cred = LinearCredential::new("ent-secure-key-456");
let witness = validator.authenticate(linear_cred).await?;
println!(" ✅ Authentication successful - received witness");
let auth_context = AuthenticatedRequestContext::from_witness(witness);
println!(
" ✅ Created authenticated context for tenant: {}",
auth_context.tenant_id()
);
let authority = auth_context.authority();
println!(
" ✅ Authority proven for client: {}",
authority.client_id()
);
println!(" ✅ Validated at: {}", authority.witness().validated_at());
Ok(())
}
async fn demonstrate_linear_credentials(
validator: &AuthenticationValidator,
) -> Result<(), Box<dyn std::error::Error>> {
println!("🔄 Testing linear credential consumption...");
let linear_cred = LinearCredential::new("startup-api-key");
println!(" ✅ Created linear credential");
println!(" ✅ Is consumed: {}", linear_cred.is_consumed());
let witness = validator.authenticate(linear_cred).await?;
println!(" ✅ Authentication consumed the credential");
let auth_context = AuthenticatedRequestContext::from_witness(witness);
println!(" ✅ Created context for: {}", auth_context.tenant_id());
Ok(())
}
async fn demonstrate_authenticated_operations(
validator: &AuthenticationValidator,
) -> Result<(), Box<dyn std::error::Error>> {
println!("📊 Testing type-safe provider operations...");
let storage = InMemoryStorage::new();
let provider = StandardResourceProvider::new(storage);
let enterprise_cred = LinearCredential::new("ent-secure-key-456");
let enterprise_witness = validator.authenticate(enterprise_cred).await?;
let enterprise_context = AuthenticatedRequestContext::from_witness(enterprise_witness);
println!(" ✅ Enterprise client authenticated");
let ceo_data = json!({
"userName": "john.ceo",
"displayName": "John Smith (CEO)",
"emails": [{"value": "john@enterprise-corp.com", "primary": true}],
"title": "Chief Executive Officer"
});
let ceo = provider
.create_resource("User", ceo_data, enterprise_context.request_context())
.await?;
println!(
" ✅ Created CEO: {} (authenticated)",
ceo.get_username().unwrap()
);
let cto_data = json!({
"userName": "jane.cto",
"displayName": "Jane Doe (CTO)",
"emails": [{"value": "jane@enterprise-corp.com", "primary": true}],
"title": "Chief Technology Officer"
});
let _cto = provider
.create_resource("User", cto_data, enterprise_context.request_context())
.await?;
println!(" ✅ Created CTO: jane.cto (authenticated)");
let startup_cred = LinearCredential::new("startup-api-key");
let startup_witness = validator.authenticate(startup_cred).await?;
let startup_context = AuthenticatedRequestContext::from_witness(startup_witness);
println!(" ✅ Startup client authenticated");
let founder_data = json!({
"userName": "alice.founder",
"displayName": "Alice Johnson (Founder)",
"emails": [{"value": "alice@startup-inc.com", "primary": true}]
});
let _founder = provider
.create_resource("User", founder_data, startup_context.request_context())
.await?;
println!(" ✅ Created founder: alice.founder (authenticated)");
let enterprise_users = provider
.list_resources("User", None, enterprise_context.request_context())
.await?;
let startup_users = provider
.list_resources("User", None, startup_context.request_context())
.await?;
println!(
" 📊 Enterprise users: {} (isolated)",
enterprise_users.len()
);
println!(" 📊 Startup users: {} (isolated)", startup_users.len());
println!(" ✅ Each authenticated context only sees their own tenant's data");
println!(" ✅ Cross-tenant access is impossible at compile time");
Ok(())
}
fn demonstrate_impossible_states() {
println!("❌ Testing impossible states (these won't compile)...");
println!(" ✅ Cannot create authenticated credentials without validation");
let _unauth = Credential::<Unauthenticated>::new("test");
println!(" ✅ Cannot access authenticated methods on unauth credentials");
println!(" ✅ Cannot create authenticated context without witness");
println!(" ✅ Cannot reuse consumed credentials (linear types)");
println!(" ✅ Cannot bypass authentication system");
println!("\n🎯 Key Compile-Time Guarantees:");
println!(" • Unauthenticated access is unrepresentable");
println!(" • Credentials must be validated before use");
println!(" • Authentication witnesses cannot be forged");
println!(" • Tenant contexts are guaranteed valid");
println!(" • Linear credentials prevent reuse");
println!(" • Zero runtime authentication overhead");
}
fn _secure_scim_provider_example() {}