Agent Governance — one control plane, both front doors

Agent Governance — one control plane, both front doors

Status: proposal (v0.3/v0.7+) · Owner: product

LessDB is one database with two front doors — MCP for agents, HTTP/SDK/CLI for humans — and a third, always-on property: everything that happens is recorded and attributable. This document specifies the control plane that makes the shared-database story safe, and the concrete features that get us there from what exists today.

1. Today (v0.1 reality, verified in code)

CapabilityStatus
LDAP/AD + file auth with roles (admin/read/write)✅ HTTP server only (less-auth)
Fail-closed group→role mapping, injection-safe filters, auth-failure counters✅ HTTP server
MCP server, 27 tools (less_ shared engine, context_/memory_/vector_ tenant-scoped)
Append-only audit log (<data_dir>/audit/, NDJSON, less audit)implemented — every MCP tool call recorded (caller, tool, role, outcome, SQL detail, duration)
Agent tokens (less token create/list, SHA-256-hashed store at auth/tokens.json)implemented
MCP-door auth + tool→permission map (less mcp --require-auth, role ladder admin>write>read, fail-closed)implemented
Per-agent tenancy (less mcp --tenant <name>)✅ namespaced under <data_dir>/tenants/
Prometheus metrics incl. auth failures
JWT/bearer tokens and mTLS for service-to-service access❌ roadmap (v0.7)
Table-level grants, RLS + masking, approvals, quotas, lineage❌ roadmap (P0/P1/P2 below)

The gap: a human connecting over HTTP is authenticated and role-checked, but an agent spawning less mcp --dir <data> gets unrestricted access to the shared engine — every table, every SQL statement, every optimize. That is the single biggest trust blocker for the "agents and humans share one database" positioning, and it is our natural wedge: most agent data stores have no audit story at all; most governed databases have no agent story at all.

2. Principles

  1. One identity, both doors. An agent principal and a human principal are
  2. the same object — a name, a role, a set of grants. No parallel worlds.

  1. Fail-closed everywhere. The MCP door inherits the HTTP door's
  2. fail-closed philosophy: unknown caller → deny.

  1. Attributable by default. Every authenticated action lands in the audit
  2. log with caller, tool/SQL, role, outcome, and cost (rows scanned). Agents are accountable exactly like humans — because they are just another caller.

  1. Humans hold the veto. Grants, schema changes, and "dangerous" tool
  2. classes default to human approval. Agents propose; humans dispose.

  1. Boring primitives. RBAC + audit + tenancy + approval — no ML, no
  2. "AI governance" magic. Deterministic, reviewable, compliance-shaped.

3. Feature spec

3.1 Agent identity (MCP auth) — new, P0

3.2 Tool → permission map — new, P0

Every MCP tool gets a permission class; the role check happens before the tool executes:

ToolsPermission
less_query, less_explain, less_schema, less_stats, less_tables, vector_search, vector_list, context_get/find/neighbors/pathread
less_insert (future), less_optimize, context_put/link/unlink, memory_insert/update, vector_put/addwrite
DDL (less_create, less_drop when added), token management, memory_create/dropadmin

3.3 Audit log — elevate existing v0.7 TODO to P0

Append-only NDJSON log, one per data dir: <data_dir>/audit/audit-<date>.ndjson (+ object store for shared dirs).

{"ts":"2025-…","caller":{"kind":"agent|human","name":"claude","tenant":"alice"},"door":"mcp|http|sdk","action":"tools/call","tool":"less_query","sql":"SELECT …","role":"read","outcome":"ok|denied|error","rows_scanned":4102559,"dur_ms":7.9}

3.4 Human approval gates — new, P1

3.5 Guardrails for the shared engine — new, P1

3.6 Tenancy completion — extend existing P2 work

3.7 Row-level security + column masking — new, P2

Enterprise buyers check RLS and masking first — they are the de-facto test of "real" governance (RESEARCH §3). Design:

3.8 Data lineage — new, P2

4. Where this lands in the code

FeatureCrates touched
Token store, role model reuseless-auth (new TokenStore, Authenticator impl)
MCP auth + permission mapless-mcp (initialize/authz middleware, tool metadata permission field)
Audit writer + less auditless-telemetry (new AuditLog), less-cli, less-server, less-mcp
Approvalsless-mcp (pending store), less-cli/less-server admin surface
Quotasless-query (execution guards)
Table grants + policy evalless-catalog (grants in table manifest), less-query (pre-exec check)

5. Sequencing (revised roadmap)

  1. P0 — audit log + MCP tokens + tool→permission map (weeks): closes the
  2. trust gap, unblocks the "shared database" story end-to-end.

  1. P0 — table grants on top of the catalog (small: manifest field +
  2. check).

  1. P1 — approvals + quotas + schema governance flags.
  1. P1 — OAuth 2.1/PKCE resource-server flow on the MCP door +
  2. JWT/mTLS for service-to-service (already in v0.7), TLS for MCP streamable transports.

  1. P2 — RLS + column masking + OpenLineage, signed policy bundles
  2. (Cedar/Rego hook), OpenTelemetry traces — the enterprise compliance tier.

Each stage ships with CLI, HTTP, and MCP surfaces simultaneously — the control plane is a feature of the database, not of one integration.