laravel-iam — Rust SDK
A thin, fail-closed Rust client for the Laravel IAM authorization
server. It asks the control plane for policy decisions and verifies OIDC tokens — and it is built so
that a gate cannot accidentally open.
Same wire contract as the production PHP client (
Padosoft\Iam\Client), different language.
No policy logic lives on the client: every decision belongs to the server.
The crate is published as laravel-iam on crates.io
(API docs on docs.rs/laravel-iam).
New here? Jump to the Quickstart for a five-minute integration, or read
Core concepts to understand what “fail-closed” buys you before you write a line of code.
Why this SDK exists
Authorization clients fail in the worst possible way when they fail open: a timeout or a 500
quietly becomes “allow”, and a security boundary evaporates exactly when the system is already under
stress. This SDK makes that outcome impossible by construction:
- A network error, timeout,
5xx,4xx, malformed body or unverifiable token always maps to deny. - There is no fail-open switch. If you must tolerate an outage, do it deliberately at the
application layer — never silently in the transport. - An
alloweddecision that stillrequires_step_upis treated as not yet allowed.
What it does
check() posts a DecisionQuery to POST {base}/decisions/check and returns a
normalized Decision. The server holds all RBAC + ABAC + ReBAC policy.
verify_token() checks an ES256 signature against the server’s cached JWKS, then validates
iss / aud / exp / nbf — all in pure-Rust crypto (p256).
list_resources() answers “which resources can this subject reach under relation r?” via
POST {base}/decisions/list-resources.
A taste
use laravel_iam::{IamClient, DecisionQuery, Subject, ResultExt};
use serde_json::json;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let iam = IamClient::builder()
.base_url("https://iam.example.com/api/iam/v1")
.token(std::env::var("IAM_SERVICE_TOKEN")?)
.build()?;
let allowed = iam.check(DecisionQuery {
subject: Subject::user("usr_123"),
application: Some("warehouse".into()),
permission: "stock.adjust".into(),
resource: Some("wh_milan".into()),
context: json!({ "amount": 300 }),
..Default::default()
}).await.is_allowed(); // <- ANY error collapses to `false`
if !allowed { return Err("forbidden".into()); }
Ok(())
}
The whole design is in that last comment: is_allowed() is true only on an explicit server
permit. Read Fail-closed authorization for the full argument.
Ecosystem
laravel-iam-rust is one client SDK in the Laravel IAM suite. The server is the policy authority;
the SDKs and clients only transport the question and the answer.
| Package | Role |
|---|---|
laravel-iam-server |
The IAM server: identity, org, Application Registry + manifest, PDP (RBAC+ABAC+ReBAC), OAuth/OIDC, tamper-evident audit, IGA, Admin API + panel. |
laravel-iam-contracts |
Shared contracts/interfaces + DTOs (PDP, KeyProvider, Assurance, FeatureScope). |
laravel-iam-client |
Laravel client for consumer apps: OIDC login, JWT/JWKS verify, introspection, iam.auth/iam.can middleware, Gate adapter. |
laravel-iam-node |
Node/TS SDK (@padosoft/laravel-iam-node), thin + fail-closed. |
laravel-iam-react-native |
React Native SDK (@padosoft/laravel-iam-react-native), thin + hooks. |
laravel-iam-rust |
This package — Rust SDK (crate laravel-iam), async + blocking, fail-closed. |
laravel-iam-ai |
Optional advisory-only AI module (redaction + hallucination-guard + audit). |
laravel-iam-directory |
Optional LDAP / Active Directory module (LdapRecord). |
laravel-iam-bridge-spatie-permission |
Migration bridge from spatie/laravel-permission. |
All SDKs and the PHP client speak the same wire contract — see The wire contract.
Where to go next
Install the crate
Addlaravel-iamtoCargo.toml. See Installation.Run the Quickstart
A working async gate in a few lines. See Quickstart.Understand the model
Core concepts and Fail-closed authorization.Go deep
Architecture overview, the check flow, and the
API reference.