Expand description
Adaptive session replay defense mode for browser identity.
§What is “replay-style” anti-bot detection?
Several anti-bot vendors record a session (TLS handshake + a sequence of navigations + identity surface values) and replay the same artifacts later. If the same fingerprint, nonce, or challenge response shows up in two different sessions (or after a site-side rotation), the vendor flags the second session as a replay. This is distinct from coherence drift (one session has multiple inconsistent identity surfaces) — replay detection specifically looks at session-lifetime artifacts:
- The session nonce issued by a challenge / challenge-response endpoint.
- The browser fingerprint captured at session start.
- The age of the session.
§How this module helps
ReplayDefensePolicy captures three orthogonal levers the
runner can use to defeat replay-style detection:
ReplayDefensePolicy::rotation_interval— maximum session age before the runner must rotate the browser.ReplayDefensePolicy::nonce_validity_window— maximum age of a session nonce. After this window the nonce is no longer trustworthy and the session must be reset.ReplayDefensePolicy::force_reset_on_drift— whentrue, signature drift (the fingerprint captured at session start no longer matches the freshly observed one) triggers a forced refresh of the sticky browser context.
The deterministic check function evaluates a
ReplayDefenseState (the per-session record) against a
ReplayDefenseCheckInput (the observed context) and returns a
ReplayDefenseDecision. The decision is purely derived from
the inputs — no I/O, no clock reads — so unit tests can exercise
the full state space.
§Integration with AcquisitionRunner
AcquisitionRequest::replay_defense
carries the live context (policy + state) into the runner. The
runner evaluates the policy before any stage executes:
- The decision is logged via
ReplayDefenseReport::log. - If the decision is invalid and
force_reset_on_driftistrue, the runner callsBrowserPool::release_contextto invalidate the sticky session, then short-circuits with aStageFailureKind::Setupfailure taggedreplay_defense_forced_refresh. - The full report is attached to the
AcquisitionResult::replay_defensefield so downstream automation can attribute the rejection.
§Feature flag
This module is default-on and is always compiled as part of
the stygian-browser crate. No new feature gate is introduced.
§Default policy
ReplayDefensePolicy::default returns a deterministic
baseline that is safe to ship in production:
rotation_interval=1800 s(30 min)nonce_validity_window=300 s(5 min)force_reset_on_drift=true
Callers can override any field via the with-builder methods or by deserialising a config from JSON / TOML.
§Example
use stygian_browser::replay_defense::{
ReplayDefenseCheckInput, ReplayDefenseDecision, ReplayDefensePolicy,
ReplayDefenseState, check,
};
use std::time::Duration;
let policy = ReplayDefensePolicy::default();
let captured = stygian_browser::freshness::unix_epoch_ms();
let state = ReplayDefenseState::with_fingerprint(
"example.com",
"sha256:abc",
Some("nonce-001"),
captured,
);
let observed = ReplayDefenseCheckInput::new(
"example.com",
Some("sha256:abc"),
Some("nonce-001"),
captured + 1_000,
);
let decision = check(&policy, &state, &observed);
assert!(decision.is_valid());Structs§
- Replay
Defense Check Input - Observed context passed to
checkon every session reuse. - Replay
Defense Policy - Adaptive session-replay defense policy.
- Replay
Defense Reason - Structured reason a replay-defense check invalidated a session.
- Replay
Defense Report - Compact replay-defense report attached to acquisition results
and emitted via
tracing. - Replay
Defense State - Per-session replay-defense state captured when the session was first bound.
Enums§
- Replay
Defense Decision - Decision produced by
check. - Replay
Defense Error - Errors produced by replay-defense policy / state construction.
- Replay
Defense Invalidation Kind - Machine-readable reason tag attached to
ReplayDefenseReason.
Functions§
- check
- Evaluate
policy+stateagainstinputand return a deterministicReplayDefenseDecision. - unix_
epoch_ ms - Current Unix epoch in milliseconds, clamped to
u64.