Confluent logoGovernance

Receipts, Not Reassurance: How We Govern a Registry We Never Touch

A successful import in CoreModels returns two lists. One is `errors`, which is empty — the run proceeded. The other is `lossiness`, and it is often not empty at all: an itemized statement of everything the import approximated, counted without parsing, or deliberately left out.

Receipts, Not Reassurance: How We Govern a Registry We Never Touch

A successful import in CoreModels returns two lists. One is errors, which is empty — the run proceeded. The other is lossiness, and it is often not empty at all: an itemized statement of everything the import approximated, counted without parsing, or deliberately left out.

That second list is the governance argument in miniature. Any system powerful enough to describe your streaming estate is powerful enough to quietly misdescribe it, and the only defense is evidence. The posture of our Confluent Schema Registry connector is not "trust us" but: here is what we did, here is what we could not do, here is who decides the rest.

The trust boundary starts at the network edge

CoreModels holds no registry credentials and opens no connection to your registry. Its only input is a file you produce: a JSON array of each subject's latest version, assembled by a short loop against your own registry's REST API with your own auth flags. A live-sync capability is declared and deliberately deferred rather than quietly shipped — so when a security review asks what this integration can reach, the answer is the file you chose to upload.

Import is additive by construction

Importing a subjects export writes governed Types, Elements, taxonomies, and references into your project. Re-importing after the registry evolves never mutates or deletes an existing governed node — the response tells you how many datasets were skipped because they already existed, next to how many were added.

This is a structural property, not a flag you could set the other way. If the registry now disagrees with the governed model, the audit surfaces that as drift; resolving it — accepting the new meaning, or rejecting it as a mistake — is a human act performed by someone with the authority to make it.

The alternative is self-defeating: a governed model that automatically follows the estate isn't governing anything. The value of a governed statement of meaning comes precisely from its ability to disagree with production.

The one thing that does refresh on every import is vendor bookkeeping — native types, doc strings, versions, schema ids, last-import state — which is estate metadata, not governed meaning.

Roles are the gate, and the gate is narrow

Import requires Admin on the project. Audit, re-audit, generate, history, badge, and status all run at Viewer. That split isn't decoration: a CI pipeline can be given a key that is structurally incapable of writing governed meaning, because the verbs it calls never write it. A key that fails a build cannot alter the definitions it is checking against.

Read-only verbs stay read-only

Auditing writes nothing. Even recording a run in the rolling history is an explicit flag on the request, defaulted off: the audit verb stays strictly read-only unless a caller asks for bookkeeping. Generation is read-only too.

One verb always records itself — re-audit, which replays the snapshot stored at import time against the current governed model — and what it records is counts, codes, trigger, and fingerprint, never a change to meaning. Semantics change only through deliberate human edits; trails accumulate only when asked.

Lossiness is a success channel

There is real texture to be honest about here, and we would rather publish it on every run than let a coverage gap pass as a clean bill of health.

Avro record subjects — the registry default — parse fully. JSON Schema subjects parse at depth one: properties, required, enums, formats. Protobuf subjects are counted but not parsed, and every audit repeats that as a standing protobuf-unparsed coverage finding, naming how much of your estate this connector is not governing. Key subjects that are a bare primitive carry nothing structural to import, and say so. Arrays, maps, and some Avro logical types arrive as declared approximations rather than confident mappings.

Even storage limits are on the receipt: when an estate's encoded snapshot exceeds the cap, the import says so and states the consequence — re-audit has nothing to replay against, though audits with fresh artifacts still work — instead of degrading silently and looking fine.

The principle generalizes: errors mean we could not proceed; lossiness means we proceeded, and here is precisely what the result does not capture. A tool that only ever reports success is asking you to trust its silence.

Drift is evidence, and evidence has a date on it

Drift is checked in both directions by the same engine. The live audit asks whether fresh registry artifacts still conform to the governed model — the CI gate, failing a build when a field's type drifts, an enum narrows, or a governed field disappears. Re-audit asks the opposite: after the model changes, does the last-known estate still conform?

Every recorded run enters the history with its trigger, severity counts, finding codes, and the fingerprint of the artifacts examined — drift over time as inspectable data rather than anecdote. The badge renders the latest recorded run in one of four colors, and the fourth is gray, for "no recorded runs." Absence of evidence is shown as absence of evidence.

Generated schemas are proposals that wait for a human

From the governed model, CoreModels emits registry-ready Avro record schemas: required fields bare, optional fields as a union with null and a null default, governed taxonomies as sanitized enums, date-times as proper logical types. What it does with them afterwards is nothing at all — the artifacts come back as content, for you to diff, review, and register through the process that already governs your registry.

Each generated record carries a doc line saying it is governed by CoreModels and should be regenerated rather than hand-edited — the artifact explains its own provenance to whoever finds it later. Where generation had to compromise — a reference whose target record wasn't in the generated set degrades to a plain string key — the compromise is declared beside the file, so the reviewer knows before the registry does.

Why the refusals are the product

Strip out the specifics and one idea repeats: the governed model is an authority you consult, not an automation that acts on your infrastructure. It imports additively, audits loudly, records only when asked, publishes what it cannot see, and generates artifacts that wait for a person. That is what makes it safe in the critical path of schema review — and being trusted there is the entire job.

The full posture — roles, endpoints, and what is deliberately not supported — is documented in the CoreModels Confluent Schema Registry quickstart in our docs.