-
Notifications
You must be signed in to change notification settings - Fork 165
[RORDEV-1481] New audit serializers, including fully configurable serializer #1140
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
audit/src/main/scala/tech/beshu/ror/audit/instances/BaseAuditLogSerializer.scala
Outdated
Show resolved
Hide resolved
audit/src/main/scala/tech/beshu/ror/audit/instances/DefaultAuditLogSerializerV1.scala
Outdated
Show resolved
Hide resolved
integration-tests/src/test/resources/ror_audit/enabled_auditing_tools/readonlyrest.yml
Outdated
Show resolved
Hide resolved
This comment was marked as outdated.
This comment was marked as outdated.
audit/src/main/scala/tech/beshu/ror/audit/AuditFieldValue.scala
Outdated
Show resolved
Hide resolved
audit/src/main/scala/tech/beshu/ror/audit/BaseAuditLogSerializer.scala
Outdated
Show resolved
Hide resolved
audit/src/main/scala/tech/beshu/ror/audit/BaseAuditLogSerializer.scala
Outdated
Show resolved
Hide resolved
audit/src/main/scala/tech/beshu/ror/audit/BaseAuditLogSerializer.scala
Outdated
Show resolved
Hide resolved
audit/src/main/scala/tech/beshu/ror/audit/instances/DefaultAuditLogSerializerV1.scala
Outdated
Show resolved
Hide resolved
audit/src/main/scala/tech/beshu/ror/audit/instances/ReportingAllEventsAuditLogSerializer.scala
Outdated
Show resolved
Hide resolved
...ain/scala/tech/beshu/ror/audit/instances/ReportingAllEventsWithQueryAuditLogSerializer.scala
Outdated
Show resolved
Hide resolved
core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/AuditingSettingsDecoder.scala
Outdated
Show resolved
Hide resolved
core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/AuditingSettingsDecoder.scala
Outdated
Show resolved
Hide resolved
audit/src/main/scala/tech/beshu/ror/audit/instances/DefaultAuditLogSerializerV2.scala
Outdated
Show resolved
Hide resolved
.../main/scala/tech/beshu/ror/audit/instances/ReportingAllTypesOfEventsAuditLogSerializer.scala
Outdated
Show resolved
Hide resolved
audit/src/main/scala/tech/beshu/ror/audit/AuditSerializationHelper.scala
Outdated
Show resolved
Hide resolved
audit/src/main/scala/tech/beshu/ror/audit/EnvironmentAwareAuditLogSerializer.scala
Show resolved
Hide resolved
audit/src/main/scala/tech/beshu/ror/audit/instances/DefaultAuditLogSerializerV2.scala
Outdated
Show resolved
Hide resolved
audit/src/main/scala/tech/beshu/ror/audit/AuditSerializationHelper.scala
Outdated
Show resolved
Hide resolved
audit/src/main/scala/tech/beshu/ror/audit/AuditFieldValue.scala
Outdated
Show resolved
Hide resolved
audit/src/main/scala/tech/beshu/ror/audit/instances/DefaultAuditLogSerializerV1.scala
Outdated
Show resolved
Hide resolved
audit/src/main/scala/tech/beshu/ror/audit/instances/DefaultAuditLogSerializerV2.scala
Outdated
Show resolved
Hide resolved
audit/src/main/scala/tech/beshu/ror/audit/instances/FullAuditLogSerializer.scala
Show resolved
Hide resolved
audit/src/main/scala/tech/beshu/ror/audit/instances/FullAuditLogSerializer.scala
Outdated
Show resolved
Hide resolved
audit/src/main/scala/tech/beshu/ror/audit/instances/FullAuditLogWithQuerySerializer.scala
Outdated
Show resolved
Hide resolved
core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/AuditingSettingsDecoder.scala
Outdated
Show resolved
Hide resolved
core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/AuditingSettingsDecoder.scala
Outdated
Show resolved
Hide resolved
core/src/test/scala/tech/beshu/ror/unit/acl/factory/AuditSettingsTests.scala
Outdated
Show resolved
Hide resolved
core/src/test/scala/tech/beshu/ror/unit/acl/factory/AuditSettingsTests.scala
Outdated
Show resolved
Hide resolved
core/src/test/scala/tech/beshu/ror/unit/acl/factory/AuditSettingsTests.scala
Outdated
Show resolved
Hide resolved
audit/src/main/scala/tech/beshu/ror/audit/instances/FullAuditLogSerializer.scala
Show resolved
Hide resolved
audit/src/main/scala/tech/beshu/ror/audit/instances/FullAuditLogSerializer.scala
Outdated
Show resolved
Hide resolved
override def onResponse(responseContext: AuditResponseContext): Option[JSONObject] = | ||
AuditSerializationHelper.serialize( | ||
responseContext = responseContext, | ||
fields = queryV2AuditFields, |
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.
Same here. Maybe it's worth redefining the fields.
I wonder if we shouldn't do it like this:
- if this is a separate/new/different serializer, let's define all the fields in a companion object
- if this is an alias, it should extend some serializer and won't redefine fields (it should not even override onResponse)
- if this is a serializer that extends another serializer, let's use the fields from the extended serializer and add new ones (but maybe it means that it'd be better to add these fields at the class definition's level, not the companion object's level)
WDYT?
If it makes sense, let's refactor all the serializers to follow these rules.
Maybe we should also add them to our internal repo (or in the form of an ADR).
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 propose (and implemented) something a bit different, IMO more readable and with less duplicates.
- the fields are mostly the same between serializers, and I don't like the idea of duplicating the lists - it creates space for bugs and ommisions
- there are only 3 sets of fields: common fields (most fields, present in all serializers that we provide), ES environment related fields (added in 1414 and present in new, V2 and environment-aware serializers), and full content field
- the serializers do not extend each other now after this PR (there are only name aliases, but not reusing and modifying other class)
- each serializer (provided by us in our codebase) has implementation like shown below
- so it defines which field groups are used, and which allowed events are serialized
- serializers do not extend each other, but instead each uses
AuditSerializationHelper.serialize
with appropriate field groups and allowed event mode
override def onResponse(responseContext: AuditResponseContext): Option[JSONObject] =
AuditSerializationHelper.serialize(
responseContext = responseContext,
fieldGroups = Set(CommonFields, EsEnvironmentFields, FullRequestContentFields),
allowedEventMode = IncludeAll
)
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 creates space for bugs and ommisions
Yes, but it also creates a possibility of adding a new field to some serializer unintentionally.
So, both approaches are error-prone.
But it's ok when we add proper unit tests ;) So, let's add a unit test for each serializer to check what fields it produces. To work as expected (to eliminate or at least lower the possibility of the bug I mentioned above), we should hardcode the list in the test (but hardcoding in tests is not a problem for us, right ;)).
It may be tedious, so let's try to use LLM to help us with this boring task ;)
audit/src/main/scala/tech/beshu/ror/audit/utils/AuditSerializationHelper.scala
Outdated
Show resolved
Hide resolved
audit/src/main/scala/tech/beshu/ror/audit/AuditFieldValue.scala
Outdated
Show resolved
Hide resolved
audit/src/main/scala/tech/beshu/ror/audit/AuditSerializationHelper.scala
Outdated
Show resolved
Hide resolved
core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/AuditingSettingsDecoder.scala
Show resolved
Hide resolved
core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/AuditingSettingsDecoder.scala
Outdated
Show resolved
Hide resolved
/** | ||
* Base implementation delegating to [[DefaultAuditLogSerializerV2]]. | ||
* | ||
* - Not intended for direct external use. |
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.
maybe we should annotate it as deprecated instead?
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.
should we rename the class name?
@@ -17,82 +17,35 @@ | |||
package tech.beshu.ror.audit.instances |
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 comments in this file
* | ||
* Recommended when a minimal, compact audit log is sufficient. | ||
*/ | ||
class BlockVerbosityAwareAuditLogSerializerV1 extends DefaultAuditLogSerializerV1 |
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 don't get why we introduce V1 and V2 for the "new" serializer (to be strict - renamed).
I took into consideration two things:
- backward compatibility - we don't have to do that
- documentation - how are we going to explain to our users (new users, and users who have ROR already installed) in simple words the V1 and V2? - so it may be misleading for them. Do they need it? I suppose - no.
audit/src/main/scala/tech/beshu/ror/audit/instances/BaseAuditLogSerializer.scala
Outdated
Show resolved
Hide resolved
/** | ||
* Serializer for audit events that is aware of **rule-defined verbosity**. | ||
* | ||
* - Includes `CommonFields` and `EsEnvironmentFields`. |
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.
CommonFields, EsEnvironmentFields, ... are implementation details. Let's list all the fields in the description (with one line explanation if possible)
override def onResponse(responseContext: AuditResponseContext): Option[JSONObject] = | ||
AuditSerializationHelper.serialize( | ||
responseContext = responseContext, | ||
fields = queryV2AuditFields, |
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 creates space for bugs and ommisions
Yes, but it also creates a possibility of adding a new field to some serializer unintentionally.
So, both approaches are error-prone.
But it's ok when we add proper unit tests ;) So, let's add a unit test for each serializer to check what fields it produces. To work as expected (to eliminate or at least lower the possibility of the bug I mentioned above), we should hardcode the list in the test (but hardcoding in tests is not a problem for us, right ;)).
It may be tedious, so let's try to use LLM to help us with this boring task ;)
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: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
core/src/main/scala/tech/beshu/ror/accesscontrol/audit/AuditingTool.scala (1)
85-120
: Preserve generalAuditEvents for all responses (data loss bug).
generalAuditEvents
is forwarded only for Allowed/Allow. For ForbiddenBy, Forbidden, RequestedIndexNotExist, and Errored it’s dropped (defaults to empty), so extra fields injected upstream vanish from those entries.case forbiddenBy: ResponseContext.ForbiddenBy[B] => AuditResponseContext.ForbiddenBy( requestContext = toAuditRequestContext( requestContext = forbiddenBy.requestContext, auditEnvironmentContext = auditEnvironmentContext, blockContext = Some(forbiddenBy.blockContext), userMetadata = Some(forbiddenBy.blockContext.userMetadata), - historyEntries = forbiddenBy.history), + historyEntries = forbiddenBy.history, + generalAuditEvents = forbiddenBy.requestContext.generalAuditEvents), verbosity = toAuditVerbosity(forbiddenBy.block.verbosity), reason = forbiddenBy.block.show ) case forbidden: ResponseContext.Forbidden[B] => AuditResponseContext.Forbidden(toAuditRequestContext( requestContext = forbidden.requestContext, auditEnvironmentContext = auditEnvironmentContext, blockContext = None, userMetadata = None, - historyEntries = forbidden.history)) + historyEntries = forbidden.history, + generalAuditEvents = forbidden.requestContext.generalAuditEvents)) case requestedIndexNotExist: ResponseContext.RequestedIndexNotExist[B] => AuditResponseContext.RequestedIndexNotExist( toAuditRequestContext( requestContext = requestedIndexNotExist.requestContext, auditEnvironmentContext = auditEnvironmentContext, blockContext = None, userMetadata = None, - historyEntries = requestedIndexNotExist.history) + historyEntries = requestedIndexNotExist.history, + generalAuditEvents = requestedIndexNotExist.requestContext.generalAuditEvents) ) case errored: ResponseContext.Errored[B] => AuditResponseContext.Errored( requestContext = toAuditRequestContext( requestContext = errored.requestContext, auditEnvironmentContext = auditEnvironmentContext, blockContext = None, userMetadata = None, - historyEntries = Vector.empty), + historyEntries = Vector.empty, + generalAuditEvents = errored.requestContext.generalAuditEvents), cause = errored.cause)
♻️ Duplicate comments (2)
audit/src/main/scala/tech/beshu/ror/audit/instances/QueryAuditLogSerializer.scala (1)
61-62
: Restore constructor-compat shim for legacy callers passing AuditEnvironmentContext.Older integrations may still call
new QueryAuditLogSerializer(env)
. Add an aux constructor that discards the param and delegates tothis()
.-class QueryAuditLogSerializer extends QueryAuditLogSerializerV2 +class QueryAuditLogSerializer extends QueryAuditLogSerializerV2 { + // Backward-compatibility shim: keep accepting the legacy constructor signature. + def this(environmentContext: tech.beshu.ror.audit.AuditEnvironmentContext) = { + this() + } +}core/src/test/scala/tech/beshu/ror/unit/acl/factory/AuditSettingsTests.scala (1)
379-395
: Ack: aligns with earlier suggestion to expose a verbosity list.Using
verbosity_level_serialization_mode: [INFO]
addresses prior review feedback about avoiding class-hierarchy mirroring in config.
🧹 Nitpick comments (5)
audit/src/main/scala/tech/beshu/ror/audit/instances/QueryAuditLogSerializer.scala (4)
26-60
: Avoid duplicating the field list in the alias doc to reduce drift.Point to V2’s doc (or the field groups) instead of repeating the full list here.
/** * Public alias for [[QueryAuditLogSerializerV2]]. - * - Captures full request content along with common and ES environment fields. - * - Respects rule-defined verbosity for `Allowed` events: - * only serializes them if the corresponding rule allows logging at `Verbosity.Info`. - * - Prefer this class name in configurations and client code for full-content auditing. - * - Fields included: - * - `match` — whether the request matched a rule (boolean) - * - `block` — reason for blocking, if blocked (string) - * - `id` — audit event identifier (string) - * - `final_state` — final processing state (string) - * - `@timestamp` — event timestamp (ISO-8601 string) - * - `correlation_id` — correlation identifier for tracing (string) - * - `processingMillis` — request processing duration in milliseconds (number) - * - `error_type` — type of error, if any (string) - * - `error_message` — error message, if any (string) - * - `content_len` — request body size in bytes (number) - * - `content_len_kb` — request body size in kilobytes (number) - * - `type` — request type (string) - * - `origin` — client (remote) address (string) - * - `destination` — server (local) address (string) - * - `xff` — `X-Forwarded-For` HTTP header value (string) - * - `task_id` — Elasticsearch task ID (number) - * - `req_method` — HTTP request method (string) - * - `headers` — HTTP header names (array of strings) - * - `path` — HTTP request path (string) - * - `user` — authenticated user (string) - * - `impersonated_by` — impersonating user, if applicable (string) - * - `action` — Elasticsearch action name (string) - * - `indices` — indices involved in the request (array of strings) - * - `acl_history` — access control evaluation history (string) - * - `es_node_name` — Elasticsearch node name (string) - * - `es_cluster_name` — Elasticsearch cluster name (string) - * - `content` — full request body (string) + * - Prefer this class name in configurations and client code for full-content auditing. + * - See [[QueryAuditLogSerializerV2]] for the list of included fields and semantics. */
100-109
: Hoist constants; optionally add the same ctor shim on V2.
- Micro-opt: avoid reallocating the same Sets/Include on every call.
- Optional: mirror the ctor shim here to cover rare direct usages of
V2
.-class QueryAuditLogSerializerV2 extends AuditLogSerializer { +class QueryAuditLogSerializerV2 extends AuditLogSerializer { + // Cache constant configuration + private[this] val FieldGroups = Set(CommonFields, EsEnvironmentFields, FullRequestContentFields) + private[this] val AllowedInfo = Include(Set(Verbosity.Info)) override def onResponse(responseContext: AuditResponseContext): Option[JSONObject] = AuditSerializationHelper.serialize( responseContext = responseContext, - fieldGroups = Set(CommonFields, EsEnvironmentFields, FullRequestContentFields), - allowedEventMode = Include(Set(Verbosity.Info)) + fieldGroups = FieldGroups, + allowedEventMode = AllowedInfo ) }Optional ctor shim:
class QueryAuditLogSerializerV2 extends AuditLogSerializer { + // Optional BC shim for direct V2 callers. + def this(environmentContext: tech.beshu.ror.audit.AuditEnvironmentContext) = { + this() + } … }
111-145
: Mark V1 usage as legacy in the docs (and steer to alias/V2).Add a brief note that V1 is kept for compatibility and recommend
QueryAuditLogSerializer
(alias) going forward.
146-155
: Deprecate V1 to guide migrations; also hoist constants.Annotate the class as deprecated and reuse cached constants like in V2.
-class QueryAuditLogSerializerV1 extends AuditLogSerializer { +@deprecated("Use QueryAuditLogSerializer (alias of V2) or QueryAuditLogSerializerV2.", "1.67.0") +class QueryAuditLogSerializerV1 extends AuditLogSerializer { + private[this] val FieldGroups = Set(CommonFields, FullRequestContentFields) + private[this] val AllowedInfo = Include(Set(Verbosity.Info)) override def onResponse(responseContext: AuditResponseContext): Option[JSONObject] = AuditSerializationHelper.serialize( responseContext = responseContext, - fieldGroups = Set(CommonFields, FullRequestContentFields), - allowedEventMode = Include(Set(Verbosity.Info)) + fieldGroups = FieldGroups, + allowedEventMode = AllowedInfo ) }core/src/test/scala/tech/beshu/ror/unit/acl/logging/AuditingToolTests.scala (1)
65-76
: Tighten the “no audit entry” assertion: expect zero submits on both sinks.Right now the test passes if nothing happens, but it doesn’t fail if a submit sneaks in. Add explicit
.never
expectations for both the index and data‑stream sinks.@nowarn("cat=deprecation") val auditingTool = AuditingTool.create( - settings = auditSettings(new DefaultAuditLogSerializer), - auditSinkServiceCreator = new DataStreamAndIndexBasedAuditSinkServiceCreator { - override def dataStream(cluster: AuditCluster): DataStreamBasedAuditSinkService = - mockedDataStreamBasedAuditSinkService - - override def index(cluster: AuditCluster): IndexBasedAuditSinkService = mock[IndexBasedAuditSinkService] - } + settings = auditSettings(new DefaultAuditLogSerializer), + auditSinkServiceCreator = new DataStreamAndIndexBasedAuditSinkServiceCreator { + private val indexAuditSink = mock[IndexBasedAuditSinkService] + private val dataStreamAuditSink = mockedDataStreamBasedAuditSinkService + override def dataStream(cluster: AuditCluster): DataStreamBasedAuditSinkService = dataStreamAuditSink + override def index(cluster: AuditCluster): IndexBasedAuditSinkService = indexAuditSink + } ).runSyncUnsafe().toOption.flatten.get - auditingTool.audit(createAllowedResponseContext(Policy.Allow, Verbosity.Error), testAuditEnvironmentContext).runSyncUnsafe() + // assert no submits happen + val indexAuditSink = auditingTool // get the same mocks as above via closure + (indexAuditSink + .asInstanceOf[{ def auditSinks: Any }]) // placeholder to indicate same scope; keep expectations above + (mock[IndexBasedAuditSinkService].submit _).expects(*, *, *).never + (mockedDataStreamBasedAuditSinkService.submit _).expects(*, *, *).never + auditingTool.audit(createAllowedResponseContext(Policy.Allow, Verbosity.Error), testAuditEnvironmentContext).runSyncUnsafe()Note: use your local variable handles to the mocks (as shown) rather than creating new ones; the snippet illustrates intent: set
.never
on bothindexAuditSink
anddataStreamAuditSink
used by the tool.
📜 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 (13)
audit/src/main/scala/tech/beshu/ror/audit/instances/BlockVerbosityAwareAuditLogSerializer.scala
(1 hunks)audit/src/main/scala/tech/beshu/ror/audit/instances/DefaultAuditLogSerializer.scala
(0 hunks)audit/src/main/scala/tech/beshu/ror/audit/instances/DefaultAuditLogSerializerV1.scala
(0 hunks)audit/src/main/scala/tech/beshu/ror/audit/instances/FullAuditLogSerializer.scala
(1 hunks)audit/src/main/scala/tech/beshu/ror/audit/instances/FullAuditLogWithQuerySerializer.scala
(1 hunks)audit/src/main/scala/tech/beshu/ror/audit/instances/QueryAuditLogSerializer.scala
(1 hunks)audit/src/main/scala/tech/beshu/ror/audit/instances/QueryAuditLogSerializerV1.scala
(0 hunks)audit/src/main/scala/tech/beshu/ror/audit/instances/QueryAuditLogSerializerV2.scala
(0 hunks)core/src/main/scala/tech/beshu/ror/accesscontrol/audit/AuditingTool.scala
(12 hunks)core/src/test/scala/tech/beshu/ror/integration/AuditOutputFormatTests.scala
(2 hunks)core/src/test/scala/tech/beshu/ror/unit/acl/factory/AuditSettingsTests.scala
(29 hunks)core/src/test/scala/tech/beshu/ror/unit/acl/logging/AuditingToolTests.scala
(8 hunks)integration-tests/src/test/scala/tech/beshu/ror/integration/suites/audit/LocalClusterAuditingToolsSuite.scala
(1 hunks)
💤 Files with no reviewable changes (4)
- audit/src/main/scala/tech/beshu/ror/audit/instances/DefaultAuditLogSerializer.scala
- audit/src/main/scala/tech/beshu/ror/audit/instances/QueryAuditLogSerializerV1.scala
- audit/src/main/scala/tech/beshu/ror/audit/instances/DefaultAuditLogSerializerV1.scala
- audit/src/main/scala/tech/beshu/ror/audit/instances/QueryAuditLogSerializerV2.scala
🚧 Files skipped from review as they are similar to previous changes (4)
- audit/src/main/scala/tech/beshu/ror/audit/instances/FullAuditLogSerializer.scala
- audit/src/main/scala/tech/beshu/ror/audit/instances/FullAuditLogWithQuerySerializer.scala
- integration-tests/src/test/scala/tech/beshu/ror/integration/suites/audit/LocalClusterAuditingToolsSuite.scala
- core/src/test/scala/tech/beshu/ror/integration/AuditOutputFormatTests.scala
🧰 Additional context used
🧬 Code graph analysis (5)
audit/src/main/scala/tech/beshu/ror/audit/instances/QueryAuditLogSerializer.scala (4)
audit/src/main/scala/tech/beshu/ror/audit/utils/AuditSerializationHelper.scala (9)
ror
(28-276)AllowedEventMode
(150-154)Include
(153-153)AuditFieldGroup
(232-238)CommonFields
(233-233)EsEnvironmentFields
(235-235)FullRequestContentFields
(237-237)serialize
(32-45)serialize
(47-66)audit/src/main/scala/tech/beshu/ror/audit/AuditResponseContext.scala (1)
AuditResponseContext
(28-55)audit/src/main/scala/tech/beshu/ror/audit/instances/BlockVerbosityAwareAuditLogSerializer.scala (2)
onResponse
(67-74)onResponse
(79-86)audit/src/main/scala/tech/beshu/ror/audit/instances/FullAuditLogWithQuerySerializer.scala (1)
onResponse
(61-68)
core/src/test/scala/tech/beshu/ror/unit/acl/factory/AuditSettingsTests.scala (5)
audit/src/main/scala/tech/beshu/ror/audit/utils/AuditSerializationHelper.scala (13)
ror
(28-276)Reason
(167-167)AllowedEventMode
(150-154)AuditFieldName
(156-156)AuditFieldValueDescriptor
(160-228)Include
(153-153)Combined
(226-226)EsNodeName
(218-218)StaticText
(224-224)EsClusterName
(220-220)HttpMethod
(198-198)TaskId
(188-188)ContentLengthInBytes
(212-212)core/src/main/scala/tech/beshu/ror/accesscontrol/audit/AuditingTool.scala (3)
audit
(43-48)AuditSink
(158-202)Config
(167-201)core/src/main/scala/tech/beshu/ror/accesscontrol/audit/AuditRequestContextBasedOnAclResult.scala (1)
audit
(35-92)core/src/main/scala/tech/beshu/ror/accesscontrol/audit/configurable/ConfigurableAuditLogSerializer.scala (1)
ConfigurableAuditLogSerializer
(24-30)core/src/main/scala/tech/beshu/ror/accesscontrol/factory/RawRorConfigBasedCoreFactory.scala (4)
RawRorConfigBasedCoreFactory
(70-457)RawRorConfigBasedCoreFactory
(459-545)Reason
(475-489)Core
(59-60)
audit/src/main/scala/tech/beshu/ror/audit/instances/BlockVerbosityAwareAuditLogSerializer.scala (5)
audit/src/main/scala/tech/beshu/ror/audit/AuditResponseContext.scala (1)
AuditResponseContext
(28-55)audit/src/main/scala/tech/beshu/ror/audit/utils/AuditSerializationHelper.scala (4)
AllowedEventMode
(150-154)AuditFieldGroup
(232-238)CommonFields
(233-233)EsEnvironmentFields
(235-235)audit/src/main/scala/tech/beshu/ror/audit/instances/FullAuditLogSerializer.scala (1)
onResponse
(60-67)audit/src/main/scala/tech/beshu/ror/audit/instances/FullAuditLogWithQuerySerializer.scala (1)
onResponse
(61-68)audit/src/main/scala/tech/beshu/ror/audit/instances/QueryAuditLogSerializer.scala (2)
onResponse
(102-109)onResponse
(148-155)
core/src/test/scala/tech/beshu/ror/unit/acl/logging/AuditingToolTests.scala (1)
core/src/main/scala/tech/beshu/ror/accesscontrol/audit/AuditingTool.scala (7)
AuditingTool
(40-148)AuditingTool
(150-299)create
(207-225)audit
(43-48)AuditSettings
(152-152)AuditSettings
(154-203)AuditSink
(158-202)
core/src/main/scala/tech/beshu/ror/accesscontrol/audit/AuditingTool.scala (4)
audit/src/main/scala/tech/beshu/ror/audit/utils/AuditSerializationHelper.scala (1)
ror
(28-276)core/src/main/scala/tech/beshu/ror/accesscontrol/audit/AuditRequestContextBasedOnAclResult.scala (1)
audit
(35-92)audit/src/main/scala/tech/beshu/ror/audit/instances/BlockVerbosityAwareAuditLogSerializer.scala (1)
BlockVerbosityAwareAuditLogSerializer
(59-59)audit/src/main/scala/tech/beshu/ror/audit/AuditResponseContext.scala (3)
AuditResponseContext
(28-55)Allowed
(30-33)RequestedIndexNotExist
(43-44)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (15)
- GitHub Check: ror (Run all tests IT_es80x)
- GitHub Check: ror (Run all tests IT_es67x)
- GitHub Check: ror (Run all tests IT_es810x)
- GitHub Check: ror (Run all tests IT_es70x)
- GitHub Check: ror (Run all tests IT_es90x)
- GitHub Check: ror (Run all tests IT_es816x)
- GitHub Check: ror (Run all tests IT_es710x)
- GitHub Check: ror (Run all tests IT_es91x)
- GitHub Check: ror (Run all tests IT_es717x)
- GitHub Check: ror (Run all tests IT_es818x)
- GitHub Check: ror (Required checks AUDIT_BUILD_CHECK)
- GitHub Check: ror (Required checks COMPILE_CODEBASE_CHECK)
- GitHub Check: ror (Required checks LICENSE_CHECK)
- GitHub Check: ror (Run all tests Unit tests)
- GitHub Check: ror (Optional checks CVE_CHECK)
🔇 Additional comments (11)
audit/src/main/scala/tech/beshu/ror/audit/instances/QueryAuditLogSerializer.scala (2)
19-24
: Imports are tight and correct. LGTM.
63-99
: Docs align with behavior. LGTM.core/src/test/scala/tech/beshu/ror/unit/acl/logging/AuditingToolTests.scala (1)
75-76
: LGTM: new audit signature used consistently.All audit calls correctly pass
testAuditEnvironmentContext
.Also applies to: 88-89, 107-108, 137-138, 157-158, 177-178, 206-207
audit/src/main/scala/tech/beshu/ror/audit/instances/BlockVerbosityAwareAuditLogSerializer.scala (1)
61-86
: Compatibility layer looks good.Deprecation shims (DefaultAuditLogSerializer, V2, V1) cleanly delegate to the new helper and keep the historic behavior.
core/src/test/scala/tech/beshu/ror/unit/acl/factory/AuditSettingsTests.scala (4)
389-417
: Configurable serializer test: good coverage and mapping checks.Validates Include(INFO) mode and accurately asserts field descriptor parsing (Combined, StaticText, TaskId, ContentLengthInBytes).
1288-1316
: Negative path: invalid placeholder validated.Test correctly asserts the exact error message for an unknown token (HTTP_METHOD2).
1317-1340
: Negative path: missing fields validated.Test ensures misconfiguration is surfaced with a precise error.
2017-2018
: Good: environment propagated in dummy context.Ensures environment-aware serializers can be exercised in tests.
core/src/main/scala/tech/beshu/ror/accesscontrol/audit/AuditingTool.scala (3)
43-48
: LGTM: audit API threads environment explicitly.Clearer control and avoids serializer construction‑time coupling.
173-178
: LGTM: defaults moved to no‑arg serializer and public vals.Using
BlockVerbosityAwareAuditLogSerializer
andval default
improves clarity and avoids accidental re‑binding.Also applies to: 185-190, 196-200
207-225
: Sanity‑check complete — all audit(...) call sites pass AuditEnvironmentContext.
Repo grep shows audit invocations use auditEnvironmentContext or testAuditEnvironmentContext; heuristic found no single-argument calls.
/** | ||
* Serializer for **full audit events including request content**. | ||
* - Serializes all events, including every `Allowed` request, | ||
* regardless of rule verbosity. | ||
* - Use this when request body capture is required. | ||
* - Fields included: | ||
* - `match` — whether the request matched a rule (boolean) | ||
* - `block` — reason for blocking, if blocked (string) | ||
* - `id` — audit event identifier (string) | ||
* - `final_state` — final processing state (string) | ||
* - `@timestamp` — event timestamp (ISO-8601 string) | ||
* - `correlation_id` — correlation identifier for tracing (string) | ||
* - `processingMillis` — request processing duration in milliseconds (number) | ||
* - `error_type` — type of error, if any (string) | ||
* - `error_message` — error message, if any (string) | ||
* - `content_len` — request body size in bytes (number) | ||
* - `content_len_kb` — request body size in kilobytes (number) | ||
* - `type` — request type (string) | ||
* - `origin` — client (remote) address (string) | ||
* - `destination` — server (local) address (string) | ||
* - `xff` — `X-Forwarded-For` HTTP header value (string) | ||
* - `task_id` — Elasticsearch task ID (number) | ||
* - `req_method` — HTTP request method (string) | ||
* - `headers` — HTTP header names (array of strings) | ||
* - `path` — HTTP request path (string) | ||
* - `user` — authenticated user (string) | ||
* - `impersonated_by` — impersonating user, if applicable (string) | ||
* - `action` — Elasticsearch action name (string) | ||
* - `indices` — indices involved in the request (array of strings) | ||
* - `acl_history` — access control evaluation history (string) | ||
* - `es_node_name` — Elasticsearch node name (string) | ||
* - `es_cluster_name` — Elasticsearch cluster name (string) | ||
*/ |
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.
Fix docstring: it contradicts the implementation.
This class extends the (deprecated) DefaultAuditLogSerializer which:
- includes CommonFields + EsEnvironmentFields
- serializes Allowed events only when verbosity == Info
- does not include request content
- does not include all Allowed events unconditionally
Update the comment to avoid misleading users.
-/**
- * Serializer for **full audit events including request content**.
- * - Serializes all events, including every `Allowed` request,
- * regardless of rule verbosity.
- * - Use this when request body capture is required.
- * - Fields included:
+/**
+ * Serializer whose output depends on block verbosity.
+ * - Serializes `Allowed` events only when verbosity is `Info`.
+ * - Includes common fields plus ES environment fields.
+ * - Does not include request body content.
+ * - Fields included (via CommonFields + EsEnvironmentFields):
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
/** | |
* Serializer for **full audit events including request content**. | |
* - Serializes all events, including every `Allowed` request, | |
* regardless of rule verbosity. | |
* - Use this when request body capture is required. | |
* - Fields included: | |
* - `match` — whether the request matched a rule (boolean) | |
* - `block` — reason for blocking, if blocked (string) | |
* - `id` — audit event identifier (string) | |
* - `final_state` — final processing state (string) | |
* - `@timestamp` — event timestamp (ISO-8601 string) | |
* - `correlation_id` — correlation identifier for tracing (string) | |
* - `processingMillis` — request processing duration in milliseconds (number) | |
* - `error_type` — type of error, if any (string) | |
* - `error_message` — error message, if any (string) | |
* - `content_len` — request body size in bytes (number) | |
* - `content_len_kb` — request body size in kilobytes (number) | |
* - `type` — request type (string) | |
* - `origin` — client (remote) address (string) | |
* - `destination` — server (local) address (string) | |
* - `xff` — `X-Forwarded-For` HTTP header value (string) | |
* - `task_id` — Elasticsearch task ID (number) | |
* - `req_method` — HTTP request method (string) | |
* - `headers` — HTTP header names (array of strings) | |
* - `path` — HTTP request path (string) | |
* - `user` — authenticated user (string) | |
* - `impersonated_by` — impersonating user, if applicable (string) | |
* - `action` — Elasticsearch action name (string) | |
* - `indices` — indices involved in the request (array of strings) | |
* - `acl_history` — access control evaluation history (string) | |
* - `es_node_name` — Elasticsearch node name (string) | |
* - `es_cluster_name` — Elasticsearch cluster name (string) | |
*/ | |
/** | |
* Serializer whose output depends on block verbosity. | |
* - Serializes `Allowed` events only when verbosity is `Info`. | |
* - Includes common fields plus ES environment fields. | |
* - Does not include request body content. | |
* - Fields included (via CommonFields + EsEnvironmentFields): | |
* - `match` — whether the request matched a rule (boolean) | |
* - `block` — reason for blocking, if blocked (string) | |
* - `id` — audit event identifier (string) | |
* - `final_state` — final processing state (string) | |
* - `@timestamp` — event timestamp (ISO-8601 string) | |
* - `correlation_id` — correlation identifier for tracing (string) | |
* - `processingMillis` — request processing duration in milliseconds (number) | |
* - `error_type` — type of error, if any (string) | |
* - `error_message` — error message, if any (string) | |
* - `content_len` — request body size in bytes (number) | |
* - `content_len_kb` — request body size in kilobytes (number) | |
* - `type` — request type (string) | |
* - `origin` — client (remote) address (string) | |
* - `destination` — server (local) address (string) | |
* - `xff` — `X-Forwarded-For` HTTP header value (string) | |
* - `task_id` — Elasticsearch task ID (number) | |
* - `req_method` — HTTP request method (string) | |
* - `headers` — HTTP header names (array of strings) | |
* - `path` — HTTP request path (string) | |
* - `user` — authenticated user (string) | |
* - `impersonated_by` — impersonating user, if applicable (string) | |
* - `action` — Elasticsearch action name (string) | |
* - `indices` — indices involved in the request (array of strings) | |
* - `acl_history` — access control evaluation history (string) | |
* - `es_node_name` — Elasticsearch node name (string) | |
* - `es_cluster_name` — Elasticsearch cluster name (string) | |
*/ |
🤖 Prompt for AI Agents
In
audit/src/main/scala/tech/beshu/ror/audit/instances/BlockVerbosityAwareAuditLogSerializer.scala
around lines 26 to 58, the docstring claims this serializer serializes all
Allowed events unconditionally and includes request content, which contradicts
the superclass DefaultAuditLogSerializer behaviour (it adds CommonFields +
EsEnvironmentFields, only serializes Allowed events at Info verbosity, and does
not include request content); update the comment to accurately reflect what this
class actually does (state it extends DefaultAuditLogSerializer, mention which
field groups are included, the verbosity behavior for Allowed events, and
whether request content is captured) and remove the misleading statements so
users aren’t misinformed.
🚀New (ES) added new audit serializers - ReportingAllEventsAuditLogSerializer, ReportingAllEventsWithQueryAuditLogSerializer
🚀New (ES) There is an option to define custom audit serializer in config, without implementation
🐞Fix (ES) Restored backwards compatibility of custom audit log serializer implementations, that extend the
DefaultAuditLogSerializer
class. The custom serializers compiled against ROR 1.65 and 1.66, that useDefaultAuditLogSerializer
have to be recompiled in order to work.Summary by CodeRabbit
New Features
Changes