For Databricks · Agent Bricks · Unity Catalog · Unity AI Gateway · Managed MCP servers · MLflow

Every agent action on the lakehouse,
independently judged before it runs.

Three data actions below are shaped exactly as they leave an agent on Databricks — a governed tool call, a job the agent triggers, an MCP tool call to a managed server — and each one goes through the live Veridect system on this page. On your side the integration is one tool function, one task at the head of a job, or a URL change in the MCP connection. Behind it is the whole control plane: consensus from frontier models across independent vendors, deterministic policy classes, risk routing, a hash-chained ledger, and an Ed25519-signed decision record you can verify right here.

Open the full live tour
3 seams
a tool, a job task, or one MCP URL — your agents, catalogs, endpoints and models stay exactly as they are
1 judgment
POST /pre-action — behind every path (the MCP gateway makes that call for you); the answer is a verdict plus a signed record
1 record each
every decision — pass, hold or refusal — is a signed record, exportable as newline-delimited JSON into a Delta table beside your MLflow traces
0 trust required
every decision re-derives from its recorded inputs and verifies against a published key — try it below
Where it sits

Between the agent’s reasoning and the write.

Databricks runs the agent: Agent Bricks builds it, Unity Catalog owns the tables, functions and permissions, Unity AI Gateway governs which endpoints and tools it may reach, managed MCP servers hand it Genie, SQL and catalog functions, and MLflow traces every step. Veridect sits at the one moment none of those were built to own: the instant before a write with consequences executes — a table changed, rows deleted, a customer record rewritten, a job released — when an independent judgment — not the model that proposed the action, not the platform that hosts it — decides whether it goes, waits for a person, or never happens, and signs the record either way.

Your agent on Databricks

Proposes an action

  • Agent Bricks and custom agents proposing writes through tools
  • Jobs and pipelines an agent triggers that update, merge, delete or publish
  • Any MCP tool an agent reaches — managed by Databricks or registered as external
Veridect · live control plane

Judges it before it runs

  • Deterministic scope check against the agent’s configured authority
  • Policy classes in code — money thresholds, protected data, regulated data, cumulative exposure
  • Multi-vendor model consensus with calibrated confidence and a dissent register
  • Risk routing: greenlight, escalate to a named human queue, or block
  • Hash-chained, Ed25519-signed record — written whether it passes or not
Outcome

Three doors, one record

greenlightthe write runs, the job proceeds or the tool call is forwarded; the verdict and record id travel with it
escalateheld for a person in the queue the policy names — the tool returns the verdict, the job stops at the judgment task, the tool call waits
blocknever executes — and the refusal is on the ledger too
Three thin paths

The integration is thin. The system behind it is not.

Each path maps the call your agent was already making onto one judgment — POST /api/ai/consensus/pre-action, made by your tool, your job task, or the MCP gateway on your behalf: the verb, the target table or object, the fields, which agent is asking, and what that agent is authorized to do. Nothing about the agent, the model, the catalog or the endpoint changes. The verdict decides whether the original action proceeds.

PATH 01 · AGENT TOOL · GOVERNED WRITE

The write tool asks first

Agents on Databricks act through tools — Unity Catalog functions or Python functions in the agent’s own code. Wrap the write in one governed tool that accepts only allowlisted tables and columns and a single key, posts to Veridect, and performs the SQL only on a greenlight, returning the verdict and the record id to the agent either way. The agent holds EXECUTE on this tool and no write privilege of its own; humans keep theirs.

~35 lines · one tool function · allowlisted tables, agents hold no write grants

Fail-closed by construction: a network error, a timeout or a malformed response never reaches the SQL branch. The Veridect key lives in a Databricks secret scope, never in the notebook or the agent’s prompt.

# the agent's only write tool — asks Veridect, then runs the SQL on greenlight
import os, requests
from databricks.sdk import WorkspaceClient
from databricks.sdk.service.sql import StatementState

WRITABLE = {                                                                   # identifiers can't be parameterized — allowlist them
    "crm.gold.accounts": {"account_tier", "owner_team"},
    "crm.silver.customers": {"phone_number", "email_address"},
}
KEYS = {"crm.gold.accounts": "account_id", "crm.silver.customers": "customer_id"}

def governed_update(table: str, set_fields: dict, key_value: str, agent_id: str, agent_scope: str) -> dict:
    """Update one row in an allowlisted Unity Catalog table. The change runs only on a Veridect greenlight."""
    if table not in WRITABLE or not set_fields or not set(set_fields) <= WRITABLE[table] or not key_value:
        return {"executed": False, "verdict": "rejected_by_tool", "record_id": ""}   # unknown table/column or no key: never asked, never run
    verdict, record_id = "unavailable", ""                                  # closed until proven open
    try:
        r = requests.post("https://<your-veridect-host>/api/ai/consensus/pre-action", timeout=60,
            headers={"Authorization": "Bearer " + os.environ["VERIDECT_API_KEY"]},   # from a secret scope
            json={"action": "update_record", "target": "unity_catalog:" + table,
                  "parameters": {"set": set_fields, "where": {KEYS[table]: key_value}},
                  "callingAgent": agent_id, "callingAgentScope": agent_scope,       # its configured authority, in words
                  "department": "data_operations"})
        d = r.json() if r.status_code == 200 else {}
        verdict, record_id = d.get("verdict", "unavailable"), d.get("auditBundleId", "")
    except Exception:
        pass                                                                # network, timeout, parse: all stay closed
    if verdict != "greenlight":
        return {"executed": False, "verdict": verdict, "record_id": record_id}
    sets = ", ".join(f"`{c}` = :{c}" for c in set_fields)                        # identifiers from the allowlist, values as parameters
    resp = WorkspaceClient().statement_execution.execute_statement(
        warehouse_id=os.environ["WAREHOUSE_ID"], wait_timeout="50s",
        statement=f"UPDATE {table} SET {sets}, veridect_record = :rec WHERE `{KEYS[table]}` = :key",
        parameters=[*({"name": c, "value": str(v)} for c, v in set_fields.items()),
                    {"name": "key", "value": key_value}, {"name": "rec", "value": record_id}])
    ok = resp.status is not None and resp.status.state == StatementState.SUCCEEDED   # pending or failed is not "executed"
    return {"executed": ok, "verdict": "greenlight", "record_id": record_id, "statement_state": str(resp.status.state if resp.status else "unknown")}
PATH 02 · JOB · JUDGMENT TASK

A judgment task at the head of any job an agent triggers

When the agent’s action is a job — a merge, a backfill, a publish to a gold table — make the first task the Veridect judgment. It posts the proposed action, writes the verdict and the record id to task values, and fails the run on anything but a greenlight; every downstream task depends on it. The job’s own tasks do not change.

1 task · one notebook at the head · the rest unchanged

Where the authority lives: the scope string is the agent’s configured authority. A read-only analyst agent that proposes to drop a gold table is a categorical no-authority action — the deterministic layer blocks it before any model is asked to weigh in. Watch it below. The policy classes work over field names; send values only for the fields your policy needs.

# jobs.yaml (Databricks Asset Bundle) — the judgment task gates every downstream task
resources:
  jobs:
    publish_revenue_daily:
      tasks:
        - task_key: veridect_judgment
          notebook_task: { notebook_path: ./judgment.py }
          # judgment.py posts the agent's proposal to /pre-action, sets task values
          #   dbutils.jobs.taskValues.set("verdict", d["verdict"]); ...set("record_id", d["auditBundleId"])
          #   and raises on anything but "greenlight" — a raised task never reaches ALL_SUCCESS
        - task_key: merge_gold
          depends_on: [{ task_key: veridect_judgment }]       # run_if defaults to ALL_SUCCESS
          notebook_task:
            notebook_path: ./merge_gold.py
            base_parameters:
              veridect_record: "{{tasks.veridect_judgment.values.record_id}}"   # the record id rides into the write
        - task_key: publish
          depends_on: [{ task_key: merge_gold }]
          notebook_task: { notebook_path: ./publish.py }

# judgment.py — the body the task posts (callingAgentScope = the agent's configured authority, in words)
{ "action": "merge_table", "target": "unity_catalog:finance.gold.revenue_daily",
  "parameters": { "source": "finance.silver.revenue_events", "mode": "upsert" },
  "callingAgent": "finance-publish-agent", "callingAgentScope": "may read silver finance tables and may merge them into the gold revenue tables" }
PATH 03 · MCP · MANAGED & EXTERNAL SERVERS

One MCP URL in front of the managed server

Databricks exposes Unity Catalog functions, Genie spaces, SQL and AI Search as managed MCP servers at workspace URLs, and lets you register external MCP servers in the catalog. Register the server as a Veridect upstream once and give the agent the Veridect gateway URL instead. Every tools/call is judged in flight; tools/list, initialize and everything else pass straight through. A refused call is never forwarded.

0 lines of agent code · one registration, one URL

Identity on the wire: the agent’s identity, run id and business context ride in params._meta["veridect/…"] — unsigned, that is the caller’s own claim, and the decision record marks it as such; a tenant can require a signed Ed25519 identity envelope on every call, and an unsigned call is then refused inside the protocol. Both outcomes run live below.

# 1) once — register the managed MCP server as an upstream (admin call)
POST /api/ai/consensus/mcp/upstreams/{tenant}
{ "upstreamId": "uc-functions-crm",
  "url": "https://<workspace-hostname>/api/2.0/mcp/functions/crm/ops", "enabled": true }   # catalog/schema — every function in the schema

# 2) the agent's MCP connection — one URL changes (Agent Bricks, a custom agent, or any MCP client)
before:  https://<workspace-hostname>/api/2.0/mcp/functions/crm/ops
after:   https://<your-veridect-host>/api/mcp/gateway/uc-functions-crm
HEADERS = {
  "Authorization":            "Bearer <VERIDECT_API_KEY>",            # your Veridect tenant
  "X-Upstream-Authorization": "Bearer <Databricks OAuth token>",      # forwarded to the workspace as Authorization
}

# 3) what the agent sees on a greenlight: the server's own result, plus
#    result._meta["veridect/verdict"] and result._meta["veridect/bundleId"]
#    on escalate / block: a JSON-RPC error (-32003 / -32004) carrying the
#    verdict and the record id — and the workspace never receives the call.
Run it live

Four lakehouse-shaped actions, through the live system, now.

Each card sends the exact request the governed tool, the judgment task, or the MCP connection would send, to the live Veridect system on a shared sandbox tenant. The verdicts are real multi-model decisions made while you wait; the records are written to the ledger and signed; the Verify button re-derives the verdict from the recorded inputs and checks the signature against the published key. Expected outcomes are stated in advance — the engine decides.

Ready. Each decision takes a few seconds while the model roster deliberates.
LIVE 01 · PATH 01 · GOVERNED TOOL

Re-tier an account and reassign its owner

An account-operations agent proposes update_record on crm.gold.accounts: tier raised to enterprise and owner moved to the strategic team, after reading the latest usage figures. Its configured authority: “may read account tables and may update account tier and owner fields.”

Expected: greenlight — inside authority, no policy class fires, the roster agrees. The tool runs the update and the record id lands in the row.

Waiting. Request shape: the governed tool’s body, verbatim.
LIVE 02 · PATH 02 · JUDGMENT TASK

A read-only analyst agent tries to drop a gold table

A revenue-analyst agent proposes drop_table on finance.gold.revenue_daily after judging it a stale duplicate of a newer table. Its configured authority: “read-only: may query finance and sales tables to answer questions and draft summaries.”

Expected: block — a read-only agent proposing to drop a table is a categorical no-authority action; the deterministic scope check decides, the models are consulted for the record, and the judgment task fails the run before any downstream task starts.

Waiting. Request shape: the judgment task’s body, verbatim.
LIVE 03 · PATH 01 · GOVERNED TOOL

Rewrite a customer’s phone and email in the silver table

A customer-data agent, inside its authority (“may read customer tables and may update customer contact fields on verified change requests”), calls update_record on crm.silver.customers setting a new phone_number and email_address.

Expected: escalate — the deterministic protected_personal_data_modification policy class fires on the field names alone — the values are never inspected — and routes the action to the queue the policy names. Authorized but consequential actions escalate to a person; they are never silently blocked and never silently allowed.

Waiting. Request shape: the governed tool’s body, verbatim.
LIVE 04 · PATH 03 · MCP

The same tools/call, two tenants, two outcomes

A JSON-RPC tools/call for lookup_policy_limit goes through the live Veridect MCP gateway to a sample tool server that counts what it actually receives — the call an agent would make to a managed MCP server. First on the shared sandbox tenant; then on a tenant that requires a signed identity envelope, sent without one.

Expected: first call forwarded, the tool’s own hit counter goes up by one and the result carries _meta["veridect/bundleId"]; second call refused inside the protocol (-32004 identity_not_presented), counter unchanged, refusal on the ledger.

Waiting. Request shape: JSON-RPC 2.0, verbatim.

What on this page is live, and what is illustrative

Live: every verdict, confidence, dissent register, policy class, escalation route, ledger write, hash chain, Ed25519 signature, MCP forwarding decision and verification result above comes from the production Veridect system on a shared sandbox tenant — the same endpoints an integrator calls. The consensus roster is four frontier providers from independent vendors with a decisive-verdict early stop, so a decision on this surface typically records three; the models are named in each record’s dissent register. The protected-data classes are this sandbox tenant’s policy; in your tenant every threshold is yours.

Illustrative: the agent side. No Databricks agent, job or SQL statement executes from this page; each card sends the exact request the governed tool, the judgment task or the MCP connection would send, so what you watch is the decision those integrations would receive. The MCP calls in Live 04 leave this browser as a standard MCP client; a Databricks-hosted agent’s MCP connection was not exercised here. The code above is written against the documented Databricks SDK statement-execution API, Jobs task dependencies and task values, and the managed MCP server URL scheme; the bundle is shown schematically, and the tool-server URL is a placeholder for your own. The integration is demonstrated wiring, not a Databricks-certified, Marketplace-listed or endorsed solution.

Verification proves that the enforcement decision re-derives from the recorded inputs and that the record is unmodified and signed by the published key. It does not re-run the models: the consensus summary is attested through the recorded dissent register and verifier-text hash, and disclosed as such in the proof itself.

Databricks, Agent Bricks, Unity Catalog, Lakehouse, Genie, Delta and other Databricks marks are trademarks of Databricks, Inc. MLflow is a trademark of LF Projects, LLC. Veridect is an independent company and is not affiliated with or endorsed by Databricks.

Five questions, answered for a Databricks team

The short version.

How does this help?

It lets agents on the lakehouse into the writes that carry consequences — table changes, merges into gold, customer records, jobs that publish — because an independent judgment stands in front of each action and a signed record stands behind it. The model that proposes the action is never the one that approves it.

How do I integrate it?

One of the three paths above: a governed tool in the agent, a judgment task at the head of the job, or one MCP URL. Your agents, catalogs, endpoints and models stay as they are. The decision records export as newline-delimited JSON into a Delta table beside your MLflow traces. It runs where you say, on your keys.

How long does it take?

The system is live today. A private sandbox on your own policy thresholds in a day once you say go; production typically about two weeks, with the pace set mostly on your side — security review, keys, access. Ours is ready on day one.

How does this make money?

Three levers, none of them invented here: revenue held back because agents could not be trusted with the consequential step; cost stopped on human review of actions a signed record now settles; losses not taken on the actions that should never have executed. Your own number comes out of the sandbox.

Why you and not a big well-known company?

Because the judgment has to be independent of the model and of the platform to be worth anything to an auditor. Unity Catalog permissions and Unity AI Gateway policies are the platform’s view of its agents — who may reach what; a platform grading its own agents is self-governance. Veridect is a separate control plane with its own ledger and keys, validated by an external red team on scope-violation semantics, and verifiable offline. Try to forge a record on the live tour; the engine refuses it.

Test-drive it yourself.

Run the four actions above, verify the records, then take the full live tour — identity envelopes, delegation chains, cross-agent exposure, the fleet layer, and the forgery the engine refuses. Seven minutes, open access.

Prefer to see it on your own scenarios? Paste one on the pre-action console — or write to lrussell@veridect.ai and a scoped production sandbox on your own thresholds and your own tenant follows in a day.

The same control plane, built the same way for Snowflake, Microsoft, AWS, ServiceNow, CrowdStrike, Rubrik, Salesforce, Okta and Google Cloud — one engine behind all ten pages, each run live. All ten platforms →