| Crates.io | vultur-sso-api-client |
| lib.rs | vultur-sso-api-client |
| version | 0.3.0 |
| created_at | 2025-08-25 03:52:34.03696+00 |
| updated_at | 2025-09-19 03:43:10.58961+00 |
| description | Rust library for VULTUR SSO API client integration |
| homepage | |
| repository | https://github.com/VULTUR-org/vultur-sso-api-client |
| max_upload_size | |
| id | 1809043 |
| size | 176,360 |
A Rust library for integrating VULTUR SSO authentication in API backends. This crate provides JWT validation, authentication middleware, and .well-known endpoint serving for Axum-based web services.
Add this to your Cargo.toml:
[dependencies]
vultur-sso-api-client = "0.1.0"
axum = "0.7"
tokio = { version = "1.0", features = ["full"] }
use vultur_sso_api_client::{VulturSSOClient, Config};
use std::sync::Arc;
#[tokio::main]
async fn main() {
let config = Config::builder()
.ident_api_url("https://ident.vultur.com")
.application_name("my-api")
.build()
.unwrap();
let sso_client = Arc::new(VulturSSOClient::new(config));
}
use axum::{Router, routing::get, middleware};
use vultur_sso_api_client::auth_middleware;
async fn protected_handler() -> &'static str {
"This endpoint requires authentication!"
}
let app = Router::new()
.route("/protected", get(protected_handler))
.layer(middleware::from_fn_with_state(
sso_client.clone(),
auth_middleware
))
.with_state(sso_client);
use vultur_sso_api_client::RequireAuth;
async fn user_info_handler(RequireAuth(user): RequireAuth) -> String {
format!("Hello, {}! Address: {}", user.character_name, user.eth_address)
}
use vultur_sso_api_client::{serve_well_known, PermissionConfig, PermissionPatterns};
use chrono::Utc;
let permission_config = PermissionConfig {
application_name: "my-api".to_string(),
version: "1.0.0".to_string(),
permissions: PermissionPatterns::crud("users"),
default_permissions: vec![],
last_updated: Utc::now(),
};
let well_known_router = serve_well_known(permission_config);
let app = Router::new()
.merge(well_known_router)
.route("/users", get(list_users));
use vultur_sso_api_client::{require_permission, VulturSSOClient};
use axum::{extract::State, Json, routing::get, Router};
use std::sync::Arc;
// Define custom permission extractors
require_permission!(CanManageUsers, "users.admin");
require_permission!(CanReadData, "data.read");
async fn admin_handler(user: CanManageUsers) -> Json<serde_json::Value> {
serde_json::json!({
"message": "Admin access granted",
"user": user.user().character_name
}).into()
}
async fn read_handler(user: CanReadData) -> Json<serde_json::Value> {
serde_json::json!({
"data": ["item1", "item2", "item3"],
"accessed_by": user.user().character_name
}).into()
}
use vultur_sso_api_client::{PermissionChecker, RequireAuth, JwtToken};
use axum::extract::State;
async fn flexible_handler(
RequireAuth(user): RequireAuth,
State(sso_client): State<Arc<VulturSSOClient>>,
// JWT token is automatically available in request extensions
) -> Result<Json<serde_json::Value>, VulturSSOError> {
let checker = PermissionChecker::new(sso_client, "my-api".to_string());
// Check multiple permissions programmatically
let can_read = checker.has_permission(&user, "data.read", &token).await?;
let can_write = checker.has_permission(&user, "data.write", &token).await?;
let has_admin_role = checker.has_role(&user, "admin", &token).await?;
Ok(Json(serde_json::json!({
"permissions": {
"can_read": can_read,
"can_write": can_write,
"is_admin": has_admin_role
}
})))
}
use vultur_sso_api_client::{PermissionScopeBuilder, PermissionConfigBuilder};
let custom_permissions = vec![
PermissionScopeBuilder::new()
.id("fleet.command")
.name("Fleet Command")
.description("Command fleet operations")
.resource("fleet")
.action("command")
.build()?,
PermissionScopeBuilder::new()
.id("warehouse.manage")
.name("Warehouse Management")
.resource("warehouse")
.action("manage")
.build()?,
];
let config = PermissionConfigBuilder::new()
.application_name("fleet-manager")
.version("2.0.0")
.add_permissions(custom_permissions)
.build()?;
use std::time::Duration;
let config = Config::builder()
.ident_api_url("https://ident.vultur.com")
.application_name("my-api")
.enable_cache(true)
.cache_duration(Duration::from_secs(300)) // 5 minutes
.request_timeout(Duration::from_secs(30))
.verify_jwt_signature(false) // Set to true in production
.build()?;
use axum::{Router, routing::{get, post}};
use vultur_sso_api_client::{VulturSSOClient, Config, auth_middleware, serve_well_known};
async fn public_endpoint() -> &'static str {
"This is public"
}
async fn private_endpoint(RequireAuth(user): RequireAuth) -> String {
format!("Private data for {}", user.character_name)
}
#[tokio::main]
async fn main() {
let config = Config::builder()
.ident_api_url("https://ident.vultur.com")
.application_name("my-api")
.build()
.unwrap();
let sso_client = Arc::new(VulturSSOClient::new(config));
// Well-known endpoints (public)
let well_known_router = serve_well_known(permission_config);
// Protected routes
let protected_routes = Router::new()
.route("/private", get(private_endpoint))
.layer(middleware::from_fn_with_state(
sso_client.clone(),
auth_middleware
));
let app = Router::new()
.route("/public", get(public_endpoint))
.merge(well_known_router)
.merge(protected_routes)
.with_state(sso_client);
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000").await.unwrap();
axum::serve(listener, app).await.unwrap();
}
The library provides comprehensive error types:
use vultur_sso_api_client::{VulturSSOError, Result};
async fn my_handler() -> Result<String, VulturSSOError> {
// Errors are automatically converted to HTTP responses
Err(VulturSSOError::forbidden("Insufficient permissions"))
}
Error types include:
Unauthorized - Invalid or expired tokenForbidden - Insufficient permissionsNotFound - Resource not foundNetworkError - Communication with auth server failedConfigError - Configuration issuesJwtError - JWT parsing/validation errorsInternalError - Internal server errorsThe library includes comprehensive test utilities:
#[cfg(test)]
mod tests {
use vultur_sso_api_client::*;
#[tokio::test]
async fn test_auth_middleware() {
// Test implementation
}
}
See the examples/ directory for complete working examples:
This project is licensed under the ISC License.
For questions or issues:
Note: This library is designed to work specifically with the VULTUR SSO ecosystem. Ensure your vultur-ident-api instance is properly configured before integration.