diff --git a/OVERVIEW.md b/OVERVIEW.md new file mode 100644 index 0000000..8dfec73 --- /dev/null +++ b/OVERVIEW.md @@ -0,0 +1,104 @@ +# Guard Rail Overview + +## Repository Split + +This repository contains two distinct surfaces: + +- `guard-rail-engine/` is the runtime. It is the container-first Rust service that enforces route and policy rules, persists audit and replay data, and exposes the operational endpoints used in the pilot deployment. +- `app/` is the marketing site. It presents the product story, but it is not part of the control plane and does not participate in request enforcement. + +That split matters operationally: the landing page can change independently of the runtime, while the runtime remains the source of truth for request handling, policy enforcement, and execution records. + +## Current Product Shape + +Guard Rail is a policy enforcement runtime for internal API traffic. The current implementation is centered on a pilot deployment that evaluates a request before forwarding it to an upstream API. + +The runtime currently exposes these surfaces: +- route execution for `POST /v1/execute/{route_id}`-style traffic +- route and method validation before forwarding +- authentication and authorization checks around runtime access +- audit logging and audit persistence for every execution +- replay capture and replay persistence for later investigation +- readiness and metrics endpoints for health and operations +- admin and maintenance commands for the pilot deployment path + +The important boundary is that Guard Rail governs the request path, not the upstream application itself. + +## Deployment Model + +The blessed deployment path is container-first: + +`container image + external Postgres + reverse proxy/LB` + +That model reflects the current runtime shape: +- the image is the deployable unit +- Postgres lives outside the container and stores durable state +- a reverse proxy or load balancer fronts the runtime +- config is mounted in from disk +- secrets are injected through the environment + +This is the deployment path the docs and verification package are aligned to. Other packaging choices may exist in the repo, but they are not the recommended pilot path. + +## Request Flow + +At a high level, the runtime does the following on each request: + +1. Resolve the target route. +2. Check the request method and basic request shape. +3. Authenticate the caller and apply route-level access controls. +4. Evaluate configured policies against the request payload and metadata. +5. Record the execution in audit and replay surfaces. +6. Forward the request upstream only if the checks pass. + +The exact policies are data-driven, so most behavior is controlled through repo-managed configuration rather than code changes. + +## Runtime Surfaces + +### Routing + +Routes define which upstream a client can reach, which HTTP methods are allowed, and which policies apply. The runtime resolves the route first so it can reject invalid or unauthorized traffic before any upstream call is made. + +### Authentication and Authorization + +The runtime has explicit request-access surfaces rather than assuming open access. That keeps the request path tied to runtime-issued or runtime-validated credentials instead of treating the engine as a public passthrough. + +### Audit + +Every execution is recorded so operators can reconstruct what happened, why a request was allowed or blocked, and which route or policy was involved. + +### Replay + +Replay artifacts capture the request context needed for later analysis and verification. In the current pilot posture, replay is an operational record, not a productized end-user workflow. + +### Runtime Health + +Readiness and metrics are part of the current operational contract. They exist so the runtime can be deployed behind a proxy/LB and observed like a production service, even though the product itself is still in pilot posture. + +## Data and Operations + +The operator-facing docs are split by concern: + +- `guard-rail-engine/deploy/container/DATA_OPERATIONS.md` covers cleanup, backup, restore, and rollback. +- `guard-rail-engine/deploy/observability/` covers metrics, alerts, dashboards, and runbooks. +- `guard-rail-engine/deploy/verification/README.md` covers the pilot verification suite and its expected scenarios. + +Those documents are the authoritative operational references for the current runtime posture. + +## Verification-Backed Position + +This repo should be described as a verified pilot runtime, not as a roadmap-era platform promise. + +That means the docs should stay aligned with what is actually covered by the current deployment and verification package: +- containerized runtime deployment +- external Postgres +- request enforcement before forwarding +- audit and replay persistence +- readiness, metrics, and operational runbooks + +It does not mean claiming broader platform features, multi-tenant control-plane behavior, or unspecified enterprise guarantees that are not backed by the current code and verification assets. + +## Non-Goals In This Overview + +This file is intentionally not a full API reference or implementation spec. It does not enumerate every config key or every endpoint, and it should not promise features that belong in future work. + +For the concrete operator procedures and verification steps, use the deployment docs linked above. diff --git a/README.md b/README.md index 5cb4662..7299361 100644 --- a/README.md +++ b/README.md @@ -1,95 +1,44 @@ # Guard Rail -`guard-rail-engine` is the Rust runtime in this repo. Stage 5 adds production-hardening support for readiness, metrics, trace-context-aware request logging, graceful drain on shutdown, and baseline deployment artifacts. +Guard Rail is a policy enforcement runtime for internal API traffic. It sits between trusted clients and upstream APIs, evaluates requests against route and policy definitions, and either forwards the request or blocks it with an auditable verdict. -## Guard Rail Engine Operations +The repo has two user-facing parts: +- `guard-rail-engine/` for the Rust runtime +- `app/` for the marketing site, which is separate from the control plane -### Canonical Pilot Deployment +## Blessed deployment path -The only supported pilot deployment path is: +The supported pilot deployment is: `container image + external Postgres + reverse proxy/LB` -The container expects: -- a mounted config directory at `/etc/guard-rail-engine` -- env overrides for secrets such as `GUARDRAIL_DATABASE__URL` and `GUARDRAIL_ADMIN__TOKEN` -- migrations to be run separately from the normal service start path +That path assumes: +- the runtime is run from the built container image +- Postgres is managed outside the container +- a reverse proxy or load balancer fronts the runtime +- runtime config is mounted from disk and secrets are injected through the environment -Build the container image: +The runtime is not positioned as a standalone VM install, a Docker Compose production target, or a Kubernetes-first control plane. -```bash -cd guard-rail-engine -docker build -t guard-rail-engine . -``` +## What the runtime does -Run migrations: +The engine currently covers the pilot-grade request flow: +- route lookup and method checks +- request authentication and authorization surfaces +- policy evaluation before forwarding +- audit persistence for executed requests +- replay capture and related runtime artifacts +- readiness and metrics surfaces for operations -```bash -docker run --rm \ - -v "$(pwd)/deploy/container:/etc/guard-rail-engine:ro" \ - --env-file ./deploy/container/guard-rail-engine.env.example \ - guard-rail-engine \ - migrate --config /etc/guard-rail-engine/config.yaml -``` +## Operational docs -Start the runtime: +Use these repo-native docs for the supported operator workflows: +- Data operations: `guard-rail-engine/deploy/container/DATA_OPERATIONS.md` +- Observability: `guard-rail-engine/deploy/observability/` +- Verification: `guard-rail-engine/deploy/verification/README.md` -```bash -docker run --rm \ - -p 8080:8080 \ - -v "$(pwd)/deploy/container:/etc/guard-rail-engine:ro" \ - --env-file ./deploy/container/guard-rail-engine.env.example \ - guard-rail-engine -``` +## Current scope -`systemd` remains in the repo only as a deferred fallback example. It is not a supported Phase 5 production path. +Guard Rail is focused on the runtime and its pilot deployment story. It is intentionally not framed here as a full SaaS platform, management console, or multi-environment control plane. -## Data Operations - -Retention cleanup is an explicit operator command, not part of normal startup: - -```bash -cd guard-rail-engine -GUARDRAIL_DATABASE__URL="$TEST_DATABASE_URL" \ -GUARDRAIL_ADMIN__TOKEN=phase3-admin-token \ -cargo run -- cleanup --config ./deploy/container/config.yaml -``` - -See `guard-rail-engine/deploy/container/DATA_OPERATIONS.md` for cleanup, backup, restore, and rollback guidance. - -## Local DB-Backed Testing - -DB-backed backend tests require `TEST_DATABASE_URL` locally. CI provisions Postgres automatically for these commands: - -```bash -cd guard-rail-engine -export TEST_DATABASE_URL=postgres://guardrail:secret@127.0.0.1:5432/guardrail - -cargo test --test audit_api_test -cargo test --test auth_integration_test -cargo test --test replay_integration_test -``` - -The CI runtime-smoke lane runs the shipped entrypoints through the helper script: - -```bash -cd guard-rail-engine -export GUARDRAIL_DATABASE__URL="$TEST_DATABASE_URL" -export GUARDRAIL_ADMIN__TOKEN=ci-admin-token -export GUARDRAIL_ENVIRONMENT=development -export GUARDRAIL_SERVER__HOST=127.0.0.1 -export GUARDRAIL_SERVER__PORT=18080 - -./scripts/ci/runtime-smoke.sh -``` - -## Observability - -The runtime exposes Prometheus metrics at `/metrics`. See `guard-rail-engine/deploy/observability/` for: -- Alert rules (`prometheus-alerts.yml`) -- Grafana dashboard (`grafana-dashboard.json`) -- Operator runbooks (`RUNBOOKS.md`) - -## Verification - -See `guard-rail-engine/deploy/verification/README.md` for the Phase 7 verification package covering load, resilience, and security verification. +If you need the deeper runtime layout, request/response surfaces, or repo structure, start with `OVERVIEW.md`. diff --git a/app/components/capabilities.tsx b/app/components/capabilities.tsx index 0dd4942..72449ee 100644 --- a/app/components/capabilities.tsx +++ b/app/components/capabilities.tsx @@ -23,7 +23,10 @@ export function Capabilities() { return (
-
+
{"// The Primitive"} @@ -39,10 +42,10 @@ export function Capabilities() {

{/* Flow Diagram */} -
+
{/* Untrusted Trigger */} -
-
+
+
@@ -54,17 +57,19 @@ export function Capabilities() {
{/* Arrow → Guard Rail */} -
-
-
+
+
+
- POST /v1/execute + + POST /v1/execute +
{/* Guard Rail Center */} -
+
@@ -76,30 +81,30 @@ export function Capabilities() {
{/* Split arrows */} -
+
-
-
+
+
- ALLOW + ALLOW
-
-
+
+
- BLOCK + BLOCK
{/* Outputs */} -
-
+
+
Forward to Enterprise Core
-
+
@@ -108,17 +113,19 @@ export function Capabilities() {
{/* Arrow → Enterprise Core */} -
-
-
+
+
+
- upstream response + + upstream response +
{/* Enterprise Core */} -
+
@@ -137,10 +144,8 @@ export function Capabilities() { {/* Step Cards */}
Configure your automation tool to POST to{" "} - gw.guardrail.co.za/v1/execute/{route}{" "} + + gw.guardrail.co.za/v1/execute/{route} + {" "} instead of your internal system. No other code changes. ), @@ -186,15 +193,19 @@ export function Capabilities() { desc: "Allowed requests forwarded with Guard Rail headers. Blocked requests return a 403 with exactly which policy matched, which field triggered it, and the value that failed.", bg: "03", }, - ].map((step) => ( + ].map((step, index) => (
{step.num} {step.icon}
{step.title}
-
{step.desc}
+
+ {step.desc} +
-
    +
      {[ - { label: "Cape Town, ZAF", href: "#" }, + { label: "Overview", href: "#" }, { label: "Privacy", href: "#" }, { label: "System Status", href: "#" }, { label: "Contact", href: "mailto:founders@guardrail.co.za" }, @@ -32,7 +32,7 @@ export function Footer() { ))}
    - + © 2025 Guard Rail Systems (Pty) Ltd. diff --git a/app/components/hero.tsx b/app/components/hero.tsx index 8754d3f..155af5c 100644 --- a/app/components/hero.tsx +++ b/app/components/hero.tsx @@ -1,23 +1,22 @@ export function Hero() { return ( -
    +
    {/* Left — Copy */}
    {/* Badge */} -
    +
    - Securing the next billion transactions + Verified pilot runtime for internal APIs

    Secure
    execution for @@ -28,16 +27,16 @@ export function Hero() {

    -

    - The enterprise-grade runtime engine. Sandboxing partner integrations, - workflows, and AI agents for South Africa's critical financial - infrastructure. +

    + A policy enforcement runtime that inspects requests before they reach + upstream APIs. Built for the current pilot deployment path and the + operational controls that go with it.

    -
    + -
    +
    Initialize @@ -69,12 +68,12 @@ export function Hero() {
    {/* Right — Orbit Visual */} -
    +
    {/* Outer orbit ring */}
    -
    +
    {/* Orbit dot */}
    @@ -101,7 +100,7 @@ export function Hero() { {/* Float chip — top right */}
    @@ -110,11 +109,11 @@ export function Hero() { {/* Float chip — bottom left */}
    - 0.04ms Latency + Pilot-verified runtime path
    diff --git a/app/components/nav.tsx b/app/components/nav.tsx index 3346133..0351666 100644 --- a/app/components/nav.tsx +++ b/app/components/nav.tsx @@ -3,10 +3,13 @@ export function Nav() { return ( diff --git a/app/components/problem.tsx b/app/components/problem.tsx index 579762e..6cb6774 100644 --- a/app/components/problem.tsx +++ b/app/components/problem.tsx @@ -23,8 +23,8 @@ export function Problem() { return (
    -
    -
    +
    +
    {/* Left — Copy */}
    @@ -32,16 +32,17 @@ export function Problem() {

    Automation is scaling.
    Control is not.

    - Enterprise architecture has fundamentally shifted. Zapier, Make, - custom scripts, and AI agents are driving operations. Yet standard - perimeter security is blind to intra-workflow execution context. + Operations now move through Zapier, Make, custom scripts, and AI + agents. Those flows still need request-level inspection because + perimeter controls do not understand what happens inside the + workflow.

    When an unverified third-party app executes a workflow across your @@ -53,20 +54,20 @@ export function Problem() {

    {/* Right — Stat Cards */} -
    - {/* 412% */} -
    +
    + {/* Fast-moving sprawl */} +
    -
    - 412% +
    + Fast-moving sprawl
    -
    Increase in API Sprawl
    -
    - In South African banking networks over the last 36 months, leading - to impossible audit trails. +
    More routes, more blind spots
    +
    + New integrations and workflow tools arrive faster than teams can + review them, which makes audit trails harder to trust.
    @@ -75,24 +76,24 @@ export function Problem() {
    - {/* 73% */} -
    + {/* Unverified third-party logic */} +
    -
    - 73% +
    + Unverified third-party logic
    -
    Unverified 3rd Party Logic
    -
    - Of mission-critical data transfers rely on external webhooks - without payload-level inspection. +
    External steps still need inspection
    +
    + External webhooks and partner automations can move critical data + without any payload-level check unless the runtime is in line.
    {/* Shadow Workflows */} -
    +
    Shadow Workflows
    - Operations bypassing IT governance entirely. + Operations bypassing central review and control.
    diff --git a/app/components/terminal-animation.tsx b/app/components/terminal-animation.tsx deleted file mode 100644 index 0a0536a..0000000 --- a/app/components/terminal-animation.tsx +++ /dev/null @@ -1,86 +0,0 @@ -"use client"; - -import { useEffect, useReducer } from "react"; - -interface TerminalLine { - text: string; - color?: string; - delay: number; -} - -const SEQUENCE: TerminalLine[] = [ - { text: "$ incoming webhook POST /api/v1/transfer", color: "text-white/50", delay: 0 }, - { text: "", delay: 300 }, - { text: "{", color: "text-white/70", delay: 600 }, - { text: ' "amount": 250000,', color: "text-white/70", delay: 800 }, - { text: ' "recipient": "ZA-ACC-8812",', color: "text-white/70", delay: 1000 }, - { text: ' "callback": "https://evil.sh/exfil",', color: "text-crimson", delay: 1200 }, - { text: ' "memo": "Invoice #4401"', color: "text-white/70", delay: 1400 }, - { text: "}", color: "text-white/70", delay: 1600 }, - { text: "", delay: 1900 }, - { text: "[guardrail] Intercepting payload...", color: "text-cyan", delay: 2200 }, - { text: "[guardrail] Policy: egress-allowlist", color: "text-cyan", delay: 2800 }, - { text: '[guardrail] VIOLATION: "callback" domain not in allowlist', color: "text-crimson", delay: 3400 }, - { text: "", delay: 3800 }, - { text: "[result] BLOCKED — execution halted", color: "text-crimson font-bold", delay: 4200 }, - { text: "[audit] Hash: 9f3a...c7e1 committed to ledger", color: "text-green", delay: 4800 }, - { text: "[audit] Event logged: GR-EXE-449281", color: "text-green", delay: 5200 }, -]; - -const CYCLE_DURATION = 8000; - -type State = { cycle: number; visibleLines: number }; -type Action = { type: "show_line"; line: number } | { type: "restart" }; - -function reducer(state: State, action: Action): State { - switch (action.type) { - case "show_line": return { ...state, visibleLines: action.line }; - case "restart": return { cycle: state.cycle + 1, visibleLines: 0 }; - } -} - -export function TerminalAnimation() { - const [{ cycle, visibleLines }, dispatch] = useReducer(reducer, { cycle: 0, visibleLines: 0 }); - - useEffect(() => { - const timers: ReturnType[] = []; - - SEQUENCE.forEach((line, i) => { - timers.push( - setTimeout(() => dispatch({ type: "show_line", line: i + 1 }), line.delay) - ); - }); - - timers.push( - setTimeout(() => dispatch({ type: "restart" }), CYCLE_DURATION) - ); - - return () => timers.forEach(clearTimeout); - }, [cycle]); - - return ( -
    - {/* Title bar */} -
    -
    -
    -
    - - guardrail — interception log - -
    - - {/* Terminal body */} -
    - {SEQUENCE.slice(0, visibleLines).map((line, i) => ( -
    - {line.text} -
    - ))} - {visibleLines < SEQUENCE.length && ( - - )} -
    -
    - ); -} diff --git a/app/components/trust.tsx b/app/components/trust.tsx index e30ddf6..63b4e9b 100644 --- a/app/components/trust.tsx +++ b/app/components/trust.tsx @@ -25,7 +25,10 @@ export function Trust() { <> {/* ── FEATURES / BENTO ── */}
    -
    +
    {"// Capabilities"} @@ -40,19 +43,15 @@ export function Trust() { {/* Bento Grid */}
    {/* Wide cell — Payload Inspection */}
    @@ -70,17 +69,17 @@ export function Trust() {
    Payload Inspection

    Guard Rail receives your webhook, inspects the payload against every configured - policy using JSONPath field matching, and either forwards or blocks. Zero code - execution surface. Zero attack surface expansion. + policy using JSONPath field matching, and either forwards or blocks the request. + No custom application code runs inside the policy path.

    -
    +
    env.inspect() → execution_context_id: GR-8922x
    {/* Declarative YAML Rules */} -
    +
    Policy Engine @@ -99,7 +98,7 @@ export function Trust() {
    {/* Cryptographic Audit Logs */} -
    +
    Audit Trail @@ -121,7 +120,7 @@ export function Trust() {
    {/* Deterministic Replay */} -
    +
    Replay Engine @@ -138,11 +137,10 @@ export function Trust() { {/* Wide cell — Safety + Compliance */}
    -
    +
    Safety @@ -153,8 +151,8 @@ export function Trust() {
    Fail-Closed by Design

    Guard Rail refuses to start if policy files reference a missing name. On - hot-reload, a syntax error keeps the previous valid set active. You never - run unprotected. + hot-reload, a syntax error keeps the last valid set active so an invalid + update does not silently disable inspection.

    @@ -164,10 +162,13 @@ export function Trust() { -
    POPIA-Safe by Architecture
    +
    + Deployment Boundaries That Support POPIA +

    - On-premise or ZA-AWS VPC deployment. No cross-border payload transmission. - Data residency is a structural guarantee, not a checkbox. + On-premise or single-region ZA AWS VPC deployment gives teams a path to keep + payload handling within their chosen boundary. Final compliance still depends + on deployment, policy, and operational controls.

    @@ -187,7 +188,7 @@ export function Trust() { borderBottom: "1px solid rgba(255,255,255,0.04)", }} > -
    +
    {"// The Shift in Paradigm"} @@ -202,32 +203,32 @@ export function Trust() { {/* Comparison Table */}
    - +
    - - -
    Capability Legacy API Gateways In-house Middleware (
    + {row.cap} + {row.legacy} + {row.inhouse} (null); - const [isVisible, setIsVisible] = useState(false); - - useEffect(() => { - const el = ref.current; - if (!el) return; - - const observer = new IntersectionObserver( - ([entry]) => { - if (entry.isIntersecting) { - setIsVisible(true); - observer.unobserve(el); - } - }, - { threshold } - ); - - observer.observe(el); - return () => observer.disconnect(); - }, [threshold]); - - return { ref, isVisible }; -} diff --git a/app/globals.css b/app/globals.css index ec45057..46376d2 100644 --- a/app/globals.css +++ b/app/globals.css @@ -41,6 +41,21 @@ body { -webkit-font-smoothing: antialiased; } +.trust-scroll-area { + -webkit-overflow-scrolling: touch; + scrollbar-width: thin; + scrollbar-color: rgba(255, 255, 255, 0.16) transparent; +} + +.trust-scroll-area::-webkit-scrollbar { + height: 6px; +} + +.trust-scroll-area::-webkit-scrollbar-thumb { + background: rgba(255, 255, 255, 0.16); + border-radius: 999px; +} + /* Background Grid */ .bg-grid-pattern { position: absolute; diff --git a/app/layout.tsx b/app/layout.tsx index f85a664..7cd4223 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -13,9 +13,9 @@ const geistMono = Geist_Mono({ }); export const metadata: Metadata = { - title: "Guard Rail — Zero-Trust Payload Inspection for Enterprise Automation", + title: "Guard Rail | Policy Enforcement for Automation Workflows", description: - "The enterprise-grade runtime engine. Sandboxing partner integrations, workflows, and AI agents for South Africa's critical financial infrastructure.", + "Inspect untrusted requests and enforce execution policy across integrations, workflows, and AI agents.", }; export default function RootLayout({ diff --git a/app/page.tsx b/app/page.tsx index 368ff0b..954aa66 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -43,7 +43,7 @@ export default function Home() { {/* ── Scroll Indicator (left side) ── */}