From zero to a read/write access graph
By the end of this tutorial you will have Olivares AI running locally and will have reached its central artifact: a read/write access graph with a real Permitted-vs-Observed drift result. You will learn the product by seeing it work — this is a learning path, not a production install (for that, see self-hosting).
We use the bundled demo estate (--seed-demo): a small synthetic set of agents,
identities and resources that flows through the real event bus exactly as a live
pgAudit or OpenTelemetry collector would. Everything runs on localhost.
Prerequisites
Section titled “Prerequisites”- Go 1.26+ (to build the binary), or Docker (see the self-hosting how-to for the container path).
curlandpython3to talk to the API from the shell.- A checkout of the Olivares AI repository.
Build and boot
Section titled “Build and boot”-
Build the single binary. From the repository root:
Terminal window task setup # install git hooks, commit tooling and web depstask build # compile the static binary with the web embedded (go:embed)./bin/olivares versiontask buildbuilds the web bundle, the first-party connector plugins and the binary, producing one self-contained artifact at./bin/olivares. -
Boot it with the demo estate on loopback. Pick a fresh data directory so you start clean:
Terminal window 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"The
--insecureflag serves plaintext HTTP on loopback (fine for a local tutorial; TLS is on by default otherwise). On boot you will see a DEMO MODE banner with the demo credentials:demo@olivares.local / olivares-demo-estate
Reach the access graph
Section titled “Reach the access graph”Leave the server running and open a second terminal.
-
Log in with the demo credentials to get a bearer token:
Terminal window BASE=http://127.0.0.1:8901TOKEN="$(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"])')" -
Resolve the demo tenant (the access-map endpoints are tenant-scoped):
Terminal window 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"]')" -
Fetch the read/write graph. This is module III — the access map:
Terminal window curl -sf "$BASE/v1/m/accessmap/graph?limit=200" \-H "Authorization: Bearer $TOKEN" -H "X-Olivares-Tenant: $TENANT" | python3 -m json.toolThe demo estate returns roughly 20 nodes and 13 edges — agents, identities, MCP servers, models, providers and resources, with each edge classified read or read-write.
-
Fetch the Permitted-vs-Observed drift:
Terminal window curl -sf "$BASE/v1/m/accessmap/drift" \-H "Authorization: Bearer $TOKEN" -H "X-Olivares-Tenant: $TENANT" | python3 -m json.toolThis surfaces the seeded unexpected accesses, for example:
- an agent reading
appdb.public.secretsit was never granted (attributed); and - a shared pool identity writing
appdb.public.logs(approximate attribution).
- an agent reading
-
(Optional) See the whole seeded inventory:
Terminal window curl -sf "$BASE/v1/m/inventory/summary" \-H "Authorization: Bearer $TOKEN" -H "X-Olivares-Tenant: $TENANT" | python3 -m json.tool
See it in the web UI
Section titled “See it in the web UI”The web UI is embedded in the same binary and served from the same origin. With the demo server still running, open:
http://127.0.0.1:8901Log in with the demo credentials and open the access-map view: the graph renders the same nodes and edges, with the drift overlay highlighting the unexpected accesses and the dashboards summarizing the estate.
What is not happening here (and what to do next)
Section titled “What is not happening here (and what to do next)”- The demo data is synthetic and the demo password is public — this is not a secure deployment. For a real one, follow self-hosting: it has no default credentials and uses a one-time setup token.
- The module endpoints used above (
/v1/m/accessmap/*,/v1/m/inventory/*) are reachable but are not part of the served OpenAPI document by design; the API reference documents the core REST surface. - To understand why the graph is built this way (cooperative telemetry crossed with native store audit, eBPF as a backstop, MCP annotations treated as untrusted), read the architecture overview.