-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Port #275 to 3-dev #305
Merged
Merged
Port #275 to 3-dev #305
Changes from 2 commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
4176155
Port #275 to 3-dev
Aschen 4a5132c
Update src/core/1/guide/guides/essentials/security/index.md
Aschen a3fcd89
fix security links
Aschen a6f9e53
fix security links
Aschen 12b514a
LOZLZ
Aschen 056b787
Merge branch '3-dev' into 3dev-port-275
Aschen File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -34,11 +34,11 @@ This means that: | |||||
|
||||||
## User Permissions | ||||||
|
||||||
User-level permissions control what data a specific user or set of users has access to, and what actions they can perform on that data. | ||||||
User-level permissions control what API actions can be executed and, optionally, restrict those to targeted data indexes and collections. | ||||||
|
||||||
### Users, Profiles and Roles | ||||||
|
||||||
Kuzzle's security layer links `users` to one or more `profiles`. | ||||||
Kuzzle's security layer links `users` to one or more `profiles`. | ||||||
You can think of a `profile` as a group of users that share the same permissions. | ||||||
|
||||||
The `profiles` themselves are made up of different groups of permissions, these groups are called `roles`. | ||||||
|
@@ -55,20 +55,20 @@ All `roles` and `profiles` can be edited in the [Kuzzle Admin Console](/core/1/g | |||||
|
||||||
A `role` can be defined using a hierarchical JSON object where permissions are outlined by `controller` and `action`. | ||||||
|
||||||
The `role` definition is represented as a Javascript object where each key at the root of the object identifies a `controller` by name: | ||||||
The `role` definition is represented as a JSON object where each key at the root of the object identifies a `controller` by name. | ||||||
|
||||||
```js | ||||||
const myRoleDefinition = { | ||||||
controllers: { | ||||||
< controller|* >: { | ||||||
actions: { | ||||||
< action|* >: < action permission|* >, | ||||||
< action|* >: < action permission|* >, | ||||||
... | ||||||
{ | ||||||
"controllers": { | ||||||
"<controller name|*>": { | ||||||
"actions": { | ||||||
"<action name|*>": true, // accepted values: [true|false|object] | ||||||
"<action name|*>": false, | ||||||
// ... | ||||||
} | ||||||
} | ||||||
} | ||||||
}; | ||||||
} | ||||||
``` | ||||||
|
||||||
The `controllers` and `actions` properties can be set to a specific value or to the wildcard value "\*". | ||||||
|
@@ -78,23 +78,24 @@ When `controller` is declared within a Plugin, its name must be prefixed with th | |||||
The `action permission` value can be set to either: | ||||||
|
||||||
- a boolean. If `true`, the `role` allows the given action. | ||||||
- an object describing a dynamic right definition. For more information check out the [advanced roles documentation](/core/1/guide/guides/kuzzle-depth/roles-definitions/)). | ||||||
- <DeprecatedBadge version="1.4.0"/> an object describing a dynamic right definition. For more information check out the [advanced roles documentation](/core/1/guide/guides/kuzzle-depth/roles-definitions/)). | ||||||
|
||||||
As an example, below is the `role` definition that Kuzzle uses to request authorization from the anonymous user once the administrator account is created and anonymous access is blocked. | ||||||
|
||||||
```js | ||||||
const anonymousRole = { | ||||||
controllers: { | ||||||
auth: { | ||||||
actions: { | ||||||
login: true, | ||||||
checkToken: true, | ||||||
getCurrentUser: true, | ||||||
getMyRights: true | ||||||
{ | ||||||
"controllers": { | ||||||
"auth": { | ||||||
"actions": { | ||||||
"login": true, | ||||||
"checkToken": true, | ||||||
"getCurrentUser": true, | ||||||
"getMyRights": true | ||||||
} | ||||||
} | ||||||
} | ||||||
}; | ||||||
} | ||||||
|
||||||
``` | ||||||
|
||||||
In the above `role` definition, anonymous users can perform the [login](/api/1/controller-auth/login/), [checkToken](/api/1/controller-auth/check-token/), [getCurrentUser](/api/1/controller-auth/get-current-user/) and [getMyRights](/api/1/controller-auth/get-my-rights/) actions of the `auth` controller. | ||||||
|
@@ -109,26 +110,34 @@ curl -X GET 'http://localhost:7512/?pretty' | |||||
|
||||||
## Defining Profiles | ||||||
|
||||||
A `profile` definition is a Javascript object that contains an array of policies, each composed of a roleId and an array of restrictions: | ||||||
A `profile` definition is a JSON object that contains an array of policies, each composed of a roleId and an array of restrictions: | ||||||
|
||||||
```js | ||||||
const myProfileDefinition = { | ||||||
policies: [ | ||||||
{ | ||||||
"policies": [ | ||||||
{ | ||||||
roleId: "< role Id >", | ||||||
restrictedTo: [ | ||||||
// Applied to all indexes and collections | ||||||
"roleId": "<role identifier>" | ||||||
}, | ||||||
{ | ||||||
// Restricted to a list of indexes or to a list of collections | ||||||
"roleId": "<another role identifier>", | ||||||
"restrictedTo": [ | ||||||
{ | ||||||
index: "< some index >", | ||||||
collections: [ | ||||||
"< a collection >", | ||||||
"< another collection >" | ||||||
] | ||||||
// All collections of this index are allowed | ||||||
"index": "<another index name>" | ||||||
}, | ||||||
... | ||||||
{ | ||||||
// Only the specified list of collections are allowed | ||||||
"index": "<an authorized index name>", | ||||||
"collections": [ | ||||||
"<authorized collection 1>", | ||||||
"<authorized collection 2>", | ||||||
"<...>" | ||||||
] | ||||||
} | ||||||
] | ||||||
}, | ||||||
<another role>, | ||||||
... | ||||||
} | ||||||
] | ||||||
}; | ||||||
``` | ||||||
|
@@ -138,65 +147,67 @@ When applying a role to a profile, the role can be applied to all indexes and co | |||||
For example, if we have a "publisher" role which allows any action on the `document` controller: | ||||||
|
||||||
```js | ||||||
const publisherRole = { | ||||||
controllers: { | ||||||
document: { | ||||||
actions: { | ||||||
'*': true | ||||||
{ | ||||||
"controllers": { | ||||||
"document": { | ||||||
"actions": { | ||||||
"*": true | ||||||
} | ||||||
} | ||||||
} | ||||||
}; | ||||||
} | ||||||
``` | ||||||
|
||||||
Then we can declare three different profiles using this same role, each with varying levels of access based on the index and collection: | ||||||
|
||||||
* Applies the publisher role to all indexes and collections | ||||||
|
||||||
```js | ||||||
const profile1 = { | ||||||
policies: [{ roleId: 'publisherRole' }] | ||||||
}; | ||||||
{ | ||||||
"policies": [ | ||||||
{"roleId": "publisherRole"} | ||||||
] | ||||||
} | ||||||
``` | ||||||
|
||||||
const profile2 = { | ||||||
policies: [ | ||||||
* Applies the publisher role only to the index "index1" and all its collections | ||||||
|
||||||
```js | ||||||
{ | ||||||
"policies": [ | ||||||
{ | ||||||
roleId: 'publisherRole', | ||||||
restrictedTo: [{ index: 'index1' }] | ||||||
"roleId": "publisherRole", | ||||||
"restrictedTo": [{"index": "index1"}] | ||||||
} | ||||||
] | ||||||
}; | ||||||
} | ||||||
``` | ||||||
|
||||||
* Applies the publisher role only to the collections "foo" and "bar" in the index "index1", and then to the index "index2" and all its collections | ||||||
|
||||||
const profile3 = { | ||||||
policies: [ | ||||||
```js | ||||||
{ | ||||||
"policies": [ | ||||||
{ | ||||||
roleId: 'publisherRole', | ||||||
restrictedTo: [ | ||||||
{ index: 'index1', collections: ['foo', 'bar'] }, | ||||||
{ index: 'index2' } | ||||||
"roleId": "publisherRole", | ||||||
"restrictedTo": [ | ||||||
{"index": "index1", "collections": ["foo", "bar"]}, | ||||||
{"index": "index2"} | ||||||
] | ||||||
} | ||||||
] | ||||||
}; | ||||||
} | ||||||
``` | ||||||
|
||||||
These three profiles will provide the following restrictions: | ||||||
|
||||||
- users with `profile1` are allowed to use all `document` controller actions on all indexes and collections. | ||||||
- users with `profile2` are only allowed to use `document` controller actions on collections stored in index `index1`. | ||||||
- users with `profile3` are only allowed to use `document` controller actions on: | ||||||
- all collections stored in index `index2` | ||||||
- collections `foo` and `bar` stored in index `index1`. | ||||||
|
||||||
--- | ||||||
|
||||||
## Writing complex permission rules | ||||||
|
||||||
So far, we've seen how to set permissions to API routes, using user roles and profiles. | ||||||
|
||||||
But this is rarely enough to secure an application, as it's commonplace to reject queries or data depending of business rules. | ||||||
But this is rarely enough to secure an application, as it's commonplace to reject queries or data depending of business rules. | ||||||
For instance, suppose you have a chat application and you want the users to only be able to edit & delete their own messages: this type of rules cannot be expressed as a simple boolean. | ||||||
|
||||||
There are multiple ways of adding a business logic layer on top of the standard Kuzzle security one: | ||||||
|
||||||
- <DeprecatedBadge version="1.4.0" /> Using [Permission Closures](core/1/guide/guides/kuzzle-depth/roles-definitions/), you can add functions directly into role definitions | ||||||
- If all you need is to make sure that submitted documents follow a strict set of formatting rules, you can add [document validators](/core/1/guide/cookbooks/datavalidation/) | ||||||
- With a [Pipe Plugin](/core/1/plugins/essentials/pipes), you can listen to one or multiple [API events](/core/1/plugins/events/), and decide whether you accept a query or document according to your business rules | ||||||
* With a [Pipe Plugin]({{ site_base_path }}plugins/1/essentials/pipes), you can listen to one or multiple [API events]({{ site_base_path }}plugins/1/events/), and decide whether you accept a query or document according to your business rules (you can see an example on [Github](https://github.com/kuzzleio/kuzzle-plugin-sample-custom-policies)) | ||||||
* If all you need is to make sure that submitted documents follow a strict set of formatting rules, you can add [document validators]({{ site_base_path }}guide/1/datavalidation/) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
* <DeprecatedBadge version="1.4.0" /> Using <a href="{{ site_base_path }}guide/1/kuzzle-depth/roles-definitions">Permission Closures</a>, you can add functions directly into role definitions | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.