From 9b4a9a60d902805feea5cc4d7483fff0572ca42b Mon Sep 17 00:00:00 2001 From: Mark Rushakoff Date: Tue, 20 Jun 2017 14:08:03 -0700 Subject: [PATCH 1/5] Add FGA guide --- .../v1.3/guides/fine-grained-authorization.md | 393 ++++++++++++++++++ 1 file changed, 393 insertions(+) create mode 100644 content/enterprise_influxdb/v1.3/guides/fine-grained-authorization.md diff --git a/content/enterprise_influxdb/v1.3/guides/fine-grained-authorization.md b/content/enterprise_influxdb/v1.3/guides/fine-grained-authorization.md new file mode 100644 index 0000000000..ad07417d2a --- /dev/null +++ b/content/enterprise_influxdb/v1.3/guides/fine-grained-authorization.md @@ -0,0 +1,393 @@ +--- +title: Fine Grained Authorization +alias: + -/docs/v1.3/administration/fga +menu: + influxdb_1_3: + weight: 10 + parent: guides +--- + +## Controlling access to data with Enterprise's Fine-Grained Authorization + +In open source InfluxDB, access control operates only at a database level. +In Enterprise, fine-grained authorization can be used to control access at a measurement or series level. + +### Concepts + +To use fine-grained authorization (hereafter "FGA"), you must first enable authentication in your configuration file. +Then the admin user needs to create users through the query API and grant those users explicit read and/or write privileges per database. +So far, this is the same as how you would configure authorization on an open source InfluxDB instance. + +To continue setting up fine-grained authorization, the admin user must first set _restrictions_ which define a combination of database, measurement, and series which cannot be accessed without an explicit _grant_. +A _grant_ enables access to entities that were previously restricted. + +Restrictions specify _permissions_ defining whether reads and/or writes are being restricted, and they specify _selectors_ defining the combination of database, measurement, and tags. +Grants also specify permissions and selectors, but unlike restrictions, grants are able to specify _users_ and _roles_. +Users are the same as the users created in InfluxQL, and roles, an Enterprise feature, are created separately through the Meta HTTP API. +(Roles are not covered in this guide.) + +### Modifying grants and restrictions + +To configure FGA, you will need access to the meta nodes' HTTP ports (which run on port 8089 by default). +Note that in a typical cluster configuration, the data nodes' HTTP ports (8086 by default) are exposed to clients but the meta nodes' HTTP ports are not. +You may need to work with your network administrator to gain access to the meta nodes' HTTP ports. + +### Scenario: partitioning access within a single measurement via users + +We'll assume a schema of a database named `datacenters`, one measurement named `network` with a tag of `dc=east` or `dc=west`, and two fields, `bytes_in` and `bytes_out`. +Suppose you want to make sure that the client in the east datacenter can't read or write the west datacenter's metrics, and vice versa. + +First, as an administrator, you would create the database and users and standard grants with InfluxQL queries: + +``` +CREATE DATABASE datacenters + +CREATE USER east WITH PASSWORD 'east' +GRANT ALL ON datacenters TO east + +CREATE USER west WITH PASSWORD 'west' +GRANT ALL ON datacenters TO west +``` + +At this point, the east and west users have unrestricted write access to the `datacenters` database and the ops user has unrestricted read access. +We'll need to use curl to set up the restrictions first, and we'll need to decide how to apply the restrictions. + +#### Restrictions + +##### Restriction option 1: the entire database + +Restricting the entire database is a simple option, and in most cases it is the simplest option to reason about. +Moreover, because this is a very general restriction, it will have minimal impact on performance. + +Assuming the meta node is running its HTTP service on localhost on the default port, you can run + +``` +curl -L -XPOST "http://localhost:8091/influxdb/v2/acl/restrictions" \ + -H "Content-Type: application/json" \ + --data-binary '{ + "database": {"match": "exact", "value": "datacenters"}, + "permissions": ["read", "write"] + }' +``` + +After applying this restriction and before applying any grants, the east and west users will not be authorized to write to the database. + +##### Restriction option 2: one measurement within the database + +Restricting a single measurement will disallow writes within that measurement, but access to other measurements within the database will be decided by standard permissions. + +``` +curl -L -XPOST "http://localhost:8091/influxdb/v2/acl/restrictions" \ + -H "Content-Type: application/json" \ + --data-binary '{ + "database": {"match": "exact", "value": "datacenters"}, + "measurement": {"match": "exact", "value": "network"}, + "permissions": ["read", "write"] + }' +``` + +Compared to the previous approach of restricting the entire database, this only restricts access to the measurement `network`. +In this state, the east and west users are free to read from and write to any measurement in the database `datacenters` besides `network`. + +##### Restriction option 3: specific series in a database + +The most fine-grained restriction option is to restrict specific tags in a measurement and database. + +``` +for region in east west; do + curl -L -XPOST "http://localhost:8091/influxdb/v2/acl/restrictions" \ + -H "Content-Type: application/json" \ + --data-binary '{ + "database": {"match": "exact", "value": "datacenters"}, + "measurement": {"match": "exact", "value": "network"}, + "tags": [{"match": "exact", "key": "dc", "value": "'$region'"}], + "permissions": ["read", "write"] + }' +done +``` + +This configuration would allow reads and writes from any measurement in `datacenters`; and when the measurement is `network`, it would only restrict when there is a tag `dc=east` or `dc=west`. +This is probably not what you want, as it would allow writes to `network` without tags or writes to `network` with a tag key of `dc` and a tag value of anything but `east` or `west`. + +##### Restriction summary + +These options were simple matchers on exact patterns. +Remember that you will achieve the best performance by having few, coarse-grained restrictions as opposed to many fine-grained restrictions. + +We only used the matcher `exact` above, but you can also match with `prefix` if you want to restrict based on a common prefix on your database, measurements, or tags. +The other matcher option is `regex` to use a regular expression. + +#### Grants + +Now that you've applied your restrictions that apply to all users, you must apply grants to allow selected users to bypass the restrictions. +The structure of a POST body for a grant is identical to the POST body for a restriction, but with the addition of a `users` array. + +##### Grant option 1: the entire database + +This offers no guarantee that the users will write to the correct measurement or use the correct tags. + +``` +curl -s -L -XPOST "http://localhost:8091/influxdb/v2/acl/grants" \ + -H "Content-Type: application/json" \ + --data-binary '{ + "database": {"match": "exact", "value": "datacenters"}, + "permissions": ["read", "write"], + "users": [{"name": "east"}, {"name": "west"}] + }' +``` + +##### Grant option 2: one measurement within the database + +This guarantees that the users will only have access to the `network` measurement but it still does not guarantee that they will use the correct tags. + +``` +curl -s -L -XPOST "http://localhost:8091/influxdb/v2/acl/grants" \ + -H "Content-Type: application/json" \ + --data-binary '{ + "database": {"match": "exact", "value": "datacenters"}, + "measurement": {"match": "exact", "value": "network"}, + "permissions": ["read", "write"], + "users": [{"name": "east"}, {"name": "west"}] + }' +``` + +##### Grant option 3: specific tags on a database + +This guarantees that the users will only have access to data with the corresponding `dc` tag but it does not guarantee that they will use the `network` measurement. + +``` +curl -s -L -XPOST "http://localhost:8091/influxdb/v2/acl/grants" \ + -H "Content-Type: application/json" \ + --data-binary '{ + "database": {"match": "exact", "value": "datacenters"}, + "tags": [{"match": "exact", "key": "dc", "value": "east"}], + "permissions": ["read", "write"], + "users": [{"name": "east"}] + }' +curl -s -L -XPOST "http://localhost:8091/influxdb/v2/acl/grants" \ + -H "Content-Type: application/json" \ + --data-binary '{ + "database": {"match": "exact", "value": "datacenters"}, + "tags": [{"match": "exact", "key": "dc", "value": "west"}], + "permissions": ["read", "write"], + "users": [{"name": "west"}] + }' +``` + +##### Grant option 4: specific series within the database + +To guarantee that both users only have access to the `network` measurement and that the east user uses the tag `dc=east` and the west user uses the tag `dc=west`, we need to make two separate grant calls: + +``` +curl -s -L -XPOST "http://localhost:8091/influxdb/v2/acl/grants" \ + -H "Content-Type: application/json" \ + --data-binary '{ + "database": {"match": "exact", "value": "datacenters"}, + "measurement": {"match": "exact", "value": "network"}, + "tags": [{"match": "exact", "key": "dc", "value": "east"}], + "permissions": ["read", "write"], + "users": [{"name": "east"}] + }' +curl -s -L -XPOST "http://localhost:8091/influxdb/v2/acl/grants" \ + -H "Content-Type: application/json" \ + --data-binary '{ + "database": {"match": "exact", "value": "datacenters"}, + "measurement": {"match": "exact", "value": "network"}, + "tags": [{"match": "exact", "key": "dc", "value": "west"}], + "permissions": ["read", "write"], + "users": [{"name": "west"}] + }' +``` + +Now, when the east user writes to the `network` measurement, it must include the tag `dc=east`, and when the west user writes to `network`, it must include the tag `dc=west`. +Note that this is only the requirement of the presence of that tag; `dc=east,foo=bar` will also be accepted. + +### Scenario: partitioning access via roles + +Suppose that we have many individuals who need to write to our `datacenters` database in the previous example. +We wouldn't want them to all share one set of login credentials. +We can instead use _roles_, which are associate a set of users with a set of permissions. + +We'll assume that we now have many users on the east and west teams, and we'll have an `ops` user who needs full access to data from both the east and west datacenters. +We will only create one user each for east and west, but the process would be the same for any number of users. + +First we will set up the users. + +``` +CREATE DATABASE datacenters + +CREATE USER e001 WITH PASSWORD 'e001' +CREATE USER w001 WITH PASSWORD 'w001' +CREATE USER ops WITH PASSWORD 'ops' +``` + +#### Creating the roles + +We want one role for full access to any point in `datacenters` with the tag `dc=east` and another role for the tag `dc=west`. + +First, we initialize the roles. + +``` +curl -s -L -XPOST "http://localhost:8091/role" \ + -H "Content-Type: application/json" \ + --data-binary '{ + "action": "create", + "role": { + "name": "east" + } + }' +curl -s -L -XPOST "http://localhost:8091/role" \ + -H "Content-Type: application/json" \ + --data-binary '{ + "action": "create", + "role": { + "name": "west" + } + }' +``` + +Next, let's specify that anyone belonging to those roles has general read and write access to the `datacenters` database. + +``` +curl -s -L -XPOST "http://localhost:8091/role" \ + -H "Content-Type: application/json" \ + --data-binary '{ + "action": "add-permissions", + "role": { + "name": "east", + "permissions": { + "datacenters": ["ReadData", "WriteData"] + } + } + }' + +curl -s -L -XPOST "http://localhost:8091/role" \ + -H "Content-Type: application/json" \ + --data-binary '{ + "action": "add-permissions", + "role": { + "name": "west", + "permissions": { + "datacenters": ["ReadData", "WriteData"] + } + } + }' +``` + +Next, we need to associate users to the roles. +The `east` role gets the user from the east team, the `west` role gets the user from the west team, and both roles get the `ops` user. + +``` +curl -s -L -XPOST "http://localhost:8091/role" \ + -H "Content-Type: application/json" \ + --data-binary '{ + "action": "add-users", + "role": { + "name": "east", + "users": ["e001", "ops"] + } + }' +curl -s -L -XPOST "http://localhost:8091/role" \ + -H "Content-Type: application/json" \ + --data-binary '{ + "action": "add-users", + "role": { + "name": "west", + "users": ["w001", "ops"] + } + }' +``` + +#### Restrictions + +Please refer to the previous scenario for directions on how to set up restrictions. + +#### Grants and roles + +Grants for a role function the same as grants for a user. +Instead of using the key `users` to refer to users, use the key `roles` to refer to roles. + +##### Grant option 1: the entire database + +This offers no guarantee that the users in the roles will write to the correct measurement or use the correct tags. + +``` +curl -s -L -XPOST "http://localhost:8091/influxdb/v2/acl/grants" \ + -H "Content-Type: application/json" \ + --data-binary '{ + "database": {"match": "exact", "value": "datacenters"}, + "permissions": ["read", "write"], + "roles": [{"name": "east"}, {"name": "west"}] + }' +``` + +##### Grant option 2: one measurement within the database + +This guarantees that the users in the roles will only have access to the `network` measurement but it still does not guarantee that they will use the correct tags. + +``` +curl -s -L -XPOST "http://localhost:8091/influxdb/v2/acl/grants" \ + -H "Content-Type: application/json" \ + --data-binary '{ + "database": {"match": "exact", "value": "datacenters"}, + "measurement": {"match": "exact", "value": "network"}, + "permissions": ["read", "write"], + "roles": [{"name": "east"}, {"name": "west"}] + }' +``` + +##### Grant option 3: specific tags on a database + +This guarantees that the users in the roles will only have access to data with the corresponding `dc` tag. +They will have access to any measurement in the `datacenters` database. + +``` +curl -s -L -XPOST "http://localhost:8091/influxdb/v2/acl/grants" \ + -H "Content-Type: application/json" \ + --data-binary '{ + "database": {"match": "exact", "value": "datacenters"}, + "tags": [{"match": "exact", "key": "dc", "value": "east"}], + "permissions": ["read", "write"], + "roles": [{"name": "east"}] + }' +curl -s -L -XPOST "http://localhost:8091/influxdb/v2/acl/grants" \ + -H "Content-Type: application/json" \ + --data-binary '{ + "database": {"match": "exact", "value": "datacenters"}, + "tags": [{"match": "exact", "key": "dc", "value": "west"}], + "permissions": ["read", "write"], + "roles": [{"name": "west"}] + }' +``` + +##### Grant option 4: specific series within the database + +To guarantee that both roles only have access to the `network` measurement and that the east user uses the tag `dc=east` and the west user uses the tag `dc=west`, we need to make two separate grant calls: + +``` +curl -s -L -XPOST "http://localhost:8091/influxdb/v2/acl/grants" \ + -H "Content-Type: application/json" \ + --data-binary '{ + "database": {"match": "exact", "value": "datacenters"}, + "measurement": {"match": "exact", "value": "network"}, + "tags": [{"match": "exact", "key": "dc", "value": "east"}], + "permissions": ["read", "write"], + "roles": [{"name": "east"}] + }' +curl -s -L -XPOST "http://localhost:8091/influxdb/v2/acl/grants" \ + -H "Content-Type: application/json" \ + --data-binary '{ + "database": {"match": "exact", "value": "datacenters"}, + "measurement": {"match": "exact", "value": "network"}, + "tags": [{"match": "exact", "key": "dc", "value": "west"}], + "permissions": ["read", "write"], + "roles": [{"name": "west"}] + }' +``` + +Now, when a user in the east role writes to the `network` measurement, it must include the tag `dc=east`, and when the west user writes to `network`, it must include the tag `dc=west`. +Note that this is only the requirement of the presence of that tag; `dc=east,foo=bar` will also be accepted. + +If a user is in both the east and west roles, they must write points with either `dc=east` or `dc=west`. +When they query data, they will be able to read points tagged with `dc=east` or `dc=west`. From 8f9224da8f5544c0d87dc61f5b1dcc955dac91a6 Mon Sep 17 00:00:00 2001 From: Regan Kuchan Date: Tue, 20 Jun 2017 14:16:34 -0700 Subject: [PATCH 2/5] Fix hugo front matter for FGA guide --- .../v1.3/guides/fine-grained-authorization.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/enterprise_influxdb/v1.3/guides/fine-grained-authorization.md b/content/enterprise_influxdb/v1.3/guides/fine-grained-authorization.md index ad07417d2a..e3c400d944 100644 --- a/content/enterprise_influxdb/v1.3/guides/fine-grained-authorization.md +++ b/content/enterprise_influxdb/v1.3/guides/fine-grained-authorization.md @@ -3,9 +3,9 @@ title: Fine Grained Authorization alias: -/docs/v1.3/administration/fga menu: - influxdb_1_3: + enterprise_influxdb_1_3: weight: 10 - parent: guides + parent: Guides --- ## Controlling access to data with Enterprise's Fine-Grained Authorization From 59a2c2a8c807ca7ef137e82045ea27ab66dc7e54 Mon Sep 17 00:00:00 2001 From: Mark Rushakoff Date: Wed, 21 Jun 2017 11:05:38 -0700 Subject: [PATCH 3/5] Address feedback --- .../v1.3/guides/fine-grained-authorization.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/enterprise_influxdb/v1.3/guides/fine-grained-authorization.md b/content/enterprise_influxdb/v1.3/guides/fine-grained-authorization.md index e3c400d944..7c55581652 100644 --- a/content/enterprise_influxdb/v1.3/guides/fine-grained-authorization.md +++ b/content/enterprise_influxdb/v1.3/guides/fine-grained-authorization.md @@ -50,8 +50,8 @@ CREATE USER west WITH PASSWORD 'west' GRANT ALL ON datacenters TO west ``` -At this point, the east and west users have unrestricted write access to the `datacenters` database and the ops user has unrestricted read access. -We'll need to use curl to set up the restrictions first, and we'll need to decide how to apply the restrictions. +At this point, the east and west users have unrestricted read and write access to the `datacenters` database. +We'll need to decide what restrictions to apply in order to limit their access. #### Restrictions From 3aac870896d7fe0d551e2ac6c5e9d6b20e4c2853 Mon Sep 17 00:00:00 2001 From: Mark Rushakoff Date: Wed, 21 Jun 2017 13:10:09 -0700 Subject: [PATCH 4/5] Address more feedback --- .../v1.3/guides/fine-grained-authorization.md | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/content/enterprise_influxdb/v1.3/guides/fine-grained-authorization.md b/content/enterprise_influxdb/v1.3/guides/fine-grained-authorization.md index 7c55581652..2b979fc915 100644 --- a/content/enterprise_influxdb/v1.3/guides/fine-grained-authorization.md +++ b/content/enterprise_influxdb/v1.3/guides/fine-grained-authorization.md @@ -19,17 +19,17 @@ To use fine-grained authorization (hereafter "FGA"), you must first enable authe Then the admin user needs to create users through the query API and grant those users explicit read and/or write privileges per database. So far, this is the same as how you would configure authorization on an open source InfluxDB instance. -To continue setting up fine-grained authorization, the admin user must first set _restrictions_ which define a combination of database, measurement, and series which cannot be accessed without an explicit _grant_. -A _grant_ enables access to entities that were previously restricted. +To continue setting up fine-grained authorization, the admin user must first set _restrictions_ which define a combination of database, measurement, and tags which cannot be accessed without an explicit _grant_. +A _grant_ enables access to series that were previously restricted. -Restrictions specify _permissions_ defining whether reads and/or writes are being restricted, and they specify _selectors_ defining the combination of database, measurement, and tags. -Grants also specify permissions and selectors, but unlike restrictions, grants are able to specify _users_ and _roles_. +Restrictions limit access to the series that match the database, measurement, and tags specified. +The different access permissions (currently just "read" and "write") can be restricted independently depending on the scenario. +Grants will allow access, according to the listed permissions, to restricted series for the users and roles specified. Users are the same as the users created in InfluxQL, and roles, an Enterprise feature, are created separately through the Meta HTTP API. -(Roles are not covered in this guide.) ### Modifying grants and restrictions -To configure FGA, you will need access to the meta nodes' HTTP ports (which run on port 8089 by default). +To configure FGA, you will need access to the meta nodes' HTTP ports (which run on port 8091 by default). Note that in a typical cluster configuration, the data nodes' HTTP ports (8086 by default) are exposed to clients but the meta nodes' HTTP ports are not. You may need to work with your network administrator to gain access to the meta nodes' HTTP ports. @@ -71,11 +71,11 @@ curl -L -XPOST "http://localhost:8091/influxdb/v2/acl/restrictions" \ }' ``` -After applying this restriction and before applying any grants, the east and west users will not be authorized to write to the database. +After applying this restriction and before applying any grants, the east and west users will not be authorized to read from or write to the database. ##### Restriction option 2: one measurement within the database -Restricting a single measurement will disallow writes within that measurement, but access to other measurements within the database will be decided by standard permissions. +Restricting a single measurement will disallow reads and writes within that measurement, but access to other measurements within the database will be decided by standard permissions. ``` curl -L -XPOST "http://localhost:8091/influxdb/v2/acl/restrictions" \ @@ -113,10 +113,9 @@ This is probably not what you want, as it would allow writes to `network` withou ##### Restriction summary These options were simple matchers on exact patterns. -Remember that you will achieve the best performance by having few, coarse-grained restrictions as opposed to many fine-grained restrictions. +Remember that you will achieve the best performance by having few, broad restrictions as opposed to many narrow restrictions. We only used the matcher `exact` above, but you can also match with `prefix` if you want to restrict based on a common prefix on your database, measurements, or tags. -The other matcher option is `regex` to use a regular expression. #### Grants From 93c4a6ad04b674647a4eba8370ef9431e3a85e1a Mon Sep 17 00:00:00 2001 From: Regan Kuchan Date: Mon, 26 Jun 2017 15:15:25 -0700 Subject: [PATCH 5/5] Add links to FGA guide --- .../v1.3/guides/fine-grained-authorization.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/enterprise_influxdb/v1.3/guides/fine-grained-authorization.md b/content/enterprise_influxdb/v1.3/guides/fine-grained-authorization.md index 2b979fc915..db02a70836 100644 --- a/content/enterprise_influxdb/v1.3/guides/fine-grained-authorization.md +++ b/content/enterprise_influxdb/v1.3/guides/fine-grained-authorization.md @@ -15,7 +15,7 @@ In Enterprise, fine-grained authorization can be used to control access at a mea ### Concepts -To use fine-grained authorization (hereafter "FGA"), you must first enable authentication in your configuration file. +To use fine-grained authorization (hereafter "FGA"), you must first [enable authentication](/influxdb/v1.3/query_language/authentication_and_authorization/#set-up-authentication) in your configuration file. Then the admin user needs to create users through the query API and grant those users explicit read and/or write privileges per database. So far, this is the same as how you would configure authorization on an open source InfluxDB instance. @@ -25,7 +25,7 @@ A _grant_ enables access to series that were previously restricted. Restrictions limit access to the series that match the database, measurement, and tags specified. The different access permissions (currently just "read" and "write") can be restricted independently depending on the scenario. Grants will allow access, according to the listed permissions, to restricted series for the users and roles specified. -Users are the same as the users created in InfluxQL, and roles, an Enterprise feature, are created separately through the Meta HTTP API. +Users are the same as the users created in InfluxQL, and [roles](/enterprise_influxdb/v1.3/features/users/#cluster-user-information), an Enterprise feature, are created separately through the Meta HTTP API. ### Modifying grants and restrictions