<commit_before>[role="xpack"]
[[custom-roles-authorization]]
=== Customizing roles and authorization

If you need to retrieve user roles from a system not supported out-of-the-box
or if the authorization system that is provided by the {es} {security-features}
does not meet your needs, a SPI loaded security extension can be implemented to
customize role retrieval and/or the authorization system. The SPI loaded
security extension is part of an ordinary elasticsearch plugin.

[[implementing-custom-roles-provider]]
==== Implementing a custom roles provider

To create a custom roles provider:

. Implement the interface `BiConsumer<Set<String>, ActionListener<Set<RoleDescriptor>>>`.
  That is to say, the implementation consists of one method that takes a set of strings,
  which are the role names to resolve, and an ActionListener, on which the set of resolved
  role descriptors are passed on as the response.
. The custom roles provider implementation must take special care to not block on any I/O
  operations.  It is the responsibility of the implementation to ensure asynchronous behavior
  and non-blocking calls, which is made easier by the fact that the `ActionListener` is
  provided on which to send the response when the roles have been resolved and the response
  is ready.

To package your custom roles provider as a plugin:

. Implement an extension class for your roles provider that implements
  `org.elasticsearch.xpack.core.security.SecurityExtension`. There you need to
  override one or more of the following methods:
+
[source,java]
----------------------------------------------------
@Override
public List<BiConsumer<Set<String>, ActionListener<Set<RoleDescriptor>>>>
getRolesProviders(Settings settings, ResourceWatcherService resourceWatcherService) {
    ...
}
----------------------------------------------------
+
The `getRolesProviders` method is used to provide a list of custom roles providers that
will be used to resolve role names, if the role names could not be resolved by the reserved
roles or native roles stores.   The list should be returned in the order that the custom role
providers should be invoked to resolve roles.  For example, if `getRolesProviders` returns two
instances of roles providers, and both of them are able to resolve role `A`, then the resolved
role descriptor that will be used for role `A` will be the one resolved by the first roles
provider in the list.

[[implementing-authorization-engine]]
==== Implementing an authorization engine

To create an authorization engine, you need to:

. Implement the `org.elasticsearch.xpack.core.security.authz.AuthorizationEngine`
  interface in a class with the desired authorization behavior.
. Implement the `org.elasticsearch.xpack.core.security.authz.Authorization.AuthorizationInfo`
  interface in a class that contains the necessary information to authorize the request.

To package your authorization engine as a plugin:

. Implement an extension class for your authorization engine that extends
  `org.elasticsearch.xpack.core.security.SecurityExtension`. There you need to
  override the following method:
+
[source,java]
----------------------------------------------------
@Override
public AuthorizationEngine getAuthorizationEngine(Settings settings) {
    ...
}
----------------------------------------------------
+
The `getAuthorizationEngine` method is used to provide the authorization engine
implementation.

Sample code that illustrates the structure and implementation of a custom
authorization engine is provided in the
https://github.com/elastic/elasticsearch/tree/master/plugin/examples/security-example-authorization-engine[elasticsearch]
repository on GitHub. You can use this code as a starting point for creating your
own authorization engine.<commit_msg>Correct documentation link for authorization engine example (#40261)<commit_after>[role="xpack"]
[[custom-roles-authorization]]
=== Customizing roles and authorization

If you need to retrieve user roles from a system not supported out-of-the-box
or if the authorization system that is provided by the {es} {security-features}
does not meet your needs, a SPI loaded security extension can be implemented to
customize role retrieval and/or the authorization system. The SPI loaded
security extension is part of an ordinary elasticsearch plugin.

[[implementing-custom-roles-provider]]
==== Implementing a custom roles provider

To create a custom roles provider:

. Implement the interface `BiConsumer<Set<String>, ActionListener<Set<RoleDescriptor>>>`.
  That is to say, the implementation consists of one method that takes a set of strings,
  which are the role names to resolve, and an ActionListener, on which the set of resolved
  role descriptors are passed on as the response.
. The custom roles provider implementation must take special care to not block on any I/O
  operations.  It is the responsibility of the implementation to ensure asynchronous behavior
  and non-blocking calls, which is made easier by the fact that the `ActionListener` is
  provided on which to send the response when the roles have been resolved and the response
  is ready.

To package your custom roles provider as a plugin:

. Implement an extension class for your roles provider that implements
  `org.elasticsearch.xpack.core.security.SecurityExtension`. There you need to
  override one or more of the following methods:
+
[source,java]
----------------------------------------------------
@Override
public List<BiConsumer<Set<String>, ActionListener<Set<RoleDescriptor>>>>
getRolesProviders(Settings settings, ResourceWatcherService resourceWatcherService) {
    ...
}
----------------------------------------------------
+
The `getRolesProviders` method is used to provide a list of custom roles providers that
will be used to resolve role names, if the role names could not be resolved by the reserved
roles or native roles stores.   The list should be returned in the order that the custom role
providers should be invoked to resolve roles.  For example, if `getRolesProviders` returns two
instances of roles providers, and both of them are able to resolve role `A`, then the resolved
role descriptor that will be used for role `A` will be the one resolved by the first roles
provider in the list.

[[implementing-authorization-engine]]
==== Implementing an authorization engine

To create an authorization engine, you need to:

. Implement the `org.elasticsearch.xpack.core.security.authz.AuthorizationEngine`
  interface in a class with the desired authorization behavior.
. Implement the `org.elasticsearch.xpack.core.security.authz.Authorization.AuthorizationInfo`
  interface in a class that contains the necessary information to authorize the request.

To package your authorization engine as a plugin:

. Implement an extension class for your authorization engine that extends
  `org.elasticsearch.xpack.core.security.SecurityExtension`. There you need to
  override the following method:
+
[source,java]
----------------------------------------------------
@Override
public AuthorizationEngine getAuthorizationEngine(Settings settings) {
    ...
}
----------------------------------------------------
+
The `getAuthorizationEngine` method is used to provide the authorization engine
implementation.

Sample code that illustrates the structure and implementation of a custom
authorization engine is provided in the
https://github.com/elastic/elasticsearch/tree/master/plugins/examples/security-authorization-engine[elasticsearch]
repository on GitHub. You can use this code as a starting point for creating your
own authorization engine.
{'fraction_non_alphanumeric': 0.10618772941793393, 'fraction_numerical': 0.0006554798112218144, 'mean_word_length': 3.7414543194530765, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 21, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6440564', 'n_tokens_mistral': 1728, 'n_tokens_neox': 1714, 'n_words': 892}