SELECT Is Not the Whole Permission to Read a Table
A Shared Table Needed a Shared Access Decision
BOTIE
Databricks introduced Unity Catalog in 2021 as a shared governance system. The managed service now covers data and AI objects. Databricks announced an open-source Unity Catalog project in June 2024. The managed Databricks service and the open-source project are related products with different operational scope; the SQL reference here uses the managed service’s documented privileges.
A catalog records what objects are called and where they belong. Access rules attach privileges to those objects and to principals, the users, groups or service identities receiving permission. We will follow one training job through those relationships, so a successful read in somebody else’s notebook cannot stand in for the job’s own permission check.
The Model Job Can See the Table Name but Cannot Read Its Rows
Botie’s experiment manifest names the right table. The scheduled job fails when it tries to read it, even though someone granted SELECT. The person who explored the data in a notebook and the service running training may also have different permissions.
A table belongs inside a schema and catalog. Reading it needs the relevant access at those boundaries, under the identity actually executing the job. Granting broad administrator access would conceal which permission was missing.
This local check considers direct explicit grants for the supplied verified identities. Authentication, group resolution and the platform’s full effective-permission rules remain the real service’s responsibility.
Step 1 of 1
Read the complete object name
The same short table name can exist in another schema or catalog.
| Boundary | Object | Explicit privilege in this fixture |
|---|---|---|
| Catalog | lab | USE CATALOG |
| Schema | lab.training | USE SCHEMA |
| Table | lab.training.features | SELECT |
Catalog
- Object
- lab
- Explicit privilege in this fixture
- USE CATALOG
Schema
- Object
- lab.training
- Explicit privilege in this fixture
- USE SCHEMA
Table
- Object
- lab.training.features
- Explicit privilege in this fixture
- SELECT
Resolve the full name before asking who may read it
A table read requires its declared object boundaries under the actual principal, not an unrelated successful grant.
Check each boundary of the table read
The training job has SELECT, but one enclosing namespace permission is absent.
BOTIE
Access decision and missing explicit requirements
{
"allow": false,
"missing": [
"USE SCHEMA lab.training"
]
}Follow the operations
1. Complete catalog.schema.table name
lab.training.features
2. List the table read requirements
[ { "object": "lab", "privilege": "USE CATALOG" }, { "object": "lab.training", "privilege": "USE SCHEMA" }, { "object": "lab.training.features", "privilege": "SELECT" } ]3. Explicit privilege records
[ { "principal": "job", "object": "lab", "privilege": "USE CATALOG" }, { "principal": "job", "object": "lab.training.features", "privilege": "SELECT" } ]4. Verified job identity and established groups
- 0job
5. Check each requirement for the actual principal
[ { "requirement": "USE CATALOG lab", "allowed": true }, { "requirement": "USE SCHEMA lab.training", "allowed": false }, { "requirement": "SELECT lab.training.features", "allowed": true } ]6. Require every read privilege
{ "allow": false, "missing": [ "USE SCHEMA lab.training" ] }7. Result
{ "allow": false, "missing": [ "USE SCHEMA lab.training" ] }
This local check considers direct explicit grants for the supplied verified identities. Authentication, group resolution and the platform’s full effective-permission rules remain the real service’s responsibility.
1. Resolve the full name before asking who may read it
Start by locating the object the job wants. In lab.training.features, lab names the catalog, training names a schema inside it, and features names the table. These names let the service distinguish this features table from a table with the same short name in another team’s schema.
Our teaching check asks for permission to use the catalog and schema, then permission to read the table. Keep each privilege beside the object it refers to. A free-floating SELECT label would not tell us which table the job may read.
A complete name makes the scope of the next permission question explicit.
A privilege is paired with its object
Tuples can keep privilege and object together in a set. Matching SELECT does not make the enclosing requirements disappear.
required = {("USE CATALOG","lab"),("USE SCHEMA","lab.training"),("SELECT","lab.training.features")}
granted = {("SELECT","lab.training.features")}
print(sorted(required - granted))[('USE CATALOG', 'lab'), ('USE SCHEMA', 'lab.training')]This component omits principal identity. The challenge adds that boundary instead of assuming every shown grant belongs to the caller.
2. Check the principal that actually runs the job
A principal is the identity receiving privileges, such as a user, group or service principal. A scheduled training job can run as a different principal from the notebook author. Inspect that execution context before editing grants.
The workshop receives verified principal and group identities as application-provided data. It does not let an agent authenticate itself by writing a group name. Real group membership must come from the identity system and be enforced at the data service.
For a read under this explicit model, SELECT must be accompanied by USE CATALOG and USE SCHEMA at the enclosing objects.
Check yourself
Questions on Parts 1 to 2
Question 1 of 2
What is missing?
Use the information below.
The only explicit grants for training-job are USE CATALOG on lab and SELECT on lab.training.features. This local check requires namespace usage as well as table read permission.3. Grant the needed boundary rather than hiding it
The SQL reference grants the explicit read permissions to an example training group. An authorised owner or administrator must choose and apply actual grants. Do not run it on a production catalog merely to make an exercise pass.
Real Unity Catalog can inherit some privileges from ancestor objects, and owners or administrators can have other authority. The browser model checks direct explicit grants only. Use the platform’s actual effective permission evidence when diagnosing a real job.
Permission to use a namespace is different from permission to read every table in it. Keep the selected table grant narrow when that matches the job’s scope.
Run in your own environment
Grant an isolated training group its declared table read
This optional reference runs in your own Databricks environment. The browser exercise below uses ordinary Python and does not contact Databricks.
Run only as an authorised grant manager in your own approved Unity Catalog environment. Replace the example group and object names deliberately.
These SQL statements change access. This is a reference to review, not a browser exercise that needs to be executed.
GRANT USE CATALOG ON CATALOG lab TO `training-job-readers`;
GRANT USE SCHEMA ON SCHEMA lab.training TO `training-job-readers`;
GRANT SELECT ON TABLE lab.training.features TO `training-job-readers`;
SHOW GRANTS ON TABLE lab.training.features;Inspect the effective principal and all relevant object levels. Do not assume a notebook author’s successful read proves a scheduled job has the same access.
Official interface documentation. Documentation checked .
4. Preserve the missing requirements in a refusal
A useful refusal can say which declared boundary is missing without returning the protected rows. Our result is {allow, missing}; missing contains privilege/object pairs. Requiring every listed result prevents one successful SELECT check from masking a failed enclosing requirement.
Passing this educational check does not authorise a real data request. The server and platform must still enforce current permission when data is accessed, including revocations after an earlier run was approved.
Relevance, validation quality and permission answer different questions. A useful feature can still be forbidden to this training job.
5. Test a different identity and a different schema
First provide SELECT but omit USE SCHEMA. Then keep all grant records unchanged and replace the principal with an unrelated job. Finally move the same short table name to another schema. Each case tests whether identity and object scope remain attached to the privilege.
The next lesson assumes the feature rows were obtained through a permitted read. It will ask which of those rows were available at the time of each prediction, another boundary permission alone cannot establish.
The next decision is which historically available rows belong to each prediction.
Check yourself
Questions on Parts 1 to 5
Question 1 of 4
Which scope changed?
Use the information below.
The allowed object is lab.training.features. A request now names lab.private.features.Try it with Botie
Build with Botie
Write and run Python