Inspiration

Universities are connecting AI chatbots to student information systems — grades, tuition, academic standing, faculty salaries. This data falls under FERPA, one of the strictest data privacy frameworks in the US.

The industry's response has been input filtering — control what the model sees. But we found three gaps that input filtering alone cannot close.

The inference gap. Access control checks fields individually. But fields exist in mathematical relationships. A department budget, a headcount, and one person's salary are three authorized fields — but together they solve for everyone else's compensation. Every field passes access control. The combination leaks denied data.

The output gap. LLMs don't just retrieve — they reason. A model that never received a salary figure might reconstruct it from budget components, estimate it from training data, or infer it from context. The input was governed. The output wasn't.

The accumulation gap. Every governance tool evaluates queries in isolation. But a user asking three narrow questions across three conversation turns can reconstruct exactly the value that was withheld in a single broad query.

These aren't edge cases. They're structural gaps in how AI data governance works today. Arbiter was built to close all three.

What it does

Arbiter is a bidirectional AI governance middleware for regulated data environments. It sits between the data layer and the LLM, governing both directions.

Before the LLM sees data: Arbiter resolves identity and clearance, evaluates ABAC policies (clearance × sensitivity at runtime), classifies query intent for minimum necessary access, detects causal inference channels where authorized fields can derive denied fields, filters data through a generic engine with zero hardcoded resource names, and generates tamper-detectable audit records.

After the LLM responds: Arbiter scans the response for denied values (leakage), numeric claims not grounded in the authorized context (reconstruction), and masked field breaches — using the same policy object that governed the input.

Across the session: A session accumulator tracks every field revealed across conversation turns and fires when multi-turn accumulation enables a derivation that was blocked in a single query.

For users, it's a chatbot — a student sees their tuition, a teacher sees her class grades, an admin sees everything with SSNs masked. Five roles, five views, all resolved from config. For compliance teams, every query produces a full audit trail with trace IDs and policy hashes.

How we built it

Core principle: adding data, roles, or inference patterns should never require changing engine code.

The ABAC policy engine resolves access from clearance × sensitivity through access rules, exceptions, and prohibited combinations — all JSON config. The data filter uses a scope resolver registry where each scope type is a small pluggable function. The filter iterates over all resources without knowing their names.

Inference detection uses templates instead of hardcoded rules. A template defines a field pattern — "any resource with total_budget and num_faculty" — and the field to withhold. At runtime, templates match against every resource in the data. Add a new department with matching fields and detection fires automatically.

The cross-query accumulator maintains per-user session state. After each query, it checks derivation rules with min_queries gates to prevent false positives.

The output scanner receives the same PolicyDecision from input governance. It extracts numeric values from the response, compares them against raw data and filtered context, and flags values that exist in the database but weren't in the authorized context.

Frontend is three React pages — governed chat with pipeline visualization, split-screen demo (ungoverned vs governed), and admin dashboard with audit logs and context packets. The full governance pipeline runs in demo mode without an API key.

Challenges we faced

Scaling inference detection. Our first version hardcoded specific inference channels per department. It didn't scale. We redesigned around templates that match field patterns at runtime — inference risk is a property of field relationships, not specific resources.

Output scanner false positives. A student's own ID appearing in the response was flagged as "leaked from grades" because the value existed in a denied resource. We fixed this by checking whether flagged values already existed in the authorized filtered context.

Cross-query timing. The accumulator initially fired on query 1 because the data filter returns complete records — all budget components appeared in a single response. We added min_queries thresholds so detection only fires after data accumulates across distinct turns.

Template scope conflicts. The class-average inference template fired for teachers viewing their own classes — but teachers already see all grades, so the average reveals nothing. We scoped templates to only fire for roles with partial visibility where hidden values actually exist.

Staying deterministic. Every decision had to be reproducible — same input, same output, every time. No probabilistic scoring, no ML-based access decisions. Compliance needs certainty, not confidence intervals. This shaped the entire architecture.

What we learned

  • Inference detection is fundamentally different from access control. Perfect field-level authorization still leaks data through mathematical relationships between authorized fields.
  • Output governance is not optional. Input filtering controls what the model receives. Output scanning catches what the model invents.
  • Deterministic systems are the right choice for compliance. Auditors need "same input, same decision" — not risk scores.
  • Config-driven architecture pays for itself immediately. Every bug fix, every new feature, every edge case we handled during the hackathon required zero changes to the core engine — just config edits.
Share this project:

Updates