Files
hanzo.ai/app/(marketing)/authz/page.tsx
zeekay bda16252a7 auth, auto, base, blog, modules: the words go through @hanzo/i18n
The sign-in callback, initiate and logout pages, authz, auto, the
connectors page, base, the blog index and its three posts, and the Go
module page wrap their copy: server pages with <T>, client pages with
t(), and copy held in data with phrase(). Figures in the posts' prose
are values; product names, code and IAM's own codes stay as written.
Models says its two sentences whole ("{n}+ models", "every model on
the gateway"); the noun prop no caller passed is gone.
2026-10-22 18:13:04 -07:00

69 lines
3.9 KiB
TypeScript

'use client'
import { ArrowRight, GitBranch, Network, ScrollText, Search, Shield, Zap } from 'lucide-react'
import { phrase } from '@hanzo/i18n'
import { ProductLanding } from '@/components/product/ProductLanding'
import { ProductFooter } from '@/components/products/ProductFooter'
/**
* Hanzo Authz, through the ONE product kit.
*
* authz, hsm and idv were a third-generation copy of the same page: a plain
* `<h1>` hero, a feature grid with NO heading above it, and a "Get started
* with X" card. See LLM.md, "Tailwind is NOT gone".
*
* EVERY WORD IS THE ONE THAT WAS HERE. The headless grid is why a section head
* is now optional in the kit rather than required — these three never had one,
* and writing three would be writing words nobody chose.
*/
export default function HanzoAuthzPage() {
return (
<>
<ProductLanding
title={"Hanzo Authz"}
lede={phrase("Hanzo Authz reads a token and answers whether the caller may do the thing. It verifies the JWT that IAM signed, then asks one question: does a grant this caller holds cover this path, and does its role admit this verb. It is a library, not a service — no store, no configuration, no network call on any path — so every Hanzo service asks that question the same way and gets the same answer.")}
ctas={[
{ label: phrase("Read the docs"), href: "https://docs.hanzo.ai/docs/projects/hanzoai/authz", icon: ArrowRight },
{ label: phrase("View on GitHub"), href: "https://github.com/hanzoai/authz" },
]}
what={{
pillars: [
{
icon: Network,
title: phrase("Where a thing is, and who may touch it"),
body: phrase("A location is a path — acme, acme/prod, acme/prod/web, and the app or site under that. Access is a grant at a prefix of one. Keeping them apart is the whole design: containment names a resource, it does not hand every ancestor's members the child."),
},
{
icon: Zap,
title: phrase("Nothing on the decision path does I/O"),
body: phrase("No store, no config, no init, no network call. Authz is a leaf package a service imports, so the check is a function call and a request that reaches your handler has already been decided."),
},
{
icon: GitBranch,
title: phrase("One rule covers every arrangement"),
body: phrase("Can is true when some grant the caller holds prefixes the target and its role admits the verb. An org-wide member holds a grant at the org; a workspace member holds one a level down; an invite-only project is a grant with no ancestor above it. There is no second mechanism."),
},
{
icon: Shield,
title: phrase("Delegation is a narrower grant"),
body: phrase("Handing an agent or a short-lived credential part of your authority means writing a grant deeper in the path than your own, with an expiry if you want one. Nothing can be delegated that the delegator does not already hold."),
},
{
icon: ScrollText,
title: phrase("The decision travels, the grant set stays"),
body: phrase("The edge resolves the requested scope once and writes the resolved path and role into the token, so the token stays the same size no matter how many grants a person has, and no service behind the edge asks IAM anything."),
},
{
icon: Search,
title: phrase("Only what IAM signs"),
body: phrase("Verification accepts the algorithms IAM's signer actually produces — RSA, EC, and ML-DSA-65 for a post-quantum certificate. HMAC and alg none are rejected. Key material is an argument, so the leaf never fetches a JWKS and a caller that supplies no keys verifies nothing."),
},
],
}}
/>
<ProductFooter slug={"authz"} name={"Authz"} />
</>
)
}