From c14a1b8c0dc7783f124dbeeaad8d091dc86a0ee7 Mon Sep 17 00:00:00 2001 From: Andrei Dulvac Date: Thu, 30 Jul 2026 12:47:25 +0200 Subject: [PATCH 1/6] OAK-12331: document the audit SPI Adds two pages under the security section: a consumer guide covering the event model, the two producer paths, the commit metadata keys, the trust model and the listener contract; and a design document covering the pipeline internals, OSGi and embedded wiring, and the threading rules the implementation relies on. Both are linked from the security overview page and the site menu. The pages describe the SPI added by this issue, so they are written against that implementation rather than as a proposal. --- .../markdown/security/audit-commit-flow.png | Bin 0 -> 138781 bytes .../site/markdown/security/audit-design.md | 435 +++++++++++++++++ .../markdown/security/audit-lifecycle.png | Bin 0 -> 68046 bytes .../site/markdown/security/audit-pipeline.png | Bin 0 -> 76458 bytes oak-doc/src/site/markdown/security/audit.md | 437 ++++++++++++++++++ .../src/site/markdown/security/overview.md | 1 + oak-doc/src/site/site.xml | 3 + 7 files changed, 876 insertions(+) create mode 100644 oak-doc/src/site/markdown/security/audit-commit-flow.png create mode 100644 oak-doc/src/site/markdown/security/audit-design.md create mode 100644 oak-doc/src/site/markdown/security/audit-lifecycle.png create mode 100644 oak-doc/src/site/markdown/security/audit-pipeline.png create mode 100644 oak-doc/src/site/markdown/security/audit.md diff --git a/oak-doc/src/site/markdown/security/audit-commit-flow.png b/oak-doc/src/site/markdown/security/audit-commit-flow.png new file mode 100644 index 0000000000000000000000000000000000000000..3c78c3692b8ee3bbf3ef138fd5298955d8d3cfcf GIT binary patch literal 138781 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%0Dxhv`~fk{Xy6&6B7pr-C$wBy!Fu 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�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

+P5puB$7m;*xEu^8Zq7K>mh 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 A=Kufz literal 0 HcmV?d00001 diff --git a/oak-doc/src/site/markdown/security/audit-design.md b/oak-doc/src/site/markdown/security/audit-design.md new file mode 100644 index 00000000000..873ac9f78e2 --- /dev/null +++ b/oak-doc/src/site/markdown/security/audit-design.md @@ -0,0 +1,435 @@ + + +Audit Pipeline Design +-------------------------------------------------------------------------------- + +This document describes the design of Oak's audit pipeline: the SPI surface +in `oak-core-spi`, the security-domain constants in `oak-security-spi`, the +pipeline implementation in `oak-core`, OSGi and embedded wiring, and the +threading and ordering rules the implementation relies on. + +For the consumer-facing guide (event model, listener contract, trust model), +see [Audit SPI](audit.html). + + +### Overview + +The audit pipeline transports structured `AuditEvent`s from producers to +bundle-registered `AuditEventListener` consumers, gated by a feature toggle +and a per-domain listener registry. + +There are two delivery paths: + +- **Commit-attached.** Oak-internal capture sites (e.g. `UserManagerImpl`) + call `AuditEvents.record(root, event)`. Events land in a per-session + `ThreadLocal` buffer (`AuditBuffer`), and a `NodeStore` `Observer` + (`AuditDrainObserver`) drains and dispatches them after the surrounding + `Root.commit()` durably persists. At drain time each event is decorated + with `commit.sessionId`, `commit.userId`, and `commit.timestamp` payload + entries; a failed commit drops the buffer. +- **Fire-and-forget.** Any OSGi bundle resolves `AuditEventEmitter` via + `@Reference` and calls `emit(event)`. The event is dispatched synchronously + on the calling thread: no buffering, no commit boundary, no payload + decoration. Caller-supplied values for the three reserved `commit.*` + attestation keys are stripped before delivery (the trust contract on + `AuditEvent#getPayload()` is the normative statement). + +Both paths converge on `AuditEventListener.onEvents(List)` and +share one listener registry. Failure isolation is layered: an outer +`Throwable` barrier in `AuditDrainObserver.contentChanged` keeps audit from +masquerading as a commit failure, and an inner per-listener `Throwable` +barrier on both paths keeps one misbehaving listener from stopping the +others. + +Pipeline state is owned by `AuditConfigurationImpl` in `oak-core`, which +holds the feature toggle, the buffer, the listener registry, the sink +installed into the `AuditEvents` facade, and the singleton drain observer. +It is registered as an OSGi service of type `AuditConfiguration`. Audit is a +top-level Oak concern, not a `SecurityConfiguration`. + + +### Pipeline diagram + +![Audit pipeline](audit-pipeline.png) + +The upper row is the commit-attached path, the lower row fire-and-forget. +They converge on the listener registry, which filters by domain and orders by +rank before invoking each listener. + +On the commit-attached path, `BufferSink.record` gates on the feature toggle +and on whether any listener is registered for the event's domain, so a +capture site allocates nothing when audit is off. The observer runs on the +commit thread once the merge has persisted, drains the buffer for that +session, and stamps the three `commit.*` keys. On the fire-and-forget path, +`BufferSink.dispatch` applies the same toggle and listener gates, strips +caller-supplied `commit.*` values, and dispatches inline. + +The short-circuit order in the observer, and the exception barriers on both +paths, are described under Implementation below. + + +### Commit flow + +![Commit flow](audit-commit-flow.png) + +The observer fires synchronously on the commit thread, after durable +persistence and before `store.merge` returns. That is the property the +per-session buffer depends on: the drain has to happen on the thread that +filled it. Every production `NodeStore` notifies observers that way, though +not all by the same route. The document and composite stores dispatch +through `ChangeDispatcher`; `MemoryNodeStore` iterates its registered +observers directly from `setRoot`. Either way the notification completes +before `merge` returns. + +Two segment-store configurations are worth knowing about, because in both the +commit-attached path silently produces nothing. `SegmentNodeStore.addObserver` +returns a no-op handle unless change dispatch is enabled, and an observer +attached through that handle is never notified. That applies to a +cold-standby instance, where the primary store turns dispatch off, and to a +store configured through `SegmentNodeStoreFactory`, where dispatch is off +unless `dispatchChanges` is set explicitly. + +Draining from an `Observer` rather than from a commit hook has two +consequences worth spelling out. Events never transit the `CommitContext`, +which is a shared string-keyed channel readable by any `CommitHook` in the +same commit; keeping audit events out of it avoids a class of cross-bundle +information disclosure. And dispatch happens only after the commit is +durable, so there is no window in which a listener sees an event for a +write that subsequently fails. + + +### SPI layout + +#### oak-core-spi + +Package `org.apache.jackrabbit.oak.spi.audit` holds the domain-neutral SPI: + +| Type | Role | +|---|---| +| `AuditEvent` | Event interface: domain, type, timestamp, payload. Static factory `AuditEvent.of(...)`. | +| `AuditEventListener` | Consumer SPI: `onEvents(List)`, scoped to one domain via `getDomain()`, ordered by `getRank()`. | +| `AuditEventEmitter` | OSGi service surface for fire-and-forget emission from any bundle. | +| `AuditEvents` | Static facade: `record(root, event)` and `dispatch(event)`, routing to the installed `Sink`; `isEnabled()` / `isEnabledFor(domain)` gates. | +| `AuditEvents.Sink` | SPI implemented by the pipeline. `AuditConfigurationImpl` installs a `BufferSink`. | +| `AuditBufferLifecycle` | Session lifecycle callouts: drain on refresh and on commit failure. | +| `AuditConfiguration` | Typed handle on pipeline state (`isActive()`, `NOOP`). | + +`AuditConfiguration.isActive()` returns `true` when the feature toggle is +enabled and at least one listener is registered. The two predicates AND +together so a deployed-but-unused pipeline reports `false`, matching the +no-allocation semantics of `AuditEvents.isEnabled()`. Both read the same +volatile sink state, so they cannot drift apart. The interface ships a +`NOOP` constant for callers that want a guaranteed-non-null handle. + +Cardinality is unary optional: multiple `AuditConfiguration` implementations +are not supported. The buffer lifecycle is a singleton install, and two +observers on the same root `NodeStore` would each produce a dispatch. +Multiplexing belongs at the listener layer. + +#### oak-security-spi + +Security-domain constants live next to the SPI they describe: + +- `spi/security/audit/SecurityAuditDomain` holds the single domain string + `"oak.security"` shared by all events Oak's security stack emits. The + `oak.` prefix namespaces the domain so listeners in mixed deployments + (Sling, application bundles) can tell Oak's security events apart from + same-named domains defined by other layers. +- `spi/security/user/UserAuditTypes` holds the user-membership vocabulary: + type strings (`MEMBER_ADDED`, `MEMBER_REMOVED`) and payload keys + (`PAYLOAD_GROUP_PATH`, `PAYLOAD_MEMBER_IDS`, `PAYLOAD_MEMBER_PATHS`, + `PAYLOAD_MEMBERSHIP_SOURCE`, `PAYLOAD_IS_CONTENT_ID`, + `PAYLOAD_FAILED_IDS`). A single and a bulk membership change share the + same type; a bulk change is one whose `PAYLOAD_MEMBER_IDS` list holds more + than one entry. + +Future ACL, principal, or token events declare their own `*AuditTypes` +classes in the respective SPI sub-packages. + +Producer-side factories are deliberately not part of the SPI. They live as +package-private classes next to their only callers, e.g. +`UserAuditEvents` next to `UserManagerImpl` in `oak-core`. The asymmetry +(read-side vocabulary public, write-side factories impl-private) raises the +bar for casually forging Oak-attested events, but it is not a hard boundary: +any bundle can call `AuditEvent.of(domain, type, payload)` directly. +Listeners that need to distinguish Oak-attested commit-attached events from +fire-and-forget emissions check for the three reserved `commit.*` payload +keys, per the trust contract on `AuditEvent#getPayload()`. + + +### Implementation (oak-core) + +| Component | Role | +|---|---| +| `AuditBuffer` | `ThreadLocal` per-session staging area, keyed by `ContentSession` id. Caps a session at 10,000 staged events: past that, further events are dropped and one WARN is logged for the session rather than one per event. The cap re-arms on the next drain, refresh, or commit failure, so it bounds the memory a single large or non-committing session can pin. | +| `BufferSink` (inner class of `AuditConfigurationImpl`) | The installed `AuditEvents.Sink`. Gates on the feature toggle and listener presence, buffers on `record`, dispatches inline on `dispatch`. | +| `AuditDrainObserver` | `Observer` that drains the buffer on commit success. Carries the outer and inner `Throwable` barriers. | +| `CommitMetadataDecorator` | Stamps the three reserved `commit.*` entries at drain time (commit-attached) and strips caller-supplied values for the same keys at dispatch (fire-and-forget). | +| `AuditEventEmitterImpl` | OSGi `@Component` implementing `AuditEventEmitter`; delegates to `AuditEvents.dispatch`. | +| `WhiteboardAuditEventListenerRegistry` | Tracks `AuditEventListener` services on the Whiteboard. `getListeners()` returns them sorted by rank descending; `hasListenerFor(domain)` backs the pre-allocation gate. | +| `AuditConfigurationImpl` | Pipeline owner: feature toggle, buffer, registry, sink, drain observer. Published as `AuditConfiguration`. | + +#### AuditDrainObserver + +The observer's `contentChanged(root, info)` short-circuits on +`CommitInfo.isExternal()`, then drains the buffer for `info.getSessionId()`. +If events came out and the toggle is still enabled, it decorates them via +`CommitMetadataDecorator`, groups them by domain, and dispatches each group +to the listeners registered for that domain, in rank order. + +The drain runs before the toggle check, not after. Draining unconditionally +means a toggle flip between capture and commit discards the staged events +cleanly; checking the toggle first would leave them in the buffer, where a +later commit on the same session would pick them up and stamp them with the +wrong commit metadata. + +Three rules govern this class: + +- **Outer `Throwable` barrier.** `CompositeObserver` iterates its observers + with no per-observer isolation, and the `NodeStore` implementations invoke + the observer chain after the commit is already durable. An exception + escaping `contentChanged` would therefore surface as a commit failure to + the merge caller even though the commit succeeded, and could mask other + observers' work. The entire method body runs inside a + `try { ... } catch (Throwable t) { log.warn(...); }`. +- **Inner per-listener barrier.** Each listener dispatch is individually + wrapped, also at `Throwable` width, so a listener throwing a + `LinkageError` or similar does not stop the remaining listeners. The same + isolation covers the `getDomain()` / `getRank()` accessors consulted + during routing. +- **Never wrap in `BackgroundObserver`.** The async wrapper replaces the + latest queued entry with `CommitInfo.EMPTY_EXTERNAL` on queue overflow, + which discards the session id. The drain keys exclusively on + `CommitInfo.getSessionId()` to find the per-thread buffer, so losing the + session id silently loses audit events for high-rate writers. Synchronous + dispatch is mandatory, and the buffer's `ThreadLocal` semantics require + draining on the capturing thread anyway. + +The external-commit short-circuit covers cluster sync from peer nodes, the +synthetic replay invocation that `Observable.addObserver` makes at +registration time, and external head movement in the segment store. By +construction the buffer is empty for external commits (no local capture site +fired), so the explicit gate is defense in depth rather than a correctness +requirement. + +#### Session lifecycle and buffer draining + +The observer only sees successful commits. `MutableRoot` covers the other +paths through `AuditBufferLifecycle` callouts: + +| Case | Who drains the buffer | +|---|---| +| `Root.commit()` succeeds | `AuditDrainObserver.contentChanged` | +| `Root.commit()` fails (merge throws) | `MutableRoot.commit` finally block, via `AuditBufferLifecycle.onCommitFailed` | +| `Root.refresh()` | `MutableRoot.refresh`, via `AuditBufferLifecycle.onRefresh` | +| Pipeline shutdown while sessions are mid-flight | `AuditConfigurationImpl.dispose`, via `buffer.clearAll()` | + +`Root.rebase()` intentionally does not drain: rebase preserves transient +changes, so the audit events staged alongside them survive and are +dispatched when the session eventually commits. + +The lifecycle callouts always fire; they are not gated on the toggle or on +listener presence. Gating them would open a race: events captured while the +toggle is on, a toggle flip to off, and a skipped drain on the next lifecycle +transition would leave stale events in the buffer to be dispatched against a +later commit with that commit's metadata. When no pipeline is installed the +callout is one volatile read plus a virtual call into a no-op listener, so +the always-fire shape costs nothing measurable. + +`AuditEvents.record(root, event)` requires that `root` is the `MutableRoot` +of an active JCR session, since the lifecycle callouts above are what keep +the buffer consistent. Non-JCR commits must not call it. + + +### OSGi wiring + +`AuditConfigurationImpl` is declared as +`@Component(service = AuditConfiguration.class)`. It takes no reference to +the `NodeStore` or to `Observable`. Instead it follows Oak's established +observer-registration idiom (the same one the Lucene index observer uses): +`@Activate` registers the drain observer as an `Observer` service on the +`BundleContext`, and the `ObserverTracker` that each NodeStore service runs +picks the service up and subscribes it to the root `NodeStore`. This keeps +the audit bundle decoupled from store selection; composite deployments get +the same root store the rest of the stack uses. + +Activation wires the pipeline internals first and publishes the `Observer` +service last; deactivation unregisters that service first and only then tears +the internals down: + +![Activation and deactivation order](audit-lifecycle.png) + +Registering the observer last means a commit thread racing with activation +either misses the observer entirely (events stay buffered for the next +commit) or sees a fully wired pipeline. Unregistering it first means +`ObserverTracker` closes the subscription before anything is dismantled, so +no further `contentChanged` call reaches a half-torn-down buffer or registry. + +Detach first, tear down internals second: the same shape as +`ChangeProcessor` in `oak-jcr`. `dispose()` checks that the observer service +has been unregistered and fails loudly otherwise, turning an out-of-order +teardown into an error instead of a dangling observer subscription over +torn-down state. The drain observer is constructed once in `initialize` and +zeroed in `dispose`; `getDrainObserver()` throws `IllegalStateException` +outside that window. It is a singleton by design: two observer instances +sharing one buffer would double-dispatch. + + +### Embedded (non-OSGi) wiring + +Embedded callers (tests, `oak-run` tooling, custom embeds) wire the pipeline +explicitly. Several of the types below, including `AuditConfigurationImpl` +and `SecurityProviderBuilder`, live in packages oak-core does not export, so +this path is available to code on a flat classpath rather than to a bundle +running inside an OSGi framework; there, use the DS service instead. + +```java +MemoryNodeStore store = new MemoryNodeStore(); +DefaultWhiteboard whiteboard = new DefaultWhiteboard(); + +AuditConfigurationImpl audit = new AuditConfigurationImpl(); +audit.initialize(whiteboard); // toggle, registry, buffer, sink + +// The toggle is created disabled. Flip it on through the FeatureToggle +// that initialize() registered, or the pipeline stays silent. +Tracker toggles = whiteboard.track(FeatureToggle.class); +try { + for (FeatureToggle ft : toggles.getServices()) { + if (AuditConfigurationImpl.FEATURE_TOGGLE_NAME.equals(ft.getName())) { + ft.setEnabled(true); + } + } +} finally { + toggles.stop(); +} + +// Register listeners before driving any commit. +whiteboard.register(AuditEventListener.class, new MyListener(), Map.of()); + +Closeable observerHandle = store.addObserver(audit.getDrainObserver()); + +SecurityProvider securityProvider = SecurityProviderBuilder.newBuilder() + .withWhiteboard(whiteboard) + .build(); + +ContentRepository repo = new Oak(store) + .with(new InitialContent()) // required: security setup needs jcr:system + .with(securityProvider) + .with(whiteboard) + .createContentRepository(); + +// ... drive commits ... + +observerHandle.close(); // detach observer first, as in OSGi teardown +if (repo instanceof Closeable) { + ((Closeable) repo).close(); // ContentRepository itself declares no close() +} +audit.dispose(); +``` + +Four things in that sequence are easy to get wrong. The toggle starts +disabled, so a pipeline that is otherwise wired correctly dispatches nothing +until something enables it. `InitialContent` is needed because the security +setup expects `jcr:system` to exist. Listeners have to be registered before +the commits you want to capture, since the capture gate checks for a listener +on the event's domain. And `ContentRepository` declares no `close()`, so the +teardown has to test for `Closeable`. + +The explicit `addObserver` call is required. `Oak.with(Observer)` relies on +an auto-attach side effect of Oak's default whiteboard, and that side effect +is lost as soon as the embedder replaces the whiteboard via +`Oak.with(Whiteboard)`. Sharing one whiteboard between audit and Oak is the +common case for embedded setups (listener registrations and the audit +tracker should see the same whiteboard), so the safe path is always the +direct `Observable.addObserver(...)`. OSGi deployments are unaffected: their +subscription runs through `ObserverTracker`, not through the default +whiteboard. + + +### Migration commits + +Migration tooling (`oak-upgrade`) calls `NodeStore.merge(...)` directly, +bypassing `MutableRoot` and the capture sites. Migration tools do not set the +pipeline up, so when one runs standalone there is no observer attached and no +audit machinery on the path at all. Run inside a container where audit is +deployed, the observer does fire on migration commits, finds an empty buffer +for the session id, and returns. Either way migration mutations are not +audited; if that is ever wanted, it is a capture-site addition, not a +pipeline change. + + +### Design rules + +The rules the implementation is built on, in one place: + +1. **Observers fire synchronously on the commit thread for local commits.** + Every production store notifies observers before `merge` returns, whether + through `ChangeDispatcher` or, as in `MemoryNodeStore`, by iterating its + observers directly. The per-thread buffer depends on this. +2. **Observers fire after durable persistence, or not at all.** A failed + merge never reaches the observer, so a dispatched event always + corresponds to a persisted write. +3. **External commits are ignored at observer entry.** One predicate covers + cluster sync, the `addObserver` replay, and external head movement. +4. **The buffer key equals `CommitInfo.getSessionId()`.** `MutableRoot` + sets the commit info's session id from the `ContentSession`, which is the + same key the sink used at capture time. +5. **`CompositeObserver` provides no per-observer isolation.** Hence the + outer `Throwable` barrier in `contentChanged`. +6. **No ordering guarantee among observers.** Audit does not depend on + observer order; listener order within the audit dispatch is defined by + `getRank()`. +7. **Never wrap the drain observer in `BackgroundObserver`.** Queue overflow + replaces the commit info with `CommitInfo.EMPTY_EXTERNAL`, losing the + session id and with it the buffered events. +8. **Audit never masquerades as a commit failure.** The outer barrier + guarantees `contentChanged` returns normally no matter what the drain, + the decorator, or a listener does. +9. **Lifecycle callouts are unconditional.** Gating them on pipeline state + opens the stale-event race described above. + +Two consequences of the destructive `ThreadLocal` drain are worth noting. +When a composite store causes the observer to be invoked twice for one +merge, the first invocation drains the buffer and the second finds it empty +and returns, so double-dispatch dedupes itself. And because `clearAll()` +removes only the calling thread's `ThreadLocal` entry, disposing the +pipeline while other threads hold sessions mid-flight leaves their staged +events behind; that residue is bounded by the per-session cap and released +when the thread is reused or discarded. + + +### Performance characteristics + +With audit off (toggle disabled, or no listener registered for the domain), +capture sites short-circuit at `AuditEvents.isEnabledFor(domain)` before +constructing an event: no allocation, no buffer touch. The check is a +volatile read of the installed sink and the toggle, and, when the toggle is +on, a linear scan of the registered listeners comparing each `getDomain()` +against the requested domain. Deployments carry a handful of listeners, so +the scan stays cheaper than maintaining a domain index. The per-commit cost +of a deployed-but-idle pipeline is the external-commit check plus an empty +buffer lookup in the observer. + +With audit on, the per-event cost is the event allocation, a buffer append, +the drain, three decorator entries, and the listener dispatch itself. +Benchmarks in `oak-benchmarks` cover both shapes: the pipeline running with +no capture site firing, and the full captured-event path. In both, the +overhead sits below the resolution of the surrounding commit machinery, so +turning audit on does not measurably change commit throughput. Listener work +is on top of that and belongs to the listener; implementations that do I/O +are expected to hand off to their own async executor. diff --git a/oak-doc/src/site/markdown/security/audit-lifecycle.png b/oak-doc/src/site/markdown/security/audit-lifecycle.png new file mode 100644 index 0000000000000000000000000000000000000000..5a0d8e128a33995d1fd59b0a5094a3fb999105f2 GIT binary patch literal 68046 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 bZ8L2`c}6C2OrbM3w~IG607T-tj-h`7%1h^G literal 0 HcmV?d00001 diff --git a/oak-doc/src/site/markdown/security/audit.md b/oak-doc/src/site/markdown/security/audit.md new file mode 100644 index 00000000000..501679f5591 --- /dev/null +++ b/oak-doc/src/site/markdown/security/audit.md @@ -0,0 +1,437 @@ + + +Audit SPI +-------------------------------------------------------------------------------- + +### General + +The Oak audit SPI records structured events about repository activity and +dispatches them to in-process consumers. Listeners are registered on the OSGi +Whiteboard and invoked synchronously when events are produced. Typical +consumers forward events to a SIEM, write to a compliance archive, or apply +runtime policy. + +The SPI is small: an event type, a listener interface, and an emitter service. +It does not prescribe transport, persistence, or out-of-process delivery. +Those are listener concerns. + +Two producer paths feed a single listener registry: + +- A **commit-attached** path used by Oak-internal capture sites, currently + group membership changes in the user-management implementation. Events are + buffered for the duration of a session write, drained on successful + `Root.commit()`, and decorated with commit metadata before dispatch. Events + are dropped if the commit fails. +- A **fire-and-forget** path exposed to any OSGi bundle through the + [AuditEventEmitter] service. Events are dispatched immediately on the + calling thread. They are not tied to a commit and are not buffered. + +Both paths converge on the same `AuditEventListener.onEvents(List)` +method, so a single listener can consume Oak-internal security events and +bundle-emitted custom events through one entry point. + + +### Module layout + +| Module | Role | +|---|---| +| `oak-core-spi` | Domain-neutral SPI: [AuditEvent], [AuditEventListener], [AuditEventEmitter], the `AuditEvents` static facade, and [AuditConfiguration] (typed handle on the pipeline's runtime state). | +| `oak-security-spi` | Security-domain constants: `SecurityAuditDomain.NAME` (the `"oak.security"` domain string) and per-sub-domain type-string classes such as `UserAuditTypes` in the `spi.security.user` package. | +| `oak-core` | Pipeline implementation: listener registry, commit-attached buffer, the observer that drains it on commit success, the emitter, and the configuration component. | + +Consumer bundles depend on `oak-core-spi` only. Implementing a listener or +emitting events requires no dependency on `oak-core`, `oak-jcr`, or +`oak-security-spi`. + + +### Event model + +#### AuditEvent + +```java +public interface AuditEvent { + @NotNull String getDomain(); + @NotNull String getType(); + long getTimestamp(); + @NotNull Map getPayload(); +} +``` + +- **Domain**: namespace identifying the event source category. Oak's security + stack uses `"oak.security"` (defined by `SecurityAuditDomain.NAME`). Bundles + defining new event types choose their own domain string; the SPI imposes no + schema. +- **Type**: stable identifier within the domain, e.g. `"membership.added"`. + Consumers dispatch on it. +- **Timestamp**: milliseconds since epoch at event construction time. +- **Payload**: open map of supplementary data. Consumers MUST tolerate missing + keys; producers MAY add keys without versioning. + +The public SPI keeps only the `AuditEvent` interface. Concrete events are +built with the static factory `AuditEvent.of(domain, type, payload)`, and +consumers discriminate events by `getDomain()` plus `getType()` rather than by +`instanceof` checks. + +The `oak.security` domain pins its type strings and payload keys in +per-sub-domain classes next to the security area they describe. User-membership +constants live in `UserAuditTypes` in the `spi.security.user` package +(`MEMBER_ADDED`, `PAYLOAD_GROUP_PATH`, and so on). Bundles emitting custom +events implement `AuditEvent` directly or call `AuditEvent.of(...)` with their +own domain string. + + +#### Commit metadata payload keys + +Events produced by the commit-attached pipeline are decorated at drain time +with three additional payload entries: + +| Key | Value | Source | +|---|---|---| +| `commit.sessionId` | session identifier of the writing session | `CommitInfo.getSessionId()` | +| `commit.userId` | acting user id (`CommitInfo.OAK_UNKNOWN`, i.e. `"oak:unknown"`, for system commits) | `CommitInfo.getUserId()` | +| `commit.timestamp` | commit timestamp in milliseconds since epoch | `CommitInfo.getDate()` | + +Events arriving through the fire-and-forget pipeline cannot carry these keys: +Oak strips caller-supplied values for exactly these three at dispatch. For +events delivered through Oak dispatch, their presence is therefore a reliable +commit-attached signal. The Javadoc on `AuditEvent#getPayload()` is the +normative statement of this contract. Consumers that need to tell the two +sources apart inspect for `commit.sessionId`. The `commit.userId` value +`"oak:unknown"` is a deliberate anonymity marker for system commits; listeners +MUST NOT attempt to resolve it to a real user. + + +### Pipelines + +#### Commit-attached pipeline + +Used by Oak-internal capture sites in the user-management implementation. Events +are buffered against the writing session and only dispatched when +`Root.commit()` succeeds, strictly **after** durable persistence rather than +inside the commit hook chain. If validators reject the commit or the merge +fails, the buffered events are discarded. + +The dispatch sequence: + +1. A capture site appends an event to the per-session buffer. +2. The session calls `Root.commit()`; commit hooks and validators run; the + merge persists durably. +3. An `Observer` registered by the audit configuration fires on the commit + thread, drains the buffer for the originating session, and decorates each + event with `commit.sessionId`, `commit.userId`, and `commit.timestamp`. +4. The registry sorts listeners by rank, filters by domain, and invokes each + matching listener's `onEvents(List)`. + +Because dispatch happens after durable persistence, a delivered event implies +the corresponding write actually landed. A failed commit never produces an +audit event. + +The converse does not hold, and consumers building a compliance trail need to +know it. The per-session buffer is capped, so a session that records more +than 10,000 events before committing has its later events dropped, with a +single WARN logged for that session rather than one per dropped event. A +persisted write can therefore leave no audit event behind. The cap exists to +bound the memory one runaway session can pin; it resets on the next commit, +refresh, or commit failure. Treat that WARN as a gap in the trail. + +This path is internal to Oak; bundles that want to record their own events use +the fire-and-forget pipeline below. + +#### Fire-and-forget pipeline + +Available to any OSGi bundle that wants to record an event for its own domain. +Events fire immediately on the calling thread; there is no buffering and no +rollback: + +1. The caller resolves `AuditEventEmitter` via `@Reference`. +2. The caller gates allocation with `isEnabledFor(domain)`. +3. The caller invokes `emit(event)`. +4. The registry sorts listeners by rank, filters by domain, and invokes each + matching listener's `onEvents(List)`. + +Properties: + +- **No commit boundary.** The event is dispatched as soon as `emit` is called; + subsequent JCR operations do not affect it. +- **Synchronous on the calling thread.** Listeners performing I/O are + responsible for wrapping themselves in an async dispatcher. +- **Per-listener isolation.** Exceptions thrown by one listener, whether from + `onEvents` or from the `getDomain()` / `getRank()` accessors consulted + during routing, are logged and swallowed; remaining listeners still run. + `emit` never propagates a listener exception back to the caller. +- **No payload decoration, but reserved keys are stripped.** No `commit.*` + keys are added; caller-supplied values for the three reserved attestation + keys (`commit.sessionId`, `commit.userId`, `commit.timestamp`) are removed + before delivery. Every other entry reaches listeners exactly as the caller + provided it. + + +### Configuration + +The pipeline is gated by a feature toggle and is **off by default**. Nothing +is captured or dispatched until the toggle is enabled, which keeps the cost +of a deployed-but-unused pipeline at zero. + +Registering a listener is not enough on its own. Both conditions have to +hold: the toggle is enabled, and at least one listener is registered for the +event's domain. Enable the toggle the same way as any other Oak feature +toggle, through the `FeatureToggle` service published on the Whiteboard; the +[OSGi configuration](../osgi_config.html) page describes the mechanism under +Feature Toggles. For a worked example of locating this toggle and flipping +it, see the embedded wiring snippet in +[Audit Pipeline Design](audit-design.html). + +`AuditConfigurationImpl` in `oak-core` owns the pipeline and is published as +an OSGi service of type `AuditConfiguration`. It carries an OSGi +object-class definition, so it appears in the Felix console alongside Oak's +other components. + + +### Probing pipeline state + +Components can ask whether the audit pipeline is currently active via +[AuditConfiguration]`.isActive()`, without depending on the implementation +class. `AuditConfiguration` is an OSGi service; resolve it via a DS +`@Reference`: + +```java +@Component(service = MyComponent.class) +public class MyComponent { + + @Reference + private AuditConfiguration audit; + + public void doWork() { + if (audit.isActive()) { + // Feature toggle is ON and at least one listener is registered. + // Safe to do work that only matters when audit will actually + // dispatch (e.g. allocate richer payload context). + } + } +} +``` + +`AuditConfiguration` is published as an OSGi service only. Embedded callers +(tests, `oak-run` tools) use `AuditEvents.isEnabled()` on the static facade +instead, which evaluates the same two conditions. + +`isActive()` returns `true` when the audit feature toggle is enabled AND at +least one `AuditEventListener` is registered on the Whiteboard. A +deployed-but-unused pipeline (toggle ON, no listener registered) reports +`false`, matching the no-allocation semantics of `AuditEvents.isEnabled()`. +The NOOP `AuditConfiguration`, returned when no implementation is bound at +all, reports `false`. + +Note that audit is a top-level Oak concern, not a `SecurityConfiguration`: +`AuditConfiguration` is not reachable via +`SecurityProvider.getConfiguration(...)`. Use a `@Reference` to +`AuditConfiguration`. + + +### User-API-level audit, not a transaction log + +Oak's audit SPI captures activity at the level of user API calls, not at the +level of the transaction log. The distinction matters when choosing whether +the audit SPI fits a given use case. + +- **What fires audit events:** capture sites in Oak's user-management + implementation. Group membership changes record member add/remove events. + The usual route is a `Group.addMember(...)` / `.removeMember(...)` call from + the Jackrabbit user-management API, but the same capture site also covers + membership applied by the protected-item importer during XML import, which + reaches it without any user-facing API call. Equivalent capture sites can + cover other security-relevant areas. +- **What does NOT fire audit events:** changes made by commit hooks, editors, + or validators during commit processing. If a hook transforms the tree in + flight (autocreated properties, denormalised indexes, side-effect writes + from a `Validator` or `Editor`), those tree changes are not recorded even + though they end up in the merged `NodeState`. + +This is intentional. The audit SPI answers "who called the API", which is the +right level for security audit, compliance trails, and "who removed user X +from group Y" investigations. It does not enumerate every node mutation that +landed in the merged commit. + +Consumers needing every node mutation (event sourcing, change-data capture, +derived index rebuilding) should use Oak's `NodeStore.addObserver(...)` / +`BackgroundObserver` mechanism instead. Those observers see the post-merge +`NodeState` diff and capture mutations regardless of which API surface or +commit hook produced them. The audit SPI and a `NodeStore` observer answer +different questions; deploy the one that matches your use case. + + +### Emitting events from a bundle + +Bundles emit events through the [AuditEventEmitter] OSGi service. A single +implementation is registered by `oak-core`. + +```java +@Component +public class ContentPublishAuditor { + + @Reference + private AuditEventEmitter audit; + + public void onPublished(String path, String variant) { + if (audit.isEnabledFor("example.content")) { + audit.emit(new ContentPublishedEvent(path, variant)); + } + } +} +``` + +The `isEnabledFor` gate short-circuits when no listener is registered for the +domain, so callers can skip event construction on hot paths. The check is +cheap; producers SHOULD use it. + +A minimal event implementation: + +```java +class ContentPublishedEvent implements AuditEvent { + + private final String path; + private final String variant; + private final long timestamp = System.currentTimeMillis(); + + ContentPublishedEvent(String path, String variant) { + this.path = path; + this.variant = variant; + } + + @Override public String getDomain() { return "example.content"; } + @Override public String getType() { return "content.published"; } + @Override public long getTimestamp() { return timestamp; } + @Override public Map getPayload() { + return Map.of("path", path, "variant", variant); + } +} +``` + +Events emitted this way are not tied to a JCR session or commit. The caller +need not hold a `Session` or `Root`, so lifecycle events such as workflow +transitions, replication outcomes, or background-job completion are valid +producers. + + +### Implementing a listener + +A listener is an OSGi component registered as a service of type +[AuditEventListener]. The Whiteboard registry discovers it automatically. + +```java +@Component(service = AuditEventListener.class) +public class SiemForwarder implements AuditEventListener { + + @Override + public String getDomain() { + return "oak.security"; + } + + @Override + public int getRank() { + return 0; + } + + @Override + public void onEvents(List events) { + for (AuditEvent e : events) { + Map p = e.getPayload(); + String sessionId = (String) p.get("commit.sessionId"); + String userId = (String) p.get("commit.userId"); + siem.forward(e, sessionId, userId); + } + } +} +``` + +Contract notes: + +- **`getDomain()`** is queried on every dispatch and MUST return a stable, + non-null value across the listener's lifetime. A listener subscribes to + exactly one domain. To consume multiple domains, register multiple listener + components. +- **`getRank()`** orders listeners within a domain, higher rank first, default + 0. Useful when one listener must observe state set by another (for example, + a redaction listener running before a SIEM forwarder). +- Both accessors are treated as listener code. A listener whose `getDomain()` + or `getRank()` throws is skipped for that dispatch and picked up again once + the accessor stops throwing; the failure is logged at WARN the first time + for that listener instance and at DEBUG afterwards, so a broken listener + cannot flood the log. Other listeners are unaffected. +- **`onEvents(List)`** is invoked with a non-empty, non-null list + of events in capture order. The same method serves both pipelines: + commit-attached events arrive in a batch sized by the originating session's + buffer; fire-and-forget events arrive in singleton lists. +- Implementations MUST be non-blocking. Expensive I/O belongs in an async + wrapper owned by the listener. +- Implementations MUST tolerate unknown payload keys and missing optional + keys. The payload schema is open. + + +### Trust model + +The fire-and-forget producer surface is open by design. + +- Any bundle that resolves `AuditEventEmitter` can emit any event for any + domain, including `"oak.security"`. There is no compile-time check, no + reserved domain registry, and no runtime gate on the emitting bundle. +- Listeners therefore receive caller-asserted data. An event arriving through + `onEvents` reflects the emitting bundle's claim, not Oak-verified truth. +- Oak does not verify, sign, or annotate events with their originating + bundle. Consumers that require Oak attestation MUST distinguish events at + the consumer side. + +The distinguishing signal is payload-based and enforced at dispatch: events +produced by the commit-attached pipeline carry the `commit.sessionId`, +`commit.userId`, and `commit.timestamp` keys, unconditionally overwritten from +the commit's `CommitInfo`. Fire-and-forget events cannot carry them, because +Oak strips caller-supplied values for exactly these three keys before +delivery. A SIEM forwarder that treats only the former as Oak-attested +mutations is operating within the contract. The Javadoc on +`AuditEvent#getPayload()` is the normative statement, including the boundaries +of the attestation: it applies to Oak dispatch only and does not survive +re-emission. + +The open surface is a deliberate trade-off. A reserved-domain registry or +typed event subclasses would put Oak in the middle of every producer bundle's +policy decision; the open surface lets any higher-stack bundle emit on its own +schedule and shifts allowlisting to the consumer side, where the deployment +owner already controls listener registration. + +Recommended consumer-side discipline: + +| Need | Approach | +|---|---| +| Distinguish Oak-attested mutations from caller-asserted events. | Inspect for `commit.sessionId` in the payload. Present implies commit-attached; anchor on the three reserved keys, not on the `commit.` prefix in general. | +| Restrict trusted producers. | Maintain a consumer-side allowlist of trusted domain prefixes and reject unknown domains. | +| Compliance audit (Oak-verified writes only). | Subscribe to `"oak.security"` and filter for events carrying the three reserved `commit.*` keys. | + + +### Further Reading + +- [Audit Pipeline Design](audit-design.html): the design document covering + the SPI shape, pipeline internals, OSGi and embedded wiring, threading + invariants, and performance characteristics. +- [OAK-12331](https://issues.apache.org/jira/browse/OAK-12331): the issue + that introduced the audit SPI. + + +[AuditEvent]: /oak/docs/apidocs/org/apache/jackrabbit/oak/spi/audit/AuditEvent.html +[AuditEventListener]: /oak/docs/apidocs/org/apache/jackrabbit/oak/spi/audit/AuditEventListener.html +[AuditEventEmitter]: /oak/docs/apidocs/org/apache/jackrabbit/oak/spi/audit/AuditEventEmitter.html +[AuditConfiguration]: /oak/docs/apidocs/org/apache/jackrabbit/oak/spi/audit/AuditConfiguration.html diff --git a/oak-doc/src/site/markdown/security/overview.md b/oak-doc/src/site/markdown/security/overview.md index e1fd787a8dd..9eb2de246a2 100644 --- a/oak-doc/src/site/markdown/security/overview.md +++ b/oak-doc/src/site/markdown/security/overview.md @@ -22,6 +22,7 @@ The Oak Security Layer * [Introduction to Oak Security](introduction.html) * [Security Reports](reports.html) + * [Audit SPI](audit.html) ### Authentication diff --git a/oak-doc/src/site/site.xml b/oak-doc/src/site/site.xml index 00d2845c724..a37e8ee7ec6 100644 --- a/oak-doc/src/site/site.xml +++ b/oak-doc/src/site/site.xml @@ -78,6 +78,9 @@ under the License. + + + From c7bb95972ecadb2f1003c1b6f480594de43f710a Mon Sep 17 00:00:00 2001 From: Andrei Dulvac Date: Tue, 4 Aug 2026 14:04:44 +0200 Subject: [PATCH 2/6] OAK-12331: address review feedback on the audit SPI docs Follow-up to the review on PR #3058: - Define "capture site" on first use, instead of leaving the term to context. - Say explicitly that the drain hangs off the commit rather than off Session.save(), and name the operations that commit implicitly. - Scope the segment-store dispatch caveat to the segment store, and state that it does not apply to the document or composite stores. - Add a clustering section: events are node-local, what that means for a cluster-wide listener, and where the node id comes from. - Replace the hand-rolled "check for three payload keys" advice with AuditEvents.hasCommitMetadata(event), and publish the key names as constants on AuditEvent. - Add a monitoring section covering the per-domain event meter, the per-listener timer and failure meter, and the dropped-event meter. - Move Design rules to the top of the Implementation chapter and restate its back-references so each rule stands alone. The SPI helper, the key constants, and the metrics are documented here but implemented in the companion PR #3059. --- .../site/markdown/security/audit-design.md | 177 +++++++++++------- oak-doc/src/site/markdown/security/audit.md | 89 +++++++-- 2 files changed, 185 insertions(+), 81 deletions(-) diff --git a/oak-doc/src/site/markdown/security/audit-design.md b/oak-doc/src/site/markdown/security/audit-design.md index 873ac9f78e2..644505de649 100644 --- a/oak-doc/src/site/markdown/security/audit-design.md +++ b/oak-doc/src/site/markdown/security/audit-design.md @@ -33,15 +33,20 @@ The audit pipeline transports structured `AuditEvent`s from producers to bundle-registered `AuditEventListener` consumers, gated by a feature toggle and a per-domain listener registry. +A *capture site* is a place in Oak's own code that records an audit event. +Today the only ones are in `UserManagerImpl`, on group membership add and +remove. The term is used throughout this document for that kind of call +site, as distinct from a bundle emitting its own events. + There are two delivery paths: - **Commit-attached.** Oak-internal capture sites (e.g. `UserManagerImpl`) call `AuditEvents.record(root, event)`. Events land in a per-session `ThreadLocal` buffer (`AuditBuffer`), and a `NodeStore` `Observer` - (`AuditDrainObserver`) drains and dispatches them after the surrounding - `Root.commit()` durably persists. At drain time each event is decorated - with `commit.sessionId`, `commit.userId`, and `commit.timestamp` payload - entries; a failed commit drops the buffer. + (`AuditDrainObserver`) drains and dispatches them after the commit that + follows, explicit or implicit, durably persists. At drain time each event + is decorated with `commit.sessionId`, `commit.userId`, and + `commit.timestamp` payload entries; a failed commit drops the buffer. - **Fire-and-forget.** Any OSGi bundle resolves `AuditEventEmitter` via `@Reference` and calls `emit(event)`. The event is dispatched synchronously on the calling thread: no buffering, no commit boundary, no payload @@ -96,13 +101,29 @@ through `ChangeDispatcher`; `MemoryNodeStore` iterates its registered observers directly from `setRoot`. Either way the notification completes before `merge` returns. +The drain hangs off the commit, not off the API call that produced the event, +so operations that persist without an explicit `Session.save()` are covered +too. The buffer is keyed by `CommitInfo.getSessionId()`, which +`MutableRoot.commit` fills from the `ContentSession`, and anything reaching +`MutableRoot.commit` drains it. That covers the commits issued internally by +`Workspace.move` and by `VersionManager.checkin` / `checkout`, none of which +require a `Session.save()` from the caller. `Workspace.move` builds a fresh +`MutableRoot` from `ContentSession.getLatestRoot()`, but it is the same +`ContentSession`, so the buffer key still matches. The one case with no drain +is a write that never goes through `MutableRoot` at all, covered under +Migration commits below. + Two segment-store configurations are worth knowing about, because in both the -commit-attached path silently produces nothing. `SegmentNodeStore.addObserver` -returns a no-op handle unless change dispatch is enabled, and an observer -attached through that handle is never notified. That applies to a -cold-standby instance, where the primary store turns dispatch off, and to a -store configured through `SegmentNodeStoreFactory`, where dispatch is off -unless `dispatchChanges` is set explicitly. +commit-attached path silently produces nothing in the segment store. +`SegmentNodeStore.addObserver` returns a no-op handle unless change dispatch +is enabled, and an observer attached through that handle is never notified. +That applies to a cold-standby instance, where the primary store turns +dispatch off, and to a store configured through `SegmentNodeStoreFactory`, +where dispatch is off unless `dispatchChanges` is set explicitly. Neither +caveat extends to the document or composite stores: +`DocumentNodeStore.addObserver` always returns a live handle, and +`DocumentNodeStore` dispatches through `ChangeDispatcher` in the `merge` +path. Draining from an `Observer` rather than from a commit hook has two consequences worth spelling out. Events never transit the `CommitContext`, @@ -121,10 +142,10 @@ Package `org.apache.jackrabbit.oak.spi.audit` holds the domain-neutral SPI: | Type | Role | |---|---| -| `AuditEvent` | Event interface: domain, type, timestamp, payload. Static factory `AuditEvent.of(...)`. | +| `AuditEvent` | Event interface: domain, type, timestamp, payload. Static factory `AuditEvent.of(...)`. Publishes the three reserved key names as `COMMIT_SESSION_ID`, `COMMIT_USER_ID`, `COMMIT_TIMESTAMP`. | | `AuditEventListener` | Consumer SPI: `onEvents(List)`, scoped to one domain via `getDomain()`, ordered by `getRank()`. | | `AuditEventEmitter` | OSGi service surface for fire-and-forget emission from any bundle. | -| `AuditEvents` | Static facade: `record(root, event)` and `dispatch(event)`, routing to the installed `Sink`; `isEnabled()` / `isEnabledFor(domain)` gates. | +| `AuditEvents` | Static facade: `record(root, event)` and `dispatch(event)`, routing to the installed `Sink`; `isEnabled()` / `isEnabledFor(domain)` gates; `hasCommitMetadata(event)` for the commit-attached check. | | `AuditEvents.Sink` | SPI implemented by the pipeline. `AuditConfigurationImpl` installs a `BufferSink`. | | `AuditBufferLifecycle` | Session lifecycle callouts: drain on refresh and on commit failure. | | `AuditConfiguration` | Typed handle on pipeline state (`isActive()`, `NOOP`). | @@ -168,12 +189,65 @@ package-private classes next to their only callers, e.g. bar for casually forging Oak-attested events, but it is not a hard boundary: any bundle can call `AuditEvent.of(domain, type, payload)` directly. Listeners that need to distinguish Oak-attested commit-attached events from -fire-and-forget emissions check for the three reserved `commit.*` payload -keys, per the trust contract on `AuditEvent#getPayload()`. +fire-and-forget emissions call `AuditEvents.hasCommitMetadata(event)`. + +The helper exists so listeners do not hardcode the key names or re-derive +the rule. It is named for what it checks: all three reserved keys are +present and non-null. Oak does not sign events, so a positive result means +the event came through Oak's commit-attached dispatch, which is exactly the +guarantee the trust contract on `AuditEvent#getPayload()` states, and no +more. The key names themselves are public as `AuditEvent.COMMIT_SESSION_ID`, +`COMMIT_USER_ID`, and `COMMIT_TIMESTAMP`, for listeners that read individual +values rather than testing for attestation. Helper and constants both sit in +`oak-core-spi`, so a listener bundle still depends on that module alone. ### Implementation (oak-core) + +#### Design rules + +The rules the components below are built on: + +1. **Observers fire synchronously on the commit thread for local commits.** + Every production store notifies observers before `merge` returns, whether + through `ChangeDispatcher` or, as in `MemoryNodeStore`, by iterating its + observers directly. The per-thread buffer depends on this. +2. **Observers fire after durable persistence, or not at all.** A failed + merge never reaches the observer, so a dispatched event always + corresponds to a persisted write. +3. **External commits are ignored at observer entry.** One predicate covers + cluster sync, the `addObserver` replay, and external head movement. +4. **The buffer key equals `CommitInfo.getSessionId()`.** `MutableRoot` + sets the commit info's session id from the `ContentSession`, which is the + same key the sink used at capture time. +5. **`CompositeObserver` provides no per-observer isolation.** Hence the + outer `Throwable` barrier in `contentChanged`. +6. **No ordering guarantee among observers.** Audit does not depend on + observer order; listener order within the audit dispatch is defined by + `getRank()`. +7. **Never wrap the drain observer in `BackgroundObserver`.** Queue overflow + replaces the commit info with `CommitInfo.EMPTY_EXTERNAL`, losing the + session id and with it the buffered events. +8. **Audit never masquerades as a commit failure.** The outer barrier + guarantees `contentChanged` returns normally no matter what the drain, + the decorator, or a listener does. +9. **Lifecycle callouts are unconditional.** Gating them on the toggle or on + listener presence would let events captured while the toggle was on stay + in the buffer across a lifecycle transition, to be dispatched later + against an unrelated commit and stamped with that commit's metadata. + +Two consequences of the destructive `ThreadLocal` drain are worth noting. +When a composite store causes the observer to be invoked twice for one +merge, the first invocation drains the buffer and the second finds it empty +and returns, so double-dispatch dedupes itself. And because `clearAll()` +removes only the calling thread's `ThreadLocal` entry, disposing the +pipeline while other threads hold sessions mid-flight leaves their staged +events behind; that residue is bounded by the per-session cap and released +when the thread is reused or discarded. + +#### Components + | Component | Role | |---|---| | `AuditBuffer` | `ThreadLocal` per-session staging area, keyed by `ContentSession` id. Caps a session at 10,000 staged events: past that, further events are dropped and one WARN is logged for the session rather than one per event. The cap re-arms on the next drain, refresh, or commit failure, so it bounds the memory a single large or non-committing session can pin. | @@ -182,7 +256,15 @@ keys, per the trust contract on `AuditEvent#getPayload()`. | `CommitMetadataDecorator` | Stamps the three reserved `commit.*` entries at drain time (commit-attached) and strips caller-supplied values for the same keys at dispatch (fire-and-forget). | | `AuditEventEmitterImpl` | OSGi `@Component` implementing `AuditEventEmitter`; delegates to `AuditEvents.dispatch`. | | `WhiteboardAuditEventListenerRegistry` | Tracks `AuditEventListener` services on the Whiteboard. `getListeners()` returns them sorted by rank descending; `hasListenerFor(domain)` backs the pre-allocation gate. | -| `AuditConfigurationImpl` | Pipeline owner: feature toggle, buffer, registry, sink, drain observer. Published as `AuditConfiguration`. | +| `AuditMonitor` | Wraps the `StatisticsProvider`: per-domain event meter, per-listener timer and failure meter, dropped-event meter. Falls back to a no-op when no provider is bound. | +| `AuditConfigurationImpl` | Pipeline owner: feature toggle, buffer, registry, sink, drain observer, monitor. Published as `AuditConfiguration`. | + +The monitor is resolved as an optional `@Reference` to `StatisticsProvider` +and passed to the components that record: the buffer for dropped events, the +dispatch path for the event meter and the per-listener timer. Recording sits +inside the existing per-listener `Throwable` barrier, so a metrics failure +cannot break a dispatch. The metric names and their operational meaning are +listed under [Monitoring](audit.html#Monitoring). #### AuditDrainObserver @@ -243,13 +325,9 @@ paths through `AuditBufferLifecycle` callouts: changes, so the audit events staged alongside them survive and are dispatched when the session eventually commits. -The lifecycle callouts always fire; they are not gated on the toggle or on -listener presence. Gating them would open a race: events captured while the -toggle is on, a toggle flip to off, and a skipped drain on the next lifecycle -transition would leave stale events in the buffer to be dispatched against a -later commit with that commit's metadata. When no pipeline is installed the -callout is one volatile read plus a virtual call into a no-op listener, so -the always-fire shape costs nothing measurable. +The lifecycle callouts always fire, for the reason given in design rule 9. +The cost of that is negligible: when no pipeline is installed the callout is +one volatile read plus a virtual call into a no-op listener. `AuditEvents.record(root, event)` requires that `root` is the `MutableRoot` of an active JCR session, since the lifecycle callouts above are what keep @@ -372,46 +450,6 @@ for the session id, and returns. Either way migration mutations are not audited; if that is ever wanted, it is a capture-site addition, not a pipeline change. - -### Design rules - -The rules the implementation is built on, in one place: - -1. **Observers fire synchronously on the commit thread for local commits.** - Every production store notifies observers before `merge` returns, whether - through `ChangeDispatcher` or, as in `MemoryNodeStore`, by iterating its - observers directly. The per-thread buffer depends on this. -2. **Observers fire after durable persistence, or not at all.** A failed - merge never reaches the observer, so a dispatched event always - corresponds to a persisted write. -3. **External commits are ignored at observer entry.** One predicate covers - cluster sync, the `addObserver` replay, and external head movement. -4. **The buffer key equals `CommitInfo.getSessionId()`.** `MutableRoot` - sets the commit info's session id from the `ContentSession`, which is the - same key the sink used at capture time. -5. **`CompositeObserver` provides no per-observer isolation.** Hence the - outer `Throwable` barrier in `contentChanged`. -6. **No ordering guarantee among observers.** Audit does not depend on - observer order; listener order within the audit dispatch is defined by - `getRank()`. -7. **Never wrap the drain observer in `BackgroundObserver`.** Queue overflow - replaces the commit info with `CommitInfo.EMPTY_EXTERNAL`, losing the - session id and with it the buffered events. -8. **Audit never masquerades as a commit failure.** The outer barrier - guarantees `contentChanged` returns normally no matter what the drain, - the decorator, or a listener does. -9. **Lifecycle callouts are unconditional.** Gating them on pipeline state - opens the stale-event race described above. - -Two consequences of the destructive `ThreadLocal` drain are worth noting. -When a composite store causes the observer to be invoked twice for one -merge, the first invocation drains the buffer and the second finds it empty -and returns, so double-dispatch dedupes itself. And because `clearAll()` -removes only the calling thread's `ThreadLocal` entry, disposing the -pipeline while other threads hold sessions mid-flight leaves their staged -events behind; that residue is bounded by the per-session cap and released -when the thread is reused or discarded. - ### Performance characteristics @@ -426,10 +464,11 @@ of a deployed-but-idle pipeline is the external-commit check plus an empty buffer lookup in the observer. With audit on, the per-event cost is the event allocation, a buffer append, -the drain, three decorator entries, and the listener dispatch itself. -Benchmarks in `oak-benchmarks` cover both shapes: the pipeline running with -no capture site firing, and the full captured-event path. In both, the -overhead sits below the resolution of the surrounding commit machinery, so -turning audit on does not measurably change commit throughput. Listener work -is on top of that and belongs to the listener; implementations that do I/O -are expected to hand off to their own async executor. +the drain, three decorator entries, the metric updates, and the listener +dispatch itself. Benchmarks in `oak-benchmarks` cover both shapes: the +pipeline running with no capture site firing, and the full captured-event +path. In both, the overhead sits below the resolution of the surrounding +commit machinery, so turning audit on does not measurably change commit +throughput. Listener work is on top of that and belongs to the listener; +implementations that do I/O are expected to hand off to their own async +executor. diff --git a/oak-doc/src/site/markdown/security/audit.md b/oak-doc/src/site/markdown/security/audit.md index 501679f5591..2a4005017da 100644 --- a/oak-doc/src/site/markdown/security/audit.md +++ b/oak-doc/src/site/markdown/security/audit.md @@ -106,14 +106,19 @@ with three additional payload entries: | `commit.userId` | acting user id (`CommitInfo.OAK_UNKNOWN`, i.e. `"oak:unknown"`, for system commits) | `CommitInfo.getUserId()` | | `commit.timestamp` | commit timestamp in milliseconds since epoch | `CommitInfo.getDate()` | +The three key names are published as `AuditEvent.COMMIT_SESSION_ID`, +`AuditEvent.COMMIT_USER_ID`, and `AuditEvent.COMMIT_TIMESTAMP`; use those +rather than string literals. + Events arriving through the fire-and-forget pipeline cannot carry these keys: Oak strips caller-supplied values for exactly these three at dispatch. For events delivered through Oak dispatch, their presence is therefore a reliable commit-attached signal. The Javadoc on `AuditEvent#getPayload()` is the normative statement of this contract. Consumers that need to tell the two -sources apart inspect for `commit.sessionId`. The `commit.userId` value -`"oak:unknown"` is a deliberate anonymity marker for system commits; listeners -MUST NOT attempt to resolve it to a real user. +sources apart call `AuditEvents.hasCommitMetadata(event)`, which returns +`true` when all three keys are present and non-null. The `commit.userId` +value `"oak:unknown"` is a deliberate anonymity marker for system commits; +listeners MUST NOT attempt to resolve it to a real user. ### Pipelines @@ -242,6 +247,33 @@ Note that audit is a top-level Oak concern, not a `SecurityConfiguration`: `SecurityProvider.getConfiguration(...)`. Use a `@Reference` to `AuditConfiguration`. + +### Monitoring + +The pipeline registers metrics through the `StatisticsProvider` it resolves at +activation, so they surface via JMX or Sling Metrics like Oak's other metrics. +Nothing is registered when no `StatisticsProvider` is bound. + +| Name | Type | Description | +|---|---|---| +| `security.audit.events;domain=` | Meter | Events dispatched, per domain. Counts events that reached at least one listener, so it excludes anything dropped at the toggle or the listener gate. | +| `security.audit.listener.duration;listener=` | Timer | Wall-clock duration of one `onEvents` call, per listener class. | +| `security.audit.listener.failures;listener=` | Meter | Dispatches that ended in a `Throwable` from the listener. | +| `security.audit.events.dropped;domain=` | Meter | Events discarded because the originating session hit the per-session buffer cap. | + +The `domain=` and `listener=` suffixes follow Oak's `StatsProviderUtil` +label convention, which Prometheus and similar systems split back into a +metric name plus labels. + +The listener timer is worth an alert. Listeners run synchronously on the +commit thread, so time spent in `onEvents` is added directly to commit +latency for the writing session. A listener that starts doing I/O inline +shows up here before it shows up as a user complaint. + +The dropped-events meter is the one that matters for a compliance trail: a +non-zero value means a persisted write left no audit event behind. The same +condition logs a WARN, but the meter is what you can alert on. + ### User-API-level audit, not a transaction log @@ -274,6 +306,35 @@ derived index rebuilding) should use Oak's `NodeStore.addObserver(...)` / commit hook produced them. The audit SPI and a `NodeStore` observer answer different questions; deploy the one that matches your use case. + +### Clustering + +Audit events are node-local. A write on one cluster node produces events on +that node only, dispatched to the listeners registered there. The drain +observer ignores commits for which `CommitInfo.isExternal()` is `true`, and +cluster sync from a peer node is exactly that, so the same write does not +produce a second event when it reaches the other nodes. + +For a listener deployed on every node this gives the property you want: each +audited write is delivered once, on the node that performed it. Aggregating +into a single SIEM or compliance archive therefore needs the listener to tag +events with the node they came from, since the SPI adds no node-identity +payload key. `DocumentNodeStore.getClusterId()` is the per-node identifier; +note that `ClusterRepositoryInfo.getId(...)` is not, since it returns one id +shared by the whole cluster. + +Two consequences to plan for. A listener deployed on only some nodes sees +only the writes performed on those nodes, which for a compliance trail is a +silent gap rather than an error. And a node going down loses whatever its +listeners had buffered in their own async queues, if they use one; the audit +SPI dispatches synchronously and holds no cross-node state, so durability +past the dispatch call belongs to the listener. + +Everything above applies to the document store, where clustering is +supported. A segment-store cold-standby instance produces no commit-attached +events at all, for the reason given under +[Commit flow](audit-design.html#Commit_flow). + ### Emitting events from a bundle @@ -350,9 +411,12 @@ public class SiemForwarder implements AuditEventListener { @Override public void onEvents(List events) { for (AuditEvent e : events) { + if (!AuditEvents.hasCommitMetadata(e)) { + continue; // caller-asserted, not an Oak-attested write + } Map p = e.getPayload(); - String sessionId = (String) p.get("commit.sessionId"); - String userId = (String) p.get("commit.userId"); + String sessionId = (String) p.get(AuditEvent.COMMIT_SESSION_ID); + String userId = (String) p.get(AuditEvent.COMMIT_USER_ID); siem.forward(e, sessionId, userId); } } @@ -401,11 +465,12 @@ produced by the commit-attached pipeline carry the `commit.sessionId`, `commit.userId`, and `commit.timestamp` keys, unconditionally overwritten from the commit's `CommitInfo`. Fire-and-forget events cannot carry them, because Oak strips caller-supplied values for exactly these three keys before -delivery. A SIEM forwarder that treats only the former as Oak-attested -mutations is operating within the contract. The Javadoc on -`AuditEvent#getPayload()` is the normative statement, including the boundaries -of the attestation: it applies to Oak dispatch only and does not survive -re-emission. +delivery. `AuditEvents.hasCommitMetadata(event)` performs the check, so +listeners need neither the key names nor the rule. A SIEM forwarder that +treats only attested events as Oak-verified mutations is operating within the +contract. The Javadoc on `AuditEvent#getPayload()` is the normative +statement, including the boundaries of the attestation: it applies to Oak +dispatch only and does not survive re-emission. The open surface is a deliberate trade-off. A reserved-domain registry or typed event subclasses would put Oak in the middle of every producer bundle's @@ -417,9 +482,9 @@ Recommended consumer-side discipline: | Need | Approach | |---|---| -| Distinguish Oak-attested mutations from caller-asserted events. | Inspect for `commit.sessionId` in the payload. Present implies commit-attached; anchor on the three reserved keys, not on the `commit.` prefix in general. | +| Distinguish Oak-attested mutations from caller-asserted events. | Call `AuditEvents.hasCommitMetadata(event)`. It anchors on the three reserved keys, not on the `commit.` prefix in general. | | Restrict trusted producers. | Maintain a consumer-side allowlist of trusted domain prefixes and reject unknown domains. | -| Compliance audit (Oak-verified writes only). | Subscribe to `"oak.security"` and filter for events carrying the three reserved `commit.*` keys. | +| Compliance audit (Oak-verified writes only). | Subscribe to `"oak.security"` and keep only events for which `AuditEvents.hasCommitMetadata(event)` is `true`. | ### Further Reading From 38efd5386d123ede8b2f9d407537092fa666a92d Mon Sep 17 00:00:00 2001 From: Andrei Dulvac Date: Tue, 4 Aug 2026 16:24:48 +0200 Subject: [PATCH 3/6] OAK-12331: carry the audit doc review fixes into the consumer guide The previous commit fixed audit-design.md only. Two of the review points apply to audit.md as well: - Define "capture site" there too, before its first use. - Note that the drain does not depend on an explicit Session.save(), and name the operations that commit on their own. Also reworded the commit-attached bullet in audit-design.md, where the "explicit or implicit" aside had buried the verb, and gave AuditEvents a javadoc link now that the page refers to it by name. --- .../site/markdown/security/audit-design.md | 7 ++++--- oak-doc/src/site/markdown/security/audit.md | 19 ++++++++++++++----- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/oak-doc/src/site/markdown/security/audit-design.md b/oak-doc/src/site/markdown/security/audit-design.md index 644505de649..beceb433429 100644 --- a/oak-doc/src/site/markdown/security/audit-design.md +++ b/oak-doc/src/site/markdown/security/audit-design.md @@ -43,9 +43,10 @@ There are two delivery paths: - **Commit-attached.** Oak-internal capture sites (e.g. `UserManagerImpl`) call `AuditEvents.record(root, event)`. Events land in a per-session `ThreadLocal` buffer (`AuditBuffer`), and a `NodeStore` `Observer` - (`AuditDrainObserver`) drains and dispatches them after the commit that - follows, explicit or implicit, durably persists. At drain time each event - is decorated with `commit.sessionId`, `commit.userId`, and + (`AuditDrainObserver`) drains and dispatches them once the following + commit has durably persisted, whether the caller issued that commit + explicitly or an operation issued it on their behalf. At drain time each + event is decorated with `commit.sessionId`, `commit.userId`, and `commit.timestamp` payload entries; a failed commit drops the buffer. - **Fire-and-forget.** Any OSGi bundle resolves `AuditEventEmitter` via `@Reference` and calls `emit(event)`. The event is dispatched synchronously diff --git a/oak-doc/src/site/markdown/security/audit.md b/oak-doc/src/site/markdown/security/audit.md index 2a4005017da..0e09e2e6b3c 100644 --- a/oak-doc/src/site/markdown/security/audit.md +++ b/oak-doc/src/site/markdown/security/audit.md @@ -30,13 +30,17 @@ The SPI is small: an event type, a listener interface, and an emitter service. It does not prescribe transport, persistence, or out-of-process delivery. Those are listener concerns. +A *capture site* is a place in Oak's own code that records an audit event. +Today the only ones are in the user-management implementation, on group +membership add and remove. + Two producer paths feed a single listener registry: - A **commit-attached** path used by Oak-internal capture sites, currently group membership changes in the user-management implementation. Events are - buffered for the duration of a session write, drained on successful - `Root.commit()`, and decorated with commit metadata before dispatch. Events - are dropped if the commit fails. + buffered for the duration of a session write, drained on the commit that + follows, and decorated with commit metadata before dispatch. Events are + dropped if the commit fails. - A **fire-and-forget** path exposed to any OSGi bundle through the [AuditEventEmitter] service. Events are dispatched immediately on the calling thread. They are not tied to a commit and are not buffered. @@ -50,7 +54,7 @@ bundle-emitted custom events through one entry point. | Module | Role | |---|---| -| `oak-core-spi` | Domain-neutral SPI: [AuditEvent], [AuditEventListener], [AuditEventEmitter], the `AuditEvents` static facade, and [AuditConfiguration] (typed handle on the pipeline's runtime state). | +| `oak-core-spi` | Domain-neutral SPI: [AuditEvent], [AuditEventListener], [AuditEventEmitter], the [AuditEvents] static facade, and [AuditConfiguration] (typed handle on the pipeline's runtime state). | | `oak-security-spi` | Security-domain constants: `SecurityAuditDomain.NAME` (the `"oak.security"` domain string) and per-sub-domain type-string classes such as `UserAuditTypes` in the `spi.security.user` package. | | `oak-core` | Pipeline implementation: listener registry, commit-attached buffer, the observer that drains it on commit success, the emitter, and the configuration component. | @@ -134,7 +138,7 @@ fails, the buffered events are discarded. The dispatch sequence: 1. A capture site appends an event to the per-session buffer. -2. The session calls `Root.commit()`; commit hooks and validators run; the +2. The session reaches `Root.commit()`; commit hooks and validators run; the merge persists durably. 3. An `Observer` registered by the audit configuration fires on the commit thread, drains the buffer for the originating session, and decorates each @@ -142,6 +146,10 @@ The dispatch sequence: 4. The registry sorts listeners by rank, filters by domain, and invokes each matching listener's `onEvents(List)`. +Step 2 does not require an explicit `Session.save()`. Operations that commit +on their own, such as `Workspace.move` or `VersionManager.checkin`, reach +`Root.commit()` too and drain the buffer the same way. + Because dispatch happens after durable persistence, a delivered event implies the corresponding write actually landed. A failed commit never produces an audit event. @@ -499,4 +507,5 @@ Recommended consumer-side discipline: [AuditEvent]: /oak/docs/apidocs/org/apache/jackrabbit/oak/spi/audit/AuditEvent.html [AuditEventListener]: /oak/docs/apidocs/org/apache/jackrabbit/oak/spi/audit/AuditEventListener.html [AuditEventEmitter]: /oak/docs/apidocs/org/apache/jackrabbit/oak/spi/audit/AuditEventEmitter.html +[AuditEvents]: /oak/docs/apidocs/org/apache/jackrabbit/oak/spi/audit/AuditEvents.html [AuditConfiguration]: /oak/docs/apidocs/org/apache/jackrabbit/oak/spi/audit/AuditConfiguration.html From d24c99d213775fe376b7f13a475964966761ae1b Mon Sep 17 00:00:00 2001 From: Andrei Dulvac Date: Tue, 4 Aug 2026 16:45:06 +0200 Subject: [PATCH 4/6] OAK-12331: align the audit docs with the implemented SPI The docs described names that the implementation does not use. Corrected against the code on the implementation branch: - The attestation check is AuditEvent.isCommitAttested(event), not AuditEvents.hasCommitMetadata(event). - The reserved payload keys are oak.commit.sessionId / .userId / .timestamp, not commit.*. - The pipeline owner class is AuditPipeline, not AuditConfigurationImpl. - Domain and type are the AuditDomain / AuditType value types rather than bare strings, so SecurityAuditDomain exposes DOMAIN rather than NAME and UserAuditTypes holds AuditType constants. Updated the three code samples that still implemented the string-based interface. Also documented how the metrics resolve their StatisticsProvider, and why the event meter counts once per domain per commit rather than once per delivery. --- .../site/markdown/security/audit-design.md | 71 ++++++++------- oak-doc/src/site/markdown/security/audit.md | 86 +++++++++++-------- 2 files changed, 88 insertions(+), 69 deletions(-) diff --git a/oak-doc/src/site/markdown/security/audit-design.md b/oak-doc/src/site/markdown/security/audit-design.md index beceb433429..3fb3cb18e90 100644 --- a/oak-doc/src/site/markdown/security/audit-design.md +++ b/oak-doc/src/site/markdown/security/audit-design.md @@ -46,12 +46,12 @@ There are two delivery paths: (`AuditDrainObserver`) drains and dispatches them once the following commit has durably persisted, whether the caller issued that commit explicitly or an operation issued it on their behalf. At drain time each - event is decorated with `commit.sessionId`, `commit.userId`, and - `commit.timestamp` payload entries; a failed commit drops the buffer. + event is decorated with `oak.commit.sessionId`, `oak.commit.userId`, and + `oak.commit.timestamp` payload entries; a failed commit drops the buffer. - **Fire-and-forget.** Any OSGi bundle resolves `AuditEventEmitter` via `@Reference` and calls `emit(event)`. The event is dispatched synchronously on the calling thread: no buffering, no commit boundary, no payload - decoration. Caller-supplied values for the three reserved `commit.*` + decoration. Caller-supplied values for the three reserved `oak.commit.*` attestation keys are stripped before delivery (the trust contract on `AuditEvent#getPayload()` is the normative statement). @@ -62,7 +62,7 @@ masquerading as a commit failure, and an inner per-listener `Throwable` barrier on both paths keeps one misbehaving listener from stopping the others. -Pipeline state is owned by `AuditConfigurationImpl` in `oak-core`, which +Pipeline state is owned by `AuditPipeline` in `oak-core`, which holds the feature toggle, the buffer, the listener registry, the sink installed into the `AuditEvents` facade, and the singleton drain observer. It is registered as an OSGi service of type `AuditConfiguration`. Audit is a @@ -81,9 +81,9 @@ On the commit-attached path, `BufferSink.record` gates on the feature toggle and on whether any listener is registered for the event's domain, so a capture site allocates nothing when audit is off. The observer runs on the commit thread once the merge has persisted, drains the buffer for that -session, and stamps the three `commit.*` keys. On the fire-and-forget path, +session, and stamps the three `oak.commit.*` keys. On the fire-and-forget path, `BufferSink.dispatch` applies the same toggle and listener gates, strips -caller-supplied `commit.*` values, and dispatches inline. +caller-supplied `oak.commit.*` values, and dispatches inline. The short-circuit order in the observer, and the exception barriers on both paths, are described under Implementation below. @@ -143,11 +143,12 @@ Package `org.apache.jackrabbit.oak.spi.audit` holds the domain-neutral SPI: | Type | Role | |---|---| -| `AuditEvent` | Event interface: domain, type, timestamp, payload. Static factory `AuditEvent.of(...)`. Publishes the three reserved key names as `COMMIT_SESSION_ID`, `COMMIT_USER_ID`, `COMMIT_TIMESTAMP`. | +| `AuditEvent` | Event interface: domain, type, timestamp, payload. Static factory `AuditEvent.of(...)`. Publishes the three reserved key names as `COMMIT_SESSION_ID`, `COMMIT_USER_ID`, `COMMIT_TIMESTAMP`, and the `isCommitAttested(event)` predicate over them. | +| `AuditDomain` / `AuditType` | Value types wrapping the domain and type strings, created via `of(name)`. Validated on construction, so a blank or malformed name fails at the producer rather than at the consumer. | | `AuditEventListener` | Consumer SPI: `onEvents(List)`, scoped to one domain via `getDomain()`, ordered by `getRank()`. | | `AuditEventEmitter` | OSGi service surface for fire-and-forget emission from any bundle. | -| `AuditEvents` | Static facade: `record(root, event)` and `dispatch(event)`, routing to the installed `Sink`; `isEnabled()` / `isEnabledFor(domain)` gates; `hasCommitMetadata(event)` for the commit-attached check. | -| `AuditEvents.Sink` | SPI implemented by the pipeline. `AuditConfigurationImpl` installs a `BufferSink`. | +| `AuditEvents` | Static facade: `record(root, event)` and `dispatch(event)`, routing to the installed `Sink`; `isEnabled()` / `isEnabledFor(domain)` gates. | +| `AuditEvents.Sink` | SPI implemented by the pipeline. `AuditPipeline` installs a `BufferSink`. | | `AuditBufferLifecycle` | Session lifecycle callouts: drain on refresh and on commit failure. | | `AuditConfiguration` | Typed handle on pipeline state (`isActive()`, `NOOP`). | @@ -167,13 +168,13 @@ Multiplexing belongs at the listener layer. Security-domain constants live next to the SPI they describe: -- `spi/security/audit/SecurityAuditDomain` holds the single domain string - `"oak.security"` shared by all events Oak's security stack emits. The - `oak.` prefix namespaces the domain so listeners in mixed deployments - (Sling, application bundles) can tell Oak's security events apart from - same-named domains defined by other layers. +- `spi/security/audit/SecurityAuditDomain` holds `DOMAIN`, the single + `AuditDomain` wrapping `"oak.security"`, shared by all events Oak's security + stack emits. The `oak.` prefix namespaces the domain so listeners in mixed + deployments (Sling, application bundles) can tell Oak's security events + apart from same-named domains defined by other layers. - `spi/security/user/UserAuditTypes` holds the user-membership vocabulary: - type strings (`MEMBER_ADDED`, `MEMBER_REMOVED`) and payload keys + `AuditType` constants (`MEMBER_ADDED`, `MEMBER_REMOVED`) and payload keys (`PAYLOAD_GROUP_PATH`, `PAYLOAD_MEMBER_IDS`, `PAYLOAD_MEMBER_PATHS`, `PAYLOAD_MEMBERSHIP_SOURCE`, `PAYLOAD_IS_CONTENT_ID`, `PAYLOAD_FAILED_IDS`). A single and a bulk membership change share the @@ -190,7 +191,7 @@ package-private classes next to their only callers, e.g. bar for casually forging Oak-attested events, but it is not a hard boundary: any bundle can call `AuditEvent.of(domain, type, payload)` directly. Listeners that need to distinguish Oak-attested commit-attached events from -fire-and-forget emissions call `AuditEvents.hasCommitMetadata(event)`. +fire-and-forget emissions call `AuditEvent.isCommitAttested(event)`. The helper exists so listeners do not hardcode the key names or re-derive the rule. It is named for what it checks: all three reserved keys are @@ -252,20 +253,28 @@ when the thread is reused or discarded. | Component | Role | |---|---| | `AuditBuffer` | `ThreadLocal` per-session staging area, keyed by `ContentSession` id. Caps a session at 10,000 staged events: past that, further events are dropped and one WARN is logged for the session rather than one per event. The cap re-arms on the next drain, refresh, or commit failure, so it bounds the memory a single large or non-committing session can pin. | -| `BufferSink` (inner class of `AuditConfigurationImpl`) | The installed `AuditEvents.Sink`. Gates on the feature toggle and listener presence, buffers on `record`, dispatches inline on `dispatch`. | +| `BufferSink` (inner class of `AuditPipeline`) | The installed `AuditEvents.Sink`. Gates on the feature toggle and listener presence, buffers on `record`, dispatches inline on `dispatch`. | | `AuditDrainObserver` | `Observer` that drains the buffer on commit success. Carries the outer and inner `Throwable` barriers. | -| `CommitMetadataDecorator` | Stamps the three reserved `commit.*` entries at drain time (commit-attached) and strips caller-supplied values for the same keys at dispatch (fire-and-forget). | +| `CommitMetadataDecorator` | Stamps the three reserved `oak.commit.*` entries at drain time (commit-attached) and strips caller-supplied values for the same keys at dispatch (fire-and-forget). | | `AuditEventEmitterImpl` | OSGi `@Component` implementing `AuditEventEmitter`; delegates to `AuditEvents.dispatch`. | | `WhiteboardAuditEventListenerRegistry` | Tracks `AuditEventListener` services on the Whiteboard. `getListeners()` returns them sorted by rank descending; `hasListenerFor(domain)` backs the pre-allocation gate. | | `AuditMonitor` | Wraps the `StatisticsProvider`: per-domain event meter, per-listener timer and failure meter, dropped-event meter. Falls back to a no-op when no provider is bound. | -| `AuditConfigurationImpl` | Pipeline owner: feature toggle, buffer, registry, sink, drain observer, monitor. Published as `AuditConfiguration`. | - -The monitor is resolved as an optional `@Reference` to `StatisticsProvider` -and passed to the components that record: the buffer for dropped events, the -dispatch path for the event meter and the per-listener timer. Recording sits -inside the existing per-listener `Throwable` barrier, so a metrics failure -cannot break a dispatch. The metric names and their operational meaning are -listed under [Monitoring](audit.html#Monitoring). +| `AuditPipeline` | Pipeline owner: feature toggle, buffer, registry, sink, drain observer, monitor. Published as `AuditConfiguration`. | + +`initialize` looks the `StatisticsProvider` up on the whiteboard rather than +taking a DS `@Reference`, so the OSGi and embedded paths share one lookup. +Deployments that publish no provider, which is the normal case for tests and +embedded callers, get `AuditMonitor.NOOP` and record nothing. The monitor is +passed to the components that record: the buffer for dropped events, and both +dispatch paths for the event meter, the per-listener timer, and the failure +meter. Recording sits inside the existing per-listener `Throwable` barrier, so +a metrics failure cannot break a dispatch. The metric names and their +operational meaning are listed under [Monitoring](audit.html#Monitoring). + +The event meter counts an event once per domain, when at least one listener +consumed it. Both are deliberate: counting per listener would multiply the +rate by the number of subscribers, and counting before the dispatch loop would +include events whose listener unregistered between capture and drain. #### AuditDrainObserver @@ -320,7 +329,7 @@ paths through `AuditBufferLifecycle` callouts: | `Root.commit()` succeeds | `AuditDrainObserver.contentChanged` | | `Root.commit()` fails (merge throws) | `MutableRoot.commit` finally block, via `AuditBufferLifecycle.onCommitFailed` | | `Root.refresh()` | `MutableRoot.refresh`, via `AuditBufferLifecycle.onRefresh` | -| Pipeline shutdown while sessions are mid-flight | `AuditConfigurationImpl.dispose`, via `buffer.clearAll()` | +| Pipeline shutdown while sessions are mid-flight | `AuditPipeline.dispose`, via `buffer.clearAll()` | `Root.rebase()` intentionally does not drain: rebase preserves transient changes, so the audit events staged alongside them survive and are @@ -337,7 +346,7 @@ the buffer consistent. Non-JCR commits must not call it. ### OSGi wiring -`AuditConfigurationImpl` is declared as +`AuditPipeline` is declared as `@Component(service = AuditConfiguration.class)`. It takes no reference to the `NodeStore` or to `Observable`. Instead it follows Oak's established observer-registration idiom (the same one the Lucene index observer uses): @@ -372,7 +381,7 @@ sharing one buffer would double-dispatch. ### Embedded (non-OSGi) wiring Embedded callers (tests, `oak-run` tooling, custom embeds) wire the pipeline -explicitly. Several of the types below, including `AuditConfigurationImpl` +explicitly. Several of the types below, including `AuditPipeline` and `SecurityProviderBuilder`, live in packages oak-core does not export, so this path is available to code on a flat classpath rather than to a bundle running inside an OSGi framework; there, use the DS service instead. @@ -381,7 +390,7 @@ running inside an OSGi framework; there, use the DS service instead. MemoryNodeStore store = new MemoryNodeStore(); DefaultWhiteboard whiteboard = new DefaultWhiteboard(); -AuditConfigurationImpl audit = new AuditConfigurationImpl(); +AuditPipeline audit = new AuditPipeline(); audit.initialize(whiteboard); // toggle, registry, buffer, sink // The toggle is created disabled. Flip it on through the FeatureToggle @@ -389,7 +398,7 @@ audit.initialize(whiteboard); // toggle, registry, buffer, sink Tracker toggles = whiteboard.track(FeatureToggle.class); try { for (FeatureToggle ft : toggles.getServices()) { - if (AuditConfigurationImpl.FEATURE_TOGGLE_NAME.equals(ft.getName())) { + if (AuditPipeline.FEATURE_TOGGLE_NAME.equals(ft.getName())) { ft.setEnabled(true); } } diff --git a/oak-doc/src/site/markdown/security/audit.md b/oak-doc/src/site/markdown/security/audit.md index 0e09e2e6b3c..1ad3c68126d 100644 --- a/oak-doc/src/site/markdown/security/audit.md +++ b/oak-doc/src/site/markdown/security/audit.md @@ -55,7 +55,7 @@ bundle-emitted custom events through one entry point. | Module | Role | |---|---| | `oak-core-spi` | Domain-neutral SPI: [AuditEvent], [AuditEventListener], [AuditEventEmitter], the [AuditEvents] static facade, and [AuditConfiguration] (typed handle on the pipeline's runtime state). | -| `oak-security-spi` | Security-domain constants: `SecurityAuditDomain.NAME` (the `"oak.security"` domain string) and per-sub-domain type-string classes such as `UserAuditTypes` in the `spi.security.user` package. | +| `oak-security-spi` | Security-domain constants: `SecurityAuditDomain.DOMAIN` (the `"oak.security"` domain) and per-sub-domain vocabulary classes such as `UserAuditTypes` in the `spi.security.user` package. | | `oak-core` | Pipeline implementation: listener registry, commit-attached buffer, the observer that drains it on commit success, the emitter, and the configuration component. | Consumer bundles depend on `oak-core-spi` only. Implementing a listener or @@ -69,19 +69,23 @@ emitting events requires no dependency on `oak-core`, `oak-jcr`, or ```java public interface AuditEvent { - @NotNull String getDomain(); - @NotNull String getType(); + @NotNull AuditDomain getDomain(); + @NotNull AuditType getType(); long getTimestamp(); @NotNull Map getPayload(); } ``` -- **Domain**: namespace identifying the event source category. Oak's security - stack uses `"oak.security"` (defined by `SecurityAuditDomain.NAME`). Bundles - defining new event types choose their own domain string; the SPI imposes no - schema. -- **Type**: stable identifier within the domain, e.g. `"membership.added"`. - Consumers dispatch on it. +- **Domain**: namespace identifying the event source category, as an + `AuditDomain`. Oak's security stack uses `SecurityAuditDomain.DOMAIN`, which + wraps `"oak.security"`. Bundles defining new event types build their own with + `AuditDomain.of("...")`; the SPI imposes no schema. +- **Type**: stable identifier within the domain, as an `AuditType`, e.g. + `AuditType.of("membership.added")`. Consumers dispatch on it. + +`AuditDomain` and `AuditType` are validated value types rather than bare +strings, so a blank or malformed name fails where the event is built instead of +silently reaching listeners. Both expose `name()` for the underlying string. - **Timestamp**: milliseconds since epoch at event construction time. - **Payload**: open map of supplementary data. Consumers MUST tolerate missing keys; producers MAY add keys without versioning. @@ -106,9 +110,9 @@ with three additional payload entries: | Key | Value | Source | |---|---|---| -| `commit.sessionId` | session identifier of the writing session | `CommitInfo.getSessionId()` | -| `commit.userId` | acting user id (`CommitInfo.OAK_UNKNOWN`, i.e. `"oak:unknown"`, for system commits) | `CommitInfo.getUserId()` | -| `commit.timestamp` | commit timestamp in milliseconds since epoch | `CommitInfo.getDate()` | +| `oak.commit.sessionId` | session identifier of the writing session | `CommitInfo.getSessionId()` | +| `oak.commit.userId` | acting user id (`CommitInfo.OAK_UNKNOWN`, i.e. `"oak:unknown"`, for system commits) | `CommitInfo.getUserId()` | +| `oak.commit.timestamp` | commit timestamp in milliseconds since epoch | `CommitInfo.getDate()` | The three key names are published as `AuditEvent.COMMIT_SESSION_ID`, `AuditEvent.COMMIT_USER_ID`, and `AuditEvent.COMMIT_TIMESTAMP`; use those @@ -119,8 +123,8 @@ Oak strips caller-supplied values for exactly these three at dispatch. For events delivered through Oak dispatch, their presence is therefore a reliable commit-attached signal. The Javadoc on `AuditEvent#getPayload()` is the normative statement of this contract. Consumers that need to tell the two -sources apart call `AuditEvents.hasCommitMetadata(event)`, which returns -`true` when all three keys are present and non-null. The `commit.userId` +sources apart call `AuditEvent.isCommitAttested(event)`, which returns +`true` when all three keys are present and non-null. The `oak.commit.userId` value `"oak:unknown"` is a deliberate anonymity marker for system commits; listeners MUST NOT attempt to resolve it to a real user. @@ -142,7 +146,8 @@ The dispatch sequence: merge persists durably. 3. An `Observer` registered by the audit configuration fires on the commit thread, drains the buffer for the originating session, and decorates each - event with `commit.sessionId`, `commit.userId`, and `commit.timestamp`. + event with `oak.commit.sessionId`, `oak.commit.userId`, and + `oak.commit.timestamp`. 4. The registry sorts listeners by rank, filters by domain, and invokes each matching listener's `onEvents(List)`. @@ -187,11 +192,11 @@ Properties: `onEvents` or from the `getDomain()` / `getRank()` accessors consulted during routing, are logged and swallowed; remaining listeners still run. `emit` never propagates a listener exception back to the caller. -- **No payload decoration, but reserved keys are stripped.** No `commit.*` +- **No payload decoration, but reserved keys are stripped.** No `oak.commit.*` keys are added; caller-supplied values for the three reserved attestation - keys (`commit.sessionId`, `commit.userId`, `commit.timestamp`) are removed - before delivery. Every other entry reaches listeners exactly as the caller - provided it. + keys (`oak.commit.sessionId`, `oak.commit.userId`, + `oak.commit.timestamp`) are removed before delivery. Every other entry + reaches listeners exactly as the caller provided it. ### Configuration @@ -209,7 +214,7 @@ Feature Toggles. For a worked example of locating this toggle and flipping it, see the embedded wiring snippet in [Audit Pipeline Design](audit-design.html). -`AuditConfigurationImpl` in `oak-core` owns the pipeline and is published as +`AuditPipeline` in `oak-core` owns the pipeline and is published as an OSGi service of type `AuditConfiguration`. It carries an OSGi object-class definition, so it appears in the Felix console alongside Oak's other components. @@ -353,11 +358,13 @@ implementation is registered by `oak-core`. @Component public class ContentPublishAuditor { + private static final AuditDomain DOMAIN = AuditDomain.of("example.content"); + @Reference private AuditEventEmitter audit; public void onPublished(String path, String variant) { - if (audit.isEnabledFor("example.content")) { + if (audit.isEnabledFor(DOMAIN)) { audit.emit(new ContentPublishedEvent(path, variant)); } } @@ -373,6 +380,9 @@ A minimal event implementation: ```java class ContentPublishedEvent implements AuditEvent { + private static final AuditDomain DOMAIN = AuditDomain.of("example.content"); + private static final AuditType TYPE = AuditType.of("content.published"); + private final String path; private final String variant; private final long timestamp = System.currentTimeMillis(); @@ -382,8 +392,8 @@ class ContentPublishedEvent implements AuditEvent { this.variant = variant; } - @Override public String getDomain() { return "example.content"; } - @Override public String getType() { return "content.published"; } + @Override public AuditDomain getDomain() { return DOMAIN; } + @Override public AuditType getType() { return TYPE; } @Override public long getTimestamp() { return timestamp; } @Override public Map getPayload() { return Map.of("path", path, "variant", variant); @@ -407,8 +417,8 @@ A listener is an OSGi component registered as a service of type public class SiemForwarder implements AuditEventListener { @Override - public String getDomain() { - return "oak.security"; + public AuditDomain getDomain() { + return SecurityAuditDomain.DOMAIN; } @Override @@ -419,7 +429,7 @@ public class SiemForwarder implements AuditEventListener { @Override public void onEvents(List events) { for (AuditEvent e : events) { - if (!AuditEvents.hasCommitMetadata(e)) { + if (!AuditEvent.isCommitAttested(e)) { continue; // caller-asserted, not an Oak-attested write } Map p = e.getPayload(); @@ -469,16 +479,16 @@ The fire-and-forget producer surface is open by design. the consumer side. The distinguishing signal is payload-based and enforced at dispatch: events -produced by the commit-attached pipeline carry the `commit.sessionId`, -`commit.userId`, and `commit.timestamp` keys, unconditionally overwritten from -the commit's `CommitInfo`. Fire-and-forget events cannot carry them, because -Oak strips caller-supplied values for exactly these three keys before -delivery. `AuditEvents.hasCommitMetadata(event)` performs the check, so -listeners need neither the key names nor the rule. A SIEM forwarder that -treats only attested events as Oak-verified mutations is operating within the -contract. The Javadoc on `AuditEvent#getPayload()` is the normative -statement, including the boundaries of the attestation: it applies to Oak -dispatch only and does not survive re-emission. +produced by the commit-attached pipeline carry the `oak.commit.sessionId`, +`oak.commit.userId`, and `oak.commit.timestamp` keys, unconditionally +overwritten from the commit's `CommitInfo`. Fire-and-forget events cannot +carry them, because Oak strips caller-supplied values for exactly these +three keys before delivery. `AuditEvent.isCommitAttested(event)` does the +check, so listeners need neither the key names nor the rule. A SIEM +forwarder that treats only attested events as Oak-verified mutations is +operating within the contract. The Javadoc on `AuditEvent#getPayload()` is +the normative statement, including the boundaries of the attestation: it +applies to Oak dispatch only and does not survive re-emission. The open surface is a deliberate trade-off. A reserved-domain registry or typed event subclasses would put Oak in the middle of every producer bundle's @@ -490,9 +500,9 @@ Recommended consumer-side discipline: | Need | Approach | |---|---| -| Distinguish Oak-attested mutations from caller-asserted events. | Call `AuditEvents.hasCommitMetadata(event)`. It anchors on the three reserved keys, not on the `commit.` prefix in general. | +| Distinguish Oak-attested mutations from caller-asserted events. | Call `AuditEvent.isCommitAttested(event)`. It anchors on the three reserved keys, not on the `oak.commit.` prefix in general. | | Restrict trusted producers. | Maintain a consumer-side allowlist of trusted domain prefixes and reject unknown domains. | -| Compliance audit (Oak-verified writes only). | Subscribe to `"oak.security"` and keep only events for which `AuditEvents.hasCommitMetadata(event)` is `true`. | +| Compliance audit (Oak-verified writes only). | Subscribe to `"oak.security"` and keep only events for which `AuditEvent.isCommitAttested(event)` is `true`. | ### Further Reading From 9f483fbd81c276addd9ca3264e6e07e85655bcfc Mon Sep 17 00:00:00 2001 From: Andrei Dulvac Date: Tue, 4 Aug 2026 16:51:21 +0200 Subject: [PATCH 5/6] OAK-12331: explain why audit domain and type are value types The design doc named AuditDomain and AuditType without saying why they exist. The rationale is from the review on PR #3059: constraining the value at construction keeps a domain usable as a JCR node name, so a listener that persists events into the repository can build a path from it without escaping. Records the actual rules (non-blank, JcrNameParser, no colon, no whitespace), why the colon is rejected rather than escaped, and why neither type is an enum. Also fixes a bullet list in audit.md that an earlier edit had split in two, orphaning Timestamp and Payload below a paragraph. --- .../site/markdown/security/audit-design.md | 19 ++++++++++++++++++- oak-doc/src/site/markdown/security/audit.md | 12 ++++++++---- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/oak-doc/src/site/markdown/security/audit-design.md b/oak-doc/src/site/markdown/security/audit-design.md index 3fb3cb18e90..6502f29e32c 100644 --- a/oak-doc/src/site/markdown/security/audit-design.md +++ b/oak-doc/src/site/markdown/security/audit-design.md @@ -144,7 +144,7 @@ Package `org.apache.jackrabbit.oak.spi.audit` holds the domain-neutral SPI: | Type | Role | |---|---| | `AuditEvent` | Event interface: domain, type, timestamp, payload. Static factory `AuditEvent.of(...)`. Publishes the three reserved key names as `COMMIT_SESSION_ID`, `COMMIT_USER_ID`, `COMMIT_TIMESTAMP`, and the `isCommitAttested(event)` predicate over them. | -| `AuditDomain` / `AuditType` | Value types wrapping the domain and type strings, created via `of(name)`. Validated on construction, so a blank or malformed name fails at the producer rather than at the consumer. | +| `AuditDomain` / `AuditType` | Value types wrapping the domain and type strings, created via `of(name)` and validated there. | | `AuditEventListener` | Consumer SPI: `onEvents(List)`, scoped to one domain via `getDomain()`, ordered by `getRank()`. | | `AuditEventEmitter` | OSGi service surface for fire-and-forget emission from any bundle. | | `AuditEvents` | Static facade: `record(root, event)` and `dispatch(event)`, routing to the installed `Sink`; `isEnabled()` / `isEnabledFor(domain)` gates. | @@ -152,6 +152,23 @@ Package `org.apache.jackrabbit.oak.spi.audit` holds the domain-neutral SPI: | `AuditBufferLifecycle` | Session lifecycle callouts: drain on refresh and on commit failure. | | `AuditConfiguration` | Typed handle on pipeline state (`isActive()`, `NOOP`). | +Domain and type are value types rather than bare strings so the constraint +on them has somewhere to live. A listener that persists events into the +repository wants to build a path from the domain, so a domain has to be +usable as a JCR node name. `AuditDomain.of(...)` and `AuditType.of(...)` +enforce that: the name must be non-blank, must pass `JcrNameParser` (which +rules out `/`, `[`, `]`, `|` and `*`), and must contain no colon and no +whitespace. The colon is rejected rather than escaped because in JCR it +denotes a namespace prefix, which means nothing for a flat audit +identifier; whitespace is rejected because it has no place in one either. + +Validating in the factory puts the failure at the producer that supplied +the bad name, rather than at whichever listener later tried to build a path +out of it. Both types are final, with `equals`/`hashCode` over the wrapped +string, so the registry can route on them and `name()` gives listeners the +raw value back. Neither is an enum: the set of domains is open, and +consumer bundles define their own. + `AuditConfiguration.isActive()` returns `true` when the feature toggle is enabled and at least one listener is registered. The two predicates AND together so a deployed-but-unused pipeline reports `false`, matching the diff --git a/oak-doc/src/site/markdown/security/audit.md b/oak-doc/src/site/markdown/security/audit.md index 1ad3c68126d..1bcbccc0703 100644 --- a/oak-doc/src/site/markdown/security/audit.md +++ b/oak-doc/src/site/markdown/security/audit.md @@ -82,14 +82,18 @@ public interface AuditEvent { `AuditDomain.of("...")`; the SPI imposes no schema. - **Type**: stable identifier within the domain, as an `AuditType`, e.g. `AuditType.of("membership.added")`. Consumers dispatch on it. - -`AuditDomain` and `AuditType` are validated value types rather than bare -strings, so a blank or malformed name fails where the event is built instead of -silently reaching listeners. Both expose `name()` for the underlying string. - **Timestamp**: milliseconds since epoch at event construction time. - **Payload**: open map of supplementary data. Consumers MUST tolerate missing keys; producers MAY add keys without versioning. +`AuditDomain` and `AuditType` wrap their names rather than passing plain +strings around, and both validate in `of(...)`: a name must be non-blank and +usable as a JCR node name, with no colon and no whitespace. That keeps a +domain safe to use as a path element for listeners that persist events into +the repository, and it means a bad name fails at the producer instead of +reaching a listener. Call `name()` for the underlying string. The +[design document](audit-design.html#SPI_layout) has the full rules. + The public SPI keeps only the `AuditEvent` interface. Concrete events are built with the static factory `AuditEvent.of(domain, type, payload)`, and consumers discriminate events by `getDomain()` plus `getType()` rather than by From 9abe72bbe52c5e11a04a528060dc4be9d620e3c1 Mon Sep 17 00:00:00 2001 From: Andrei Dulvac Date: Thu, 6 Aug 2026 15:20:48 +0200 Subject: [PATCH 6/6] OAK-12331: follow the AuditDispatch rename and impl-package move in the docs AuditEvents is now AuditDispatch, and AuditEventImpl moved to the unexported spi.audit.impl package. Both pages referred to the old names. Also records why AuditEventImpl sits outside the exported package, since that is the kind of thing the next reader will otherwise undo. --- .../site/markdown/security/audit-design.md | 27 ++++++++++++------- oak-doc/src/site/markdown/security/audit.md | 8 +++--- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/oak-doc/src/site/markdown/security/audit-design.md b/oak-doc/src/site/markdown/security/audit-design.md index 6502f29e32c..90ea2f1cd25 100644 --- a/oak-doc/src/site/markdown/security/audit-design.md +++ b/oak-doc/src/site/markdown/security/audit-design.md @@ -41,7 +41,7 @@ site, as distinct from a bundle emitting its own events. There are two delivery paths: - **Commit-attached.** Oak-internal capture sites (e.g. `UserManagerImpl`) - call `AuditEvents.record(root, event)`. Events land in a per-session + call `AuditDispatch.record(root, event)`. Events land in a per-session `ThreadLocal` buffer (`AuditBuffer`), and a `NodeStore` `Observer` (`AuditDrainObserver`) drains and dispatches them once the following commit has durably persisted, whether the caller issued that commit @@ -64,7 +64,7 @@ others. Pipeline state is owned by `AuditPipeline` in `oak-core`, which holds the feature toggle, the buffer, the listener registry, the sink -installed into the `AuditEvents` facade, and the singleton drain observer. +installed into the `AuditDispatch` facade, and the singleton drain observer. It is registered as an OSGi service of type `AuditConfiguration`. Audit is a top-level Oak concern, not a `SecurityConfiguration`. @@ -147,11 +147,20 @@ Package `org.apache.jackrabbit.oak.spi.audit` holds the domain-neutral SPI: | `AuditDomain` / `AuditType` | Value types wrapping the domain and type strings, created via `of(name)` and validated there. | | `AuditEventListener` | Consumer SPI: `onEvents(List)`, scoped to one domain via `getDomain()`, ordered by `getRank()`. | | `AuditEventEmitter` | OSGi service surface for fire-and-forget emission from any bundle. | -| `AuditEvents` | Static facade: `record(root, event)` and `dispatch(event)`, routing to the installed `Sink`; `isEnabled()` / `isEnabledFor(domain)` gates. | -| `AuditEvents.Sink` | SPI implemented by the pipeline. `AuditPipeline` installs a `BufferSink`. | +| `AuditDispatch` | Static facade: `record(root, event)` and `dispatch(event)`, routing to the installed `Sink`; `isEnabled()` / `isEnabledFor(domain)` gates. | +| `AuditDispatch.Sink` | SPI implemented by the pipeline. `AuditPipeline` installs a `BufferSink`. | | `AuditBufferLifecycle` | Session lifecycle callouts: drain on refresh and on commit failure. | | `AuditConfiguration` | Typed handle on pipeline state (`isActive()`, `NOOP`). | +One class in the package is not part of the SPI: `AuditEventImpl`, the +immutable holder behind `AuditEvent.of(...)`. It lives in +`org.apache.jackrabbit.oak.spi.audit.impl`, which is absent from the +bundle's `Export-Package`, so it is unreachable outside `oak-core-spi` +despite being `public`. It has to be public because the factory that builds +it sits on the interface in the parent package. Keeping it out of the +exported package also keeps edits to it from moving that package's baseline +version, which BND computes per package rather than per class. + Domain and type are value types rather than bare strings so the constraint on them has somewhere to live. A listener that persists events into the repository wants to build a path from the domain, so a domain has to be @@ -172,7 +181,7 @@ consumer bundles define their own. `AuditConfiguration.isActive()` returns `true` when the feature toggle is enabled and at least one listener is registered. The two predicates AND together so a deployed-but-unused pipeline reports `false`, matching the -no-allocation semantics of `AuditEvents.isEnabled()`. Both read the same +no-allocation semantics of `AuditDispatch.isEnabled()`. Both read the same volatile sink state, so they cannot drift apart. The interface ships a `NOOP` constant for callers that want a guaranteed-non-null handle. @@ -270,10 +279,10 @@ when the thread is reused or discarded. | Component | Role | |---|---| | `AuditBuffer` | `ThreadLocal` per-session staging area, keyed by `ContentSession` id. Caps a session at 10,000 staged events: past that, further events are dropped and one WARN is logged for the session rather than one per event. The cap re-arms on the next drain, refresh, or commit failure, so it bounds the memory a single large or non-committing session can pin. | -| `BufferSink` (inner class of `AuditPipeline`) | The installed `AuditEvents.Sink`. Gates on the feature toggle and listener presence, buffers on `record`, dispatches inline on `dispatch`. | +| `BufferSink` (inner class of `AuditPipeline`) | The installed `AuditDispatch.Sink`. Gates on the feature toggle and listener presence, buffers on `record`, dispatches inline on `dispatch`. | | `AuditDrainObserver` | `Observer` that drains the buffer on commit success. Carries the outer and inner `Throwable` barriers. | | `CommitMetadataDecorator` | Stamps the three reserved `oak.commit.*` entries at drain time (commit-attached) and strips caller-supplied values for the same keys at dispatch (fire-and-forget). | -| `AuditEventEmitterImpl` | OSGi `@Component` implementing `AuditEventEmitter`; delegates to `AuditEvents.dispatch`. | +| `AuditEventEmitterImpl` | OSGi `@Component` implementing `AuditEventEmitter`; delegates to `AuditDispatch.dispatch`. | | `WhiteboardAuditEventListenerRegistry` | Tracks `AuditEventListener` services on the Whiteboard. `getListeners()` returns them sorted by rank descending; `hasListenerFor(domain)` backs the pre-allocation gate. | | `AuditMonitor` | Wraps the `StatisticsProvider`: per-domain event meter, per-listener timer and failure meter, dropped-event meter. Falls back to a no-op when no provider is bound. | | `AuditPipeline` | Pipeline owner: feature toggle, buffer, registry, sink, drain observer, monitor. Published as `AuditConfiguration`. | @@ -356,7 +365,7 @@ The lifecycle callouts always fire, for the reason given in design rule 9. The cost of that is negligible: when no pipeline is installed the callout is one volatile read plus a virtual call into a no-op listener. -`AuditEvents.record(root, event)` requires that `root` is the `MutableRoot` +`AuditDispatch.record(root, event)` requires that `root` is the `MutableRoot` of an active JCR session, since the lifecycle callouts above are what keep the buffer consistent. Non-JCR commits must not call it. @@ -481,7 +490,7 @@ pipeline change. ### Performance characteristics With audit off (toggle disabled, or no listener registered for the domain), -capture sites short-circuit at `AuditEvents.isEnabledFor(domain)` before +capture sites short-circuit at `AuditDispatch.isEnabledFor(domain)` before constructing an event: no allocation, no buffer touch. The check is a volatile read of the installed sink and the toggle, and, when the toggle is on, a linear scan of the registered listeners comparing each `getDomain()` diff --git a/oak-doc/src/site/markdown/security/audit.md b/oak-doc/src/site/markdown/security/audit.md index 1bcbccc0703..aff178545e5 100644 --- a/oak-doc/src/site/markdown/security/audit.md +++ b/oak-doc/src/site/markdown/security/audit.md @@ -54,7 +54,7 @@ bundle-emitted custom events through one entry point. | Module | Role | |---|---| -| `oak-core-spi` | Domain-neutral SPI: [AuditEvent], [AuditEventListener], [AuditEventEmitter], the [AuditEvents] static facade, and [AuditConfiguration] (typed handle on the pipeline's runtime state). | +| `oak-core-spi` | Domain-neutral SPI: [AuditEvent], [AuditEventListener], [AuditEventEmitter], the [AuditDispatch] static facade, and [AuditConfiguration] (typed handle on the pipeline's runtime state). | | `oak-security-spi` | Security-domain constants: `SecurityAuditDomain.DOMAIN` (the `"oak.security"` domain) and per-sub-domain vocabulary classes such as `UserAuditTypes` in the `spi.security.user` package. | | `oak-core` | Pipeline implementation: listener registry, commit-attached buffer, the observer that drains it on commit success, the emitter, and the configuration component. | @@ -249,13 +249,13 @@ public class MyComponent { ``` `AuditConfiguration` is published as an OSGi service only. Embedded callers -(tests, `oak-run` tools) use `AuditEvents.isEnabled()` on the static facade +(tests, `oak-run` tools) use `AuditDispatch.isEnabled()` on the static facade instead, which evaluates the same two conditions. `isActive()` returns `true` when the audit feature toggle is enabled AND at least one `AuditEventListener` is registered on the Whiteboard. A deployed-but-unused pipeline (toggle ON, no listener registered) reports -`false`, matching the no-allocation semantics of `AuditEvents.isEnabled()`. +`false`, matching the no-allocation semantics of `AuditDispatch.isEnabled()`. The NOOP `AuditConfiguration`, returned when no implementation is bound at all, reports `false`. @@ -521,5 +521,5 @@ Recommended consumer-side discipline: [AuditEvent]: /oak/docs/apidocs/org/apache/jackrabbit/oak/spi/audit/AuditEvent.html [AuditEventListener]: /oak/docs/apidocs/org/apache/jackrabbit/oak/spi/audit/AuditEventListener.html [AuditEventEmitter]: /oak/docs/apidocs/org/apache/jackrabbit/oak/spi/audit/AuditEventEmitter.html -[AuditEvents]: /oak/docs/apidocs/org/apache/jackrabbit/oak/spi/audit/AuditEvents.html +[AuditDispatch]: /oak/docs/apidocs/org/apache/jackrabbit/oak/spi/audit/AuditDispatch.html [AuditConfiguration]: /oak/docs/apidocs/org/apache/jackrabbit/oak/spi/audit/AuditConfiguration.html