You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kyuubi.apache.org by ch...@apache.org on 2026/09/04 09:04:45 UTC
(kyuubi) branch master updated: [KYUUBI #7671][AUTHZ] Cover all injected authz rules in the excludedRules check
This is an automated email from the ASF dual-hosted git repository.
pan3793 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/kyuubi.git
The following commit(s) were added to refs/heads/master by this push:
new 330a6426d8 [KYUUBI #7671][AUTHZ] Cover all injected authz rules in the excludedRules check
330a6426d8 is described below
commit 330a6426d8126da8721bd288e7b1257193204149
Author: Aleksandr Efimov <dz...@gmail.com>
AuthorDate: Fri Sep 4 17:04:35 2026 +0800
[KYUUBI #7671][AUTHZ] Cover all injected authz rules in the excludedRules check
### Why are the changes needed?
Closes #7671, the follow-up wForget asked for while reviewing #7637.
`AuthzConfigurationChecker` matches `org.apache.kyuubi.plugin.spark.authz.ranger` in the effective `spark.sql.optimizer.excludedRules`, which was the whole extension when the check was written. Most rules live under `org.apache.kyuubi.plugin.spark.authz.rule` now, so a rule added there is outside the denylist. This matches the extension's own package instead.
It is future-proofing rather than a fix for a live bypass, and worth saying why. `spark.sql.optimizer.excludedRules` filters optimizer batches only and Spark has no analyzer counterpart, so the resolution rules that apply masking and row filtering cannot be excluded at all. Of the four optimizer rules `RangerSparkExtension` injects, `RuleAuthorization` is in `…authz.ranger` and already covered; the other three — `RuleEliminateMarker`, `RuleEliminatePermanentViewMarker`, `RuleEliminate [...]
The change does reject configurations that are accepted today, which is why it is separate from #7637 rather than part of it.
### How was this patch tested?
A new case in `AuthzConfigurationCheckerSuite` covers the three `…authz.rule` rules by their `ruleName`, through both paths the checker guards: the value in effect, and the `SET` syntax.
30 tests green across `AuthzConfigurationCheckerSuite`, `DataMaskingForInMemoryParquetSuite` and the row filtering suite. With the constant reverted to the ranger package the new case fails, so it tests the change rather than the code around it.
### Was this patch authored or co-authored using generative AI tooling?
Assisted-by: Claude Opus 5
Closes #7672 from alexandrefimov/kyuubi-authz-excluded-rules-prefix.
Closes #7671
2df8dede5 [Aleksandr Efimov] [KYUUBI #7671][AUTHZ] Cover all injected authz rules in the excludedRules check
Authored-by: Aleksandr Efimov <dz...@gmail.com>
Signed-off-by: Cheng Pan <ch...@apache.org>
---
.../rule/config/AuthzConfigurationChecker.scala | 10 +++++---
.../rule/AuthzConfigurationCheckerSuite.scala | 28 ++++++++++++++++++++++
2 files changed, 35 insertions(+), 3 deletions(-)
diff --git a/extensions/spark/kyuubi-spark-authz/src/main/scala/org/apache/kyuubi/plugin/spark/authz/rule/config/AuthzConfigurationChecker.scala b/extensions/spark/kyuubi-spark-authz/src/main/scala/org/apache/kyuubi/plugin/spark/authz/rule/config/AuthzConfigurationChecker.scala
index e2c7cfb52b..c4d95195f2 100644
--- a/extensions/spark/kyuubi-spark-authz/src/main/scala/org/apache/kyuubi/plugin/spark/authz/rule/config/AuthzConfigurationChecker.scala
+++ b/extensions/spark/kyuubi-spark-authz/src/main/scala/org/apache/kyuubi/plugin/spark/authz/rule/config/AuthzConfigurationChecker.scala
@@ -32,7 +32,11 @@ case class AuthzConfigurationChecker(spark: SparkSession) extends (LogicalPlan =
final val RESTRICT_LIST_KEY = "spark.kyuubi.conf.restricted.list"
final val EXCLUDED_RULES_KEY = "spark.sql.optimizer.excludedRules"
- final private val AUTHZ_RANGER_RULE_PACKAGE = "org.apache.kyuubi.plugin.spark.authz.ranger"
+ // Every rule the extension injects lives under this package, not only the ranger ones:
+ // the marker-eliminating rules sit in org.apache.kyuubi.plugin.spark.authz.rule, and new
+ // rules land there too. Excluding one of those breaks the query at planning today rather
+ // than lifting a check, but the denylist should not depend on that staying true.
+ final private val AUTHZ_RULE_PACKAGE = "org.apache.kyuubi.plugin.spark.authz"
private val restrictedConfList: Set[String] =
Set(
@@ -48,13 +52,13 @@ case class AuthzConfigurationChecker(spark: SparkSession) extends (LogicalPlan =
// case below never sees them. Check the value that is actually in effect on every
// plan instead - check rules are not affected by spark.sql.optimizer.excludedRules,
// which only filters optimizer batches, so this check cannot be turned off the same way.
- if (spark.conf.getOption(EXCLUDED_RULES_KEY).exists(_.contains(AUTHZ_RANGER_RULE_PACKAGE))) {
+ if (spark.conf.getOption(EXCLUDED_RULES_KEY).exists(_.contains(AUTHZ_RULE_PACKAGE))) {
throw new AccessControlException("Excluding Authz security rules is not allowed")
}
plan match {
case SetCommand(Some((
EXCLUDED_RULES_KEY,
- Some(v)))) if v.contains(AUTHZ_RANGER_RULE_PACKAGE) =>
+ Some(v)))) if v.contains(AUTHZ_RULE_PACKAGE) =>
throw new AccessControlException("Excluding Authz security rules is not allowed")
case SetCommand(Some((k, Some(_)))) if restrictedConfList.contains(k) =>
throw new AccessControlException(s"Modifying config $k is not allowed")
diff --git a/extensions/spark/kyuubi-spark-authz/src/test/scala/org/apache/kyuubi/plugin/spark/authz/rule/AuthzConfigurationCheckerSuite.scala b/extensions/spark/kyuubi-spark-authz/src/test/scala/org/apache/kyuubi/plugin/spark/authz/rule/AuthzConfigurationCheckerSuite.scala
index 3b764c0e3d..c0b68cae86 100644
--- a/extensions/spark/kyuubi-spark-authz/src/test/scala/org/apache/kyuubi/plugin/spark/authz/rule/AuthzConfigurationCheckerSuite.scala
+++ b/extensions/spark/kyuubi-spark-authz/src/test/scala/org/apache/kyuubi/plugin/spark/authz/rule/AuthzConfigurationCheckerSuite.scala
@@ -84,6 +84,34 @@ class AuthzConfigurationCheckerSuite extends KyuubiFunSuite with SparkSessionPro
}
}
+ test("check every authz rule the extension injects, not only the ranger ones") {
+ val extension = AuthzConfigurationChecker(spark)
+ val plan = sql("select 1").queryExecution.analyzed
+
+ // the marker-eliminating rules live in org.apache.kyuubi.plugin.spark.authz.rule and are
+ // optimizer rules, so spark.sql.optimizer.excludedRules reaches them the same way it
+ // reaches RuleAuthorization
+ Seq(
+ RuleEliminateMarker.ruleName,
+ RuleEliminatePermanentViewMarker(spark).ruleName,
+ RuleEliminateTypeOf.ruleName).foreach { rule =>
+ spark.conf.set(extension.EXCLUDED_RULES_KEY, rule)
+ try {
+ intercept[AccessControlException](extension.apply(plan))
+ } finally {
+ spark.conf.unset(extension.EXCLUDED_RULES_KEY)
+ }
+ }
+
+ val setPlan = sql(s"set ${extension.EXCLUDED_RULES_KEY}=${RuleEliminateMarker.ruleName}")
+ .queryExecution.analyzed
+ try {
+ intercept[AccessControlException](extension.apply(setPlan))
+ } finally {
+ spark.conf.unset(extension.EXCLUDED_RULES_KEY)
+ }
+ }
+
test("apply spark configuration restriction rules for RESET") {
sql("set spark.kyuubi.conf.restricted.list=spark.sql.abc,spark.sql.xyz")
val extension = AuthzConfigurationChecker(spark)