Role Bindings
Role bindings bind together roles, but what does that mean? In essence, they connect a public key to a role. If you want to grant a user permissions you first need a Role with those permissions. Then you need to grant their public-key access to those permissions using a role binding.
Remember that all requests into the M10 API are signed with ECDSA private keys, that have a public key associated with them
Each role binding has a few different fields, some fairly self-explanatory, and others not so much. Each role binding must have a unique id. We often use UUIDs as ids, though you can use any unique string of bytes. Role bindings also have names, which can be used for easy identification when querying. Finally, every role binding has a "role" field which is the id of the role you wish to bind. There are a few more fields that allow for complex behavior, each of which will have its own section.
Expressions
Expressions are a way of conditionally applying role bindings. If you are familiar with GCP's RBAC system then you will find these familiar. Each role binding supports a list of expressions, one for each collection the role binding operators on. Expressions are written in a small non-Turing complete language called MQL. MQL has a similar syntax to Rust, and will hopefully be familiar to users of most C-like languages. For more detail on MQL's syntax visit the design page on it.
Expressions tend to be in forms like request.timestamp <= 1660687573
. This example expression could limit a role-binding so it only takes place
Expressions are particularly useful when combined with is_universal
. is_universal
allows a role-binding to be used by any public key. You may have noticed that most of M10's models have a field called owner
. The owner field does not actually give any permissions. Instead, we often create role bindings with an expression like document.owner == public_key
.
Permissions on RBAC
Who watches the watcher? Or said less cryptically, how do we get permissions to create roles and role-bindings ourselves? Roles are fairly safe to allow anyone to create -- an operator may wish to restrict this functionality, but it's not necessary. Role-bindings on the other hand actually give public-keys permissions. There are two ways to grant access to creating a role-binding. The first is to simply grant the key a new role and binding with create
on the role-bindings
collection.
The second is a little more nuanced. M10's RBAC system allows you to create a role-binding to any role that is less permissive than a role you already have. So say you have access to your account, you can then create a new role-binding that gives someone else access to your account. This model gives users the autonomy to grant permissions to accounts they own or already have access to. For example, if a user has a new key they want to onboard to their account, they can simply create a new role-binding with that key.
Model
API Calls
Create
- Rust
- TS
- Dart
- CLI
Get
- Rust
- TS
- Dart
- CLI
List
- Rust
- TS
- Dart
- CLI
Update
- Rust
- TS
- Dart
- CLI
Delete
- Rust
- TS
- Dart
- CLI