Skip to content

fix msq compaction to apply security policies#18741

Merged
gianm merged 10 commits intoapache:masterfrom
clintropolis:fix-msq-compaction-policy-stuff
Nov 18, 2025
Merged

fix msq compaction to apply security policies#18741
gianm merged 10 commits intoapache:masterfrom
clintropolis:fix-msq-compaction-policy-stuff

Conversation

@clintropolis
Copy link
Copy Markdown
Member

Description

Fixes an issue with MSQ compaction tasks can fail if a policy enforcer is enabled, since compaction generates MSQ tasks directly instead of going through the broker, it would miss out on decorating the DataSource as a restricted datasource with the policy set.

To fix, MSQCompactionRunner now uses an escalator to create an auth result and uses the policy from that to decorate the query it generates.

To test, I hijacked CompactionSupervisorTest and switched it to use MSQ engine and set it up with an auth config and policy enforcer (with a newly added AllowAllWithPolicyAuthResource which is essentially allow-all but with NoRestrictionPolicy permitted)

@github-actions github-actions Bot added Area - Batch Ingestion Area - MSQ For multi stage queries - https://github.com/apache/druid/issues/12262 labels Nov 13, 2025
@clintropolis clintropolis force-pushed the fix-msq-compaction-policy-stuff branch from bc82725 to 675c565 Compare November 13, 2025 20:27
Copy link
Copy Markdown
Contributor

@kfaraz kfaraz left a comment

Choose a reason for hiding this comment

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

Left some minor suggestions.

}
}

@JsonTypeName(AUTH_TYPE)
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.

Why is a json type name needed for the module?

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.

it is not, this was an accidental copy and paste when i was setting it on the other classes


public class AllowAllWithPolicyAuthResource implements EmbeddedResource
{
private static final String AUTH_TYPE = "actually-allow-all";
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.

Nit: any specific reason for the prefix "actually"? 🙂 Should we use some other name like allow-all-with-policy?

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.

i named it this on discovering that allowAll does not actually allow everything if you have a policy enforcer configured because it does not set policies. I considered just fixing allowAll to be able to set the NoRestrictionPolicy, on the other hand there is probably limited scenario where you would have both allowAll and also a policy enforcer configured, and this has a somewhat ugly side-effect of setting a policy always (and so making a restricted datasource on the query) even if you don't have policy enforcement or policies of any sort, which seems a bit odd for out of the box behavior, so I did this instead.

Copy link
Copy Markdown
Contributor

@gianm gianm Nov 14, 2025

Choose a reason for hiding this comment

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

Part of the purpose of the enforcer mechanism is to allow people to verify that allowAll is not being used by accident. So, adding a no-restriction policy to allowAll wouldn't be a "fix", it would partially defeat the purpose of the enforcer. It's fine to have an option for tests though that does this.

Copy link
Copy Markdown
Member Author

@clintropolis clintropolis Nov 14, 2025

Choose a reason for hiding this comment

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

i changed things so that allowAll itself can have an optional policy defined, so deleted this stuff since is no longer necessary

import java.util.List;
import java.util.Map;

public class AllowAllWithPolicyAuthResource implements EmbeddedResource
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.

Please add a short javadoc.

Comment on lines +155 to +159
final MapBinder<String, Authenticator> authenticatorMapBinder = PolyBind.optionBinder(
binder,
Key.get(Authenticator.class)
);
authenticatorMapBinder.addBinding(AUTH_TYPE)
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.

Nit: can be chained.

Suggested change
final MapBinder<String, Authenticator> authenticatorMapBinder = PolyBind.optionBinder(
binder,
Key.get(Authenticator.class)
);
authenticatorMapBinder.addBinding(AUTH_TYPE)
PolyBind.optionBinder(binder, Key.get(Authenticator.class))
.addBinding(AUTH_TYPE)

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.

guilty, i just copied these from other auth modules 🙃

return msqControllerTasks;
}

private Query<?> maybeApplyPolicy(DataSchema dataSchema, Query<?> query)
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.

Nit: Please add a short javadoc too.

Suggested change
private Query<?> maybeApplyPolicy(DataSchema dataSchema, Query<?> query)
private Query<?> maybeApplyPolicyOnDatasource(DataSchema dataSchema, Query<?> query)

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.

i didn't think this was needed since Policy apply to datasources so it seemed redundant, but can rename if you feel like it isn't obvious

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.

this is changed now to just be getInputDataSource and is used by the 'build' query methods directly to create the DataSource instead of rewriting the query later

.addCommonProperty("druid.auth.authenticatorChain", "[\"test\"]")
.addCommonProperty("druid.auth.authenticator.test.type", "actually-allow-all")
.addCommonProperty("druid.auth.authorizers", "[\"test\"]")
.addCommonProperty("druid.auth.authorizer.test.type", "actually-allow-all")
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.

Instead of writing a new one, can't we use the allowAll authenticaator/authorizer policy itself alongwith enforcer.allowedPolicies config?

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.

see #18741 (comment), allowAll doesn't work if you have an enforcer defined because it does not set any policy on the auth result (and doing so would have some undesirable side-effects)

{
final UpdateResponse updateResponse = cluster.callApi().onLeaderOverlord(
o -> o.updateClusterCompactionConfig(new ClusterCompactionConfig(1.0, 100, null, true, null))
o -> o.updateClusterCompactionConfig(new ClusterCompactionConfig(1.0, 100, null, true, CompactionEngine.MSQ))
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.

Maybe keep both the test cases, native and MSQ.

@gianm gianm merged commit f5dde64 into apache:master Nov 18, 2025
103 of 104 checks passed
@clintropolis clintropolis deleted the fix-msq-compaction-policy-stuff branch November 18, 2025 00:24
gianm added a commit to gianm/druid that referenced this pull request Nov 18, 2025
PR apache#18741 flipped an AND to an OR, potentially causing policies
from non-table-read authorizations to apply to a resource. This patch
fixes the logic and also introduces a defensive check that only a
single policy is in play per resource.
gianm added a commit to gianm/druid that referenced this pull request Nov 18, 2025
PR apache#18741 flipped an AND to an OR, potentially causing policies
from non-table-read authorizations to apply to a resource. This patch
fixes the logic and also introduces a defensive check that only a
single policy is in play per resource.
clintropolis pushed a commit that referenced this pull request Nov 19, 2025
PR #18741 flipped an AND to an OR, potentially causing policies
from non-table-read authorizations to apply to a resource. This patch
fixes the logic and also introduces a defensive check that only a
single policy is in play per resource.
@kgyrtkirk kgyrtkirk added this to the 36.0.0 milestone Jan 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area - Batch Ingestion Area - Dependencies Area - Ingestion Area - MSQ For multi stage queries - https://github.com/apache/druid/issues/12262 Bug jacoco:skip

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants