Ir al contenido

Inicio rápido

Esta es la vía rápida para ver para qué sirve Olivares AI: un mapa de acceso de lectura/escritura de tu estate y la desviación Permitido-frente-a-Observado sobre él — la brecha entre el acceso que se concede a un agente y el acceso que se observa que usa.

Llegarás a ese resultado dos veces, en unos cinco minutos en total:

  1. En un minuto, sobre el estate de demostración incluido — la vía de entrada instantánea para ver “qué pinta tiene esto” (observaciones sintéticas, fluyendo a través del motor real).
  2. Luego sobre un conector real — el mismo grafo y la misma desviación, esta vez parseados literalmente desde un log pgAudit de PostgreSQL, para demostrar que el resultado estrella corre sobre datos genuinos, no una demo.

Todos los comandos de abajo los ejecuta, exactamente tal como están escritos, scripts/quickstart-smoke.sh (reproducibilidad) — así que esta página no puede desviarse silenciosamente del binario.

Es una vía de aprendizaje, no un despliegue de producción. Para la instalación real (sin credenciales por defecto, un token de configuración de un solo uso, TLS), ve a autoalojamiento. Para un recorrido guiado por la UI, consulta el tutorial de cero a grafo.

Desde un clon del repositorio (necesita Go 1.26+, Task y pnpm — task build empaqueta la UI web antes de compilar; el almacén es SQLite puro en Go, así que no hace falta toolchain de C):

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

task build produce un único artefacto autocontenido en ./bin/olivares — el motor, la UI web embebida y los plugins de conectores de primera parte. Las instalaciones en contenedor y Kubernetes envuelven este mismo binario: una imagen publicada más un fichero Compose (autoalojamiento), o un manifiesto plano que aplicas con kubectl apply -f deploy/manifests/install.yaml (sin necesidad de Helm). El resultado estrella que ves abajo es idéntico en las tres — solo difiere la semilla de demostración (solo loopback, nunca en una instalación real).

2. Arranca el estate de demostración (solo loopback)

Sección titulada «2. Arranca el estate de demostración (solo loopback)»
Ventana 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 sirve HTTP en texto plano sobre loopback (correcto para una demo local; TLS está activado por defecto en cualquier otro caso). Verás líneas WARN honestas para los seams que vienen deny-closed de fábrica (sin juez, sin embedder, sin gate de aprobación, sin fuentes reales), y luego un banner de DEMO MODE con las credenciales:

demo@olivares.local / olivares-demo-estate

El estate sintético fluye a través del bus de eventos real exactamente como lo haría un colector pgAudit u OpenTelemetry en vivo — solo las observaciones están sembradas.

3. Llega al grafo de acceso y a su desviación (el resultado estrella)

Sección titulada «3. Llega al grafo de acceso y a su desviación (el resultado estrella)»

Deja el servidor corriendo; en una segunda terminal, inicia sesión, resuelve el tenant de demostración y obtén el grafo y su desviación:

Ventana 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

El estate de demostración devuelve exactamente 20 nodos y 13 aristas, y la desviación saca a la superficie 8 accesos inesperados y 2 concesiones sin usar. Cada arista lleva los ejes de honestidad del producto, para que puedas leer cada hallazgo sin adivinar:

  • moderead / write / readwrite / unknown: la clasificación de L/E, tomada literalmente de la señal, nunca inferida.
  • attribution_tierfirm / approximate / unknown: con qué firmeza el acceso está ligado a una identidad de agente o de carga de trabajo específica. En la demo, 6 aristas son firmes y 7 aproximadas — p. ej. un agente leyendo un recurso que nunca le fue concedido (appdb.public.secrets, firme) frente a una identidad de pool compartido escribiendo logs (appdb.public.logs, honestamente aproximada).
  • coverage_tierclean / lossy / opaque / mixed: la fidelidad de la señal del recurso, ortogonal a la atribución.

El mismo grafo se renderiza en la UI web embebida en http://127.0.0.1:8901 (inicia sesión con las credenciales de demostración y cambia a la organización Demo Estate).

Detén el servidor de demostración (Ctrl-C) antes del siguiente paso.

4. Demuéstralo sobre un conector real (no una demo)

Sección titulada «4. Demuéstralo sobre un conector real (no una demo)»

El resultado estrella no es magia sembrada: corre sobre lo que sea que tus fuentes observen. Aquí cableas el conector pgAudit real — la misma vía de código que usa una instalación de producción — contra un log de auditoría de PostgreSQL, con ninguna semilla de demostración.

Primero, un pequeño csvlog de pgAudit (tres líneas de auditoría reales: dos lecturas y una escritura por una aplicación). En producción pgAudit escribe estas en el log de Postgres; aquí un fichero hace las veces de ese tail:

Ventana 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

Ahora haz un primer arranque real: arranca una vez sin credenciales por defecto, reclama el token de configuración de un solo uso y crea un tenant al que adjuntar el conector.

Ventana 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

Los conectores se cablean desde un único fichero de configuración del operador, por valor, nunca persistido por el motor. Apunta pgAudit al log de tu tenant y reinicia con la configuración:

Ventana 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"

El log de arranque imprime ingest: wired source … kind=pgaudit. En una segunda terminal, inicia sesión de nuevo y lee el grafo — esta vez las aristas están genuinamente parseadas, no sembradas:

Ventana 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

Obtienes 3 aristassalesdb.public.customers (lectura), …orders (escritura), …secrets (lectura) — cada una con signal_source: pg_audit y coverage_tier: clean (pgAudit reporta L/E literalmente), y la desviación marca las 3 como accesos inesperados (aún no hay ninguna concesión cableada, así que todo acceso observado es desviación).

Todo lo de arriba está aseverado, de extremo a extremo, contra el binario real:

Ventana de terminal
task smoke:quickstart # or: scripts/quickstart-smoke.sh

Arranca el estate de demostración y la vía pgAudit real, ejecuta los comandos exactos de esta página y comprueba los números (20 nodos / 13 aristas, 8 inesperados + 2 sin usar, 3 aristas pgAudit reales). Si la vía de instalación→valor o el resultado de desviación dejara alguna vez de ser cierto, el smoke falla — ese es el contrato que mantiene honesta esta página. Se completa en unos pocos segundos de reloj; la vía recorrida por un humano de arriba son los cinco minutos documentados.