Streamlit Passwordless enables secure, passwordless authentication for Streamlit apps using Passkeys powered by Bitwarden Passwordless.dev.
It provides ready-to-use Streamlit components, a full SQLAlchemy user model, and a command-line interface β so you can add Passkey (FIDO2) sign-in to your Streamlit app in minutes.
π Live demo: https://passwordless.streamlit.app
- β¨ Features
- π¦ Installation
- βοΈ Configuration
- π Example
- π§© Examples
- π§± Architecture & Import Conventions
- π» CLI Usage
- π§± Database Models
- π§ Project Status
- π€ Contributing
- π License
- π Resources
- π API Reference
- π Streamlit components for passkey registration, sign-in, and sign-out
- π§© Built-in SQLAlchemy models for users, roles, emails, and sign-ins
- π‘οΈ Role-based authorization for individual Streamlit pages via the decorator API
- π§± Compatibility with any SQL backend (e.g. SQLite, PostgreSQL, Microsoft SQL Server)
- βοΈ Simple configuration via environment variables or Streamlit secrets
- π» CLI tools for database initialization and administration
- π§βπ» Native integration with Streamlitβs UI and state model
- π‘ Fully type-hinted and documented
Install from PyPI:
pip install streamlit-passwordlessInstall from conda-forge:
conda install conda-forge::streamlit_passwordlessStreamlit Passwordless can be configured via environment variables or the Streamlit secrets' file
(.streamlit/secrets.toml or ~/.streamlit/secrets.toml).
| Variable | Description | Default |
|---|---|---|
STP_DB_URL |
SQLAlchemy database URL | sqlite:///streamlit_passwordless.db |
STP_BWP_PUBLIC_KEY |
Bitwarden Passwordless.dev public key | Required |
STP_BWP_PRIVATE_KEY |
Bitwarden Passwordless.dev secret key | Required |
STP_DB_SCHEMA |
Optional schema name for e.g. PostgreSQL or SQL Server (environment variable only) | None |
This section shows two ways to get started:
- Quick Start (SQLite) β easiest way to try it out.
- Using Another Database Backend β for production environments.
~ $ mkdir stp_demo && cd stp_demo
~/stp_demo $ python -m venv .venv
~/stp_demo $ source .venv/bin/activate # (on Windows: .venv\bin\Activate.ps1)
~/stp_demo (.venv) $ python -m pip install streamlit-passwordless
~/stp_demo (.venv) $ mkdir .streamlit && touch .streamlit/secrets.toml2. Add your Bitwarden Passwordless.dev keys to .streamlit/secrets.toml:
[streamlit-passwordless]
STP_BWP_PUBLIC_KEY = "<PUBLIC_KEY>"
STP_BWP_PRIVATE_KEY = "<PRIVATE_KEY>"# app.py
import streamlit as st
import streamlit_passwordless as stp
def main() -> None:
st.set_page_config(page_title='Streamlit Passwordless', page_icon='β¨')
st.title('Streamlit Passwordless Demo')
# initialize client and database
client, session_factory, _ = stp.setup(create_database=True)
with session_factory() as session:
stp.db.init(_session=session) # create the default roles once on startup
with st.container(border=True):
stp.bitwarden_register_form(client=client, db_session=session, border=False)
st.write('Already have an account?')
stp.bitwarden_sign_in_button(client=client, db_session=session)
stp.sign_out_button(use_container_width=True)
if __name__ == '__main__':
main()~/stp_demo (.venv) $ streamlit run app.py
You can now view your Streamlit app in your browser.
Local URL: http://localhost:8501Open your favorite browser at http://localhost:8501 and enjoy passwordless registration and sign-in! π
To use another database backend, update STP_DB_URL in your secrets file or environment variable:
[streamlit-passwordless]
STP_DB_URL = "postgresql+psycopg://user:password@localhost/stp_demo"
STP_BWP_PUBLIC_KEY = "<PUBLIC_KEY>"
STP_BWP_PRIVATE_KEY = "<PRIVATE_KEY>"Example connection URLs:
| Database | Example URL |
|---|---|
| PostgreSQL | postgresql+psycopg://user:password@localhost/dbname |
| SQL Server | mssql+pyodbc://user:password@localhost/dbname?driver=ODBC+Driver+18+for+SQL+Server |
| MySQL | mysql+pymysql://user:password@localhost/dbname |
Once configured, initialize the database and create an admin user via the CLI.
Restrict access to Streamlit pages based on user roles using the decorator API:
import streamlit as st
import streamlit_passwordless as stp
@stp.authorized(role=stp.AdminRole, redirect="sign_in_page.py")
def admin():
st.title("Admin Page")
st.write("Only signed-in admins can view this page.")
if __name__ == '__main__':
admin()If a non-admin user attempts to access this page, they will automatically be redirected to the sign-in page.
The examples directory includes ready-to-run demonstration apps showing how to use Streamlit Passwordless in different contexts:
| Example | Description |
|---|---|
examples/mwp.py |
π§± A minimal single-page Streamlit app demonstrating basic passkey registration and sign-in. This corresponds to the Quick Start (SQLite) example in this README. |
examples/app |
π A multi-page Streamlit app showcasing the core features of Streamlit Passwordless β including registration, sign-in, role-based authorization, and automatic page redirects. |
π Try out and explore the examples above locally to better understand how Streamlit Passwordless works.
Note: Run the examples from inside the
examples/directory (cd examples) to avoid import errors.
Each example can be launched directly with Streamlit from your local terminal.
cd examples
streamlit run mvp.pycd examples
streamlit run app/main.pyThen open your browser at http://localhost:8501
You can register new users, sign in, and explore the authentication and authorization flows.
Streamlit Passwordless is designed with a clear, discoverable import structure.
Always import the package under the alias stp:
import streamlit_passwordless as stpCommon entry points are available directly on stp (this is a short, non-exhaustive list):
# Setup & session
stp.setup()
stp.authenticated()
stp.get_current_user()
# Built-in UI
stp.bitwarden_register_form()
stp.bitwarden_register_form_existing_user()
stp.bitwarden_sign_in_button()
stp.bitwarden_sign_in_form()
stp.sign_out_button()
# Authorization
stp.authorized()
# Models (commonly imported when interacting with user data)
from streamlit_passwordless import User, Role, CustomRole, Email, UserSignIn
# Default roles
from streamlit_passwordless import Viewer, UserRole, SuperUser, AdminNote: Most UI functions require a Bitwarden Passwordless.dev client (client) and a database session (db_session). See the Examples section for complete usage.
All database functionality is available under stp.db, with SQLAlchemy models exposed via stp.db.models.
# Database helpers
stp.db.init()
stp.db.get_user_by_user_id()
# Models
from streamlit_passwordless.db.models import User, Role, CustomRole, Email, UserSignInThis modular layout keeps everyday usage simple (stp.*), while making lower-level pieces (stp.db.*) easy to find.
For a detailed API reference, see the API Reference section (coming soon).
Streamlit Passwordless includes a convenient command-line interface (CLI) called stp.
Create the tables and the default roles (Viewer, User, SuperUser, Admin):
stp run initThis will launch a small Streamlit app that:
- Creates and initializes the database if it does not exist
- Allows you to create the first admin user
Once initialized, you can manage users and passkeys via the admin web interface:
stp run adminThis launches the Streamlit Passwordless Admin App where only admin users can:
- Sign in securely using passkeys
- Create, modify, enable, or disable users
- Register additional passkeys for users
Perfect for managing your appβs user base directly from the browser.
Note: the admin app is still experimental and not yet feature-complete.
The following SQLAlchemy models are included:
| Model | Description |
|---|---|
User |
Represents an application user |
Role |
Predefined roles: Viewer, User, SuperUser, Admin (extendable if needed) |
CustomRole |
App-specific user roles |
Email |
User email addresses and verification info |
UserSignIn |
Tracks sign-in attempts and metadata |
The models include audit columns (updated_at, updated_by, created_at, created_by)
and work seamlessly with an SQL backend.
Roadmap:
- Admin UI enhancements (create and update roles and emails)
- Support for step-up authentication
- Support for magic-link sign in and email verification
- Improved error handling and display of passkey related errors
The project is open-source but not open contribution.
Feature requests and suggestions are welcome β but pull requests are not currently accepted.
Contributions focused on bug reports and documentation improvements are especially welcome.
Streamlit Passwordless is distributed under the MIT License.
Detailed API documentation for Streamlit Passwordless will be available in future releases.