pan3793 commented on code in PR #3838:
URL: https://github.com/apache/incubator-kyuubi/pull/3838#discussion_r1031774248


##########
docs/deployment/settings.md:
##########
@@ -497,6 +497,7 @@ kyuubi.session.idle.timeout|PT6H|session idle timeout, it 
will be closed when it
 kyuubi.session.local.dir.allow.list||The local dir list that are allowed to 
access by the kyuubi session application. User might set some parameters such 
as `spark.files` and it will upload some local files when launching the kyuubi 
engine, if the local dir allow list is defined, kyuubi will check whether the 
path to upload is in the allow list. Note that, if it is empty, there is no 
limitation for that and please use absolute path list.|seq|1.6.0
 kyuubi.session.name|<undefined>|A human readable name of session and we 
use empty string by default. This name will be recorded in event. Note that, we 
only apply this value from session conf.|string|1.4.0
 kyuubi.session.timeout|PT6H|(deprecated)session timeout, it will be closed 
when it's not accessed for this duration|duration|1.0.0
+kyuubi.session.user.verify.enabled|true|Whether to verify the integrity of 
session user name in Spark engine within Authz plugin.|boolean|1.7.0

Review Comment:
   How about
   ```
   kyuubi.session.user.sign.enabled
   // it could be used for other cases in the future
   kyuubi.session.sign.algorithm
   kyuubi.session.sign.public.key
   kyuubi.session.sign.private.key
   ...
   ```
   ?



##########
externals/kyuubi-spark-sql-engine/src/main/scala/org/apache/kyuubi/engine/spark/operation/SparkOperation.scala:
##########
@@ -73,11 +76,24 @@ abstract class SparkOperation(session: Session)
     spark.conf.getOption(KyuubiConf.OPERATION_SCHEDULER_POOL.key).orElse(
       session.sessionManager.getConf.get(KyuubiConf.OPERATION_SCHEDULER_POOL))
 
+  protected val isSessionUserVerifyEnabled: Boolean = 
spark.sparkContext.getConf.getBoolean(
+    s"spark.${SESSION_USER_VERIFY_ENABLED.key}",
+    SESSION_USER_VERIFY_ENABLED.defaultVal.get)
+
   protected def withLocalProperties[T](f: => T): T = {
     try {
       spark.sparkContext.setJobGroup(statementId, redactedStatement, 
forceCancel)
       spark.sparkContext.setLocalProperty(KYUUBI_SESSION_USER_KEY, 
session.user)
       spark.sparkContext.setLocalProperty(KYUUBI_STATEMENT_ID_KEY, statementId)
+
+      if (isSessionUserVerifyEnabled) {
+        val (publicKey, privateKey) = SignUtils.generateKeyPair
+        val signed = SignUtils.signWithECDSA(session.user, privateKey)
+        val publicKeyStr = 
Base64.getEncoder.encodeToString(publicKey.getEncoded)
+        spark.sparkContext.setLocalProperty(KYUUBI_SESSION_USER_PUBIC_KEY, 
publicKeyStr)
+        spark.sparkContext.setLocalProperty(KYUUBI_SESSION_USER_SIGN, signed)

Review Comment:
   seems you forget to clear the local properties



##########
kyuubi-common/src/main/scala/org/apache/kyuubi/config/KyuubiReservedKeys.scala:
##########
@@ -20,6 +20,8 @@ package org.apache.kyuubi.config
 object KyuubiReservedKeys {
   final val KYUUBI_CLIENT_IP_KEY = "kyuubi.client.ipAddress"
   final val KYUUBI_SESSION_USER_KEY = "kyuubi.session.user"
+  final val KYUUBI_SESSION_USER_SIGN = "kyuubi.session.user.sign"
+  final val KYUUBI_SESSION_USER_PUBIC_KEY = "kyuubi.session.user.public.key"

Review Comment:
   typo: PUBIC



##########
externals/kyuubi-spark-sql-engine/src/main/scala/org/apache/kyuubi/engine/spark/operation/ExecutePython.scala:
##########
@@ -70,10 +72,20 @@ class ExecutePython(
       worker.runCode(s"spark.sparkContext.setLocalProperty('$key', '$value')")
     }
     try {
+

Review Comment:
   nit: unnecessary new line



##########
extensions/spark/kyuubi-spark-authz/src/main/scala/org/apache/kyuubi/plugin/spark/authz/util/AuthZUtils.scala:
##########
@@ -74,6 +85,13 @@ private[authz] object AuthZUtils {
   def getAuthzUgi(spark: SparkContext): UserGroupInformation = {
     // kyuubi.session.user is only used by kyuubi
     val user = spark.getLocalProperty("kyuubi.session.user")
+    if (StringUtils.isNotBlank(user)) {
+      if (!verifyKyuubiSessionUser(spark, user)) {
+        throw new AccessControlException(

Review Comment:
   we can move the `throw new AccessControlException` into 
`verifyKyuubiSessionUser` to make the caller side clearer.



##########
docs/deployment/settings.md:
##########
@@ -497,6 +497,7 @@ kyuubi.session.idle.timeout|PT6H|session idle timeout, it 
will be closed when it
 kyuubi.session.local.dir.allow.list||The local dir list that are allowed to 
access by the kyuubi session application. User might set some parameters such 
as `spark.files` and it will upload some local files when launching the kyuubi 
engine, if the local dir allow list is defined, kyuubi will check whether the 
path to upload is in the allow list. Note that, if it is empty, there is no 
limitation for that and please use absolute path list.|seq|1.6.0
 kyuubi.session.name|<undefined>|A human readable name of session and we 
use empty string by default. This name will be recorded in event. Note that, we 
only apply this value from session conf.|string|1.4.0
 kyuubi.session.timeout|PT6H|(deprecated)session timeout, it will be closed 
when it's not accessed for this duration|duration|1.0.0
+kyuubi.session.user.verify.enabled|true|Whether to verify the integrity of 
session user name in Spark engine within Authz plugin.|boolean|1.7.0

Review Comment:
   And it's not limited to authz mode, please make the description more 
generic, the authz use case could be referred to as an "example" 



##########
kyuubi-common/src/main/scala/org/apache/kyuubi/util/SignUtils.scala:
##########
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.kyuubi.util
+
+import java.nio.charset.StandardCharsets
+import java.security.{KeyPairGenerator, PrivateKey, PublicKey, SecureRandom, 
Signature}
+import java.security.spec.ECGenParameterSpec
+import java.util.Base64
+
+object SignUtils {
+
+  private lazy val ecKeyPairGenerator = {
+    val g = KeyPairGenerator.getInstance("EC")
+    g.initialize(new ECGenParameterSpec("secp256k1"), new SecureRandom())

Review Comment:
   tip, using `Random` w/ a random seed generates indeterminate results, it's 
secure and should be used for production, but makes the test not repeatable, 
better to allow setting the seed in UT.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to