Skip to content

Add Prometheus metrics for auth validation - #184

Merged
lukebakken merged 5 commits into
amazon-mq:mainfrom
sdewhitt:feature/auth-validation-metrics
Aug 6, 2026
Merged

Add Prometheus metrics for auth validation#184
lukebakken merged 5 commits into
amazon-mq:mainfrom
sdewhitt:feature/auth-validation-metrics

Conversation

@sdewhitt

@sdewhitt sdewhitt commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Adds Prometheus metrics for the auth-validation endpoint so operators can observe call volume, outcome mix, latency, and capacity pressure.

Metrics are emitted at the single point every request passes through (the audit log call site), dimensioned only by method and the fixed result-category set. No source IP, user, target, or secret material is ever used as a label.

Emitted via the prometheus_collector behaviour (the same pull-based pattern other RabbitMQ plugins use): the hot path is a lock-free counter update, and formatting happens only on scrape.

  • ..._requests_total (counter), ..._duration_ms (histogram), ..._capacity_exhausted_total (counter)
  • semaphore in-use / capacity gauges
  • Metrics register only when the feature is enabled; no state exists when it is off.

Adds new dependency, prometheus, to DEPS. However, it is already listed as a dependency in rabbitmq_prometheus, which already exists within rabbitmq-server.

Tests

CT suite covering counter increments per outcome, duration recording, capacity signalling, gauge behaviour, disabled-state, and crash-safety. All green.

  - New module aws_auth_validate_metrics implementing prometheus_collector
    behaviour (pull-based, matching rabbitmq_shovel_prometheus idiom)
  - Uses OTP counters with write_concurrency + persistent_term for
    lock-free atomic increments on the request hot path
  - Metrics: requests_total (counter, by method+result),
    duration_milliseconds (histogram, by method),
    capacity_exhausted_total (counter, by method),
    semaphore_in_use (gauge), semaphore_capacity (gauge)
  - Wired observe/3 into audit/5 in aws_auth_validate_mgmt so audit
    and metrics stay in lockstep at the single choke point
  - Added usage/0 to aws_auth_validate_semaphore for gauge reads at
    scrape time
  - Registration gated on auth_validation_enabled in aws_sup; no metric
    state when feature is off
  - Common Test suite covering counter increments, histogram buckets,
    capacity_exhausted, semaphore gauges, disabled-state no-op, and
    crash safety
  - Documented in AUTH_VALIDATION.md Metrics section
@sdewhitt sdewhitt self-assigned this Aug 6, 2026
@sdewhitt sdewhitt added C-enhancement Category: Improvements dependencies Pull requests that update a dependency file A-auth-validation Area: The auth-validation endpoint (aws_auth_validate_*). E-large Effort: Hard. Thorough code-base knowledge and high-level vision required. P-medium Priority: Medium. Normal priority. labels Aug 6, 2026
@sdewhitt sdewhitt added this to the 0.4.0 milestone Aug 6, 2026
  - aws_auth_validate_metrics uses prometheus_registry and the
    prometheus_collector behaviour, but prometheus was not in DEPS; it
    resolved only because another plugin in the build tree pulls it in.
    Add it to DEPS so it is a declared runtime dependency, matching
    rabbitmq_prometheus.
  - prometheus is a declared dependency, so a registration error is a real
    fault; drop the try/catch that swallowed it silently.
@sdewhitt
sdewhitt force-pushed the feature/auth-validation-metrics branch from 38e133b to c25c10e Compare August 6, 2026 18:20
@sdewhitt sdewhitt added P-low Priority: Low. Minor; can wait. and removed P-medium Priority: Medium. Normal priority. labels Aug 6, 2026
@sdewhitt
sdewhitt marked this pull request as ready for review August 6, 2026 18:29
Comment thread Makefile Outdated

@lukebakken lukebakken left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding a pull-based Prometheus collector for the auth-validation endpoint. The slot layout and the no-op-when-unregistered guard are clean. A few issues need addressing before merge, most severity in the duration histogram and scrape robustness. Details inline; findings 1-3 are the blockers, 4 is a real metric-quality bug, 5-6 are lower priority.

Verified locally at deps/aws on feature/auth-validation-metrics (HEAD c25c10e), including that prometheus_model_helpers:histogram_buckets/1 maps buckets 1:1 with no auto-appended +Inf.

