Files
zeekay 11265a21fd Highlight every code sample with shiki in the code theme
Code on hanzo.ai was plain monospace: 285 blocks across 200 pages, one of
them hand-inked in four greys. components/code now renders each sample
at build with shiki and @hanzo/ui's codeTheme (Dracula dark, GitHub
Light light), every colour written as light-dark() so the page's
color-scheme picks it, on the theme's own ground. The page ships the
coloured spans and no highlighter; e2e/gates/code.spec.ts holds both.

A client page that shows code is split into a server page.tsx that owns
the sample and a client view.tsx that takes the highlighted node:
ProductLanding's code.source, the blockchain pages' codeExamples, the
models kit Sample, the guest-key card, realtime, analytics, payments,
sdks and the rest. Transcripts, agent prompts and ASCII diagrams are not
code and keep their markup.

Takes @hanzo/ui 8.27.83 for codeTheme and @hanzo/design 0.5.35 with it,
regenerates app/gui.css for the new theme keys, and lowers the raw-colour
allowance to 58: the samples' literal inks are gone.
2026-10-05 01:31:58 -07:00

104 lines
5.7 KiB
TypeScript

'use client'
import type { ReactNode } from 'react'
import { ArrowRight, Eye, GitBranch, KeyRound, Lock, RefreshCw, Shield, Terminal } from 'lucide-react'
import { OSSRevenueBanner } from '@/components/oss/OSSRevenueBanner'
import { ProductLanding } from '@/components/product/ProductLanding'
import { ProductFooter } from '@/components/products/ProductFooter'
/**
* KMS, through the ONE product kit.
*
* One of NINE pages — console, insights, kms, kv, mq, pubsub, sql, storage,
* stream — that shared a class set 100%: the same hero, stat row, six-card
* grid, terminal and call to action, written out nine times in ~310 utility
* classes each. They now pass one typed props object to `ProductLanding` and
* carry zero layout classes. See LLM.md, "Tailwind is NOT gone", for the rule.
*
* EVERY WORD IS THE ONE THAT WAS HERE, the four stat tiles included: 28 of the
* group's 36 carry a port, a version, a licence or a coding the prose does not
* (measured), so unlike /ledger's four they are not restatements and they stay.
*
* One fix the move makes by construction: ProductFooter sat INSIDE the final
* card's `max-w-4xl` wrapper on all nine, so the OSS attribution and deploy
* block rendered narrower here than on every other product page.
*/
export default function KMSPage({ source }: { source: ReactNode }) {
return (
<>
<ProductLanding
badge={"kms.hanzo.ai"}
badgeIcon={KeyRound}
title={"Hanzo KMS"}
tagline={"Secrets management"}
lede={"Hanzo KMS is where the credentials your code needs actually live, so they stop living in a file somebody committed. The SDK seals a value on your machine before it goes anywhere: your passphrase becomes a key through Argon2id, that key becomes an organization key through HKDF-SHA256, and the value is sealed with AES-256-GCM. The organization key never leaves the client. What the server stores is a blob it cannot read."}
ctas={[
{ label: "Open KMS", href: "https://kms.hanzo.ai", icon: ArrowRight },
{ label: "Documentation", href: "https://docs.hanzo.ai/docs/openapi/kms/" },
]}
what={{
title: "What it holds and how it holds it",
sub: "A secret is a value under a path, a name and an environment, inside one organization. That is the whole model.",
pillars: [
{
icon: Lock,
title: "Sealed before it leaves you",
body: "Argon2id turns a passphrase into a key, HKDF-SHA256 turns that into the organization's key, and AES-256-GCM seals the value. The organization key stays on the client. Sharing with a colleague wraps that same key to their public key using a hybrid post-quantum exchange, so nobody has to send anybody a secret to share one.",
},
{
icon: GitBranch,
title: "Into the process, not into a file",
body: "Run a command with the secrets already in its environment, export a dotenv when a tool insists on one, or let the Kubernetes operator keep a Secret in step with what KMS holds. The CLI also reads your repository and its git history looking for values that escaped.",
},
{
icon: RefreshCw,
title: "Replacing one is deliberate",
body: "Rotate is a command, and a write states the version it means to replace — so a second writer who read the old value is refused rather than quietly winning. Signing keys generate, sign and rotate through the same API, backed by threshold MPC.",
},
{
icon: Eye,
title: "Who read it, when, and why",
body: "Reads and writes land in an append-only record written by a single writer off the request path, so keeping it never slows a fetch. An AI agent's read is attributed to that agent by name, not to whichever human's key it borrowed.",
},
{
icon: Terminal,
title: "One key, several languages",
body: "A CLI for a laptop and for CI. SDKs in Go, Node and Python over the same routes. In-cluster callers can take the binary ZAP transport instead of HTTP, and it enforces the identical token and role checks.",
},
{
icon: Shield,
title: "Fail closed, or do not start",
body: "Every call carries a Hanzo IAM token verified against a cached JWKS; HMAC and alg none are refused outright. The organization comes from the verified token, never from a field the caller sets. Outside development the daemon will not boot without an issuer, an audience and a JWKS URL — there is no accidental open mode. A secret can be marked so that any agent read waits for a person to approve it, or is refused.",
},
],
}}
stats={{
items: [
{ value: "AES-256", label: "Sealed on your machine" },
{ value: "K8s", label: "Secrets kept in step" },
{ value: "Audit", label: "Every read recorded" },
{ value: "MIT", label: "Run it yourself" },
],
}}
code={{
head: { title: "Nothing lands on disk" },
name: "terminal",
source,
}}
finalCta={{
title: "Take them out of the repo",
sub: "Use it hosted, or run the same binary yourself. The source is MIT and the client is where the encryption happens either way.",
buttons: [
{ label: "Open KMS", href: "https://kms.hanzo.ai", icon: ArrowRight },
{ label: "View on GitHub", href: "https://github.com/hanzoai/kms" },
],
}}
>
<OSSRevenueBanner />
</ProductLanding>
<ProductFooter slug={"kms"} name={"KMS"} />
</>
)
}