Aller au contenu

Démarrage rapide

C’est le chemin rapide pour comprendre à quoi sert Olivares AI : une carte d’accès lecture/écriture de votre estate et la dérive Permis-vs-Observé par-dessus — l’écart entre l’accès qu’un agent s’est vu accorder et l’accès qu’il est observé en train d’utiliser.

Vous atteindrez ce résultat deux fois, en cinq minutes environ au total :

  1. En une minute, sur l’estate de démonstration fourni — la rampe d’accès instantanée « à quoi ça ressemble au juste » (observations synthétiques, circulant à travers le moteur réel).
  2. Puis sur un véritable connecteur — le même graphe et la même dérive, cette fois analysés mot pour mot à partir d’un journal pgAudit PostgreSQL, pour prouver que la fonctionnalité phare tourne sur des données authentiques, pas sur une démo.

Chaque commande ci-dessous est exécutée, exactement telle qu’écrite, par scripts/quickstart-smoke.sh (reproductibilité) — de sorte que cette page ne peut pas dériver discrètement par rapport au binaire.

C’est un parcours d’apprentissage, pas un déploiement de production. Pour la véritable installation (pas d’identifiants par défaut, un jeton de configuration à usage unique, TLS), allez à auto-hébergement. Pour une visite guidée de l’interface, voir le tutoriel zéro-au-graphe.

À partir d’un checkout du dépôt (nécessite Go 1.26+, Task et pnpm — task build empaquette l’interface web avant de compiler ; le store est en SQLite pur-Go, donc pas de chaîne d’outils C) :

Fenêtre de terminal
task build # compiles ./bin/olivares with the web UI embedded
./bin/olivares version

task build produit un unique artefact autonome dans ./bin/olivares — le moteur, l’interface web embarquée et les plugins de connecteurs de première partie. Les installations conteneur et Kubernetes enveloppent ce même binaire : une image publiée plus un fichier Compose (auto-hébergement), ou un manifeste plat que vous appliquez avec kubectl apply -f deploy/manifests/install.yaml (pas de Helm requis). La fonctionnalité phare que vous voyez ci-dessous est identique sur les trois — seul le seed de démo diffère (loopback uniquement, jamais dans une véritable installation).

2. Démarrer l’estate de démonstration (loopback uniquement)

Section intitulée « 2. Démarrer l’estate de démonstration (loopback uniquement) »
Fenêtre de terminal
DATA="$(mktemp -d)"
./bin/olivares serve --insecure --seed-demo \
--listen 127.0.0.1:8901 --grpc-listen 127.0.0.1:8902 \
--data-dir "$DATA"

--insecure sert du HTTP en clair sur loopback (acceptable pour une démo locale ; TLS est activé par défaut sinon). Vous verrez d’honnêtes lignes WARN pour les coutures fermées par défaut (deny-closed) prêtes à l’emploi (pas de juge, pas d’embedder, pas de portail d’approbation, pas de sources réelles), puis une bannière DEMO MODE avec les identifiants :

demo@olivares.local / olivares-demo-estate

L’estate synthétique circule à travers le vrai bus d’événements exactement comme le ferait un collecteur pgAudit ou OpenTelemetry en direct — seules les observations sont ensemencées.

3. Atteindre le graphe d’accès et sa dérive (la fonctionnalité phare)

Section intitulée « 3. Atteindre le graphe d’accès et sa dérive (la fonctionnalité phare) »

Laissez le serveur tourner ; dans un second terminal, connectez-vous, résolvez le tenant de démo, et récupérez le graphe et sa dérive :

