feat(ingester): rfc 0026 green d — rejection telemetry + denial audit - #409
Conversation
Rejections count on the existing request counters with error.type (unauthenticated | permission_denied; the ingest batches counter and the query duration histogram under a new registry 'rejected' kind member), and an ingest tenant-binding denial emits an ingest_denied audit event (kind 8, denied_token_name column — RFC 0005 §3.7 additive-OPTIONAL) carrying the token's audit label and the offending tenant, never a token value. RFC0026.7 goes green in a dedicated global-provider-exempt test binary. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Warning Review limit reached
Next review available in: 20 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (5)
📝 WalkthroughWalkthroughThis PR introduces a new ChangesIngestDenied audit event and ingest pipeline
Parquet audit storage for IngestDenied
Estimated code review effort: 3 (Moderate) | ~30 minutes Possibly related PRs
Poem A rabbit sniffs a token gone astray, 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
Implements RFC 0026 “green slice (d)” by adding rejection telemetry (using existing metric names + error.type) and emitting/round-tripping a new ingest_denied audit event (kind 8) that records the offending tenant plus the token’s audit label (never the token value).
Changes:
- Adds
ourios.query.kind=rejectedsemconv member and records query rejections on the existing query duration metric witherror.type. - Emits ingest rejection metrics (
ourios.ingest.batches+error.type) and introduces aningest_deniedaudit event carryingdenied_token_name. - Extends the audit Parquet schema + reader/writer to support the new event kind/column, and adds dedicated RFC0026.7 tests.
Reviewed changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| semconv/registry/attributes.yaml | Adds ourios.query.kind enum member rejected for pre-dispatch rejections. |
| crates/ourios-server/src/receiver.rs | Wires the denial audit sink into the shared ingest pipeline. |
| crates/ourios-server/src/querier.rs | Records authn/authz query rejections as kind rejected with error.type. |
| crates/ourios-parquet/tests/it/schema_pin.rs | Pins the audit schema with the new optional denied_token_name column. |
| crates/ourios-parquet/tests/it/audit_round_trip.rs | Adds a round-trip test for the new ingest_denied audit event. |
| crates/ourios-parquet/src/lib.rs | Extends the audit schema + column constants for denied_token_name. |
| crates/ourios-parquet/src/audit_record_batch.rs | Writes AuditPayload::IngestDenied into the new column; nulls it for other kinds. |
| crates/ourios-parquet/src/audit_reader.rs | Reads kind 8 and tolerates absent rejection-group columns for older files. |
| crates/ourios-ingester/tests/rfc0026_telemetry.rs | Dedicated RFC0026.7 binary test for metrics + audit + token-value redaction. |
| crates/ourios-ingester/tests/README.md | Documents the new harness-exempt telemetry test binary. |
| crates/ourios-ingester/tests/it/rfc0026_auth.rs | Removes the RFC0026.7 stub and points to the dedicated telemetry binary. |
| crates/ourios-ingester/tests/it/ingest_support/mod.rs | Adds helper to build a capturing pipeline with a denial audit sink attached. |
| crates/ourios-ingester/src/receiver/pipeline.rs | Implements rejection metric recording + ingest_denied emission on tenant-binding denial. |
| crates/ourios-ingester/src/receiver/http.rs | Records unauthenticated rejection telemetry on HTTP 401. |
| crates/ourios-ingester/src/receiver/grpc.rs | Records unauthenticated rejection telemetry in the gRPC auth interceptor. |
| crates/ourios-ingester/src/metrics.rs | Adds record_rejected_batch helper and error.type value constants. |
| crates/ourios-core/src/audit.rs | Adds AuditPayload::IngestDenied plus kind/type constants and mappings. |
| crates/ourios-core/src/alias.rs | Updates match coverage to include the new audit payload variant. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
🧹 Nitpick comments (1)
crates/ourios-parquet/tests/it/audit_round_trip.rs (1)
140-152: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winExtend the audit round-trip suite with property coverage
The newingest_deniedcase is only covered by an example-based round-trip. Add it to the existing proptest-based audit coverage, or expand the generator so this variant is included with the other audit payloads.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@crates/ourios-parquet/tests/it/audit_round_trip.rs` around lines 140 - 152, The new ingest_denied audit case is only covered by the example helper denied_event, so the property-based audit round-trip suite still misses it. Update the proptest coverage in the audit round-trip tests to include AuditPayload::IngestDenied, either by extending the existing generator used for AuditEvent payloads or by adding this variant to the shared audit payload strategy so it is exercised alongside the other cases.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@crates/ourios-parquet/tests/it/audit_round_trip.rs`:
- Around line 140-152: The new ingest_denied audit case is only covered by the
example helper denied_event, so the property-based audit round-trip suite still
misses it. Update the proptest coverage in the audit round-trip tests to include
AuditPayload::IngestDenied, either by extending the existing generator used for
AuditEvent payloads or by adding this variant to the shared audit payload
strategy so it is exercised alongside the other cases.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 8ca2b4e4-3e95-48dd-b7e4-2d2d4fc180e0
📒 Files selected for processing (18)
crates/ourios-core/src/alias.rscrates/ourios-core/src/audit.rscrates/ourios-ingester/src/metrics.rscrates/ourios-ingester/src/receiver/grpc.rscrates/ourios-ingester/src/receiver/http.rscrates/ourios-ingester/src/receiver/pipeline.rscrates/ourios-ingester/tests/README.mdcrates/ourios-ingester/tests/it/ingest_support/mod.rscrates/ourios-ingester/tests/it/rfc0026_auth.rscrates/ourios-ingester/tests/rfc0026_telemetry.rscrates/ourios-parquet/src/audit_reader.rscrates/ourios-parquet/src/audit_record_batch.rscrates/ourios-parquet/src/lib.rscrates/ourios-parquet/tests/it/audit_round_trip.rscrates/ourios-parquet/tests/it/schema_pin.rscrates/ourios-server/src/querier.rscrates/ourios-server/src/receiver.rssemconv/registry/attributes.yaml
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
What
RFC 0026 green slice (d) — the last scenario, RFC0026.7 (rejection telemetry + audit):
ourios.ingest.batchescounter witherror.type—unauthenticatedrecorded by the transports that own the 401 surface (the gRPC interceptor and the HTTP handler),permission_deniedby the pipeline's binding check. Query rejections record on the existingourios.query.durationhistogram under a new registry memberrejectedfor the enumeratedourios.query.kind(authn/authz answer before the body parse, so neitherlogsnordriftapplies) — weaver-generated, no hand-written names.ingest_denied(kind 8) — the offending derived tenant on the envelope, the token's audit label in the newdenied_token_namecolumn (OPTIONAL Utf8, appended after the quarantine group; RFC 0005 §3.7 additive rules, schema pin updated citing RFC 0026), never a token value. Wired through the same durable audit sink as every other event (IngestPipeline::with_denial_audit_sink, threaded in the server receiver).Scenario mapping
RFC0026.7 lives in the dedicated
tests/rfc0026_telemetry.rsbinary — it installs the process-global meter provider, the RFC0028.2 harness-exemption class (README updated). One test covers: botherror.typevalues on the exported batches counter, theingest_deniedevent's tenant + token label, WAL emptiness on denial, and a no-token-value sweep across every surface. The Parquet round-trip is in the parquet harness (rfc0026_ingest_denied_audit_event_round_trips); the schema pin is the RFC 0026 §3.4 amendment record.This closes the RFC 0026 §5 board — all seven scenarios green. The green-flip doc PR follows.
Invariants / hazards
rejectedmember on the existingourios.query.kind;error.typeis upstream-standard, deliberately not Ourios-coined.Checks run locally
cargo fmt --all --check,cargo clippy -p {core,parquet,ingester,server} --all-targets --all-features -- -D warnings,cargo teston all four crates.🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Bug Fixes
Tests