treetop-client
A Rust client library for Treetop policy authorization servers.
Treetop is a Cedar-based policy evaluation service. This client provides a typed, async API for evaluating authorization requests, managing policies, and querying server status.
Compatibility
This version targets treetop-rest v0.0.7. CI verifies the stable health, version, policy, and authorization contract against v0.0.4, v0.0.5, v0.0.6, and v0.0.7; v0.0.7 receives the complete endpoint suite. Newer response fields use #[serde(default)] for backward compatibility.
Features
- Type-driven design -- strongly typed request/response types with serde, wire-compatible with the Treetop REST API
- Connection pooling -- built on reqwest with configurable pool sizes and idle timeouts
- Secure token handling -- upload tokens backed by
SecretString(zeroized on drop, redacted in Debug output) - Validated request boundaries -- private request fields, Cedar identifier checks, and validated IP/header newtypes
- TLS by default -- uses rustls (pure-Rust TLS, no OpenSSL dependency) with optional custom root certificates
- Bounded responses -- successful response bodies are capped at 16 MiB by default, with a configurable limit
- Builder patterns -- ergonomic builders for client configuration, authorization requests, users, resources, and actions
- Batch authorization -- evaluate multiple authorization requests in a single API call
- Correlation IDs -- clone-with-override pattern for request tracing without shared mutable state
- Schema management -- download and upload Cedar schema data alongside policies
Installation
Add to your Cargo.toml:
[]
= "0.0.1"
= { = "1", = ["macros", "rt-multi-thread"] }
Quick start
use ;
async
Usage
Client configuration
use Duration;
use ;
let client = builder
.connect_timeout
.request_timeout
.pool_idle_timeout
.pool_max_idle_per_host
.max_response_bytes
.upload_token
.build?;
Upload tokens require HTTPS unless the destination is loopback. For an explicitly accepted
plaintext development server, opt in with .danger_allow_insecure_uploads(true). The default
HTTP client also rejects redirects so a token cannot be forwarded to a redirect target. A custom
reqwest client bypasses that redirect policy, so configure its policy deliberately.
For custom TLS configuration:
use Client;
let client = builder
.add_root_certificate
.build?;
Or bring your own pre-configured reqwest client:
let client = builder
.with_reqwest_client
.build?;
Correlation IDs
Correlation IDs are managed via a clone-with-override pattern. The cloned client shares the same connection pool:
let traced = client.with_correlation_id?;
traced.authorize.await?; // sends x-correlation-id header
// Original client is unaffected
client.authorize.await?; // no correlation header
Authorization
Request fields are private and exposed through read-only accessors. authorize() validates the
complete batch before transport; try_new and try_with_* constructors are available when you
want validation at construction time. AttrValue::ip() always validates its IP/CIDR value.
Single check
use ;
let allowed = client
.is_allowed
.await?;
Batch authorization
use ;
let batch = new
.add_request
.add_request_with_id;
let response = client.authorize.await?;
println!;
// Look up a result by client-provided ID
if let Some = response.find_by_id
Detailed authorization (includes matching policies)
let response = client.authorize_detailed.await?;
Resources with attributes
use ;
let resource = new
.with_attr
.with_attr
.with_attr
.with_attr;
Namespaced types
Users, groups, and actions support Cedar namespaces:
use ;
let user = new
.with_namespace
.with_group_names;
let action = new
.with_namespace;
let group = new
.with_namespace;
Policy management
// Download policies as structured data
let download = client.get_policies.await?;
// Download policies as raw Cedar DSL
let cedar_text = client.get_policies_raw.await?;
// Upload policies (requires upload token)
let metadata = client
.upload_policies_raw
.await?;
// List policies for a specific user
let user_policies = client
.get_user_policies
.await?;
Schema management
// Download schema as structured metadata
let schema = client.get_schema.await?;
// Download schema as raw Cedar schema JSON
let raw_schema = client.get_schema_raw.await?;
// Upload schema (requires upload token)
let metadata = client
.upload_schema_raw
.await?;
Server status
let version = client.version.await?;
println!;
let status = client.status.await?;
println!;
println!;
Request context
Request-scoped context is serialized on the wire via AuthRequest.context and evaluated by treetop-rest v0.0.7.
use HashMap;
use ;
let mut context = new;
context.insert;
let request = new
.with_context;
let batch = from_auth_requests;
let response = client.authorize.await?;
Inspect status.request_context if you need to know whether the server runtime is currently schema-backed or running in permissive fallback mode. Uploading a schema via upload_schema_raw() or upload_schema_json() lets you verify the schema-backed path explicitly.
Prometheus metrics
let metrics_text = client.metrics.await?;
Error handling
All methods return treetop_client::Result<T>, which uses TreetopError:
use TreetopError;
match client.health.await
License
MIT
Releasing
Stable tags drive the crates.io and GitHub release workflow. See
RELEASING.md for the one-time v0.0.1 bootstrap and subsequent OIDC releases.