Skip to content

Commit 43ed544

Browse files
WIP bypass local permissions check for esql in CPS
1 parent 3979d74 commit 43ed544

File tree

6 files changed

+70
-10
lines changed

6 files changed

+70
-10
lines changed

x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/Security.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,7 @@
322322
import org.elasticsearch.xpack.security.authc.support.mapper.ProjectStateRoleMapper;
323323
import org.elasticsearch.xpack.security.authz.AuthorizationDenialMessages;
324324
import org.elasticsearch.xpack.security.authz.AuthorizationService;
325+
import org.elasticsearch.xpack.security.authz.CustomActionAuthorizationStep;
325326
import org.elasticsearch.xpack.security.authz.DlsFlsRequestCacheDifferentiator;
326327
import org.elasticsearch.xpack.security.authz.FileRoleValidator;
327328
import org.elasticsearch.xpack.security.authz.ReservedRoleNameChecker;
@@ -643,6 +644,7 @@ public class Security extends Plugin
643644
private final SetOnce<RemoteClusterSecurityExtension.Provider> remoteClusterSecurityExtensionProvider = new SetOnce<>();
644645
private final SetOnce<RemoteClusterSecurityExtension> remoteClusterSecurityExtension = new SetOnce<>();
645646
private final SetOnce<RemoteClusterAuthenticationService> remoteClusterAuthenticationService = new SetOnce<>();
647+
private final SetOnce<CustomActionAuthorizationStep.Factory> esqlAuthorizationStep = new SetOnce<>();
646648

647649
private final SetOnce<SecurityMigrations.Manager> migrationManager = new SetOnce<>();
648650
private final SetOnce<List<Closeable>> closableComponents = new SetOnce<>();
@@ -1143,6 +1145,9 @@ Collection<Object> createComponents(
11431145
if (authorizationDenialMessages.get() == null) {
11441146
authorizationDenialMessages.set(new AuthorizationDenialMessages.Default());
11451147
}
1148+
if (esqlAuthorizationStep.get() == null) {
1149+
esqlAuthorizationStep.set(new CustomActionAuthorizationStep.Factory.Default());
1150+
}
11461151
final AuthorizationService authzService = new AuthorizationService(
11471152
settings,
11481153
allRolesStore,
@@ -1160,7 +1165,8 @@ Collection<Object> createComponents(
11601165
restrictedIndices,
11611166
authorizationDenialMessages.get(),
11621167
linkedProjectConfigService,
1163-
projectResolver
1168+
projectResolver,
1169+
esqlAuthorizationStep.get().create(settings, linkedProjectConfigService)
11641170
);
11651171

11661172
components.add(nativeRolesStore); // used by roles actions
@@ -2524,6 +2530,7 @@ public void loadExtensions(ExtensionLoader loader) {
25242530
RemoteClusterSecurityExtension.Provider.class,
25252531
CrossClusterAccessSecurityExtension.Provider::new
25262532
);
2533+
loadSingletonExtensionAndSetOnce(loader, esqlAuthorizationStep, CustomActionAuthorizationStep.Factory.class);
25272534
}
25282535

25292536
private <T> void loadSingletonExtensionAndSetOnce(ExtensionLoader loader, SetOnce<T> setOnce, Class<T> clazz) {

x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/AuthorizationService.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,8 @@ public AuthorizationService(
166166
RestrictedIndices restrictedIndices,
167167
AuthorizationDenialMessages authorizationDenialMessages,
168168
LinkedProjectConfigService linkedProjectConfigService,
169-
ProjectResolver projectResolver
169+
ProjectResolver projectResolver,
170+
CustomActionAuthorizationStep esqlAuthorizationStep
170171
) {
171172
this.clusterService = clusterService;
172173
this.auditTrailService = auditTrailService;
@@ -182,7 +183,8 @@ public AuthorizationService(
182183
settings,
183184
rolesStore,
184185
fieldPermissionsCache,
185-
new LoadAuthorizedIndicesTimeChecker.Factory(logger, settings, clusterService.getClusterSettings())
186+
new LoadAuthorizedIndicesTimeChecker.Factory(logger, settings, clusterService.getClusterSettings()),
187+
esqlAuthorizationStep
186188
);
187189
this.authorizationEngine = authorizationEngine == null ? this.rbacEngine : authorizationEngine;
188190
this.requestInterceptors = requestInterceptors;
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0; you may not use this file except in compliance with the Elastic License
5+
* 2.0.
6+
*/
7+
8+
package org.elasticsearch.xpack.security.authz;
9+
10+
import org.elasticsearch.common.settings.Settings;
11+
import org.elasticsearch.transport.LinkedProjectConfigService;
12+
import org.elasticsearch.xpack.core.security.authz.AuthorizationEngine;
13+
14+
public interface CustomActionAuthorizationStep {
15+
boolean authorize(AuthorizationEngine.RequestInfo requestInfo);
16+
17+
class Default implements CustomActionAuthorizationStep {
18+
@Override
19+
public boolean authorize(AuthorizationEngine.RequestInfo requestInfo) {
20+
return false;
21+
}
22+
}
23+
24+
interface Factory {
25+
CustomActionAuthorizationStep create(Settings settings, LinkedProjectConfigService linkedProjectConfigService);
26+
27+
class Default implements Factory {
28+
@Override
29+
public CustomActionAuthorizationStep create(Settings settings, LinkedProjectConfigService linkedProjectConfigService) {
30+
return new CustomActionAuthorizationStep.Default();
31+
}
32+
}
33+
}
34+
}

x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/RBACEngine.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,17 +153,20 @@ public class RBACEngine implements AuthorizationEngine {
153153
private final CompositeRolesStore rolesStore;
154154
private final FieldPermissionsCache fieldPermissionsCache;
155155
private final LoadAuthorizedIndicesTimeChecker.Factory authzIndicesTimerFactory;
156+
private final CustomActionAuthorizationStep esqlStep;
156157

157158
public RBACEngine(
158159
Settings settings,
159160
CompositeRolesStore rolesStore,
160161
FieldPermissionsCache fieldPermissionsCache,
161-
LoadAuthorizedIndicesTimeChecker.Factory authzIndicesTimerFactory
162+
LoadAuthorizedIndicesTimeChecker.Factory authzIndicesTimerFactory,
163+
CustomActionAuthorizationStep esqlStep
162164
) {
163165
this.settings = settings;
164166
this.rolesStore = rolesStore;
165167
this.fieldPermissionsCache = fieldPermissionsCache;
166168
this.authzIndicesTimerFactory = authzIndicesTimerFactory;
169+
this.esqlStep = esqlStep;
167170
}
168171

169172
@Override
@@ -334,6 +337,9 @@ public SubscribableListener<IndexAuthorizationResult> authorizeIndexAction(
334337
} catch (Exception e) {
335338
return SubscribableListener.newFailed(e);
336339
}
340+
if (esqlStep.authorize(requestInfo)) {
341+
return SubscribableListener.newSucceeded(IndexAuthorizationResult.EMPTY);
342+
}
337343
if (TransportActionProxy.isProxyAction(action) || shouldAuthorizeIndexActionNameOnly(action, request)) {
338344
// we've already validated that the request is a proxy request so we can skip that but we still
339345
// need to validate that the action is allowed and then move on

x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/AuthorizationServiceTests.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,8 @@ public void setup() {
341341
RESTRICTED_INDICES,
342342
new AuthorizationDenialMessages.Default(),
343343
linkedProjectConfigService,
344-
projectResolver
344+
projectResolver,
345+
new CustomActionAuthorizationStep.Default()
345346
);
346347
}
347348

@@ -1775,7 +1776,8 @@ public void testDenialForAnonymousUser() {
17751776
RESTRICTED_INDICES,
17761777
new AuthorizationDenialMessages.Default(),
17771778
linkedProjectConfigService,
1778-
projectResolver
1779+
projectResolver,
1780+
new CustomActionAuthorizationStep.Default()
17791781
);
17801782

17811783
RoleDescriptor role = new RoleDescriptor(
@@ -1826,7 +1828,8 @@ public void testDenialForAnonymousUserAuthorizationExceptionDisabled() {
18261828
RESTRICTED_INDICES,
18271829
new AuthorizationDenialMessages.Default(),
18281830
linkedProjectConfigService,
1829-
projectResolver
1831+
projectResolver,
1832+
new CustomActionAuthorizationStep.Default()
18301833
);
18311834

18321835
RoleDescriptor role = new RoleDescriptor(
@@ -3365,7 +3368,8 @@ public void testAuthorizationEngineSelectionForCheckPrivileges() throws Exceptio
33653368
RESTRICTED_INDICES,
33663369
new AuthorizationDenialMessages.Default(),
33673370
linkedProjectConfigService,
3368-
projectResolver
3371+
projectResolver,
3372+
new CustomActionAuthorizationStep.Default()
33693373
);
33703374

33713375
Subject subject = new Subject(new User("test", "a role"), mock(RealmRef.class));
@@ -3522,7 +3526,8 @@ public void getUserPrivileges(AuthorizationInfo authorizationInfo, ActionListene
35223526
RESTRICTED_INDICES,
35233527
new AuthorizationDenialMessages.Default(),
35243528
linkedProjectConfigService,
3525-
projectResolver
3529+
projectResolver,
3530+
new CustomActionAuthorizationStep.Default()
35263531
);
35273532
Authentication authentication;
35283533
try (StoredContext ignore = threadContext.stashContext()) {

x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/RBACEngineTests.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,13 @@ public void createEngine() {
172172
final LoadAuthorizedIndicesTimeChecker.Factory timerFactory = mock(LoadAuthorizedIndicesTimeChecker.Factory.class);
173173
when(timerFactory.newTimer(any())).thenReturn(LoadAuthorizedIndicesTimeChecker.NO_OP_CONSUMER);
174174
rolesStore = mock(CompositeRolesStore.class);
175-
engine = new RBACEngine(Settings.EMPTY, rolesStore, new FieldPermissionsCache(Settings.EMPTY), timerFactory);
175+
engine = new RBACEngine(
176+
Settings.EMPTY,
177+
rolesStore,
178+
new FieldPermissionsCache(Settings.EMPTY),
179+
timerFactory,
180+
new CustomActionAuthorizationStep.Default()
181+
);
176182
}
177183

178184
public void testResolveAuthorizationInfoForEmptyRolesWithAuthentication() {

0 commit comments

Comments
 (0)