Skip to content

feat(auth): use central application handoff - #17

Merged
jzhao234 merged 1 commit into
mainfrom
feat/central-auth-client
Sep 11, 2026
Merged

jzhao234 merged 1 commit into
mainfrom
feat/central-auth-client

Conversation

@jzhao234

Copy link
Copy Markdown
Contributor

TLDR

Replaces Explorer's duplicated local password implementation with the central Auth authorization-code flow. Explorer preserves the existing Elcano provider and now owns only its deployment-local email allowlist and revocable application sessions.

Motivation

Running a separate password database in every Explorer, Lens, and Pages deployment would multiply credentials and security implementations. Authentication should be central while each application independently decides which authenticated client users it admits.

Fix

  • Add a central Auth client with exact callbacks, state, nonce, S256 PKCE, confidential token exchange, redirect refusal, response-size limits, and generic browser-facing failures.
  • Apply an operator-managed, deployment-local email allowlist after central authentication.
  • Issue random 256-bit Explorer-only sessions stored as SHA-256 hashes with 60-minute idle and 12-hour absolute expiration.
  • Revoke sessions immediately on access removal and protect logout with CSRF.
  • Remove the temporary Explorer-local password database, routes, templates, admin commands, tests, and Argon2 dependency.
  • Preserve the legacy Elcano external-cookie provider and its existing application behavior.
  • Add explorer access grant/revoke/list commands, bootstrap and update plumbing, deployment documentation, and a signed-out page.

Tests

  • 87 passed: .venv/bin/python -m pytest -q
  • Ruff check passed
  • Ruff format check: 16 files already formatted
  • bash -n and shellcheck passed for deployment scripts
  • git diff --cached --check
  • gitleaks staged scan: no leaks

Checklist

  • Ruff lint and format checks pass
  • Full tests pass without AWS credentials
  • Fixtures remain synthetic
  • Documentation and deployment templates are updated
  • New source files carry SPDX headers
  • No secrets, customer data, or internal hostnames are included

Screenshots

Not included. This removes the local login/password pages; the only new page is the small signed-out handoff page, while redirects, cookies, callbacks, allowlist denial, and logout behavior are covered by endpoint tests.

TLDR\n\nReplace Explorer's duplicated local password system with the central Auth authorization-code flow. Explorer keeps its Elcano integration and now owns only its deployment-specific access list and revocable application sessions.

Motivation\n\nMaintaining passwords independently in every client application creates inconsistent security behavior and additional accounts for users. Explorer should delegate authentication while still deciding which authenticated emails may access each deployment.

Fix\n\n- Add a central Auth client with exact callback, state, nonce, S256 PKCE, confidential token exchange, redirect refusal, and bounded responses.\n- Add a SQLite email access list plus hashed opaque Explorer sessions with idle and absolute expiry, CSRF logout, and immediate revocation.\n- Remove the temporary Explorer-local password implementation and Argon2 dependency.\n- Preserve the legacy Elcano external-cookie provider as the default mode.\n- Add access-list CLI commands, bootstrap/update plumbing, deployment documentation, and a signed-out page.

Tests\n\n- 87 passed: .venv/bin/python -m pytest -q\n- Ruff check passed and 16 files formatted\n- bash -n and shellcheck passed for deployment scripts\n- git diff --cached --check\n- gitleaks staged scan: no leaks
@jzhao234
jzhao234 merged commit bd1c5d4 into main Sep 11, 2026
4 checks passed
@jzhao234
jzhao234 deleted the feat/central-auth-client branch September 11, 2026 17:24
@jzhao234

Copy link
Copy Markdown
Contributor Author

Review pass (second reviewer). Verdict: sound and compatible with ElcanoTek/auth#20. State and nonce are 256-bit and single-use, PKCE S256 with an 86-character verifier, exact callback from the configured public origin, Basic client auth with the client id echoed in the form, redirect refusal and a bounded body on the token response, transaction popped before exchange, app session hashed at rest with idle and absolute limits, access list is default-deny, next is restricted to local paths.

Pushed one follow-up commit with low-risk hardening: the token response is now checked for iss, aud and exp (60-second skew); a 400 from the token endpoint tells the user to try again instead of reporting an outage (this is what a second tab produces); two compare_digest calls no longer raise on non-ASCII input, which a visitor could trigger on the callback; .env is written owner-only since it holds the client secret. 98 tests, ruff clean.

For the owner (also in the brain vault):

  1. This PR deletes the local password login merged two days ago in Add isolated local password authentication #15. Confirm no deployment enabled local mode in between; the bootstrap now refuses it with a pointer to central.
  2. Session validation writes last_seen_at on every request. The auth service touches at most every 5 minutes; consider the same here.
  3. No Content-Security-Policy on Explorer pages (pre-existing).
  4. /root/explorer's local main has diverged from origin (84 ahead, 9 behind) and both feature worktrees live under /tmp, which does not survive a reboot.

jzhao234 added a commit that referenced this pull request Sep 11, 2026
…; tell users to retry a rejected code (#18)

TL;DR: Review follow-ups on the central-auth client (#17). The token response is checked for iss, aud and exp (60s skew); a 400 from the token endpoint maps to "Sign-in expired. Try again." instead of a 502; state and nonce compares operate on bytes so non-ASCII input cannot raise; bootstrap writes .env owner-only. 98 tests, ruff, shellcheck, CodeQL clean.
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