-
Notifications
You must be signed in to change notification settings - Fork 164
[RORDEV-1639] Separate JWT authentication and authorization rules #1182
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
base: develop
Are you sure you want to change the base?
Conversation
|
|
||
| // Pseudo-authorization rule should be used exclusively as part of the JwtAuthRule, when there are is no groups logic defined. | ||
| // It preserves the kbn_auth rule behavior from before introducing separate authn and authz rules. | ||
| final class JwtPseudoAuthorizationRule(val settings: Settings) |
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 logic from JwtAuthRule is now extracted into 3 parts:
- the
JwtAuthenticationRule - the
JwtAuthorizationRule - and this
JwtPseudoAuthorizationRule
The JwtAuthRule until now handled the situation, when there was no groups rule defined in a very specific way. It was even more complicated than the RorKbnAuth rule, which we refactored recently.
When groups rule is not defined, then the "authorization" part checks, if the current, preferred group is eligible. When the preferred group is not defined, then it is simply accepted and passes.
But this "pseduo-authorization" is different in other ways too - it does not add available groups to BlockContext's user metadata.
So if we would want to change this behavior, it would change the output BlockContext after the rule matches. We can either:
- preserve this pseudo-authorization logic (the current implementation extracted 3 parts of logic from
JwtAuthRule, but did not change the behavior) - remove pseudo-authorization and change the behavior
But as I wrote - this "pseudo-authorization" is even more complex, than the one for RorKbnAuth was. It does not add groups to context and additionally it accepts the situation, when there are no groups in JWT token - something that was not allowed in RorKbnAuth.
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.
ok, let's think about it a little bit. I'd like to avoid the JwtPesudoAuthorizationRule. But first, let's analyse all the cases. I think we can find them in this code:
private def handleGroupsClaimSearchResult[B <: BlockContext : BlockContextUpdater](blockContext: B,
result: Option[ClaimSearchResult[UniqueList[Group]]]) = {
(result, settings.permittedGroups) match {
// 1. authorization rule - groups are defined, but no groups cannot be extracted from JWT, because of not configured groups claim (FORBIDDEN - correct in context of authorization rule)
case (None, Groups.Defined(_)) =>
Left(())
// 2. authentication rule - no groups definition in authentication rule; we don't have to look at groups from JWT (in this case, no groups claim name was configured, so we don't even know how to extract them) (ALLOWED - correct in context of authentication rule)
case (None, Groups.NotDefined) =>
Right(blockContext)
// 3. authorization rule - groups are defined; there is a configured groups claim name, but no groups are extracted (FORBIDDEN - correct in context of authorization rule)
case (Some(NotFound), Groups.Defined(_)) =>
Left(())
// 4. authorization rule - groups are not defined (we can assume it's allow all - "*"); there is a configured groups claim name, and groups are not extracted (should be FORBIDDEN - it looks it's bug. We had a similar use case in the context of the ror_kbn_auth, don't we?)
case (Some(NotFound), Groups.NotDefined) =>
Right(blockContext)
// 5. authorization rule - groups are defined; there is a configured groups claim name, and groups are extracted from JWT (FORBIDDEN/ALLOWED - result based on the groups logic)
case (Some(Found(groups)), Groups.Defined(groupsLogic)) =>
UniqueNonEmptyList.from(groups) match {
case Some(nonEmptyGroups) =>
groupsLogic.availableGroupsFrom(nonEmptyGroups) match {
case Some(matchedGroups) =>
checkIfCanContinueWithGroups(blockContext, UniqueList.from(matchedGroups))
.map(_.withUserMetadata(_.addAvailableGroups(matchedGroups)))
case None =>
Left(())
}
case None =>
Left(())
}
// 6. authorization rule - groups are not defined (we can assume it's allow all - "*"); there is a configured groups claim name, and groups are extracted from JWT (FORBIDDEN/ALLOWED - result based on current group eligibility)
case (Some(Found(groups)), Groups.NotDefined) =>
checkIfCanContinueWithGroups(blockContext, groups)
}
}
I've added comments.
Could you please compare each case with the current ror_kbn_auth... rules logic?
I see that 2. and 4. points are problematic. Do you agree?
If so, let's focus on them and compare with:
- current ror_kbn_auth... implementation
- old ror_kbn_auth... implementation
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.
Actually from my point of view, points 2 and 6 are most problematic, but let me summarize as I understand it:
The pseudo-authorization rule (the authorization part of old auth rule when no groups) is points 2,4,6 - all with Groups.NotDefined
- point 2.
- we did not have a similar case in ROR KBN rules, because we did not allow parsing token with missing groups
- in jwt_auth rule we allowed situation, where there was a token with missing groups claim
- it is now part of "pseudo-authorization" - because we don't want such behavior in "real-authorization" rule
- point 4.
- yes, exactly, that is the case similar to the one in the ROR KBN auth rule
- yes, we changed the behavior of the ROR KBN auth rule (and the new authz rule) to not allow it
- point 6.
- it does the pseudo - authorization when there are groups in JWT, but no groups rule
- but it is not equivalent to
allow all - "*"- it does not modify the user metadata, so the result is different - probably we can change that, but it is an incompatible change in behavior
So the changes in the jwt_auth rule will be (if we remove the "pseudo-authorization" and use only the newly created "real-authorization"):
- from point 2. - ROR will no longer accept JWT tokens without groups claim
- we did not have similar case in ROR KBN, because we did not allow tokens without groups claim, but for JWT it looks like a feature to me
- but it is similar to the point below, so I guess we can change that (with breaking change in behavior)
- from point 4. - ROR will no longer accept siaution with not found groups claims in token
- we fixed it in the same way for ROR KBN (with breaking change in behavior) so I guess we can do the same here
- from point 6. - the real pseudo-authorization
- we can use
allow all - "*" - bu the resulting context (user metadata) will be different that before - it will start to contain user groups (they were not added to context in old implementation)
- we can use
There are 14 failing tests when I switch from the pseudo to real authorization. Most of them fail, because before this change the result was ALLOWED, and now is FORBIDDEN, because of the breaking changes from those 3 points.
...cala/tech/beshu/ror/accesscontrol/factory/decoders/definitions/UsersDefinitionsDecoder.scala
Show resolved
Hide resolved
core/src/test/scala/tech/beshu/ror/unit/acl/factory/LocalUsersTest.scala
Outdated
Show resolved
Hide resolved
This comment was marked as spam.
This comment was marked as spam.
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.
let's rename the file to JwtAuthRulesDecoders
| extends RuleBaseDecoderWithoutAssociatedFields[JwtAuthRule] { | ||
| extends RuleBaseDecoderWithoutAssociatedFields[JwtAuthRule] with Logging { | ||
|
|
||
| override protected def decoder: Decoder[RuleDefinition[JwtAuthRule]] = { |
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.
Can we make JwtAuthRuleDecoder and RorKbnAuthRuleDecoder much more similar to each other (also consider changing the JwtAuthRuleDecoder if it would be better to achieve the goal)?
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.
Even more than that - I created a common decoder implementation for those 2 families of rules (trait JwtLikeRulesDecoders)
| import java.security.KeyPairGenerator | ||
| import java.util.Base64 | ||
|
|
||
| class JwtAuthorizationRuleSettingsTests |
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.
It looks like it should have similar tests to the RorKbnAuthorizationRuleSettingsTests suite. Shouldn't it?
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 reorganized the tests. Now the ROR KBN and JWT suites are very similar. In both those cases I created those suites by copying, adjusting and taking only those tests from auth-rule suite, that were applicable to authn/z rules. And the JWT-specific tests (like testing signatures, algorithms etc.) are now only in the authn suites, not duplicated for authz and auth suites.
| extends BaseRuleSettingsDecoderTest[JwtAuthenticationRule] | ||
| with MockFactory { | ||
|
|
||
| "A JwtAuthenticationRule" should { |
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 same here. It seems that, at least, a subset of the tests should be similar to the RorKbnAuthenticationRuleSettingsTests suite's tests. Can you verify it?
It would be nice to see the difference at first glance.
Maybe we could have a different section for settings in the defs (because I guess, there are many differences /in RorKbnAuth...Rule, the def schema is pretty strict and not so configurable)
| | | ||
| | - name: jwt1 | ||
| | group_ids_claim: groups | ||
| | group_names_claim: group_names |
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.
Oh, this is suspicious.
We use the jwt_authentication rule, but we define group_names_claim. Isn't it kind of a misconfiguration? In the context of authentication, the groups should not be used. But you (as a user) can declare them. It looks like we should catch them.
Maybe JwtDef with None should not be valid in the context of the JwtAuthenticationRule? Should we distinguish it in types?
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.
At the moment, in the current implementation, it is not a misconfiguration. The group_names_claim is a property of JWT service definition, and not of the authentication rule. But it is completely unused in this context and in this test.
In current implementation it is correct, because the same jwt1 definition may be used for multiple authn/authz/auth rules.
I added this issue to the thread about the compatibility of auth rule and the pseudo-authorization rule.
|
|
||
| // Pseudo-authorization rule should be used exclusively as part of the JwtAuthRule, when there are is no groups logic defined. | ||
| // It preserves the kbn_auth rule behavior from before introducing separate authn and authz rules. | ||
| final class JwtPseudoAuthorizationRule(val settings: Settings) |
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.
ok, let's think about it a little bit. I'd like to avoid the JwtPesudoAuthorizationRule. But first, let's analyse all the cases. I think we can find them in this code:
private def handleGroupsClaimSearchResult[B <: BlockContext : BlockContextUpdater](blockContext: B,
result: Option[ClaimSearchResult[UniqueList[Group]]]) = {
(result, settings.permittedGroups) match {
// 1. authorization rule - groups are defined, but no groups cannot be extracted from JWT, because of not configured groups claim (FORBIDDEN - correct in context of authorization rule)
case (None, Groups.Defined(_)) =>
Left(())
// 2. authentication rule - no groups definition in authentication rule; we don't have to look at groups from JWT (in this case, no groups claim name was configured, so we don't even know how to extract them) (ALLOWED - correct in context of authentication rule)
case (None, Groups.NotDefined) =>
Right(blockContext)
// 3. authorization rule - groups are defined; there is a configured groups claim name, but no groups are extracted (FORBIDDEN - correct in context of authorization rule)
case (Some(NotFound), Groups.Defined(_)) =>
Left(())
// 4. authorization rule - groups are not defined (we can assume it's allow all - "*"); there is a configured groups claim name, and groups are not extracted (should be FORBIDDEN - it looks it's bug. We had a similar use case in the context of the ror_kbn_auth, don't we?)
case (Some(NotFound), Groups.NotDefined) =>
Right(blockContext)
// 5. authorization rule - groups are defined; there is a configured groups claim name, and groups are extracted from JWT (FORBIDDEN/ALLOWED - result based on the groups logic)
case (Some(Found(groups)), Groups.Defined(groupsLogic)) =>
UniqueNonEmptyList.from(groups) match {
case Some(nonEmptyGroups) =>
groupsLogic.availableGroupsFrom(nonEmptyGroups) match {
case Some(matchedGroups) =>
checkIfCanContinueWithGroups(blockContext, UniqueList.from(matchedGroups))
.map(_.withUserMetadata(_.addAvailableGroups(matchedGroups)))
case None =>
Left(())
}
case None =>
Left(())
}
// 6. authorization rule - groups are not defined (we can assume it's allow all - "*"); there is a configured groups claim name, and groups are extracted from JWT (FORBIDDEN/ALLOWED - result based on current group eligibility)
case (Some(Found(groups)), Groups.NotDefined) =>
checkIfCanContinueWithGroups(blockContext, groups)
}
}
I've added comments.
Could you please compare each case with the current ror_kbn_auth... rules logic?
I see that 2. and 4. points are problematic. Do you agree?
If so, let's focus on them and compare with:
- current ror_kbn_auth... implementation
- old ror_kbn_auth... implementation
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.
Actionable comments posted: 2
♻️ Duplicate comments (2)
core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/JwtAuthenticationRuleSettingsTests.scala (1)
125-154: Group claims in authentication context – addressed by existing comment.The past review correctly identified that testing
group_ids_claim/group_names_claimin a pure authentication context is semantically questionable. The current approach loads the sharedJwtDefwhich may contain these claims, but authentication rules don't use them. This is an acceptable tradeoff for definition reuse.core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/JwtAuthorizationRuleSettingsTests.scala (1)
37-39: New test suite structure looks good – addressed by existing review comment.The past review noted this should have similar tests to
RorKbnAuthorizationRuleSettingsTests. This is a valid observation for ensuring parity.
🧹 Nitpick comments (6)
core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/RorKbnAuthRuleSettingsTests.scala (1)
295-301: UnusedenvVarsProvideroverride.This provider returns RSA keys for
SECRET_RSA, but no tests in this file exercise environment-variable-based key loading. Consider removing or adding relevant tests.core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/RorKbnAuthorizationRuleSettingsTests.scala (1)
268-274: UnusedenvVarsProvideroverride.Same as in
RorKbnAuthRuleSettingsTests- this provider isn't exercised by any test in this file.core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/JwtAuthorizationRuleSettingsTests.scala (3)
243-266: Ambiguous test name – conflicts with earlier test at line 113.Line 113 has "no JWT definition name is defined in rule setting" and line 243 has "no JWT definition name is defined". While they test different scenarios (rule vs definition level), the naming is confusing.
- "no JWT definition name is defined" in { + "no name attribute in JWT definition" in {
267-298: Duplicate test case – overlaps with lines 209-242.Both test cases validate "both 'groups or' key and 'groups and' key used" with nearly identical assertions. Consider removing this duplicate.
328-334: UnusedenvVarsProvideroverride.No tests in this file use RSA/EC signature algorithms that require the
SECRET_RSAenvironment variable. Consider removing or adding relevant tests.tests-utils/src/main/resources/log4j2_es_7.10_and_newer.properties (1)
18-146: Double‑check root logger wiring forreadonlyrest_audit.logand potential console duplicationOverall the Log4j2 config looks coherent and aligned with ES 7.10+ patterns (console, rolling main log, deprecation, slowlogs, header warnings, ROR audit, etc.). Two points are worth explicitly confirming:
Root logger →
ror_audit_rolling(lines 101‑107)
WithrootLogger.appenderRef.ror_audit_router.ref=ror_audit_rolling, every log reaching the root logger (i.e. effectively all categories except those withadditivity=false) will be written intoreadonlyrest_audit.log, not only thereadonlyrest_auditlogger.
If the intent is forreadonlyrest_audit.logto contain only ROR audit entries, consider removing the root logger reference and relying solely onlogger.ror_audit:-rootLogger.appenderRef.ror_audit_router.type=AppenderRef -rootLogger.appenderRef.ror_audit_router.ref=ror_audit_rolling(Or keep it as‑is if you really want a catch‑all audit log.)
Possible double console logging for
org.elasticsearch.action(lines 111‑117 vs 101‑105)
logger.actionsends toconsolewithadditivity=true, and the root logger also sends toconsole. That can result in duplicated console lines fororg.elasticsearch.actionlogs. If you see duplicates in practice, you may want to setlogger.action.additivity=falseor drop its explicit console appender and rely on root.These are configuration semantics rather than hard bugs, but worth validating against the intended logging behavior and test expectations.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Jira integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (15)
core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/definitions/DefinitionsPack.scala(2 hunks)core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/ruleDecoders.scala(1 hunks)core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/JwtAuthRuleDecoder.scala(0 hunks)core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/JwtAuthRulesDecoders.scala(1 hunks)core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/JwtLikeRulesDecoders.scala(1 hunks)core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/RorKbnRulesDecoders.scala(1 hunks)core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/JwtAuthRuleSettingsTests.scala(19 hunks)core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/JwtAuthenticationRuleSettingsTests.scala(1 hunks)core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/JwtAuthorizationRuleSettingsTests.scala(1 hunks)core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/RorKbnAuthRuleSettingsTests.scala(2 hunks)core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/RorKbnAuthenticationRuleSettingsTests.scala(3 hunks)core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/RorKbnAuthorizationRuleSettingsTests.scala(2 hunks)integration-tests/src/test/resources/ror_audit/enabled_auditing_tools/readonlyrest.yml(1 hunks)integration-tests/src/test/scala/tech/beshu/ror/integration/suites/audit/LocalClusterAuditingToolsSuite.scala(1 hunks)tests-utils/src/main/resources/log4j2_es_7.10_and_newer.properties(4 hunks)
💤 Files with no reviewable changes (1)
- core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/JwtAuthRuleDecoder.scala
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: mgoworko
Repo: sscarduzio/elasticsearch-readonlyrest-plugin PR: 1163
File: core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/variables/runtime/VariableContext.scala:96-98
Timestamp: 2025-10-03T21:07:20.002Z
Learning: In the ROR KBN authentication refactoring (PR #1163), the VariableUsage implicit for rorKbnAuthRule uses a union type `VariableUsage[RorKbnAuthRule | RorKbnAuthenticationRule]` because the decoder explicitly uses this union type to represent the fallback behavior where `ror_kbn_auth` without groups falls back to `RorKbnAuthenticationRule`. A separate `VariableUsage[RorKbnAuthRule]` implicit is not needed since there are no direct usages of that specific type - all usage goes through the union type in the decoder.
📚 Learning: 2025-10-03T21:07:20.002Z
Learnt from: mgoworko
Repo: sscarduzio/elasticsearch-readonlyrest-plugin PR: 1163
File: core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/variables/runtime/VariableContext.scala:96-98
Timestamp: 2025-10-03T21:07:20.002Z
Learning: In the ROR KBN authentication refactoring (PR #1163), the VariableUsage implicit for rorKbnAuthRule uses a union type `VariableUsage[RorKbnAuthRule | RorKbnAuthenticationRule]` because the decoder explicitly uses this union type to represent the fallback behavior where `ror_kbn_auth` without groups falls back to `RorKbnAuthenticationRule`. A separate `VariableUsage[RorKbnAuthRule]` implicit is not needed since there are no direct usages of that specific type - all usage goes through the union type in the decoder.
Applied to files:
core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/JwtAuthenticationRuleSettingsTests.scalacore/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/RorKbnAuthenticationRuleSettingsTests.scalacore/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/RorKbnAuthorizationRuleSettingsTests.scalacore/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/JwtAuthRuleSettingsTests.scalacore/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/JwtLikeRulesDecoders.scalacore/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/RorKbnAuthRuleSettingsTests.scalacore/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/JwtAuthRulesDecoders.scalacore/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/RorKbnRulesDecoders.scalacore/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/ruleDecoders.scala
📚 Learning: 2025-09-21T14:09:30.387Z
Learnt from: mgoworko
Repo: sscarduzio/elasticsearch-readonlyrest-plugin PR: 1163
File: core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/rules/auth/base/RorKbnRuleHelper.scala:168-172
Timestamp: 2025-09-21T14:09:30.387Z
Learning: RorKbnDef.SignatureCheckMethod sealed trait has only three cases: Hmac(key: Array[Byte]), Rsa(pubKey: PublicKey), and Ec(pubKey: PublicKey). There is no NoCheck case.
Applied to files:
core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/JwtAuthenticationRuleSettingsTests.scalacore/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/RorKbnAuthenticationRuleSettingsTests.scalacore/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/JwtAuthRuleSettingsTests.scalacore/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/RorKbnAuthRuleSettingsTests.scala
📚 Learning: 2025-11-19T16:33:39.709Z
Learnt from: mateuszkp96
Repo: sscarduzio/elasticsearch-readonlyrest-plugin PR: 1186
File: integration-tests/src/test/scala/tech/beshu/ror/integration/suites/audit/LocalClusterAuditingToolsSuite.scala:193-193
Timestamp: 2025-11-19T16:33:39.709Z
Learning: In LocalClusterAuditingToolsSuite, when truncating audit data via adminAuditManagers.values.foreach(_.head.truncate()), calling truncate on only the head manager is sufficient because all AuditIndexManager instances in each NonEmptyList point to the same cluster's audit index. Since the truncation affects the underlying index, there's no need to iterate all managers in the list.
Applied to files:
integration-tests/src/test/scala/tech/beshu/ror/integration/suites/audit/LocalClusterAuditingToolsSuite.scala
🧬 Code graph analysis (6)
core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/JwtAuthenticationRuleSettingsTests.scala (3)
core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/definitions/JwtDef.scala (1)
SignatureCheckMethod(41-46)core/src/main/scala/tech/beshu/ror/accesscontrol/factory/HttpClientsFactory.scala (2)
HttpClientsFactory(49-81)HttpClient(52-65)core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/JwtAuthorizationRuleSettingsTests.scala (1)
envVarsProvider(328-334)
core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/RorKbnAuthorizationRuleSettingsTests.scala (1)
core/src/main/scala/tech/beshu/ror/accesscontrol/factory/RawRorConfigBasedCoreFactory.scala (3)
CoreCreationError(475-504)DefinitionsLevelCreationError(478-478)RulesLevelCreationError(480-480)
core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/JwtAuthRuleSettingsTests.scala (8)
core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/definitions/ExternalAuthenticationService.scala (1)
definitions(126-126)core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/definitions/JwtDef.scala (4)
JwtDef(27-36)JwtDef(37-51)GroupsConfig(48-48)SignatureCheckMethod(41-46)core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/rules/auth/JwtPseudoAuthorizationRule.scala (3)
rules(41-45)JwtPseudoAuthorizationRule(34-60)JwtPseudoAuthorizationRule(62-64)core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/rules/auth/JwtAuthorizationRule.scala (4)
rules(39-48)JwtAuthorizationRule(32-65)JwtAuthorizationRule(67-74)Name(69-71)core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/rules/auth/JwtAuthRule.scala (3)
JwtAuthRule(25-36)JwtAuthRule(38-42)Name(39-41)core/src/main/scala/tech/beshu/ror/accesscontrol/domain/userAndGroups.scala (10)
GroupIdLike(80-121)GroupId(81-82)GroupId(84-86)GroupsLogic(154-261)GroupIds(123-125)GroupIds(127-150)from(69-69)from(75-75)from(100-104)from(129-131)core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/definitions/ldap/LdapService.scala (2)
Name(35-35)Name(36-38)core/src/main/scala/tech/beshu/ror/accesscontrol/domain/http.scala (1)
AuthorizationTokenDef(276-277)
core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/JwtLikeRulesDecoders.scala (6)
core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/common.scala (1)
common(53-368)core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/definitions/DefinitionsPack.scala (2)
Definitions(34-34)Definitions(35-41)core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/RuleBaseDecoder.scala (2)
RuleBaseDecoder(84-109)RuleBaseDecoderWithoutAssociatedFields(86-94)core/src/main/scala/tech/beshu/ror/accesscontrol/utils/CirceOps.scala (2)
CirceOps(42-419)toSyncDecoder(279-279)core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/JwtAuthRulesDecoders.scala (7)
humanReadableName(34-34)createAuthenticationRule(36-39)createAuthorizationRule(39-42)createAuthRule(45-48)createAuthorizationRuleWithoutGroups(42-45)createAuthRuleWithoutGroups(48-51)serializeDefinitionId(51-54)core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/RorKbnRulesDecoders.scala (7)
humanReadableName(37-37)createAuthenticationRule(39-42)createAuthorizationRule(42-45)createAuthRule(48-51)createAuthorizationRuleWithoutGroups(45-48)createAuthRuleWithoutGroups(51-54)serializeDefinitionId(54-57)
core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/RorKbnRulesDecoders.scala (4)
core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/JwtAuthRulesDecoders.scala (7)
humanReadableName(34-34)createAuthenticationRule(36-39)createAuthorizationRule(39-42)createAuthorizationRuleWithoutGroups(42-45)createAuthRule(45-48)createAuthRuleWithoutGroups(48-51)serializeDefinitionId(51-54)core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/rules/auth/RorKbnAuthenticationRule.scala (3)
RorKbnAuthenticationRule(33-76)RorKbnAuthenticationRule(78-85)Settings(84-84)core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/rules/auth/RorKbnAuthorizationRule.scala (3)
Settings(73-73)RorKbnAuthorizationRule(32-65)RorKbnAuthorizationRule(67-74)core/src/main/scala/tech/beshu/ror/accesscontrol/domain/userAndGroups.scala (2)
GroupsLogic(154-261)AnyOf(172-172)
core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/ruleDecoders.scala (2)
core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/JwtAuthRulesDecoders.scala (1)
JwtAuthRulesDecoders(25-54)core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/RorKbnRulesDecoders.scala (1)
RorKbnRulesDecoders(28-57)
🔇 Additional comments (20)
integration-tests/src/test/resources/ror_audit/enabled_auditing_tools/readonlyrest.yml (1)
18-22: Clarify the purpose of the new log-based audit output.The new ECS serializer-based log output appears syntactically correct and is positioned consistently with other audit outputs. However, the relationship to the JWT authentication/authorization rule separation (PR objective) isn't immediately clear.
Is this log output specifically needed to support testing of the new JWT rules, or is it test infrastructure unrelated to the core JWT separation work? If it's required for the JWT tests, consider adding an inline comment explaining the dependency.
core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/definitions/DefinitionsPack.scala (1)
34-34: LGTM! Type parameter refinement improves type safety.The upper bound
ITEM <: Itemallows callers to preserve the specific item type while ensuring it conforms toItem. This aligns well with the typed definitions used throughoutDefinitionsPack.core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/RorKbnAuthenticationRuleSettingsTests.scala (2)
85-86: Good test organization.Splitting tests into general config loading and token-related scenarios improves readability.
Also applies to: 397-398
364-366: Error message correctly references the authorization rule.The updated message
"ROR Kibana authorization rule 'kbn1'"aligns with the new separation of authentication and authorization concerns.core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/RorKbnAuthRuleSettingsTests.scala (1)
62-72: Composed rule access pattern looks correct.The tests properly validate both
authenticationandauthorizationcomponents ofRorKbnAuthRule, reflecting the new separation.Also applies to: 96-106
core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/RorKbnAuthorizationRuleSettingsTests.scala (1)
51-53: Correct test setup for authorization rule.Including
auth_key_sha1beforeror_kbn_authorizationis appropriate since authorization rules require prior authentication.Also applies to: 84-86
core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/ruleDecoders.scala (2)
134-139: JWT decoder wiring is correct.Routing to
JwtAuthRulesDecoders.AuthRuleDecoder,AuthenticationRuleDecoder, andAuthorizationRuleDecoderproperly delegates to the new consolidated decoder framework.
144-149: ROR KBN decoder wiring mirrors JWT pattern.Consistent with
JwtAuthRulesDecoders, the ROR KBN rules now useRorKbnRulesDecodersfor authentication, authorization, and combined auth rules.core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/JwtAuthRuleSettingsTests.scala (2)
65-71: LGTM – assertions properly verify the new composed rule structure.The tests correctly access
rule.authentication.settings.jwtand verify the authorization rule type. TheasInstanceOfusage is acceptable here for test assertions.
128-130: Consistent pattern for groups logic verification.Properly asserts
JwtAuthorizationRulewith expectedGroupsLogic.AnyOfconfiguration.core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/JwtAuthenticationRuleSettingsTests.scala (2)
39-41: New test suite for standalone JWT authentication rule – LGTM.Comprehensive coverage for the new
JwtAuthenticationRuledecoder including signature algorithms and external validators.
620-626: Environment variable provider pattern is consistent across test suites.Matches the pattern used in other JWT test files.
core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/JwtAuthRulesDecoders.scala (1)
25-54: Clean factory implementation for JWT rules.The decoder properly implements
JwtLikeRulesDecoderswith correct rule construction. Factory methods are well-structured and consistent.core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/RorKbnRulesDecoders.scala (2)
28-35: Design note: RorKbn uses same type for with/without groups.Unlike
JwtAuthRulesDecoderswhich uses distinctJwtPseudoAuthorizationRule, RorKbn reusesRorKbnAuthorizationRulefor both cases. This is consistent with ROR Kibana's requirement that group validation always occurs, using a wildcard pattern"*"as the permissive default.
45-46: Wildcard group pattern for "without groups" scenario – LGTM.Using
GroupIdPattern.fromNes(nes("*"))effectively permits any group, matching the expected behavior when groups aren't explicitly configured.core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/JwtLikeRulesDecoders.scala (5)
40-48: Clean abstraction for shared JWT/ROR-KBN decoding logic.The generic trait with context bounds properly captures the common decoding pattern. The asymmetry in
AUTHZ_WITHOUT_GROUPS_RULE(lacking the additional context bounds) is appropriate since it's only used internally for the deprecated fallback path.
68-87: LGTM!Authentication decoder correctly rejects superfluous groups settings and provides actionable error messages pointing users to
AUTHZ_RULEorAUTH_RULEalternatives.
89-107: LGTM!Authorization decoder correctly enforces that groups logic is mandatory and provides a documentation link in the error message.
109-140: Good backward compatibility handling.The deprecation warning for missing groups logic is well-crafted—it explains the implicit fallback behavior (
groups_any_of: ["*"]), provides documentation, and suggests the alternative (AUTHN_RULE). This matches the pattern from the ROR KBN refactoring per prior learnings.
142-175: LGTM!The helper decoders properly handle the three cases: simple string form, extended object form with groups logic, and the multiple-groups-defined error case. The ignored error in
GroupsLogicNotDefinedis intentional—each parent decoder handles theNonecase appropriately for its semantics.
| } | ||
| ) | ||
| } | ||
| "RSA algorithm is defined but on signature key" in { |
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.
Typo in test description.
"RSA algorithm is defined but on signature key" → should be "no signature key".
- "RSA algorithm is defined but on signature key" in {
+ "RSA algorithm is defined but no signature key" in {🤖 Prompt for AI Agents
In
core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/JwtAuthenticationRuleSettingsTests.scala
around line 495, the test description contains a typo: replace the string "RSA
algorithm is defined but on signature key" with "RSA algorithm is defined but no
signature key" so the message correctly reads "no signature key".
.../src/test/scala/tech/beshu/ror/integration/suites/audit/LocalClusterAuditingToolsSuite.scala
Outdated
Show resolved
Hide resolved
This reverts commit 6ff6868.
🚀Added separate JWT authentication and authorization rules
Summary by CodeRabbit
New Features
Refactor
Tests
✏️ Tip: You can customize this high-level summary in your review settings.