Fenêtre de terminal
BASE=http://127.0.0.1:8901
TOKEN="$(curl -sf -X POST "$BASE/v1/auth/login" \
-H 'Content-Type: application/json' \
-d '{"email":"demo@olivares.local","password":"olivares-demo-estate"}' \
| python3 -c 'import sys,json;print(json.load(sys.stdin)["token"])')"
TENANT="$(curl -sf "$BASE/v1/system/orgs" -H "Authorization: Bearer $TOKEN" \
| python3 -c 'import sys,json;[print(o["tenant_id"]) for o in json.load(sys.stdin)["items"] if o["slug"]=="demo"]')"
# The read/write access map — module III:
curl -sf "$BASE/v1/m/accessmap/graph?limit=200" \
-H "Authorization: Bearer $TOKEN" -H "X-Olivares-Tenant: $TENANT" | python3 -m json.tool
# The Permitted-vs-Observed drift:
curl -sf "$BASE/v1/m/accessmap/drift" \
-H "Authorization: Bearer $TOKEN" -H "X-Olivares-Tenant: $TENANT" | python3 -m json.tool

L’estate de démo retourne exactement 20 nœuds et 13 arêtes, et la dérive fait ressortir 8 accès inattendus et 2 autorisations inutilisées. Chaque arête porte les axes d’honnêteté du produit, afin que vous puissiez lire chaque constat sans deviner :

  • moderead / write / readwrite / unknown : la classification L/É, prise mot pour mot du signal, jamais déduite.
  • attribution_tierfirm / approximate / unknown : avec quelle fermeté l’accès est lié à une identité d’agent ou de charge de travail spécifique. Dans la démo, 6 arêtes sont firm et 7 approximate — par exemple un agent lisant une ressource qui ne lui a jamais été accordée (appdb.public.secrets, firm) versus une identité de pool partagé écrivant des journaux (appdb.public.logs, honnêtement approximate).
  • coverage_tierclean / lossy / opaque / mixed : la fidélité du signal de la ressource, orthogonale à l’attribution.

Le même graphe s’affiche dans l’interface web embarquée à http://127.0.0.1:8901 (connectez-vous avec les identifiants de démo et basculez vers l’organisation Demo Estate).

Arrêtez le serveur de démo (Ctrl-C) avant l’étape suivante.

4. Le prouver sur un véritable connecteur (pas une démo)

Section intitulée « 4. Le prouver sur un véritable connecteur (pas une démo) »

La fonctionnalité phare n’est pas une magie ensemencée : elle tourne sur ce que vos sources observent. Ici vous câblez le véritable connecteur pgAudit — le même chemin de code qu’utilise une installation de production — contre un journal d’audit PostgreSQL, sans seed de démo.

D’abord, un petit pgAudit csvlog (trois véritables lignes d’audit : deux lectures et une écriture par une application). En production, pgAudit écrit celles-ci dans le journal Postgres ; ici un fichier tient lieu de cette traînée :

Fenêtre de terminal
WORK="$(mktemp -d)"
python3 - "$WORK/postgresql.csv" <<'PY'
import csv, sys
def row(ts, user, db, msg, app):
r = [''] * 26
r[0], r[1], r[2] = ts, user, db
r[11] = 'LOG'; r[13] = msg; r[22] = app; r[23] = 'client backend'
return r
rows = [
row("2026-06-09 09:00:01.001 UTC", "claude_rw", "salesdb", "AUDIT: SESSION,1,1,READ,SELECT,TABLE,public.customers", "billing-agent"),
row("2026-06-09 09:00:02.002 UTC", "claude_rw", "salesdb", "AUDIT: SESSION,2,1,WRITE,INSERT,TABLE,public.orders", "billing-agent"),
row("2026-06-09 09:00:03.003 UTC", "claude_rw", "salesdb", "AUDIT: SESSION,3,1,READ,SELECT,TABLE,public.secrets", "billing-agent"),
]
with open(sys.argv[1], 'w', newline='') as f:
csv.writer(f).writerows(rows)
PY

Maintenant, effectuez un véritable premier démarrage : démarrez une fois sans identifiants par défaut, revendiquez le jeton de configuration à usage unique, et créez un tenant auquel rattacher le connecteur.

