privacyIDEA for Self-Hosted Multi-Factor Authentication
:closed_lock_with_key: multi factor authentication system (2FA, MFA, OTP, FIDO Server)
At a glance
- What is it?
- privacyIDEA is an on-premise MFA platform for organizations that need to protect applications, SSH, VPNs, identity providers, and web portals with OTP, passkeys, push authentication, and other factors. Its main trade-off is operational: it keeps sensitive data inside the operator's infrastructure but requires database, encryption-key, audit-key, and upgrade management.
- Who is it for?
- Adopt privacyIDEA when the requirement is self-hosted MFA across heterogeneous applications and existing user stores, provided an administrator can own the database, encryption keys, configuration, and upgrade path. Do not choose it as a lightweight library when an application only needs a single local OTP check.
- Can I use it commercially?
- Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What privacyIDEA Solves
privacyIDEA addresses the problem of adding a second authentication step to systems that do not share one common identity provider. The README describes it as an open-source MFA platform for applications including SSH, VPNs, identity providers such as Keycloak, and web portals. Its intended audience includes system administrators and organizations that want to control where authentication data is stored rather than place that control in an external SaaS platform.
The platform is not limited to one token format. The documented factors include FIDO2 and WebAuthn devices, passkeys, PUSH notifications, TOTP, HOTP, TiQR, SMS, email, SSH keys, security questionnaires, registration codes, and smartcards using PIV or x509 certificates. That breadth matters when an organization already has a mixture of mobile devices, hardware keys, smartcards, and directory users. The project presents those factors as alternatives within one management platform rather than as separate products that need to be joined by a home-grown authentication layer.
privacyIDEA also aims to avoid requiring a particular identity ecosystem. The README names AD, LDAP, SQL, and EntraID as possible user stores. Integrations listed by the project include Linux PAM, a Windows Credential Provider, Keycloak, ADFS, Shibboleth, SimpleSAMLphp, RADIUS-based VPNs, SSH, Apache, Nginx, nextCloud, and ownCloud. A REST API is also mentioned for web applications. The practical problem is therefore not simply generating an OTP. It is administering factors across different identity sources while exposing consistent authentication endpoints to systems that do not all speak the same protocol.
privacyIDEA's Flask and Database Architecture
The repository identifies privacyIDEA as a Python project and classifies it as a Flask application in `pyproject.toml`. It requires Python 3.11 or later and lists Python 3.11, 3.12, 3.13, and 3.14 as supported versions. The top-level layout includes the `privacyidea/` application package, `authmodules/`, `pi-manage`, migration files, deployment assets, documentation, translations, and tests. This indicates a server application with a management command and an authentication extension area, rather than a standalone command-line OTP generator.
The README says that database models are defined in `models.py` and tested in `tests/test_db_model.py`. It also names `lib/config.py` as the library responsible for basic configuration in the database. The management workflow calls `./pi-manage create_tables` to create database tables, `./pi-manage create_enckey` to create an encryption key, and `./pi-manage create_audit_keys` to create the audit-log key. Those commands show that configuration and security state have separate setup concerns. A deployment that creates the database but omits the required keys is incomplete.
Configuration can be supplied through a config file selected with `PRIVACYIDEA_CONFIGFILE`, or through individual `PRIVACYIDEA_<KEY>` environment variables. The `.env.example` states that Flask removes the `PRIVACYIDEA_` prefix and injects the resulting key into `app.config`. Individual variables override the config file. The example also documents configuration classes selected through `PI_CONFIG_NAME`, including development, testing, production, and docker configurations. This layered configuration model is useful for controlled deployments, but it gives operators several places where a value can be changed. A successful installation therefore depends on documenting which config class and external settings are in effect.
The documented development data path is concrete enough to understand the intended startup sequence: create tables, create the encryption key, optionally stamp the development database to `head`, create audit keys, create the first administrator, and run the server. The README does not document the complete request flow for every factor, nor does it define the production topology in this excerpt. The confirmed architecture is therefore best understood as a Flask service backed by database state, managed through `pi-manage`, with factor and integration behavior organized inside the application and `authmodules/`.
Installing privacyIDEA for a First Local Run
The README sends readers to the linked installation documentation for setting up a system to run. The following sequence is explicitly labeled for a development environment, so it should not be mistaken for a production deployment guide. It starts by obtaining the repository and creating an isolated Python environment.
git clone https://github.com/privacyidea/privacyidea.git
cd privacyidea
virtualenv venv
source venv/bin/activate
pip install -r requirements.txtThese commands clone the default project, create a directory named `venv`, activate it, and install the pinned requirements. The requirements file identifies itself as generated by `pip-compile` with Python 3.11 and includes hashes for dependency artifacts. If the goal is to run the test suite, the README also directs developers to install the additional test dependencies.
pip install -r tests/requirements.txtThe server needs a config file before the management commands are run. The README points to the installation documentation for creating that file and does not provide a complete `pi.cfg` example. After the configuration exists, the database and cryptographic state are prepared with these commands.
./pi-manage create_tables
./pi-manage create_enckey
./pi-manage db stamp head -d migrations/
./pi-manage create_audit_keys
./pi-manage admin add <username>The first two commands create database tables and the encryption key. The `db stamp head -d migrations/` command is documented as optional for keeping the development database upgradable and simplifying updates. The audit-key command creates the key used by the audit log. Replace `<username>` with the administrator account name when running the final command.
The development server can then be started with the management runner.
./pi-manage runThe README says to open `http://localhost:5000` and log in as the administrator. It does not document the exact login sequence beyond that point, nor does this excerpt provide a REST request for enrolling a passkey or issuing an OTP. A first real verification should therefore be limited to the documented startup result until the separate installation and API documentation is consulted.
Factor Coverage and Integration Boundaries
privacyIDEA's strongest design decision is factor abstraction across protocols that behave very differently. FIDO2 and WebAuthn devices require compatible clients and credential ceremonies. TOTP and HOTP use shared secrets and time or counter algorithms. PUSH depends on the privacyIDEA Authenticator. SMS and email depend on external delivery infrastructure. Smartcard enrollment depends on the named Microsoft CA service and a compatible PIV device. The project groups these under one administration system, but it does not make them operationally equivalent.
The listed mobile support includes the privacyIDEA Authenticator for PUSH, TOTP, and HOTP. The README also says that standard TOTP and HOTP clients such as Google Authenticator are compatible. That gives an organization a choice between a project-specific authenticator and established software tokens. TiQR, SMS, email, SSH keys, questionnaires, and registration codes broaden the set further. Each additional factor adds a provisioning path, a recovery policy, and a failure mode that must be handled.
The integration list is similarly broad, but it is not evidence that every deployment requires the same components. PAM integration is relevant to Linux hosts, while the Windows Credential Provider addresses a different operating-system surface. Keycloak, ADFS, Shibboleth, and SimpleSAMLphp solve federation and identity-provider integration problems. RADIUS support covers selected VPN workflows. Apache, Nginx, and arbitrary web portals depend on the REST API and the authentication flow that the application uses. The README lists these connections, but it does not provide configuration files or step-by-step instructions for each one in the shown text.
This makes privacyIDEA more suitable for organizations with heterogeneous infrastructure than a single-purpose OTP plugin. It also makes evaluation more demanding. An administrator needs to identify the actual applications, protocols, identity sources, factor devices, and recovery procedures before deciding whether the platform is a fit.
Operational Limits of a Self-Hosted MFA Platform
The clearest limitation is that privacyIDEA is infrastructure an operator must run. The README requires a config file, database tables, an encryption key, audit keys, and an administrator account. The project provides management commands, but the repository excerpt does not document backup procedures, disaster recovery, secret rotation, database replication, or production monitoring. Those omissions do not mean the product lacks such procedures, but they mean they are not confirmed here.
The README also distinguishes the development database workflow from a full production installation. Its first-run commands use a local server at `http://localhost:5000`, while production requirements are deferred to external installation documentation. The repository includes `deploy/`, `compose-dev.yml`, and a `dev/` directory, but the listed contents do not establish which deployment arrangement is appropriate for a particular organization. Using a development configuration as a production configuration without checking the documented requirements could leave security and availability decisions unexamined.
Factor choice creates another constraint. A user who loses a FIDO2 device needs an enrollment or recovery path. A user who loses a phone may need an alternative factor. A shared TOTP secret and a push registration are not interchangeable credentials. The README lists many options, but it does not say how every recovery workflow is configured or how policy should prevent fallback to a weaker factor. For small deployments, the breadth may be unnecessary. For larger deployments, the breadth can be useful only if administrators define enrollment, revocation, recovery, and support procedures.
The project is also not a complete identity provider. The README positions it as an MFA layer for systems such as Keycloak, ADFS, LDAP, AD, and SQL user stores. That is useful when an organization wants to add a factor without replacing its primary identity system. It is the wrong choice when the requirement is a full identity lifecycle product or when a single application only needs a local password and OTP check.
privacyIDEA Compared with Application-Local OTP
The main alternative is application-local OTP implemented inside the service that needs authentication. A local implementation can send a request to a small service that creates or checks a token, or it can embed an OTP library and its own database records. The difference is architectural. privacyIDEA provides a centralized authentication platform with multiple factors, external identity-store connections, integrations, audit-related setup, and a REST API. A local implementation keeps the dependency and state inside one application, which can be easier to reason about when there is only one application and one factor.
The choice depends on scope. For a web portal with one TOTP requirement, a local service may avoid the need to configure a general MFA platform, its database, its keys, and multiple integrations. For an organization protecting SSH, VPNs, identity providers, and several web applications, duplicating factor logic across services creates more administrative work. privacyIDEA's design is more suitable for that shared enforcement point.
Another alternative is relying on the MFA capabilities already included in an identity provider. The README explicitly describes integrations with Keycloak, ADFS, Shibboleth, and SimpleSAMLphp. In such an environment, privacyIDEA can serve as an additional authentication factor rather than replace the identity provider. That may be preferable if existing applications already delegate authentication to that provider. The project does not claim to eliminate the identity provider, and its documented integration list should be checked against the exact identity flow in use.
The practical comparison is therefore not privacyIDEA versus every authentication system. It is central MFA coordination versus application-specific handling. privacyIDEA earns its additional operational cost when several applications need one policy and several factor types.
Maintenance, Upgrades, and AGPL Licensing
The repository is not archived, and its last push was on 2026-10-16. That is recent relative to the recorded project activity, but it does not by itself establish the cost or procedure for upgrading a particular installation. The release history includes v3.14 on 2026-10-07 and v3.13.4 on 2026-09-17. The presence of `READ_BEFORE_UPDATE.md`, migrations, and the optional `db stamp` command confirms that database evolution is part of the project layout.
The README says the development database should be stamped to `head` if it is to remain upgradable. Production upgrade behavior is delegated to the linked upgrade documentation. An operator should therefore treat the database, encryption key, audit keys, configuration file, and application version as related upgrade concerns. Losing or regenerating a key without understanding its relationship to stored data is not a documented safe recovery procedure, and the shown README does not provide one.
The package metadata declares `AGPL-3.0-or-later`, while the README describes the project as AGPLv3. That license matters for organizations considering modifications or network use. The repository is self-hosted and the project distributes source code, but this article does not provide legal advice or a conclusion about a particular deployment. Distribution and modification terms should be reviewed against the actual `LICENSE` file and the organization's legal requirements before adoption.
The project's broad integrations and factor implementations also create upgrade work beyond the Python package. Operators may need to review configuration compatibility, database migrations, API behavior, authenticator versions, and client integrations. The repository layout documents where those concerns live, but it does not promise that every upgrade is operationally neutral.
Editorial conclusion
Adopt privacyIDEA when the requirement is self-hosted MFA across heterogeneous applications and existing user stores, provided an administrator can own the database, encryption keys, configuration, and upgrade path. Do not choose it as a lightweight library when an application only needs a single local OTP check. Before adoption, verify the deployment requirements in the linked installation documentation, the configuration file mechanism in `.env.example`, and the implications of AGPL-3.0-or-later for your distribution model.
Frequently asked questions
What is privacyIDEA used for?
privacyIDEA is a self-hosted MFA platform for protecting applications, SSH, VPNs, identity providers, and web portals with OTP, passkeys, push, smartcards, and other factors. It is intended for organizations that want to coordinate authentication across multiple systems and user stores.
How do I install privacyIDEA for development?
The README gives a development setup that clones the repository, creates a `virtualenv` environment, activates it, and installs `requirements.txt`. It then directs operators to create a config file and initialize tables and keys with `pi-manage`.
Does privacyIDEA require a particular identity provider?
No single identity provider is required by the documented design. The README lists connections to AD, LDAP, SQL, EntraID, Keycloak, ADFS, Shibboleth, and SimpleSAMLphp, while also describing REST API integration for web applications.
What is privacyIDEA licensed under?
The project metadata declares `AGPL-3.0-or-later`, and the README describes the project as AGPLv3. Review the repository's `LICENSE` file for the applicable terms before modifying or distributing it.
Can privacyIDEA be used as a self-hosted MFA server?
Yes. The README describes privacyIDEA as an on-premise, self-hosted platform and includes a local development startup flow using `./pi-manage run`, followed by access to `http://localhost:5000`. Production installation requirements are documented separately.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/privacyidea-privacyidea)Was this useful?