External API and MCP boundary
Target design · 21 September 2026. The public API and MCP server described here are not implemented yet. Today Legal Core accepts only short-lived internal workload JWTs issued for Kesita workloads. This page fixes the intended boundary before public contracts are introduced.
Open the interactive architecture diagram · Diagram source.
One authoritative legal service, two external protocols
Section titled “One authoritative legal service, two external protocols”External consumers do not connect directly to the Legal Core network endpoint, legal PostgreSQL or corpus blobs. They enter through a Kesita-owned public integration boundary. That boundary authenticates the external principal, resolves tenant and entitlement, applies scopes, content policy, quotas and idempotency, and records a bounded usage/policy receipt. It then exchanges that authority for a short-lived workload JWT accepted by Legal Core.
The Public API is the canonical application contract. The MCP server is an adapter over the same application services and policies; it must not become a second legal API or carry corpus credentials. ComproCausa and other Kesita-owned products use the same versioned server-to-server contract offered to partners, with their own client identity and entitlements.
flowchart LR
subgraph Consumers[External consumers]
Partner[Partner backend]
Compro[ComproCausa backend]
Host[MCP host]
end
subgraph PublicBoundary[Kesita public integration boundary]
MCP[Kesita MCP server]
API[Public Legal API<br/>api.kesita.ai/v1/legal]
Policy[Identity, scopes, entitlements<br/>content policy and quotas]
Meter[(Audit and usage receipts)]
end
subgraph PrivatePlane[Private legal data plane]
Core[Legal Core API]
Legal[(Legal PostgreSQL)]
Blobs[(Corpus originals)]
end
Partner -->|HTTPS + client grant| API
Compro -->|HTTPS + service identity| API
Host -->|MCP over HTTPS| MCP
MCP -->|Typed application calls| API
Policy -->|Principal + allowed capability| API
API -->|Short-lived workload JWT| Core
API -->|Decision + usage receipt| Meter
Core -->|Scoped read SQL| Legal
Core -->|Checksum-verified read| Blobs
The private Legal Core address is reachable only from approved Kesita workloads. Network isolation reduces exposure but does not replace application authorization: Legal Core still verifies issuer, audience, key ID, lifetime, service identity, organization, optional user, scopes and content policy on every request.
Public API request
Section titled “Public API request”The external credential terminates at the public boundary and is never forwarded to Legal Core. The gateway builds a narrower internal authority envelope. Public response schemas remain stable even when corpus tables, retrieval engines or internal Legal Core routes change.
sequenceDiagram autonumber participant C as External backend participant I as Authorization service participant G as Kesita Public API participant L as Legal Core API participant D as Legal data stores C->>I: OAuth client-credentials grant I-->>C: Short-lived access token C->>G: POST /v1/legal/search + Bearer token + idempotency key G->>G: Resolve client, tenant, scopes, entitlement, quota and content policy G->>L: Search + short-lived workload JWT L->>L: Verify audience, service, scope and content policy L->>D: Scoped retrieval against active corpus generations D-->>L: Pinned versions and citation coordinates L-->>G: Internal typed retrieval result G->>G: Minimize fields, meter usage and record policy receipt G-->>C: Versioned public response + request ID
Initial public capabilities should remain narrow:
| Capability | Public behavior | Internal authority |
|---|---|---|
| Legal search | Filtered ranked results with stable citations and explicit degradation | legal:search plus metadata or snippet content policy |
| Pinned source metadata | Immutable version identity, provenance, hash and availability | legal:source:read plus metadata |
| Source passage | Bounded citation context, never an unbounded corpus dump | legal:source:read plus snippet |
| Original download | Separate entitlement, attachment disposition and audit event | legal:original:read plus explicitly permitted full-content policy |
Legal Core currently serves full text to internal callers and rejects lower-content policy values at runtime. Metadata/snippet projection is therefore an implementation prerequisite, not merely a gateway filter: data that is not permitted must not cross the Legal Core boundary in the first place.
MCP request
Section titled “MCP request”The remote MCP endpoint exposes task-oriented, bounded tools such as legal search, source inspection and pinned-original retrieval. Tool schemas map to the Public API contract. Arbitrary SQL, arbitrary URLs, raw internal route selection and caller-supplied authorization context are never tools.
sequenceDiagram autonumber actor U as User participant H as MCP host participant M as Kesita MCP server participant I as Authorization service participant G as Kesita Public API participant L as Legal Core API U->>H: Connect Kesita tools H->>I: OAuth authorization with PKCE I-->>H: User-delegated token with MCP scopes H->>M: tools/call legal_search M->>M: Validate tool input and delegated scope M->>G: Typed legal-search request with delegated principal G->>L: Narrow request + short-lived workload JWT L-->>G: Pinned legal evidence G-->>M: Public contract response M-->>H: Bounded MCP tool result with citations H-->>U: Assistant-visible result
MCP authorization is user-delegated; unattended product integrations use client credentials. Both paths resolve to a Kesita principal with explicit tenant, scopes and content policy. The authorization-server choice and consent UX require a separate implementation decision, but static shared secrets in source code and direct reuse of Legal Core signing credentials are excluded.
Tokens are audience-bound to either the Public API or MCP endpoint and are never forwarded across that boundary. The MCP server must reject caller-supplied tenant IDs, scopes and downstream tokens, derive authority from the verified principal, and defend against confused-deputy use by binding every tool call to the active authorization grant. Non-human credentials require rotation and immediate disablement; authorization-code, refresh-token and client-grant revocation must prevent new gateway exchanges within the ratified revocation objective.
ComproCausa migration
Section titled “ComproCausa migration”ComproCausa currently opens a read-only PostgreSQL pool with LEGAL_DB_URL and queries canonical.* tables to enrich reports. That makes its runtime depend on Kesita’s physical schema, connection limits, database network access and full-text layout. The target removes that dependency.
flowchart TB
subgraph Current[Current coupling]
C1[ComproCausa report service] -->|LEGAL_DB_URL + SQL| DB1[(Shared legal PostgreSQL)]
C1 -->|Knows canonical tables and columns| DB1
end
subgraph Target[Target integration]
C2[ComproCausa Kesita client] -->|Versioned HTTPS contract| API[Kesita Public Legal API]
API -->|Policy-bound workload JWT| Core[Legal Core API]
Core --> DB2[(Legal PostgreSQL + corpus originals)]
end
Current -. Replace direct database access .-> Target
The migration unit is the use case, not a table wrapper. For example, the existing batch lookup of canonical judgments becomes a batch pinned-source endpoint with typed metadata and an explicit optional content tier. ComproCausa retains its case workflow and report composition; Kesita becomes authoritative for legal identity, versioning, retrieval, provenance and source delivery.
- Inventory ComproCausa legal queries and group them into search, batch source resolution, passages and originals.
- Define those application operations in a separate public OpenAPI contract; do not expose the internal
platform-api.yamlunchanged. - Issue a dedicated non-human ComproCausa client identity with least-privilege scopes, quotas and environment separation.
- Add a typed Kesita client in ComproCausa and run contract tests against staging fixtures.
- Cut each use case from direct SQL to the API, then remove
LEGAL_DB_URL, database firewall access and canonical-schema knowledge from ComproCausa.
No dual-running compatibility layer is required after a use case passes acceptance: both products are pre-ship and the clean end state is one authoritative API.
Contract and ownership rules
Section titled “Contract and ownership rules”- A new public OpenAPI source belongs in
packages/contracts; it is versioned independently from the internal Legal Core contract and generates supported client types/SDKs. - Public resource IDs identify immutable legal source versions. They must not encode table names, blob keys, storage URLs or retrieval-engine coordinates.
- Requests carry a stable request ID; mutations or billable operations also carry idempotency keys. Retry and rate-limit responses use stable public error codes and
Retry-Afterwhere applicable. - Public endpoints enforce bounded pagination, query complexity, response size and content tiers. Bulk corpus export is a separate product/security decision, not an accidental large page size.
- The gateway propagates W3C trace context and a request ID to Legal Core. Logs, traces and metrics contain opaque IDs and aggregate quantities, never queries, source text, credentials, prompts or completions by default.
- Legal Core remains the only runtime reader of legal PostgreSQL and corpus originals. Public API, MCP and consumers never receive database credentials or storage credentials.
- Public API availability, SDK support, pricing, retention and legal-data licensing claims require explicit acceptance evidence before publication.
Security acceptance
Section titled “Security acceptance”Before any external client is admitted, prove cross-tenant and cross-client denial; audience, issuer, expiry and scope rejection; revoked client/user denial; content-tier non-disclosure; quota and complexity enforcement; idempotent replay; original-download authorization before and after blob I/O; MCP consent and confused-deputy resistance; request/trace correlation without content leakage; and absence of public routes to Legal Core, PostgreSQL or blob storage. Exercise key rotation and authorization-service outage behavior without a fail-open path.
Delivery order
Section titled “Delivery order”- Implement metadata/snippet enforcement inside Legal Core and generalize its workload trust policy to allow only registered Kesita gateway identities.
- Add the public contract, authorization/entitlement boundary, quotas, metering and audit receipts.
- Add the MCP adapter over the accepted public application operations.
- Migrate ComproCausa use cases and revoke its direct database access.
- Open partner access only after isolation, revocation, abuse, licensing, load and source-delivery tests pass.
See Kesita architecture for the core system and Deployment for runtime placement and network boundaries.