diff --git a/CLAUDE.md b/CLAUDE.md
index df6c26b..4ca14a4 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -64,11 +64,15 @@ internal/ # All Go modules (see Architecture above for full list)
gen/ # Generated Go gRPC stubs (buf generate → never edit manually)
services/pii/ # Python FastAPI + gRPC PII detection service
gen/pii/v1/ # Generated Python proto stubs (run `make proto` first)
+ tests/ # pytest unit tests (test_regex.py, test_pipeline.py, test_pseudo.py)
proto/pii/v1/ # gRPC .proto definitions
migrations/ # golang-migrate SQL files (up/down pairs)
clickhouse/ # ClickHouse DDL applied at startup via ApplyDDL()
web/ # React frontend (Vite, src/pages, src/components, src/api)
-deploy/ # Helm charts for Kubernetes
+test/ # Integration tests (test/integration/, //go:build integration) + k6 load tests (test/k6/)
+deploy/ # Helm, Kubernetes manifests, Terraform (EKS), Prometheus/Grafana, alertmanager
+ clickhouse/ # ClickHouse config overrides for Docker (e.g. listen-ipv4.xml — forces IPv4)
+docker-compose.yml # Full local dev stack (9 services)
config.yaml # Local dev config (overridden by VEYLANT_* env vars)
```
@@ -114,7 +118,7 @@ go test -run TestName ./internal/module/
**Run a single Python test:**
```bash
-pytest services/pii/test_file.py::test_function
+pytest services/pii/tests/test_file.py::test_function
```
**Proto prerequisite:** Run `make proto` before starting the PII service if `gen/` or `services/pii/gen/` is missing — the service will start but reject all gRPC requests otherwise.
@@ -143,6 +147,8 @@ In production (`server.env=production`), any of the above causes a fatal startup
**Immutable audit logs**: ClickHouse is append-only — no DELETE operations. Retention via TTL policies only. ClickHouse DDL is applied idempotently at startup from `migrations/clickhouse/`.
+**Proxy Docker image**: Uses `distroless/static` — no shell, no `wget`. `CMD-SHELL` health checks in docker-compose cannot work for the proxy container; dependents use `condition: service_started` instead.
+
**Routing rule evaluation**: Rules are sorted ascending by `priority` (lower = evaluated first). All conditions within a rule are AND-joined. An empty `Conditions` slice is a catch-all. First match wins. Supported condition fields: `user.role`, `user.department`, `request.sensitivity`, `request.model`, `request.use_case`, `request.token_estimate`. Operators: `eq`, `neq`, `in`, `nin`, `gte`, `lte`, `contains`, `matches`.
## Conventions
@@ -161,7 +167,7 @@ In production (`server.env=production`), any of the above causes a fatal startup
**OpenAPI docs**: Generated from swaggo annotations — never write API docs by hand.
-**Testing split**: 70% unit (`testing` + `testify` / `pytest`) · 20% integration (`testcontainers` for PG/ClickHouse/Redis) · 10% E2E (Playwright for UI). Tests are written in parallel with each module, not deferred.
+**Testing split**: 70% unit (`testing` + `testify` / `pytest`) · 20% integration (`testcontainers` for PG/ClickHouse/Redis, lives in `test/integration/`, requires `//go:build integration` tag) · 10% E2E (Playwright for UI). Tests are written in parallel with each module, not deferred.
**CI coverage thresholds**: Go internal packages must maintain ≥80% coverage; Python PII service ≥75%. NER tests (`test_ner.py`) are excluded from CI because `fr_core_news_lg` (~600MB) is only available in the Docker build.
diff --git a/cmd/proxy/main.go b/cmd/proxy/main.go
index 2a44f42..09e2d64 100644
--- a/cmd/proxy/main.go
+++ b/cmd/proxy/main.go
@@ -283,6 +283,7 @@ func main() {
r.Use(metrics.Middleware("openai"))
}
+ r.Get("/", health.LandingHandler)
r.Get("/healthz", health.Handler)
// OpenAPI documentation (E11-02).
diff --git a/deploy/clickhouse/listen-ipv4.xml b/deploy/clickhouse/listen-ipv4.xml
new file mode 100644
index 0000000..c25cf0b
--- /dev/null
+++ b/deploy/clickhouse/listen-ipv4.xml
@@ -0,0 +1,4 @@
+
+
+ 0.0.0.0
+
diff --git a/docker-compose.yml b/docker-compose.yml
index 982cd14..df5c1c7 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -51,8 +51,9 @@ services:
- "9000:9000" # Native TCP (used by Go driver)
volumes:
- clickhouse_data:/var/lib/clickhouse
+ - ./deploy/clickhouse/listen-ipv4.xml:/etc/clickhouse-server/config.d/listen-ipv4.xml:ro
healthcheck:
- test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:8123/ping || exit 1"]
+ test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://127.0.0.1:8123/ping || exit 1"]
interval: 5s
timeout: 5s
retries: 20
@@ -133,12 +134,8 @@ services:
condition: service_healthy
clickhouse:
condition: service_healthy
- healthcheck:
- test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:8090/healthz || exit 1"]
- interval: 5s
- timeout: 3s
- retries: 10
- start_period: 5s
+ # distroless/static has no shell or wget, so Docker health checks via CMD-SHELL
+ # cannot run. The proxy exposes /healthz at :8090 — healthy when it starts.
# ─────────────────────────────────────────────
# PII detection service — Python (Sprint 3: full pipeline)
@@ -190,7 +187,7 @@ services:
- "--web.console.templates=/etc/prometheus/consoles"
depends_on:
proxy:
- condition: service_healthy
+ condition: service_started
# ─────────────────────────────────────────────
# Grafana — metrics visualisation
@@ -228,7 +225,7 @@ services:
VITE_KEYCLOAK_URL: "http://localhost:8080/realms/veylant"
depends_on:
proxy:
- condition: service_healthy
+ condition: service_started
volumes:
postgres_data:
diff --git a/internal/health/landing.go b/internal/health/landing.go
new file mode 100644
index 0000000..4e4deab
--- /dev/null
+++ b/internal/health/landing.go
@@ -0,0 +1,991 @@
+package health
+
+import "net/http"
+
+// LandingHandler serves the Veylant IA marketing landing page at GET /.
+func LandingHandler(w http.ResponseWriter, r *http.Request) {
+ w.Header().Set("Content-Type", "text/html; charset=utf-8")
+ w.Header().Set("Content-Security-Policy",
+ "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; connect-src 'self'")
+ w.WriteHeader(http.StatusOK)
+ _, _ = w.Write([]byte(landingHTML))
+}
+
+const landingHTML = `
+
+
+
+
+ Veylant IA — Gouvernance IA pour l'entreprise
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Proxy IA d'entreprise
+
+
L'IA de vos equipes,enfin sous controle
+
Veylant intercepte, anonymise et gouverne tous vos echanges LLM en moins de 50 ms. RGPD natif, EU AI Act pret, zero Shadow AI.
+
+
+
+
+
<50ms
+
Latence pipeline PII
+
+
+
+
0
+
Shadow AI autorise
+
+
+
100%
+
Compatible OpenAI SDK
+
+
+
+
+
+
+
+
+
+
// Requete entrante
+
POST /v1/chat/completions
+
tenant: acme-corp · user: alice
+
+
// Detection PII — 12ms
+
⚠ PERSON "Marie Dubois" → [PERSONNE_1]
+
⚠ IBAN "FR76 3000..." → [IBAN_1]
+
⚠ EMAIL "m.dubois@..." → [EMAIL_1]
+
+
// Routage intelligent — regle #3
+
✓ provider azure · model gpt-4o
+
✓ dept finance · budget OK
+
+
// Log d'audit — ClickHouse
+
✓ tokens: 847 in / 312 out
+
✓ cout: €0.0043 impute
+
✓ latence totale: 38ms ✨
+
+
+
+
+
+
+
+
+
+
Compatible avec
+
+
+
+
+
+
+
+ Ollama (on-premise)
+
+
+
+
+
+
+
+
+
Le probleme
+
Vos equipes utilisent l'IA. Vous n'en savez rien.
+
ChatGPT, Claude, Copilot — vos collaborateurs contournent les politiques IT. Resultat : donnees sensibles exposees, couts incontroles, conformite compromise.
+
+
+
🕵
+
Shadow AI
+
73 % des entreprises ont des employes utilisant des outils IA non approuves. Donnees clients, contrats, code proprietaire partent vers des serveurs tiers sans votre accord.
+
+
+
🔓
+
Fuites de donnees PII
+
Sans filtre, vos prompts contiennent noms, IBAN, emails, numeros de securite sociale. Une seule fuite = violation RGPD notifiable a la CNIL sous 72h.
+
+
+
💸
+
Couts hors de controle
+
Les abonnements proliferent, les tokens s'accumulent. Sans visibilite centralisee, la facture IA gonfle sans correlation avec la valeur produite.
+
+
+
+
+
+
+
+
+
La solution
+
Un proxy intelligent entre vos equipes et les LLMs
+
Veylant se deploie en 15 minutes sans modifier votre code existant. Il intercepte chaque requete et applique vos politiques en temps reel.
+
+
+
🔍
+
Anonymisation PII automatique
+
3 couches de detection (regex, Presidio NER, validation LLM). Pseudonymisation reversible avec mapping chiffre AES-256-GCM en Redis.
+
latence <50ms
+
+
+
🧭
+
Routage intelligent
+
Moteur de regles base sur le role, le departement, la sensibilite et le modele demande. Fallback automatique en cas de panne provider.
+
circuit breaker integre
+
+
+
🛡
+
RBAC granulaire
+
4 roles (admin, manager, user, auditor) avec controle par modele et par departement. Compatible OIDC / Keycloak / SAML 2.0.
+
SSO ready
+
+
+
📋
+
Logs d'audit immuables
+
Chaque requete est enregistree dans ClickHouse (append-only). Impossible a modifier, retention configurable, export PDF pour la CNIL.
+
RGPD Art. 30
+
+
+
⚖
+
Conformite RGPD & EU AI Act
+
Registre de traitement automatique, classification des risques AI Act, rapports PDF telechargeables. DPO-ready des le premier jour.
+
EU AI Act ready
+
+
+
📊
+
Controle des couts
+
Suivi des tokens par tenant, utilisateur et departement. Alertes budgetaires, tableaux de bord Grafana, imputation par centre de cout.
+
dashboard temps reel
+
+
+
+
+
+
+
+
+
Demarrage en 15 minutes
+
Trois etapes vers la conformite
+
+
+
1
+
Pointez votre endpoint
+
Remplacez l'URL OpenAI par votre instance Veylant. Zero modification de code — compatible avec tout SDK OpenAI existant.
+
+
# Avant
+
OPENAI_BASE_URL=api.openai.com
+
+
# Apres
+
OPENAI_BASE_URL=ai.votre-entreprise.com
+
+
+
+
2
+
Configurez vos politiques
+
Via l'API admin ou l'interface React : regles de routage, RBAC, budgets par departement, seuils d'alerte PII.
+
+
# Regle de routage
+
department == "finance"
+
→ provider: azure
+
→ model: gpt-4o
+
+
+
+
3
+
Observez et gouvernez
+
Tableau de bord temps reel, alertes Prometheus/PagerDuty, logs d'audit exportables pour vos audits RGPD.
+
+
# Dashboard SLO
+
✓ SLO 99.5 % respecte
+
✓ 0 fuite PII ce mois
+
✓ Budget: 847 / 1200 EUR
+
+
+
+
+
+
+
+
+
+
Securite
+
Concu pour les equipes securite les plus exigeantes
+
+
+
+
🔐
+
+
Zero Trust & mTLS
+
Communication inter-services chiffree via mTLS. TLS 1.3 en externe. Aucun trafic en clair, jamais.
+
+
+
+
🔑
+
+
Chiffrement bout-en-bout
+
Prompts chiffres AES-256-GCM au repos. Cles API stockees en SHA-256 uniquement. Rotation 90 jours via HashiCorp Vault.
+
+
+
+
✅
+
+
Pentest reussi — 2026
+
0 vulnerabilite critique, 0 high. Semgrep SAST + Trivy image scanning + OWASP ZAP DAST integres en CI/CD.
+
+
+
+
📝
+
+
Audit de l'audit
+
Chaque acces aux logs d'audit est lui-meme logue. Tracabilite complete et inviolable.
+
+
+
+
+
+
🇪🇺
+
RGPD natif
+
Registre Art. 30 automatique. Notification CNIL prete sous 72h.
+
+
+
⚖
+
EU AI Act
+
Classification des risques, documentation systeme requise.
+
+
+
🏛
+
NIS2 ready
+
Logs immuables, alertes PagerDuty, SLO 99,5 %.
+
+
+
🔒
+
ISO 27001
+
Architecture Zero Trust, RBAC, gestion des secrets.
+
+
+
+
+
+
+
+
+
+
Pour qui
+
Un outil, trois interlocuteurs
+
+
+
RSSI
+
Responsable Securite SI
+
+ Visibilite complete sur tous les flux LLM
+ Zero Trust, mTLS, AES-256-GCM
+ Rapport pentest disponible sur demande
+ Alertes temps reel (PagerDuty, Slack)
+ Shadow AI elimine structurellement
+
+
+
+
DSI
+
Directeur Systemes d'Information
+
+ Deploiement Helm/Kubernetes en 15 min
+ Compatible tout SDK OpenAI existant
+ Multi-provider avec fallback automatique
+ Dashboard couts par equipe et projet
+ HPA autoscaling, blue/green deployment
+
+
+
+
DPO
+
Data Protection Officer
+
+ Registre Art. 30 genere automatiquement
+ Classification risques EU AI Act integree
+ Export PDF pour audits CNIL
+ Pseudonymisation reversible et tracable
+ Retention configurable par type de donnee
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`
diff --git a/proxy b/proxy
index ab68fb1..0750833 100755
Binary files a/proxy and b/proxy differ
diff --git a/web/src/components/Sidebar.tsx b/web/src/components/Sidebar.tsx
index 4e4d7db..79e68d6 100644
--- a/web/src/components/Sidebar.tsx
+++ b/web/src/components/Sidebar.tsx
@@ -16,16 +16,16 @@ import { cn } from "@/lib/utils";
import { Separator } from "@/components/ui/separator";
const navItems = [
- { to: "/", label: "Vue d'ensemble", icon: LayoutDashboard, end: true },
- { to: "/playground", label: "Playground IA", icon: FlaskConical },
- { to: "/policies", label: "Politiques", icon: Shield },
- { to: "/users", label: "Utilisateurs", icon: Users },
- { to: "/providers", label: "Fournisseurs", icon: Plug },
- { to: "/security", label: "Sécurité", icon: ShieldAlert },
- { to: "/costs", label: "Coûts", icon: TrendingUp },
- { to: "/alerts", label: "Alertes Budget", icon: Bell },
- { to: "/logs", label: "Journaux", icon: BookOpen },
- { to: "/compliance", label: "Conformité", icon: FileCheck },
+ { to: "/dashboard", label: "Vue d'ensemble", icon: LayoutDashboard, end: true },
+ { to: "/dashboard/playground", label: "Playground IA", icon: FlaskConical },
+ { to: "/dashboard/policies", label: "Politiques", icon: Shield },
+ { to: "/dashboard/users", label: "Utilisateurs", icon: Users },
+ { to: "/dashboard/providers", label: "Fournisseurs", icon: Plug },
+ { to: "/dashboard/security", label: "Sécurité", icon: ShieldAlert },
+ { to: "/dashboard/costs", label: "Coûts", icon: TrendingUp },
+ { to: "/dashboard/alerts", label: "Alertes Budget", icon: Bell },
+ { to: "/dashboard/logs", label: "Journaux", icon: BookOpen },
+ { to: "/dashboard/compliance", label: "Conformité", icon: FileCheck },
];
export function Sidebar() {
diff --git a/web/src/pages/LandingPage.tsx b/web/src/pages/LandingPage.tsx
new file mode 100644
index 0000000..d4f0fd2
--- /dev/null
+++ b/web/src/pages/LandingPage.tsx
@@ -0,0 +1,759 @@
+import { useEffect } from "react";
+import { Link, useNavigate } from "react-router-dom";
+import { useAuth } from "@/auth/AuthProvider";
+
+const brand = "#4f46e5";
+const brandLight = "#818cf8";
+const accent = "#06b6d4";
+const bg = "#0a0f1e";
+const card = "rgba(255,255,255,0.04)";
+const cardHover = "rgba(255,255,255,0.07)";
+const border = "rgba(255,255,255,0.08)";
+const muted = "#94a3b8";
+const dim = "#64748b";
+
+// ── Feature card data ─────────────────────────────────────────────────────────
+const features = [
+ {
+ icon: "🔍",
+ title: "Anonymisation PII automatique",
+ body: "3 couches de détection (regex, Presidio NER, validation LLM). Pseudonymisation réversible avec mapping chiffré AES-256-GCM en Redis.",
+ badge: "latence <50ms",
+ },
+ {
+ icon: "🧭",
+ title: "Routage intelligent",
+ body: "Moteur de règles basé sur le rôle, le département, la sensibilité et le modèle demandé. Fallback automatique en cas de panne provider.",
+ badge: "circuit breaker intégré",
+ },
+ {
+ icon: "🛡️",
+ title: "RBAC granulaire",
+ body: "4 rôles (admin, manager, user, auditor) avec contrôle par modèle et par département. Compatible OIDC / Keycloak / SAML 2.0.",
+ badge: "SSO ready",
+ },
+ {
+ icon: "📋",
+ title: "Logs d'audit immuables",
+ body: "Chaque requête est enregistrée dans ClickHouse (append-only). Impossible à modifier, rétention configurable, export PDF pour la CNIL.",
+ badge: "RGPD Art. 30",
+ },
+ {
+ icon: "⚖️",
+ title: "Conformité RGPD & EU AI Act",
+ body: "Registre de traitement automatique, classification des risques AI Act, rapports PDF téléchargeables. DPO-ready dès le premier jour.",
+ badge: "EU AI Act ready",
+ },
+ {
+ icon: "📊",
+ title: "Contrôle des coûts",
+ body: "Suivi des tokens par tenant, utilisateur et département. Alertes budgétaires, tableaux de bord Grafana, imputation par centre de coût.",
+ badge: "dashboard temps réel",
+ },
+];
+
+const problems = [
+ {
+ icon: "🕵️",
+ title: "Shadow AI",
+ body: "73 % des entreprises ont des employés utilisant des outils IA non approuvés. Données clients, contrats, code propriétaire partent vers des serveurs tiers sans votre accord.",
+ },
+ {
+ icon: "🔓",
+ title: "Fuites de données PII",
+ body: "Sans filtre, vos prompts contiennent noms, IBAN, emails, numéros de sécurité sociale. Une seule fuite = violation RGPD notifiable à la CNIL sous 72h.",
+ },
+ {
+ icon: "💸",
+ title: "Coûts hors de contrôle",
+ body: "Les abonnements prolifèrent, les tokens s'accumulent. Sans visibilité centralisée, la facture IA gonfle sans corrélation avec la valeur produite.",
+ },
+];
+
+const personas = [
+ {
+ role: "RSSI",
+ title: "Responsable Sécurité SI",
+ items: [
+ "Visibilité complète sur tous les flux LLM",
+ "Zero Trust, mTLS, AES-256-GCM",
+ "Rapport pentest disponible sur demande",
+ "Alertes temps réel (PagerDuty, Slack)",
+ "Shadow AI éliminé structurellement",
+ ],
+ },
+ {
+ role: "DSI",
+ title: "Directeur Systèmes d'Information",
+ items: [
+ "Déploiement Helm/Kubernetes en 15 min",
+ "Compatible tout SDK OpenAI existant",
+ "Multi-provider avec fallback automatique",
+ "Dashboard coûts par équipe et projet",
+ "HPA autoscaling, blue/green deployment",
+ ],
+ },
+ {
+ role: "DPO",
+ title: "Data Protection Officer",
+ items: [
+ "Registre Art. 30 généré automatiquement",
+ "Classification risques EU AI Act intégrée",
+ "Export PDF pour audits CNIL",
+ "Pseudonymisation réversible et traçable",
+ "Rétention configurable par type de donnée",
+ ],
+ },
+];
+
+// ── Reusable small components ─────────────────────────────────────────────────
+
+function Label({ children }: { children: React.ReactNode }) {
+ return (
+
+ {children}
+
+ );
+}
+
+function GradientText({ children }: { children: React.ReactNode }) {
+ return (
+
+ {children}
+
+ );
+}
+
+function BtnPrimary({ href, to, children }: { href?: string; to?: string; children: React.ReactNode }) {
+ const style: React.CSSProperties = {
+ display: "inline-flex",
+ alignItems: "center",
+ gap: "0.45rem",
+ padding: "0.85rem 2rem",
+ borderRadius: "10px",
+ fontSize: "1rem",
+ fontWeight: 600,
+ textDecoration: "none",
+ cursor: "pointer",
+ border: "none",
+ background: brand,
+ color: "#fff",
+ transition: "all .2s",
+ whiteSpace: "nowrap",
+ };
+ if (to) return {children};
+ return {children} ;
+}
+
+function BtnOutline({ href, to, children }: { href?: string; to?: string; children: React.ReactNode }) {
+ const style: React.CSSProperties = {
+ display: "inline-flex",
+ alignItems: "center",
+ gap: "0.45rem",
+ padding: "0.85rem 2rem",
+ borderRadius: "10px",
+ fontSize: "1rem",
+ fontWeight: 600,
+ textDecoration: "none",
+ background: "transparent",
+ color: "#f1f5f9",
+ border: `1px solid ${border}`,
+ transition: "all .2s",
+ whiteSpace: "nowrap",
+ };
+ if (to) return {children};
+ return {children} ;
+}
+
+// ── Main component ─────────────────────────────────────────────────────────────
+
+export function LandingPage() {
+ const { isAuthenticated } = useAuth();
+ const navigate = useNavigate();
+
+ useEffect(() => {
+ if (isAuthenticated) {
+ navigate("/dashboard", { replace: true });
+ }
+ }, [isAuthenticated, navigate]);
+
+ return (
+
+ {/* Background glow */}
+
+
+ {/* ── NAV ── */}
+
+
+
+
+ {/* ── HERO ── */}
+
+
+ {/* Left */}
+
+
+
+ Proxy IA d'entreprise
+
+
+ L'IA de vos équipes,
+ enfin sous contrôle
+
+
+ Veylant intercepte, anonymise et gouverne tous vos échanges LLM en moins de 50 ms. RGPD natif, EU AI Act prêt, zéro Shadow AI.
+
+
+
+
+ Demander une démo
+
+
+
+ Tester le playground
+
+
+
+ {/* Stats */}
+
+ {[
+ { val: "<50ms", lbl: "Latence pipeline PII" },
+ { val: "5", lbl: "Providers LLM" },
+ { val: "0", lbl: "Shadow AI autorisé" },
+ { val: "100%", lbl: "Compatible OpenAI SDK" },
+ ].map((s) => (
+
+
+ {s.val}
+
+
{s.lbl}
+
+ ))}
+
+
+
+ {/* Terminal */}
+
+
+
+
+
+
+ veylant-proxy — requête interceptée
+
+
+
+
{`// Requête entrante`}
+
POST /v1/chat/completions
+
tenant: acme-corp · user: alice
+
+
{`// Détection PII — 12ms`}
+
+ ⚠
+ PERSON
+ "Marie Dubois"
+ →
+ [PERSONNE_1]
+
+
+ ⚠
+ IBAN
+ "FR76 3000..."
+ →
+ [IBAN_1]
+
+
+ ⚠
+ EMAIL
+ "m.dubois@..."
+ →
+ [EMAIL_1]
+
+
+
{`// Routage intelligent — règle #3`}
+
✓ provider azure · model gpt-4o
+
✓ dept finance · budget OK
+
+
{`// Log d'audit — ClickHouse`}
+
✓ tokens: 847 in / 312 out
+
✓ coût: €0.0043 imputé
+
✓ latence totale: 38ms ✨
+
+
+
+
+
+ {/* ── TRUST BAR ── */}
+
+
+ Compatible avec
+ {["OpenAI", "Anthropic", "Azure OpenAI", "Mistral AI", "Ollama (on-premise)"].map((p) => (
+ {p}
+ ))}
+
+
+
+ {/* ── PROBLEM ── */}
+
+
+
Le problème
+
+ Vos équipes utilisent l'IA. Vous n'en savez rien.
+
+
+ ChatGPT, Claude, Copilot — vos collaborateurs contournent les politiques IT. Résultat : données sensibles exposées, coûts incontrôlés, conformité compromise.
+
+
+ {problems.map((p) => (
+
+
{p.icon}
+
{p.title}
+
{p.body}
+
+ ))}
+
+
+
+
+ {/* ── FEATURES ── */}
+
+
+
La solution
+
+ Un proxy intelligent entre vos équipes et les LLMs
+
+
+ Veylant se déploie en 15 minutes sans modifier votre code existant. Il intercepte chaque requête et applique vos politiques en temps réel.
+
+
+ {features.map((f) => (
+
+
+ {f.icon}
+
+
{f.title}
+
{f.body}
+
+ {f.badge}
+
+
+ ))}
+
+
+
+
+ {/* ── HOW IT WORKS ── */}
+
+
+
Démarrage en 15 minutes
+
+ Trois étapes vers la conformité
+
+
+ {[
+ {
+ n: 1,
+ title: "Pointez votre endpoint",
+ body: "Remplacez l'URL OpenAI par votre instance Veylant. Zéro modification de code — compatible avec tout SDK OpenAI existant.",
+ code: (
+ <>
+
# Avant
+
OPENAI_BASE_URL=api.openai.com
+
+
# Après
+
OPENAI_BASE_URL=ai.votre-entreprise.com
+ >
+ ),
+ },
+ {
+ n: 2,
+ title: "Configurez vos politiques",
+ body: "Via l'API admin ou l'interface React : règles de routage, RBAC, budgets par département, seuils d'alerte PII.",
+ code: (
+ <>
+
# Règle de routage
+
department == "finance"
+
→ provider: azure
+
→ model: gpt-4o
+ >
+ ),
+ },
+ {
+ n: 3,
+ title: "Observez et gouvernez",
+ body: "Tableau de bord temps réel, alertes Prometheus/PagerDuty, logs d'audit exportables pour vos audits RGPD.",
+ code: (
+ <>
+
# Dashboard SLO
+
✓ SLO 99.5 % respecté
+
✓ 0 fuite PII ce mois
+
✓ Budget: 847 / 1200 €
+ >
+ ),
+ },
+ ].map((step) => (
+
+
+ {step.n}
+
+
{step.title}
+
{step.body}
+
+ {step.code}
+
+
+ ))}
+
+
+
+
+ {/* ── SECURITY ── */}
+
+
+
Sécurité
+
+ Conçu pour les équipes sécurité les plus exigeantes
+
+
+ {/* Checks */}
+
+ {[
+ { icon: "🔐", title: "Zero Trust & mTLS", body: "Communication inter-services chiffrée via mTLS. TLS 1.3 en externe. Aucun trafic en clair, jamais." },
+ { icon: "🔑", title: "Chiffrement bout-en-bout", body: "Prompts chiffrés AES-256-GCM au repos. Clés API en SHA-256. Rotation 90 jours via HashiCorp Vault." },
+ { icon: "✅", title: "Pentest réussi — 2026", body: "0 vulnérabilité critique, 0 high. Semgrep SAST + Trivy image scanning + OWASP ZAP DAST en CI/CD." },
+ { icon: "📝", title: "Audit de l'audit", body: "Chaque accès aux logs d'audit est lui-même loggué. Traçabilité complète et inviolable." },
+ ].map((c) => (
+
+ ))}
+
+ {/* Compliance badges */}
+
+ {[
+ { ico: "🇪🇺", title: "RGPD natif", body: "Registre Art. 30 automatique. Notification CNIL prête sous 72h." },
+ { ico: "⚖️", title: "EU AI Act", body: "Classification des risques, documentation système requise." },
+ { ico: "🏛️", title: "NIS2 ready", body: "Logs immuables, alertes PagerDuty, SLO 99,5 %." },
+ { ico: "🔒", title: "ISO 27001", body: "Architecture Zero Trust, RBAC, gestion des secrets." },
+ ].map((b) => (
+
+
{b.ico}
+
{b.title}
+
{b.body}
+
+ ))}
+
+
+
+
+
+ {/* ── PERSONAS ── */}
+
+
+
Pour qui
+
+ Un outil, trois interlocuteurs
+
+
+ {personas.map((p) => (
+
+
+ {p.role}
+
+
{p.title}
+
+ {p.items.map((item) => (
+
+ →
+ {item}
+
+ ))}
+
+
+ ))}
+
+
+
+
+ {/* ── CTA ── */}
+
+
+ {/* ── FOOTER ── */}
+
+
+
+ Veylant
IA
+
+
+ {[
+ { label: "Documentation", href: "http://localhost:8090/docs" },
+ { label: "Playground", href: "http://localhost:8090/playground" },
+ { label: "Contact", href: "mailto:demo@veylant.io" },
+ ].map((l) => (
+
+ {l.label}
+
+ ))}
+
+
© 2026 Veylant. Conçu pour l'entreprise européenne.
+
+
+
+ );
+}
diff --git a/web/src/pages/LoginPage.tsx b/web/src/pages/LoginPage.tsx
index 0cb4e13..65cca7b 100644
--- a/web/src/pages/LoginPage.tsx
+++ b/web/src/pages/LoginPage.tsx
@@ -10,7 +10,7 @@ export function LoginPage() {
const { login, isAuthenticated, isLoading } = useAuth();
const navigate = useNavigate();
const location = useLocation();
- const from = (location.state as { from?: { pathname: string } })?.from?.pathname ?? "/";
+ const from = (location.state as { from?: { pathname: string } })?.from?.pathname ?? "/dashboard";
useEffect(() => {
if (isAuthenticated) {
diff --git a/web/src/pages/NotFoundPage.tsx b/web/src/pages/NotFoundPage.tsx
index 901ba11..d01c618 100644
--- a/web/src/pages/NotFoundPage.tsx
+++ b/web/src/pages/NotFoundPage.tsx
@@ -10,7 +10,7 @@ export function NotFoundPage() {
La page que vous cherchez n'existe pas.
- Retour à l'accueil
+ Retour au dashboard
);
diff --git a/web/src/router.tsx b/web/src/router.tsx
index bbcf3ec..1c70936 100644
--- a/web/src/router.tsx
+++ b/web/src/router.tsx
@@ -1,6 +1,7 @@
import { createBrowserRouter } from "react-router-dom";
import { AppLayout } from "@/components/AppLayout";
import { ProtectedRoute } from "@/components/ProtectedRoute";
+import { LandingPage } from "@/pages/LandingPage";
import { LoginPage } from "@/pages/LoginPage";
import { OverviewPage } from "@/pages/OverviewPage";
import { PoliciesPage } from "@/pages/PoliciesPage";
@@ -15,6 +16,10 @@ import { CompliancePage } from "@/pages/CompliancePage";
import { NotFoundPage } from "@/pages/NotFoundPage";
export const router = createBrowserRouter([
+ {
+ path: "/",
+ element: ,
+ },
{
path: "/login",
element: ,
@@ -25,7 +30,7 @@ export const router = createBrowserRouter([
element: ,
},
{
- path: "/",
+ path: "/dashboard",
element: (