| Crates.io | hodei-authz-postgres |
| lib.rs | hodei-authz-postgres |
| version | 0.1.0 |
| created_at | 2025-10-17 20:59:40.71519+00 |
| updated_at | 2025-10-17 20:59:40.71519+00 |
| description | PostgreSQL policy store adapter for Hodei authorization framework |
| homepage | https://github.com/Rubentxu/hodei-policies |
| repository | https://github.com/Rubentxu/hodei-policies |
| max_upload_size | |
| id | 1888422 |
| size | 92,762 |
PostgreSQL adapter for the Hodei authorization framework.
hodei-authz-sdk-authz-postgres provides a production-ready PostgreSQL implementation of the PolicyStore trait from hodei-authz-sdk-authz. It handles policy persistence, CRUD operations, and includes database migrations.
[dependencies]
hodei-authz-sdk-authz-postgres = "0.1"
sqlx = { version = "0.8", features = ["runtime-tokio-rustls", "postgres"] }
use hodei_postgres::PostgresPolicyStore;
use hodei_authz::PolicyStore;
use sqlx::PgPool;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create database connection pool
let pool = PgPool::connect("postgres://user:pass@localhost/db").await?;
// Create policy store
let store = PostgresPolicyStore::new(pool);
// Run migrations
store.migrate().await?;
Ok(())
}
use hodei_authz::PolicyStore;
let policy_content = r#"
permit(
principal == User::"alice",
action == Action::"read",
resource
);
"#;
let policy_id = store.create_policy(policy_content.to_string()).await?;
println!("Created policy: {}", policy_id);
use hodei_authz::PolicyStore;
// Load all policies as a Cedar PolicySet
let policy_set = store.load_all_policies().await?;
// Use with Cedar Authorizer
use cedar_policy::{Authorizer, Request, Entities};
let authorizer = Authorizer::new();
let decision = authorizer.is_authorized(&request, &policy_set, &entities);
use hodei_authz::PolicyStore;
// Get a policy
let policy = store.get_policy(&policy_id).await?;
// List all policies
let policies = store.list_policies().await?;
for (id, content) in policies {
println!("{}: {}", id, content);
}
// Update a policy
store.update_policy(&policy_id, new_content).await?;
// Delete a policy
store.delete_policy(&policy_id).await?;
The migration creates the following table:
CREATE TABLE policies (
id TEXT PRIMARY KEY,
content TEXT NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP
);
Migrations are embedded in the binary and run automatically:
let store = PostgresPolicyStore::new(pool);
store.migrate().await?;
use hodei_authz::PolicyStoreError;
match store.get_policy("invalid-id").await {
Ok(Some(policy)) => println!("Found: {}", policy),
Ok(None) => println!("Not found"),
Err(PolicyStoreError::Database(e)) => eprintln!("DB error: {}", e),
Err(PolicyStoreError::NotFound(id)) => eprintln!("Policy {} not found", id),
Err(e) => eprintln!("Error: {}", e),
}
Integration tests require a running PostgreSQL instance:
# Start PostgreSQL
docker run -d -p 5432:5432 -e POSTGRES_PASSWORD=postgres postgres:15
# Run tests
DATABASE_URL="postgres://postgres:postgres@localhost/test" cargo test -- --ignored
MIT OR Apache-2.0