Skip to content
ONTO

Legal AI Agents Without the Confidentiality Headache

Privilege, confidentiality, conflicts checking, and the unauthorized practice of law — what your legal AI agent actually has to handle, and how to handle it cleanly.

· 10 min read · ONTO team

Legal AI has four hard problems that don’t have the same shape as healthcare or financial services:

  1. Attorney-client privilege is broken by disclosure to third parties.
  2. Conflicts of interest require not even appearing to use one client’s data on another.
  3. Unauthorized practice of law (UPL) rules forbid providing legal advice without a license.
  4. Confidentiality obligations under state bar rules are independent of privilege and apply broadly.

This post is about how to design an AI agent system that respects these by construction.

The privilege problem

Privilege protects communications between attorney and client from compelled disclosure. Disclosure to a third party — including a hosted AI vendor — can constitute a waiver, depending on jurisdiction and circumstances.

The conservative path is to keep all privileged material inside the firm’s network. That eliminates the “is sharing with vendor X a waiver?” question by not sharing.

For ONTO, this maps to the on-prem deployment story: open-weight models running locally (Ollama / vLLM), Postgres + pgvector for typed memory, your VPC, your KMS. No third-party API call touches privileged matter.

If you do want hosted models, do it under a vendor agreement that addresses confidentiality, with client consent where required. The ABA Formal Opinion 512 (2024) gives some structure here. But the cleanest answer is “no hosted vendor sees privileged material.”

The conflicts problem

A law firm can’t represent two clients with adverse interests on the same matter. Discovering a conflict is a deliberate process — every new matter is run against the conflicts database. An AI agent that’s processed Client A’s matter cannot, even theoretically, contaminate Client B’s matter.

The structural answer is domain-scoped memory. ONTO’s four-level extraction includes a domain scope:

# Matter intake for Client A.
onto.run_sync(
    intake_text,
    user_id="attorney_williams",
    domain_id="matter_4421_clientA",
    consent_scopes=["memory:write", "matter:read", "matter:write"],
    extract=True,
)

# Different matter, different client.
onto.run_sync(
    different_intake,
    user_id="attorney_williams",
    domain_id="matter_5512_clientB",
    consent_scopes=["memory:write", "matter:read", "matter:write"],
    extract=True,
)

The runtime stores Client A’s typed assertions in a separate partition from Client B’s. A read query without the right domain_id returns nothing. A tool that needs to cross domains has to declare required_consent=["matter:cross-domain"] — which you don’t grant to general matter work.

For the conflicts database itself, that’s a separate system (matter intake software, with its own controls). The AI agent’s job is not to be the conflicts check; it’s to not leak across matters in normal use.

The UPL problem

In most US states, providing legal advice without a license is unauthorized practice of law. An AI agent that talks to non-lawyer end users and produces legal advice can be UPL.

The right pattern is Plan Mode: the agent proposes; a licensed attorney reviews; only after attorney approval does the output go to the client.

# AI drafts a response to a client's question.
draft = onto.run_sync(
    "Draft a response to client question 14.",
    user_id="matter_4421",
    consent_scopes=["matter:read", "tasks:write"],
    mode="plan_only",
)

# Attorney reviews and edits.
approved_draft = attorney_review(draft)

# Approved draft goes out.
if approved_draft:
    onto.execute_task(
        approved_draft,
        consent_scopes=["matter:read", "client:communicate", "audit:write"],
    )

The attorney remains the legal decision-maker. The AI accelerates the work; it doesn’t replace the judgment. The audit log captures the attorney’s approval — useful for both UPL defense and malpractice insurance.

The confidentiality obligation

State bar rules treat all client information as confidential, not just privileged communications. This is broader than privilege. Disclosure of metadata, of the fact of representation, of even the existence of the matter can be a confidentiality breach.

For an AI system this means:

  • No logging of client identifiers in third-party telemetry. Plausible / Mixpanel / etc. — opaque the data.
  • No model training on client data without consent. ONTO doesn’t train; if you use a hosted model, the vendor agreement must prohibit training.
  • No transcript leak through error messages. Logs that contain prompt content must be in a controlled store with the same access rules as the matter.

ONTO’s telemetry exports per-run metadata (model_id, scopes, tool calls) but not prompt content by default. Configure the OpenTelemetry exporter accordingly.

The retention question

Different states have different rules on client file retention. Some require 5 years; some 7; some specific to matter type. The retention applies to AI-generated work product if it’s part of the file.

ONTO’s decay curves attach to assertions. A retention policy per domain_id purges expired assertions on schedule. The audit log records purges so you can demonstrate compliance.

  1. On-prem deployment with open-weight models for privileged matter.
  2. Domain-scoped memory partitioned by matter.
  3. Plan Mode for any output that goes to a client.
  4. Attorney approval captured in the audit log per output.
  5. Confidentiality-aware logging (no client content in third-party telemetry).
  6. Retention policy per matter, with documented purge procedure.
  7. Vendor agreements with appropriate confidentiality terms if any hosted service is in the path.

If those seven are in place, your legal AI deployment is in defensible shape.

What ONTO doesn’t do

To be honest:

  • Conflicts checking is a separate system. ONTO partitions memory to prevent accidental leak; it does not screen new matters against the conflicts database. That’s still your matter management software.
  • Privilege log generation is a separate workflow. ONTO records what the agent saw; constructing a privilege log for discovery is a manual or semi-automated process on top.
  • State-by-state UPL nuance is your problem. ONTO supports the supervised-attorney pattern; whether that pattern satisfies your state’s specific UPL rules is a legal question, not a technical one.

The job of the SDK is to give you the primitives that make the technical part defensible. The legal part remains a human judgment.

The summary

Privilege, confidentiality, conflicts, and UPL aren’t insurmountable. They’re solved structurally — domain scoping, Plan Mode, attorney supervision, retention policies — rather than prompt-engineered around. If your legal AI deployment fights these problems at the prompt layer, you’ve built a fragile system. If it solves them at the runtime layer, you’ve built one that can survive an audit and a malpractice claim.


See the comparison page for how other agent SDKs handle this. The features page covers consent scopes in detail.

Frequently asked questions

Can an AI agent be 'practicing law without a license'?

If it provides legal advice to a non-lawyer client without attorney oversight, yes — in most US states this would be UPL. Plan Mode + supervised execution lets a licensed attorney remain the legal decision-maker while the AI handles the volume.

How do I prevent client A's privileged data from leaking into client B's context?

Domain-scoped extraction (one of ONTO's four extraction levels) partitions memory by domain_id. The runtime refuses cross-domain reads when the consent scopes don't permit. A client's typed memory is in a separate partition that the system can't accidentally cross.

Is on-prem necessary for legal AI?

Strongly preferred for privileged matter. Many state bar rules treat client data sent to a third party as a potential confidentiality breach without explicit client consent and vendor controls. Self-hosted open-weight models avoid that entire branch of the problem.

Build with ONTO

The agent SDK where humans drive the state.

Plan Mode, typed memory, per-call consent scopes, and open-weight defaults. Open source under MIT or Apache-2.0.