Files
hanzo.ai/components/home/Security.tsx

125 lines
6.4 KiB
TypeScript

'use client'
import { ArrowRight } from 'lucide-react'
import { YStack, Text } from '@hanzo/ui'
import { Cta, Section } from '@/components/marketing/page-kit'
import { Caption, Dim, Plate, Row } from './plate'
/**
* Security, on the front page.
*
* An agentic company runs work that no person watched start. The governing
* question is not "is the platform secure" but "whose authority did that action
* run under" — so this leads with identity and ends with the record, and now
* does so literally: the picture opens on `actor` and closes on `seq`.
*
* THE PICTURE IS ONE AUDIT RECORD, in the shape the platform writes it. The six
* invariants rendered here as six aligned sentences until the sentences were
* doing a drawing's job. The artefact behind them is hanzoai/cloud's audit
* package: an INSERT-only `audit_log` whose `seq` is a gapless chain position
* and whose rows hash-chain to their predecessor, so Verify recomputes every
* hash and an out-of-band edit is detectable whatever the storage layer says
* (`audit/store.go`). The field names here are that record's own contract
* (`audit/record.go`): actor, auth, action, resource, seq. The actor is
* populated only from a validated principal, never from a client header, and a
* service principal records the org with no user sub — which is what an agent's
* work looks like in the log: attributed, with no person at the keyboard. The
* VALUES are a hand-authored sample and the caption says so; the action string
* is one the platform really writes — `automations.tool.call`, an agent's tool
* call, audited, with the tool as the resource (`apps/auto/invoke.go`).
*
* SURFACES' POLICY PLATE IS THE OTHER FACE OF THIS SAME LOG — a stream of
* verdicts, allowed and refused, with times. So this plate shows NO outcome
* column and no clock: one entry, opened to its identity-and-authority fields.
* Two cards drawing the same columns would be one card twice. And no TAMPERED
* row: the page's willingness to show a loud state already lives in that
* card's refusals.
*
* WHAT THE RECORD DOES NOT CARRY STAYS PROSE. AuthContext is how the actor
* authenticated plus the validated admin bit — there is no permission string,
* no secret-policy field, no sandbox id and no approval field in this record.
* So four invariants (tool→permission, secret→policy, execution→boundary,
* action→approval when required) keep one sentence under the plate rather than
* being drawn as fields the record does not have. An invented field is worse
* than a sentence. The two the picture now says — identity, and the record
* itself — lost their sentences.
*
* STILL NOT A SEQUENCE. Nothing here draws an arrow: a record's field order is
* layout, not a pipeline, and its own contract says so (the chain hashes
* canonical sorted-key JSON, so field order cannot even matter). The `run`
* sweep went with the grid — six claims needed animating into simultaneity;
* one write is simultaneous by construction.
*
* IT STOPS AT THE PROPERTY AND HANDS OFF. Mechanism — key derivation, sandbox
* runtimes, header stripping, the reserved audit rows — lives on /security and
* /trust in those pages' words, and /trust is held to what it says by
* `e2e/gates/trust-copy.spec.ts` against the rendered DOM. A general buyer
* reading cipher suites is reading a different genre than the sentence before.
*
* WHERE THEY WERE READ: the record and chain in hanzoai/cloud
* `audit/record.go` + `audit/store.go` and the tool-call emit in
* `apps/auto/invoke.go`; key derivation and envelope sealing in luxfi/kms
* `pkg/store/crypto.go`; isolation defaults, the refusal to substitute a
* weaker runtime and the capability drop in hanzoai/runtime
* `apps/runner/pkg/docker/isolation.go` and `container_configs.go`.
*
* THREE THINGS THE SOURCE REFUSES, and this page therefore does not say:
* isolation is per SANDBOX and not per run (a sandbox is long-lived and many
* executions share one, whatever `runtime/LLM.md` says); there is no egress
* policy at all — `getContainerNetworkingConfig` returns nil when
* unconfigured, which is the Docker bridge and full outbound, so never claim
* network isolation; and no latency number, because "sub-90ms" is runtime's
* README with no committed benchmark behind it.
*
* NO FRAMEWORK IS NAMED, deliberately. `ci/bin/certclaims` fails any line
* naming one beside a certificate word or a hedge, and the failure it exists
* to catch is real: four framework names once rendered on /security with green
* checkmarks while the qualifiers that made them honest sat in a field the
* markup never printed. That question has exactly one home, /trust.
*/
/** Field names print padded to the widest, as a log printer would — in mono,
* NBSP is a full column, so the values start at one x. */
const lead = (s: string) => s.padEnd(8, '\u00A0')
export default function Security() {
return (
<Section
title="Autonomous within boundaries. Accountable everywhere."
// It said "six things" above a plate that renders FIVE rows — a count that was
// wrong on the page it headed, which is what a counted headline does the first
// time the thing under it changes. What matters was never the number: it is that
// one record shape covers a person and an agent alike, and that is what the
// ending already said.
lede="Every action leaves the same record, whoever or whatever started it."
>
<YStack gap="$4" maxW={672}>
<YStack maxW={420}>
<Plate>
<Row lead={lead('actor')}>
acme<Dim> · service principal</Dim>
</Row>
<Row lead={lead('auth')}>api-key</Row>
<Row lead={lead('action')}>automations.tool.call</Row>
<Row lead={lead('resource')}>automations/deploy</Row>
<Row lead={lead('seq')} verdict="verified">
#4821<Dim> · append-only chain</Dim>
</Row>
</Plate>
<Caption>one audit record · sample values</Caption>
</YStack>
<Text render="p" fontSize="$3" color="$quiet">
Every tool has a permission, every secret a policy, every execution a
boundary, and every consequential action an approval when you require
one. Identity, authorization, secrets, isolation, networking and audit
are built into Hanzo OS.
</Text>
<Cta href="/security" icon={ArrowRight}>
Read the security architecture
</Cta>
</YStack>
</Section>
)
}