From 43c2deddff0d2b706a2adbdeb8e8e0c147af5b78 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Thu, 1 Oct 2020 23:10:23 -0400 Subject: [PATCH] Add permissions concepts and the beginning of the perms table (#526) --- internal/perms/acl.go | 26 +- internal/perms/acl_test.go | 2 +- website/content/docs/concepts/permissions.mdx | 233 ++++++++++++++++++ website/data/docs-navigation.js | 1 + 4 files changed, 248 insertions(+), 14 deletions(-) create mode 100644 website/content/docs/concepts/permissions.mdx diff --git a/internal/perms/acl.go b/internal/perms/acl.go index 0f09f1693..ea13975b8 100644 --- a/internal/perms/acl.go +++ b/internal/perms/acl.go @@ -76,19 +76,6 @@ func (a ACL) Allowed(r Resource, aType action.Type) (results ACLResults) { continue } switch { - // type=;actions= when action is list or create. - // If create, must be a top-level collection; otherwise an ID or "*" - // must be specified (as a pin format string, below). - case grant.id == "" && - r.Id == "" && - grant.typ == r.Type && - grant.typ != resource.Unknown && - (aType == action.List || - (topLevelType(r.Type) && aType == action.Create)): - - results.Allowed = true - return - // id=;actions= where ID cannot be a wildcard case grant.id == r.Id && grant.id != "" && @@ -98,6 +85,19 @@ func (a ACL) Allowed(r Resource, aType action.Type) (results ACLResults) { results.Allowed = true return + // type=;actions= when action is list or create. + // Must be a top level collection, otherwise must be one of the two + // formats specified below. + case grant.id == "" && + r.Id == "" && + grant.typ == r.Type && + grant.typ != resource.Unknown && + topLevelType(r.Type) && + (aType == action.List || aType == action.Create): + + results.Allowed = true + return + // id=*;type=;actions= where type cannot be // unknown but can be a wildcard to allow any resource at all case grant.id == "*" && diff --git a/internal/perms/acl_test.go b/internal/perms/acl_test.go index 8cac46049..ddd3cc9d9 100644 --- a/internal/perms/acl_test.go +++ b/internal/perms/acl_test.go @@ -36,7 +36,7 @@ func Test_ACLAllowed(t *testing.T) { grants: []string{ "id=a_bar;actions=read,update", "type=host-catalog;actions=create", - "type=host;actions=list", + "type=target;actions=list", "id=*;type=host-set;actions=list,create", }, }, diff --git a/website/content/docs/concepts/permissions.mdx b/website/content/docs/concepts/permissions.mdx new file mode 100644 index 000000000..e21c3f29d --- /dev/null +++ b/website/content/docs/concepts/permissions.mdx @@ -0,0 +1,233 @@ +--- +layout: docs +page_title: Permissions +sidebar_title: Permissions +description: |- + Boundary's permissions model +--- + +# Overview + +Boundary's permissions model is a composable, RBAC, allow-only model that +attempts to marry flexibility with usability. This page discusses the permission +model's fundamental concepts, provides examples of the specific forms of allowed +grants, and contains a table that acts as an easy cheat sheet to help those new +to its grant syntax with crafting roles. + +Each grant is a mapping that describes a resource or set of resources and the actions that should be allowed on them. Thus, each grant contains one or more of: + +* An `id` field that indicates a specific resource or a wildcard to match all +* A `type` field that indicates a specific resource type or a wildcard to match all +* An `actions` field indicating which actions to provide the resources matched by `id` and `type` + +Grant strings can be supplied via JSON or a CLI/UI friendly, easily-composable string syntax. + +Roles are composable; a user's final set of grants will be composed of various +roles that each contribute grants to a set of principals that include that user +or groups of which that user is a member. + +## Applicable Resource Types + +Boundary's [domain model](/docs/concepts/domain-model) is based on resource +types. These can be implemented directly, such as with targets, or they can be +abstract types that are implemented by concrete types within the system. As an +example of the latter, a host catalog is an abstract type and a Static host +catalog is a concrete type. + +From a permissions standpoint, however, all actions take place against directly +implemented or abstract types. There may be actions that are only implemented by +some concrete types (e.g., not all auth methods will support a `change-password` +action), but the permissions model still defines these at the abstract level. +This helps keep the overall system relatively simple and predictable. + +## Scopes are Permission Boundaries + +Every role assigns grants within a specific scope: either the scope in which the +role exists, or a scope that is a child of the scope in which the role exists. +This is controlled by the role's "grant scope ID". + +When a request is made, the scope in which to discover grants is either provided +by the client (if against specific collection types) or is looked up using the +resource's ID. This scope ID, along with the user's ID and the IDs of the groups +the user belongs to, controls which roles are fetched to provide grants for the +request. + +A role provides grants for a request if the grant scope ID matches the request's +scope ID and one or more of the following are true: + +* The user's ID is contained in the principal IDs set on the role +* A group the user belongs to is contained in the principal IDs set on the role +* The user is logged in and the `u_auth` user is contained in the principal IDs set on the role +* The role contains the `u_anon` user in the in the principal IDs set on the role + +## Permission Grant Formats + +Because of the aforementioned properties of the permissions model, grants are +relatively simple. All grants take one of four forms. These examples use the +canonical string syntax; the JSON equivalents are simply an object with a string +`id` value, a string `type` value, and a string array `actions` value. + +### ID Only + +This is the simplest form: for a given specific resource, allow these actions. +Example: + +`id=hsst_1234567890;actions=read,update` + +This grants `read` and `update` actions to that single resource. + +### Type Only + +For a given type, allow these actions. Because type specifies only a collection +as opposed to specific resources within that collection, only colletion actions +are allowed in this format. Currently, this is `create` and `list`. Example: + +`type=host-catalog;actions=create,list` + +There is one additional restriction: this is only valid against "top-level" +resource types, which currently are: + +* Auth Methods +* Auth Tokens +* Groups +* Host Catalogs +* Roles +* Scopes +* Sessions +* Targets +* Users + +The reason for this is that other types of resources are contained within one of +these resource types; for instance, accounts are instantiated within an auth +method. To specify actions against those, you must also specify to which +specific containing resource you want the grants to apply. This can be done with +one of the formats shown below. + +### Wildcard ID + +In this form, the ID of the grant string is a wildcard `*` character. Depending on `type` and `actions` this results in one of a few behaviors. + +#### Wildcard ID + +When just the ID is `*`, it matches all IDs of the given type. This can be used +with both top-level resource types and not. Example: + +`id=*;type=host-set;actions=create,read,update,set-hosts` + +#### Wildcard ID and Type + +`type` can also be a wildcard, which essentially turns it into a catch-all that +will match any resource of any type within the scope: + +`id=*;type=*;actions=read,list` + +#### Wildcard ID, Type, and Actions + +`actions` can also be a wildcard: + +`id=*;type=*;actions=*` + +Such a grant is essentially a full administrator grant for a scope. + +### Pinned ID + +The final form "pins" actions to a non-top-level type within a specific ID. It's +easiest to explain with an example: + +`id=hcst_1234567890;type=host-set;actions=create,read,update` + +In this example, the user is able to create, read, or update host sets within +the scope, but *only the host sets belonging to host catalog hcst_1234567890*. +Pinning is essentially a way to use top-level resources to create mini +permission boundaries for their subordinate resources. + +In this format, `type` can be a wildcard: + +`id=hcst_1234567890;type=*;actions=create,read,update` + +This would allow `create`, `read`, and `update` actions for all types of +subordinate resources (in this case host sets and hosts) underneath the host +catalog with ID `hcst_1234567890`. + +## Resource Table + +The following table works as a quick cheat-sheet to help you manage your +permissions. Note that it's not exhaustive; wildcards can provide additional +ways to specify grants. Instead this table indicates the most scoped-down ways +that access to an action can be granted, while helping to portray the concepts +around ID, type, and pin. + + + + + + + + + + + + + + + + + + + + + + + + + +
Resource TypeAvailable ScopesAPI EndpointParameters into Permissions EngineAvailable Actions/Grant Examples
Auth Method +
    +
  • Global
  • +
  • Organization
  • +
+
/auth-methods +
    +
  • Type
  • +
      +
    • auth-method
    • +
    +
+
+
    +
  • create: Create an auth method
  • +
      +
    • type=auth-method;actions=create
    • +
    +
  • list: List auth methods
  • +
      +
    • type=auth-method;actions=list
    • +
    +
+
/auth-methods/[id] +
    +
  • ID
  • +
      +
    • [id]
    • +
    +
  • Type
  • +
      +
    • auth-method
    • +
    +
+
+
    +
  • read: Read an auth method's configuration
  • +
      +
    • id=[id];actions=read
    • +
    +
  • update: Update an auth method's configuration
  • +
      +
    • id=[id];actions=update
    • +
    +
  • delete: Delete an auth method
  • +
      +
    • id=[id];actions=delete
    • +
    +
+
\ No newline at end of file diff --git a/website/data/docs-navigation.js b/website/data/docs-navigation.js index 5e14a13d1..b9a13a635 100644 --- a/website/data/docs-navigation.js +++ b/website/data/docs-navigation.js @@ -31,6 +31,7 @@ export default [ content: [ 'api-standards', 'cli-standards', + 'permissions', 'security-model', { category: 'domain-model',