Comment thread src/aws_auth_validate_metrics.erl Outdated
Comment thread src/aws_auth_validate_metrics.erl
Comment thread src/aws_auth_validate_metrics.erl Outdated
Comment thread src/aws_auth_validate_mgmt.erl
Comment thread src/aws_auth_validate_metrics.erl Outdated
Comment thread src/aws_auth_validate_metrics.erl Outdated
- Depend on rabbitmq_prometheus (which transitively pulls in prometheus)
  rather than the bare prometheus library, matching how rabbitmq-stream-s3
  does it -- guarantees the /api/metrics scrape endpoint is actually served
- Update the aws_sup comment that referenced the old dependency
…nd scrape

Metric correctness (Group A):
- A1: Add overflow bucket (position 11) for durations > 10000ms and emit
  le="+Inf" as the final cumulative bucket (Prometheus requirement);
  NUM_BUCKETS=11, SLOTS_PER_HIST=13
- A2: Track unrecognized method paths under a synthetic method="unknown"
  label in requests_total (fixed cardinality, no raw string leak);
  NUM_METHODS=5
- A4: Gate duration recording by category -- only categories that
  represent actual backend/outbound work (success, auth_failed,
  connection_failed, tls_failed, authz_unverified, token_expired,
  token_invalid) contribute to the histogram; pre-connection rejects
  (input_invalid, body_too_large, config_conflict, capacity_exhausted,
  method_disabled, unknown_method, internal_error, query_invalid) are
  excluded. query_invalid is excluded because query parsing happens
  inside parse_input (step 1 of validate/1), before any eldap:open.

Scrape robustness (Group B):
- B3: Add catch-all clause in try_semaphore_usage/0 so an arbitrary exit
  degrades to unavailable rather than crashing the whole /api/metrics
  scrape
- B5: Make register/0 get-or-create -- only allocate counters when absent;
  a second call (e.g. supervisor restart) preserves existing values

Cleanup (Group C):
- C6: Replace find_bucket_pos coupling in build_cumulative_buckets/2 with
  direct positional enumeration via lists:zip; layout is expressed once
  in the macros and cannot drift

Tests: 13 CT cases covering all new behaviour (inf_bucket_exists,
duration_gating_excludes_fast_rejects, unknown_method_counted,
semaphore_exit_catch_all, register_preserves_counters, plus existing).
@sdewhitt
sdewhitt requested a review from lukebakken August 6, 2026 22:36

@lukebakken lukebakken left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All six findings from the earlier review are addressed in 097938e, each with test coverage, and the prometheus dependency now goes through rabbitmq_prometheus per the Makefile thread. Approving.

  • +Inf/overflow bucket added (position 11); build_cumulative_buckets/2 emits {infinity, sample_count}, which renders as le="+Inf"
  • unknown methods counted under a fixed method="unknown" label (no raw-string cardinality risk)
  • try_semaphore_usage/0 has a : catch-all so an arbitrary semaphore exit no longer fails the whole scrape
  • duration histogram gated by is_timed_category/1 so pre-connection rejects no longer skew latency
  • register/0 is get-or-create, preserving counts across re-registration
  • build_cumulative_buckets/2 enumerates slots directly instead of round-tripping through find_bucket_pos/1

Verified locally at deps/aws on feature/auth-validation-metrics (HEAD 097938e): compile, dialyzer (after a PLT rebuild, since the dependency set changed), eunit (183), and ct-aws_auth_validate_metrics (13 Ok / 0 failed) all pass.

@lukebakken
lukebakken merged commit 503f783 into amazon-mq:main Aug 6, 2026
@the-mikedavis

the-mikedavis commented Aug 7, 2026

Copy link
Copy Markdown
Member

Actually I was curious if we could have rabbitmq-stream-s3 depend on prometheus and not rabbitmq_prometheus. I think that should still work (i.e. the collector will be registered) and it would drop the dependency on rabbitmq_prometheus.

We don't call anything within the rabbitmq_prometheus plugin directly. IIRC the collector is registered during boot - something scans for modules which declare the prometheus_collector behaviour.

@the-mikedavis

Copy link
Copy Markdown
Member

Another example: cloudamqp/rabbitmq-delayed-message-exchange#17

@lukebakken

Copy link
Copy Markdown
Contributor

Ah OK. Well, I don't think it's too much of a hassle / hardship since rabbitmq_prometheus is tier-1.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-auth-validation Area: The auth-validation endpoint (aws_auth_validate_*). C-enhancement Category: Improvements dependencies Pull requests that update a dependency file E-large Effort: Hard. Thorough code-base knowledge and high-level vision required. P-low Priority: Low. Minor; can wait.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants