Skip to content

Tighten API key behaviour with DLS and incompatible license#78378

Merged
ywangd merged 13 commits into
elastic:masterfrom
ywangd:error-on-dls-and-incompatible-license
Oct 12, 2021
Merged

Tighten API key behaviour with DLS and incompatible license#78378
ywangd merged 13 commits into
elastic:masterfrom
ywangd:error-on-dls-and-incompatible-license

Conversation

@ywangd

@ywangd ywangd commented Sep 28, 2021

Copy link
Copy Markdown
Member

When the cluster license is incompatible with DLS and FLS, instead of
failing open, API keys now fail closed by throwing an error if any of
the target indices has DLS/FLS protection.

When the cluster license is incompatible with DLS and FLS, instead of
failing open, API keys now fail closed by throwing an error if any of
the target indices has DLS/FLS protection.
@ywangd ywangd added >enhancement :Security/Authorization Roles, Privileges, DLS/FLS, RBAC/ABAC v8.0.0 v7.16.0 labels Sep 28, 2021
@elasticmachine elasticmachine added the Team:Security Meta label for security team label Sep 28, 2021
@elasticmachine

Copy link
Copy Markdown
Collaborator

Pinging @elastic/es-security (Team:Security)

@bytebilly

Copy link
Copy Markdown
Contributor

@ywangd thanks for creating this.
Is the check performed on both the creator and api key descriptors?

@ywangd

ywangd commented Sep 28, 2021

Copy link
Copy Markdown
Member Author

Is the check performed on both the creator and api key descriptors?

Yes as long as the index has DLS/FLS protection regardless where the protection comes from (key roles or creator roles). The updated test covers the both scenarios.

@ywangd ywangd added >bug and removed >enhancement labels Sep 29, 2021
@davishmcclurg

Copy link
Copy Markdown

@ywangd what's the behavior for api keys that have both dls and non-dls index privileges? For example:

{
  "name": "my-api-key",
  "role_descriptors": {
    "my-role": {
      "indices": [
        {
          "names": ["someindex-1"],
          "privileges": ["read"]
        },
        {
          "names": ["someindex-*"],
          "privileges": ["read"],
          "query": { ... }
        }
      ]
    }
  }
}

Will the someindex-1 privileges still be applied if dls is no longer supported?

@ywangd

ywangd commented Oct 1, 2021

Copy link
Copy Markdown
Member Author

After some more thinking, I decided to add a new interceptor instead of relying on existing interceptors. The purpose of existing interceptors is to prevent certain misuse of DLS/FLS (e.g. update with DLS/FLS, caching etc.). So they don't cover the cases where misuse is not applicable. For example, the Get API is not covered and hence previous approach of handling incompatible license does not work correctly for Get API, i.e. you can still GET index/_doc/1 when the index has DLS/FLS.

The new interceptor should cover all cases. I didn't add new tests for the new changes because I'd like to agree on the approach first. Thanks!

@ywangd

ywangd commented Oct 1, 2021

Copy link
Copy Markdown
Member Author

Will the someindex-1 privileges still be applied if dls is no longer supported?

Yes. You will still be able to search someindex-1. The index privileges are union of all applicable groups. In your case, someindex-1 is covered by both itself and someindex-*. Since the final privilege is an union, it takes the more permissive one which does not have any DLS/FLS. So you can search someindex-1 before or after license downgrade.

"Checking for whether the request touches any indices that have DLS or FLS configured");
final IndicesAccessControl indicesAccessControl = threadContext.getTransient(INDICES_PERMISSIONS_KEY);
if (indicesAccessControl != null && indicesAccessControl.hasFieldOrDocumentLevelSecurity()) {
final ElasticsearchSecurityException licenseException =

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The actual check for DLS/FLS is guarded by several conditions for performance because it can be expensive to iterate through a large list of indices on every request. The assumption here is that a Role with DLS/FLS while license is incompatible should be an exceptional case. Therefore, most normal usages will return quickly.

@ywangd

ywangd commented Oct 1, 2021

Copy link
Copy Markdown
Member Author

@elasticmachine update branch

@ywangd

ywangd commented Oct 1, 2021

Copy link
Copy Markdown
Member Author

@elasticmachine run elasticsearch-ci/part-1-fips

Comment on lines +76 to +78
public boolean hasFieldOrDocumentLevelSecurity() {
return indices.hasFieldOrDocumentLevelSecurity();
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the PR gets merged, this new method here can be used in IndicesPermission#authorize to avoid the loop for computing DLS and FLS controls when the Roles does not have it.

@davishmcclurg

Copy link
Copy Markdown

Will the someindex-1 privileges still be applied if dls is no longer supported?

Yes. You will still be able to search someindex-1. The index privileges are union of all applicable groups. In your case, someindex-1 is covered by both itself and someindex-*. Since the final privilege is an union, it takes the more permissive one which does not have any DLS/FLS. So you can search someindex-1 before or after license downgrade.

Great—thanks @ywangd!

import static org.elasticsearch.xpack.core.security.authz.AuthorizationServiceField.AUTHORIZATION_INFO_KEY;
import static org.elasticsearch.xpack.core.security.authz.AuthorizationServiceField.INDICES_PERMISSIONS_KEY;

public class LicenseComplianceRequestInterceptor implements RequestInterceptor {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder whether this should have a more specific name.
Since it's only installed if DLS/FLS is enabled, it's probably worth naming it to be explicitly about DLS/FLS.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I renamed it to DlsFlsLicenseComplianceRequestInterceptor.
Btw, it wasn't more specifically named because I noticed BulkShardRequestInterceptor is about DLS/FLS and only has a generic name. But on hindsight, I don't think it is a good reference.

@albertzaharovits albertzaharovits left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@ywangd ywangd merged commit 42a5e56 into elastic:master Oct 12, 2021
@elasticsearchmachine

Copy link
Copy Markdown
Collaborator

💔 Backport failed

Status Branch Result
7.x Commit could not be cherrypicked due to conflicts

You can use sqren/backport to manually backport by running backport --upstream elastic/elasticsearch --pr 78378

ywangd added a commit to ywangd/elasticsearch that referenced this pull request Oct 12, 2021
…78378)

When the cluster license is incompatible with DLS and FLS, instead of
failing open, API keys now fail closed by throwing an error if any of
the target indices has DLS/FLS protection.
elasticsearchmachine pushed a commit that referenced this pull request Oct 13, 2021
…79021)

* Tighten API key behaviour with DLS and incompatible license (#78378)

When the cluster license is incompatible with DLS and FLS, instead of
failing open, API keys now fail closed by throwing an error if any of
the target indices has DLS/FLS protection.

* Fix for 7.x quirks

* more quirks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

>bug :Security/Authorization Roles, Privileges, DLS/FLS, RBAC/ABAC Team:Security Meta label for security team v7.16.0 v8.0.0-beta1

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants