Clients are authorized using roles.
- A role can be assigned to multiple users and to multiple groups and vice versa.
- A role defines privileges which grant particular permissions on the index, document-type and field level.
- Privileges from multiple roles are applied in a combined fashion and cannot restrict one another.
Users and groups are assigned to roles using their name.
Note:
For anonymous clients, this is the name of the host.
Privileges consist of the following scopes:
- cluster
- indices
- types
- fields
For the cluster scope you can only define permissions, whereas for all other scopes you define restrictions.
A restriction consists of includes and optionally excludes and permissions. Depending on the scope you have several ways to define includes and excludes.
Note:
Restrictions will inherit permissions from their parent scope, if they do not define any permissions by themselves.
Index in- and excludes can be defined using patterns with one or more optional *
wildcards.
Type restrictions only support includes by explicit names. No wildcards.
Field restrictions are like index restrictions with support for in- and excludes as well as optional *
wildcards.
Permissions are divided into namespaces separated by a slash /
. To grant an entire namespace you can use the *
wildcard instead.
ElasticArmor allows to store some of its configuration in Elasticsearch itself. To access the index and its configuration one of the following cluster-wide permissions is required:
Permission Name | Configuration Type |
---|---|
config/authentication | Users |
config/authorization | Roles |
Each permission in the table below has a scope assigned to it. This is the smallest scope a permission can be granted to. This means that permissions can also be granted in a bigger scope, causing a permission to apply to all restrictions defined in the lower scopes, if they are able to inherit permissions.
Permission Name | Applies to Scope |
---|---|
api/cluster/health | indices |
api/cluster/state | cluster |
api/cluster/stats | cluster |
api/cluster/pendingTasks | cluster |
api/cluster/reroute | cluster |
api/cluster/get/settings | cluster |
api/cluster/update/settings | cluster |
api/cluster/nodes/stats | cluster |
api/cluster/nodes/info | cluster |
api/cluster/nodes/hotThreads | cluster |
api/cluster/nodes/shutdown | cluster |
api/indices/create/index | indices |
api/indices/delete/index | indices |
api/indices/open | indices |
api/indices/close | indices |
api/indices/create/mappings | types |
api/indices/delete/mappings | types |
api/indices/get/mappings | types |
api/indices/create/aliases | indices |
api/indices/delete/aliases | indices |
api/indices/get/aliases | indices |
api/indices/update/settings | indices |
api/indices/get/settings | indices |
api/indices/analyze | indices |
api/indices/create/templates | cluster |
api/indices/delete/templates | cluster |
api/indices/get/templates | cluster |
api/indices/create/warmers | indices |
api/indices/delete/warmers | indices |
api/indices/get/warmers | indices |
api/indices/stats | indices |
api/indices/segments | indices |
api/indices/recovery | indices |
api/indices/cache/clear | indices |
api/indices/flush | indices |
api/indices/refresh | indices |
api/indices/optimize | indices |
api/indices/upgrade | indices |
api/documents/index | types |
api/documents/get | fields |
api/documents/delete | types |
api/documents/update | fields |
api/documents/deleteByQuery | types |
api/documents/termVector | types |
api/search/documents | fields |
api/search/templates | cluster |
api/search/shards | indices |
api/search/suggest | cluster |
api/search/explain | fields |
api/search/percolate | types |
api/search/fieldStats | indices |
api/cat | cluster |
api/bulk | cluster |
api/feature/deprecated | cluster |
api/feature/facets | types |
api/feature/fuzzyLikeThis | fields |
api/feature/innerHits | types |
api/feature/moreLikeThis | fields |
api/feature/notImplemented | types |
api/feature/queryString | types |
api/feature/script | fields |
While the purpose of most of the permissions above should be clear, as they are very similar structured to how Elasticsearch's REST api is, you may wonder what these permissions in the feature namespace are for. They look different to all others and seem to have a special purpose and that is exactly what is intended.
Feature permissions should be granted with care. They are used to protect parts of Elasticsearch's REST api which are not regulated by ElasticArmor to the same extent as the others are. Granting such a permission will most likely allow a client to freely access data or perform write operations. Below are some more details about those feature permissions.
Required for all bulk operations such as:
Required for api endpoints which are deprecated, not fully inspected and where it is unlikely that the missing functionality will be added. These include:
Required for faceted searches because they are not inspected and will never be, as they have been replaced by aggregations.
Required for the Fuzzy Like This Query and the Fuzzy Like This Field Query.
Required for inner hits because they are not inspected yet. Expect this permission to fade out in the future once the missing functionality has been added.
Required for the More Like This API and the More Like This Query.
Required for api endpoints which are not yet fully inspected, but their functionality is partly implemented for other endpoints. These include:
Expect this permission to fade out in the future once the missing functionality has been added.
Required for query string
searches because they are not inspected yet. For compatibility reasons with Kibana, *
does not require it. Expect
this permission to fade out in the future once the missing functionality has been added.
Required for scripting.
ElasticArmor currently supports only one way to configure roles: The Elasticsearch index .elasticarmor
This index is created on the first run using the following settings and mappings:
{
"settings": {
"analysis": {
"analyzer": {
"lowercase_keyword": {
"type": "custom",
"filter": "lowercase",
"tokenizer": "keyword"
}
}
}
},
"mappings": {
"user": {
"properties": {
"password_hash": {
"type": "binary"
}
}
},
"role": {
"properties": {
"privileges": {
"type": "object",
"enabled": false
}
}
},
"role_user": {
"_parent": {
"type": "role"
},
"properties": {
"name": {
"type": "string",
"analyzer": "lowercase_keyword"
},
"backend": {
"type": "string",
"analyzer": "lowercase_keyword"
}
}
},
"role_group": {
"_parent": {
"type": "role"
},
"properties": {
"name": {
"type": "string",
"analyzer": "lowercase_keyword"
},
"backend": {
"type": "string",
"analyzer": "lowercase_keyword"
}
}
}
}
}
Note:
The
backend
property is required for flawless integration with the configuration UI. If you are not using the UI, you can omit it safely. If used, it should hold the name of the backend the user or group originates from.
A simple example on how to create or update a role:
curl -XPOST localhost:9200/.elasticarmor/role/kibana-user -d @examples/kibana-user.json
And a basic example on how to assign a user to this role:
curl -XPOST localhost:9200/.elasticarmor/role_user?parent=kibana-user -d '{"name": "kibana"}'
For more information on how to manage documents please take a look at the documentation.