Skip to content

Limit failed Console tokens and passwords per client address - #1790

Merged
JacobStephens2 merged 4 commits into
issue-1753from
issue-1758
Nov 5, 2026
Merged

JacobStephens2 merged 4 commits into
issue-1753from
issue-1758

Conversation

@JacobStephens2

@JacobStephens2 JacobStephens2 commented Nov 5, 2026 •

Copy link
Copy Markdown
Owner

Summary

Failed Console bearer tokens and password sign-ins now share a per-client-IP budget, so changing holders or account names cannot avoid the limit.

failed token or password
  client = last X-Forwarded-For address only from proxy 127.0.0.1; otherwise peer
  failures 3–7 → increasing response delay
  failure 8    → 429, Retry-After, 60-second cool-down

Counts expire after 60 idle seconds and clear on restart. Success leaves counts intact. The existing account password slowdown and five-tries-per-code limit stay in place. The manual, hand-written site pages and OpenAPI describe the behavior.

Closes #1758

Evidence

Execution evidence

  • Before: cargo test --test console failed_tokens_are_slowed_then_limited_per_forwarded_address failed: left: 401, right: 429.
    After: same command passed: 1 passed; 0 failed.
  • Before: cargo test --test console failed_passwords_are_limited_by_client_address_across_account_names failed: left: 401, right: 429.
    After: same command passed: 1 passed; 0 failed.
  • Before: cargo test --test console openapi_equals_cli_and_describes_operations_without_local_secrets failed: left: Null, right: "integer" for the missing 429 retry metadata.
    After: same command passed: 1 passed; 0 failed.
  • cargo test --test console rate_limit: all three HTTP tests passed, including a real peer at 127.0.0.2 with rotating forwarded headers, combined token/password failures, and restart clearing.
  • cargo check --locked: passed.
  • scripts/affected-tests 39ce50f9473ccccc202200a13a2e6c0942030e06: site tests 62 passed (130.25s), locked Console build passed (130.17s), Console browser tests 126 passed (205.78s).
  • The first full Rust attempt stopped on an existing clock race: the authenticated parity test compared CLI stage age 6 with HTTP age 7. fffaa482 shares the existing frozen-wall-clock fixture between those processes; both affected parity tests pass.
  • Full Rust: CI on fffaa482 passed cargo nextest run: 3767 tests run: 3767 passed (2 slow), 82 skipped. Execution took 888.000s, with 1m 06s compilation reported separately. The redundant local retry was stopped after successful CI covered this exact head, following docs/testing.md.
  • CI's site and Console browser jobs also passed, alongside formatting, clippy and release artifact builds.
  • cargo fmt -- --check and git diff --check: passed.

Seams under test: the real Console binary over HTTP, with passwords and tokens configured through the CLI; OpenAPI is compared over HTTP and its CLI twin. No test reaches into limiter or token-store internals.

Visual evidence

Documentation pages, matched viewports and expanded sections. Captures are in a secret Gist; no evidence media is added to this branch.

Console API manual — 1440×900

Before
After

Console API manual — 390×844

Before
After

Homepage Console workflow — 1440×900

Before
After

Homepage Console workflow — 390×844

Before
After

How it works: Console API — 1440×900

Before
After

How it works: Console API — 390×844

Before
After

Architecture: Console authentication — 1440×900

Before
After

Architecture: Console authentication — 390×844

Before
After

Review coverage

Reviewed against issue-1753, pinned at remote commit 39ce50f9473ccccc202200a13a2e6c0942030e06. Standards raised one Duplicated Code judgement call; it was addressed in 25e78b17 and the reviewer confirmed the fix. Spec raised zero findings and also reviewed the subsequent shared clock-fixture fix. Neither axis raised an incorrect-behavior finding.

Both axes read all 12 changed files, including generated site/docs/index.html. No generated output was excluded. Unread changed files: none for Standards; none for Spec. Reports and summary.json are retained with this Session.

Unaddressed findings

Standards

None.

Spec

None.

Security

None.

Security review outcome

No unaddressed introduced findings.

Merge Danger

Door: two-way

No data migration or new dependency. Reverting removes the in-memory limit.

Blast Radius: authentication

Clients sharing an IP share its failure budget. A custom proxy must set or append the real client address; missing or malformed forwarding falls back to the proxy peer. Existing signed-in sessions continue through their current authorization path.

Built with codex codex-cli 0.164.0 · gpt-6.1-sol · xhigh

@JacobStephens2
JacobStephens2 merged commit 3d38143 into issue-1753 Nov 5, 2026
16 checks passed
@JacobStephens2
JacobStephens2 deleted the issue-1758 branch November 5, 2026 19:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant