Inspiration
Every agent-permission model shares one blind spot: the gap between the human's "yes" and the agent's action.
RBAC answers who can do what. OAuth scopes answer what a token may touch. An approval queue answers did a person say yes. None of them answer whether that yes is still valid at the moment the agent actually acts.
A human approves deprecating a production table when it has two critical downstream consumers. Minutes later — before the agent executes — a third is wired up by a dbt job or another team. The world that justified the approval is gone, and nothing notices. The table gets deprecated with three dashboards depending on it, and a clean-looking audit trail. We built DataHubX to close exactly that gap, live against a real DataHub.
What it does
DataHubX is a governance layer for AI agents making real DataHub changes. Every change is approved against live data and re-verified at execution — if the data changed since approval, the action is blocked.
- The agent proposes one governed action. It reads DataHub through the official MCP server with every write tool disabled — it has no way to mutate anything.
- A policy engine deterministically returns ALLOW / REVIEW / BLOCK and declares which context fields its decision depended on.
- A Passport captures exactly those fields from DataHub and hashes them into an SHA-256 fingerprint — the record of the world the human is about to approve.
- A human approves that action against that fingerprint, producing an Ed25519-signed, single-use, 15-minute authorization (or a persisted rejection).
- The Gateway — the only mutation path in the system — runs fifteen checks in order before any write, ending in a fresh re-read of DataHub whose fingerprint must still match.
- Match → consume once, mutate, read the state back,
VERIFIED_SUCCESS. - Mismatch —
CONTEXT_DRIFT→ the authorization is permanently invalidated and DataHub is left byte-for-byte untouched. The agent replans against reality.
It runs live: the console drives a real self-hosted DataHub, and you can sign in to the catalog read-only and verify every mutation — or its absence — yourself.
How we built it
- Pure domain core (no I/O): action registry, canonicalization + SHA-256 fingerprinting where
absent,[]and""are three distinct worlds and unreadable context fails closed, deterministic policy with declared dependencies, and Ed25519 signing where verifying authority never means being able to mint it. - The Gateway: the single privileged path — fifteen ordered checks, consume-before-mutate, read-back verification. It's the only file that imports the mutation module, enforced by a test that walks every source file.
- DataHub integration: the security-critical Passport reads OpenAPI v3 aeage search — we measured search lagging real edge changes by 30+ seconds.The agent's discovery runs on the official
mcp-server-datahub, version-pinned, six read tools allowlisted. - State & evidence: Postgres 18 + Prisma. Consumption is one atomic conditional UPDATE (proven by a 20-racer test). The full chain — action → passport → decision → approval →authorization → execution → receipt — is one transaction, and even refused changes land on a public changelog.
- Delivery: Next.js 16 + Bun on a GCP VM behind Caddy, DataHub OSS v1.7 in Docker with auth enforced, GitHub Actions CI, one-command Docker tryout.
Challenges we ran into
- Lineage search cannot feed a security decision. We found this by measurement, not docs — so the Passport reads primary-store aspects; search is only for agent discovery, wherestaleness costs a suggestion, not a mutation.
- Unreadable ≠ empty. A narrowed DataHub token returns less rather than erroring, which would silently turn "production AND PII → REVIEW" into ALLOW. Readability is now part of the type — and this caught a real fail-open bug.
- Proving nothing happened. The hardest thing to demonstrate is a mutation that didn't occur. The golden scenario asserts DataHub's own state is byte-identical after therefusal.
Accomplishments we're proud of
The central claim is provable, not asserted: 60 unit tests (including an adversarial gateway-security suite that attempts parameter swaps, replays, tampered claims, policy changes, and dishonest verification), 10 Postgres race tests, and an end-to-end golden scenario that asserts DataHub state byte-for-byte. CI is green. The agent's inability to writeis structural, not a prompt — so prompt injection has nothing to reach for.
What we learned
Trust in an agent system shouldn't be a property of the model's behavior — it should be a property of the surrounding machine. The model can propose anything; it simply cannot execute anything the Gateway hasn't independently re-verified against current reality.
What's next
Authenticated approver identity; split deployment with per-component scoped credentials; step-level authorization for multi-step workflows; a policy-management UI; and providerconnectors beyond DataHub — the domain core already knows nothing about DataHub, so the Gateway is the only piece a new provider has to teach.
Built With
- bun
- caddy
- datahub
- docker
- google-gemini
- model-context-protocol
- next.js
- postgresql
- prisma
- react
- typescript
Log in or sign up for Devpost to join the conversation.