diff --git a/app/globals.css b/app/globals.css
index 766559b..8356a1f 100644
--- a/app/globals.css
+++ b/app/globals.css
@@ -49,8 +49,8 @@
}
@theme inline {
- --font-sans: 'Inter', ui-sans-serif, system-ui, sans-serif;
- --font-serif: 'Source Serif 4', 'Source Serif Pro', Georgia, serif;
+ --font-sans: var(--font-inter), 'Inter', ui-sans-serif, system-ui, sans-serif;
+ --font-serif: var(--font-source-serif), 'Source Serif 4', 'Source Serif Pro', Georgia, serif;
--font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
--color-background: rgb(var(--background));
diff --git a/app/greyscan/layout.tsx b/app/greyscan/layout.tsx
index 2f7c9b2..49f2471 100644
--- a/app/greyscan/layout.tsx
+++ b/app/greyscan/layout.tsx
@@ -3,8 +3,35 @@ import type { Metadata } from 'next'
export const metadata: Metadata = {
title: 'Greyscan | Greywall',
description: 'Scan your repo and see what an unrestricted AI agent would attempt. Powered by Greywall.',
+ alternates: {
+ canonical: 'https://greywall.io/greyscan',
+ },
+ openGraph: {
+ title: 'Greyscan | Greywall',
+ description: 'Scan your repo and see what an unrestricted AI agent would attempt. Powered by Greywall.',
+ url: 'https://greywall.io/greyscan',
+ siteName: 'Greywall',
+ type: 'website',
+ },
+}
+
+const breadcrumbJsonLd = {
+ '@context': 'https://schema.org',
+ '@type': 'BreadcrumbList',
+ itemListElement: [
+ { '@type': 'ListItem', position: 1, name: 'Greywall', item: 'https://greywall.io' },
+ { '@type': 'ListItem', position: 2, name: 'Greyscan', item: 'https://greywall.io/greyscan' },
+ ],
}
export default function ExposureLayout({ children }: { children: React.ReactNode }) {
- return children
+ return (
+ <>
+
+ {children}
+ >
+ )
}
diff --git a/app/layout.tsx b/app/layout.tsx
index c33a4fd..d6cddac 100644
--- a/app/layout.tsx
+++ b/app/layout.tsx
@@ -1,10 +1,26 @@
import type { Metadata } from 'next'
+import { Inter, Source_Serif_4 } from 'next/font/google'
import './globals.css'
+const inter = Inter({
+ subsets: ['latin'],
+ display: 'swap',
+ variable: '--font-inter',
+})
+
+const sourceSerif = Source_Serif_4({
+ subsets: ['latin'],
+ display: 'swap',
+ variable: '--font-source-serif',
+ style: ['normal', 'italic'],
+ axes: ['opsz'],
+})
+
export const metadata: Metadata = {
+ metadataBase: new URL('https://greywall.io'),
title: 'Greywall: Sandbox for AI Agents',
description:
- 'Container-free, default-deny sandboxing with observability for AI agents. Five layers of defense in one command.',
+ 'Container-free, default-deny sandboxing with real-time observability for AI agents on Linux and macOS. Five kernel-enforced security layers in one command. Open source.',
icons: {
icon: [
{ url: '/icon.svg', type: 'image/svg+xml' },
@@ -13,6 +29,74 @@ export const metadata: Metadata = {
],
apple: '/apple-icon.png',
},
+ openGraph: {
+ title: 'Greywall: Sandbox for AI Agents',
+ description: 'Container-free, default-deny sandboxing with real-time observability for AI agents. Five kernel-enforced security layers in one command.',
+ url: 'https://greywall.io',
+ siteName: 'Greywall',
+ type: 'website',
+ },
+ twitter: {
+ card: 'summary',
+ title: 'Greywall: Sandbox for AI Agents',
+ description: 'Container-free, default-deny sandboxing with real-time observability for AI agents. Five kernel-enforced security layers in one command.',
+ },
+ alternates: {
+ canonical: 'https://greywall.io',
+ },
+}
+
+const jsonLd = {
+ '@context': 'https://schema.org',
+ '@graph': [
+ {
+ '@type': 'Organization',
+ '@id': 'https://greyhaven.co/#organization',
+ name: 'Greyhaven',
+ url: 'https://greyhaven.co',
+ logo: { '@type': 'ImageObject', url: 'https://greywall.io/icon.svg' },
+ sameAs: ['https://github.com/GreyhavenHQ'],
+ },
+ {
+ '@type': 'WebSite',
+ '@id': 'https://greywall.io/#website',
+ name: 'Greywall',
+ url: 'https://greywall.io',
+ publisher: { '@id': 'https://greyhaven.co/#organization' },
+ },
+ {
+ '@type': 'SoftwareApplication',
+ '@id': 'https://greywall.io/#software',
+ name: 'Greywall',
+ description:
+ 'Container-free, default-deny sandboxing with real-time observability and dynamic controls for AI agents on Linux and macOS.',
+ applicationCategory: 'SecurityApplication',
+ operatingSystem: 'Linux, macOS',
+ url: 'https://greywall.io',
+ downloadUrl: 'https://github.com/GreyhavenHQ/greywall',
+ license: 'https://opensource.org/licenses/Apache-2.0',
+ offers: { '@type': 'Offer', price: '0', priceCurrency: 'USD' },
+ author: { '@id': 'https://greyhaven.co/#organization' },
+ featureList: [
+ 'Filesystem isolation',
+ 'Network isolation',
+ 'Command blocking',
+ 'Real-time violation monitoring',
+ 'Learning mode',
+ 'Syscall filtering',
+ 'Dynamic allow/deny controls',
+ ],
+ isAccessibleForFree: true,
+ },
+ {
+ '@type': 'SoftwareSourceCode',
+ name: 'Greywall',
+ codeRepository: 'https://github.com/GreyhavenHQ/greywall',
+ programmingLanguage: 'Go',
+ license: 'https://opensource.org/licenses/Apache-2.0',
+ targetProduct: { '@id': 'https://greywall.io/#software' },
+ },
+ ],
}
export default function RootLayout({
@@ -21,13 +105,11 @@ export default function RootLayout({
children: React.ReactNode
}>) {
return (
-
+
-
-
-
diff --git a/app/privacy/page.tsx b/app/privacy/page.tsx
new file mode 100644
index 0000000..0df2866
--- /dev/null
+++ b/app/privacy/page.tsx
@@ -0,0 +1,118 @@
+import type { Metadata } from 'next'
+
+export const metadata: Metadata = {
+ title: 'Privacy Policy | Greywall',
+ description: 'How Greywall handles your data.',
+ alternates: {
+ canonical: 'https://greywall.io/privacy',
+ },
+}
+
+export default function PrivacyPage() {
+ return (
+
+
+
+ Privacy Policy
+
+
+ Last updated: March 19, 2026
+
+
+
+
+ Greywall (the CLI tool)
+
+ Greywall runs entirely on your machine. It does not phone home, collect telemetry,
+ or transmit any data. No analytics, no crash reports, no usage tracking. The source
+ code is open and auditable
+ at github.com/GreyhavenHQ/greywall .
+
+
+
+
+ This website (greywall.io)
+
+ The Greywall landing page is a static site hosted on Vercel. We do not use cookies,
+ analytics scripts, or tracking pixels. Vercel may collect minimal server logs
+ (IP address, user agent, timestamp) as part of standard web hosting.
+ See Vercel's privacy policy for
+ details.
+
+
+
+
+ Greyscan
+
+ When you use Greyscan at /greyscan ,
+ the following happens:
+
+
+
+ Your browser fetches the public file tree, dependency list, and README from GitHub's
+ API directly. This data never passes through our servers during collection.
+
+
+ To generate the threat report, a summary of the repo structure (file names,
+ detected stack, dependency names, and up to 8,000 characters of the README) is
+ sent to our server and forwarded to a third-party LLM provider for analysis.
+
+
+ Results are cached in server memory for up to 24 hours to avoid redundant
+ LLM calls for the same repository, then discarded. We do not persist scan
+ results to disk or a database.
+
+
+ No repository source code is read or transmitted. Only file paths, dependency
+ names, and the public README are included.
+
+
+
+
+
+ Third-party services
+
+
+ GitHub API — Greyscan
+ calls the GitHub REST API from your browser to fetch public repository metadata.
+ Subject to GitHub's privacy statement .
+
+
+ LLM provider — Repo
+ summaries sent through Greyscan are processed by a third-party LLM to generate
+ threat reports. The provider may retain data per their own policies.
+
+
+ Vercel — Hosting
+ infrastructure. See Vercel's privacy policy .
+
+
+
+
+
+ Security
+
+ If you discover a security issue in Greywall or this website, please report it
+ via GitHub Security Advisories .
+ We will respond promptly.
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/app/sitemap.ts b/app/sitemap.ts
new file mode 100644
index 0000000..e192578
--- /dev/null
+++ b/app/sitemap.ts
@@ -0,0 +1,9 @@
+import type { MetadataRoute } from 'next'
+
+export default function sitemap(): MetadataRoute.Sitemap {
+ return [
+ { url: 'https://greywall.io', lastModified: new Date(), changeFrequency: 'weekly', priority: 1 },
+ { url: 'https://greywall.io/greyscan', lastModified: new Date(), changeFrequency: 'monthly', priority: 0.8 },
+ { url: 'https://greywall.io/privacy', lastModified: new Date(), changeFrequency: 'yearly', priority: 0.3 },
+ ]
+}
diff --git a/components/agents.tsx b/components/agents.tsx
index fa8eeeb..5c252b3 100644
--- a/components/agents.tsx
+++ b/components/agents.tsx
@@ -1,3 +1,4 @@
+import Image from 'next/image'
import { CheckCircle2 } from 'lucide-react'
const agents = [
@@ -42,7 +43,7 @@ export function Agents() {
rel="noopener noreferrer"
className="group flex items-center gap-2.5 sm:gap-3 p-3 sm:p-4 rounded-lg border border-border/40 bg-card/30 hover:border-primary/20 hover:bg-card/50 transition-all cursor-pointer"
>
-
-
+
+
)
}
if (value === 'no') {
return (
-
-
+
+
)
}
if (value === 'partial') {
return (
-
-
+
+
)
}
@@ -214,19 +214,19 @@ export function Comparison() {
-
+
Supported
-
+
Partial
-
+
Not supported
diff --git a/components/footer.tsx b/components/footer.tsx
index 10104a5..0e2ca46 100644
--- a/components/footer.tsx
+++ b/components/footer.tsx
@@ -32,6 +32,12 @@ export function Footer() {
>
greyhaven.co
+
+ Privacy
+
Apache 2.0
diff --git a/components/observability.tsx b/components/observability.tsx
index 33fb034..9dac6d6 100644
--- a/components/observability.tsx
+++ b/components/observability.tsx
@@ -1,6 +1,7 @@
'use client'
import { useState, useEffect, useRef } from 'react'
+import Image from 'next/image'
import { Eye } from 'lucide-react'
const slides = [
@@ -97,20 +98,26 @@ export function Observability() {
{/* Screenshot with crossfade */}
{/* Hidden reference image to lock container height */}
-
{slides.map((slide, i) => (
-
))}
diff --git a/next.config.mjs b/next.config.mjs
index b8cc775..88e8ace 100644
--- a/next.config.mjs
+++ b/next.config.mjs
@@ -4,7 +4,6 @@ const nextConfig = {
ignoreBuildErrors: true,
},
images: {
- unoptimized: true,
remotePatterns: [
{
protocol: 'https',
@@ -12,6 +11,19 @@ const nextConfig = {
},
],
},
+ async headers() {
+ return [
+ {
+ source: '/(.*)',
+ headers: [
+ { key: 'X-Frame-Options', value: 'DENY' },
+ { key: 'X-Content-Type-Options', value: 'nosniff' },
+ { key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' },
+ { key: 'Permissions-Policy', value: 'camera=(), microphone=(), geolocation=()' },
+ ],
+ },
+ ]
+ },
}
export default nextConfig
diff --git a/public/llms.txt b/public/llms.txt
new file mode 100644
index 0000000..46b3862
--- /dev/null
+++ b/public/llms.txt
@@ -0,0 +1,30 @@
+# Greywall
+
+> Container-free, default-deny sandboxing with real-time observability for AI agents on Linux and macOS.
+
+Greywall is an open-source CLI tool that wraps any AI agent (Claude Code, Codex, Cursor, Aider, and others) in a kernel-enforced sandbox. It uses five security layers on Linux (Bubblewrap namespaces, Landlock filesystem, Seccomp BPF syscall filtering, eBPF monitoring, and TUN+SOCKS5 network proxy) and four on macOS (Seatbelt sandbox, filesystem policy, log stream monitor, and proxy-based network control). Default-deny policy means nothing is accessible unless explicitly granted. Built by Greyhaven, licensed Apache 2.0.
+
+## Key Features
+- Filesystem isolation (kernel-enforced read/write/deny per path)
+- Network isolation (all traffic routed through GreyProxy)
+- Command blocking (detects blocked commands in pipes, chains, nested shells)
+- Real-time violation monitoring (every denial captured with full context)
+- Learning mode (auto-generates least-privilege templates from observed access)
+- Syscall filtering (blocks 27+ dangerous system calls via Seccomp BPF)
+- Dynamic allow/deny controls (adjust policies live without restarting)
+
+## Links
+- [Homepage](https://greywall.io)
+- [Documentation](https://docs.greywall.io/)
+- [GitHub](https://github.com/GreyhavenHQ/greywall)
+- [Greyhaven (parent company)](https://greyhaven.co)
+
+## Install
+- Homebrew: `brew tap greyhavenhq/tap && brew install greywall`
+- Curl: `curl -fsSL https://raw.githubusercontent.com/GreyhavenHQ/greywall/main/install.sh | sh`
+- Go: `go install github.com/GreyhavenHQ/greywall/cmd/greywall@latest`
+
+## Compatibility
+Works with: Claude Code, Codex, Cursor, Aider, Goose, Amp, Gemini CLI, Cline, OpenCode, Copilot.
+Platforms: Linux (3.8+), macOS.
+License: Apache 2.0.
diff --git a/public/robots.txt b/public/robots.txt
new file mode 100644
index 0000000..8fc6a7d
--- /dev/null
+++ b/public/robots.txt
@@ -0,0 +1,26 @@
+User-agent: *
+Allow: /
+Disallow: /api/
+
+User-agent: GPTBot
+Allow: /
+
+User-agent: OAI-SearchBot
+Allow: /
+
+User-agent: ClaudeBot
+Allow: /
+
+User-agent: PerplexityBot
+Allow: /
+
+User-agent: CCBot
+Disallow: /
+
+User-agent: anthropic-ai
+Disallow: /
+
+User-agent: cohere-ai
+Disallow: /
+
+Sitemap: https://greywall.io/sitemap.xml