User Roles and Permissions Design Doc [DRAFT] #983
Replies: 2 comments
-
Thanks for transcribing all of this information here! I'd like to specify where the |
Beta Was this translation helpful? Give feedback.
-
Action and Hasura Function permissions:Context:Hasura only permits Actions and Hasura Functions to have binary allow/deny permissions per role. However, we need more fine-grained control while not hard-coding any permissions into our Java or SQL code. The solution we settled on was having these permissions declared per-role in the DB that our actions and functions will check before executing. Design:A new table will be created in Merlin, named Each JSONB will have the structure
|
Key | Hasura Action |
---|---|
check_constraints |
constraintViolations |
create_expansion_rule |
addCommandExpansionTypeScript |
create_expansion_set |
createExpansionSet |
expand_all_activities |
expandAllActivities |
insert_ext_dataset |
addExternalDataset |
resource_samples |
resourceSamples |
schedule |
schedule |
sequence_seq_json_bulk |
getSequenceSeqJsonBulk |
simulate |
simulate |
Any Actions not listed above will only have coarse-grained control.
Keys Permitted for `function_permissions`
Key | Hasura Function |
---|---|
apply_preset |
apply_preset_to_activity |
begin_merge |
begin_merge |
branch_plan |
duplicate_plan |
cancel_merge |
cancel_merge |
commit_merge |
commit_merge |
create_merge_rq |
create_merge_request |
create_snapshot |
create_snapshot |
deny_merge |
deny_merge |
delete_activity_reanchor |
delete_activity_by_pk_reanchor_to_anchor |
delete_activity_reanchor_bulk |
delete_activity_by_pk_reanchor_to_anchor_bulk |
delete_activity_reanchor_plan |
delete_activity_by_pk_reanchor_plan_start |
delete_activity_reanchor_plan_bulk |
delete_activity_by_pk_reanchor_plan_start_bulk |
delete_activity_subtree |
delete_activity_by_pk_delete_subtree |
delete_activity_subtree_bulk |
delete_activity_by_pk_delete_subtree_bulk |
get_conflicting_activities |
get_conflicting_activities |
get_non_conflicting_activities |
get_non_conflicting_activities |
get_plan_history |
get_plan_history |
restore_activity_changelog |
restore_activity_changelog |
restore_snapshot |
restore_from_snapshot |
set_resolution |
set_resolution |
set_resolution_bulk |
set_resolution_bulk |
withdraw_merge_rq |
withdraw_merge_request |
Any Functions not included here will only have coarse-grained control.
Allowed Values for `PERMISSION`
Permission | Meaning |
---|---|
NO_CHECK |
The user may run the action/function with no restrictions. The aerie_admin role will always be treated as having NO_CHECK permissions on all Actions and Functions. |
OWNER |
The user must be the owner of all relevant objects directly used by the KEY |
MISSION_MODEL_OWNER |
The user must own the relevant Mission Model |
PLAN_OWNER |
The user must be the Owner of the relevant Plan |
PLAN_COLLABORATOR |
The user must be a Collaborator of the relevant Plan. The Plan Owner is NOT considered a Collaborator of the Plan |
PLAN_OWNER_COLLABORATOR |
The user must be either the Owner or a Collaborator of the relevant Plan |
In general, OWNER
is equivalent to PLAN_OWNER
. Exceptions are as follows:
apply_preset
, whereOWNER
means a user must own both the plan and the preset
On Plan Merge Keys
The following Function Keys are in a group known as "Plan Merge Keys": begin_merge
, cancel_merge
, create_merge_rq
, commit_merge
, deny_merge
, get_conflicting_activities
, get_non_conflicting_activities
, set_resolution
, set_resolution_bulk
, withdraw_merge_rq
.
Plan Merge Keys are special, as they involve multiple plans. As such, there are special Permissions that may be used on these Keys. Additionally, the other Permissions take on a slightly different meaning when applied to a Plan Merge Key.
A complete list of what Permissions are allowed on Plan Merge Keys follows. Recall that the Source Plan is the one providing changes in a merge, and the Target Plan is the one to receive changes in a merge.
Permission | Meaning |
---|---|
NO_CHECK |
The user may run the action/function with no restrictions. The aerie_admin role will always be treated as having NO_CHECK permissions on all Actions and Functions. |
OWNER |
The user must be the Owner of both Plans |
MISSION_MODEL_OWNER |
The user must be the Owner of the relevant Mission Model |
PLAN_OWNER |
The user must be the Owner of either Plan |
PLAN_COLLABORATOR |
The user must be a Collaborator of either Plan. The Plan Owner is NOT considered a Collaborator of the Plan |
PLAN_OWNER_COLLABORATOR |
The user must be either the Owner or a Collaborator of either Plan |
PLAN_OWNER_SOURCE |
The user must be the Owner of the Source Plan. |
PLAN_COLLABORATOR_SOURCE |
The user must be a Collaborator of the Source Plan. |
PLAN_OWNER_COLLABORATOR_SOURCE |
The user must be either the Owner or a Collaborator of the Source Plan. |
PLAN_OWNER_TARGET |
The user must be the Owner of the Target Plan. |
PLAN_COLLABORATOR_TARGET |
The user must be a Collaborator of the Target Plan. |
PLAN_OWNER_COLLABORATOR_TARGET |
The user must be either the Owner or a Collaborator of the Target Plan. |
Beta Was this translation helpful? Give feedback.
-
Table of Contents
Context and scope
Up until recently, Aerie has had (UI-only) authentication, and no
differentiated authorization. The scope of this work is to imbue Aerie
with a first-class notion of users, and to introduce mechanisms for
restricting the actions of these users.
Goals and non-goals
Primary goal: give Aerie users some peace of mind:
To achieve this goal, we set out to:
We acknowledge that different deployments may have different needs, so we additionally wish to:
Non-goals:
Design overview
In our initial cut of roles and permissions, we identified four distinct roles:
Roles are coarse grained, and serve to put a user into a broad
category. The Admin role has no restrictions. The Unauthenticated role
applies to users who have not logged in, and it restricts all capabilities.
The Viewer role, by default, gives a user read-only access to all data
in Aerie.
In addition to read-only access to all data, the User role, by
default, gives a user selective access to certain data and
actions. For certain data and actions, access can be granted to users
on an individual basis. A single user at a time can be given ownership
of a particular plan (referred to as "plan owner"), and multiple users
can simulaneously be given write access to a plan (referred to as
"plan collaborators"). Plan owners and collaborators have write access
to the plans they are associated with, but not to other plans.
Default permissions
Expand below to see the full table of default permissions.
Table of default permissions
These are the default permissions defined by the Aerie system
Activity Directives:
Scheduling Goals and Conditions:
Constraints:
Plan Branching and Merging (the "supplying" plan is being merged into the "receiving" plan):
Command Dictionaries:
Command expansion rules:
UI Views:
Actions:
Other
System context diagram
We wish to configure Hasura and the Gateway to levy access controls on the Client. The Gateway interfaces with CAM for authentication. See the runtime components and connectors diagram below to see which components communicate. Note that all interactions of a Client with the Aerie system happen through the Gateway and Hasura.
Connectors between entities in this diagram represent any form of network communication.
The authentication process starts with a login request to the Gateway
service. The Gateway forwards the request to CAM, and, if it succeeds,
receives a CAM session token. The Gateway uses a secret key to sign a
JSON Web Token (abbreviated JWT). This signed token contains the following information:
This token is not encrypted, but it is signed using symmetric
encryption key. This means that Hasura can use that same secret key to
verify the authenticity and integrity of this token.
Certain trusted clients can be given the Hasura "Admin" secret, which they can provide in requests to Hasura without going through the gateway.
Implementing permissions
Hasura provides an expressive declarative rules language that we have
chosen to use to specify the majority of our permissions. It has the
advantage of being very granular, allowing for fine-grained control of
select, insert, update, and delete permissions on individual
tables. It is customizable via yaml files, making it easier to tweak
for a particular deployment.
Note: One of the docker containers we ship, aeriehasura, internalizes
these yaml files. A mission would need to deploy hasura themselves to
and manage their own metadata make use of custom yaml files.
The tradeoff associated with fine granularity is that it can get a
little repetitive to set select, insert, update, and delete
permissions on every single table, for every role. Traversing long
chains of table relationships can also get quite verbose.
Here is an example of the Hasura permissions definition syntax. This
defines restrictions on operations involving activity directives. This
lives in the same API definition files that we use to expose certain
tables via the API:
Note that the filter field cross references the session header named
"X-Hasura-User-Id" with that activity directive's plan's owners and
collaborators.
As mentioned earlier in this document, the default set of roles
includes Admin, User, and Viewer. (Unauthenticated is a pseudo-role
that allows for permissions to be defined for clients who have not
logged in). These roles are to be stored in a table in the merlin
database. A mission that wishes to add new roles will need to add
these new roles to this table, as well as add permissions definitions
referring to these roles in the yaml files.
Notions such as "Plan owner" and "Plan collaborators" are not "Roles"
in the Hasura sense. A mission cannot add new concepts of this
sort. What they can do is customize the abilities of a plan owner or
collaborator.
API client implications
API clients are now required to provide an Authorization header with all requests. This header can be obtained using the Gateway's login endpoint, or it can be the admin key.
Queries from unauthenticated clients will receive error
responses. Similarly, queries that attempt to perform actions for
which a user does not have permission will also be rejected.
UI implications
In order to tailor a user interface to a particular user's
permissions, it is necessary to be able to query for the set of
permissible queries. Using the role of the given user, Hasura returns
a pared down version of the API schema. The absence of certain parts
of the schema indicates that the current user's role does not have
permission to take these actions - and a user interface can display
that information accordingly.
Note that notions of plan owners, collaborators, and similar notions
of ownership in other entities need to be handled separately - the
query above cannot provide nuance based on filters defined in the
permissions rules.
User IDs
We consider usernames to be mutable, and thus unreliable identifiers,
so we will assign each user a numeric user id.
This does introduce some difficulty in migrating existing data, which
has thus far used username strings. See "Problems left to solve" below.
Some changes involve:
id either in place of or in addition to the username.
permissions that use a relationship to the users table. In other
databases, we will need this id to be in a session header.
or replaced with their numeric counterparts.
first collects the full set of existing usernames, bulk inserts
them into the users table, and then proceeds to supplement or
replace them by joining on the username.
migration script, since it relies on data from a different
database.
Beta Was this translation helpful? Give feedback.
All reactions