Files
zeekay ac64d5d7dd Folds say one line: every first screen keeps its heading and a single lede
The owner's spec for a landing page is the models bento's: monochrome, the
words left and the art right, no extra prose. The folds carried two to four
sentences under each heading, and some a claim, a lede and a list besides.
Each now says one line: ProductLanding the tagline where a page states one
(the lede still describes it to search), a claim alone where the claim is
the line (/payments, /treasury, /zap, the extension), and elsewhere the
sentence that says what the thing is. /philosophy's two points, /dns' claim
that repeated its title, /calculator's capabilities line and the
Spare clauses on /research and /learn go.
2026-10-30 06:42:40 -07:00

55 lines
2.9 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use client'
import { ProductFooter } from "@/components/products/ProductFooter"
import { Lede } from "@/components/products/Lede"
import { AgentPrompt } from "@/components/product/AgentPrompt"
import { Related } from "@/components/product/Related"
import { product } from '@/lib/product'
import { Box } from '@hanzo/ui'
import { useI18n } from '@hanzo/i18n/react'
import { phrase } from '@hanzo/i18n'
import { KeyRound } from 'lucide-react'
import { Steps } from '@/components/preview/steps'
/** The prompt's product, off the one table that holds a product's name, route,
* audited command and docs page. */
const PRODUCT = product('iam')
/** What IAM does, one guarantee a step, walked beside the heading. */
const HOLDS = [
{ title: phrase('PKCE'), body: phrase('Authorization code with PKCE, always S256.') },
{ title: phrase('Passwords'), body: phrase('The passwords that do exist are argon2id digests, and a scheme IAM does not recognize fails closed.') },
{ title: phrase('Refresh tokens'), body: phrase('Refresh tokens are single-use and kept only as a hash. Presenting a spent one revokes the whole family, so a stolen token cannot outlive its session.') },
{ title: phrase('A second factor'), body: phrase('A second factor is an authenticator app, a code by SMS or email, or a passkey. Adding or dropping one signs the account out of every other browser.') },
{ title: phrase('Federation'), body: phrase('Sign-in arrives from Google, from GitHub or from any OIDC issuer you name, and SCIM 2.0 keeps a directory in step.') },
{ title: phrase('Signing keys'), body: phrase('Tokens are signed RS256, with ML-DSA-65 available per certificate and published in the same JWKS.') },
{ title: phrase('Organizations'), body: phrase('Every organization is a tenancy boundary, and membership travels in the token.') },
{ title: phrase('Authorization'), body: phrase('What you may reach once signed in is Authz’s to decide, reading the same token.') },
]
export default function IamPage() {
const { t } = useI18n()
return (
<Box minH="100vh" $platform-web={{ color: 'var(--foreground)' }}>
<main>
<Lede
title="Hanzo IAM"
badge={phrase('Identity')}
badgeIcon={KeyRound}
actions={[
{ label: phrase('API reference'), href: 'https://docs.hanzo.ai/docs/openapi/iam' },
{ label: phrase('Discovery document'), href: 'https://hanzo.id/.well-known/openid-configuration' },
{ label: phrase('Source'), href: 'https://github.com/hanzoai/iam' },
]}
preview={<Steps title="hanzo.id" icon={<KeyRound size={12} color="currentColor" />} steps={HOLDS} />}
>
{t('The sign-in behind every Hanzo service.')}
</Lede>
{PRODUCT && <AgentPrompt product={PRODUCT} />}
{PRODUCT && <Related product={PRODUCT} />}
<ProductFooter slug="iam" name="IAM" />
</main>
</Box>
)
}