mirror of
https://github.com/lancedb/lancedb.git
synced 2026-10-13 07:12:27 +00:00
Authorization wrote objects as namespace:db/ns and table:db/ns/table, which the deployment rejects; it writes namespace:db:ns and table:db:ns$table, nesting namespaces with $. The page now lists the view, function and secret objects, CREATE_FUNCTION and CREATE_SECRET, USAGE and UPDATE where they apply beyond tables, and what OPERATE and USAGE on system allow. An a: subject names the principal holding a key rather than a narrower grantee, creation falls back to the parent's create privilege only for an unowned database or namespace, and a listing page holds at most 100 entries. The materialized view page said a deployment's refresh, options and stable row id needs depend on version and configuration. Newer versions rebuild the whole view on every create and refresh as a job, need no stable row ids, take no refresh options, and have no REST route to create one; earlier ones differed, and their views have to be recreated. The page and the REFRESH reference now say so, without naming which version a deployment runs. Vector search no longer says it has no SQL form: some deployment versions plan ORDER BY distance(...) LIMIT k as one.
132 lines
5.2 KiB
Plaintext
132 lines
5.2 KiB
Plaintext
---
|
|
title: "Authorization"
|
|
sidebarTitle: "Authorization"
|
|
description: "Who may do what: privileges granted on catalog objects to principals, groups, roles, and API keys."
|
|
icon: shield-halved
|
|
keywords: ["authorization", "authz", "privileges", "rbac", "access control"]
|
|
availability:
|
|
oss: unavailable
|
|
enterprise: varies
|
|
summary: >-
|
|
A deployment checks privileges on its databases, namespaces, tables and
|
|
other catalog objects only when its administrator has configured it to.
|
|
Embedded LanceDB has no such layer: access is whatever the object store
|
|
allows.
|
|
---
|
|
|
|
[Authentication](/enterprise/authentication) establishes who is calling.
|
|
Authorization decides what they may do.
|
|
|
|
An access control entry grants **one privilege** on **one object** to **one
|
|
subject**. Everything below is a consequence of that shape.
|
|
|
|
## Subjects {#subjects}
|
|
|
|
A grant is held by one of four kinds of subject, distinguished by a prefix:
|
|
|
|
| Prefix | Subject |
|
|
| --- | --- |
|
|
| `p:` | a principal, by ID -- `P:` by name |
|
|
| `g:` | a group, by ID -- `G:` by name |
|
|
| `r:` | a role |
|
|
| `a:` | the principal holding an API key, named by the key |
|
|
|
|
Granting to a group or role rather than a principal is what keeps the entry
|
|
count manageable: a principal's effective privileges are the union of what it
|
|
holds directly and what it inherits.
|
|
|
|
`P:`, `G:` and `a:` are ways of naming a subject when you make a request. The
|
|
entry is stored against the ID they resolve to, so a grant to `a:` belongs to
|
|
the principal holding that key and carries that principal's full authority,
|
|
not a narrower one.
|
|
|
|
## Objects {#objects}
|
|
|
|
Objects are addressed by kind and path:
|
|
|
|
```
|
|
system
|
|
database:db
|
|
namespace:db:ns
|
|
table:db:ns$table
|
|
view:db:ns$view
|
|
function:db:ns$function
|
|
secret:db:ns$secret
|
|
```
|
|
|
|
A nested namespace joins its path with `$`, as in `namespace:db:parent$child`
|
|
or `table:db:parent$child$table`.
|
|
|
|
The hierarchy is not decorative. Reaching a table requires `USAGE` on the
|
|
namespace containing it and on the database containing that -- a grant on the
|
|
table alone is not enough to traverse to it.
|
|
|
|
## Privileges {#privileges}
|
|
|
|
| Privilege | Granted on | Allows |
|
|
| --- | --- | --- |
|
|
| `OWNERSHIP` | any object but `system` | ownership, conveying full authority |
|
|
| `USAGE` | system | listing jobs and their events, and looking up other identities |
|
|
| `USAGE` | database | accessing the namespaces inside |
|
|
| `USAGE` | namespace | accessing the tables inside |
|
|
| `USAGE` | function | binding it to a column, and refreshing a column it computes |
|
|
| `USAGE` | secret | binding and resolving it |
|
|
| `SELECT` | table, view | reading rows |
|
|
| `INSERT` | table | appending rows |
|
|
| `UPDATE` | table | modifying existing rows |
|
|
| `UPDATE` | secret | rotating it, without the right to bind or read it |
|
|
| `DELETE` | table | deleting rows |
|
|
| `CREATE_DATABASE` | system | creating a database |
|
|
| `CREATE_NAMESPACE` | database, namespace | creating immediate child namespaces |
|
|
| `CREATE_TABLE` | namespace | creating a table in it |
|
|
| `CREATE_MATERIALIZED_VIEW` | namespace | creating a materialized view in it |
|
|
| `CREATE_VIEW` | namespace | creating a non-materialized view in it |
|
|
| `CREATE_FUNCTION` | namespace | registering a function in it |
|
|
| `CREATE_SECRET` | namespace | creating a secret in it |
|
|
| `OPERATE` | system | describing and controlling jobs, managing caches, and reading server configuration |
|
|
|
|
The four data privileges map onto the four
|
|
[ingestion operations](/ingestion), so a principal that may append but not
|
|
modify is expressed by granting `INSERT` without `UPDATE`.
|
|
|
|
<Note>
|
|
`CREATE_MATERIALIZED_VIEW` and `CREATE_VIEW` are separate privileges because
|
|
[the two objects differ](/basics/catalog): one stores rows and is refreshed,
|
|
the other stores only a query. Granting the ability to create one does not
|
|
grant the other.
|
|
</Note>
|
|
|
|
## Creation privileges resolve upward {#upward}
|
|
|
|
A subtlety worth knowing, because it explains grants that appear to work on
|
|
objects that do not exist yet.
|
|
|
|
When you create an object, the deployment checks the database and each
|
|
namespace that will contain it. One that **has no owner** -- because it does
|
|
not exist yet, or predates per-object authorization -- is treated as one you are
|
|
creating: the check falls back to `CREATE_DATABASE` on `system` for the
|
|
database, or to `CREATE_NAMESPACE` on its parent for a namespace, and you become
|
|
its owner. One that has an owner needs `USAGE` as usual.
|
|
|
|
So a principal holding `CREATE_DATABASE` can create a table in a database that
|
|
has not been created -- which is what makes creation possible at all, and why
|
|
an empty ACL set is not the same as a deny. The fallback applies only when
|
|
creating; other operations on a database or namespace need `USAGE` on it.
|
|
|
|
## Listing grants {#listing}
|
|
|
|
Entries can be listed filtered by object, by subject, or both:
|
|
|
|
```
|
|
object = table:db:ns$documents
|
|
subject = G:data-science
|
|
```
|
|
|
|
Results paginate through a continuation token, at most 100 entries to a page. One stored `(object, subject)`
|
|
tuple carrying several privileges expands into several entries in the
|
|
response, so the count reflects privileges rather than tuples.
|
|
|
|
Listing by subject answers "what can this team reach"; listing by object
|
|
answers "who can reach this table". Both are worth running before changing a
|
|
grant.
|