What you will be able to do
- Explain who can see public, protected and private models in Catalog, and why seeing a model's metadata does not mean you can query its data
- Open the account-level lineage graph and List view to find every project and public model in an account
- Use the Relationships tab and Referenced by list to find out which downstream projects depend on a public model
- Read cross-project references in a consumer project's lineage, including why indirectly referenced upstream public models and column-level links do not appear
Key concept
Public model as a discoverable interface — In a multi-project dbt account, a model with public access is the interface a producing team offers to everyone else. Catalog lists it for every user in the account and draws it in the lineage of each project that references it directly. Protected and private models stay visible only to users who have access to their project.
1.Who can see public models in Catalog
When one dbt project consumes another team's work, it goes through public models, and dbt Catalog (formerly dbt Explorer) is where teams find them. Before anyone writes a cross-project ref, they need to know which public models exist, who owns them and which columns they contain. Catalog provides that view across the whole account. The access config that makes a model public is covered in [model governance](lesson:7.3). This page is about finding and reading public models once they exist.
What a user sees depends on the model's access level. Public models are listed for every user in the account. Protected and private models are visible only to users who have access to their project, and read-only access is enough. The same rule applies one level up: any project that exposes at least one public model is visible to everyone in the organization with read-only access.
Inside the public tier there are two levels of visibility. The first is the listing: a user with permission on any project in the account can see all public models used across the account, whichever project defines them. The second is full detail: to view a public model's full details, or any private model, you need permission on the specific project that defines it. Opening the producing project's own lineage graph by double-clicking a model from another project is likewise subject to permission on that project. A user with read-only access to every project can therefore move across the organization's entire DAG at full detail.
| Model access | Who can find it in Catalog | Who sees it in full detail |
|---|---|---|
| public | Every user in the dbt account, listed in the multi-project view | Users with access to the project that defines it |
| protected | Only users with access to that project, including read-only | Users with access to that project |
| private | Only users with access to that project, including read-only | Users with access to that project |
Seeing a model's metadata does not mean you can read its data. dbt does not coordinate warehouse grants with model-level access, so a user can find a public model, write a ref to it, and only discover when they run or preview it that they cannot read the underlying table. This is intentional. The organization keeps least-privileged access to the data while still letting everyone discover what exists. An analyst who has read a public model's description, owner and columns can make a well-informed request for access.
Search follows soft access controls. Your project permissions decide which projects appear in the left-hand menu of the global navigation. A Catalog search, however, returns every matching resource and clearly flags the ones you cannot open. Two preconditions also apply before any of this works. Multi-project lineage is an Enterprise and Enterprise+ feature, so Starter accounts can browse lineage only within each project. And a newly public model reaches downstream projects only after the producer has had a successful job run since the access change. CI runs do not refresh Catalog, as covered in [generating docs for Catalog](lesson:4.7).
Checkpoint 1 of 8· Check yourself
An analyst with access only to the marketing project finds the finance project's public model fct_orders in Catalog, adds a cross-project ref to it, and gets a permission error on preview. What explains this?
Model access controls who can discover a model and write a ref to it. Warehouse grants control who can read the data. dbt does not coordinate the two, so this mismatch is expected.
“they realize they do not have access to the underlying data in the data warehouse”Source: docs.getdbt.com
Checkpoint 2 of 8· Exam question
In a downstream dbt project, the lineage graph in dbt Catalog shows the public model `finance.customer_ltv`, which itself references another public model, `finance.customer_raw`, inside the upstream `finance` project. `customer_raw` does not appear anywhere in the downstream project's Catalog lineage graph, even though the Studio IDE lineage view for the `finance` project shows both models chained together. What explains this?
Correct answer: A — Catalog renders only directly referenced public models in a project's lineage graph; since only `customer_ltv` is referenced directly, the model it depends on stays hidden.
- A. Correct. Catalog's lineage graph only displays public models a project references directly; a model that is only an indirect (transitive) dependency is left off the graph even though the Studio IDE lineage view resolves the full chain.
- B. Incorrect. Stale-metadata deletion happens after three months without a job run and would remove a model from Catalog entirely, not selectively hide it based on how many hops away it sits in a reference chain.
- C. Incorrect. Contract enforcement is a governance recommendation for public models, not a requirement for appearing in Catalog's lineage graph; an unenforced public model still shows up when referenced directly.
- D. Incorrect. Seat type controls how much detail a user can see about a model, not how many links of a dependency chain render in the lineage graph; the direct-vs-indirect rule applies to every seat.
2.Browsing every project and public model in the account
The account-level lineage graph shows every project and the public models connecting them. To open it, select your project from the sidebar in Catalog, then click Account lineage in the upper right corner. Each project appears as one node, labelled with its name and the number of public models it exposes. Arrows between the nodes show which projects depend on which.
The graph is built for scanning. The top toolbar has a search bar and toggles between lineage view and List view, and the zoom controls sit in the lower right. List view turns the graph into a table of projects and public models. It suits a question like whether anyone already publishes a customer dimension, which is easier to answer from a list than from a picture. When a node looks relevant, double-click it to open that project's resource-level lineage graph.
There is a second way in from inside a single project. Catalog's marts and public models view shows the marts and public models in the current project and also links to all public models in the account. Use it when you start from your own project and want to see what is available elsewhere. Use the account graph when the question is about how the projects connect.
Checkpoint 3 of 8· Put it in order
Put these steps in order to go from Catalog to the details of a public model in another project
- 1.Click Account lineage in the upper right corner
- 2.Select the public model to open its details panel
- 3.Double-click the producing project's node to open its resource-level lineage graph
- 4.In Catalog, select your project from the sidebar
The account graph is opened from inside a project. Double-clicking a project node opens that project's resource-level lineage, and selecting a model there opens the details panel on the right.
“Double-click a project node to open that project's resource-level lineage graph.”Source: docs.getdbt.com
Checkpoint 4 of 8· Exam question
A data governance lead clicks on a cross-project public model, `sales.order_summary`, inside a downstream project's Catalog lineage graph. The side panel opens without granting the lead full IDE access to the `sales` project. Which two pieces of information does that side panel display for the model? (Select two.)(Select 2)
Correct answers: A, C — The producing project's name, letting the lead identify which team owns and maintains `order_summary`.; The model's description together with its package information, for context without opening the source project.
- A. Correct. The side panel for a cross-project public model surfaces the producing project so a viewer can tell at a glance which team owns the model, without needing permissions on that project.
- B. Incorrect. The panel exposes documentation-level metadata, not the model's compiled SQL; viewing raw SQL requires project permissions and access to the Studio IDE itself.
- C. Correct. The panel shows the model's documented description and package information, giving governance and discovery context without requiring access to the producing project.
- D. Incorrect. Catalog's model detail views expose run history and timing on the model's own detail page, but the cross-project side panel does not surface a live cost or credit breakdown.
3.Seeing who consumes a project's public models
The producing project's lineage graph shows who consumes its models. From the project's Overview page, click View lineage to open the resource-level graph. It shows the project's sources, seeds and models with connectors between them. Downstream projects that reference its public models appear as separate project nodes joined by dashed lines, and nodes that stand for another dbt project carry a project icon to the left of the project name. The general mechanics of this graph, including selectors, lenses and refocusing, are covered in [navigating Catalog lineage](lesson:8.1).
Selecting a model opens a details panel with three tabs, and the Relationships tab answers the cross-project question:
- General: the description and metadata fields such as Project and Relation. - Columns: each column's name, data type and description, plus test results where tests exist, with a Search for columns field. - Relationships: the downstream projects that reference the model, listed under Referenced by.
The dependency count on a project node is broader than it looks. In a project's resource-level lineage graph, click the node of an upstream (parent) project, the one whose public models are being consumed. Its Relationships tab then shows how many downstream (child) projects depend on that parent project. The count includes every project that lists the parent in its dependencies.yml, even if none of its models contains a direct {{ ref() }}. A consumer that declared the dependency and never used it still counts, so a non-zero number does not prove that a model is actually being queried.
Checkpoint 5 of 8· Match them up
Match each part of the producing project's lineage view to what it shows
Tap a term, then the definition that fits it.
The details panel splits model information across General, Columns and Relationships. Consuming projects are drawn on the graph as separate nodes joined by dashed lines.
“Relationships tab: downstream projects that reference the model, listed under Referenced by.”Source: docs.getdbt.com
Sources2
4.Cross-project references in a consumer project's lineage
A consumer project creates a cross-project reference in two steps. It lists the upstream project in dependencies.yml, under the exact case-sensitive name from that project's dbt_project.yml. Then it refers to the upstream model with a two-argument ref that includes the project name. dbt resolves the dependency and shows the cross-project lineage in its lineage and DAG views.
projects:
- name: jaffle_finance # case sensitive and matches the 'name' in the 'dbt_project.yml'Checkpoint 6 of 8· Fill the gap
A model in jaffle_marketing selects from the Finance team's public monthly_revenue model. Which token completes the ref?
select * from {{ ref(' ? ', 'monthly_revenue') }}Models referenced from a project dependency must use the two-argument ref, and the first argument is the producing project's name. Catalog then draws monthly_revenue as a node from jaffle_finance.
Source: docs.getdbt.comIn the consumer's lineage graph, each public model it references appears as a node you can open. Clicking the node opens a side panel showing which dbt project produces the model, along with its description, package and other details. Double-clicking it opens the parent project's resource-level lineage graph, provided you have permission on that project.
Catalog's lineage stops at the public models a project references directly. In the example above, project_b's graph shows upstream_b but not upstream_a, even though upstream_b is built from upstream_a. The Studio IDE lineage view does show upstream_a, because dbt resolves the full dependency graph there. The difference is deliberate: Catalog shows only the immediate dependencies available to that project. To trace the chain further upstream, double-click upstream_b and follow it in project_a's own lineage graph.
Cross-project lineage also works at the model level only. Within one project, Catalog can trace individual columns. Across a project boundary, it shows how a public model is used by other projects, but not which columns flow where. The dbt version a project runs on can matter as well. An account can mix projects on dbt v1 and dbt v2, because each project can be upgraded to v2 on its own, in any order, while others stay on v1. Projects on different versions can still reference each other's public models. Full Catalog lineage across projects, however, works best when every project in the account is on the same dbt version.
Checkpoint 7 of 8· Check yourself
A developer in project_b can see upstream_a in the Studio IDE lineage view but not in project_b's lineage in Catalog. project_b refs only upstream_b, which depends on upstream_a. What should they conclude?
Catalog shows only immediate dependencies, while the Studio IDE resolves the full graph. A model that appears in the IDE but not in Catalog in this situation is the expected result.
“In the Studio IDE lineage view, however, upstream_a (the indirect dependency) will appear because dbt dynamically resolves the full dependency graph.”Source: docs.getdbt.com
Checkpoint 8 of 8· Exam question
A platform engineer notices that a downstream project's nightly job has started taking much longer to finish and suspects a public model consumed from an upstream project. Using dbt Catalog, what is the most direct way to confirm whether that upstream public model is the bottleneck?
Correct answer: A — Open the upstream public model's detail page in Catalog and review its run history and timing information to see whether its execution time has increased recently.
- A. Correct. Catalog's model detail views include run history and timing, so opening the upstream public model directly shows whether its execution time has grown, which is the direct way to confirm a bottleneck.
- B. Incorrect. Recreating the project dependency changes how the mesh relationship is declared, not how fast the upstream model executes; it does not surface any timing information to diagnose slowness.
- C. Incorrect. Downgrading the plan removes Catalog features like column-level lineage entirely; it does not target or diagnose a specific model's runtime and would only reduce visibility, not improve it.
- D. Incorrect. Account lineage arrows represent dependency relationships between projects, not runtime or arrow thickness encoding; there is no timing signal to read from that graph's visual style.
Exam traps
Each one states something that sounds right. Open it to see what is actually true.
1.A consumer project's Catalog lineage shows every upstream public model in the chain, including ones that its directly referenced models depend on.Why is that wrong?
Catalog shows only public models that the project references directly. Indirect upstream public models appear in the Studio IDE lineage view, not in Catalog.
Covered in Cross-project references in a consumer project's lineage
2.The downstream project count in an upstream project's Relationships tab counts only projects that actually ref one of its models.Why is that wrong?
The count includes every project that lists the upstream project in its dependencies.yml, even without a direct ref.
3.If a public model is visible in Catalog, any user who can see it can also query its data in the warehouse.Why is that wrong?
Model access and Catalog visibility are separate from warehouse grants. dbt does not coordinate them, so a user can see and ref a public model and still lack access to the underlying data.
Covered in Who can see public models in Catalog
4.Column-level lineage in Catalog follows columns across project boundaries into upstream public models.Why is that wrong?
Across projects, Catalog shows how a public model is used, but not at column level.
Covered in Cross-project references in a consumer project's lineage
Sources
Every claim above is drawn from one of these pages, quoted as it was written on the date shown.
- 1.
“public models are discoverable for every user in the dbt account”
↩︎ Who can see public models in Catalog“The existence of projects that have at least one public model will be visible to everyone in the organization with read-only access.”
↩︎ Who can see public models in Catalog“an analyst on another team can prepare a well-informed request for access to the underlying data.”
↩︎ Who can see public models in Catalog“You can upgrade select projects to dbt v2 while keeping others on dbt v1.”
↩︎ Cross-project references in a consumer project's lineage“You can upgrade dbt Mesh projects to dbt v2 in any order”
↩︎ Cross-project references in a consumer project's lineage“some advanced platform features (like full Catalog lineage visibility across projects) work best when all projects use the same engine.”
↩︎ Cross-project references in a consumer project's lineage“public models are discoverable for every user in the dbt account”
↩︎ Key concept“they realize they do not have access to the underlying data in the data warehouse”
↩︎ Exam trap 3“they realize they do not have access to the underlying data in the data warehouse”
↩︎ Checkpoint - 2.
“you can only view full public model details and private models if you have permissions for the specific project where those models are defined.”
↩︎ Who can see public models in Catalog“If you have permissions for a project in the account, you can view all public models used across the entire account.”
↩︎ Who can see public models in Catalog“Double-clicking on a model from another project opens the resource-level lineage graph of the parent project, if you have the permissions to do so.”
↩︎ Who can see public models in Catalog“Click Account lineage in the upper right corner.”
↩︎ Browsing every project and public model in the account“each project appears as its own node with the project name and a count of public models it exposes”
↩︎ Browsing every project and public model in the account“Click List view to switch to a table of projects and public models.”
↩︎ Browsing every project and public model in the account“Downstream projects that reference the project's public models, shown as separate project nodes connected by dashed lines.”
↩︎ Seeing who consumes a project's public models“Nodes that represent another dbt project show a project icon to the left of the project name.”
↩︎ Seeing who consumes a project's public models“Columns tab: each column's name, data type, and description, plus column test results when tests are defined.”
↩︎ Seeing who consumes a project's public models“Click on an upstream (parent) project to view the other projects that reference it in the Relationships tab”
↩︎ Seeing who consumes a project's public models“This includes all projects listing the upstream one as a dependency in its dependencies.yml file”
↩︎ Seeing who consumes a project's public models“such as the specific dbt project that produces that model, description, package, and more.”
↩︎ Cross-project references in a consumer project's lineage“Double-clicking on a model from another project opens the resource-level lineage graph of the parent project, if you have the permissions to do so.”
↩︎ Cross-project references in a consumer project's lineage“When viewing a project's lineage, Catalog shows only directly referenced public models. It doesn't show indirect dependencies.”
↩︎ Exam trap 1“This includes all projects listing the upstream one as a dependency in its dependencies.yml file”
↩︎ Exam trap 2“Double-click a project node to open that project's resource-level lineage graph.”
↩︎ Checkpoint“Relationships tab: downstream projects that reference the model, listed under Referenced by.”
↩︎ Checkpoint - 3.
“you'll see all matching resources in search results, with clear indicators for items you don't have access to.”
↩︎ Who can see public models in Catalog“certain features are only available on Enterprise and Enterprise+ plans”
↩︎ Who can see public models in Catalog“You can also navigate to all public models in your account through this view.”
↩︎ Browsing every project and public model in the account - 4.
“Configure models in upstream project with access: public and have at least one successful job run after defining access.”
↩︎ Who can see public models in Catalog“surface cross-project lineage in the lineage and DAG (Directed Acyclic Graph) views.”
↩︎ Cross-project references in a consumer project's lineage - 5.
“This behavior makes sure that Catalog only shows the immediate dependencies available to that specific project.”
↩︎ Cross-project references in a consumer project's lineage“In Explorer, only directly referenced public models (upstream_b in this case) appear.”
↩︎ Prediction“In the Studio IDE lineage view, however, upstream_a (the indirect dependency) will appear because dbt dynamically resolves the full dependency graph.”
↩︎ Checkpoint - 6.
“Cross-project column lineage is supported in the sense of viewing how a public model is used across projects, but not on a column-level”
↩︎ Cross-project references in a consumer project's lineage“Cross-project column lineage is supported in the sense of viewing how a public model is used across projects, but not on a column-level”
↩︎ Exam trap 4