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
+
+
+
5
+
Providers LLM
+
+
+
0
+
Shadow AI autorise
+
+
+
100%
+
Compatible OpenAI SDK
+
+
+
+ + +
+
+
+
+
+
+ veylant-proxy — requete interceptee +
+
+
// 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 +
+
+ + OpenAI +
+
+ + Anthropic +
+
+ + Azure OpenAI +
+
+ + Mistral AI +
+
+ + 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
  • +
+
+
+
+
+ + +
+
+
Commencer
+

Pret a reprendre le controle
de votre IA d'entreprise ?

+

Demo personnalisee · Deploiement en 15 minutes · Support dedie

+ +
+
+ + + + + + +` 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 */} +
+ +

+ 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 ── */} +
+
+ +

+ 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 ── */} +
+
+ +

+ 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 ── */} +
+
+ +

+ 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 ── */} +
+
+ +

+ 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) => ( +
+
+ {c.icon} +
+
+

{c.title}

+

{c.body}

+
+
+ ))} +
+ {/* 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 ── */} +
+
+ +

+ Un outil, trois interlocuteurs +

+
+ {personas.map((p) => ( +
+
+ {p.role} +
+
{p.title}
+
    + {p.items.map((item) => ( +
  • + + {item} +
  • + ))} +
+
+ ))} +
+
+
+ + {/* ── CTA ── */} +
+
+ +

+ Prêt à reprendre le contrôle
de votre IA d'entreprise ? +

+

+ Démo personnalisée · Déploiement en 15 minutes · Support dédié +

+
+ + + Demander une démo + + + Se connecter au dashboard + + + + Documentation + +
+
+
+ + {/* ── 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.

); 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: (