Fenêtre de terminal
BASE=http://127.0.0.1:8901
./bin/olivares serve --insecure \
--listen 127.0.0.1:8901 --grpc-listen 127.0.0.1:8902 \
--data-dir "$WORK/data" > "$WORK/server.log" 2>&1 &
SERVER=$!
sleep 2
# The one-time setup token is printed to stdout on first boot (look for `olst_…` on the
# server's console, or read it from the redirected log):
SETUP="$(grep -oE 'olst_[A-Z0-9]+' "$WORK/server.log" | head -1)"
curl -sf -X POST "$BASE/v1/setup" -H 'Content-Type: application/json' \
-d "{\"token\":\"$SETUP\",\"email\":\"admin@local\",\"password\":\"correct-horse-battery-staple\"}"
TOKEN="$(curl -sf -X POST "$BASE/v1/auth/login" -H 'Content-Type: application/json' \
-d '{"email":"admin@local","password":"correct-horse-battery-staple"}' \
| python3 -c 'import sys,json;print(json.load(sys.stdin)["token"])')"
TENANT="$(curl -sf -X POST "$BASE/v1/system/orgs" -H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' -d '{"name":"Production","slug":"prod"}' \
| python3 -c 'import sys,json;print(json.load(sys.stdin)["tenant_id"])')"
echo "tenant: $TENANT"
kill "$SERVER" # stop the first-run server; we restart it with pgAudit wired

Les connecteurs sont câblés depuis un seul fichier de configuration opérateur, par valeur, jamais persisté par le moteur. Pointez pgAudit vers le journal de votre tenant et redémarrez avec la configuration :

Fenêtre de terminal
cat > "$WORK/sources.json" <<JSON
{"sources":[{"name":"salesdb-pgaudit","kind":"pgaudit","tenant":"$TENANT",
"config":{"log_path":"$WORK/postgresql.csv","format":"csvlog"}}]}
JSON
OLIVARES_SOURCES_CONFIG="$WORK/sources.json" ./bin/olivares serve --insecure \
--listen 127.0.0.1:8901 --grpc-listen 127.0.0.1:8902 --data-dir "$WORK/data"

Le journal de démarrage affiche ingest: wired source … kind=pgaudit. Dans un second terminal, reconnectez-vous et lisez le graphe — cette fois les arêtes sont réellement analysées, pas ensemencées :

Fenêtre de terminal
TOKEN="$(curl -sf -X POST "$BASE/v1/auth/login" -H 'Content-Type: application/json' \
-d '{"email":"admin@local","password":"correct-horse-battery-staple"}' \
| python3 -c 'import sys,json;print(json.load(sys.stdin)["token"])')"
curl -sf "$BASE/v1/m/accessmap/graph?limit=200" \
-H "Authorization: Bearer $TOKEN" -H "X-Olivares-Tenant: $TENANT" | python3 -m json.tool
curl -sf "$BASE/v1/m/accessmap/drift" \
-H "Authorization: Bearer $TOKEN" -H "X-Olivares-Tenant: $TENANT" | python3 -m json.tool

Vous obtenez 3 arêtessalesdb.public.customers (lecture), …orders (écriture), …secrets (lecture) — chacune avec signal_source: pg_audit et coverage_tier: clean (pgAudit rapporte la L/É mot pour mot), et la dérive signale les 3 comme accès inattendus (aucune autorisation n’est encore câblée, donc chaque accès observé est une dérive).

Tout ce qui précède est vérifié, de bout en bout, contre le binaire réel :

Fenêtre de terminal
task smoke:quickstart # or: scripts/quickstart-smoke.sh

Il démarre l’estate de démo et le véritable chemin pgAudit, exécute les commandes exactes de cette page, et vérifie les nombres (20 nœuds / 13 arêtes, 8 inattendus + 2 inutilisés, 3 arêtes pgAudit réelles). Si le parcours installation→valeur ou le résultat de dérive cesse un jour d’être vrai, le smoke échoue — c’est le contrat qui garde cette page honnête. Il s’achève en quelques secondes de temps réel ; le parcours parcouru à la main ci-dessus correspond aux cinq minutes documentées.