Skip to content

Add opt-in password auth gate#85

Open
dkedar7 wants to merge 2 commits into
devfrom
feature/auth
Open

Add opt-in password auth gate#85
dkedar7 wants to merge 2 commits into
devfrom
feature/auth

Conversation

@dkedar7

@dkedar7 dkedar7 commented May 2, 2026

Copy link
Copy Markdown
Owner

Summary

Adds a single-kwarg password gate so Fast Dash apps shared via a tunnel aren't open to the public internet.

@fastdash(auth={"alice": "wonderland"})
def greet(name: str = "world") -> str:
    return f"Hello, {name}!"
  • Two configuration shapes: a {username: password} dict, or a callable (username, password) -> bool for custom verification (hashed stores, etc.).
  • /login + /logout routes; before_request middleware redirects unauthenticated visitors and blocks /\_dash-* so callback state can't leak.
  • Constant-time password compare (hmac.compare_digest).
  • FASTDASH_SECRET_KEY env var for restart-stable sessions; random per-process key otherwise.
  • current_user() re-exported from the package root for callbacks to read the signed-in username.

This is the smallest possible auth surface — covers the "share with a colleague behind a tunnel" case. OIDC (Google/GitHub/Microsoft) is a follow-up.

Test plan

  • 17 new tests in tests/test_auth.py across 5 classes (disabled, dict auth, callable, validation, current_user)
  • Full suite green: 173 passing locally
  • Verified _dash-layout returns 401 when unauthenticated (callback state isolation)
  • Manual smoke test: build a Fast Dash app with auth=..., confirm login flow in browser

🤖 Generated with Claude Code

dkedar7 and others added 2 commits May 2, 2026 10:51
Fast Dash apps default to no auth — anyone with the URL can use them.
That's fine for local dev but blocks the demo→colleague hop the moment
the URL is shared via a tunnel.

Add an opt-in password gate via a single kwarg:

    @fastdash(auth={"alice": "wonderland"})
    def greet(name: str = "world") -> str:
        return f"Hello, {name}!"

The new fast_dash/auth.py installs /login and /logout routes plus a
before_request gate that redirects unauthenticated visitors. Passwords
are compared in constant time via hmac.compare_digest. Dash's
internal endpoints (/_dash-*) return 401 when unauthenticated to stop
callback state from leaking. Sessions sign with FASTDASH_SECRET_KEY
when set, otherwise a per-process random key.

Two configuration shapes:
- dict {"username": "password"} for the simple case
- callable (username, password) -> bool for custom verification
  against a hashed store

current_user() is exposed from the package root so callbacks can read
the signed-in username.

Tests cover 17 scenarios across five classes: disabled auth, dict
auth (login/logout/redirects/_dash-* blocking), callable verifier,
input validation, and current_user binding inside a request. Full
suite: 173 passing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The auth gate had /logout wired but no UI affordance — users had to
type /logout into the URL bar. Add a "Sign out" button to the right
side of the dmc header (just before the dark-mode toggle) that links
to /logout.

Rendered conditionally based on app._auth_config so the button is
absent for apps without auth. Wrapped in html.A because dmc.Button
doesn't support href directly.

Three new tests cover: button present when auth is on, absent when
auth is off, and the href points to /logout.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@dkedar7

dkedar7 commented Jul 4, 2026

Copy link
Copy Markdown
Owner Author

Keeping this open as an active TODO. It's currently conflicting with dev — it touches fast_dash/Components.py, fast_dash/__init__.py, and fast_dash/fast_dash.py, all of which moved substantially in the 0.4.0 UI overhaul and the 0.5.0 chat/sidecar + MCP work. It'll need a rebase onto current dev and a conflict pass before it can go anywhere.

Not merging or reworking the auth logic itself without a fresh requirements pass — auth is security-sensitive and the surface has drifted a lot since May. Flagging here so it's not silently stale.

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