Data Contracts: schemas, teams, linked assets and Data Products¶
A Data Contract is the governed, versioned interface a producing team publishes to its consumers — its schema, owner, lifecycle, and terms in one place, exportable as standard ODCS.
When to choose this¶
-
Publish a stable interface
Pin a version, an owner, and a schema that downstream consumers can build on without fear of a silent change.
-
Govern who depends on what
The Linked Assets tab names the approved tables and catalog assets the contract covers, and flags any that went missing. Linking or unlinking follows the contract's domain: only members of that domain (or anyone, for a contract with no domain) can change what it binds, and the audit log records who did. The Linked Products tab reaches everything else (metrics, glossary terms, processes, connections, alert rules) through a Data Product.
-
Export a portable ODCS
Datahub emits valid Open Data Contract Standard YAML (v3.1.0) for every contract, ready to pull into a consumer's own pipeline. Import works the same way.
-
Version with approval and lineage
Every change ships as a new version behind an approval gate, and Datahub records which version was active at each point in time.
When not to publish a contract
- Internal scratch tables or work-in-progress notebooks.
- Ad-hoc views that no team outside yours consumes.
- A glossary term in isolation — it lives in the business glossary; promote it into a Data Product first if it earns a contract.
How a contract fits together¶
A contract is the hub that ties five things together: the team that owns it, the schema it binds to real catalog tables and columns, the approved data assets it links directly, the Data Products that carry every other kind of asset, and the ODCS export that consumers pull downstream.
flowchart LR
TEAM["Owning team<br/>members + roles"] -->|owns| DC
DC(["Data Contract<br/>name · version · status · domain"])
DC -->|binds| SCHEMA["Schema<br/>catalog tables + columns<br/>+ assertions"]
DC -->|links| LINKED["Approved data assets<br/>published catalog assets<br/>harvested tables · dbt · Databricks"]
DC -->|links| DP["Data Products"]
DP -.->|bundle| ASSETS["Bundled assets<br/>metrics · terms · catalog<br/>processes · connections · alerts"]
DC -->|exports| ODCS[/"ODCS YAML<br/>v3.1.0"/]
classDef accent fill:#ff8400,stroke:#e67700,color:#ffffff,font-weight:600;
class DC accent
Figure 1 — A contract is the hub: an owning team holds it, it binds a schema of real catalog tables and columns (with the assertions consumers rely on), it links approved data assets directly and Data Products that bundle the rest, and it exports as ODCS.
Why teams reach for this
A contract turns an informal "please don't break this table" into a named, versioned promise: consumers see the exact schema, owner, and terms; producers get an approval gate before any change goes live; and everyone pulls the same interface as standard ODCS instead of a wiki page that quietly drifts.
What links directly, and what goes through a Data Product¶
A contract links two kinds of target, each on its own tab:
| Target | Tab | How |
|---|---|---|
| A published data catalog asset | Linked Assets | Link Asset opens the picker; see The Link data assets picker. |
| A table, dbt model, seed, snapshot or source, or Databricks asset that the metadata engine's last harvest still finds | Linked Assets | The same picker. |
| A Data Product | Linked Products | Link Product. |
| A metric, glossary term, BPM process, metadata-engine connection or alert rule | Linked Products | Register it as (or add it to) a Data Product first, then link the product. |
If you linked metrics or glossary terms straight to a contract before April 2026
That direct path is gone for metrics, glossary terms, processes, connections and alert rules: they reach a contract through a Data Product. Since September 2026, catalog assets and harvested tables link directly again, from the Linked Assets tab, as long as they are approved (published, or still found by the harvest).
Before April 2026, the Link entity modal on a contract detail page offered six entity types behind a tabbed picker: Data Product, BPM Process, Data Catalog Asset, Glossary Term, Metric, and Connection. In April 2026 it became a single Data Product picker, which it still is.
| Then | Now |
|---|---|
Pick Metric → pick mrr → linked. |
Open the metric's detail page → Register as Data Product → link the new product to the contract. |
Pick Glossary Term → pick Customer → linked. |
Open the glossary term → Register as Data Product → link the product. |
Pick Connection → pick prod-warehouse → linked. |
Open the connection → Register as Data Product → link the product. |
Pick Data Product → pick Customer 360 → linked. |
Unchanged — linking a product works exactly as before. |
The reason is functional: a contract describes a product that a team ships to its consumers, so a metric, a term or a process belongs on it as part of a product. The tables and catalog assets the contract is about are the exception: they are the data itself, so they link directly. See Data Products for the bundle side of the bridge.
What about my legacy non-product links? They were removed in April 2026. If a direct link genuinely mattered, register that asset as a Data Product (one click on its detail page) and re-attach the resulting product to the contract. A catalog asset can simply be linked again on the Linked Assets tab.
The rules hold outside the page too
Hand-editing an API request gets you no further than the page does. The Linked Products route accepts a Data Product and nothing else; the database refuses any other target as well. The Linked Assets route refuses a catalog asset that is not published, a table the harvest no longer finds, a dbt test or macro, and an asset from a source you may not read (see Setup).
What a Data Contract looks like¶
| Surface | Where | What you see |
|---|---|---|
| List | /data-contracts |
Filterable table — name, version, status, domain, contract team. KPIs and a chart at the top of the lander. |
| Detail — Overview tab | /data-contracts/{id} (default) |
Name, description, version, status with lifecycle actions, domain, owner, ODCS export download, audit metadata. |
| Detail — Schema tab | /data-contracts/{id} |
Schema objects and properties bound to real catalog tables and columns — fields, types, constraints, descriptions, and the assertions the contract adds on top. |
| Detail — Team tab | /data-contracts/{id} |
Contract team members and their roles, with join/leave dates. |
| Detail — Linked Assets tab | /data-contracts/{id} |
Every data asset linked to this contract. Each row: name, type, where it came from (the connection, for a harvested table), a status badge (Available, Missing or Archived), linked-at, and unlink. Rows that need attention come first. A count on the tab says how many are not available. Use Link Asset to attach more. |
| Detail — Linked Products tab | /data-contracts/{id} |
Every Data Product linked to this contract. Each row: product name, type badge (always Data Product), linked-at, and unlink (gated on the contract write role). Use Link Data Product to attach more. |
The Link data assets picker¶
Link Asset opens a wide table of everything you can link:
- Published catalog assets first, then the tables, dbt resources and Databricks assets the metadata engine's last harvest found. Drafts, assets under review, archived assets, and anything the harvest no longer finds are not offered.
- Search matches the name or the location (the connection a harvested table came from). The Type filter narrows to one kind: Catalog asset, Database table, dbt resource or Databricks asset.
- Select several rows, across pages and searches, then Link N assets. Assets already on the contract are marked Linked and cannot be picked again. A table the contract's Schema already describes is marked On the schema and cannot be picked either: the schema object ties it to the contract. The reverse holds too: a table linked as an asset has to be unlinked before it can join the schema.
- If the server refuses one of your picks (someone archived it a moment ago, for example), the others still link and the refused one stays selected, with the reason in the message.
You only see, and can only link, the sources you may read: the catalog assets need data catalog read access, the harvested tables need metadata engine read access. With neither, the picker says so. An asset from a source you cannot read is reported as not found, without its name.
When a linked asset goes missing¶
A link stays on the contract when its target disappears, so the contract still says what it was about:
- Missing (red): the metadata engine's last harvest no longer finds the table, its connection was deleted, or the catalog asset was removed. The row keeps the name it had.
- Archived (amber): the catalog asset was archived; it still exists but is no longer maintained.
While any link is missing or archived, a banner at the top of the contract says how many, whichever tab is open, and Show linked assets takes you to them. It is red while any link is missing and amber when they are only archived, and so is the count on the Linked Assets tab. Link the replacement and unlink the old one; the banner goes away when every link is available again.
The Link Data Product modal¶
After April 2026 this modal contains exactly one field: a Data Product picker. It lists every Data Product not already linked to this contract, so you can never pick one you can't actually attach. Submit stays disabled until you choose a product, and if you try to close the modal — Escape, backdrop click, or the close button — with an unsaved selection, Datahub asks you to confirm before discarding it.
Setup — what an admin needs to do once¶
There is no per-tenant setup for linking itself. The relevant prerequisites are:
| Prereq | Where | Why |
|---|---|---|
| A published catalog asset, or a harvest by the metadata engine | The data catalog, or the connection's harvest in the metadata engine | The Link data assets picker offers only approved assets. |
| At least one Data Product exists | /data-products (or the Register as Data Product flow on any asset) |
The Link Data Product modal needs at least one product to pick from. |
| Roles | /admin/users → role groups |
datacontracts.contracts.read to view; datacontracts.contracts.write to create, edit, link, and unlink. Linking an asset also needs read access to where it comes from: datacatalog.assets.read for a catalog asset, metadata_engine.resources.read for a harvested table. Registering an asset as a Data Product is a different module and needs dataproducts.products.write. |
Linking an asset to a contract — the full path¶
A table or a catalog asset links in one step. Anything else goes through a Data Product first.
flowchart LR
T["Approved data asset<br/>published catalog asset<br/>harvested table · dbt · Databricks"]
T -->|"Link Asset"| DC["Data Contract"]
A["Metric · glossary term<br/>process · connection · alert rule"]
A -->|"1 · Register as Data Product"| DP(["Data Product"])
DP -->|"2 · Link Data Product"| DC
classDef accent fill:#ff8400,stroke:#e67700,color:#ffffff,font-weight:600;
class DC accent
Figure 2 — Two paths onto a contract. An approved table or catalog asset links directly from the Linked Assets tab; a metric, term, process, connection or alert rule is registered as a Data Product first, and the product is linked.
A table or catalog asset: on the contract's detail page → Linked Assets tab → Link Asset → search, select one or more rows → Link N assets.
Anything else:
- On the asset's detail page (metric, glossary term, process, connection, alert rule) — find the Part of N data products panel and click Register as Data Product. Either create a new product or add the asset to an existing one.
- On the contract's detail page → Linked Products tab → Link Data Product → pick the product → save.
Fan several assets into one contract
If several assets belong on the same contract, wrap them in a single Data Product and link that product once. For a Customer 360 contract: build a Customer 360 product holding 4 metrics + 2 catalog assets + 1 glossary term, then link the product to the contract a single time.
The version & approval lifecycle¶
A contract moves through a defined status lifecycle, and going live is gated on human approval — so a reviewer consciously signs off before a new interface is published to consumers.
stateDiagram-v2
direction LR
[*] --> Draft
Draft --> Proposed: Propose
Draft --> UnderReview: Submit for review
Proposed --> UnderReview: Submit for review
UnderReview --> Published: Approve
UnderReview --> Draft: Reject / Withdraw
Published --> Deprecated: Deprecate
Published --> Deprecated: Superseded by new version
Deprecated --> Retired: Retire
Retired --> [*]
classDef accent fill:#ff8400,stroke:#e67700,color:#ffffff,font-weight:600;
class Published accent
Figure 3 — A contract's status lifecycle. Submitting freezes the version for review; approval publishes it. Publishing a new version supersedes the previous one — which becomes deprecated — and Datahub records which version was live at every point in time.
- Draft — create or edit the contract's fundamentals, schema, and team. A brand-new contract starts as version 1 in draft.
- Submit for review — validates the contract and starts an approval workflow; the version is frozen while under review. The approver sees the contract's name and version, so they know exactly what they are signing off.
- Approve — the version becomes published (goes live). If it replaces an earlier published version, that predecessor is deprecated — superseded by the new one.
- Reject / withdraw — the version returns to draft for further editing. You can withdraw while the review is open. Archiving a contract that is under review ends its review the same way (the contract goes back to draft and its review task closes), and it asks the same people: anyone else is refused. The people who may are whoever submitted it, the team or person it is waiting on, and an administrator; see Workflows. A direct status change on a contract under review is refused: it leaves review only by approval, rejection or withdrawal, so the review and its task never stay open with nothing left to decide.
- New version — deep-clone the active contract to start the next draft; its schema, team, and linked products come along, and the lineage back to the previous version stays intact.
- Deprecate / retire — wind a contract down through deprecated to retired once consumers have migrated off it.
How a version supersedes cleanly
Approving a version never overwrites its predecessor. On activation, Datahub freezes the new version's active-from timestamp and closes the previous version's interval, so the history is gapless — for any past date you can answer "which version was live then?" The lineage chain links each version back to the one it replaced.
ODCS export & import¶
Every contract exports as ODCS v3.1.0 YAML from the Overview tab. The export's info.dataProduct block is derived from the Data Products linked to the contract (their names, comma-joined), so consumers pull a single, uniform interface into their own pipelines. Datahub can also import an ODCS YAML file to create a contract, matching linked products back by name.
The shape of the export is unchanged from before April 2026 — only the source data is now uniform (one product type) instead of a mix of entity types.
Limitations¶
| Limit | Why | Workaround |
|---|---|---|
| You cannot link a metric, glossary term, process, connection, or alert rule directly to a contract. | They reach a contract through a Data Product — see What links directly. | Register the asset as a Data Product first, then link the product. |
| Only a published catalog asset, or a table the latest harvest still finds, can be linked. | A contract should point at approved data, not a draft or something already gone. | Publish the catalog asset, or run the metadata engine's harvest, then link it. |
| A linked asset that disappears is flagged, not removed. | The contract keeps saying what it was about, so someone decides what replaces it. | Link the replacement and unlink the missing row. |
| The Link Data Product modal hides products you've already linked. | Already-linked products are filtered out of the dropdown so you never hit a duplicate-link error. | Unlink the product first if you truly want to "re-link" it (rarely useful). |
| Pre-2026 direct links to non-product entities were deleted at migration. | Chosen over auto-wrapping each one in a synthetic, curator-less product. | Re-register the relevant assets as Data Products. |
| Several ODCS sections — Data Quality, SLA, Roles, Pricing, Support, Infrastructure — aren't editable yet. | Datahub ships ODCS Fundamentals, Schema, and Team first; the rest are on the roadmap (Data Quality will read from the data platform). | Capture those terms out-of-band for now; the export still validates against ODCS v3.1.0. |
Audit & compliance¶
| Question a CISO might ask | Where to look |
|---|---|
| "Which tables and catalog assets does this contract cover?" | The contract's Linked Assets tab, with each link's status. |
| "Which Data Products does this contract govern?" | The contract's Linked Products tab. |
| "Which assets sit inside those Data Products?" | Open each linked product → its Assets tab. |
| "Can someone link an unrelated entity by editing the API directly?" | No. The API accepts only a published catalog asset, a table the latest harvest still finds, or a Data Product, and only from a source the caller may read. The database also refuses any product link to something that is not a Data Product. |
| "Which version was active on a given date, and who approved it?" | The version history keeps gapless intervals, so it shows the active version for any date; the approval workflow records who approved the activation. |
| "Who archived, restored or deleted this contract, and who submitted, approved or rejected it?" | The audit log names the person for each of these, including the moves the approval workflow makes (submit, approval, rejection with the reviewer's comment). |
| "Where did the legacy direct links go?" | They were deleted at the April 2026 lockdown migration, which logged the number of rows it removed. |
| "Who can link or unlink an asset or a Data Product?" | Anyone with datacontracts.contracts.write; an asset also needs read access to its source (the data catalog or the metadata engine). Read-only viewers see the tabs but no buttons. |
Troubleshooting¶
| Symptom | Likely cause | Fix |
|---|---|---|
| The Link data assets picker says there are no approved assets to link | No catalog asset is published and the metadata engine has not harvested any table | Publish a catalog asset, or run the harvest on a connection. |
| The picker says you cannot read the data catalog or the metadata engine | Your role groups lack both read roles | Ask an admin for datacatalog.assets.read or metadata_engine.resources.read. |
| A catalog asset I expect is not in the picker | It is a draft, under review or archived | Publish it first. |
| Linking fails with "Asset … not found in the catalog" | The asset does not exist, or it comes from a source you may not read | Check the id, or ask for read access to its source. |
| A linked asset shows Missing | The harvest no longer finds the table, its connection was deleted, or the catalog asset was removed | Link the replacement and unlink the missing row. |
| A linked asset shows Archived | The catalog asset was archived | Link its replacement and unlink it, or restore the asset in the catalog. |
| Link Data Product modal dropdown is empty | No Data Products exist yet (or all are already linked) | Register an asset as a Data Product on its detail page first. |
| The metric or term I want on the contract isn't in any product | You haven't wrapped it yet | Open its detail page → Register as Data Product. |
| Submit on the modal stays disabled | No product is selected | Pick a product from the dropdown; the modal enables submit once you choose one. |
| Pressing Escape / closing the modal loses my selection | The discard guard is intentional | Confirm the discard, then re-open and pick again — the guard stops you losing an unsaved pick by accident. |
ODCS export's info.dataProduct shows the wrong name |
The product was renamed after the link was created | The export reads the product's current name; re-export to refresh. |
| The Linked Products tab is empty for a contract that "had links last week" | Pre-2026 direct links were deleted at the April 2026 migration | Re-register the relevant assets as Data Products and re-attach. |
| HERC says it can't link a metric directly to a contract | Metrics reach a contract through a Data Product, by design | Ask HERC to register the metric as a Data Product first, then link the product. |
If something is broken that this page does not cover, ping your Datahub contact with the contract ID (visible in the URL) and the error text from the toast or banner.
Arriving from a domain's detail page narrows this list to that domain automatically — a banner names it, with a one-click way back out. See Domains.
See also¶
-
The bundle side of the bridge: how a metric, term, process, connection or alert rule reaches a contract.
-
How a metric reaches a contract through a Data Product, including joined tables.