# Access Control

## Organization <a href="#organiation" id="organiation"></a>

An organization is the unit of tenant isolation in DeltaStream. All objects ([databases](https://docs.deltastream.io/overview/core-concepts/databases), data [stores](https://docs.deltastream.io/overview/core-concepts/store), [queries](https://docs.deltastream.io/overview/core-concepts/queries), and so on) are set up under the organization.

## User <a href="#user" id="user"></a>

A user represents an authenticated identity within DeltaStream. A user may be a member of multiple organizations. Within each organization, a user can hold one or more [roles](#role).

## DeltaStream Object <a href="#securable_object" id="securable_object"></a>

DeltaStream objects are entities you can protect with access controls. Access to an object is denied by default; it must be explicitly granted privileges to a role. Each object resides within a hierarchy, with the [organization](#_organiation) as the root. Organizations contain data [stores](https://docs.deltastream.io/overview/core-concepts/store), [schema registries](https://docs.deltastream.io/overview/store#_schema_registry), [descriptors](https://docs.deltastream.io/reference/sql-syntax/data-format-serialization#protocol-buffers-and-descriptors), [databases](https://docs.deltastream.io/overview/core-concepts/databases), [function sources](https://docs.deltastream.io/overview/core-concepts/function), and [queries](https://docs.deltastream.io/overview/core-concepts/queries). Databases contain namespaces, which in turn contain streams, changelogs, and materialized views.

<figure><img src="https://1288764042-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fdbd9e6ZJodkgF1H6AVay%2Fuploads%2FeGRrCs3dycuudbRLiFKW%2FAccessControlOrgChartRevised.png?alt=media&#x26;token=54693c20-287a-4686-971a-87e104554fdd" alt="" width="563"><figcaption><p>Securable object container hierarchy</p></figcaption></figure>

Every DeltaStream object is owned solely by the role used when the object was created. The owner role has all [privileges](#_privilege) on the object and can grant or revoke privileges to other [roles](#_role). Object ownership can be transferred from one role to another.

## Privilege <a href="#privilege" id="privilege"></a>

In DeltaStream, privileges determine which role can access and perform operations on a given object. Every object has a set of privileges that can be granted on it. Privileges are managed using the [GRANT](https://docs.deltastream.io/reference/sql-syntax/command/grant-privileges) and [REVOKE](https://docs.deltastream.io/reference/sql-syntax/command/revoke-privileges) commands.

Use of these commands is restricted to:

* The role that owns an object (that is, the role with `OWNERSHIP` privilege on the object)
* Any roles that have the `MANAGE_GRANTS` global privilege for the object
  * By default, this is `SECURITYADMIN`.

{% hint style="info" %}
**Note** A role that holds the global `MANAGE_GRANTS` privilege can grant additional privileges to the current (grantor) role.
{% endhint %}

#### **Available privileges**

<table><thead><tr><th width="290.3333333333333">Privilege</th><th>Applicable object</th><th>Description</th></tr></thead><tbody><tr><td><code>CREATE_DATABASE</code></td><td><a href="#_organiation">Organization</a></td><td>Allows databases to be created</td></tr><tr><td><code>CREATE_STORE</code></td><td><a href="#_organiation">Organization</a></td><td>Allows data stores to be created</td></tr><tr><td><code>CREATE_SCHEMA_REGISTRY</code></td><td><a href="#_organiation">Organization</a></td><td>Allows schema registries to be created</td></tr><tr><td><code>CREATE_DESCRIPTOR_SOURCE</code></td><td><a href="#_organiation">Organization</a></td><td>Allows descriptor sources to be created</td></tr><tr><td><code>CREATE_FUNCTION_SOURCE</code></td><td><a href="#_organiation">Organization</a></td><td>Allows function sources to be created</td></tr><tr><td><code>CREATE_FUNCTION</code></td><td><a href="#_organiation">Organization</a></td><td>Allows functions to be created</td></tr><tr><td><code>CREATE_QUERY</code></td><td><a href="#_organiation">Organization</a></td><td>Allows queries to be run</td></tr><tr><td><code>MANAGE_MEMBERS</code></td><td><a href="#_organiation">Organization</a></td><td>Allows management of users and roles</td></tr><tr><td><code>MANAGE_GRANTS</code></td><td><a href="#_organiation">Organization</a></td><td>Allows management of privileges</td></tr><tr><td><code>USAGE</code></td><td><a href="#_organiation">Organization</a>, <a href="databases">Database</a>, <a href="../databases#_schema">Schema</a>, <a href="../../how-do-i.../database">Namespace</a>, data <a href="store">Store</a>, <a href="../store#_schema_registry">Schema Registry</a>, <a href="../../../reference/sql-syntax/data-format-serialization#protocol-buffers-and-descriptors">Descriptor Source</a>, <a href="function">Function Source</a>, <a href="function">Function</a>, <a href="queries">Query</a>, <a href="#_role">Role</a></td><td>Allows viewing and basic usage of the object. Additional privileges may be required for some actions</td></tr><tr><td><code>CREATE</code></td><td><a href="databases">Database</a>, <a href="../databases#_schema">Schema</a></td><td>For databases, allows new schemas to be created with in the database.<br><br>For schemas, allows defining new relations within the schema.</td></tr><tr><td><code>SELECT</code></td><td><a href="../databases#_relation">Relation</a></td><td>Allows select queries to use to the relation</td></tr><tr><td><code>INSERT</code></td><td><a href="../databases#_relation">Relation</a></td><td>Allows queries to inserting data into the relation</td></tr></tbody></table>

## Role <a href="#role" id="role"></a>

A role is an entity to which privileges can be granted. You assign roles to [users](#_user) to allow them to perform actions against an [object](#_securable_object).

Users can have multiple roles. This enables them to switch roles to perform actions with a different set of privileges.

{% hint style="info" %}
**Note** DeltaStream includes a set of[ built-in roles](#built-in-roles) under every organization. Built-in roles cannot be dropped and the [privileges](#_privilege) assigned to these roles cannot be revoked.
{% endhint %}

Roles also can be granted to other roles. This creates a hierarchy of roles wherein the privileges associated with one role are inherited by any role that's higher in the hierarchy.

Here's an example: In the diagram below, the `SysAdmin` role automatically inherits any privilege assigned to a custom role.

<figure><img src="https://1288764042-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fdbd9e6ZJodkgF1H6AVay%2Fuploads%2Fgit-blob-eecaeeed1b50f00a989f19f8fbf010a41b34c02d%2Frole%20hierarchy.png?alt=media" alt=""><figcaption><p>Role hierarchy</p></figcaption></figure>

### Built-in roles

The following are built into DeltaStream and are available "out of the box:"

* **ORGADMIN** — Root of the the role hierarchy. This role manages operations at the organization level.
* **SYSADMIN** — Has privileges to create, manage, and drop objects.
* **USERADMIN** — Has privileges to manage users and roles within the organization.
* **SECURITYADMIN** — Manages any object grants globally. This role inherits privileges from the `USERADMIN` role.
* **PUBLIC** — A pseudo role granted to all roles within the organization. This role can be granted privileges on objects that are inherited by all other roles.

### Custom roles

Custom roles can be created in two ways:

* by someone with the `USERADMIN` (or a higher) role
* by any other role to which the `MANAGE_MEMBERS` privilege has been granted.

When you create a new role it is not assigned to any user, nor granted to any other role. For roles you intend to be owners of objects, we recommend you use a custom role hierarchy wherein the top-most custom role in the hierarchy is assigned to the `SYSADMIN` system role. This enables system administrators to manage all the objects in the organization, while still restricting management of users and roles to the `USERADMIN` role.

{% hint style="warning" %}
If you do not assign `SYSADMIN` through a role hierarchy to a custom role, the system administrator cannot manage objects owned by the custom role. This means that only roles that have been granted the `MANAGE_GRANTS` privilege (the `SECURITYADMIN` role by default) can view the objects and modify their access grants.
{% endhint %}

For instructions to create custom roles, see [CREATE ROLE](https://docs.deltastream.io/reference/sql-syntax/ddl/create-role).

## Best Practices

We recommend the following best practices for access control:

* Reserve the `ORGADMIN` role for administrative tasks only. **It must not be used for day-to-day access.**
* Administrators should have 2 separate logins:
  * a login with the `ORGADMIN` role for administrative tasks
  * a separate role for day-to-day access.
* `ORGADMIN` must not own any objects and it must never be granted to any other roles.
* `SECURITYADMIN` is also a very powerful role with the `MANAGE_GRANTS` privilege. Only use this role in limited cases.
* `USERADMIN` should be the default role for managing users and role grants. This role typically is the owner of all other custom roles.
* `SYSADMIN` should be the default role for managing objects and should always be the eventual owner of all other objects. You can grant custom roles to `SYSADMIN.` But you must never grant it ownership of other roles. This maintains the separation of responsibility between `SYSADMIN` and `USERADMIN`.
* When you build a custom role hierarchy, define functional roles and access roles. You can grant privileges on objects to access roles, and you can grant access roles to functional roles.
* Use [SCIM](https://docs.deltastream.io/enterprise-security-integrations/okta-scim-integration)-based automation to manage grants of functional roles to users.
