ACCESS
IS NOT
A STRING CHECK
Policies are data.
Compile-time safe.
Fully auditable.
:: comparison
Before & After
// Scattered across codebase if (user.role === "admin" || user.permissions .includes("Write")) { if (!user.suspended) { // allow... maybe? } } // No audit trail // No composition // No type safety // Changes require grep + pray
// Defined once, enforced everywhere const policy = allOf( anyOf(hasRole("admin"), hasPermission(Write)), not(hasAttribute("suspended", true)), ); const { granted, trace } = evaluate(policy, ctx); // Full audit trail // Composable & reusable // Compile-time type safe // Changes in one place
:: policy kinds
10 Policy Kinds
Every authorization pattern you need, as a composable value.
hasPermission
hasPermission(Permissions.Write)
Check if subject holds a specific permission token.
hasRole
hasRole("admin")
Check if subject has been assigned a role.
hasAttribute
hasAttribute("department", "engineering")
Match a subject attribute against an expected value.
hasResourceAttribute
hasResourceAttribute("visibility", "public")
Match a resource attribute against an expected value.
hasSignature
hasSignature("electronic")
Verify electronic signature type — 21 CFR Part 11.
hasRelationship
hasRelationship("owner")
Check subject-resource relationship — ReBAC pattern.
allOf
allOf(policy1, policy2, policy3)
All child policies must grant. Short-circuits on first deny.
anyOf
anyOf(policy1, policy2)
At least one child must grant. Short-circuits on first allow.
not
not(hasAttribute("suspended", true))
Inverts the child policy decision.
withLabel
withLabel("audit-check", policy)
Attaches a label for trace identification and filtering.
:: composition
Compose Into Any Shape
:: evaluation
Full Decision Objects
- ■
granted— boolean result - ■
trace— full evaluation path with timing - ■
durationMs— total evaluation time - ■
Every nodein the tree is individually traceable
:: react
First-Class React Support
<Can> Component
import { Can } from "@hex-di/guard/react"; function DocumentActions({ doc }) { return ( <Can policy={canPublish} resource={doc}> <button>Publish</button> </Can> ); } // Renders children only if policy grants
Declarative gate. Renders children only when the policy grants.
useCan() Hook
import { useCan } from "@hex-di/guard/react"; function DocumentPage({ doc }) { const { granted, loading } = useCan(canPublish, { resource: doc }); if (loading) return <Spinner />; if (!granted) return <Forbidden />; return <Editor doc={doc} />; }
Imperative hook for conditional rendering and loading states.
:: capabilities
Why Guard?
Compile-Time Policies
Policies are data, not decorators. Define authorization rules as composable values with full type safety at compile time.
Role DAG Inheritance
O(1) permission lookup via directed acyclic graph flattening. Define role hierarchies that resolve instantly.
10 Policy Kinds
hasPermission, hasRole, hasAttribute, hasResourceAttribute, hasSignature, hasRelationship, allOf, anyOf, not, withLabel.
Full Evaluation Traces
Every authorization decision is auditable. The Decision object carries the full evaluation trace, timing, and policy metadata.
Framework Agnostic
No decorators, no reflection, no magic. Pure functions and data structures that work everywhere TypeScript runs.
GxP Ready
21 CFR Part 11 compliance support. Electronic signatures, audit trails, and tamper-evident records.
:: ecosystem
Part of the HexDI Stack
Guard integrates seamlessly with the HexDI dependency injection ecosystem. Use it standalone or compose it with other libraries.
Ready to secure your stack?
Replace scattered permission checks with composable, typed policies. Zero dependencies. Full TypeScript inference.