mirror of
https://github.com/hanzo-apps/hanzo.ai.git
synced 2026-10-30 14:58:08 +00:00
125 lines
6.4 KiB
TypeScript
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>
|
|
)
|
|
}
|