Authfu

Quickstart · Python / Streamlit

Add Authfu to Streamlit

Streamlit has native OpenID Connect. Point it at Authfu and sign-in is st.login() — no auth code to write.

  1. Create the Authfu app

    From the terminal, if you have the CLI:

    bash
    authfu login
    authfu apps create my-streamlit-app \
      --redirect-uri http://localhost:8501/oauth2callback --link

    Or in the console at authfu.app: create an app and register the redirect URI http://localhost:8501/oauth2callback — Streamlit’s fixed callback path on its default port. Either way you end with a client ID and secret.

  2. Install

    bash
    python3 -m venv .venv
    .venv/bin/python -m pip install "streamlit>=1.42" Authlib

    Native auth arrived in Streamlit 1.42; Authlib is its OIDC engine.

  3. Configure secrets.toml

    toml
    # .streamlit/secrets.toml  — keep this file out of git
    [auth]
    redirect_uri = "http://localhost:8501/oauth2callback"
    # Generate with: openssl rand -hex 32
    cookie_secret = "replace-with-a-long-random-value"
    
    [auth.default]
    client_id = "your-authfu-client-id"
    client_secret = "your-authfu-client-secret"
    server_metadata_url = "https://authfu.app/.well-known/openid-configuration"

    server_metadata_url is Authfu’s discovery document — Streamlit reads every endpoint it needs from there. The cookie_secret signs the session cookie; make it long and random.

  4. Sign in and read the user

    python
    # app.py
    import streamlit as st
    
    if not st.user.is_logged_in:
        if st.button("Log in with Authfu", type="primary"):
            st.login()
        st.stop()
    
    st.write(f"Signed in as {st.user.get('name')} ({st.user.get('email')})")
    
    # Authfu's roles claim rides the ID token — authorize with it directly.
    roles = st.user.get("roles", [])
    if "admin" in (roles if isinstance(roles, list) else [roles]):
        st.success("Admin area unlocked by the 'admin' role.")
    
    if st.button("Log out"):
        st.logout()

    st.user carries Authfu’s claims: sub, email, name — and roles, so authorization is a list check away.

  5. Run it

    bash
    .venv/bin/streamlit run app.py

    Your first sign-in flips the app to Connected in the Authfu console — proof the wiring is right rather than a guess.

Troubleshooting

Redirect mismatch? The registered URI must match exactly — http://localhost:8501/oauth2callback, scheme, port, and path included. Login loops? Set a real cookie_secret. No roles in st.user? Assign one: authfu roles assign you@example.com admin.

Next steps