Skip to content

Decouple ILM action execution from the user setting the policy #72856

@inqueue

Description

@inqueue

By design, index lifecycle management performs operations as the user who last updated the ILM policy. This behavior is documented. See the original PR.

This design is causing problems when the last user to apply ILM policies loses authorization to perform index operations performed by ILM.

    "index-000061" : {
      "index" : "index-000061",
      "managed" : true,
      "policy" : "indexpolicy",
      "lifecycle_date" : "2021-04-28T21:20:27.810Z",
      "lifecycle_date_millis" : 1619644827810,
      "age" : "4.73d",
      "phase" : "hot",
      "phase_time" : "2021-05-03T14:40:42.715Z",
      "phase_time_millis" : 1620052842715,
      "action" : "rollover",
      "action_time" : "2021-04-28T21:30:28.123Z",
      "action_time_millis" : 1619645428123,
      "step" : "ERROR",
      "step_time" : "2021-05-03T14:50:41.446Z",
      "step_time_millis" : 1620053441446,
      "failed_step" : "check-rollover-ready",
      "is_auto_retryable_error" : true,
      "failed_step_retry_count" : 335,
      "step_info" : {
        "type" : "security_exception",
        "reason" : "action [indices:admin/rollover] is unauthorized for API key id [B3BJM4gBw7Tb8aIbES1t] of user [[email protected]]",
        "stack_trace" : "ElasticsearchSecurityException[action [indices:admin/rollover] is unauthorized for API key id [B3BJM4gBw7Tb8aIbES1t] of user [[email protected]]]

A user can lose permissions for too many reasons to name here. If it happens and the user is associated with ILM policies, it can create failures in ILM that can be very difficult to recover from. If not noticed, an index failing rollover like in the _ilm/explain output above can create indices with very large shards and cluster imbalance.

associated ES server log
[instance-0008675309] policy [indexpolicy] for index [index-000061] failed on step [{"phase":"hot","action":"rollover","name":"check-rollover-ready"}]. Moving to ERROR step
org.elasticsearch.ElasticsearchSecurityException: action [indices:admin/rollover] is unauthorized for API key id [B3BJM4gBw7Tb8aIbES1t] of user [[email protected]]
	at org.elasticsearch.xpack.core.security.support.Exceptions.authorizationError(Exceptions.java:34) ~[x-pack-core-7.8.1.jar:7.8.1]
	at org.elasticsearch.xpack.security.authz.AuthorizationService.denialException(AuthorizationService.java:596) ~[x-pack-security-7.8.1.jar:7.8.1]
	at org.elasticsearch.xpack.security.authz.AuthorizationService.access$300(AuthorizationService.java:94) ~[x-pack-security-7.8.1.jar:7.8.1]
	at org.elasticsearch.xpack.security.authz.AuthorizationService$AuthorizationResultListener.handleFailure(AuthorizationService.java:647) [x-pack-security-7.8.1.jar:7.8.1]
	at org.elasticsearch.xpack.security.authz.AuthorizationService$AuthorizationResultListener.onResponse(AuthorizationService.java:633) [x-pack-security-7.8.1.jar:7.8.1]
	at org.elasticsearch.xpack.security.authz.AuthorizationService$AuthorizationResultListener.onResponse(AuthorizationService.java:603) [x-pack-security-7.8.1.jar:7.8.1]
	at org.elasticsearch.action.support.ContextPreservingActionListener.onResponse(ContextPreservingActionListener.java:43) [elasticsearch-7.8.1.jar:7.8.1]
	at org.elasticsearch.xpack.security.authz.RBACEngine.lambda$authorizeIndexAction$4(RBACEngine.java:319) [x-pack-security-7.8.1.jar:7.8.1]
	at org.elasticsearch.action.ActionListener$1.onResponse(ActionListener.java:63) [elasticsearch-7.8.1.jar:7.8.1]
	at org.elasticsearch.xpack.security.authz.RBACEngine.authorizeIndexActionName(RBACEngine.java:332) [x-pack-security-7.8.1.jar:7.8.1]
	at org.elasticsearch.xpack.security.authz.RBACEngine.authorizeIndexAction(RBACEngine.java:303) [x-pack-security-7.8.1.jar:7.8.1]
	at org.elasticsearch.xpack.security.authz.AuthorizationService.authorizeAction(AuthorizationService.java:269) [x-pack-security-7.8.1.jar:7.8.1]
	at org.elasticsearch.xpack.security.authz.AuthorizationService.maybeAuthorizeRunAs(AuthorizationService.java:234) [x-pack-security-7.8.1.jar:7.8.1]
	at org.elasticsearch.xpack.security.authz.AuthorizationService.lambda$authorize$1(AuthorizationService.java:199) [x-pack-security-7.8.1.jar:7.8.1]
	at org.elasticsearch.action.ActionListener$1.onResponse(ActionListener.java:63) [elasticsearch-7.8.1.jar:7.8.1]
	at org.elasticsearch.action.support.ContextPreservingActionListener.onResponse(ContextPreservingActionListener.java:43) [elasticsearch-7.8.1.jar:7.8.1]
	at org.elasticsearch.xpack.security.authz.RBACEngine.lambda$resolveAuthorizationInfo$1(RBACEngine.java:121) [x-pack-security-7.8.1.jar:7.8.1]
	at org.elasticsearch.action.ActionListener$1.onResponse(ActionListener.java:63) [elasticsearch-7.8.1.jar:7.8.1]
	at org.elasticsearch.xpack.security.authz.store.CompositeRolesStore.lambda$getRoles$7(CompositeRolesStore.java:234) [x-pack-security-7.8.1.jar:7.8.1]
	at org.elasticsearch.action.ActionListener$1.onResponse(ActionListener.java:63) [elasticsearch-7.8.1.jar:7.8.1]
	at org.elasticsearch.xpack.security.authz.store.CompositeRolesStore.buildAndCacheRoleFromDescriptors(CompositeRolesStore.java:265) [x-pack-security-7.8.1.jar:7.8.1]
	at org.elasticsearch.xpack.security.authz.store.CompositeRolesStore.lambda$getRoles$8(CompositeRolesStore.java:232) [x-pack-security-7.8.1.jar:7.8.1]
	at org.elasticsearch.action.ActionListener$1.onResponse(ActionListener.java:63) [elasticsearch-7.8.1.jar:7.8.1]
	at org.elasticsearch.xpack.security.authz.store.CompositeRolesStore.buildAndCacheRoleFromDescriptors(CompositeRolesStore.java:265) [x-pack-security-7.8.1.jar:7.8.1]
	at org.elasticsearch.xpack.security.authz.store.CompositeRolesStore.lambda$getRoles$9(CompositeRolesStore.java:231) [x-pack-security-7.8.1.jar:7.8.1]
	at org.elasticsearch.action.ActionListener$1.onResponse(ActionListener.java:63) [elasticsearch-7.8.1.jar:7.8.1]
	at org.elasticsearch.xpack.security.authc.ApiKeyService.getRoleForApiKey(ApiKeyService.java:373) [x-pack-security-7.8.1.jar:7.8.1]
	at org.elasticsearch.xpack.security.authz.store.CompositeRolesStore.getRoles(CompositeRolesStore.java:224) [x-pack-security-7.8.1.jar:7.8.1]
	at org.elasticsearch.xpack.security.authz.RBACEngine.getRoles(RBACEngine.java:127) [x-pack-security-7.8.1.jar:7.8.1]
	at org.elasticsearch.xpack.security.authz.RBACEngine.resolveAuthorizationInfo(RBACEngine.java:115) [x-pack-security-7.8.1.jar:7.8.1]
	at org.elasticsearch.xpack.security.authz.AuthorizationService.authorize(AuthorizationService.java:201) [x-pack-security-7.8.1.jar:7.8.1]
	at org.elasticsearch.xpack.security.action.filter.SecurityActionFilter.authorizeRequest(SecurityActionFilter.java:173) [x-pack-security-7.8.1.jar:7.8.1]
	at org.elasticsearch.xpack.security.action.filter.SecurityActionFilter.lambda$applyInternal$3(SecurityActionFilter.java:159) [x-pack-security-7.8.1.jar:7.8.1]
	at org.elasticsearch.action.ActionListener$1.onResponse(ActionListener.java:63) [elasticsearch-7.8.1.jar:7.8.1]
	at org.elasticsearch.xpack.security.authc.AuthenticationService$Authenticator.lambda$authenticateAsync$2(AuthenticationService.java:323) [x-pack-security-7.8.1.jar:7.8.1]
	at org.elasticsearch.xpack.security.authc.AuthenticationService$Authenticator.lambda$lookForExistingAuthentication$6(AuthenticationService.java:385) [x-pack-security-7.8.1.jar:7.8.1]
	at org.elasticsearch.xpack.security.authc.AuthenticationService$Authenticator.lookForExistingAuthentication(AuthenticationService.java:396) [x-pack-security-7.8.1.jar:7.8.1]
	at org.elasticsearch.xpack.security.authc.AuthenticationService$Authenticator.authenticateAsync(AuthenticationService.java:320) [x-pack-security-7.8.1.jar:7.8.1]
	at org.elasticsearch.xpack.security.authc.AuthenticationService$Authenticator.access$000(AuthenticationService.java:261) [x-pack-security-7.8.1.jar:7.8.1]
	at org.elasticsearch.xpack.security.authc.AuthenticationService.authenticate(AuthenticationService.java:156) [x-pack-security-7.8.1.jar:7.8.1]
	at org.elasticsearch.xpack.security.action.filter.SecurityActionFilter.applyInternal(SecurityActionFilter.java:156) [x-pack-security-7.8.1.jar:7.8.1]
	at org.elasticsearch.xpack.security.action.filter.SecurityActionFilter.apply(SecurityActionFilter.java:108) [x-pack-security-7.8.1.jar:7.8.1]
	at org.elasticsearch.action.support.TransportAction$RequestFilterChain.proceed(TransportAction.java:177) [elasticsearch-7.8.1.jar:7.8.1]
	at org.elasticsearch.action.support.TransportAction.execute(TransportAction.java:155) [elasticsearch-7.8.1.jar:7.8.1]
	at org.elasticsearch.action.support.TransportAction.execute(TransportAction.java:83) [elasticsearch-7.8.1.jar:7.8.1]
	at org.elasticsearch.client.node.NodeClient.executeLocally(NodeClient.java:83) [elasticsearch-7.8.1.jar:7.8.1]
	at org.elasticsearch.client.node.NodeClient.doExecute(NodeClient.java:72) [elasticsearch-7.8.1.jar:7.8.1]
	at org.elasticsearch.client.support.AbstractClient.execute(AbstractClient.java:399) [elasticsearch-7.8.1.jar:7.8.1]
	at org.elasticsearch.xpack.core.ClientHelper.executeWithHeadersAsync(ClientHelper.java:160) [x-pack-core-7.8.1.jar:7.8.1]
	at org.elasticsearch.xpack.ilm.LifecyclePolicySecurityClient.doExecute(LifecyclePolicySecurityClient.java:51) [x-pack-ilm-7.8.1.jar:7.8.1]
	at org.elasticsearch.client.support.AbstractClient.execute(AbstractClient.java:399) [elasticsearch-7.8.1.jar:7.8.1]
	at org.elasticsearch.client.support.AbstractClient$IndicesAdmin.execute(AbstractClient.java:1234) [elasticsearch-7.8.1.jar:7.8.1]
	at org.elasticsearch.client.support.AbstractClient$IndicesAdmin.rolloverIndex(AbstractClient.java:1736) [elasticsearch-7.8.1.jar:7.8.1]
	at org.elasticsearch.xpack.core.ilm.WaitForRolloverReadyStep.evaluateCondition(WaitForRolloverReadyStep.java:128) [x-pack-core-7.8.1.jar:7.8.1]
	at org.elasticsearch.xpack.ilm.IndexLifecycleRunner.runPeriodicStep(IndexLifecycleRunner.java:173) [x-pack-ilm-7.8.1.jar:7.8.1]
	at org.elasticsearch.xpack.ilm.IndexLifecycleService.triggerPolicies(IndexLifecycleService.java:329) [x-pack-ilm-7.8.1.jar:7.8.1]
	at org.elasticsearch.xpack.ilm.IndexLifecycleService.triggered(IndexLifecycleService.java:267) [x-pack-ilm-7.8.1.jar:7.8.1]
	at org.elasticsearch.xpack.core.scheduler.SchedulerEngine.notifyListeners(SchedulerEngine.java:183) [x-pack-core-7.8.1.jar:7.8.1]
	at org.elasticsearch.xpack.core.scheduler.SchedulerEngine$ActiveSchedule.run(SchedulerEngine.java:211) [x-pack-core-7.8.1.jar:7.8.1]
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) [?:?]
	at java.util.concurrent.FutureTask.run(FutureTask.java:264) [?:?]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304) [?:?]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130) [?:?]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630) [?:?]
	at java.lang.Thread.run(Thread.java:832) [?:?]

Please strongly consider decoupling ILM policy execution from the user setting the policy. Could ILM actions be executed as a built-in system user?

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions