-
Notifications
You must be signed in to change notification settings - Fork 24.7k
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
Remove combo security and license helper from license state #55366
Conversation
Security features in the license state currently do a dynamic check on whether security is enabled. This is because the license level can change the default security enabled state. This commit splits out the check on security being enabled, so that the combo method of security enabled plus license allowed is no longer necessary.
Pinging @elastic/es-security (:Security/License) |
Note that I have intentionally not added new uses of the "copy license state" method. I think that method is making the code more convoluted, and not actually fully protecting from race conditions because several different services within a request may check the license state, yet that method only copies within a single method. We should instead completely rework how the license state is frozen within a request once #53909 is complete. |
In the abstract, that concerns me (subject to how long #53909 will take). This behaviour was added to solve real race conditions that affected users. However, I think in most (maybe all) cases here it's fine.
The only situation were need to worry about is moving between a license where security is enabled by default (Gold, Platinum, Enterprise) to one where it is not (Trial, Basic), so that the first condition occurs on the old license and the second condition checks the new license. If the security-enabled state doesn't change then there's no race condition between If you move from not-enabled to enabled (install a paid license), then this should be safe because the first condition fails, so the second check is never performed, so there is no issue. Moving from platinum/enterprise to trial should have no effect, because the set of features are identical. Moving from platinum/enterprise to basic could have an effect, because the second check would fail where it would have passed on the first license, but since the basic license would have failed the first check, the overall result is as if the check was performed on a basic license. So the only case that could matter is moving from Gold to Trial. In that case we could have a situation where we detected security-enabled && feature-allowed even though that didn't hold true for either license independently. |
@@ -51,7 +51,7 @@ public void intercept(RequestInfo requestInfo, AuthorizationEngine authorization | |||
final XPackLicenseState frozenLicenseState = licenseState.copyCurrentLicenseState(); | |||
final AuditTrail auditTrail = auditTrailService.get(); | |||
if (frozenLicenseState.isSecurityEnabled()) { | |||
if (frozenLicenseState.isDocumentAndFieldLevelSecurityAllowed()) { | |||
if (frozenLicenseState.isSecurityEnabled() && frozenLicenseState.isDocumentAndFieldLevelSecurityAllowed()) { |
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.
The isSecurityEnabled
is covered in the enclosing if
@@ -47,7 +47,7 @@ public void intercept(RequestInfo requestInfo, AuthorizationEngine authorization | |||
final XPackLicenseState frozenLicenseState = licenseState.copyCurrentLicenseState(); | |||
final AuditTrail auditTrail = auditTrailService.get(); | |||
if (frozenLicenseState.isSecurityEnabled()) { | |||
if (frozenLicenseState.isDocumentAndFieldLevelSecurityAllowed()) { | |||
if (frozenLicenseState.isSecurityEnabled() && frozenLicenseState.isDocumentAndFieldLevelSecurityAllowed()) { |
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.
isSecurityEnabled
is covered in the enclosing if
@@ -165,7 +165,7 @@ public void roles(Set<String> roleNames, ActionListener<Role> roleActionListener | |||
rolesRetrievalResult.getMissingRoles())); | |||
} | |||
final Set<RoleDescriptor> effectiveDescriptors; | |||
if (licenseState.isDocumentAndFieldLevelSecurityAllowed()) { | |||
if (licenseState.isSecurityEnabled() && licenseState.isDocumentAndFieldLevelSecurityAllowed()) { |
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.
I think in this context we should ignore isSecurityEnabled()
It's a check to disable roles with DLS/FLS is the license does not permit it. I think it confuses the code to explicitly include enabled
in that check.
@@ -319,8 +319,9 @@ private void roleDescriptors(Set<String> roleNames, ActionListener<RolesRetrieva | |||
|
|||
private void loadRoleDescriptorsAsync(Set<String> roleNames, ActionListener<RolesRetrievalResult> listener) { | |||
final RolesRetrievalResult rolesResult = new RolesRetrievalResult(); | |||
boolean allAllowed = licenseState.isSecurityEnabled() && licenseState.isCustomRoleProvidersAllowed(); |
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.
As above, I'd skip the enabled check here. It's not clear why we'd prefer one behaviour over another if we ended up in deep in this method but security was disabled.
@@ -175,7 +175,7 @@ public static Path resolveFile(Environment env) { | |||
if (Files.exists(path)) { | |||
try { | |||
List<String> roleSegments = roleSegments(path); | |||
final boolean flsDlsLicensed = licenseState.isDocumentAndFieldLevelSecurityAllowed(); | |||
final boolean flsDlsLicensed = licenseState.isSecurityEnabled() && licenseState.isDocumentAndFieldLevelSecurityAllowed(); |
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.
As above, I'd skip enabled
@@ -188,7 +188,7 @@ public void onFailure(Exception e) { | |||
} | |||
|
|||
public void putRole(final PutRoleRequest request, final RoleDescriptor role, final ActionListener<Boolean> listener) { | |||
if (licenseState.isDocumentAndFieldLevelSecurityAllowed()) { | |||
if (licenseState.isSecurityEnabled() && licenseState.isDocumentAndFieldLevelSecurityAllowed()) { |
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.
As above.
@@ -369,7 +369,7 @@ static RoleDescriptor transformRole(String id, BytesReference sourceBytes, Logge | |||
// we pass true as last parameter because we do not want to reject permissions if the field permissions | |||
// are given in 2.x syntax | |||
RoleDescriptor roleDescriptor = RoleDescriptor.parse(name, sourceBytes, true, XContentType.JSON); | |||
if (licenseState.isDocumentAndFieldLevelSecurityAllowed()) { | |||
if (licenseState.isSecurityEnabled() && licenseState.isDocumentAndFieldLevelSecurityAllowed()) { |
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.
As above.
Thanks for the thorough review @tvernum! |
…55366) Security features in the license state currently do a dynamic check on whether security is enabled. This is because the license level can change the default security enabled state. This commit splits out the check on security being enabled, so that the combo method of security enabled plus license allowed is no longer necessary.
…55417) Security features in the license state currently do a dynamic check on whether security is enabled. This is because the license level can change the default security enabled state. This commit splits out the check on security being enabled, so that the combo method of security enabled plus license allowed is no longer necessary.
Security features in the license state currently do a dynamic check on
whether security is enabled. This is because the license level can
change the default security enabled state. This commit splits out the
check on security being enabled, so that the combo method of security
enabled plus license allowed is no longer necessary.