Skip to content

P1 E10 F10.4g: warn on sustained refusal-only authentication traffic #274

Description

@gnanirahulnutakki

Problem

Sith now exposes one bounded aggregate denominator,
sith_auth_attempts_total{outcome="accepted|refused"}, for completed bearer-token and browser-session
verifier decisions. The portable Hub alert package does not yet surface the strongest truthful
authentication symptom available from that aggregate signal: all observed attempts are being
refused for a sustained period.

A generic refusal-ratio threshold is not justified without workload-specific baselines or a
negotiated objective. OWASP requires authentication successes and failures to be monitored while
explicitly warning that monitoring thresholds are not one-size-fits-all. This slice therefore does
not classify attacks and does not invent an SLO.

Contract

Add one aggregate warning when:

sum(increase(sith_auth_attempts_total{outcome="refused"}[15m])) >= 20
and
sum(increase(sith_auth_attempts_total{outcome="accepted"}[15m])) == 0
and
sum(count_over_time(sith_auth_attempts_total{outcome="accepted"}[10m])) > 0

and the condition remains true for 10m.

The last clause proves accepted-outcome telemetry is recent rather than merely present somewhere in
the 15-minute range. Ten minutes matches the existing Hub telemetry-missing tolerance and the alert
hold. The rule must aggregate every metric and scrape label away, emit one fixed-label warning, and
use static annotations. It reports refusal-only authentication traffic; it must not claim brute
force, credential stuffing, account compromise, actor attribution, or identity-level evidence.

Acceptance criteria

  • Exact expression, 15-minute outcome window, 10-minute accepted-sample freshness guard,
    inclusive 20-refusal guard, 10-minute hold, warning severity, static annotations, and
    ninth-rule limit are pinned by Go and shell contracts.
  • Promtool fixtures prove sustained firing and resolution, hostile-label aggregation into one
    alert, and that exactly 20 refusals satisfies the volume guard.
  • Missing data, missing or stale accepted telemetry, fewer than 20 refusals, accepted-only
    traffic, any accepted traffic in the same window, transient refusal-only traffic, and counter
    resets remain quiet.
  • A regression proves the original two-clause expression would remain true on stale accepted
    samples while the guarded expression and alert stay quiet.
  • The runbook distinguishes an operational symptom from attack attribution, directs operators
    to verify telemetry completeness before interpreting it, and keeps threshold overrides local
    and reviewed.
  • README, E10 epic notes, GSTACK journal, Notion, Obsidian, and the EXTENDED session checkpoint
    document meaning, triage, privacy, cost, and nonclaims.
  • Focused/race tests, full CI, vulnerability checks, forced-RLS/isolation, release/Helm/OCI/Kind
    gates, secret scan, repeated CodeRabbit review, signed DCO/GSTACK, exact-head hosted gates,
    merge, security queues, and exact post-merge dev gates pass.

Security, operability, and cost boundary

No tenant, workspace, actor, identity, intent, trace, request, credential, endpoint, verifier error,
or scrape/source label may survive aggregation. The rule adds one evaluation per minute over two
existing fixed-cardinality series and at most one warning instance. count_over_time is summed
before matching and creates no recording series. The change adds no runtime request path, listener,
Service, exporter, storage, remote write, receiver, credential, network request, or cloud resource.

This warning is not an attack detector, SLO, error budget, page, authentication-completeness claim,
OIDC-provider signal, authorization-denial signal, or proof that the monitoring path is healthy.
The existing telemetry-missing alert remains the separate metamonitoring signal.

Primary references

Parent: #28 (E10)

Metadata

Metadata

Assignees

No one assigned

    Labels

    phase-1Phase 1: read-only federation

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions