0% found this document useful (0 votes)
60 views

Privacyidea

privacyIDEA is a modular authentication system that allows two-factor authentication to be added to existing applications. It is open source and written in Python. It can integrate with various user directories and authentication devices. Users and administrators can manage authentication devices via a web UI. It has various installation options, including via Python packages or Ubuntu packages.

Uploaded by

gaucon2902
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
60 views

Privacyidea

privacyIDEA is a modular authentication system that allows two-factor authentication to be added to existing applications. It is open source and written in Python. It can integrate with various user directories and authentication devices. Users and administrators can manage authentication devices via a web UI. It has various installation options, including via Python packages or Ubuntu packages.

Uploaded by

gaucon2902
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 503

privacyIDEA Authentication System

Release 3.8

Cornelius Kölbel

Feb 20, 2023


CONTENTS

1 Table of Contents 3

2 Indices and tables 463

Python Module Index 465

HTTP Routing Table 467

Index 471

i
ii
privacyIDEA Authentication System, Release 3.8

privacyIDEA is a modular authentication system. Using privacyIDEA you can enhance your existing applications like
local login, VPN, remote access, SSH connections, access to web sites or web portals with a second factor during
authentication. Thus boosting the security of your existing applications. Originally it was used for OTP authentication
devices. But other “devices” like challenge response and SSH keys are also available. It runs on Linux and is completely
Open Source, licensed under the AGPLv3.
privacyIDEA can read users from many different sources like flat files, different LDAP services, SQL databases and
SCIM services. (see Realms)
Authentication devices to provide two factor authentication can be assigned to those users, either by administrators or
by the users themselves. Policies define what a user is allowed to do in the web UI and what an administrator is allowed
to do in the management interface.
The system is written in python, uses flask as web framework and an SQL database as datastore. Thus it can be enrolled
quite easily providing a lean installation. (see Installation)

CONTENTS 1
privacyIDEA Authentication System, Release 3.8

2 CONTENTS
CHAPTER

ONE

TABLE OF CONTENTS

1.1 Overview

privacyIDEA is a system that is used to manage devices for two factor authentication. Using privacyIDEA you can
enhance your existing applications like local login, VPN, remote access, SSH connections, access to web sites or web
portals with a second factor during authentication. Thus boosting the security of your existing applications.
In the beginning there were OTP tokens, but other means to authenticate like SSH keys are added. Other concepts like
handling of machines or enrolling certificates are coming up, you may monitor this development on Github.
privacyIDEA is a web application written in Python based on the flask micro framework. You can use any webserver
with a wsgi interface to run privacyIDEA. E.g. this can be Apache, Nginx or even werkzeug.
A device or item used to authenticate is still called a “token”. All token information is stored in an SQL database,
while you may choose, which database you want to use. privacyIDEA uses SQLAlchemy to map the database to
internal objects. Thus you may choose to run privacyIDEA with SQLite, MySQL, PostgreSQL, Oracle, DB2 or other
database.
The code is divided into three layers, the API, the library and the database layer. Read about it at Code Documentation.
privacyIDEA provides a clean REST API.
Administrators can use a Web UI or a command line client to manage authentication devices. Users can log in to the
Web UI to manage their own tokens.
Authentication is performed via the API or certain plugins for FreeRADIUS, simpleSAMLphp, Wordpress, Contao,
Dokuwiki. . . to either provide default protocols like RADIUS or SAML or to integrate into applications directly.
Due to this flexibility there are also many different ways to install and setup privacyIDEA. We will take a look at
common ways to setup privacyIDEA in the section Installation but there are still many others.

1.2 Installation

The ways described here to install privacyIDEA are


• the installation via the Python Package Index, which can be used on any Linux distribution and
• ready made Ubuntu Packages for Ubuntu 16.04 LTS and 18.04 LTS.
If you want to upgrade please read Upgrading.

3
privacyIDEA Authentication System, Release 3.8

1.2.1 Python Package Index

You can install privacyidea usually on any Linux distribution in a python virtual environment. This way you keep all
privacyIDEA code in one defined subdirectory.
privacyIDEA currently runs with Python 2.7 and 3.5, 3.6, 3.7 and 3.8. Other versions either do not work or are not
tested.
You first need to install a package for creating a python virtual environment.
Now you can setup the virtual environment for privacyIDEA like this:

virtualenv /opt/privacyidea

cd /opt/privacyidea
source bin/activate

Note: Some distributions still ship Python 2.7 as the system python. If you want to use Python 3 you can create the
virtual environment like this: virtualenv -p /usr/bin/python3 /opt/privacyidea

Now you are within the python virtual environment and you can run:

pip install privacyidea

in order to install the latest privacyIDEA version from PyPI.

Deterministic Installation

The privacyIDEA package contains dependencies with a minimal required version. However, newest versions of de-
pendencies are not always tested and might cause problems. If you want to achieve a deterministic installation, you can
now install the pinned and tested versions of the dependencies:

pip install -r lib/privacyidea/requirements.txt

It would even be safer to install the pinned dependencies before installing privacyIDEA. So if you e.g. know that you
are going to install version 3.6 you can run:

pip install -r https://raw.githubusercontent.com/privacyidea/privacyidea/v3.6/


˓→requirements.txt

pip install privacyidea==3.6

Configuration

Database

privacyIDEA makes use of SQLAlchemy to be able to talk to different SQL-based databases. Our best experience is
with MySQL but SQLAlchemy supports many different databases1 .
The database server should be installed on the host or be otherwise reachable.
In order for privacyIDEA to use the database, a database user with the appropriate privileges is needed. The following
SQL commands will create the database as well as a user in MySQL:
1 https://docs.sqlalchemy.org/en/13/dialects/index.html

4 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

CREATE DATABASE pi;


CREATE USER "pi"@"localhost" IDENTIFIED BY "<dbsecret>";
GRANT ALL PRIVILEGES ON pi.* TO "pi"@"localhost";

You must then add the database name, user and password to your pi.cfg. See The Config File for more information on
the configuration.

Setting up privacyIDEA

Additionally to the database connection a new PI_PEPPER and SECRET_KEY must be generated in order to secure the
installation:

PEPPER="$(tr -dc A-Za-z0-9_ </dev/urandom | head -c24)"


echo "PI_PEPPER = '$PEPPER'" >> /path/to/pi.cfg
SECRET="$(tr -dc A-Za-z0-9_ </dev/urandom | head -c24)"
echo "SECRET_KEY = '$SECRET'" >> /path/to/pi.cfg

An encryption key for encrypting the secrets in the database and a key for signing the Audit log is also needed (the
following commands should be executed inside the virtual environment):

pi-manage create_enckey # encryption key for the database


pi-manage create_audit_keys # key for verification of audit log entries

To create the database tables execute:

pi-manage create_tables

Stamping the database to the current database schema version is important for the update process later:

pi-manage db stamp head -d /opt/privacyidea/lib/privacyidea/migrations/

After creating a local administrative user with:

pi-manage admin add <login>

the development server can be started with:

pi-manage runserver

Warning: The development server should not be used for a productive environment.

Webserver

To serve authentication requests and provide the management UI a WSGI capable webserver like Apache2 or nginx is
needed.
Setup and configuration of a webserver can be a complex procedure depending on several parameter (host OS, SSL,
internal network structure, . . . ). Some example configuration can be found in the NetKnights GitHub repositories2 .
More on the WSGI setup for privacyIDEA can be found in wsgiscript.
2 https://github.com/NetKnights-GmbH/ubuntu/tree/master/deploy

1.2. Installation 5
privacyIDEA Authentication System, Release 3.8

1.2.2 Ubuntu Packages

There are ready made packages for Ubuntu.


Packages of older releases of privacyIDEA up to version 2.23 are available for Ubuntu 14.04 LTS and Ubuntu 16.04
LTS from a public ppa repository1 . Using these is deprecated.
For recent releases of privacyIDEA starting from version 3.0 a repository is available which provides packages for
Ubuntu 18.04 LTS, 20.04LTS and 22.04LTS2 .

Note: The packages privacyidea-apache2 and privacyidea-nginx assume that you want to run a priva-
cyIDEA system. These packages deactivate all other (default) websites. Instead, you may install the package
privacyidea-mysql to install the privacyIDEA application and setup the database without any webserver config-
uration. After this, you can integrate privacyIDEA with your existing webserver configuration.

Read about the upgrading process in Upgrading a packaged installation.

Installing privacyIDEA 3.0 or higher

Before installing privacyIDEA 3.0 or upgrading to 3.0 you need to add the repository.

Add repository

The packages are digitally signed. First you need to download the signing key:

wget https://lancelot.netknights.it/NetKnights-Release.asc

Then you can verify the fingerprint:

gpg --import --import-options show-only --with-fingerprint NetKnights-Release.asc

The fingerprint of the key is:

pub 4096R/AE250082 2017-05-16 NetKnights GmbH <[email protected]>


Key fingerprint = 0940 4ABB EDB3 586D EDE4 AD22 00F7 0D62 AE25 0082

On Ubuntu 18.04LTS and 20.04LTS you can now add the signing key to your system:

apt-key add NetKnights-Release.asc

On Ubuntu 22.04LTS you can add the signing key by:

mv NetKnights-Release.asc /etc/apt/trusted.gpg.d/

Now you need to add the repository for your release (either bionic/18.04LTS, focal/20.04LTS or jammy/22.04LTS)
You can do this by running the command:

add-apt-repository http://lancelot.netknights.it/community/bionic/stable

1https://launchpad.net/~privacyidea
2Starting with privacyIDEA 2.15 Ubuntu 16.04 packages are provided. Starting with privacyIDEA 3.0 Ubuntu 16.04 and 18.04 packages are
provided, Ubuntu 14.04 packages are dropped. Starting with privacyIDEA 3.5 Ubuntu 20.04 packages are available. Starting with privacyIDEA 3.8
Ubuntu 22.04 packages are available, Ubuntu 16.04 packages are dropped.

6 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

or:

add-apt-repository http://lancelot.netknights.it/community/focal/stable

or:

add-apt-repository http://lancelot.netknights.it/community/jammy/stable

As an alternative you can add the repo in a dedicated file. Create a new file /etc/apt/sources.list.d/
privacyidea-community.list with the following contents:

deb http://lancelot.netknights.it/community/xenial/stable xenial main

or:

deb http://lancelot.netknights.it/community/bionic/stable bionic main

or:

deb http://lancelot.netknights.it/community/focal/stable focal main

Note: While the link http://lancelot.netknights.it/community/ and its subdirectories are browsable, it is only avail-
able via http! Most browsers will automatically redirect you to https, which will result in a 404 error, since the link
http**s**://lancelot.netknights.it/community/ does not exist. So if you want to browse the repository, take care to do
this via http. This is OK. The apt program fetches all packages via http. If you still fail to fetch packages, you might
most probably need to check your firewall and proxy settings.

Installation of privacyIDEA 3.x

After having added the repositories, run:

apt update
apt install privacyidea-apache2

If you do not like the Apache2 webserver you could alternatively use the meta package privacyidea-nginx.

Now you may proceed to First Steps.

FreeRADIUS

privacyIDEA has a perl module to “translate” RADIUS requests to the API of the privacyIDEA server. This module
plugs into FreeRADIUS. The FreeRADIUS does not have to run on the same machine as privacyIDEA. To install this
module run:

apt-get install privacyidea-radius

For further details see rlm_perl.

1.2. Installation 7
privacyIDEA Authentication System, Release 3.8

1.2.3 CentOS Installation

Step-by-Step installation on CentOS

In this chapter we describe a way to install privacyIDEA on CentOS 7 based on the installation via Python Package
Index. It follows the approach used in the enterprise packages (See RPM Repository).

Setting up the required services

In this guide we use Python 2.7 even though its end-of-life draws closer. CentOS 7 will support Python 2 until the end
of its support frame. Basically the steps for using privacyIDEA with Python 3 are the same but several other packages
need to be installed1 .
First the necessary packages need to be installed:

$ yum install mariadb-server httpd mod_wsgi mod_ssl python-virtualenv policycoreutils-


˓→python

Now enable and configure the services:

$ systemctl enable --now httpd


$ systemctl enable --now mariadb
$ mysql_secure_installation

Setup the database for the privacyIDEA server:

$ echo 'create database pi;' | mysql -u root -p


$ echo 'create user "pi"@"localhost" identified by "<dbsecret>";' | mysql -u root -p
$ echo 'grant all privileges on pi.* to "pi"@"localhost";' | mysql -u root -p

If this should be a pinned installation (i.e. with all the package pinned to the versions with which we are develop-
ing/testing), some more packages need to be installed for building these packages:

$ yum install gcc postgresql-devel

Create the necessary directories:

$ mkdir /etc/privacyidea
$ mkdir /opt/privacyidea
$ mkdir /var/log/privacyidea

Add a dedicated user for the privacyIDEA server and change some ownerships:

$ useradd -r -M -d /opt/privacyidea privacyidea


$ chown privacyidea:privacyidea /opt/privacyidea /etc/privacyidea /var/log/privacyidea

1 https://stackoverflow.com/questions/42004986/how-to-install-mod-wgsi-for-apache-2-4-with-python3-5-on-centos-7

8 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Install the privacyIDEA server

Now switch to that user and install the virtual environment for the privacyIDEA server:

$ su - privacyidea

Create the virtual environment:

$ virtualenv /opt/privacyidea

activate it:

$ . /opt/privacyidea/bin/activate

and install/update some prerequisites:

(privacyidea)$ pip install -U pip setuptools

If this should be a pinned installation (that is the environment we use to build and test), we need to install some pinned
dependencies first. They should match the version of the targeted privacyIDEA. You can get the latest version tag from
the GitHub release page or the PyPI package history (e.g. “3.3.1”):

(privacyidea)$ export PI_VERSION=3.3.1


(privacyidea)$ pip install -r https://raw.githubusercontent.com/privacyidea/privacyidea/v
˓→${PI_VERSION}/requirements.txt

Then just install the targeted privacyIDEA version with:

(privacyidea)$ pip install privacyidea==${PI_VERSION}

Setting up privacyIDEA

In order to setup privacyIDEA a configuration file must be added in /etc/privacyidea/pi.cfg. It should look
something like this:

import logging
# The realm, where users are allowed to login as administrators
SUPERUSER_REALM = ['super']
# Your database
SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://pi:<dbsecret>@localhost/pi'
# This is used to encrypt the auth_token
#SECRET_KEY = 't0p s3cr3t'
# This is used to encrypt the admin passwords
#PI_PEPPER = "Never know..."
# This is used to encrypt the token data and token passwords
PI_ENCFILE = '/etc/privacyidea/enckey'
# This is used to sign the audit log
PI_AUDIT_KEY_PRIVATE = '/etc/privacyidea/private.pem'
PI_AUDIT_KEY_PUBLIC = '/etc/privacyidea/public.pem'
PI_AUDIT_SQL_TRUNCATE = True
# The Class for managing the SQL connection pool
PI_ENGINE_REGISTRY_CLASS = "shared"
PI_AUDIT_POOL_SIZE = 20
(continues on next page)

1.2. Installation 9
privacyIDEA Authentication System, Release 3.8

(continued from previous page)


PI_LOGFILE = '/var/log/privacyidea/privacyidea.log'
PI_LOGLEVEL = logging.INFO

Make sure the configuration file is not world readable:

(privacyidea)$ chmod 640 /etc/privacyidea/pi.cfg

More information on the configuration parameters can be found in The Config File.
In order to secure the installation a new PI_PEPPER and SECRET_KEY must be generated:

(privacyidea)$ PEPPER="$(tr -dc A-Za-z0-9_ </dev/urandom | head -c24)"


(privacyidea)$ echo "PI_PEPPER = '$PEPPER'" >> /etc/privacyidea/pi.cfg
(privacyidea)$ SECRET="$(tr -dc A-Za-z0-9_ </dev/urandom | head -c24)"
(privacyidea)$ echo "SECRET_KEY = '$SECRET'" >> /etc/privacyidea/pi.cfg

From now on the pi-manage-tool can be used to configure and manage the privacyIDEA server:

(privacyidea)$ pi-manage create_enckey # encryption key for the database


(privacyidea)$ pi-manage create_audit_keys # key for verification of audit log entries
(privacyidea)$ pi-manage create_tables # create the database structure
(privacyidea)$ pi-manage db stamp head -d /opt/privacyidea/lib/privacyidea/migrations/
˓→# stamp the db

An administrative account is needed to configure and maintain privacyIDEA:

(privacyidea)$ pi-manage admin add <admin-user>

Setting up the Apache webserver

Now We need to set up apache to forward requests to privacyIDEA, so the next steps are executed as the root-user
again.
First the SELinux settings must be adjusted in order to allow the httpd-process to access the database and write to the
privacyIDEA logfile:

$ semanage fcontext -a -t httpd_sys_rw_content_t "/var/log/privacyidea(/.*)?"


$ restorecon -R /var/log/privacyidea

and:

$ setsebool -P httpd_can_network_connect_db 1

If the user store is an LDAP-resolver, the httpd-process also needs to access the ldap ports:

$ setsebool -P httpd_can_connect_ldap 1

If something does not seem right, check for “denied” entries in /var/log/audit/audit.log
Some LDAP-resolver could be listening on a different port. In this case SELinux has to be configured accordingly.
Please check the SELinux audit.log to see if SELinux might block any connection.
For testing purposes we use a self-signed certificate which should already have been created. In production environ-
ments this should be replaced by a certificate from a trusted authority.

10 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

To correctly load the apache config file for privacyIDEA we need to disable some configuration first:

$ cd /etc/httpd/conf.d
$ mv ssl.conf ssl.conf.inactive
$ mv welcome.conf welcome.conf.inactive
$ curl -o privacyidea.conf https://raw.githubusercontent.com/NetKnights-GmbH/centos7/
˓→master/SOURCES/privacyidea.conf

In order to avoid recreation of the configuration files during update You can create empty dummy files for ssl.conf
and welcome.conf.
And we need a corresponding wsgi-script file in /etc/privacyidea/:

$ cd /etc/privacyidea
$ curl -O https://raw.githubusercontent.com/NetKnights-GmbH/centos7/master/SOURCES/
˓→privacyideaapp.wsgi

If firewalld is running ($ firewall-cmd --state) You need to open the https port to allow connections:

$ firewall-cmd --permanent --add-service=https


$ firewall-cmd --reload

After a restart of the apache webserver ($ systemctl restart httpd) everything should be up and running. You
can log in with Your admin user at https://<privacyidea server> and start enrolling tokens.

RPM Repository

For customers with a valid service level agreement2 with NetKnights there is an RPM repository, that can be used to
easily install and update privacyIDEA on CentOS 7 / RHEL 7. For more information see3 .

1.2.4 Upgrading

In any case before upgrading a major version read the document READ_BEFORE_UPDATE which is continuously
updated in the Github repository. Note, that when you are upgrading over several major versions, read all the comments
for all versions.
If you installed privacyIDEA via DEB or RPM repository you can use the normal system ways of apt-get, aptitude and
yum to upgrade privacyIDEA to the current version.
If you want to upgrade an old Ubuntu installation from privacyIDEA 2.23 to privacyIDEA 3.0, please read the Note on
legacy upgrades.
2 https://netknights.it/en/leistungen/service-level-agreements/
3 https://netknights.it/en/additional-service-privacyidea-support-customers-centos-7-repository/

1.2. Installation 11
privacyIDEA Authentication System, Release 3.8

Different upgrade processes

Depending on the way privacyIDEA was installed, there are different recommended update procedures. The following
section describes the process for pip installations. Instructions for packaged versions on RHEL and Ubuntu are found
in Upgrading a packaged installation.

Upgrading a pip installation

If you install privacyIDEA into a python virtualenv like /opt/privacyidea, you can follow this basic upgrade process.
First you might want to backup your program directory:

tar -zcf privacyidea-old.tgz /opt/privacyidea

and your database:

source /opt/privacyidea/bin/activate
pi-manage backup create

Running upgrade

Starting with version 2.17 the script privacyidea-pip-update performs the update of the python virtualenv and the
DB schema.
Just enter your python virtualenv (you already did so, when running the backup) and run the command:
privacyidea-pip-update
The following parameters are allowed:
-f or --force skips the safety question, if you really want to update.
-s or --skipstamp skips the version stamping during schema update.
-n or --noschema completely skips the schema update and only updates the code.

Manual upgrade

Now you can upgrade the installation:

source /opt/privacyidea/bin/activate
pip install --upgrade privacyidea

Usually you will need to upgrade/migrate the database:

privacyidea-schema-upgrade /opt/privacyidea/lib/privacyidea/migrations

Now you need to restart your webserver for the new code to take effect.

12 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Upgrading a packaged installation

In general, the upgrade of a packaged version of privacyIDEA should be done using the default tools (e.g. apt and yum).
In any case, read the READ_BEFORE_UPDATE file. It is also a good idea to backup your system before upgrading.

Ubuntu upgrade

If you use the Ubuntu packages in a default setup, the upgrade can should be done using:

apt update
apt dist-upgrade

Note: In case you upgrade from the old privacyIDEA 2.23.x to the version 3.x you have to change from your ppa
sources to the new repositories. If you are upgrading your Ubuntu release, e.g. from 14.04 to 16.04 the principal steps
are
• Bring your Ubuntu 14.04 system up-to-date
• Run the release upgrade (do-release-upgrade)
• Eventually remove old repositories and add recent repositories as described in Add repository.
• Reinstall/Upgrade privacyIDEA 3.x
privacyIDEA 2.x installed the python packages to the system directly. The packages in the repository instead come
with a virtual python environment. This may cause lots of obsolete packages after upgrading which may be removed
with:

apt autoremove

CentOS upgrade

For a Red Hat Enterprise Linux (RHEL) installation run:

yum update

to upgrade.

1.2.5 The Config File

privacyIDEA reads its configuration from different locations:


1. default configuration from the module privacyidea/config.py
2. then from the config file /etc/privacyidea/pi.cfg if it exists and then
3. from the file specified in the environment variable PRIVACYIDEA_CONFIGFILE:

export PRIVACYIDEA_CONFIGFILE=/your/config/file

The configuration is overwritten and extended in each step. I.e. values define in privacyidea/config.py that are
not redefined in one of the other config files, stay the same.

1.2. Installation 13
privacyIDEA Authentication System, Release 3.8

You can create a new config file (either /etc/privacyidea/pi.cfg) or any other file at any location and set the
environment variable. The file should contain the following contents:

# The realm, where users are allowed to login as administrators


SUPERUSER_REALM = ['super', 'administrators']
# Your database
SQLALCHEMY_DATABASE_URI = 'sqlite:////etc/privacyidea/data.sqlite'
# Set maximum identifier length to 128
# SQLALCHEMY_ENGINE_OPTIONS = {"max_identifier_length": 128}
# This is used to encrypt the auth_token
SECRET_KEY = 't0p s3cr3t'
# This is used to encrypt the admin passwords
PI_PEPPER = "Never know..."
# This is used to encrypt the token data and token passwords
PI_ENCFILE = '/etc/privacyidea/enckey'
# This is used to sign the audit log
PI_AUDIT_KEY_PRIVATE = '/home/cornelius/src/privacyidea/private.pem'
PI_AUDIT_KEY_PUBLIC = '/home/cornelius/src/privacyidea/public.pem'
# PI_AUDIT_MODULE = <python audit module>
# PI_AUDIT_SQL_URI = <special audit log DB uri>
# Options passed to the Audit DB engine (supersedes SQLALCHEMY_ENGINE_OPTIONS)
# PI_AUDIT_SQL_OPTIONS = {}
# Truncate Audit entries to fit into DB columns
PI_AUDIT_SQL_TRUNCATE = True
# PI_LOGFILE = '....'
# PI_LOGLEVEL = 20
# PI_INIT_CHECK_HOOK = 'your.module.function'
# PI_CSS = '/location/of/theme.css'
# PI_UI_DEACTIVATED = True

Note: The config file is parsed as python code, so you can use variables to set the path and you need to take care for
indentations.

SQLALCHEMY_DATABASE_URI defines the location of your database. You may want to use the MySQL database or
Maria DB. There are two possible drivers, to connect to this database. Please read MySQL database connect string.
SQLALCHEMY_ENGINE_OPTIONS is a dictionary of keyword args to send to create_engine(). The
max_identifier_length is the database’s configured maximum number of characters that may be used in
a SQL identifier such as a table name, column name, or label name. For Oracle version 19 and above the
max_identifier_length should be set to 128.
The SUPERUSER_REALM is a list of realms, in which the users get the role of an administrator.
PI_INIT_CHECK_HOOK is a function in an external module, that will be called as decorator to token/init and token/
assign. This function takes the request and action (either “init” or “assign”) as an arguments and can modify the
request or raise an exception to avoid the request being handled.
If you set PI_DB_SAFE_STORE to True the database layer will in the cases of tokenowner, tokeinfo and tokenrealm
read the id of the newly created database object in an additional SELECT statement and not return it directly. This is
slower but more robust and can be necessary in large redundant setups.

Note: In certain cases (e.g. with Galera Cluster) it can happen that the database node has no information about the
object id directly during the write-process. The database might respond with an error like “object has been deleted or

14 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

its row is otherwise not present”. In this case setting PI_DB_SAFE_STORE to True might help.

PI_HASH_ALGO_LIST is a user-defined list of hash algorithms which are used to verify passwords and pins. The
first entry in PI_HASH_ALGO_LIST is used for hashing a new password/pin. If PI_HASH_ALGO_LIST is not defined,
['argon2', 'pbkdf2_sha512'] is the default. Further information can be found in the FAQ (PIN Hashing).

Note: If you change the hash algorithm, take care that the previously used one is still included in the
PI_HASH_ALGO_LIST so already generated hashes can still be verified.

PI_HASH_ALGO_PARAMS is a user-defined dictionary where various parameters for the hash algorithm can be set, for
example:

PI_HASH_ALGO_PARAMS = {'argon2__rounds': 5, 'argon2__memory_cost': 768'}

Further information on possible parameters can be found in the PassLib documentation.


PI_PREFERRED_LANGUAGE is a list in which the preferred languages can be defined. The browser’s language settings
are compared to this list and the “best match” wins. If none of the languages set in the browser match, the first language
in the list will be used as the default language:

PI_PREFERRED_LANGUAGE = ["en", "de", "es", "fr"]

Note: If PI_PREFERRED_LANGUAGE is not defined, the following list is used. [‘en’, ‘de’, ‘nl’, ‘zh_Hant’, ‘fr’, ‘es’, ‘tr’]

Logging

There are three config entries, that can be used to define the logging. These are PI_LOGLEVEL, PI_LOGFILE,
PI_LOGCONFIG. These are described in Debugging and Logging.
You can use PI_CSS to define the location of another cascading style sheet to customize the look and feel. Read more
at Themes.

Note: If you ever need passwords being logged in the log file, you may set PI_LOGLEVEL = 9, which is a lower log
level than logging.DEBUG. Use this setting with caution and always delete the logfiles!

privacyIDEA digitally signs the responses. You can disable this using the parameter PI_NO_RESPONSE_SIGN. Set this
to True to suppress the response signature.
You can set PI_UI_DEACTIVATED = True to deactivate the privacyIDEA UI. This can be interesting if you are only
using the command line client or your own UI and you do not want to present the UI to the user or the outside world.

Note: The API calls are all still accessible, i.e. privacyIDEA is technically fully functional.

The parameter PI_TRANSLATION_WARNING can be used to provide a prefix, that is set in front of every string in the
UI, that is not translated to the language your browser is using.

1.2. Installation 15
privacyIDEA Authentication System, Release 3.8

Engine Registry Class

The PI_ENGINE_REGISTRY_CLASS option controls the pooling of database connections opened by SQL resolvers and
the SQL audit module. If it is set to "null", SQL connections are not pooled at all and new connections are opened for
every request. If it is set to "shared", connections are pooled on a per-process basis, i.e. every wsgi process manages
one connection pool for each SQL resolver and the SQL audit module. Every request then checks out connections from
this shared pool, which reduces the overall number of open SQL connections. If the option is left unspecified, its value
defaults to "null".

Audit parameters

PI_AUDIT_MODULE lets you specify an alternative auditing module. The default which is shipped with privacyIDEA is
privacyidea.lib.auditmodules.sqlaudit. There is no need to change this, unless you know exactly what you
are doing.
You can change the servername of the privacyIDEA node, which will be logged to the audit log using the variable
PI_AUDIT_SERVERNAME.
You can run the database for the audit module on another database or even server. For this you can specify the database
URI via PI_AUDIT_SQL_URI. With PI_AUDIT_SQL_OPTIONS You can pass a dictionary of options to the database
engine. If PI_AUDIT_SQL_OPTIONS is not set, SQLALCHEMY_ENGINE_OPTIONS will be used.
PI_AUDIT_SQL_TRUNCATE = True lets you truncate audit entries to the length of the database fields.
In certain cases when you experiencing problems you may use the parameters PI_AUDIT_POOL_SIZE and
PI_AUDIT_POOL_RECYCLE. However, they are only effective if you also set PI_ENGINE_REGISTRY_CLASS to
"shared".
If you by any reason want to avoid signing audit entries you can set PI_AUDIT_NO_SIGN = True. If
PI_AUDIT_NO_SIGN is set to True audit entries will not be signed and also the signature of audit entries will not
be verified. Audit entries will appears with signature fail.

Monitoring parameters

PI_MONITORING_MODULE lets you specify an alternative statistics monitoring module. The monitoring module takes
care of writing values with timestamps to a store. This is used e.g. by the EventCounter and SimpleStats.
The first available monitoring module is privacyidea.lib.monitoringmodules.sqlstats. It accepts the follow-
ing additional parameters:
PI_MONITORING_SQL_URI can hold an alternative SQL connect string. If not specified the normal
SQLALCHEMY_DATABASE_URI is used.
PI_MONITORING_POOL_SIZE (default 20) and PI_MONITORING_POOL_RECYCLE (default 600) let you configure pool-
ing. It uses the settings from the above mentioned PI_ENGINE_REGISTRY_CLASS.

Note: A SQL database is probably not the best database to store time series. Other monitoring modules will follow.

16 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

privacyIDEA Nodes

privacyIDEA can run in a redundant setup. For statistics and monitoring purposes you can give these different nodes,
dedicated names.
PI_NODE is a string with the name of this very node. PI_NODES is a list of all available nodes in the cluster.
If PI_NODE is not set, then PI_AUDIT_SERVERNAME is used as node name. If this is also not set, the node name is
returned as “localnode”.

Trusted JWTs

Other applications can use the API without the need to call the /auth endpoint. This can be achieved by trusting
private RSA keys to sign JWTs. You can define a list of corresponding public keys that are trusted for certain users and
roles using the parameter PI_TRUSTED_JWT:

PI_TRUSTED_JWT = [{"public_key": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEF...


˓→",

"algorithm": "RS256",
"role": "user",
"realm": "realm1",
"username": "userA",
"resolver": "resolverX"}]

This entry means, that the private key, that corresponds to the given public key can sign a JWT, that can impersonate
as the userA in resolver resolverX in realmA.

Note: The username can be a regular expression like “.*”. This way you could allow a private signing key to
impersonate every user in a realm. (Starting with version 3.3)

A JWT can be created like this:

auth_token = jwt.encode(payload={"role": "user",


"username": "userA",
"realm": "realm1",
"resolver": "resolverX"},
"key"=private_key,
"algorithm"="RS256")

Note: The user and the realm do not necessarily need to exist in any resolver! But there probably must be certain
policies defined for this user. If you are using an administrative user, the realm for this administrative must be defined
in pi.cfg in the list SUPERUSER_REALM.

1.2. Installation 17
privacyIDEA Authentication System, Release 3.8

3rd party token types

You can add 3rd party token types to privacyIDEA. Read more about this at New token classes.
To make the new token type available in privacyIDEA, you need to specify a list of your 3rd party token class modules
in pi.cfg using the parameter PI_TOKEN_MODULES:

PI_TOKEN_MODULES = [ "myproject.cooltoken", "myproject.lametoken" ]

Custom Web UI

The Web UI is a single page application, that is initiated from the file static/templates/index.html. This file
pulls all CSS, the javascript framework and all the javascript business logic.
You can configure privacyIDEA to use your own WebUI, which is completely different and stored at another location.
You can do this using the following config values:

PI_INDEX_HTML = "myindex.html"
PI_STATIC_FOLDER = "mystatic"
PI_TEMPLATE_FOLDER = "mystatic/templates"

In this example the file mystatic/templates/myindex.html would be loaded as the initial single page application.

1.2.6 Debugging and Logging

You can set PI_LOGLEVEL to a value 10 (Debug), 20 (Info), 30 (Warning), 40 (Error) or 50 (Critical). If you experience
problems, set PI_LOGLEVEL = 10 restart the web service and resume the operation. The log file privacyidea.log
should contain some clues.
You can define the location of the logfile using the key PI_LOGFILE. Usually it is set to:

PI_LOGFILE = "/var/log/privacyidea/privacyidea.log"

Advanced Logging

You can also define a more detailed logging by specifying a log configuration file. By default the file is /etc/
privacyidea/logging.cfg.
You can change the location of the logging configuration file in The Config File like this:

PI_LOGCONFIG = "/path/to/logging.yml"

Since Version 3.3 the logging configuration can be written in YAML1 . Such a YAML based configuration could look
like this:

version: 1
formatters:
detail:
class: privacyidea.lib.log.SecureFormatter
format: '[%(asctime)s][%(process)d][%(thread)d][%(levelname)s][%(name)s:%(lineno)d]
˓→%(message)s'

(continues on next page)


1 https://yaml.org/

18 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

(continued from previous page)

handlers:
mail:
class: logging.handlers.SMTPHandler
mailhost: mail.example.com
fromaddr: [email protected]
toaddrs:
- [email protected]
- [email protected]
subject: PI Error
formatter: detail
level: ERROR
file:
# Rollover the logfile at midnight
class: logging.handlers.RotatingFileHandler
backupCount: 5
maxBytes: 1000000
formatter: detail
level: INFO
filename: /var/log/privacyidea/privacyidea.log
syslog:
class: logging.handlers.SysLogHandler
address: ('192.168.1.110', 514)
formatter: detail
level: INFO

loggers:
# The logger name is the qualname
privacyidea:
handlers:
- file
- mail
level: INFO

root:
handlers:
- syslog
level: WARNING

Different handlers can be used to send log messages to log-aggregators like splunk2 or logstash3 .
The old python logging config file format is also still supported:

[formatters]
keys=detail

[handlers]
keys=file,mail

[formatter_detail]
(continues on next page)
2 https://www.splunk.com/
3 https://www.elastic.co/logstash

1.2. Installation 19
privacyIDEA Authentication System, Release 3.8

(continued from previous page)


class=privacyidea.lib.log.SecureFormatter
format=[%(asctime)s][%(process)d][%(thread)d][%(levelname)s][%(name)s:%(lineno)d]
˓→%(message)s

[handler_mail]
class=logging.handlers.SMTPHandler
level=ERROR
formatter=detail
args=('mail.example.com', '[email protected]', ['[email protected]',\
'[email protected]'], 'PI Error')

[handler_file]
# Rollover the logfile at midnight
class=logging.handlers.RotatingFileHandler
backupCount=14
maxBytes=10000000
formatter=detail
level=DEBUG
args=('/var/log/privacyidea/privacyidea.log',)

[loggers]
keys=root,privacyidea

[logger_privacyidea]
handlers=file,mail
qualname=privacyidea
level=DEBUG

[logger_root]
level=ERROR
handlers=file

Note: These examples define a mail handler, that will send emails to certain email addresses, if an ERROR occurs.
All other DEBUG messages will be logged to a file.

Note: The filename extension is irrelevant in this case

1.2.7 The WSGI Script

Apache2 and Nginx are using a WSGI script to start the application.
This script is usually located at /etc/privacyidea/privacyideaapp.py or /etc/privacyidea/
privacyideaapp.wsgi and has the following contents:

import sys
sys.stdout = sys.stderr
from privacyidea.app import create_app
# Now we can select the config file:
application = create_app(config_name="production", config_file="/etc/privacyidea/pi.cfg")

20 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

In the create_app-call you can also select another config file.

WSGI configuration for the Apache webserver

The site-configuration for the Apache webserver to use WSGI should contain at least:

<VirtualHost _default_:443>
...
WSGIScriptAlias / /etc/privacyidea/privacyideaapp.wsgi
WSGIDaemonProcess privacyidea processes=1 threads=15 display-name=%{GROUP}␣
˓→user=privacyidea

WSGIProcessGroup privacyidea
WSGIApplicationGroup %{GLOBAL}
WSGIPassAuthorization On
...
</VirtualHost>

Running several instances with the Apache webserver

You can run several instances of privacyIDEA on one Apache2 server by defining several WSGIScriptAlias definitions
pointing to different wsgi-scripts, which again reference different config files with different database definitions.
To run further Apache instances add additional lines in your Apache config:

WSGIScriptAlias /instance1 /etc/privacyidea1/privacyideaapp.wsgi


WSGIScriptAlias /instance2 /etc/privacyidea2/privacyideaapp.wsgi
WSGIScriptAlias /instance3 /etc/privacyidea3/privacyideaapp.wsgi
WSGIScriptAlias /instance4 /etc/privacyidea4/privacyideaapp.wsgi

It is a good idea to create a subdirectory in /etc for each instance. Each wsgi script needs to point to the corresponding
config file pi.cfg.
Each config file can define its own
• database
• encryption key
• signing key
• logging configuration
• ...
To create the new database you need The pi-manage Script. The pi-manage command reads the configuration from
/etc/privacyidea/pi.cfg by default.
If you want to use another instance with another config file, you need to set an environment variable and create the
database like this:

PRIVACYIDEA_CONFIGFILE=/etc/privacyidea3/pi.cfg pi-manage create_tables

This way you can use pi-manage for each instance.

1.2. Installation 21
privacyIDEA Authentication System, Release 3.8

1.2.8 The pi-manage Script

pi-manage is the script that is used during the installation process to setup the database and do many other tasks.

Note: The interesting thing about pi-manage is, that it does not need the server to run as it acts directly on the database.
Therefor you need read access to /etc/privacyidea/pi.cfg and the encryption key.

If you want to use a config file other than /etc/privacyidea/pi.cfg, you can set an environment variable:

PRIVACYIDEA_CONFIGFILE=/home/user/pi.cfg pi-manage

pi-manage always takes a command and sometimes a sub command:

pi-manage <command> [<subcommand>] [<parameters>]

For a complete list of commands and sub commands use the -h parameter.
You can do the following tasks.

Encryption Key

You can create an encryption key and encrypt the encryption key.
Create encryption key:

pi-manage create_enckey [--enckey_b64=BASE64_ENCODED_ENCKEY]

Note: The filename of the encryption key is read from the configuration. The key will not be created, if it already
exists. Optionally, enckey can be passed via –enckey_b64 argument, but it is not recommended. –enckey_b64 must be
a string with 96 bytes, encoded in base 64 in order to avoid ambiguous chars.

The encryption key is a plain file on your hard drive. You need to take care, to set the correct access rights.
You can also encrypt the encryption key with a passphrase. To do this do:

pi-manage encrypt_enckey /etc/privacyidea/enckey

and pipe the encrypted enckey to a new file.


Read more about the database encryption and the enckey in Security Modules.

Backup and Restore

You can create a backup which will be save to /var/lib/privacyidea/backup/.


The backup will contain the database dump and the complete directory /etc/privacyidea. You may choose if you want
to add the encryption key to the backup or not.

Warning: If the backup includes the database dump and the encryption key all seeds of the OTP tokens can be
read from the backup.

22 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

As the backup contains the etc directory and the database you only need this tar archive backup to perform a complete
restore.

Rotate Audit Log

Audit logs are written to the database. You can use pi-manage to perform a log rotation.
pi-manage rotate_audit
You can specify a highwatermark and a lowwatermark, age or a config file. Read more about it at Cleaning up entries.

API Keys

You can use pi-manage to create API keys. API keys can be used to
1. secure the access to the /validate/check API or
2. to access administrative tasks via the REST API.
You can create API keys for /validate/check using the command
pi-manage api createtoken -r validate
If you want to secure the access to /validate/check you also need to define a policy in scope authorizaion. See
api_key_required.
If you wan to use the API key to automate administrative REST API calls, you can use the command:
pi-manage api createtoken -r admin
This command also generates an admin account name. But it does not create this admin account. You need to do so
using pi-manage admin. You can now use this API key to enroll tokens as administrator.

Note: These API keys are not persistent. They are not stored in the privacyIDEA server. The API key is connected to
the username, that is also generated. This means you have to create an administrative account with this very username
to use this API key for this admin user. You also should set policies for this admin user, so that this API key has only
restricted rights!

Note: The API key is valid for 365 days.

Policies

You can use pi-manage policy to enable, disable, create and delete policies. Using the sub commands p_export
and p_import you can also export a backup of your policies and import this policy set later.
This could also be used to transfer the policies from one privacyIDEA instance to another.

1.2. Installation 23
privacyIDEA Authentication System, Release 3.8

1.2.9 Security Modules

Note: For a normal installation this section can be safely ignored.

privacyIDEA provides a security module that takes care of


• encrypting the token seeds,
• encrypting passwords from the configuration like the LDAP password,
• creating random numbers,
• and hashing values.

Note: The Security Module concept can also be used to add a Hardware Security Module to perform the above
mentioned tasks.

Default Security Module

The default security module is implemented with the operating systems capabilities. The encryption key is located
in a file enckey specified via PI_ENCFILE in the configuration file (The Config File).
This enckey contains three 32byte keys and is thus 96 bytes. This file has to be protected. So the access rights to this
file are set accordingly.
In addition you can encrypt this encryption key with an additional password. In this case, you need to enter the password
each time the privacyIDEA server is restarted and the password for decrypting the enckey is kept in memory.
The pi-manage Script contains the instruction how to encrypt the enckey
After starting the server, you can check, if the encryption key is accessible. To do so run:

privacyidea -U <yourserver> --admin=<youradmin> securitymodule

The output will contain "is_ready": True to signal that the encryption key is operational.
If it is not yet operational, you need to pass the password to the privacyIDEA server to decrypt the encryption key. To
do so run:

privacyidea -U <yourserver> --admin=<youradmin> securitymodule \


--module=default

Note: If the security module is not operational yet, you might get an error message “HSM not ready.”.

24 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

AES HSM Security Module

The AES Hardware Security Module can be used to encrypt data with an hardware security module (HSM) connected
via the PKCS11 interface. This module allows to use AES keys stored in the HSM to encrypt and decrypt data.
This module uses three keys, similarly to the content of PI_ENCFILE, identified as token, config and value.
To activate this module add the following to the configuration file (The Config File):

PI_HSM_MODULE = "privacyidea.lib.security.aeshsm.AESHardwareSecurityModule"

Additional attributes are


PI_HSM_MODULE_MODULE which takes the pkcs11 library. This is the full specified path to the shared object file in the
file system.
PI_HSM_MODULE_SLOT is the slot on the HSM where the keys are located (default: 1).
You can set the slot number to -1 if there is only one slot available and you do not know the slot number. Then
privacyIDEA will determine the one and only slot number and use this one.
PI_HSM_MODULE_PASSWORD is the password to access the slot.
PI_HSM_MODULE_MAX_RETRIES is the number privacyIDEA tries to perform a cryptographic operation like decrypt,
encrypt or random if the first attempt with the HSM fails. The default value is 5.

Note: Some PKCS11 libraries for network attached HSMs also implement a retry. You should take this into account,
since retries would multiply and it could take a while till a request would finally fail.

PI_HSM_MODULE_KEY_LABEL is the label prefix for the keys on the HSM (default: privacyidea). In order to locate
the keys, the module will search for key with a label equal to the concatenation of this prefix, _ and the key identifier
(respectively token, config and value).
PI_HSM_MODULE_KEY_LABEL_TOKEN is the label for token key (defaults to value based on
PI_HSM_MODULE_KEY_LABEL setting).
PI_HSM_MODULE_KEY_LABEL_CONFIG is the label for config key (defaults to value based on
PI_HSM_MODULE_KEY_LABEL setting).
PI_HSM_MODULE_KEY_LABEL_VALUE is the label for value key (defaults to value based on
PI_HSM_MODULE_KEY_LABEL setting).

Encrypt Key Security Module

The Encrypt Key Security Module uses a hardware security module (HSM) to decrypt the encrypted encryption key.
Within the HSM a private RSA key is used to decrypt an encrypted file like /etc/privacyidea/enckey.enc.
With the first request to each process of the privacyIDEA server, the HSM is used to decrypt the encryption key. After
that the encryption key is kept in memory during run time.
To activate this module add the following to the configuration file (The Config File)
PI_HSM_MODULE = “privacyidea.lib.security.encryptkey.EncryptKeyHardwareSecurityModule”
Further attributes are PI_HSM_MODULE_MODULE which takes the pkcs11 library. This is the fully specified path to the
shared object file in the file system.
PI_HSM_MODULE_SLOT is the slot on the HSM where the keys are located. This is an integer value. Alternatively you
can specify PI_HSM_MODULE_SLOTNAME which would be the descriptive name of this slot.

1.2. Installation 25
privacyIDEA Authentication System, Release 3.8

To use the correct key in this slot you can either specify the key by providing PI_HSM_MODULE_KEYID with the integer
id of the key or PI_HSM_MODULE_KEYLABEL with the descriptive label of the key.
The PI_HSM_MODULE_TIMEOUT can be used to define an integer value for a HSM lock timeout. The default is 15
seconds.
Using the key PI_HSM_MODULE_LOCK_DIR you can define a different locking directory. The default is /dev/shm/
pilock/. Note, that the locking directory is created or removed by privacyIDEA when acquiring or releasing the lock
on the HSM and you must not create this directory manually!

Note: Some HSM fail to provide a correct keyid and it is necessary to use the key label.

The last two mandatory attributes are PI_HSM_MODULE_PASSWORD which holds the password of the slot and
PI_HSM_MODULE_ENCFILE which specifies the encrypted encryption key.
You could e.g. use a Yubikey this way:

PI_HSM_MODULE = "privacyidea.lib.security.encryptkey.EncryptKeyHardwareSecurityModule"
PI_HSM_MODULE_MODULE = "/usr/lib/libykcs11.so"
PI_HSM_MODULE_SLOTNAME = "Yubico YubiKey"
PI_HSM_MODULE_KEYLABEL = 'Private key for PIV Authentication'
PI_HSM_MODULE_PASSWORD = 'yourPin'
PI_HSM_MODULE_ENCFILE = "/etc/privacyidea/enckey.enc"

To encrypt an existing key file you can use the module like this:

python encryptkey.py --module /usr/lib/libykcs11.so --keyid 1 --slotname "Yubico YubiKey


˓→" \
--infile enckey --outfile enckey.enc

If your key in the HSM is identified by a key label, then you can encrypt the existing key file like this:

python encryptkey.py --module /usr/lib/libykcs11.so --keylabel "my secret key" --


˓→slotname "Yubico YubiKey" \

--infile enckey --outfile enckey.enc

Preloading of encryption keys

This security module allows you to preload the encryption keys. I.e. privacyIDEA can use the HSM to decrypt the
keys before the first request is sent to privacyIDEA. To do so, you need to modify the wsgi script (See wsgiscript) and
add the parameter init_hsm:

application = create_app(config_name="production",
config_file="/etc/privacyidea/pi.cfg", init_hsm=True)

Moreover, you need to add the WSGIImportScript statement to your Apache2 configuration:

WSGIApplicationGroup %{GLOBAL}
WSGIImportScript /etc/privacyidea/privacyideaapp.wsgi process-group=privacyidea␣
˓→application-group=%{GLOBAL}

Note: Please note, that this security module uses a lock file, to handle concurrent access to the HSM. In certain cases
of errors the log file could remain and not cleaned up. Ensure, that the directory /dev/shm/pilock/ does not exist at

26 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Apache2 startup.

After installation you might want to take a look at First Steps.

1.3 First Steps

You installed privacyIDEA successfully according to Installation.


These first steps will guide you through the tasks of logging in to the management web UI, attaching your first users
and enrolling the first token.

1.3.1 Add an administrator

PrivacyIDEA does not come with a pre-defined administrator user. If you just installed privacyIDEA, you need to
create a new one by running:

pi-manage admin add admin -e admin@localhost

To configure privacyIDEA, continue with Login to the Web UI.

Note: Administrator accounts are used for various purposes in privacyIDEA. Once you need another administrator
user, you should consider adding an admin policy to set up the permissions correctly. This is described in Admin
policies.
You may also read So what’s the thing with all the admins?.

1.3.2 Login to the Web UI

privacyIDEA has only one login form that is used by administrators and normal users to login. Administrators will be
able to configure the system and to manage all tokens, while normal users will only be able to manage their own tokens.
You should enter your username with the right realm. You need to append the realm to the username like
username@realm.

Login for administrators

Administrators can authenticate at this login form to access the management UI.
Administrators are stored in the database table Admin and can be managed with the tool:

pi-manage admin ...

The administrator just logs in with his username.

Note: You can configure privacyIDEA to authenticate administrators against privacyIDEA itself, so that administrators
need to login with a second factor. See So what’s the thing with all the admins? how to do this.

1.3. First Steps 27


privacyIDEA Authentication System, Release 3.8

Login for normal users

Normal users authenticate at the login form to be able to manage their own tokens. By default users need to authenticate
with the password from their user source.
E.g. if the users are located in an LDAP or Active Directory the user needs to authenticate with his LDAP/AD password.
But before a user can login, the administrator needs to configure realms, which is described in the next step Creating
your first realm.

Note: The user may either login with his password from the userstore or with any of his tokens.

Note: The administrator may change this behaviour by creating an according policy, which then requires the user
to authenticate against privacyIDEA itself. I.e. this way the user needs to authenticate with a second factor/token to
access the self service portal. (see the policy section login_mode)

1.3.3 Creating your first realm

Note: When the administrator logs in and no useridresolver and no realm is defined, a popup appears, which asks you
to create a default realm. During these first steps you may say “No”, to get a better understanding.

Users in privacyIDEA are read from existing sources. See Realms for more information.
In these first steps we will simply read the users from your /etc/passwd file.

Create a UserIdResolver

The UserIdResolver is the connector to the user source. For more information see UserIdResolvers.
• Go to Config -> Users to create a UserIdResolver.

Fig. 1: Create the first UserIdResolver

• Choose New passwdresolver and


• Enter the name “myusers”.

28 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

• Save it.

Fig. 2: Create the first UserIdResolver

You just created your first connection to a user source.

Create a Realm

User sources are grouped together to a so called “realm”. For more information see Realms.
• Go to Config -> Realms
• Enter “realm1” as the new realm name and select the priority 1.
• Check the resolver “myusers” to be included into this realm.
• Save it.
• Go to Users and you will see the users from the /etc/passwd.
Congratulation! You created your first realm.
You are now ready to enroll a token to a user. Read Enrolling your first token.

1.3.4 Enrolling your first token

You may now enroll a new token. In this example we are using the Google Authenticator App, that you need to install
on your smartphone.
• Go to Tokens -> Enroll Token
• Select the username root. When you start typing “r”, “o”. . . the system will find the user root automatically.
• Enter a PIN. I entered “test” . . .
• . . . and click “Enroll Token”.

1.3. First Steps 29


privacyIDEA Authentication System, Release 3.8

Fig. 3: Create the first Realm

Fig. 4: The users from /etc/passwd

30 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Fig. 5: The Token Enrollment Dialog

Fig. 6: Enrollment Success

1.3. First Steps 31


privacyIDEA Authentication System, Release 3.8

• After enrolling the token you will see a QR code, that you need to scan with the Google Authenticator App.
• Click on the serial number link at the top of the dialog.

Fig. 7: Test the Token

• Now you see the token details.


• Left to the button “Test Token” you can enter the PIN and the OTP value generated by the Google Authenticator.
• Click the button “Test Token”. You should see a green “matching 1 tokens”.
Congratulations! You just enrolled your first token to a user.
Now you are ready to attach applications to privacyIDEA in order to add two factor authentication to those applications.
To attach applications read the chapter Application Plugins.
You may also go on reading the chapter Configuration to get a deeper insight in the configuration possibilities.
After these first steps you will be able to start attaching applications to privacyIDEA in order to add two factor authen-
tication to those applications. You can
• use a PAM module to authenticate with OTP at SSH or local login
• or the RADIUS plugin to configure your firewall or VPN to use OTP,
• or use an Apache2 plugin to do Basic Authentication with OTP.
• You can also setup different web applications to use OTP.
To attach applications read the chapter Application Plugins.
You may also go on reading the next chapter which gives an overview on the WebUI or you directly skip to Configuration
to get a deeper insight in the configuration possibilities.

32 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

1.4 WebUI

privacyIDEA comes with a web-based user interface which is used to manage and configure the privacyIDEA server.
It is also used a self-service portal for the average user, who manages his own tokens. This section gives an overview
on the interface and links the respective sections in the documentation.

1.4.1 Dashboard

Starting with version 3.4, privacyIDEA includes a basic dashboard, which can be enabled by the WebUI policy ad-
min_dashboard. The dashboard will be displayed as a starting page for administrators and contains information about
token numbers, authentication requests, recent administrative changes, policies, event handlers and subscriptions. It
uses the usual endpoints to fetch the information, so only information to which an administrator has read access is
displayed in the dashboard.

1.4.2 Tokens

The administrator can see all the tokens of all realms he is allowed to manage in the tokenview. Each token can be
located in several realms and be assigned to one user. The administrator can see all the details of the token.

Fig. 8: Tokens overview

The administrator can click on one token, to show more details of this token and to perform actions on this token. Read
on in token_details.

1.4. WebUI 33
privacyIDEA Authentication System, Release 3.8

1.4.3 Users

The administrator can see all users fetched by UserIdResolvers located in Realms he is allowed to manage.

Note: Users are only visible, if the useridresolver is located within a realm. If you only define a useridresolver but no
realm, you will not be able to see the users!

You can select one of the realms in the left drop down box. The administrator will only see the realms in the drop down
box, that he is allowed to manage.

Fig. 9: The Users view list all users in a realm.

The list shows the users from the select realm. The username, surname, given name, email and phone are filled accord-
ing to the definition of the useridresolver.
Even if a realm contains several useridresolvers all users from all resolvers within this realm are displayed.
Read about the functionality of the users view in the following sections.

User Details

When clicking on a username, you can see the users details and perform several actions on the user.
You see a list of the users tokens and change to the token_details.

Enroll tokens

In the users details view you can enroll additional tokens to the user. In the enrollment dialog the user will be selected
and you only need to choose what tokentype you wish to enroll for this user.

34 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Fig. 10: User Details.

1.4. WebUI 35
privacyIDEA Authentication System, Release 3.8

Assign tokens

You can assign a new, already existing token to the user. Just start typing the token serial number. The system will
search for tokens, that are not assigned yet and present you a list to choose from.

View Audit Log

You can also click View user in Audit log which will take you to the Audit log with a filter on this very user, so that you
will only see audit entries regarding this user.

Edit user

If the user is located in a resolver, that is marked as editable, the administrator will also see a button “Edit User”. To
read more about this, see Manage Users.

Manage Users

Since version 2.4 privacyIDEA allows you to edit users in the configured resolvers. At the moment this is possible for
SQL resolvers.
In the resolver definition you need to check the new checkbox Edit user store.

Fig. 11: Users in SQL can be edited, when checking the checkbox.

In the Users Detail view, the administrator then can click the button “Edit” and modify the user data and also set a new
password.

Note: The data of the user will be modified in the user store (database). Thus the users data, which will be returned
by a resolver, is changed. If the resolver is contained in several realms these changes will reflect in all realms.

If you want to add a user, you can click on Add User in the User View.
Users are contained in resolvers and added to resolvers. So you need to choose an existing resolver and not a realm.
The user will be visible in all realms, the resolver is contained in.

Note: Of course you can set policies to allow or deny the administrator these rights.

36 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Fig. 12: Edit the attributes of an existing user.

Fig. 13: Add a new user.

1.4. WebUI 37
privacyIDEA Authentication System, Release 3.8

Simple local users setup

You can setup a local users definition quite easily. Run:

pi-manage resolver create_internal test

This will create a database table “users_test” in your token database. And it will create a resolver “test” that refers to
this database table.
Then you can add this resolver to realm:

pi-manage realm create internal_realm test

Which will create a realm “internal_realm” containing the resolver “test”. Now you can start adding users to this
resolver as described above.

Note: This is an example of how to get started with users quite quickly. Of course you do not need to save the users
table in the same database as the tokens. But in scenarios, where you do not have existing user stores or the user stores
are managed by another department or are not accessible easily this may be sensible way.

Additional user attributes

Since version 3.6 privacyIDEA allows to manage additional internal attributes for users read from resolvers. These
additional attributes are stored and managed within privacyIDEA. Administrators can manage attributes of users (see
policies set_custom_user_attributes and delete_custom_user_attributes) and users can manage their attributes them-
selves (see policies set_custom_user_attributes and delete_custom_user_attributes).
The additional attributes are added to the user object, whenever a user is used. The attributes are also added in the
response of an authentication request. Thus these attributes could be used to pass additional attributes via the RADIUS
protocol.
The user attributes can also be used as additional conditions in policies (see Extended Policy Conditions) in the userinfo
section. This way the additional attributes can be used to group users together within privacyIDEA and assign distinct
policies to these groups, without the need to rely on information from the user store.
The policy condition uses attributes (userinfo) from the user store and additional user attributes managed in priva-
cyIDEA at the same time.

Note: If the user already has a certain key in the userinfo that is fetched from the resolver, the additional user attributes
can also be used to overwrite the value from the user store!

1.4.4 Machines

In this view Machines are listed which are fetched by the configured machine resolvers. Machines are only necessary
if you plan special use cases like managing SSH keys or doing offline OTP. In most cases there is no need to manage
machines and this view is empty.

38 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Fig. 14: The Machines view.

1.4.5 Config

The configuration tab is the heart of the privacyIDEA server. It contains the general System Config, allows configuring
Policies which are important to configure behavior of the system, manages the Event Handler and lets the user set up
Periodic Tasks.

1.4.6 Audit

In this tab, the Audit log is displayed which lists all events the server registers.

1.4.7 Components

Starting with privacyIDEA 2.15 you can see privacyIDEA components in the Web UI. privacyIDEA collects authen-
ticating clients with their User Agent. Usually this is a type like PAM, FreeRADIUS, Wordpress, OwnCloud, . . . For
more information, you may read on Application Plugins. This overview helps you to understand your network and keep
track which clients are connected to your network.
Subscriptions, e.g. with NetKnights, the company behind privacyIDEA, can also be viewed and managed in this tab.

1.5 Configuration

The configuration menu can be used to define useridresolvers and realms, set the system config and the token config.
It also contains a shortcut to the Policies, Event Handler and Periodic Tasks.

1.5.1 UserIdResolvers

Each organisation or company usually has its users managed at a central location. This is why privacyIDEA does not
provide its own user management but rather connects to existing user stores.
UserIdResolvers are connectors to those user stores, the locations, where the users are managed. Nowadays this can be
LDAP directories or especially Active Directory, some times FreeIPA or the Redhat 389 service. But classically users
are also located in files like /etc/passwd on standalone unix systems. Web services often use SQL databases as user
store.
Today with many more online cloud services SCIM is also an uprising protocol to access userstores.

1.5. Configuration 39
privacyIDEA Authentication System, Release 3.8

Fig. 15: The Config section is the heart of the privacyIDEA server.

Fig. 16: Events can be displayed in the Audit log.

40 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Fig. 17: The Components display client applications and subscriptions

privacyIDEA already comes with UserIdResolvers to talk to all these user stores:
• Flatfile resolver
• LDAP resolver
• SQL resolver
• SCIM resolver
• HTTP resolver

Note: New resolver types (python modules) can be added easily. See the module section for this (UserIdResolvers).

You can create as many UserIdResolvers as you wish and edit existing resolvers. When you have added all configuration
data, most UIs of the UserIdResolvers have a button “Test resolver”, so that you can test your configuration before saving
it.
Starting with privacyIDEA 2.4 resolvers can be editable, i.e. you can edit the users in the user store. Read more about
this at Manage Users.

Note: Using the authentication policy otppin=userstore users can authenticate with the password from their user
store, being the LDAP password, SQL password or password from flat file.

1.5. Configuration 41
privacyIDEA Authentication System, Release 3.8

Flatfile resolver

Flatfile resolvers read files like /etc/passwd.

Note: The file /etc/passwd does not contain the unix password. Thus, if you create a flatfile resolver from this
file the functionality with otppin=userstore is not available. You can create a flatfile with passwords using the tool
privacyidea-create-pwidresolver-user which is usually found in /opt/privacyidea/bin/.

Create a flat file like this:

privacyidea-create-pwidresolver-user -u user2 -i 1002 >> /your/flat/file

LDAP resolver

The LDAP resolver can be used to access any kind of LDAP service like OpenLDAP, Active Directory, FreeIPA,
Penrose, Novell eDirectory.

Server settings

The Server URI can contain a comma separated list of servers. The servers are used to create a server pool and are
used with a round robin strategy1 .
Example:

ldap://server1, ldaps://server2:1636, server3, ldaps://server4

This will create LDAP requests to


• server1 on port 389
• server2 on port 1636 using SSL
• server3 on port 389
• server4 on port 636 using SSL.

TLS Version

When using TLS, you may specify the TLS version to use. Starting from version 3.6, privacyIDEA offers TLS v1.3 by
default.

TLS certificates

When using TLS with LDAP, you can tell privacyIDEA to verify the certificate. The according checkbox is visible in
the WebUI if the target URL starts with ldaps or when using STARTTLS.
You can specify a file with the trusted CA certificate, that signed the TLS certificate. The default CA filename is
/etc/privacyidea/ldap-ca.crt and can contain a list of base64 encoded CA certificates. PrivacyIDEA will use the CA
file if specified. If you leave the field empty it will also try the system certificate store (/etc/ssl/certs/ca-certificates.crt
or /etc/ssl/certs/ca-bundle.crt).
1 https://github.com/cannatag/ldap3/blob/master/docs/manual/source/server.rst#server-pool

42 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Fig. 18: LDAP resolver configuration

1.5. Configuration 43
privacyIDEA Authentication System, Release 3.8

Binding

The Bind Type for querying the LDAP-Server can be Anonymous, Simple, NTLM, SASL Digest-MD5 (Deprecated)
or SASL Kerberos.

Note: When using bind type Simple you can specify the Bind-DN like cn=administrator,cn=users,
dc=domain,dc=name or [email protected]. When using bind type NTLM you need to specify Bind-DN
like DOMAINNAME\\username. In case of SASL Kerberos the Bind-DN needs to be the PrincipalName corresponding
to the given keytab-file.

For the SASL Kerberos bind type, the privacyIDEA server needs to be integrated into the AD Domain. A basic setup
and more information on the Kerberos authentication can be found in the corresponding GitHub Wiki.

Caching

The Cache Timeout configures a short living per process cache for LDAP users. The cache is not shared between
different Python processes, if you are running more processes in Apache or Nginx. You can set this to 0 to deactivate
this cache.

Server Pools

The Server pool retry rounds and Server pool skip timeout settings configure the behavior of the LDAP
server pool. When establishing a LDAP connection, the resolver uses a round-robin strategy to select a LDAP server
from the pool. If the current server is not reachable, it is removed from the pool and will be re-inserted after the number
of seconds specified in the skip timeout. If the pool is empty after a round, a timeout is added before the next round
is started. The ldap3 module defaults system wide to 10 seconds before starting the next round. This timeout can be
changed by setting PI_LDAP_POOLING_LOOP_TIMEOUT to an integer in seconds in the The Config File. If no reachable
server could be found after the number of rounds specified in the retry rounds, the request fails.
By default, knowledge about unavailable pool servers is not persisted between requests. Consequently, a new request
may retry to reach unavailable servers, even though the skip timeout has not passed yet. If the Per-process server pool is
enabled, knowledge about unavailable servers is persisted within each process. This setting may improve performance
in situations in which a LDAP server from the pool is down for extended periods of time.

Modifying users

Starting with privacyIDEA 2.12, you can define the LDAP resolver as editable. I.e. you can create and modify users
from within privacyIDEA.
There are two additional configuration parameters for this case.
DN Template defines how the DN of the new LDAP object should be created. You can use username, surname,
givenname and basedn to create the distinguished name.
Examples:

CN=<givenname> <surname>,<basedn>

CN=<username>,OU=external users,<basedn>

uid=<username>,ou=users,o=example,c=com

44 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Object Classes defines which object classes the user should be assigned to. This is a comma separated list. The
usual object classes for Active Directory are:

top, person, organizationalPerson, user, inetOrgPerson

Resolver settings

The LoginName attribute is the attribute that holds the login name. It can be changed to your needs.
Starting with version 2.20 you can provide a list of attributes in LoginName Attribute like:

sAMAccountName, userPrincipalName

This way a user can login with either his sAMAccountName or his principalName.
The searchfilter is used to list all possible users, that can be used in this resolver. The search filter is used for
forward and backward search the object in LDAP.
The attribute mapping maps LDAP object attributes to user attributes in privacyIDEA. privacyIDEA knows the
following attributes:
• phone,
• mobile,
• email,
• surname,
• givenname,
• password
• accountExpires.
The above attributes are used for privacyIDEA’s normal functionality and are listed in the User Details. However, with
a SAML authentication request, the user attributes can be returned. (see Include SAML attributes in the authentication
response.). To return arbitrary attributes from the LDAP You can add additional keys to the attribute mapping with a
key, you make up and the LDAP attribute like:

"homedir": "homeDirectory",
"studentID": "objectGUID"

"homeDirectory" and "objectGUID" being the attributes in the LDAP directory and "homedir" and "studentID"
the keys returned in a SAML authentication request.
The MULTIVALUEATTRIBUTES config value can be used to specify a list of user attributes, that should return a list
of values. Imagine you have a user mapping like { "phone" : "telephoneNumber", "email" : "mail",
"surname" : "sn", "group": "memberOf"}. Then you could specify ["email", "group"] as the multi
value attribute and the user object would return the emails and the group memberships of the user from the LDAP
server as a list.

Note: If the MULTIVALUEATTRIBUTES is left blank the default setting is “mobile”. I.e. the mobile number will be
returned as a list.

The MULTIVALUEATTRIBUTES can be well used with the samlcheck endpoint (see Validate endpoints) or with the
policy add_user_in_response.

1.5. Configuration 45
privacyIDEA Authentication System, Release 3.8

The UID Type is the unique identifier for the LDAP object. If it is left blank, the distinguished name will be used.
In case of OpenLDAP this can be entryUUID and in case of Active Directory objectGUID. For FreeIPA you can use
ipaUniqueID.

Note: The attributes entryUUID, objectGUID, and ipaUniqueID are case sensitive!

In case of Active Directory connections you might need to check the box No anonymous referral chasing. The
underlying LDAP library is only able to do anonymous referral chasing. Active Directory will produce an error in this
case2 .
The option No retrieval of schema information can be used to disable the retrieval of schema information4
in order to improve performance. This checkbox is deactivated by default and should only be activated after having
ensured that schema information are unnecessary.

Expired Users

You may set:

"accountExpires": "accountExpires"

in the attribute mapping for Microsoft Active Directories. You can then call the user listing API with the parameter
accountExpires=1 and you will only see expired accounts.
This functionality is used with the script privacyidea-expired-users.

SQL resolver

The SQL resolver can be used to retrieve users from any kind of SQL database like MySQL, PostgreSQL, Oracle, DB2
or sqlite.
In the upper frame you need to configure the SQL connection. The SQL resolver uses SQLAlchemy internally. In the
field Driver you need to set a driver name as defined by the SQLAlchemy dialects like “mysql” or “postgres”.
In the SQL attributes frame you can specify how the users are identified.
The Database table contains the users.

Note: At the moment, only one table is supported, i.e. if some of the user data like email address or telephone number
is located in a second table, those data can not be retrieved.

The Limit is the SQL limit for a userlist request. This can be important if you have several thousand user entries in
the table.
The Attribute mapping defines which table column should be mapped to which privacyIDEA attribute. The known
attributes are:
• userid (mandatory),
• username (mandatory),
• phone,
• mobile,
2 https://techcommunity.microsoft.com/t5/azure-active-directory-identity/referral-chasing/ba-p/243177
4 https://ldap3.readthedocs.io/en/latest/schema.html

46 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Fig. 19: SQL resolver configuration

1.5. Configuration 47
privacyIDEA Authentication System, Release 3.8

• email,
• givenname,
• surname,
• password.
The password attribute is the database column that contains the user password. This is used, if you are doing user
authentication against the SQL database.

Note: There is no standard way to store passwords in an SQL database. privacyIDEA supports the most common
ways like Wordpress hashes starting with $P or $S. Secure hashes starting with {SHA} or salted secure hashes starting
with {SSHA}, {SSHA256} or {SSHA512}. Password hashes of length 64 are interpreted as OTRS sha256 hashes.

You can mark the users as Editable. The Password_Hash_Type can be used to determine which hash algorithm
should be used, if a password of an editable user is written to the database.
You can add an additional Where statement if you do not want to use all users from the table.
The poolSize and poolTimeout determine the pooling behaviour. The poolSize (default 5) determine how many
connections are kept open in the pool. The poolTimeout (default 10) specifies how long the application waits to get
a connection from the pool.

Note: The pooling parameters only have an effect if the PI_ENGINE_REGISTRY_CLASS config option is set to
"shared" (see Engine Registry Class). If you then have several SQL resolvers with the same connection and pooling
settings, they will use the same shared connection pool. If you change the connection settings of an existing connection,
the connection pool for the old connection settings will persist until the respective connections are closed by the SQL
server or the web server is restarted.

Note: The Additional connection parameters refer to the SQLAlchemy connection but are not used at the
moment.

SCIM resolver

SCIM is a “System for Cross-domain Identity Management”. SCIM is a REST-based protocol that can be used to ease
identity management in the cloud.
The SCIM resolver is tested in basic functions with OSIAM3 , the “Open Source Identity & Access Management”.
To connect to a SCIM service you need to provide a URL to an authentication server and a URL to the resource server.
The authentication server is used to authenticate the privacyIDEA server. The authentication is based on a Client
name and the Secret for this client.
User information is then retrieved from the resource server.
The available attributes for the Attribute mapping are:
• username (mandatory),
• givenname,
• surname,
• phone,
3 http://osiam.github.io

48 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

• mobile,
• email.

HTTP resolver

Starting with version 3.4 the HTTP resolver is available to retrieve user information from any kind of web service API.
privacyIDEA issues a request to the target service and expects a JSON object in return. The configuration of the HTTP
resolver sets the details of the request in the Request Mapping as well as the mapping of the obtained information as
a Response Mapping.

The Request Mapping is used to build the request issued to the remote API from privacyIDEA’s user information.
For example an endpoint definition:

POST /get-user
customerId=<user_id>&accessKey="secr3t!"

will require a request mapping

1.5. Configuration 49
privacyIDEA Authentication System, Release 3.8

{ "customerId": "{userid}", "accessKey": "secr3t!" }

The Response Mapping follows the same rules as the attribute mapping of the SQL resolver. The known attributes
are
• username (mandatory),
• givenname,
• surname,
• phone,
• mobile,
• email.
Nested attributes are also supported using pydash deep path for parsing, e.g.

{ "username": "{Username}", "email": "{Email}", "phone": "{Phone_Numbers.Phone}" }

For APIs which return 200 OK also for a negative response, Special error handling can be activated to treat the
request as unsuccessful if the response contains certain content.
The above configuration image will throw an error for a response

{ "success": false, "message": "There was an error!" }

because privacyIDEA will match { "success": false }.

Note: If the HTTP response status is >= 400, the resolver will throw an exception.

User Cache

privacyIDEA does not implement local user management by design and relies on UserIdResolvers to connect to external
user stores instead. Consequently, privacyIDEA queries user stores quite frequently, e.g. to resolve a login name to a
user ID while processing an authentication request, which may introduce a significant slowdown. In order to optimize
the response time of authentication requests, privacyIDEA 2.19 introduces the user cache which is located in the local
database. It can be enabled in the system configuration (see User Cache expiration in seconds).
A user cache entry stores the association of a login name in a specific UserIdResolver with a specific user ID for a
predefined time called the expiration timeout, e.g. for one week. The processing of further authentication requests by
the same user during this timespan does not require any queries to the user store, but only to the user cache.
The user cache should only be enabled if the association of users and user ID is not expected to change often: In case
a user is deleted from the user store, but can still be found in the user cache and still has assigned tokens, the user will
still be able to authenticate during the expiration timeout! Likewise, any changes to the user ID will not be noticed by
privacyIDEA until the corresponding cache entry expires.
Expired cache entries are not deleted from the user cache table automatically. Instead, the tool
privacyidea-usercache-cleanup should be used to delete expired cache entries from the database, e.g. in
a cronjob.
However, cache entries are removed at some defined events:
• If a UserIdResolver is modified or deleted, all cache entries belonging to this resolver are deleted.
• If a user is modified or deleted in an editable UserIdResolver, all cache entries belonging to this user are deleted.

50 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Note: Realms with multiple UserIdResolvers are a special case: If a user userX tries to authenticate in a realm with
two UserIdResolvers resolverA (with highest priority) and resolverB, the user cache is queried to find the user ID
of userX in the UserIdResolver resolverA. If the cache contains no matching entry, resolverA itself is queried for
a matching user ID! Only if resolverA does not find a corresponding user, the user cache is queried to determine the
user ID of userX in resolverB. If no matching entry can be found, resolverB is queried.

1.5.2 Realms

Users need to be in realms to have tokens assigned. A user, who is not member of a realm can not have a token assigned
and can not authenticate.
You can combine several different UserIdResolvers (see UserIdResolvers) into a realm. The system knows one default
realm. Users within this default realm can authenticate with their username.
Users in realms, that are not the default realm, need to be additionally identified. Therefor the users need to authenticate
with their username and the realm like this:

user@realm

Relate User to a Realm

There are several options to relate a user to a specific realm during authentication. Usually, if only a login name is
given, the user will be searched in the default realm, indicated with defrealm in the mapping table below.
If a realm parameter is given in a /auth or /validate/check request, it supersedes a possible split realm.
The following table shows different combinations of user(name)-parameter and realm-parameter. Depending on the
Use @ sign to split the username and the realm.-setting, the following table shows in which realm the user will be
searched.

Input parameter Use @ sign to split the username and the realm.-setting
user(name) realm true false
user – user defrealm user defrealm
user realm1 user realm1 user realm1
user unknown – –
user@realm1 – user realm1 user@realm1 defrealm
user@realm1 realm1 user realm1 user@realm1 realm1
user@realm1 realm2 user realm2 user@realm1 realm2
user@realm2 realm1 user realm1 user@realm2 realm1
user@realm1 unknown – –
user@unknown – user@unknown defrealm user@unknown defrealm
user@unknown realm1 user@unknown realm1 user@unknown realm1
user@unknown unknown – –

Note: Be aware that if the Use @ sign to split the username and the realm.-setting is true, a realm parameter is given
and a user name with an @-sign is given where the part after the @ denotes a valid realm, the realm parameter will
take precedence.

1.5. Configuration 51
privacyIDEA Authentication System, Release 3.8

List of Realms

The realms dialog gives you a list of the already defined realms.
It shows the name of the realms, whether it is the default realm and the names of the resolvers, that are combined to
this realm.
You can delete or edit an existing realm or create a new realm.

Edit Realm

Each realm has to have a unique name. The name of the realm is case insensitive. If you create a new realm with the
same name like an existing realm, the existing realm gets overwritten.
If you click Edit Realm you can select which userresolver should be contained in this realm. A realm can contain several
resolvers.

Fig. 20: Edit a realm

Resolver Priority

Within a realm you can give each resolver a priority. The priority is used to find a user that is located in several resolvers.
If a user is located in more than one resolver, the user will be taken from the resolver with the lowest number in the
priority.
Priorities are numbers between 1 and 999. The lower the number the higher the priority.
Example:
A user “administrator” is located in a resolver “users” which contains all Active Directory users. And the “administra-
tor” is located in a resolver “admins”, which contains all users in the Security Group “Domain Admins” from the very
same domain. Both resolvers are in the realm “AD”, “admins” with priority 1 and “users” with priority 2.
Thus the user “administrator@AD” will always resolve to the user located in resolver “admins”.
This is useful to create policies for the security group “Domain Admins”.

Note: A resolver has a priority per realm. I.e. a resolver can have a different priority in each realm.

52 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Autocreate Realm

If you have a fresh installation, no resolver and no realm is defined. To get you up and running faster, the system will
ask you, if it should create the first realm for you.
If you answer “yes”, it will create a resolver named “deflocal” that contains all users from /etc/passwd and a realm
named “defrealm” with this very resolver.
Thus you can immediately start assigning and enrolling tokens.
If you check “Do not ask again” this will be stored in a cookie in your browser.

Note: The realm “defrealm” will be the default realm. So if you create a new realm manually and want this new realm
to be the default realm, you need to set this new realm to be default manually.

1.5.3 System Config

The system configuration has three logical topics: Settings, token default settings and GUI settings.

Settings

Use @ sign to split the username and the realm.

splitAtSign defines if the username like user@company given during authentication should be split into the login-
name user and the realm name company. In most cases this is the wanted behaviour so this is enabled by default.
But given your users log in with email addresses like [email protected] and [email protected] you probably do
not want to split.
How a user is related to a realm is described here: Relate User to a Realm
This option also affects the login via the Authentication endpoints

1.5. Configuration 53
privacyIDEA Authentication System, Release 3.8

Fig. 21: The system config

54 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Increase the failcounter if the wrong PIN was entered.

If during authentication the given PIN matches a token but the OTP value is wrong the failcounter of the tokens for
which the PIN matches, is increased. If the given PIN does not match any token, by default no failcounter is increased.
The latter behaviour can be adapted by FailCounterIncOnFalsePin. If FailCounterIncOnFalsePin is set and
the given OTP PIN does not match any token, the failcounter of all tokens is increased.

Clear failcounter after x minutes

If the failcounter reaches the maximum the token gets a timestamp, when the max fail count was reached. After the
specified amount of minutes in failcounter_clear_timeout the following will clear the failcounter again:
• A successful authentication with correct PIN and correct OTP value
• A successfully triggered challenge (Usually this means a correct PIN)
• An authentication with a correct PIN, but a wrong OTP value (Only if Resetting Failcounter on correct PIN is
set).
A “0” means automatically clearing the fail counter is not used.

Note: After the maximum failcounter is reached, new requests will not update the mentioned timestamp.

Also see How to mitigate brute force and lock tokens.

Resetting Failcounter on correct PIN

After the above mentioned timeout the failcounter is reset by a successful authentication (correct PIN and OTP value)
or by the correct PIN of a challenge response token.
It can be also reset by the correct PIN of any token, when setting ResetFailcounterOnPIN to True. The default
behaviour is, that the correct PIN of a normal token will not reset the failcounter after the clearing timeout.

Prepend the PIN in front of the OTP value.

Defines if the OTP PIN should be given in front (“pin123456”) or in the back (“123456pin”) of the OTP value.

Include SAML attributes in the authentication response.

Return SAML attributes defines if during an SAML authentication request additional SAML attributes should be
returned. Usually an authentication response only returns true or false.
The SAML attributes are the known attributes that are defined in the attribute mapping e.g. of the LDAP resolver like
email, phone, givenname, surname or any other attributes you fetch from the LDAP directory. For more information
read LDAP resolver.
In addition you can set the parameter ReturnSamlAttributesOnFail. In this case the response contains the SAML
attributes of the user, even if the user failed to authenticate.

1.5. Configuration 55
privacyIDEA Authentication System, Release 3.8

Automatic resync during authentication

Automatic resync defines if the system should try to resync a token if a user provides a wrong OTP value. AutoResync
works like this:
• If the counter of a wrong OTP value is within the resync window, the system remembers the counter of the OTP
value for this token in the token info field otp1c.
• Now the user needs to authenticate a second time within auto resync timeout with the next successive OTP
value.
• The system checks if the counter of the second OTP value is the successive value to otp1c.
• If it is, the token counter is set and the user is successfully authenticated.

Note: AutoResync works for all HOTP and TOTP based tokens including SMS and Email tokens.

User Cache expiration in seconds

The setting User Cache expiration in seconds is used to enable the user cache and configure its expiration
timeout. If its value is set to 0 (which is the default value), the user cache is disabled. Otherwise, the value determines
the time in seconds after which entries of the user cache expire. For more information read User Cache.

Note: If the user cache is already enabled and you increase the expiration timeout, expired entries that still exist in the
user cache could be considered active again!

Override Authorization Client

Override Authorization client is important with client specific policies (see Policies) and RADIUS servers or
other proxies. In case of RADIUS the authenticating client for the privacyIDEA system will always be the RADIUS
server, which issues the authentication request. But you can allow the RADIUS server IP to send another client infor-
mation (in this case the RADIUS client) so that the policy is evaluated for the RADIUS client. A RADIUS server may
add the API parameter client with a new IP address. A HTTP reverse proxy may append the respective client IP to the
X-Forwarded-For HTTP header.
This field takes a comma separated list of sequences of IP Networks mapping to other IP networks.
Examples

10.1.2.0/24 > 192.168.0.0/16

Proxies in the sub net 10.1.2.0/24 may mask as client IPs 192.168.0.0/16. In this case the policies for the corresponding
client in 192.168.x.x apply.

172.16.0.1

The proxy 172.16.0.1 may mask as any arbitrary client IP.

10.0.0.18 > 10.0.0.0/8

The proxy 10.0.0.18 may mask as any client in the subnet 10.x.x.x.
Note that the proxy definitions may be nested in order to support multiple proxy hops. As an example:

56 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

10.0.0.18 > 10.1.2.0/24 > 192.168.0.0/16

means that the proxy 10.0.0.18 may map to another proxy into the subnet 10.1.2.x, and a proxy in this subnet may mask
as any client in the subnet 192.168.x.x.
With the same configuration, a proxy 10.0.0.18 may map to an application plugin in the subnet 10.1.2.x, which may in
turn use a client parameter to mask as any client in the subnet 192.168.x.x.

Token default settings

Reset Fail Counter

DefaultResetFailCount will reset the failcounter of a token if this token was used for a successful authentication.
If not checked, the failcounter will not be reset and must be reset manually.

Note: The following settings are token specific value which are set during enrollment. If you want to change this value
of a token later on, you need to change this at the tokeninfo dialog.

Maximum Fail Counter

DefaultMaxFailCount is the maximum failcounter a token may get. If the failcounter exceeds this number the token
can not be used unless the failcounter is reset.

Note: In fact the failcounter will only increase till this maxfailcount. Even if more failed authentication request occur,
the failcounter will not increase anymore.

Sync Window

DefaultSyncWindow is the window how many OTP values will be calculated during resync of the token.

OTP Length

DefaultOtpLen is the length of the OTP value. If no OTP length is specified during enrollment, this value will be
used.

Count Window

DefaultCountWindow defines how many OTP values will be calculated during an authentication request.

1.5. Configuration 57
privacyIDEA Authentication System, Release 3.8

Challenge Validity Time

DefaultChallengeValidityTime is the timeout for a challenge response authentication. If the response is set after
the ChallengeValidityTime, the response is not accepted anymore.

SerialLength

The default length of generated serial numbers is an 8 digit hex string. If you need another length, it can be configured
in the database table Config with the key word SerialLength.

No Authentication Counter

Usually privacyIDEA keeps track of how often a token is used for authentication and how often this authentication was
successful. This is a per token counter. This information is written to the token database as a parameter of each token.
The setting “Do not use an authentication counter per token” (no_auth_counter) means that privacyIDEA does not
track this information at all.

1.5.4 CA Connectors

You can use privacyIDEA to enroll certificates and assign certificates to users.
You can define connections to Certificate Authorities, that are used when enrolling certificates.
When you enroll a Token of type certificate the Certificate Signing Request gets signed by one of the CAs attached to
privacyIDEA by the CA connectors.
The first CA connector that ships with privacyIDEA is a connector to a local openSSL based Certificate Authority as
shown in figure A local CA definition.
When enrolling a certificate token you can choose, which CA should sign the certificate request.

Local CA Connector

The local CA connector calls a local openssl configuration.


Starting with privacyIDEA version 2.12 an example openssl.cnf is provided in /etc/privacyidea/CA/openssl.cnf.

Note: This configuration and also this description is ment to be as an example. When setting up a productive CA, you
should ask a PKI consultant for assistance.

Manual Setup

1. Modify the parameters in the file /etc/privacyidea/CA/openssl.cnf according to your needs.


2. Create your CA certificate:

openssl req -days 1500 -new -x509 -keyout /etc/privacyidea/CA/ca.key \


-out /etc/privacyidea/CA/ca.crt \
-config /etc/privacyidea/CA/openssl.cnf
(continues on next page)

58 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Fig. 22: A local CA definition

1.5. Configuration 59
privacyIDEA Authentication System, Release 3.8

Fig. 23: Enrolling a certificate token

60 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

(continued from previous page)

chmod 0600 /etc/privacyidea/CA/ca.key


touch /etc/privacyidea/CA/index.txt
echo 01 > /etc/privacyidea/CA/serial
chown -R privacyidea /etc/privacyidea/CA

3. Now set up a local CA connector within privacyIDEA with the directory /etc/privacyidea/CA and the files ac-
cordingly.

Easy Setup

Starting with privacyIDEA version 2.18 it gets easier to setup local CAs.
You can use the The pi-manage Script tool to setup a new CA like this:
pi-manage ca create myCA
This will ask you for all necessary parameters for the CA and then automatically
1. Create the files for this new CA and
2. Create the CA connector in privacyIDEA.

Management

There are different ways to enroll a certificate token. See Certificate Token.
When an administrator revokes a certificate token, the certificate is revoked and a CRL is created.

Note: privacyIDEA does not create the CRL regularly. The CRL usually has a validity period of 30 days. I.e. you
need to create the CRL on a regular basis. You can use openssl to do so or the pi-manage command.

Starting with version 2.18 the pi-manage command has an additional sub-command ca:
pi-manage ca list
lists all configured CA connectors. You can use the -v switch to get more information.
You can create a new CRL with the command:
pi-manage ca create_crl <CA name>
This command will check the overlap period and only create a new CRL if it is necessary. If you want to force the
creation of the CRL, you can use the switch -f.
For more information on pi-manage see The pi-manage Script.

1.5. Configuration 61
privacyIDEA Authentication System, Release 3.8

Templates

The local CA supports a kind of certificate templates. These “templates” are predefined combinations of extensions
and validity days, as they are passed to openssl via the parameters -extensions and -days.
This way the administrator can define certificate templates with certain X.509 extensions like keyUsage, extended-
KeyUsage, CDPs or AIAs and certificate validity periods.
The extensions are defined in YAML file and the location of this file is added to the CA connector definition.
The file can look like this, defining three templates “user”, “webserver” and “template3”:
user: days: 365 extensions: “user”
webserver: days: 750 extensions: “server”
template3: days: 10 extensions: “user”

Microsoft CA Connector

This CA connector communicates to the privacyIDEA MS CA worker, that is installed on a Windows server in the
Windows Domain. Through this worker, privacyIDEA can connect potentially to all Microsoft CAs in the Windows
Domain.
The Microsoft CA Connector has the following options.
Hostname
The hostname (FQDN) or IP address where the privacyIDEA MS CA worker is running.

Note: If you configure Use SSL, you need to provide the correct hostname as it is contained in the server certificate.

Port
The port on which the worker listens.
Connect via Proxy
Whether the worker is situated behind a HTTP proxy.
Domain CA
The worker will provide a list of available CAs in the domain. This is the actual CA to which privacyIDEA shall com-
municate. After providing the initial connection information hostname and Port, privacyIDEA can fetch the available
CAs in the Windows Domain. The CA is identified by the hostname where the Microsoft CA is running and the name
of the CA like <hostname>\<name of CA>.
Use SSL
This is a boolean parameter. If it is checked, then privacyIDEA will communicate to the CA worker via TLS. Depending
on the worker configuration it will also be required, to provide a client certificate for authentication.

Note: In productive use SSL should always be activated and a client certificate must be used for authentication.

CA certificate
This is the location of the file, that contains the CA certificate, that issued the CA worker server certificate. This file is
located on the privacyIDEA server in PEM format.
Client certificate

62 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

This is the file location of the certificate that privacyIDEA uses to authenticate against the CA worker. It is in PEM
format.

Note: The subject of this certificate must match the name of the privacyIDEA server as seen by the CA worker. It is
a good idea to request the client certificate from the CA on the domain where the CA worker is actually running at.

Client private key


This is the location of the file containing the private key that belongs to the Client certificate. It is in PEM format and
can either be password protected (encrypted) or not.
The key can be provided in PKCS1 or PKCS8 format.

Note: The PCKCS1 format will start with “—–BEGIN RSA PRIVATE KEY—–”, the PKCS8 format will start with
“—–BEGIN PRIVATE KEY—–“.

To convert between PKCS1 and PKCS8 format you can use:

openssl pkcs8 -in private-p1.pem -topk8 -out private-p8.pem -nocrypt


openssl pkcs8 -in private-p1.pem -topk8 -out private-p8-encrypted.pem

openssl rsa -in private-p8.pem -out private-p1.pem

Password of client certificate


This is the password of the encrypted client private key.

Note: We strongly recommend to protect the file with a password. As encrypted key files we only support PKCS8!

1.5.5 Basic setup from the command line

Of cours the MS CA Connector can be configured in the privacyIDEA Web UI. For quick setup, you can also configure
a connector at the command line using pimange like this:

pi-manage ca create -t microsoft <name-of-connector>

It will ask you all relevant questions and setup a connector in privacyIDEA.

1.5.6 SMTP server configuration

Starting with privacyIDEA 2.10 you can define SMTP server configurations. SMTP server endpoints.
An SMTP server configuration contains the
• server as FQDN or IP address,
• the port (defaults to 25),
• the sender email address,
• a username and password in case of authentication
• an optional description

1.5. Configuration 63
privacyIDEA Authentication System, Release 3.8

• a TLS flag.
Each SMTP server configuration is addressed via a unique identifier. You can then use such a configuration for Email
or SMS token, for PIN handling or in policies for User registration.
Under Config->Sytem->SMTP servers you can get a list of all configured SMTP servers, create new server definitions
and delete them.

Fig. 24: The list of SMTP servers.

In the edit dialog you can enter all necessary attributes to talk to the SMTP server. You can also send a test email, to
verify if your settings are correct.
In case a Job Queue is configured, the SMTP server dialog shows a checkbox that enables sending all emails for the
given SMTP server configuration via the job queue. Note that if the checkbox is checked, any test email will also be
sent via the queue. This also means that privacyIDEA will display a success notice when the job has been sent to the
queue successfully, which does not necessarily mean that the mail was actually sent. Thus, it is important to check that
the test email is actually received.

1.5.7 RADIUS server configuration

At config->system->RADIUS servers the administrator can configure a RADIUS servers to which privacyIDEA can
forward authentication requests.
These RADIUS servers can be used with RADIUS tokens and in the Passthru Policy.

Note: This is meant for outgoing RADIUS requests, not for incoming RADIUS requests! To receive RADIUS requests
you need to install the privacyIDEA FreeRADIUS plugin.

1.5.8 privacyIDEA server configuration

At config->system->privacyIDEA servers the administrator can configure a remote privacyIDEA servers. These can
be used in the Remote or in the Federation Handler Module to forward the authentication request to.

64 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Fig. 25: Edit an existing SMTP server definition.

1.5. Configuration 65
privacyIDEA Authentication System, Release 3.8

Fig. 26: privacyIDEA can reveice incoming RADIUS requests and send outgoing RADIUS requests.

66 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

1.5.9 SMS Gateway configuration

You can centrally define SMS gateways that can be used to send SMS with SMS Token or to use the SMS gateway for
sending notifications.
There are different providers (gateways) to deliver SMS.

Firebase Provider

The Firebase provider was added in privacyIDEA 3.0. It sends notifications via the Google Firebase service and this
is used for the Push Token. For an exemplary configuration, you may have a look on the articles on the privacyIDEA
community website tagged with push token.
JSON config file
This is the location of the configuration file of the Firebase service. It has to be located on the privacyIDEA
server.
You can get the necessary JSON config file, from your Firebase console. The default PUSH authenticator App (priva-
cyIDEA Authenticator) which you can find in Google Play Store and Apple App Store uses a Firebase project, that is
managed by the company NetKnights. You need to get an SLA to receive a JSON config file for accessing the project.

HTTP provider

The HTTP provider can be used for any SMS gateway that provides a simple HTTP POST or GET request. This is the
most commonly used provider. Each provider type defines its own set of parameters.
The following parameters can be used. These are parameters, that define the behaviour of the SMS Gateway definition.
CHECK_SSL
If the URL is secured via TLS (HTTPS), you can select, if the certificate should be verified or not.
PROXY, HTTP_PROXY and HTTP_PROXY
You can specify a proxy to connect to the HTTP gateway. Use the specific values to separate HTTP and
HTTPS.
REGEXP
Regular expression to modify the phone number to make it compatible with provider.
Example: If you want to replace the leading zero with your country code like 0123456789 ->
0049123456789, then you need to enter /^0/0049/.

1.5. Configuration 67
privacyIDEA Authentication System, Release 3.8

HTTP_METHOD
Can be GET or POST.
RETURN_FAIL
If the text of RETURN_FAIL is found in the HTTP response of the gateway privacyIDEA assumes that the
SMS could not be sent and an error occurred.
RETURN_SUCCESS
You can either use RETURN_SUCCESS or RETURN_FAIL. If the text of RETURN_SUCCESS is found in the
HTTP response of the gateway privacyIDEA assumes that the SMS was sent successfully.
TIMEOUT
The timeout for contacting the API and receiving a response.
URL
This is the URL for the gateway.
USERNAME and PASSWORD
These are the username and the password if the HTTP request requires basic authentication.
PARAMETER
This can contain a dictionary of arbitrary fixed additional parameters. Usually this would also contain an
ID or a password to identify you as a sender.

Options

You can define additional options. These are sent as parameters in the GET or POST request.

Note: The fixed parameters and the options can not have the same name! If you need an options, that has the same
name as a parameter, you must not fill in the corresponding parameter.

Note: You can use the tags {phone} to specify the phone number. The tag {otp} will be replaced simply with the
OTP value or with the contents created by the policy smstext.

Examples

Clickatell

In case of the Clickatell provider the configuration will look like this:
• URL: http://api.clickatell.com/http/sendmsg
• HTTP_METHOD: GET
• RETURN_SUCCESS: ID
Set the additional options to be passed as HTTP GET parameters:
• user: YOU
• password: your password

68 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

• api_id: you API ID


• text: “Your OTP value is {otp}”
• to: {phone}
This will construct an HTTP GET request like this:

http://api.clickatell.com/http/sendmsg?user=YOU&password=YOU&\
api_id=YOUR API ID&text=....&to=....

where text and to will contain the OTP value and the mobile phone number. privacyIDEA will assume a successful
sent SMS if the response contains the text “ID”.

GTX-Messaging

GTX-Messaging is an SMS Gateway located in Germany.


The configuration looks like this (see2 ):
• URL: https://http.gtx-messaging.net/smsc.php
• HTTP_METHOD: GET
• CHECK_SSL: yes
• RETURN_SUCCESS: 200 OK
You need to set the additional options:
• user: <your account>
• pass: <the account password>
• to: {phone}
• text: Your OTP value is {otp}.

Note: The user and pass are not the credentials you use to login. You can find the required credentials for sending
SMS in your GTX messaging account when viewing the details of your routing account.

Twilio

You can also use the Twilio service for sending SMS.1 .
• URL: https://api.twilio.com/2010-04-01/Accounts/B. . . 8/Messages
• HTTP_METHOD: POST
For basic authentication you need:
• USERNAME: your accountSid
• PASSWORD: your password
Set the additional options as POST parameters:
• From: your Twilio phone number
2 https://www.gtx-messaging.com/de/api-docs/http/
1 https://www.twilio.com/docs/api/rest/sending-messages

1.5. Configuration 69
privacyIDEA Authentication System, Release 3.8

• Body: {otp}
• To: {phone}

Sipgate provider

The sipgate provider connects to https://samurai.sipgate.net/RPC2 and takes only two arguments USERNAME and
PASSWORD.
Parameters:
USERNAME
The sipgate username.
PASSWORD
The sipgate password.
PROXY
You can specify a proxy to connect to the HTTP gateway.
It takes not options.
If you activate debug log level you will see the submitted SMS and the response content from the Sipgate gateway.

SMPP Provider

The SMPP provider was added in privacyIDEA 2.22. It uses an SMS Center via the SMPP protocol to deliver SMS to
the users.
You need to specify the SMSC_HOST and SMSC_PORT to talk to the SMS center. privacyIDEA need to authenticate
against the SMS center. For this you can add the parameters SYSTEM_ID and PASSWORD. The parameter S_ADDR
is the sender’s number, shown to the users receiving an SMS. For the other parameters contact your SMS center operator.

SMTP provider

The SMTP provider sends an email to an email gateway. This is a specified, fixed mail address.
The mail should contain the phone number and the OTP value. The email gateway will send the OTP via SMS to the
given phone number.
BODY
This is the body of the email. You can use this to explain the user, what he should do with this email. You
can use the tags {phone} and {otp} to replace the phone number or the one time password.
MAILTO
This is the address where the email with the OTP value will be sent. Usually this is a fixed email address
provided by your SMTP Gateway provider. But you can also use the tags {phone} and {otp} to replace
the phone number or the one time password.
SMTPIDENTIFIED
Here you can select on of your centrally defined SMTP servers.
SUBJECT
This is the subject of the email to be sent. You can use the tags {phone} and {otp} to replace the phone
number or the one time password.

70 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

The default SUBJECT is set to {phone} and the default BODY to {otp}. You may change the SUBJECT and the BODY
accordingly.

Script provider

The Script provider calls a script which can take care of sending the SMS. The script takes the phone number as the
only parameter. The message is expected at stdin.
Scripts are located in the directory /etc/privacyidea/scripts/. You can change this default location by setting
the value in PI_SCRIPT_SMSPROVIDER_DIRECTORY in pi.cfg.
In the configuration of the Script provider you can set two attributes.
SCRIPT
This is the file name of the script without the directory part.
BACKGROUND
Here you can choose, whether the script should be started and run in the background or if the HTTP requests waits for
the script to finish.

1.5.10 Token configuration

Each of the Token types in privacyIDEA can provide its own configuration dialog.
In this configuration dialog you can define default values for these token types. Some token additionally require Con-
figuration such as the configuration of an SMTP server.

Fig. 27: Examplary token configuration for an SMS Token

1.5. Configuration 71
privacyIDEA Authentication System, Release 3.8

Email Token Configuration

Fig. 28: Email Token configuration

For the email token to work, you have to first setup an SMTP server configuration and link it to the Email Token
configuration at Config -> Tokens -> Email. The UI warns the user if one of these requirements is not fulfilled yet.
The Email OTP token creates a OTP value and sends this OTP value to the email address of the uses. The email can
be triggered by authenticating with only the OTP PIN:

First step

In the first step the user will enter his OTP PIN and the sending of the email is triggered. The user is denied the access.

Seconds step

In the second step the user authenticates with the OTP PIN and the OTP value he received via email. The user is granted
access.
Alternatively the user can authenticate with the transaction_id that was sent to him in the response during the first
step and only the OTP value. The transaction_id assures that the user already presented the first factor (OTP PIN)
successfully.

Configuration Parameters

Concurrent Challenges
The config entry email.concurrent_challenges set in The Config File will save the sent OTP value in the challenge
database. This way several challenges can be open at the same time. The user can answer the challenges in an arbitrary
order. Set this to a true value. Defaults to off.

72 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Deprecated Configuration Parameters

There are few more config entries handled, which are deprecated in recent versions of privacyIDEA.
• email.mailserver - The name or IP address of the mail server that is used to send emails.
• email.port - The port of the mail server.
• email.username - If the mail server requires authentication you need to enter a username. If no username is
entered, no authentication is performed on the mail server.
• email.password - The password of the mail username to send emails.
• email.mailfrom - The mail address of the mail sender. This needs to correspond to the Mail User.
• email.validtime - This is the time in seconds, for how long the sent OTP value is valid. If a user tries to
authenticate with the sent OTP value after this time, authentication will fail.
• email.tls - Whether the mail server should use TLS.

HOTP Token Config

Fig. 29: HOTP Token configuration

SMS Token Configuration

The SMS OTP token creates a OTP value and sends this OTP value to the mobile phone of the user. The SMS can be
triggered by authenticating with only the OTP PIN:

First step

In the first step the user will enter his OTP PIN and the sending of the SMS is triggered. The user is denied the access.

1.5. Configuration 73
privacyIDEA Authentication System, Release 3.8

Second step

In the second step the user authenticates with the OTP PIN and the OTP value he received via SMS. The user is granted
access.
Alternatively the user can authenticate with the transaction_id that was sent to him in the response during the first
step and only the OTP value. The transaction_id assures that the user already presented the first factor (OTP PIN)
successfully.
A python SMS provider module defines how the SMS is sent. This can be done using an HTTP SMS Gateway. Most
services like Clickatel or sendsms.de provide such a simple HTTP gateway. Another possibility is to send SMS via
sipgate, which provides an XMLRPC API. The third possibility is to send the SMS via an SMTP gateway. The provider
receives a specially designed email and sends the SMS accordingly. The last possibility to send SMS is to use an
attached GSM modem.
Starting with version 2.13 the SMS configuration has been redesigned. You can now centrally define SMS gateways.
These SMS gateways can be used for sending SMS OTP token but also for the event notifications. (See User Notification
Handler Module)
For configuring SMS Gateways read SMS Gateway configuration. I this token configuration you can select on defined
gateway to send SMS for authentication.

Configuration Parameters

Concurrent Challenges
If set to True in The Config File, the config entry sms.concurrent_challenges will save the sent OTP value in the
challenge database. This way several challenges can be open at the same time. The user can answer the challenges in
an arbitrary order. Defaults to off.

TiQR Token Configuration

TiQR Registration Server

You need at least enter the TiQR Registration Server. This is the URL of your privacyIDEA installation, that can be
reached from the smartphone during enrollment. So your smartphone needs to be on the same LAN (WLAN) like the
privacyIDEA server or the enrollment URL needs to be accessible from the internet.
You also need to specify the path, which is usually /ttype/tiqr.
During enrollment the parameter action=metadata and action=enrollment is added.

Note: We do not recommend putting the registration URL on the internet.

74 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Fig. 30: TiQR Token configuration

1.5. Configuration 75
privacyIDEA Authentication System, Release 3.8

TiQR Authentication Server

This is the URL that is used during authentication. This can be another URL than the Registration Server. If it is left
blank, the URL of the Registration Server is used.
During authentication the parameter operation=login is added.

TOTP Token Config

Fig. 31: TOTP Token configuration

U2F Token Config

AppId

You need to configure the AppId of the privacyIDEA server. The AppId is define in the FIDO specification1 .
The AppId is the URL of your privacyIDEA and used to find or create the right key pair on the U2F device. The AppId
must correspond the the URL that is used to call the privacyIDEA server.

Note: if you register a U2F device with an AppId https://privacyidea.example.com and try to authenticate at https:
//10.0.0.1, the U2F authentication will fail.

Note: The AppId must not contain any trailing slashes!

1 https://fidoalliance.org/specs/fido-u2f-v1.0-nfc-bt-amendment-20150514/fido-appid-and-facets.html

76 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Facets

If specifying the AppId as the FQDN you will only be able to authenticate at the privacyIDEA server itself or at any
application in a sub directory on the privacyIDEA server. This is OK, if you are running a SAML IdP on the same
server.
But if you also want to use the U2F token with other applications, you need to specify the AppId like this:
https://privacyidea.example.com/pi-url/ttype/u2f
pi-url is the path, if you are running the privacyIDEA instance in a sub folder.
/ttype/u2f is the endpoint that returns a trusted facets list. Trusted facets are other hosts in the domain example.com.
You need to define a policy that contains a list of the other hosts (u2f_facets).
For more information on AppId and trusted facets see? .
For further details and for information how to add U2F to your application you can see the code documentation at U2F
Token.

Workflow

You can use a U2F token on privacyIDEA and other hosts in the same Domain. To do so you need to do the following
steps:
1. Configure the AppId to reflect your privacyIDEA server:
https://pi.your-network.com/ttype/u2f
Add the path /ttype/u2f is crucial. Otherwise privacyIDEA will not return the trusted facets.
2. Define a policy with the list of trusted facets. (see u2f_facets). Add the FQDNs of the hosts to the policy:
saml.your-network.com otherapp.your-network.com vpn.your-network.com

Note: The privacyIDEA plugin for simpleSAMLphp supports U2F with privacyIDEA starting with version 2.8.

3. Now register a U2F token on https://pi.your-network.com. Due to the trusted facets you will also be able to use
this U2F token on the other hosts.
4. Now got to https://saml.your-network.com and you will be able to authenticate with the very U2F token without
any further registering.

WebAuthn Token Config

Trust Anchor Directory

You may define a directory containing trust roots for attestation certificates.
This should be a path to a local directory on the server which privacyIDEA has read access to. Any certificate in this
directory will be trusted to correctly attest authenticators during enrollment.
This does not need to be set for WebAuthn to work, however without this, privacyIDEA can not check, whether an
attestation certificate is actually trusted (it will still be checked for validity). Therefore it is mandatory to set this, if
webauthn_authenticator_attestation_level is set to “trusted” through policy for any user.

1.5. Configuration 77
privacyIDEA Authentication System, Release 3.8

WebAuthn Required Policies

For WebAuthn to work, a name and ID for the relying party need to be set. The relying party in WebAuthn represents
the entity the user is registering with. In most cases this will be your company. In larger companies it is often helpful to
segment according to department by setting up multiple ID and name policies for WebAuthn which apply to different
users.

Relying Party ID

The ID of the relying party must be a fully-qualified domain name. Every web-service, where the WebAuthn to-
ken should be used needs to be reachable under a domain name which is a superset (i.e. a subdomain) of this ID.
This means that a WebAuthn token enrolled with a relying party ID of example.com may be used to sign in to pri-
vacyidea.example.com and owncloud.example.com. However, this token will not be able to sign in to a service under
example.de, or any other webservice that is not hosted on a subdomain of example.com.
See also: webauthn_relying_party_id.

Relying Party Name

This is a human-readable name to go along with the relying party ID. It will usually be either the name of your company
(if there is just one relying party for the entire company), or the name of the department or other organizational unit
the relying party represents.
See also: webauthn_relying_party_name.

Yubico Cloud mode

The Yubico Cloud mode sends the One Time Password emitted by the Yubikey to the Yubico Cloud service or another
(possibly self hosted) validation server.

Fig. 32: Configure the Yubico Cloud mode

To contact the Yubico Cloud service you need to get an API key and a Client ID from Yubico and enter these here in
the config dialog. In that case you can leave the Yubico URL blank and privacyIDEA will use the Yubico servers.

78 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

You can use another validation host, e.g. a self hosted validation server. If you use the privacyIDEA token type
Yubikey, you can use the URL https://<privacyideaserver>/ttype/yubikey, other validation servers might use
https://<validationserver>/wsapi/2.0/verify. You’ll get the Client ID and API key from the configuration
of your validation server.
You can get your own API key at1 .

Yubikey AES mode

The Yubico AES mode uses the same kind of token as the Yubico Cloud service, but validates the OTP in your local
privacyidea server. So the secrets stay local to your system and are not stored in Yubico’s Cloud service.

Fig. 33: Configure the Yubikey AES mode

You can have more than one Client with a Client ID connect to your server. The Client ID starts with yubikey.apiid.
and is followed by the API ID, which you’ll need to configure your clients. With create new API key you generate
a new API for that specific Client ID. The API key is used to sign the validation request sent to the server and the
server signs the answer too. That way tampering or MITM attacks might be detected. It is possible to validate token
without the API key, but then the request and answer can’t be verify against the key. It is useful to use HTTPS for your
validation requests, but this is another kind of protection.
OTP validation can either use the privacyidea API /validate/check or the Yubikey validation protocol /ttype/
yubikey or - if enabled in your webserver configuration - /wsapi/2.0/verify.

1.5.11 privacyIDEA Appliance

privacyIDEA offers an appliance tool to manage your token administrators, RADIUS clients and also setup MySQL
master-master replication. It can be found in a Github repository1 .
This tool is supposed to run on Ubuntu 16.04 LTS or 18.04 LTS. You can find a ready install ISO at another Github
repository2 .
1 https://upgrade.yubico.com/getapikey/.
1 https://github.com/NetKnights-GmbH/privacyidea-appliance
2 https://github.com/NetKnights-GmbH/privacyidea-appliance-iso

1.5. Configuration 79
privacyIDEA Authentication System, Release 3.8

Note: The ready made Ubuntu package for the appliance tool is only available with a Service Level Agreement from
the company NetKnights3 .

To configure the system, login as the user root on your machine and run the command:
pi-appliance

This will bring you to this start screen.

Fig. 34: Start screen of the appliance setup tool.

You can configure privacyidea settings, the log level, administrators, encryption key and much more. You can configure
the webserver settings and RADIUS clients.

Fig. 35: Configure privacyidea

All changes done in this setup tool are directly read from and written to the corresponding configuration files. The
setup tool parses the original nginx and freeradius configuration files. So there is no additional place where this data
is kept.
3 https://netknights.it/en/produkte/privacyidea/

80 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Fig. 36: You can create new token administrators, delete them and change their passwords.

Fig. 37: In the FreeRADIUS settings you can create and delete RADIUS clients.

1.5. Configuration 81
privacyIDEA Authentication System, Release 3.8

Note: You can also edit the clients.conf and other configuration files manually. The setup tool will also read those
manual changes!

Backup and Restore

Starting with version 1.5 the setup tool also supports backup and restore. Backups are written to the directory
/var/lib/privacyidea/backup.
The backup contains all privacyIDEA configuration, the contents of the directory /etc/privacyidea, the encryption key,
the configured administrators, the complete token database (MySQL) and Audit log. Furthermore if you are running
FreeRADIUS the backup also contains the /etc/freeradius/clients.conf file.

Scheduled backup

At the configuration point Configure Backup you can define times when a scheduled backup should be performed. This
information is written to the file /etc/crontab.
You can enter minutes, hours, day of month, month and day of week. If the entry should be valid for each e.g. month
or hour, you need to enter a ‘*’.
In this example the 10 17 * * * (minute=10, hour=17) means to perform a backup each day and each month at 17:10
(5:10pm).
The example 1 10 1 * * (minute=1, hour=10, day of month=1) means to perform a backup on the first day of each
month at 10:01 am.
Thus you could also perform backups only once a week at the weekend.

82 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Fig. 38: Scheduled backup

Immediate backup

If you want to run a backup right now you can choose the entry Backup now.

Restore

The entry View Backups will list all the backups available.

Fig. 39: All available backups

You can select a backup and you are asked if you want to restore the data.

1.5. Configuration 83
privacyIDEA Authentication System, Release 3.8

Warning: Existing data is overwritten and will be lost.

Database: Setup Redundancy

The appliance-tool is also capable of setting up a redundant setup between two privacyIDEA nodes in master-master
replication. The administrator sets up redundancy on the first configured node. On the second node the same version
of privacyIDEA needs to be installed. No configuration needs to be done on the second node. The configuration and
the token database is completely copied from the first node to the second node. Possible existing configuration on the
second node will be overwritten during the setup. The appliance-tool can also set up an encrypted VPN that is used
for the replication of the database.

Note: If you choose to use the tinc VPN connection between the nodes and an SSH root login, make sure the services
are installed.

Warning: Existing data on the second node is overwritten and will be lost.

Updates

In this menu, you can setup cronjobs for automatic updates which is seldom used in productive setups.

Audit Rotation

In the Audit Rotation menu, you can setup cronjobs for the audit rotation conditioned by age or the number of entries.
The syntax follows the crontab syntax as explained in Backup and Restore.

Note: Keep in mind that the audit log is synchronized between the nodes in a redundant setup. If you chose to rotate
both audit logs, make sure you do it at different times to avoid synchronisation issues.

84 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

1.6 Tokens

PrivacyIDEA is a token management system which supports a great variety of different token types. They each have
different requirements concerning configuration and how the authentication works. This chapter explains the authen-
tication modes, lists the supported hardware and software tokens and explains how the token types can be used with
privacyIDEA. Tools which facilitate and automate token enrollment are found in Enrollment Tools.

1.6.1 Authentication Modes and Client Modes

privacyIDEA supports a variety of tokens that implement different authentication flows. We call these flows authenti-
cation modes. Currently, tokens may implement three authentication modes, namely authenticate, challenge and
outofband.
Application plugins need to implement the three authentication modes separately, as the modes differ in their user
experience. To help the plugins identify the flow, the JSON response of an authentication request contains additional
information in the section

{
"detail": "multi_challenge": [
{
"client_mode": "poll",
}
]
}

The “client_mode” gives the plugin even more information how to respond. The authentication mode challenge can
either result in client_mode interactive, webauthn of u2f and the authentication mode outofband can currently
result in client mode poll.
Here are examples for the flows:
• The HOTP token type implements the authenticate mode, which is a single-shot authentication flow. For
each authentication request, the user uses their token to generate a new HOTP value and enters it along with their

1.6. Tokens 85
privacyIDEA Authentication System, Release 3.8

OTP PIN. The plugin sends both values to privacyIDEA, which decides whether the authentication is valid or
not.
• The E-Mail and SMS token types implement the challenge mode. With such a token, the authentication flow
consists of two steps: In a first step, the plugin triggers a challenge. privacyIDEA sends the challenge response
— a fresh OTP value — to the user via E-Mail or SMS. In a second step, the user responds to the challenge by
entering the respective OTP value in the plugin’s login form. The plugin sends the challenge response to priva-
cyIDEA, which decides whether the authentication is valid or not. The “client_mode” is set to interactive.
This indicates that the plugin should display an input field, so that the user can enter the response interactively.
• WebAuthn tokens and U2F tokens also implement the challenge mode. However, the plugin needs to han-
dle these challenges differently, since the user does not need to enter the response to the challenge manually.
The “client_mode” is either set to webauthn or u2f so that the plugin can handle the cryptographic challenge
accordingly.
• The PUSH and TiQR token types implement the outofband mode. With a PUSH token, the authentication step
also consists of two steps: In a first step, the user triggers a challenge. privacyIDEA pushes the challenge to the
user’s smartphone app. In a second step, the user approves the challenge on their phone, and the app responds
to the challenge by communicating with the privacyIDEA server on behalf of the user. The plugin periodically
queries privacyIDEA to check if the challenge has been answered correctly and the authentication is valid. In
this case the “client_mode” is set to poll, so that the plugin knows, that it needs to poll for the response to the
challenge.
The following describes the authentication flows of the three authentication modes in more detail.

authenticate mode

The Service is an application that is protected with a second factor by privacyIDEA.


• The user enters a OTP PIN along with an OTP value at the Service.
• The plugin sends a request to the /validate/check endpoint of privacyIDEA:

POST /validate/check

user=<user>&pass=<PIN+OTP>

and privacyIDEA returns whether the authentication request has succeeded or not.

challenge mode

• The plugin triggers a challenge, for example via the /validate/triggerchallenge endpoint:

POST /validate/triggerchallenge

user=<user>

Alternatively, a challenge can be triggered via the /validate/check endpoint with the PIN of a challenge-
response token:

POST /validate/check

user=<user>&pass=<PIN>

In both variants, the plugin receives a transaction ID which we call transaction_id and asks the user for the
challenge response.

86 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

• The user enters the challenge response, which we call OTP. The plugin forwards the response to privacyIDEA
along with the transaction ID:

POST /validate/check

user=<user>&transaction_id=<transaction_id>&pass=<OTP>

and privacyIDEA returns whether the authentication request succeeded or not.

outofband mode

• The plugin triggers a challenge, for example via the /validate/triggerchallenge endpoint:

POST /validate/triggerchallenge

user=<user>

or via the /validate/check endpoint with the PIN of a out-of-band token:

POST /validate/check

user=<user>&pass=<PIN>

In both variants, the plugin receives a transaction ID which we call transaction_id. The plugin may now
periodically query the status of the challenge by polling the /validate/polltransaction endpoint:

GET /validate/polltransaction

transaction_id=<transaction_id>

If this endpoint returns false, the challenge has not been answered yet.
• The user approves the challenge on a separate device, e.g. their smartphone app. The app communicates with a
tokentype-specific endpoint of privacyIDEA, which marks the challenge as answered. The exact communication
depends on the token type.
• Once /validate/polltransaction returns true, the plugin must finalize the authentication via the /
validate/check endpoint:

POST /validate/check

user=<user>&transaction_id=<transaction_id>&pass=

For the pass parameter, the plugin sends an empty string.


This step is crucial because the /validate/check endpoint takes defined authentication and authorization poli-
cies into account to decide whether the authentication was successful or not.

Note: The /validate/polltransaction endpoint does not require authentication and does not increase the
failcounters of tokens. Hence, attackers may try to brute-force transaction IDs of correctly answered challenges.
Due to the short expiration timeout and the length of the randomly-generated transaction IDs, it is unlikely that
attackers correctly guess a transaction ID in time. Nonetheless, plugins must not allow users to inject transaction
IDs, and plugins must not leak transaction IDs to users.

1.6. Tokens 87
privacyIDEA Authentication System, Release 3.8

1.6.2 Hardware and Software Tokens

privacyIDEA supports a wide variety of tokens by different hardware vendors. It also supports token apps on the
smartphone which handle software tokens.
Tokens not listed, will be probably supported, too, since most tokens use standard algorithms.
If in doubt drop your question on the mailing list.

Hardware Tokens

The following hardware tokens are known to work well.


Yubikey. The Yubikey is supported in all modes: AES (Yubikey), HOTP Token and Yubico Cloud. You can initialize
the Yubikey yourself, so that the secret key is not known to the vendor. The process is described in Yubikey Enrollment
Tools.
eToken Pass. The eToken Pass is a push button token by SafeNet. It can be initialized with a special hardware device.
Or you get a seed file, that you need to import to privacyIDEA. The eToken Pass can run as HOTP Token or TOTP
token.
eToken NG OTP. The eToken NG OTP is a push button token by SafeNet. As it has a USB connector, you can initialize
the token via the USB connector. Thus the hardware vendor does not know the secret key.
DaPlug. The DaPlug token is similar to the Yubikey and can be initialized via the USB connector. The secret key is
not known to the hardware vendor.
Smartdisplayer OTP Card. This is a push button card. It features an eInk display, that can be read very good in all
light condition at all angles. The Smartdisplayer OTP card is initialized at the factory and you get a seed file, that you
need to import to privacyIDEA.
Feitian. The C100 and C200 tokens are classical, reasonably priced push button tokens. The C100 is an HOTP Token
token and the C200 a TOTP token. These tokens are initialized at the factory and you get a seed file, that you need to
import to privacyIDEA.
U2F. The Yubikey and the Daplug token are known U2F devices to work well with privacyIDEA. See U2F.

Smartphone Apps

privacyIDEA Authenticator. Our own privacyIDEA Authenticator is based on the concept of the Google Authenti-
cator and works with the usual QR Code key URI enrollment. But on top it also allows for a more secure enrollment
process (See Two Step Enrollment). It can be used for HOTP Token, TOTP and Push Token.
Google Authenticator. The Google Authenticator is working well in HOTP Token and TOTP mode. If you choose
“Generate OTP Key on the Server” during enrollment, you can scan a QR Code with the Google Authenticator. See
Enrolling your first token to learn how to do this.
FreeOTP. privacyIDEA is known to work well with the FreeOTP App. The FreeOTP App is a TOTP token. So if you
scan the QR Code of an HOTP token, the OTP will not validate.
mOTP. Several mOTP Apps like “Potato”, “Token2” or “DroidOTP” are supported.

88 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

1.6.3 Token types in privacyIDEA

The following list is an overview of the supported token types. For more details, consult the respective description
listed in Tokens. Some token require prior configuration as described in Token type details.
• Four Eyes - Meta token that can be used to create a Two Man Rule.
• Certificate Token - A token that represents a client certificate.
• Email - A token that sends the OTP value to the EMail address of the user.
• HOTP Token - event based One Time Password tokens based on RFC4226.
• Indexed Secret Token - a challenge response token that asks the user for random positions from a secret string.
• Daplug - A hardware OTP token similar to the Yubikey.
• mOTP Token - time based One Time Password tokens for mobile phones based on an a public Algorithm.
• OCRA - A basic OATH Challenge Response token.
• Paper Token (PPR) - event based One Time Password tokens that get you list of one time passwords on a sheet
of paper.
• Push Token - A challenge response token, that sends a challenge to the user’s smartphone and the user simply
accepts the request to login.
• Password Token - A password token used for losttoken scenario.
• Questionnaire Token - A token that contains a list of answered questions. During authentication a random ques-
tion is presented as challenge from the list of answered questions is presented. The user must give the right
answer.
• Registration - A special token type used for enrollment scenarios (see Registration Code).
• RADIUS - A virtual token that forwards the authentication request to a RADIUS server.
• registration
• Remote - A virtual token that forwards the authentication request to another privacyIDEA server.
• SMS Token - A token that sends the OTP value to the mobile phone of the user.
• Spass - Simple Pass Token - The simple pass token. A token that has no OTP component and just consists of the
OTP pin or (if otppin=userstore is set) of the userstore password.
• SSH Keys - An SSH public key that can be managed and used in conjunction with the Machines concept.
• TAN Token -
• TiQR - A Smartphone token that can be used to login by only scanning a QR code.
• TOTP - time based One Time Password tokens based on RFC6238.
• U2F - A U2F device as specified by the FIDO Alliance. This is a USB device to be used for challenge response
authentication.
• VASCO - The proprietary VASCO token.
• WebAuthn - The WebAuthn or FIDO2 token which can use several different mechanisms like USB tokens or
TPMs to authenticate via public key cryptography.
• Yubikey - A Yubikey hardware initialized in the AES mode, that authenticates against privacyIDEA.
• Yubico - A Yubikey hardware that authenticates against the Yubico Cloud service.

1.6. Tokens 89
privacyIDEA Authentication System, Release 3.8

Token type details

Detailed information on the different token types used in privacyIDEA can be found in the following sections.

Four Eyes

Starting with version 2.6 privacyIDEA supports 4 Eyes Token. This is a meta token, that can be used to define, that
two or more token must be used to authenticate. This way, you can set up a “two man rule”.
You can define, from which realm how many unique tokens need to be present, when authenticating:

Fig. 40: Enroll a 4 eyes token

In this example authentication will only be possible if at least two tokens from realm2 and one token from realm sqlite
are present.
Authentication is done by concatenating the OTP PINs and the OTP values of all tokens. The concatenation is split by
the separator character.
It does not matter, in which order the tokens from the realms are entered.
Example
Authentication as:

username: "root@r2"
password: "pin123456 secret789434 key098123"

The three blocks separated by the blank are checked, if they match tokens in the realms realm2 and sqlite.
The response looks like this in case of success:

{
"detail": {
"message": "matching 1 tokens",
"serial": "PI4E000219E1",
(continues on next page)

90 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

(continued from previous page)


"type": "4eyes"
},
"id": 1,
"jsonrpc": "2.0",
"result": {
"status": true,
"value": true
},
"version": "privacyIDEA 2.6dev0",
"versionnumber": "2.6dev0"
}

In case of a failed authentication the response looks like this:

{
"detail": {
"foureyes": "Only found 0 tokens in realm themis",
"message": "wrong otp value",
"serial": "PI4E000219E1",
"type": "4eyes"
},
"id": 1,
"jsonrpc": "2.0",
"result": {
"status": true,
"value": false
},
"version": "privacyIDEA 2.6dev0",
"versionnumber": "2.6dev0"
}

Using Challenge Response mode

Starting with version 3.5 it is also possible to use the 4eyes token in multi challenge-response mode. This way in the
first authentication response the users will either enter the OTP PIN of the 4eyes token or (if the 4eyes token has no
PIN) enter the first token (OTP PIN + OTP value) of one of the users. After this a challenge is sent back, that further
tokens need to be entered. Every one of the required tokens is entered separately.

Note: The 4Eyes Token verifies that unique tokens from each realm are used. I.e. if you require 2 tokens from a realm,
you can not use the same token twice.

Warning: But it does not verify, if these two unique tokens belong to the same user. Thus you should create a
policy, that in such a realm a user may only have on token.

1.6. Tokens 91
privacyIDEA Authentication System, Release 3.8

Certificate Token

Starting with version 2.3 privacyIDEA supports certificates. A user can


• submit a certificate signing request (including an attestation certificate),
• upload a certificate or
• generate a certificate signing request within privacyIDEA.
privacyIDEA does not sign certificate signing requests itself but connects to existing certificate authorities. To do so,
you need to define CA Connectors.
Certificates are attached to the user just like normal tokens. One token of type certificate always contains only one
certificate.
If you have defined a CA connector you can upload a certificate signing request (CSR) via the Token Enroll Dialog in
the WebUI.

Fig. 41: Upload a certificate signing request

You need to choose the CA connector. The certificate will be signed by the CA accordingly. Just like all other tokens
the certificate token can be attached to a user.

Generating Signing Requests

You can also generate the signing request. The key pair and the request is generated on the server.
When generating the certificate signing request this way the RSA key pair is generated on the server and the private
key is available on the server side. The user can later download a PKCS12/PFX file from the server.
The certificate is signed by the CA connected by the chosen CA connector.
Afterwards the user can install the certificate into the browser.

Note: By requiring OTP authentication for the users to login to the WebUI (see login_mode) you can have two factor
authentication required for the user to be allowed to enroll a certificate.

92 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Fig. 42: Generate a certificate signing request

Fig. 43: Download or install the client certificate

1.6. Tokens 93
privacyIDEA Authentication System, Release 3.8

Pending certificate requests

When sending certificate requests the issuing of the certificate can be pending. This can happen with e.g. the Microsoft
CA, when a CA manage approval is required. In this case the certificate token in privacyIDEA is marked in the
rollout_state “pending”.
Using the Event Handler a user can be notified if a certificate request is pending. E.g. privacyIDEA can automatically
send an email to the user.

Example event handler

To configure this, create a new post event handler on the event token_init with the User Notification Handler Module.
In the conditions set the rollout_state=pending and in the actions choose to send an email to the tokenowner. This way,
after the token is enrolled and in the state pending, privacyIDEA will send the notification email.

Email

The token type email sends the OTP value in an email to the users. You can configure the email server in Email Token
Configuration.

Fig. 44: Enroll an email token

When enrolling an email token, you only need to specify the email address of the user.
The email token is a challenge response token. I.e. when using the OTP PIN in the first authentication request, the
sending of the email will be triggered and in a second authentication request the OTP value from the email needs to be
presented. It implements the challenge authentication mode.
For a more detailed insight see the code documentation Email Token.

HOTP Token

The HOTP token is - together with the TOTP - the most common token. The HOTP Algorithm is defined in RFC4225.
The HOTP token is an event base token. The HOTP algorithm offers two parameters: * The length of the generated
OTP value (6 or 8 digits) * The hashing algorithm to use (SHA1, SHA256 or SHA512).
The HOTP token implements the authenticate mode. With a suitable challenge_response policy, it may also be used
in the challenge mode.

94 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Hardware tokens

There are many token vendors out there who are using the official algorithm to build and sell hardware tokens. You
can get HOTP based hardware tokens in different form factors, as a normal key fob for your key ring or as a display
card for your purse.

Preseeded or Seedable

Usually the hardware tokens like keyfobs or display cards contain a secret key that was generated and implanted at the
vendors factory. The vendor ships the tokens and a seed file.

Warning: In this case privacyIDEA can not guarantee that the secret seed of the token is unique and if you are
using a real strong factor.

privacyIDEA also supports the following seedable HOTP tokens:


• SafeNet eToken NG OTP
• SafeNet eToken Pass
• Yubikey in OATH mode (See Yubikey Enrollment Tools on how to enroll Yubikeys in HOTP mode.)
• Daplug
Those tokens can be initialized by privacyIDEA. Thus you can be sure, that only you are in possession of the secret
seed.

Experiences

The above mentioned hardware tokens are known to play well with privacyIDEA. In theory all OATH/HOTP tokens
should work well with privacyIDEA. However, there are good experiences with Smartdisplayer OTP cards1 and Feitian
C2002 tokens.

Software tokens

Besides the hardware tokens there are also software tokens, implemented as Apps for your smartphone. These software
tokens allow are seedable, so there is no vendor, knowing the secret seed of your OTP tokens.
But software tokens are software after all on device prone to security issues.
1 https://netknights.it/en/produkte/smartdisplayer/
2 https://netknights.it/en/produkte/oath-hotptotp/

1.6. Tokens 95
privacyIDEA Authentication System, Release 3.8

Experiences

The Google Authenticator can be enrolled easily in HOTP mode using the QR-Code enrollment Feature.
The Google Authenticator is available for iOS, Android and Blackberry devices.

Enrollment

Default settings for HOTP tokens can be configured at HOTP Token Config.

Fig. 45: Enroll an HOTP token

During enrollment you can choose, if the server should generate the key or if you have a key, that you can enter into the
enrollment page.
As mentioned earlier, you can also choose the OTP length and the hash algoriothm.

Fig. 46: If the server generated the secret seed, you can scan the QR-Code

After enrolling the token, the QR-Code, containing the secret seed, is displayed, so that you can scan this with your
smartphone and import it to your app.

96 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Indexed Secret Token

The indexed secret token is a simple challenge response token.


A shared secret like “mySecret” is stored in the privacyIDEA server. When the token is used a challenge is sent to the
user like “Give me the 2nd and the 4th position of your secret”.
Then the user needs to respond with the concatenated characters from the given positions. In the example the response
would be “ye”.
Certain policies can be used to either preset or force the value of the indexed secret during enrollment to the value of
a user attribute. The attribute specified in these policies is a privacyidea attribute from the attribute mapping of the
corresponding user resolver.
Starting with version 3.4 the Indexed Secret Token can work in multi challenge authentication. This way each position
is asked separately in consecutive challenges. To achieve this, the token needs the tokeninfo value multichallenge=1.

mOTP Token

mOTP is a time based One Time Password token for mobile phones based on a public Algorithm.

OCRA

Starting with version 2.20 privacyIDEA supports common OCRA tokens. OCRA tokens can not be enrolled via the
UI but need to be imported via a seed file. The OATH CSV seed file would look like this:

<serial>, <seed>, ocra, <ocrasuite>

The OCRA token is a challenge/response token. So the first authentication request issues a challenge. This challenge
is the input for the response of the OCRA token.
For more information see OCRA Token.

DisplayTAN token

privacyIDEA supports the DisplayTAN1 , which can be used for securing banking transactions. The OCRA Algorithm
is used to digitally sign transaction data. The transaction data can be verified by the user on an external banking card.
All cryptographical processes are running on the external card, so that an attacker can not interfere with the user’s
component.
The DisplayTAN cards would be imported into privacyIDEA using the token import.
A banking website will use the Validate endpoints API.
The first call will trigger the challenge response mechanism. The first call needs to contain the transaction data: the
recipient’s account number and amount of money to transfer:

<account>~<amount>~

Please note the tilde:

1 http://www.display-tan.com/

1.6. Tokens 97
privacyIDEA Authentication System, Release 3.8

POST https://privacyidea.example.com/validate/check

pass=pin
serial=ocra1234
challenge=1234567890~423,40~
addrandomchallenge=20
hashchallenge=sha1

This will result in a response like this:

{
"jsonrpc": "2.0",
"signature": "128057011582042...408",
"detail": {
"multi_challenge": [
{
"attributes": {
"qrcode": "data:image/png;base64, iVBORw0KG..RK5CYII=",
"original_challenge": "83507112 ~320,
00~cfbGSopfdDROOMjeu3IR",
"challenge": "f8a1818f35ae0cc64fe8a191961ec829487dfa82"
},
"serial": "ocra1234",
"transaction_id": "05221757445370623976"
}
],
"threadid": 139847557760768,
"attributes": {
"qrcode": "data:image/png;base64, iVBO...CYII=",
"original_challenge": "83507112 ~320,00~cfbGSopfdDROOMjeu3IR",
"challenge": "f8a1818f35ae0cc64fe8a191961ec829487dfa82"
},
"message": "Please answer the challenge",
"serial": "ocra1234",
"transaction_id": "05221757445370623976"
},
"versionnumber": "2.20.dev2",
"version": "privacyIDEA 2.20.dev2",
"result": {
"status": true,
"value": false
},
"time": 1504005837.417481,
"id": 1
}

Note: The response also contains the QR code. The banking website should show the QR code, so that the user can
scan it with the DisplayTAN App to transfer the data to the card.

The user can verify the data on the card and transaction data will be digitally signed on the card. The card will calculate
an OTP value for this very transaction.
The banking website can now send the OTP value to privacyIDEA to check, if the user authorized the correct transaction

98 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

data. The banking site will issue this request:

POST https://privacyidea.example.com/validate/check

serial=ocra1234
transaction_id=05221757445370623976
pass=54006635

privacyIDEA will respond with a usual authentication response:

{
"jsonrpc": "2.0",
"signature": "162....2454851",
"detail": {
"message": "Found matching challenge",
"serial": "ocra1234",
"threadid": 139847549368064
},
"versionnumber": "2.20.dev2",
"version": "privacyIDEA 2.20.dev2",
"result": {
"status": true,
"value": true
},
"time": 1504005901.823667,
"id": 1
}

Paper Token (PPR)

The token type paper lets you print out a list of OTP values, which you can use to authenticate and cross of the list.
The paper token is based on the HOTP Token. I.e. you need to use one value after the other.

Customization

CSS

You can customize the look and feel of the printed paper token. You may change the style sheet papertoken.css
which is only loaded for printing.

Header and Footer

Then you may add a header in front and a footer behind the table containing the OTP values.
Create the files
• static/customize/views/includes/token.enrolled.paper.top.html
• static/customize/views/includes/token.enrolled.paper.bottom.html
to display the contents before (top) and behind (bottom) the table.
Within these html templates you may use angular replacements. To get the serial number of the token use:

1.6. Tokens 99
privacyIDEA Authentication System, Release 3.8

{{ tokenEnrolled.serial }}

to get the name and realm of the user use:

{{ newUser.user }}
{{ newUser.realm }}

A good example for the token.enrolled.paper.top.html is:

<h1>{{ enrolledToken.serial }}</h1>


<p>
Please use the OTP values of your paper token in order one after the
other. You may scratch of or otherwise mark used values.
</p>

A good example for the token.enrolled.paper.bottom.html is:

<p>
The paper token is a weak second factor. Please assure, that no one gets
hold of this paper and can make a copy of it.
</p>
<p>
Store it at a safe location.
</p>

Note: You can change the directory static/customize to a URL that fits your needs the best by defining a variable
PI_CUSTOMIZATION in the file pi.cfg. This way you can put all modifications in one place apart from the original
code.

OTP Table

If you want to change the complete layout of the table you need to overwrite the file static/components/token/
views/token.enrolled.paper.html. The scope variable:

{{ enrolledToken.otps }}

contains an object with the complete OTP value list.

Push Token

The push token uses the privacyIDEA Authenticator app. You can get it from Google Play Store or Apple App Store.
The token type push sends a cryptographic challenge via the Google Firebase service to the smartphone of the user.
This push notification is displayed on the smartphone of the user with a text that tells the user that he or somebody
else requests to login to a service. The user can simply accept this request. The smartphone sends a cryptographically
signed response to the privacyIDEA server and the login request gets marked as confirmed in the privacyIDEA server.
The application checks for this mark and logs the user in automatically. For an example of how the components in a
typical deployment of push tokens interact reference the following diagram.

Fig. 47: A typical push token deployment

100 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

To allow privacyIDEA to send push notifications, a Firebase service needs to be configured. To do so see Firebase
Provider.
The PUSH token implements the outofband mode.

Configuration

The minimum necessary configuration is an enrollment policy push_firebase_configuration.


With the authentication policies push_text_on_mobile and push_title_on_mobile you can define the contents of the
push notification.
If you want to use push tokens with legacy applications that are not yet set up to be compatible with out-of-band
tokens, you can set the authentication policy push_wait. Please note, that setting this policy can interfere with
other tokentypes and will impact performance, as detailed in the documentation for push_wait.

Enrollment

The enrollment of the push token happens in two steps.

Step 1

The user scans a QR code. This QR code contains the basic information for the push token and a enrollment URL, to
which the smartphone should respond in the enrollment process.
The smartphone stores this data and creates a new key pair.

Step 2

The smartphone sends its Firebase ID, the public key of the keypair, the serial number and an enrollment credential
back to the enrollment URL of the privacyIDEA server.
The server responds with it’s public key for this token.

Authentication

Triggering the challenge

The authentication request is triggered by an application just the same like for any challenge response tokens either
with the PIN to the endpoint /validate/check or via the endpoint /validate/triggerchallenge.
privacyIDEA sends a cryptographic challenge with a signature to the Firebase service. The firebase service sends the
notification to the smartphone, which can verify the signature using the public key from enrollment step 2.

1.6. Tokens 101


privacyIDEA Authentication System, Release 3.8

Accepting login

The user can now accept the login by tapping on the push notification. The smartphone sends the signed challenge
back to the authentication URL of the privacyIDEA server. The privacyIDEA server verifies the response and marks
this authentication request as successfully answered.
In some cases the push notification does not reach the smartphone. Since version 3.4 the smartphone can also poll for
active challenges.

Login to application

The application can check with the original transaction ID with the privacyIDEA server, if the challenge has been
successfully answered and automatically login the user.

More information

For a more detailed insight see the code documentation for the Push Token.
For an in depth view of the protocol see the github issue and the wiki page.
Information on the polling mechanism can be found in the corresponding wiki page.
For recent information and a setup guide, visit the community blog

Password Token

This token is not enrolled by the user. It is automatically created whenever an authorized user initiates a losttoken
scenario.

Questionnaire Token

The administrator can define a list of questions and also how many answers to the questions a user needs to define.
During enrollment of such a questionnaire type token, the user answers at least as many questions as specified by the
administrator with answers only he knows.
This token is a challenge response token. During authentication the user gives the token PIN before he is presented
with a random question to which he defined the answer during the token rollout.

Note: By default, no questions are defined, so the administrator has to setup those in “Config->Tokens->Questionnaire”
before a questionnaire token can be rolled out successfully.

Note: If the administrator changes the questions after a token was enrolled, the enrolled token still works with the old
questions and answers. I.e. an enrolled token is not affected by changing the questions by the administrator.

Note: As for all token, it is not changed after the rollout (see above note), so a change of the answers of an existing
token is not possible.

102 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

RADIUS

The token type RADIUS forwards the authentication request to a RADIUS Server.
When forwarding the authentication request, you can change the username and mangle the password.

Fig. 48: Enroll a RADIUS token

Check the PIN locally


If checked, the PIN of the token will be checked on the local server. If the PIN matches only the remaining part of the
issued password will be sent to the RADIUS server.
RADIUS Server configuration
The configuration of the RADIUS server to which the authentication request will be forwarded. The configuration can

1.6. Tokens 103


privacyIDEA Authentication System, Release 3.8

be defined in RADIUS server configuration


RADIUS User
When forwarding the request to the RADIUS server, the authentication request will be issued for this user. If the user
is left empty, the RADIUS request will be sent with the same user currently trying to authenticate.
RADIUS Secret
The RADIUS secret for this RADIUS client.

Note: Using the RADIUS token you can design migration scenarios. When migrating from other (proprietary) OTP
solutions, you can enroll a RADIUS token for the users. The RADIUS token points to the RADIUS server of the old
solution. Thus the user can authenticate against privacyIDEA with the old, proprietary token, till he is enrolled a new
token in privacyIDEA. The interesting thing is, that you also get the authentication request with the proprietary token in
the audit log of privacyIDEA. This way you can have a scenario, where users are still using old tokens and other users
are already using new (privacyIDEA) tokens. You will see all authentication requests in the privacyIDEA system.

Registration

(See FAQ Registration Code)


The registration token can be used to create a registration code for a user. This registration code can be sent via postal
mail to the user, so that the user can use this registration code as a second factor to login to a portal.
After a one single use, the registration code is deleted and can not be used a second time.
The length and the contents of the registration code can be configured using the Enrollment policies registra-
tioncode_length and registrationcode_contents.

Note: The registration code can only be enrolled via the API to provide automated smooth workflow to your needs.

For a more detailed insight see the code documentation Registration Code Token.

Remote

The token type remote forwards the authentication request to another privacyIDEA Server.
When forwarding the authentication request, you can
• change the username
• change the resolver
• change the realm
• change the serial number
and mangle the password.
The serial number of the token, that was used on the other privacyIDEA server, is stored in the tokeninfo of the remote
token object in the key last_matching_remote_serial. This serial number can then be used in further workflows
and e.g. be processed in event handlers.
Check the PIN locally

104 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Fig. 49: Enroll a Remote token

If checked, the PIN of the token will be checked on the local server. If the PIN matches only the remaining part of the
issued password will be sent to the remote privacyIDEA server.
Remote Server ID
The other privacyIDEA server, to which the authentication request will be forwarded. You need to configure the
privacyIDEA Server at privacyIDEA server configuration.

Note: You can define a remote server to be localhost. Thus you can assign one token to several users.

Using the direct URL in the remote token is deprecated.


Remote Serial
If the Remote Serial is specified the given password will be checked against the serial number on the remote priva-
cyIDEA server. Usernames will be ignored.
Remote User
When forwarding the request to the remote server, the authentication request will be issued for this user.
Remote Realm
When forwarding the request to the remote server, the authentication request will be issued for this realm.
Remote Resolver
When forwarding the request to the remote server, the authentication request will be issued for this resolver.

Note: You can use Remote Serial to forward the request to a central privacyIDEA server, that only knows tokens but
has no knowledge of users. Or you can use Remote Serial to forward the request to an existing to on localhost thus
adding a second user to the same token.

1.6. Tokens 105


privacyIDEA Authentication System, Release 3.8

SMS Token

The token type sms sends the OTP value via an SMS service. You can configure the SMS service in SMS Token
Configuration.

Fig. 50: Enroll an SMS token

When enrolling an SMS token, you only need to specify the mobile phone number.
SMS token is a challenge response token. I.e. when sending the OTP PIN in the first authentication request, the sending
of the SMS will be triggered and in a second authentication request the OTP value from the SMS needs to be presented.
It implements the challenge authentication mode.
For a more detailed insight see the code documentation SMS Token.

Spass - Simple Pass Token

The OTP component of the spass token is always true. Thus the user only needs to provide the OTP pin or the userstore
password - depending on the policy settings.
For a more detailed insight see the code documentation SPass Token.

SSH Keys

The token type sshkey is the public SSH key, that you can upload and assign to a user. The SSH key is only used for
the application type SSH in conjunction with the Machines concept.
A user or the administrator can upload the public SSH key and assign to a user.
Paste the SSH key into the text area. The comment in the SSH key will be used as token comment. You can assign the
SSH key to a user and then use the SSH key in Application Definitions SSH.

Note: This way you can manage SSH keys centrally, as you do not need to distribute the SSH keys to all machines.
You rather store the SSH keys centrally in privacyIDEA and use privacyidea-authorizedkeys to fetch the keys in real
time during the login process.

106 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Fig. 51: Enroll an SSH key token

1.6. Tokens 107


privacyIDEA Authentication System, Release 3.8

TAN Token

(added in version 2.23)


The token type tan is related to the Paper Token (PPR).
In contrast to the paper token, a user can use the OTP values of a tan token in any arbitrary order.
A tan token can either be initialized with random OTP values. In this case the HOTP mechanism is used. Or it can be
initialized or imported with a dedicated list of TANs.
After enrollment, you are prompted to print the generated TAN list.

Import of TAN token

The import schema for TAN tokens via the OATH CSV file look like this:
<serial>, <seed>, tan, <white space separated list of tans>
The TANs are located in the 4th column. TANs are separated by blanks or whitespaces. The <seed> is not used with
a TAN token. You can leave this blank or set to any (not used) value.

108 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

TiQR

Starting with version 2.6 privacyIDEA supports the TiQR token. The TiQR token is a smartphone token, that can be
used to login by only scanning a QR code.
The TiQR token implements the outofband authentication mode. The configuration is described in TiQR Token Con-
figuration.
The token is also enrolled by scanning a QR code.

Fig. 52: Choose a user for the TiQR token

You can only enroll a TiQR token, when a user is selected.

Note: You can not enroll a TiQR token without assign the token to a user.

1.6. Tokens 109


privacyIDEA Authentication System, Release 3.8

For more technical information about the TiQR token please see TiQR Token.

TOTP

The TOTP token is - together with the HOTP Token - the most common token. The TOTP Algorithm is defined in
RFC6238. The TOTP token is a time based token. Roughly speaking the TOTP algorithm is the same algorithm like
the HOTP, where the event based counter is replaced by the unix timestamp.
The TOTP algorithm has some parameter, like if the generated OTP value will be 6 digits or 8 digits or if the SHA1 or
the SHA256 hashing algorithm is used and the timestep being 30 or 60 seconds.
The TOTP token implements the authenticate mode. With a suitable challenge_response policy, it may also be used in
the challenge mode.

Hardware tokens

The information about preseeded token and seedable tokens is the same as described in the section about HOTP Token.
The only available seedable pushbutton TOTP token is the SafeNet eToken Pass. The Yubikey can be used as a TOTP
token, but only in conjunction with a smartphone app, since the Yubikey does not have an internal clock.

Software tokens

Experiences

The Google Authenticator and the FreeOTP token can be enrolled easily in TOTP mode using the QR-Code enrollment
Feature.
The Google Authenticator is available for iOS, Android and Blackberry devices.

Enrollment

Default settings for TOTP tokens can be configured at TOTP Token Config.
The enrollment is the same as described in HOTP Token. However, when enrolling TOTP token, you can specify some
additional parameters.

U2F

Starting with version 2.7 privacyIDEA supports U2F tokens. The administrator or the user himself can register a U2F
device and use this U2F token to login to the privacyIDEA web UI or to authenticate at applications.
When enrolling the token a key pair is generated and the public key is sent to privacyIDEA. During this process the user
needs to prove that he is present by either pressing the button (Yubikey) or by replugging the device (Plug-up token).
The device is identified and assigned to the user.

Note: This is a normal token object which can also be reassigned to another user.

110 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Fig. 53: Enroll an TOTP token

Note: As the key pair is only generated virtually, you can register one physical device for several users.

For configuring privacyIDEA for the use of U2F token, please see U2F.
For further details and for information how to add this to your application you can see the code documentation at U2F
Token.

VASCO

Starting with version 2.22 privacyIDEA supports VASCO tokens.


VASCO OTP tokens are a proprietary OTP token. You can import the VASCO blobs from a CSV file or you the
administrator can enroll a single VASCO token.

Note: privacyIDEA uses a proprietary VASCO library vacman to verify the OTP values. Please note that you need to

1.6. Tokens 111


privacyIDEA Authentication System, Release 3.8

license this library from VASCO Data Security N.V. directly. The privacyIDEA project does not provide this library.

WebAuthn

Starting with version 3.4 privacyIDEA supports WebAuthn tokens. The administrator or the user himself can regis-
ter a WebAuthn device and use this WebAuthn token to login to the privacyIDEA WebUI or to authenticate against
applications.
When enrolling the token, a key pair is generated and the public key is sent to privacyIDEA. During this process, the
user needs to prove that he is present, which typically happens by tapping a button on the token. The user may also be
required by policy to provide some form of verification, which might be biometric or knowledge-based, depending on
the token.
The devices is identified and assigned to the user.

Note: This is a normal token object which can also be reassigned to another user.

Note: As the key pair is only generated virtually, you can register one physical device for several users.

For configuring privacyIDEA for the use of WebAuthn tokens, please see WebAuthn Token Config.
For further details and information how to add this to your application, see the code documentation at WebAuthn Token.

Yubico

The token type Yubico authenticates against the Yubico Cloud mode. You need to configure this at Yubico Cloud mode.

Fig. 54: Enroll a Yubico token

The token is enrolled by simply saving the Yubikey token ID in the token object. You can either enter the 12 digit ID
or you can simply press the Yubikey button in the input field, which will also assign the token.

112 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Yubikey

As Yubikey token type, privacyIDEA refers to Yubico’s own AES mode. A Yubikey, configured in this mode outputs a
44 character OTP value, consisting of a 12 character prefix and a 32 character OTP. But in contrast to the Yubico Cloud
mode, in this mode the secret key is contained within the token and your own privacyIDEA installation. If you have
the time and care about privacy, you should prefer the Yubikey AES mode over the Yubico Cloud mode.
There are several possible ways to enroll a Yubikey token in privacyIDEA. We describe the methods in Yubikey En-
rollment Tools.

Redirect API URLs to /ttype/yubikey

To have a service query not the Yubico Cloud URL, but the privacyIDEA endpoint /ttype/yubikey, you sometimes
need to redirect the default API URL via the local webserver. Yubico servers use /wsapi/2.0/verify as the path in
the validation URL. Some tools (e.g. Kolab 2FA) let the user/admin change the API host, but not the rest of the URL.
To redirect the API URL to privacyIDEA’s endpoint /ttype/yubikey, you’ll need to enable the following two lines
in /etc/apache2/site-enabled/privacyidea.conf:

RewriteEngine on
RewriteRule "^/wsapi/2.0/verify" "/ttype/yubikey" [PT]

If you use nginx there is a similar line provided as a comment to the nginx configuration as well.

1.7 Policies

Policies can be used to define the reaction and behaviour of the system.
Each policy defines the behaviour in a certain area, called scope. privacyIDEA knows the scopes:

1.7.1 Admin policies

Admin policies are used to regulate the actions that administrators are allowed to do. Technically admin policies control
the use of the REST API Token endpoints, System endpoints, Realm endpoints and Resolver endpoints.
Admin policies are implemented as decorators in Policy Module and Policy Decorators.
Starting with privacyIDEA 2.4 admin policies can also store a field “admin realm”. This is used, if you define realms to
be superuser realms. See The Config File for information how to do this. Read So what’s the thing with all the admins?
for more information on the admin realms.
This way it is easy to define administrative rights for big groups of administrative users like help desk users in the IT
department.
All administrative actions also refer to the defined user realm. Meaning an administrator may have many rights in one
user realm and only a few rights in another realm.
Creating a policy with scope:admin, admin-realm:helpdesk, user:frank, action:enable and realm:sales
means that the administrator frank in the admin-realm helpdesk is allowed to enable tokens in the user-realm sales.

Note: As long as no admin policy is defined all administrators are allowed to do everything.

1.7. Policies 113


privacyIDEA Authentication System, Release 3.8

Fig. 55: The Admin scope provides an additional field ‘admin realm’.

114 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Note: Admin policies are also checked for all local administrators.

The following actions are available in the scope admin:

tokenlist

type: bool
This allows the administrator to list existing tokens in the specified user realm. Note, that the resolver in this policy is
ignored.
If the policy with the action tokenlist is not bound to any user realm, this acts as a wild card and the admin is allowed
to list all tokens.
If the action tokenlist is not active, but admin policies exist, then the admin is not allowed to list any tokens.

Note: As with all boolean policies, multiple tokenlist policies add up to create the resulting rights of the administrator.
So if there are multiple matching policies for different realms, the admin will have list rights on all mentioned realms
independent on the priority of the policies.

enroll

type: bool
There are enrollment actions per token type, e.g. enrollHOTP. Only those token types are selectable in the WebUI
during enrollment which are allowed by their corresponding enroll policy action.

enable

type: bool
The enable action allows the administrator to activate disabled tokens.

disable

type: bool
Tokens can be enabled and disabled. Disabled tokens can not be used to authenticate. The disable action allows the
administrator to disable tokens.

revoke

type: bool
Tokens can be revoked. Usually this means the token is disabled and locked. A locked token can not be modified
anymore. It can only be deleted.
Certain token types like certificate may define special actions when revoking a token.

1.7. Policies 115


privacyIDEA Authentication System, Release 3.8

set

type: bool
Tokens can have additional token information, which can be viewed in the token_details.
If the set action is defined, the is administrator allowed to set those token properties like description,
max_failcount or validity_period_start at the /token/set endpoints (see Token endpoints).

setpin

type: bool
If the setpin action is defined, the administrator is allowed to set the OTP PIN of a token.

setrandompin

type: bool
If the setrandompin action is defined, the administrator is allowed to call the endpoint, that sets a random token PIN.

settokeninfo

type: bool
The administrator is allowed to manually set and delete token info.

enrollpin

type: bool
If the action enrollpin is defined, the administrator can set a token PIN during enrollment. If the action is not defined
and the administrator tries to set a PIN during enrollment, this PIN is deleted from the request.

hide_tokeninfo

type: string
This specifies a blank-separated list of tokeninfo keys, which should be removed from the response and therefore will
not be shown in the WebUI or JSON response.
For example a value tokenkind auto_renew will hide these two tokeninfo entries.

otp_pin_maxlength

type: integer
range: 0 - 31
This is the maximum allowed PIN length the admin is allowed to use when setting the OTP PIN.

Note: There can be token type specific policies like spass_otp_pin_maxlength, spass_otp_pin_minlength and
spass_otp_pin_contents. If suche a token specific policy exists, it takes priority of the common PIN policy.

116 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

otp_pin_minlength

type: integer
range: 0 - 31
This is the minimum required PIN the admin must use when setting the OTP PIN.

otp_pin_contents

type: string
contents: cns
This defines what characters an OTP PIN should contain when the admin sets it.
c are letters matching [a-zA-Z].
n are digits matching [0-9].
s are special characters matching [[].:,;-_<>+*!/()=?$§%&#~^].
[allowedchars] is a specific list of allowed characters.
Example: The policy action otp_pin_contents=cn, otp_pin_minlength=8 would require the admin to choose
OTP PINs that consist of letters and digits which have a minimum length of 8.
cn
test1234 and test12$$ would be valid OTP PINs. testABCD would not be a valid OTP PIN.
The logic of the otp_pin_contents can be enhanced and reversed using the characters + and -.
-cn (denial)
The PIN must not contain a character and must not contain a number. test1234 would not be a valid PIN,
since it does contains numbers and characters. test/// would not be a valid PIN, since it contains characters.
-s (denial)
The PIN must not contain a special character. test1234 would be a valid PIN. test12$$ would not.
+cn (grouping)
combines the two required groups. I.e. the OTP PIN should contain characters from the sum of the two
groups. test1234, test12$$, test and 1234 would all be valid OTP PINs. Note, how this is different to -s,
since it allows special characters to be included.
[123456]
allows the digtits 1-6 to be used. 1122 would be a valid PIN. 1177 would not be a valid PIN.

otp_pin_set_random

type: integer
range: 1-31
The administrator can set a random pin for a token with the endpoint token/setrandompin. This policy is needed to
define how long the PIN will be.

Note: The PIN will consist of digits and letters.

1.7. Policies 117


privacyIDEA Authentication System, Release 3.8

reset

type: bool
The administrator is allowed to reset the fail counter of a token.

resync

type: bool
If the resync action is defined, the administrator is allowed to resynchronize a token.

assign

type: bool
If the assign action is defined, the administrator is allowed to assign a token to a user. This is used for assigning an
existing token to a user but also to enroll a new token to a user.
Without this action, the administrator can not create a connection (assignment) between a user and a token.

unassign

type: bool
If the unassign action is defined, the administrator is allowed to unassign tokens from a user. I.e. the administrator
can remove the link between the token and the user. The token still continues to exist in the system.

importtokens

type: bool
If the importtokens action is defined, the administrator is allowed to import token seeds from a token file, thus
creating many new token objects in the systems database.
The right to upload tokens can be limited to certain realms. Thus the administrator could only upload tokens into realm
he is allowed to manage.

delete

type: bool
If the delete action is defined, the administrator is allowed to delete a token from the system.

Note: If a token is deleted, it can not be recovered.

Note: All audit entries of this token still exist in the audit log.

118 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

spass_otp_pin_contents

type: str

spass_otp_pin_minlength and spass_otp_pin_maxlength

type: int
These policy actions define the required minimal and allowed maximal pin length for Spass - Simple Pass Token.

userlist

type: bool
If the userlist action is defined, the administrator is allowed to view the user list in a realm. An administrator might
not be allowed to list the users, if he should only work with tokens, but not see all users at once.

Note: If an administrator has any right in a realm, the administrator is also allowed to view the token list.

getchallenges

type: bool
If the getchallenges action is defined, the administrator is allowed to check the status of open challenge requests.

tokenrealms

type: bool
If the tokenrealms action is defined, the administrator is allowed to manage the realms of a token.
A token may be located in multiple realms. This can be interesting if you have a pool of spare tokens and several realms
but want to make the spare tokens available to several realm administrators. (Administrators, who have only rights in
one realm)
Then all administrators can see these tokens and assign the tokens. But as soon as the token is assigned to a user in one
realm, the administrator of another realm can not manage the token anymore.

tokengroups

type: bool
If the ``tokengroups``action is defined, the administrator is allowed to manage the tokengroups of a token.
Tokens can be grouped into tokengroups, so that such tokens can be more easily addressed in certain situations.
Administrators can also be allowed to define tokengroups and delete tokengroup definitions.

1.7. Policies 119


privacyIDEA Authentication System, Release 3.8

tokengroup_list

type: bool
This allows the administrator to list all defined tokengroups.

tokengroup_add

type: bool
If the policy tokengroup_add is defined, the administrator is allowed to define new tokengroups.

tokengroup_delete

type: bool
If the policy tokengroup_delete is defined, the administrator is allowed to delete existing tokengroup definitions.

getserial

type: bool
If the getserial action is defined, the administrator is allowed to calculate the token serial number for a given OTP
value.

getrandom

type: bool
The getrandom action allows the administrator to retrieve random keys from the endpoint getrandom. This is an
endpoint in System endpoints.
getrandom can be used by the client, if the client has no reliable random number generator. Creating API keys for the
Yubico Validation Protocol uses this endpoint.

getchallenges

type: bool
This policy allows the administrator to retrieve a list of active challenges of a challenge response tokens. The admin-
istrator can view these challenges in the web UI.

losttoken

type: bool
If the losttoken action is defined, the administrator is allowed to perform the lost token process.
To only perform the lost token process the actions copytokenuser and copytokenpin are not necessary!

120 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

adduser

type: bool
If the adduser action is defined, the administrator is allowed to add users to a user store.

Note: The user store still must be defined as editable, otherwise no users can be added, edited or deleted.

updateuser

type: bool
If the updateuser action is defined, the administrator is allowed to edit users in the user store.

deleteuser

type: bool
If the deleteuser action is defined, the administrator is allowed to delete an existing user from the user store.

copytokenuser

type: bool
If the copytokenuser action is defined, the administrator is allowed to copy the user assignment of one token to
another.
This functionality is also used during the lost token process. But you only need to define this action, if the administrator
should be able to perform this task manually.

copytokenpin

type: bool
If the copytokenpin action is defined, the administrator is allowed to copy the OTP PIN from one token to another
without knowing the PIN.
This functionality is also used during the lost token process. But you only need to define this action, if the administrator
should be able to perform this task manually.

smtpserver_write

type: bool
To be able to define new SMTP server configuration or delete existing ones, the administrator needs this rights
smtpserver_write.

1.7. Policies 121


privacyIDEA Authentication System, Release 3.8

smtpserver_read

type: bool
Allow the administrator to read the SMTP server configuration.

smsgateway_write

type: bool
To be able to define new SMS Gateway configuration or delete existing ones, the administrator needs the right
smsgateway_write.

smsgateway_read

type: bool
Allow the administrator to read the SMS Gateway configuration.

periodictask_write

type: bool
Allow the administrator to write or delete Periodic Tasks definitions.

periodictask_read

type: bool
Allow the administrator to read the Periodic Tasks definitions.

eventhandling_write

type: bool
Allow the administrator to configure Event Handler.

eventhandling_read

type: bool
Allow the administrator to read Event Handler.

Note: Currently the policies do not take into account resolvers, or realms. Having the right to read event handlers,
will allow the administrator to see all event handler definitions.

122 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

radiusserver_write

type: bool
Allow the administrator to write or delete RADIUS server configuration definitions.

radiusserver_read

type: bool
Allow the administrator to read the RADIUS server configuration definitions.

privacyideaserver_write

type: bool
Allow the administrator to write or delete privacyIDEA server configuration definitions.

privacyideaserver_read

type: bool
Allow the administrator to read the privacyIDEA server configuration definitions.

policywrite, policyread, policydelete

type: bool
Allow the administrator to write, read or delete policies.

Note: Currently the policies do not take into account resolvers, or realms. Having the right to read policies, will allow
the administrator to see all policies.

resolverwrite, resolverread, resolverdelete

type: bool
Allow the administrator to write, read or delete user resolvers and realms.

Note: Currently the policies do not take into account resolvers, or realms. Having the right to read resolvers, will
allow the administrator to see all resolvers and realms.

1.7. Policies 123


privacyIDEA Authentication System, Release 3.8

mresolverwrite, mresolverread, mresolverdelete

type: bool
Allow the administrator to write, read or delete machine resolvers.

configwrite, configread, configdelete

type: bool
Allow the administrator to write, read or delete system configuration.

caconnectorwrite, caconnectorread, caconnectordelete

type: bool
Allow the administrator to write, read or delete CA connectors.

statistics_read

type: bool
This action allows the reading of the statistics at the Monitoring endpoints.

statistics_delete

type: bool
This action allows to delete statistics at the Monitoring endpoints.

auditlog

type: bool
The administrators are allowed to view the audit log. If the policy contains a user realm, than the administrator is only
allowed to see entries which contain this very user realm. A list of user realms may be defined.
To learn more about the audit log, see Audit.

auditlog_download

type: bool
The administrator is allowed to download the audit log.

Note: The download is not restricted to filters, hidden columns and audit age. Thus, if you want to avoid, that an
administrator can see older logs or columns, hidden by hide_audit_columns, you need to disallow downloading the
data. Otherwise he may download the audit log and look at older entries manually.

124 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

auditlog_age

type: string
This limits the maximum age of displayed audit entries. Older entries are not remove from the audit table but the
administrator is simply not allowed to view older entries.
Can be something like 10m (10 minutes), 10h (10 hours) or 10d (ten days).

hide_audit_columns

type: string
This species a blank separated list of audit columns, that should be removed from the response and also from the WebUI.
For example a value sig_check log_level will hide these two columns.
The list of available columns can be checked by examining the response of the request to the Audit endpoint.

triggerchallenge

type: bool
If set the administrator is allowed to call the API /validate/triggerchallenge. This API can be used to send an
OTP SMS to user without having specified the PIN of the SMS token.
The usual setup that one administrative account has only this single policy and is only used for triggering challenges.
New in version 2.17.

hotp_2step and totp_2step

type: string
This allows or forces the administrator to enroll a smartphone based token in two steps. In the second step the smart-
phone generates a part of the OTP secret, which the administrator needs to enter. (see Two Step Enrollment). Pos-
sible values are allow and force. This works in conjunction with the enrollment parameters {type}_2step_clientsize,
{type}_2step_serversize, {type}_2step_difficulty.
Such a policy can also be set for the user. See hotp_2step and totp_2step.

Note: This does not work in combination with the enrollment policy verify_enrollment, since the usage of 2step
already ensures, that the user has successfully scanned the QR code.

hotp_hashlib and totp_hashlib

type: string
Force the admin to enroll HOTP/TOTP Tokens with the specified hashlib. The corresponding input selector will be
disabled in the web UI. Possible values are sha1, sha256 and sha512, default is sha1.
New in 3.2

1.7. Policies 125


privacyIDEA Authentication System, Release 3.8

hotp_otplen and totp_otplen

type: int
Force the admin to enroll HOTP/TOTP Tokens with the specified otp length. The corresponding input selector will be
disabled in the web UI. Possible values are 6 or 8, default is 6.
New in 3.2

totp_timestep

type: int
Enforce the timestep of the time-based OTP token. A corresponding input selection will be disabled/hidden in the web
UI. Possible values are 30 or 60, default is 30.
New in 3.2

system_documentation

type: bool
The administrator is allowed to export a complete system documentation including resolvers and realm. The documen-
tation is created as restructured text.

sms_gateways

type: string
Usually an SMS token sends the SMS via the SMS gateway that is system wide defined in the token settings. This
policy takes a blank-separated list of configured SMS gateways. It allows the administrator to define an individual
SMS gateway during token enrollment.
New in version 3.0.

indexedsecret_force_attribute

type: string
If an administrator enrolls an indexedsecret token then the value of the given user attribute is set as the secret. The
admin does not know the secret and can not change the secret.
For more details of this token type see Indexed Secret Token.
New in version 3.3.

126 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

certificate_trusted_Attestation_CA_path

type: string
An administrator can enroll a certificate token for a user. If an attestation certificate is provided in addition, this policy
holds the path to a directory, that contains trusted CA paths. Each PEM encoded file in this directory needs to contain
the root CA certificate at the first position and the consecutive intermediate certificates.
An additional enrollment policy certificate_require_attestation, if an attestation certificate is required.
New in version 3.5.

set_custom_user_attributes

type: string
New in version 3.6
This policy defines which additional attributes an administrator is allowed to set. It can also define, to which value the
admin is allowed to set such attribute. For allowing all values, the asterisk (“*”) is used.

Note: Commas are not allowed in policy actions value, so the setting has to be defined by separating colons (“:”) and
spaces.

Each key is enclosed in colons and followed by a list of values separated by whitespaces, thus values are not allowed
to contain whitespaces.
Example:
:department: sales finance :city: * :*: 1 2
:department: sales finance means that the administrator can set an additional attribute “department” with the
allowed values of “sales” or “finance”.
:city: * means that the administrator can set an additional attribute “city” to any value.
:*: 1 2 means that the administrator can set any other additional attribute either to the value “1” or to the value “2”.

delete_custom_user_attributes

type: string
This takes a space separated list of attributes that the administrator is allowed to delete. You can use the asterisk “*” to
indicate, that this policy allows the administrator to delete any additional attribute.
Example:
attr1 attr2 department
The administrator is allowed to delete the attributes “attr1”, “attr2” and the attributes “department” of the corresponding
users.

Note: If this policy is not set, the admin is not allowed to delete any custom user attributes.

New in version 3.6

1.7. Policies 127


privacyIDEA Authentication System, Release 3.8

machinelist

type: bool
The administrator is allowed to list the machines.

manage_machine_tokens

type: bool
The administrator is allowed to attach and detach tokens to machines to enable the use with one of the available appli-
actions. See Machines.

fetch_authentication_items

type: bool
The administrator is allowed to fetch authentication items of tokens assigned to machines. It grants access to the
/machine/authitem endpoints (see Machine endpoints).

clienttype

type: bool
This policy action allows the admin to view the list of clients which authenticate to privacyIDEA at the Client endpoints.

managesubscription

type: bool
The administrator is able to view and change the subscriptions. It grants access to the Subscriptions endpoints.

set_hsm_password

The administrator is able to set the password of the hardware security module. It grants access to the /system/hsm
endpoint (see System endpoints).

1.7.2 User Policies

In the Web UI users can manage their own tokens. User can login to the Web UI with the username of their useridre-
solver. I.e. if a user is found in an LDAP resolver pointing to Active Directory the user needs to login with his domain
password.
User policies are used to define, which actions users are allowed to perform.
The user policies also respect the client input, where you can enter a list of IP addresses and subnets (like 10.2.0.0/16).
Using the client parameter you can allow different actions in if the user either logs in from the internal network or
remotely from the internet via the firewall.
Technically user policies control the use of the REST API Token endpoints and are checked using Policy Module and
Policy Decorators.

128 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Note: If no user policy is defined, the user has all actions available to him, to manage his tokens.

The following actions are available in the scope user:

enroll

type: bool
There are enrollment actions per token type, e.g. enrollHOTP. The user is only allowed to enroll such specified token
types.

assign

type: bool
The user is allowed to assign an existing token, that is located in his realm and that does not belong to any other user,
by entering the serial number.

disable

type: bool
The user is allowed to disable his own tokens. Disabled tokens can not be used to authenticate.

enable

type: bool
The user is allowed to enable his own tokens.

delete

type: bool
The user is allowed to delete his own tokens from the database. Those tokens can not be recovered. Anyway, the audit
log concerning these tokens remains.

unassign

type: bool
The user is allowed to drop his ownership of the token. The token does not belong to any user anymore and can be
reassigned.

1.7. Policies 129


privacyIDEA Authentication System, Release 3.8

resync

type: bool
The user is allowed to resynchronize the token if it has got out of synchronization.

reset

type: bool
The user is allowed to reset the failcounter of the token.

setpin

type: bool
The user is allowed to set the OTP PIN for his tokens.

setrandompin

type: bool
If the setrandompin action is defined, the user is allowed to call the endpoint, that sets a random PIN on his specified
token.

setdescription

type: bool
The user is allowed to set the description of his tokens.

enrollpin

type: bool
If the action enrollpin is defined, the user can set a token PIN during enrollment. If the action is not defined and the
user tries to set a PIN during enrollment, this PIN is deleted from the request.

hide_tokeninfo

type: string
This specifies a blank-separated list of tokeninfo keys, which should be removed from the response and therefore will
not be shown in the WebUI or JSON response.
For example a value tokenkind auto_renew will hide these two tokeninfo entries.

130 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

otp_pin_maxlength

type: integer
range: 0 - 31
This is the maximum allowed PIN length the user is allowed to use when setting the OTP PIN.

Note: There can be token type specific policies like spass_otp_pin_maxlength, spass_otp_pin_minlength and
spass_otp_pin_contents. If suche a token specific policy exists, it takes priority of the common PIN policy.

otp_pin_minlength

type: integer
range: 0 - 31
This is the minimum required PIN the user must use when setting the OTP PIN.

otp_pin_contents

type: string
contents: cns
This defines what characters an OTP PIN should contain when the user sets it.
This takes the same values like the admin policy otp_pin_contents.

otp_pin_set_random

type: int
The length of a random PIN set by the user.

auditlog

type: bool
This action allows the user to view and search the audit log for actions with his own tokens.
To learn more about the audit log, see Audit.

auditlog_age

type: string
This limits the maximum age of displayed audit entries. Older entries are not remove from the audit table but the user
is simply not allowed to view older entries.
Can be something like 10m (10 minutes), 10h (10 hours) or 10d (ten days).

1.7. Policies 131


privacyIDEA Authentication System, Release 3.8

hide_audit_columns

type: string
This species a blank separated list of audit columns, that should be removed from the response (Audit endpoint) and
also from the WebUI. For example a value sig_check log_level will hide these two columns.
The list of available columns can be checked by examining the response of the request to the Audit endpoint.

updateuser

type: bool
If the updateuser action is defined, the user is allowed to change his attributes in the user store.

Note: To be able to edit the attributes, the resolver must be defined as editable.

userlist

type: bool
If the userlist action is defined, the user is allowed to view his own user information.

revoke

type: bool
Tokens can be revoked. Usually this means the token is disabled and locked. A locked token can not be modified
anymore. It can only be deleted.
Certain token types like certificate may define special actions when revoking a token.

password_reset

type: bool
Introduced in version 2.10.
If the user is located in an editable user store, this policy can define, if the user is allowed to perform a password reset.
During the password reset an email with a link to reset the password is sent to the user.

hotp_2step and totp_2step

type: string
This allows or forces the user to enroll a smartphone based token in two steps. In the second step the smartphone
generates a part of the OTP secret, which the user needs to enter. (see Two Step Enrollment). Possible values are allow
and force. This works in conjunction with the enrollment parameters {type}_2step_clientsize, {type}_2step_serversize,
{type}_2step_difficulty.
Such a policy can also be set for the administrator. See hotp_2step and totp_2step.

132 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Note: This does not work in combination with the enrollment policy verify_enrollment, since the usage of 2step
already ensures, that the user has successfully scanned the QR code.

sms_gateways

type: string
Usually an SMS tokens sends the SMS via the SMS gateway that is system wide defined in the token settings. This
policy takes a blank separated list of configured SMS gateways. It allows the user to define an individual SMS gateway
during token enrollment.
New in version 3.0.

hotp_hashlib and totp_hashlib

type: string
Force the user to enroll HOTP/TOTP Tokens with the specified hashlib. The corresponding input selector will be
disabled/hidden in the web UI. Possible values are sha1, sha256 and sha512, default is sha1.

hotp_otplen and totp_otplen

type: int
Force the user to enroll HOTP/TOTP Tokens with the specified otp length. The corresponding input selector will be
disabled/hidden in the web UI. Possible values are 6 or 8, default is 6.

hotp_force_server_generate and totp_force_server_generate

type: bool
Enforce the key generation on the server. A corresponding input field for the key data will be disabled/hidden in the
web UI. Default value is false.

totp_timestep

type: int
Enforce the timestep of the time-based OTP token. A corresponding input selection will be disabled/hidden in the web
UI. Possible values are 30 or 60, default is 30.

indexedsecret_force_attribute

type: string
If a user enrolls an indexedsecret token then the value of the given user attribute is set as the secret. The user does not
see the value and can not change the value.
For more details of this token type see Indexed Secret Token.
New in version 3.3.

1.7. Policies 133


privacyIDEA Authentication System, Release 3.8

certificate_trusted_Attestation_CA_path

type: string
A user can enroll a certificate token. If an attestation certificate is provided in addition, this policy holds the path to
a directory, that contains trusted CA paths. Each PEM encoded file in this directory needs to contain the root CA
certificate at the first position and the consecutive intermediate certificates.
An additional enrollment policy certificate_require_attestation, if an attestation certificate is required.
New in version 3.5.

set_custom_user_attributes

type: string
This defines how a user is allowed to set his own attributes. It uses the same setting as the admin policy
set_custom_user_attributes.

Note: Using a ‘*’ in this setting allows the user to set any attribute or any value and thus the user can overwrite
existing attributes from the user store. If policies, depending on user attributes are defined, then the user would be able
to change the matching of the policies. Use with CAUTION!

New in version 3.6

delete_custom_user_attributes

type: string
This defines how a user is allowed to delete his own attributes. It uses the same setting as the admin policy
delete_custom_user_attributes.

Note: Using a ‘*’ in this setting allows the user to delete any attribute and thus the user can change overwritten
attributes and revert to the user store attributes. If policies, depending on user attributes are defined, then the user
would be able to change the matching of the policies. Use with CAUTION!

New in version 3.6

1.7.3 Authentication policies

The scope authentication gives you more detailed possibilities to authenticate the user or to define what happens during
authentication.
Technically the authentication policies apply to the REST API Validate endpoints and are checked using Policy Module
and Policy Decorators.
The following actions are available in the scope authentication:

134 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

otppin

type: string
This action defines how the fixed password part during authentication should be validated. Each token has its own OTP
PIN, but the administrator can choose how the authentication should be processed:
otppin=tokenpin
This is the default behaviour. The user needs to pass the OTP PIN concatenated with the OTP value.
otppin=userstore
The user needs to pass the user store password concatenated with the OTP value. It does not matter if
the OTP PIN is set or not. If the user is located in an Active Directory the user needs to pass his domain
password together with the OTP value.

Note: The domain password is checked with an LDAP bind right at the moment of authentication. So if the user is
locked or the password was changed authentication will fail.

otppin=none
The user does not have to pass any fixed password. Authentication is only done via the OTP value.

passthru

type: str
If the user has no token assigned, he will be authenticated against the userstore or against the given RADIUS configu-
ration. I.e. the user needs to provide the LDAP- or SQL-password or valid credentials for the RADIUS server.

Note: This is a good way to do a smooth enrollment. Users having a token enrolled will have to use the token, users
not having a token, yet, will be able to authenticate with their domain password.
It is also a way to do smooth migrations from other OTP systems. The authentication request of users without a token
is forwarded to the specified RADIUS server.

Note: The passthru policy overrides the authorization policy for tokentype. I.e. a user may authenticate due to the
passthru policy (since he has no token) although a tokentype policy is active!

Warning: If the user has the right to delete his tokens in selfservice portal, the user could delete all his tokens and
then authenticate with his static password again.

1.7. Policies 135


privacyIDEA Authentication System, Release 3.8

passthru_assign

type: str
This policy is only evaluated, if the policy passthru is set. If the user is authenticated against a RADIUS server, then
privacyIDEA splits the sent password into PIN and OTP value and tries to find an unassigned token, that is in the user’s
realm by using the OTP value. If it can identify this token, it assigns this token to the user and sets the sent PIN.
The policy is configured with a string value, that contains * the position of the PIN * the OTP length and * the number
of OTP values tested for each unassigned token (optional, default=100).
Examples are
• 8:pin would be an eight digit OTP value followed by the PIN
• pin:6:10000 would be the PIN followed by an 6 digit OTP value, 10.000 otp values would be checked for each
token.

Note: This method can be used to automatically migrated tokens from an old system to privacyIDEA. The adminis-
trator needs to import all seeds of the old tokens and put the tokens in the user’s realm.

Warning: This can be very time consuming if the OTP values to check is set to high!

passOnNoToken

type: bool
If the user has no token assigned an authentication request for this user will always be true.

Warning: Only use this if you know exactly what you are doing.

passOnNoUser

type: bool
If the user does not exist, the authentication request is successful.

Warning: Only use this if you know exactly what you are doing.

smstext

type: string
This is the text that is sent via SMS to the user trying to authenticate with an SMS token. This can contain the tags
<otp> and <serial>. Texts containing whitespaces must be enclosed in single quotes.
Starting with version 2.20 you can use the tag {challenge}. This will add the challenge data that was passed in the first
authentication request in the challenge parameter. This could contain banking transaction data.
Starting with version 3.6 the smstext can contain a lot more tags similar to the policy emailtext:

136 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

• {otp} or <otp> the One-Time-Password


• {serial} or <serial> the serial number of the token.
• {user} the given name of the token owner.
• {givenname} the given name of the token owner.
• {surname} the surname of the token owner.
• {username} the loginname of the token owner.
• {userrealm} the realm of the token owner.
• {tokentype} the type of the token.
• {recipient_givenname} the given name of the recipient.
• {recipient_surname} the surname of the recipient.
• {time} the current server time in the format HH:MM:SS.
• {date} the current server date in the format YYYY-MM-DD
In the SMS Gateway configuration the tag {otp} will be replaced by the custom message, set with this policy.
Default: <otp>

Note: The length of an SMS is limited to 140 characters due to the definition of SMS. You should take care, that the
smstext does not exceed this limit. SMS gateways could reject too long messages or the delivery could fail.

Note: Some apps may be able to handle incoming OTPs as a so called origin-bound one-time code in the format:

Your OTP is {otp}


@privacyidea.mydomain.com #{otp}

smsautosend

type: bool
A new OTP value will be sent via SMS if the user authenticated successfully with his SMS token. Thus the user does
not have to trigger a new SMS when he wants to login again.

emailtext

type: string
This is the text that is sent via Email to be used with Email Token. This text should contain the OTP tag.
The text can contain the following tags, that will be filled:
• {otp} or <otp> the One-Time-Password
• {serial} or <serial> the serial number of the token.
• {user} the given name of the token owner.
• {givenname} the given name of the token owner.
• {surname} the surname of the token owner.

1.7. Policies 137


privacyIDEA Authentication System, Release 3.8

• {username} the loginname of the token owner.


• {userrealm} the realm of the token owner.
• {tokentype} the type of the token.
• {recipient_givenname} the given name of the recipient.
• {recipient_surname} the surname of the recipient.
• {time} the current server time in the format HH:MM:SS.
• {date} the current server date in the format YYYY-MM-DD
Starting with version 2.20 you can use the tag {challenge}. This will add the challenge data that was passed in the first
authentication request in the challenge parameter. This could contain banking transaction data.
Default: <otp>
You can also provide the filename to an email template. The filename must be prefixed with file: like file:/etc/
privacyidea/emailtemplate.html. The template is an HTML file.

Note: If a message text is supplied directly, the email is sent as plain text. If the email template is read from a file, a
HTML-only email is sent instead.

emailsubject

type: string
This is the subject of the Email sent by the Email Token. You can use the same tags as mentioned in emailtext.
Default: Your OTP

emailautosend

type: bool
If set, a new OTP Email will be sent, when successfully authenticated with an Email Token.

mangle

type: string
The mangle policy can mangle the authentication request data before they are processed. I.e. the parameters user,
pass and realm can be modified prior to authentication.
This is useful if either information needs to be stripped or added to such a parameter. To accomplish that, the mangle
policy can do a regular expression search and replace using the keyword user, pass (password) and realm.
A valid action could look like this:

action: mangle=user/.*(.{4})/user\\1/

This would modify a username like “userwithalongname” to “username”, since it would use the last four characters of
the given username (“name”) and prepend the fixed string “user”.

138 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

This way you can add, remove or modify the contents of the three parameters. For more information on the regular
expressions see1 .

Note: You must escape the backslash as \\ to refer to the found substrings.

Example: A policy to remove whitespace characters from the realm name would look like this:

action: mangle=realm/\\s//

Example: If you want to authenticate the user only by the OTP value, no matter what OTP PIN he enters, a policy
might look like this:

action: mangle=pass/.*(.{6})/\\1/

Example: If you want to strip a string from the front of a username, for example to have “admin_username” resolve to
just “username”, it would look like this:

action: mangle=user/admin_(.*)/\\1/

challenge_response

type: string
This is a list of token types for which challenge response can be used during authentication. The list is separated by
whitespaces like “hotp totp”.

change_pin_via_validate

type: bool
This works with the enrollment policies change_pin_on_first_use and change_pin_every. When a PIN change is due,
then a successful authentication will start a challenge response mechanism in which the user is supposed to enter a new
PIN two times.
Only if the user successfully changes the PIN the authentication process is finished successfully. E.g. if the user enters
two different new PINs, the authentication process will fail.

Note: The application must support several consecutive challenge response requests.

resync_via_multichallenge

type: bool
This policy is based on the global setting Automatic resync during authentication. If AutoResync is enabled and this
policy is configured, a user can synchronize his token during authentication via challenge response.
If privacyIDEA realizes, that the first given OTP value is within the syncwindow, a challenge will be presented to the
user saying “To resync your token, please enter the next OTP value”. In contrast to the generic AutoResync a user has
to enter the token PIN only once.
1 https://docs.python.org/2/library/re.html

1.7. Policies 139


privacyIDEA Authentication System, Release 3.8

Note: The application must support several consecutive challenge response requests.

enroll_via_multichallenge

type: string
This policy allows the rollout of tokens during the authentication via /validate/check.
The policy action can take one of the followig token types: hotp, totp, push, email, sms.
The clients and plugins should make use of this policy in a transparent way and using multiple consecutive challenges.
The only condition currently, if a new token will be enrolled is that the user currently has no token of this token type.
This way, we avoid loops in this authentication process. This means, a user could authenticate via passthru or using a
registration code and right during this authentication session be asked to enroll a new token.

Note: During this kind of enrollment the policies for max_token are not checked. Also, currently no token PIN is set.

The different ways of enrollment are defined in detail by the token types:
HOTP and TOTP
If the policy is set to enroll an HOTP or a TOTP token, after successful authentication a QR code is displayed to
the user. The user has to scan the QR code and will then have to enter the valid OTP value, generated by the newly
scanned/enrolled token. Only after that, the user is finally authenticated.

Note: 2step enrollment is currently not supported in this enrollment scenario.

SMS and Email


After the first successful authentication step the user is presented with an input field to enter his email address or mobile
number. If done so, the user will then in the final step have to enter the OTP value sent via email or text message.

Note: Enrolls an SMS token or Email token with the email address from the userstore can be easily accomplished
with a token event handler. (See enroll).

PUSH
After the fist successful authentication step the user is presented a QR code for push token enrollment. The user needs
to scan the QR code with the privacyIDEA Authenticator App. If the token is successfully enrolled, the user is logged
in without any further interaction. Since the successful enrollment of the Push token already verifies the presence of
the user’s smartphone, there is no additional authentication step anymore during enrollment.

Note: Enrolling multiple token types one after another is not supported. It is currently possible to enroll only one
token type.

140 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

u2f_facets

type: string
This is a white space separated list of domain names, that are trusted to also use a U2F device that was registered with
privacyIDEA.
You need to specify a list of FQDNs without the https scheme like:
“host1.example.com host2.example.com firewall.example.com”
For more information on configuring U2F see U2F.

reset_all_user_tokens

type: bool
If a user authenticates successfully all failcounter of all of his tokens will be reset. This can be important, if using
empty PINs or otppin=None.

increase_failcounter_on_challenge

type: bool
The normal behaviour is: to not increase the failcounter in case of challenge response.
If this policy is activated the failcounter is increased for each token for which a challenge is triggered.
The reason for this is that an attack can no longer trigger an infinite number of SMS or emails, for example. Because
once the maximum failcounter has been reached, no further challenges for these tokens can be triggered.

Note: It should be noted that for all tokens for which a challenge has been generated, the failcounter will be incre-
mented. In the case of validate/triggerchallenge, the failcounters are increased for all tokens. In some cases it makes
sense to use this policy together with reset_all_user_tokens.

auth_cache

type: string
The Authentication Cache caches the credentials of a successful authentication and allows to use the same credentials
- also with an OTP value - for the specified amount of time and optionally for a specified number of authentications.
The time to cache the credentials can be specified like “4h”, “5m”, “2d”, “3s” (hours, minutes, days, seconds). The
number of allowed authentications can be specified as a whole number, greater than zero.
The notation “4h/5m” means, that credentials are cached for 4 hours, but may only be used again, if every 5 minutes the
authentication occurs. If the authentication with the same credentials would not occur within 5 minutes, the credentials
can not be used anymore.
The notation “2m/3” means, that credentials are cached for 2 minutes, but may only be used 3 times in this timeframe.
In future implementations the caching of the credentials could also be dependent on the clients IP address and the user
agent.

1.7. Policies 141


privacyIDEA Authentication System, Release 3.8

Note: Cache entries are written to the database table authcache. Please note that expired entries are automatically
deleted only when the user attempts to log in with the same expired credentials again. In all other cases, expired entries
need to be deleted from this table manually by running:

pi-manage authcache cleanup --minutes MIN

which deletes all cache entries whose last authentication has occurred at least MIN minutes ago. As an example:

pi-manage authcache cleanup --minutes 300

will delete all authentication cache entries whose last authentication happened more than 5 hours ago.
It may make sense to create a cronjob that periodically cleans up old authentication cache entries.

Note: The AuthCache only works for user authentication, not for authentication with serials.

push_text_on_mobile

type: string
This is the text that should be displayed on the push notification during the login process with a Push Token. You can
choose different texts for different users or IP addresses. This way you could customize push notifications for different
applications.

push_title_on_mobile

type: string
This is the title of the push notification that is displayed on the user’s smartphone during the login process with a Push
Token.

push_wait

type: int
This can be set to a number of seconds. If this is set, the authentication with a push token is only performed via one
request to /validate/check. The HTTP request to /validate/check will wait up to this number of seconds and
check, if the push challenge was confirmed by the user.
This way push tokens can be used with any non-push-capable applications.
Sensible numbers might be 10 or 20 seconds.

Note: This behaviour can interfere with other tokentypes. Even if the user also has a normal HOTP token, the
/validate/check request will only return after this number of seconds.

Warning: Using simple webserver setups like Apache WSGI this actually can block all available worker threads,
which will cause privacyIDEA to become unresponsive if the number of open PUSH challenges exceeds the number
of available worker threads!

142 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

push_allow_polling

type: string
This policy configures if push tokens are allowed to poll the server for open challenges (e.g. when the the third-party
push service is unavailable or unreliable).
The following options are available:
allow
Allow push tokens to poll for challenges.
deny
Deny push tokens to poll for challenges. This basically returns a 403 error when requesting the poll
endpoint.
token
Allow / Deny polling based on the individual token. The tokeninfo key polling_allowed is checked. If
the value evaluates to False, polling is denied for this token. If it evaluates to True or is not set, polling
is allowed for this token.
The default is to allow polling

push_ssl_verify

type: int
The smartphone needs to verify the SSL certificate of the privacyIDEA server during the authentication with push
tokens. By default, the verification is enabled. To disable verification during enrollment, see push_ssl_verify.

challenge_text, challenge_text_header, challenge_text_footer

Using these policies the administrator can modify the challenge texts of e.g. Email-Token or SMS-Token. The action
challenge_text changes the challenge text in general, no matter which challenge response token is used.
If the challenge_text_header is set and if there are more matching challenge response tokens, then the texts of all tokens
are concatenated together. Double challenge texts are reduced to one text only.
The challenge_text_header and challenge_text_footer may contain HTML. If the challenge_text_header ends with
an <ul> or <ol>, then all the challenge texts are formatted as an ordered or unordered list. In this case the chal-
lenge_text_footer also should contain the closing tag.

Note: The footer will only be used, if the header is also set.

1.7. Policies 143


privacyIDEA Authentication System, Release 3.8

indexedsecret_challenge_text

The Indexed Secret Token asks the user to provide the characters of the secret from certain positions. The default text
is:
Please enter the position 3,1,6,7 from your secret.
with 3,1,6,7 being the positions of the characters, the user is supposed to enter. This text can be changed with this
policy setting. The text needs to contain the python formatting tag {0!s} which will be replaced with the list of the
requested positions.
For more details of this token type see Indexed Secret Token.

webauthn_challenge_text

type: str
Use an alternate challenge text for requesting the user to confirm with his WebAuthn token during authentication. This
might be different from the challenge text received during enrollment (see webauthn_challenge_text).

email_challenge_text, sms_challenge_text, u2f_challenge_text

type: str
With these actions the administrator may set alternative challenge texts for email, SMS and U2F tokens.

indexedsecret_count

The Indexed Secret Token asks the used for a number of characters from a shared secret. The default number to ask is
2.
The number of requested positions can be changed using this policy.

webauthn_allowed_transports

type: string
This action determines, which transports may be used to communicate with the authenticator, during authentication.
For instance, if the authenticators used support both an USB connection and NFC wireless communication, they can
be limited to USB only using this policy. The allowed transports are given as a space-separated list.
The default is to allow all transports (equivalent to a value of usb ble nfc internal).

webauthn_timeout

type: integer
This action sets the time in seconds the user has to confirm an authentication request on his WebAuthn authenticator.
This is a client-side setting, that governs how long the client waits for the authenticator. It is independent of the time for
which a challenge for a challenge response token is valid, which is governed by the server and controlled by a separate
setting. This means, that if you want to increase this timeout beyond two minutes, you will have to also increase the
challenge validity time, as documented in Challenge Validity Time.
This setting is a hint. It is interpreted by the client and may be adjusted by an arbitrary amount in either direction, or
even ignored entirely.

144 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

The default timeout is 60 seconds.

Note: If you set this policy you may also want to set webauthn_timeout.

webauthn_user_verification_requirement

type: string
This action configures whether the user’s identity should be checked when authenticating with a WebAuthn token. If
this is set to required, any user signing in with their WebAuthn token will have to provide some form of verification.
This might be biometric identification, or knowledge-based, depending on the authenticator used.
This defaults to preferred, meaning user verification will be performed if supported by the token.

Note: User verification is different from user presence checking. The presence of a user will always be confirmed
(by asking the user to take action on the token, which is usually done by tapping a button on the authenticator). User
verification goes beyond this by ascertaining, that the user is indeed the same user each time (for example through
biometric means), only set this to required, if you know for a fact, that you have authenticators, that actually support
some form of user verification (these are still quite rare in practice).

Note: If you configure this, you will likely also want to configure webauthn_user_verification_requirement.

question_number

type: integer
The questionnaire token can ask more than one question during one authentication process. It will ask the first question,
verify the answer, ask the next question and verify the answer. This policy setting defines how many questions the user
needs to answer. (default: 1)

Note: A question will be asked only once, unless the policy requires more questions to be asked, than the token has
available answers.

preferred_client_mode

type: string
This action sets a list of the client mode in the preferred order. You can enter the different client modes in the order you
like. For example: “interactive, webauthn, poll, u2f”. The client you’re using will show you the riad login for you’re
preferred client mode. For example: this is you’re list: “interactive, webauthn, poll, u2f” and in you’re multi challenge
are a webauthn and u2f token, than you’re client will automatically show you the login for a webauthn token.

Note: The default list is “interactive, webauthn, poll, u2f”

1.7. Policies 145


privacyIDEA Authentication System, Release 3.8

1.7.4 Authorization policies

The scope authorization provides means to define what should happen if a user proved his identity and authenticated
successfully.
Authorization policies take the realm, the user and the client into account.
Technically the authorization policies apply to the Validate endpoints and are checked using Policy Module and Policy
Decorators.
The following actions are available in the scope authorization:

authorized

This is the basic authorization, that either grants the user access or denies access via the /validate endpoints (see
Validate endpoints). The default behaviour is to grant access, if and after the user has authenticated successfully.
Using authorized=deny_access specific authentication requests can be denied, even if the user has provided the
correct credentials.
In combination with different IP addresses and policy priorities the administrator can generically deny_access with the
lowest policy priority and grant_access for specific requests e.g. originating from specific IP addresses to certain users
by defining higher policy priorities.

Note: Since authorized is checked as a postpolicy the OTP value used during an authentication attempt will be
invalidated even if the authorized policy denies the access.

Note: The actual “success” of the authentication can be changed to “failed” by this postpolicy. I.e. pre-event handlers
(Pre and Post Handling) would still see the request as successful before it would be changed by this policy and match
the event handler condition result value == True.

tokentype

type: string
Users will only be authorized with this very tokentype. The string can hold a space separated list of case sensitive
tokentypes. It should look like:

hotp totp spass

This is checked after the authentication request, so that a valid OTP value is wasted, so that it can not be used, even if
the user was not authorized at this request

Note: Combining this with the client IP you can use this to allow remote access to sensitive areas only with one special
token type while allowing access to less sensitive areas with other token types.

146 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

application_tokentype

type: bool
If this policy is set, an application may add a parameter type as tokentype in the authentication request like validate/
check, validate/samlcheck or validate/triggerchallenge.
Then the application can determine via this parameter, which tokens of a user should be checked.
E.g. when using this in triggerchallenge, an application could assure, that only SMS tokens are used for authentication.

serial

type: string
Users will only be authorized with the serial number. The string can hold a regular expression as serial number.
This is checked after the authentication request, so that a valid OTP value is wasted, so that it can not be used, even if
the user was not authorized at this request

Note: Combining this with the client IP you can use this to allow remote access to sensitive areas only with hardware
tokens like the Yubikey, while allowing access to less secure areas also with a Google Authenticator.

tokeninfo

type: string
Users will only be authorized if the tokeninfo field of the token matches this regular expression.
This is checked after the authentication request, so that a valid OTP value can not be used anymore, even if authorization
is forbidden.
A valid action could look like:

action = key/regexp/

Example:

action = last_auth/^2018.*/

This would mean the tokeninfo field needs to start with “2018”.

setrealm

type: string
This policy is checked before the user authenticates. The realm of the user matching this policy will be set to the realm
in this action.

Note: This can be used if the user can not pass his realm when authenticating at a certain client, but the realm needs
to be available during authentication since the user is not located in the default realm.

1.7. Policies 147


privacyIDEA Authentication System, Release 3.8

no_detail_on_success

type: bool
Usually an authentication response returns additional information like the serial number of the token that was used to
authenticate or the reason why the authentication request failed.
If this action is set and the user authenticated successfully this additional information will not be returned.

no_detail_on_fail

type: bool
Usually an authentication response returns additional information like the serial number of the token that was used to
authenticate or the reason why the authentication request failed.
If this action is set and the user fails to authenticate this additional information will not be returned.

api_key_required

type: bool
This policy is checked before the user is validated.
You can create an API key, that needs to be passed to use the validate API. If an API key is required, but no key is
passed, the authentication request will not be processed. This is used to avoid denial of service attacks by a rogue user
sending arbitrary requests, which could result in the token of a user being locked.
You can also define a policy with certain IP addresses without issuing API keys. This would result in “blocking” those
IP addresses from using the validate endpoint.
You can issue API keys like this:

pi-manage api createtoken -r validate

The API key (Authorization token) which is generated is valid for 365 days.
The authorization token has to be used as described in Authentication endpoints.

auth_max_success

type: string
Here you can specify how many successful authentication requests a user is allowed to perform during a given time. If
this value is exceeded, the authentication attempt is canceled.
Specify the value like 2/5m meaning 2 successful authentication requests per 5 minutes. If during the last 5 minutes 2
successful authentications were performed the authentication request is discarded. The used OTP value is invalidated.
Allowed time specifiers are s (second), m (minute) and h (hour).

Note: This policy depends on reading the audit log. If you use a non readable audit log like Logger Audit this policy
will not work.

148 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

auth_max_fail

type: string
Here you can specify how many failed authentication requests a user is allowed to perform during a given time.
If this value is exceeded, authentication is not possible anymore. The user will have to wait.
If this policy is not defined, the normal behaviour of the failcounter applies. (see Reset Fail Counter)
Specify the value like 2/1m meaning 2 successful authentication requests per minute. If during the last 5 minutes 2
successful authentications were performed the authentication request is discarded. The used OTP value is invalidated.
Allowed time specifiers are s (second), m (minute) and h (hour).

Note: This policy depends on reading the audit log. If you use a non readable audit log like Logger Audit this policy
will not work.

last_auth

type: string
You can define if an authentication should fail, if the token was not successfully used for a certain time.
Specify a value like 12h, 123d or 2y to disallow authentication, if the token was not successfully used for 12 hours,
123 days or 2 years.
The date of the last successful authentication is store in the tokeninfo field of a token and denoted in UTC.

u2f_req

type: string
Only the specified U2F devices are authorized to authenticate. The administrator can specify the action like this:
u2f_req=subject/.*Yubico.*/
The the key word can be “subject”, “issuer” or “serial”. Followed by a regular expression. During registration of the
U2F device the information from the attestation certificate is stored in the tokeninfo. Only if the regexp matches this
value, the authentication with such U2F device is authorized.

add_user_in_response

type: bool
In case of a successful authentication additional user information is added to the response. A dictionary containing
user information is added in detail->user.

1.7. Policies 149


privacyIDEA Authentication System, Release 3.8

add_resolver_in_response

type: bool
In case of a successful authentication the resolver and realm of the user are added to the response. The names are added
in detail->user-resolver and detail->user-realm.

webauthn_authenticator_selection_list

type: string
This action configures a whitelist of authenticator models which may be authorized. It is a space-separated list of
AAGUIDs. An AAGUID is a hexadecimal string (usually grouped using dashes, although these are optional) identi-
fying one particular model of authenticator. To limit enrollment to a few known-good authenticator models, simply
specify the AAGUIDs for each model of authenticator that is acceptable. If multiple policies with this action apply, the
set of acceptable authenticators will be the union off all authenticators allowed by the various policies.
If this action is not configured, all authenticators will be deemed acceptable, unless limited through some other action.

Note: If you configure this, you will likely also want to configure webauthn_authenticator_selection_list

webauthn_req

type: string
This action allows filtering of WebAuthn tokens by the fields of the attestation certificate.
The action can be specified like this:

webauthn_req=subject/.*Yubico.*/

The the key word can be “subject”, “issuer” or “serial”. Followed by a regular expression. During registration of the
WebAuthn authenticator the information is fetched from the attestation certificate. Only if the attribute in the attestation
certificate matches accordingly the token can be enrolled.

Note: If you configure this, you will likely also want to configure webauthn_req

1.7.5 Enrollment policies

The scope enrollment defines what happens during enrollment either by an administrator or during the user self enroll-
ment.
Enrollment policies take the realms, the client (see Policies) and the user settings into account.
Technically enrollment policies control the use of the REST API Token endpoints and specially the init and assign-
methods.
Technically the decorators in API Policies are used.
The following actions are available in the scope enrollment:

150 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

max_token_per_realm

type: int
This is the maximum allowed number of tokens in the specified realm.

Note: If you have several realms with realm admins and you imported a pool of hardware tokens you can thus limit
the consumed hardware tokens per realm.

Note: If there are multiple matching policies, the highest maximum allowed number of tokens among the matching
policies is enforced. Policy priorities are ignored.

max_token_per_user

type: int
Limit the maximum number of tokens per user in this realm.
There are also token type specific policies to limit the number of tokens of a specific token type, that a user is allowed
to have assigned.

Note: If you do not set this action, a user may have unlimited tokens assigned.

Note: If there are multiple matching policies, the highest maximum allowed number of tokens among the matching
policies is enforced. Policy priorities are ignored.

max_active_token_per_user

type: int
Limit the maximum number of active tokens per user.
There are also token type specific policies to limit the number of tokens of a specific token type, that a user is allowed
to have assigned.

Note: Inactive tokens will not be taken into account. If the token already exists, it can be recreated if the token is
already active.

1.7. Policies 151


privacyIDEA Authentication System, Release 3.8

tokenissuer

type: string
This sets the issuer label for a newly enrolled Google Authenticator. This policy takes a fixed string, to add additional
information about the issuer of the soft token.
Starting with version 2.20 you can use the tags {user}, {realm}, {serial} and as new tags {givenname} and
{surname} in the field issuer.

Note: A good idea is to set this to the instance name of your privacyIDEA installation or the name of your company.

tokenlabel

type: string
This sets the label for a newly enrolled Google Authenticator. Possible tags to be replaces are <u> for user, <r> for
realm an <s> for the serial number.
The default behaviour is to use the serial number.

Note: This is useful to identify the token in the Authenticator App.

Note: Starting with version 2.19 the usage of <u>, <s> and <r> is deprecated. Instead you should use {user},
{realm}, {serial} and as new tags {givenname} and {surname}.

Warning: If you are only using <u> or {user} as tokenlabel and you enroll the token without a user, this will
result in an invalid QR code, since it will have an empty label. You should rather use a label like “{user}@{realm}”,
which would result in “@”.

appimageurl

type: string
With this action the administrator may specify the URL to a token image which is included in the QR code during
enrollment (key in otpauth URL: image). It is used by the privacyIDEA Authenticator and some other smartphone
apps like FreeOTP (supported file formats: PNG, JPG and GIF).

autoassignment

type: string
allowed values: any_pin, userstore
Users can assign a token just by using this token. The user can take a token from a pool of unassigned tokens. When
this policy is set, and the user has no token assigned, autoassignment will be done: The user authenticates with a new
PIN or his userstore password and an OTP value from the token. If the OTP value is correct the token gets assigned to
the user and the given PIN is set as the OTP PIN.

152 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Note: Requirements are:


1. The user must have no other tokens assigned.
2. The token must be not assigned to any user.
3. The token must be located in the realm of the authenticating user.
4. (The user needs to enter the correct userstore password)

Warning: If you set the policy to any_pin the token will be assigned to the user no matter what pin he enters. In
this case assigning the token is only a one-factor-authentication: the possession of the token.

otp_pin_random

type: int
Generates a random OTP PIN of the given length during enrollment. Thus the user is forced to set a certain OTP PIN.

Note: To use the random PIN, you also need to define a pinhandling policy.

pinhandling

type: string
If the otp_pin_random policy is defined, you can use this policy to define, what should happen with the random pin.
The action value take the class of a PinHandler like privacyidea.lib.pinhandling.base.PinHandler. The base
PinHandler just logs the PIN to the log file. You can add classes to send the PIN via EMail or print it in a letter.
For more information see the base class PinHandler.

change_pin_on_first_use

type: bool
If the administrator enrolls a token or resets a PIN of a token, then the PIN of this token is marked to be changed on
the first (or next) use. When the user authenticates with the old PIN, the user is authenticated successfully. But the
detail-response contains the keys “next_pin_change” and “pin_change”. If “pin_change” is True the authenticating
application must trigger the change of the PIN using the API /token/setpin. See Token endpoints.

Note: If the application does not honour the “pin_change” attribute, then the user can still authenticate with his old
PIN.

Note: Starting with version 3.4 privacyIDEA also allows to force the user to change the PIN in such a case using the
policy change_pin_via_validate.

1.7. Policies 153


privacyIDEA Authentication System, Release 3.8

change_pin_every

type: string
This policy requires the user to change the PIN of his token on a regular basis. Enter a value followed by “d”, e.g.
change the PIN every 180 days will be “180d”.
The date, when the PIN needs to be changed, is returned in the API response of /validate/check. For more information
see change_pin_on_first_use. To specify the contents of the PIN see User Policies.

encrypt_pin

type: bool
If set the OTP PIN of a token will be encrypted. The default behaviour is to hash the OTP PIN, which is safer.

registration.length

type: int
This is the length of the generated registration codes.

registration.contents

type: string
contents: cns
This defines what characters the registrationcodes should contain.
This takes the same values like the admin policy otp_pin_contents.

pw.length

type: int
This is the length if the password of a password token (pw token) is automatically generated with the genkey parameter.
The default length is 12.

pw.contents

type: string
contents: cns
This is the contents of an automatically generated password of a password token (pw token).
This takes the same values like the admin policy otp_pin_contents.

154 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

losttoken_PW_length

type: int
This is the length of the generated password for the lost token process.

losttoken_PW_contents

type: string
This is the contents that a generated password for the lost token process should have. You can use
• c: for lowercase letters
• n: for digits
• s: for special characters (!#$%&()*+,-./:;<=>?@[]^_)
• C: for uppercase letters
• 8: Base58 character set
Example:
The action lostTokenPWLen=10, lostTokenPWContents=Cns could generate a password like AC#!49MK)).

Note: If you combine 8 with e.g. C there will be double characters like “A”, “B”. . . Thus, those characters will have a
higher probability of being part of the password. Also C would again add the character “I”, which is not part of Base58.

losttoken_valid

type: int
This is how many days the replacement token for the lost token should be valid. After this many days the replacement
can not be used anymore.

yubikey_access_code

type: string
This is a 12 character long access code in hex format to be used to initialize Yubikeys. This access code is not actively
used by the privacyIDEA server. It is meant to be read by an admin client or enrollment client, so the component
initializing the Yubikey can use this access code, without the operator knowing the code.
If a yubikey uses an access code, Yubikeys can only be re-initialized by persons who know this code. You could choose
a company wide access code, so that Yubikeys can only be re-initialized by your own system.
You can add two access codes separated by a colon to change from one access code to the other.
313233343536:414243444546

Note: As long as the enrollment client does not read and use this access code, this configuration has no effect.

1.7. Policies 155


privacyIDEA Authentication System, Release 3.8

papertoken_count

type: int
This is a specific action of the paper token. Here the administrator can define how many OTP values should be printed
on the paper token.

tantoken_count

type: int
This is a specific action for the TAN token. The administrator can define how many TANs will be generated and printed.

u2f_req

type: string
Only the specified U2F devices are allowed to be registered. The action can be specified like this:
u2f_req=subject/.*Yubico.*/
The the key word can be “subject”, “issuer” or “serial”. Followed by a regular expression. During registration of the
U2F device the information is fetched from the attestation certificate. Only if the attribute in the attestation certificate
matches accordingly the token can be registered.

u2f_no_verify_certificate

type: bool
By default the validity period of the attestation certificate of a U2F device gets verified during the registration process.
If you do not want to verify the validity period, you can check this action.

{type}_2step_clientsize, {type}_2step_serversize, {type}_2step_difficulty

type: string
These are token type specific parameters. They control the key generation during the 2step token enrollment (see Two
Step Enrollment).
The serversize is the optional size (in bytes) of the server’s key part. The clientsize is the size (in bytes) of the
smartphone’s key part. The difficulty is a parameter for the key generation. In the implementation in version 2.21
PBKDF2 is used. In this case the difficulty specifies the number of rounds.
This is new in version 2.21.

hotp_force_app_pin, totp_force_app_pin

type: bool
During enrollment of a privacyIDEA Authenticator smartphone app this policy is used to force the user to protect the
token with a PIN.

Note: This only works with the privacyIDEA Authenticator. This policy has no effect, if the QR code is scanned with
other smartphone apps.

156 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

This is new in version 3.1.

push_firebase_configuration

type: string
For enrolling a Push Token, the administrator can select which Firebase configuration should be used. The adminis-
trator can create several connections to the Firebase service (see Firebase Provider). This way even different Firebase
configurations could be used depending on the user’s realm or the IP address.
This is new in version 3.0.
Starting with version 3.6, if the push token is supposed to run in poll-only mode, then the entry “poll only” can be
selected instead of a firebase configuration. In this mode, neither the privacyIDEA server nor the smartphone app will
connect to Google Firebase during enrollment or authentication. Note, that you also need to set the authentication
policy push_allow_polling to allow the push token to poll for challenges.

push_registration_url

type: string
This is the URL of your privacyIDEA server, which the push App should connect to for the second registration step.
This URL usually ends with /ttype/push. Note, that the smartphone app may connect to a different privacyIDEA
URL than the URL of the privacyIDEA Web UI.

push_ttl

This is the time (in minutes) how long the privacyIDEA server accepts the response of the second registration step.
The smartphone could have connection issues, so the second step could take some time to happen.

push_ssl_verify

type: int
The smartphone needs to verify the SSL certificate of the privacyIDEA server during the enrollment of push tokens.
By default, the verification is enabled. To disable verification during authentication, see push_ssl_verify.

verify_enrollment

type: string
This action takes a white space separated list of tokentypes. These tokens then need to be verified during enrollment.
This is supported for HOTP, TOTP, Email, SMS and Indexed Secret tokens.
In this case after enrolling the token the user is prompted to enter a valid OTP value. This way the system can verify,
that the user has successfully enrolled the token.
As long as no OTP value is provided by the user during the enrollment process, the token can not be used for authenti-
cation.

Note: This does not work in combination with the admin policy hotp_2step and totp_2step and the user policy
hotp_2step and totp_2step.

1.7. Policies 157


privacyIDEA Authentication System, Release 3.8

webauthn_relying_party_id

type: string
This action sets the relying party id to use for the enrollment of new WebAuthn tokens, at defined by the WebAuthn
specification1 . Please note, that a token will be rolled out with one particular ID and that the relying party of an existing
token can not be changed. In order to change the relying party id for existing tokens, they need to be deleted and new
tokens need to be enrolled. This is a limitation of the WebAuthn standard and is unlikely to change in the future.
The relying party id is a valid domain string that identifies the WebAuthn Relying Party on whose behalf a given
registration or authentication ceremony is being performed. A public key credential can only be used for authentication
with the same entity (as identified by RP ID) it was registered with.
This id needs to be a registrable suffix of or equal to the effective domain for each webservice the tokens should be
used with. This means if the token is being enrolled on – for example – https://login.example.com, them the relying
party ID may be either login.example.com, or example.com, but not – for instance – m.login.example.com, or com.
Similarly, a token enrolled with a relying party ID of login.example.com might be used by https://login.example.com,
or even https://m.login.example.com:1337, but not by https://example.com (because the RP ID login.example.com is
not a valid relying party ID for the domain example.com).

Note: This action needs to be set to be able to enroll WebAuthn tokens. For an overview of all the settings required
for the use of WebAuthn, see WebAuthn Token Config.

webauthn_relying_party_name

type: string
This action sets the human-readable name for the relying party, as defined by the WebAuthn specification2 . It should
be the name of the entity whose web applications the WebAuthn tokens are used for.

Note: This action needs to be set to be able to enroll WebAuthn tokens. For an overview of all the settings required
for the use of WebAuthn, see WebAuthn Token Config.

webauthn_timeout

type: integer
This action sets the time in seconds the user has to confirm enrollment on his WebAuthn authenticator.
This is a client-side setting, that governs how long the client waits for the authenticator. It is independent of the time for
which a challenge for a challenge response token is valid, which is governed by the server and controlled by a separate
setting. This means, that if you want to increase this timeout beyond two minutes, you will have to also increase the
challenge validity time, as documented in Challenge Validity Time.
This setting is a hint. It is interpreted by the client and may be adjusted by an arbitrary amount in either direction, or
even ignored entirely.
The default timeout is 60 seconds.

Note: If you set this policy you may also want to set webauthn_timeout.

1 https://w3.org/TR/webauthn-2/#rp-id
2 https://w3.org/TR/webauthn-2/#webauthn-relying-party

158 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

webauthn_authenticator_attachment

type: string
This action configures whether to limit roll out of WebAuthn tokens to either only platform authenticators, or only
platform authenticators. Cross-platform authenticators are authenticators, that are intended to be plugged into different
devices, whereas platform authenticators are those, that are built directly into one particular device and can not (easily)
be removed and plugged into a different device.
The default is to allow both platform and cross-platform attachment for authenticators.

webauthn_authenticator_selection_list

type: string
This action configures a whitelist of authenticator models which may be enrolled. It is a space-separated list of
AAGUIDs. An AAGUID is a hexadecimal string (usually grouped using dashes, although these are optional) iden-
tifying one particular model of authenticator. To limit enrollment to a few known-good authenticator models, simply
specify the AAGUIDs for each model of authenticator that is acceptable. If multiple policies with this action apply, the
set of acceptable authenticators will be the union off all authenticators allowed by the various policies.
If this action is not configured, all authenticators will be deemed acceptable, unless limited through some other action.

Note: If you configure this, you will likely also want to configure webauthn_authenticator_selection_list.

webauthn_user_verification_requirement

type: string
This action configures whether the user’s identity should be checked when rolling out a new WebAuthn token. If this is
set to required, any user rolling out a new WebAuthn token will have to provide some form of verification. This might
be biometric identification, or knowledge-based, depending on the authenticator used.
This defaults to preferred, meaning user verification will be performed if supported by the token.

Note: User verification is different from user presence checking. The presence of a user will always be confirmed
(by asking the user to take action on the token, which is usually done by tapping a button on the authenticator). User
verification goes beyond this by ascertaining, that the user is indeed the same user each time (for example through
biometric means), only set this to required, if you know for a fact, that you have authenticators, that actually support
some form of user verification (these are still quite rare in practice).

Note: If you configure this, you will likely also want to configure webauthn_user_verification_requirement.

1.7. Policies 159


privacyIDEA Authentication System, Release 3.8

webauthn_public_key_credential_algorithms

type: string
This action configures which algorithms should be available for the creation of WebAuthn asymmetric cryptography
key pairs. privacyIDEA currently supports ECDSA, RSASSA-PSS and RSASSA-PKCS1-v1_5. Please check back
with the manufacturer of your authenticators to get information on which algorithms are acceptable to your model of
authenticator.
The default is to allow both ECDSA and RSASSA-PSS.
The Order of preferred algorithms is ECDSA > RSASSA-PSS > RSASSA-PKCS1-v1_5

Note: Not all authenticators will supports all algorithms. It should not usually be necessary to configure this action.
Do not change this preference, unless you are sure you know what you are doing!

webauthn_authenticator_attestation_form

type: string
This action configures whether to request attestation data when enrolling a new WebAuthn token. Attestation is used
to verify, that the authenticator being enrolled has been made by a trusted manufacturer. Since depending on the
authenticator this may include personally identifying information, indirect attestation can be requested. If indirect
attestation is requested the client may pseudonymize the attestation data. Attestation can also be turned off entirely.
The default is to request direct (full) attestation from the authenticator.

Note: In a normal business-context it will not be necessary to change this. If this is set to none, webau-
thn_authenticator_attestation_level must also be none.

Note: Authenticators enrolled with this option set to none can not be filtered using webauthn_req and webau-
thn_authenticator_selection_list or webauthn_req and webauthn_authenticator_selection_list, respectively. Apply-
ing these filters is not possible without attestation information, since the fields these actions rely upon will be miss-
ing. With indirect attestation, checking may be possible (depending on the client). If any of webauthn_req, webau-
thn_authenticator_selection_list, webauthn_req, or webauthn_authenticator_selection_list are set and apply to a re-
quest for a token without attestation information, access will be denied.

webauthn_authenticator_attestation_level

type: string
This action determines whether and how strictly to check authenticator attestation data. Set this to none, to allow
any authenticator, even if the attestation information is missing completely. If this is set to trusted, strict checking is
performed. No authenticator is allowed, unless it contains attestation information signed by a certificate trusted for
attestation.

Note: Currently the certificate that signed the attestation needs to be trusted directly. Traversal of the trust path is not
yet supported!

160 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

The default is untrusted. This will perform the attestation check like normal, but will not fail the attestation, if the
attestation is self-signed, or signed by an unknown certificate.

Note: In order to be able to use trusted attestation, a directory needs to be provided, containing the certificates trusted
for attestation. See WebAuthn Token Config for details.

Note: If this is set to untrusted, a manipulated token could send a self-signed attestation message with modified a mod-
ified AAGUID and faked certificate fields in order to bypass webauthn_req and webauthn_authenticator_selection_list,
or webauthn_req and webauthn_authenticator_selection_list, respectively. If this is of concern for your attack scenar-
ios, please make sure to properly configure your attestation roots!

webauthn_req

type: string
This action allows filtering of WebAuthn tokens by the fields of the attestation certificate.
The action can be specified like this:

webauthn_req=subject/.*Yubico.*/

The the key word can be “subject”, “issuer” or “serial”. Followed by a regular expression. During registration of the
WebAuthn authenticator the information is fetched from the attestation certificate. Only if the attribute in the attestation
certificate matches accordingly the token can be enrolled.

Note: If you configure this, you will likely also want to configure webauthn_req.

webauthn_challenge_text

type: str
Use an alternate challenge text for requesting the user to confirm with his WebAuthn token during enrollment. This
might be different from the challenge text received during authentication (see webauthn_challenge_text).

webauthn_avoid_double_registration

type: bool
If this policy is set, a user or an admin can not register the same webauthn token to a user more than once. However,
the same webauthn token could be registered to a different user.

1.7. Policies 161


privacyIDEA Authentication System, Release 3.8

certificate_require_attestation

type: string
When enrolling a certificate token, privacyIDEA can require that an attestation certificate is passed along to verify, if
the key pair was generated on a (PIV) smartcard.
This policy can be set to:
• ignore (default): Ignore any existence of an attestation certificate
• verify: If an attestation certificate is passed along during enrollment, the attestation certificate gets verified.
• require_and_verify: An attestation certificate is required and verified. If no attestation certificate is provided,
the enrollment will fail.
The trusted root certificate authorities and intermediate certificate authorities can be configured via the policies certifi-
cate_trusted_Attestation_CA_path and certificate_trusted_Attestation_CA_path

certificate_ca_connector

type: string
During enrollment of a certificate token the user needs to specify the CA connector from which the CSR should be
signed. This policy adds the given CA connector parameter to the request. The list of CA connectors is read from the
configured connectors.

Note: When using the privacyIDEA Smartcard Enrollment Tool, this policy needs to be set, otherwise the enrollment
will fail.

certificate_template

type: string
During enrollment of a certificate token the user needs to specify the certificate template that should be used for en-
rollment. This policy adds the given template parameter to the request. The administrator needs to add the name of the
template manually in this policy.

Note: When using the privacyIDEA Smartcard Enrollment Tool in combination with a Microsoft CA, this policy
needs to be set, otherwise the enrollment will fail.

certificate_request_subject_component

type: string
During enrollment of a certificate by creating a request, privacyIDEA can add additional components to the request
subject.
This can be “email” (The email of the user read from the userstore) and/or “realm”, which is written to the orgnaiza-
tionalUnit (OU) of the request.

162 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Note: A couple of certificate templates on the Microsoft CA will not allow to have the email component directly in
the subject!

1.7.6 WebUI Policies

WebUI policies define the behaviour of the WebUI. After activating WebUI policies, the UI must be reloaded once for
the change to take effect

login_mode

type: string
allowed values: userstore, privacyIDEA, disable
If set to userstore (default), users and administrators need to authenticate with the password of their userstore, being
an LDAP service or an SQL database.
If this action is set to login_mode=privacyIDEA, the users and administrators need to authenticate against privacyIDEA
when logging into the WebUI. I.e. they can not login with their domain password anymore but need to authenticate
with one of their tokens.
If set to login_mode=disable the users and administrators of the specified realms can not login to the UI anymore.

Warning: If you set this action and the user deletes or disables all his tokens, he will not be able to login anymore.

Note: Administrators defined in the database using the pi-manage command can still login with their normal pass-
words.

Note: A sensible way to use this, is to combine this action in a policy with the client parameter: requiring the
users to login to the Web UI remotely from the internet with OTP but still login from within the LAN with the domain
password.

Note: Another sensible way to use this policy is to disable the login to the web UI either for certain IP addresses
(client) or for users in certain realms.

remote_user

type: string
This policy defines, if the login to the privacyIDEA using the web servers integrated authentication (like basic authen-
tication or digest authentication) should be allowed.
Possible values are disable, allowed and force.
If set to “allowed” a user can choose to use the REMOTE_USER or login with credentials. If set to “force”, the user
can not switch to login with credentials but can only login with the REMOTE_USER from the browser.

1.7. Policies 163


privacyIDEA Authentication System, Release 3.8

Note: The policy is evaluated before the user is logged in. At this point in time there is no realm known, so a policy
to allow remote_user must not select any realm.

Note: The policy setting “force” only works on the UI level. On the API level the user could still log in with credentials!
If you want to avoid this, see the next note.

Note: The policy login_mode and remote_user work independent of each other. I.e. you can disable login_mode and
allow remote_user.

You can use this policy to enable Single-Sign-On and integration into Kerberos or Active Directory. Add the following
template into you apache configuration in /etc/apache2/sites-available/privacyidea.conf:

<Directory />
# For Apache 2.4 you need to set this:
# Require all granted
Options FollowSymLinks
AllowOverride None

SSLRequireSSL
AuthType Kerberos
AuthName "Kerberos Login"
KrbMethodNegotiate On
KrbMethodK5Passwd On
KrbAuthRealms YOUR-REALM
Krb5KeyTab /etc/apache2/http.keytab
KrbServiceName HTTP
KrbSaveCredentials On
<RequireAny>
# Either we need a URL with no authentication or we need a valid user
<RequireAny>
# Any of these URL do NOT need a basic authentication
Require expr %{REQUEST_URI} =~ m#^/validate#
Require expr %{REQUEST_URI} =~ m#^/ttype#
</RequireAny>
Require valid-user
</RequireAny>
</Directory>

logout_time

type: int
Set the timeout, after which a user in the WebUI will be logged out. The default timeout is 120 seconds.
Being a policy this time can be set based on clients, realms and users.

164 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

timeout_action

type: str
The action taken when a user is idle beyond the logout_time limit. Defaults to lockscreen.

audit_page_size

type: int
By default 10 entries are displayed on one page in the audit view. On big screens you might want to display more
entries. Thus you can define in this policy how many audit entries should be displayed.

token_page_size

type: int
By default 15 tokens are displayed on one page in the token view. On big screens you might want to display more
tokens. Thus you can define in this policy how many tokens should be displayed.

user_page_size

type: int
By default 15 users are displayed on one page in the user view. On big screens you might want to display more users.
Thus you can define in this policy how many users should be displayed.

policy_template_url

type: string
Here you can define a URL from where the policies should be fetched. The default URL is a Github repository1 .

Note: When setting a template_url policy the modified URL will only get active after the user has logged out and in
again.

default_tokentype

type: string
You can define which is the default tokentype when enrolling a new token in the Web UI. This is the token, which will
be selected, when entering the enrollment dialog.
1 https://github.com/privacyidea/policy-templates/.

1.7. Policies 165


privacyIDEA Authentication System, Release 3.8

tokenwizard

type: bool
If this policy is set and the user has no token, then the user will only see an easy token wizard to enroll his first token.
If the user has enrolled his first token and he logs in to the web UI, he will see the normal view.
The user will enroll a token defined in default_tokentype.
Other sensible policies to combine are in User Policies the OTP length, the TOTP timestep and the HASH-lib.
You can add a prologue and epilog to the enrollment wizard in the greeting and after the token is enrolled and e.g. the
QR code is displayed.
Create the files:

static/customize/views/includes/token.enroll.pre.top.html
static/customize/views/includes/token.enroll.pre.bottom.html
static/customize/views/includes/token.enroll.post.top.html
static/customize/views/includes/token.enroll.post.bottom.html

to display the contents in the first step (pre) or in the second step (post).

Note: You can change the directory static/customize to a URL that fits your needs the best by defining a variable
PI_CUSTOMIZATION in the file pi.cfg. This way you can put all modifications in one place apart from the original
code.

If you want to adapt the privacyIDEA look and feel even more, read Customization.

tokenwizard_2nd_token

type: bool
The tokenwizard will be displayed in the token menu, even if the user already has a token.

realm_dropdown

type: string
If this policy is activated the web UI will display a realm dropdown box. Of course this policy can not filter for users
or realms, since the user is not known at this moment.
The type of this action was changed to “string” in version 2.16. You can set a space separated list of realm names. Only
these realm names are displayed in the dropdown box.

Note: The realm names in the policy are not checked, if they really exist!

166 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

search_on_enter

type: bool
The searching in the user list is performed as live search. Each time a key is pressed, the new substring is searched in
the user store.
Sometimes this can be too time consuming. You can use this policy to change the behaviour that the administrator
needs to press enter to trigger the search.
(Since privacyIDEA 2.17)

user_details

type: bool
This action adds the user ID and the resolver name to the token list.

custom_baseline

type: string
The administrator can replace the file templates/baseline.html with another template. This way he can change the
links to e.g. internal documentation or ticketing systems. The new file could be called mytemplates/mybase.html.
This will only work with a valid subscription of privacyIDEA Enterprise Edition.

Note: This policy is evaluated before login. So any realm or user setting will have no effect. But you can specify
different baselines for different client IP addresses.

If you want to adapt the privacyIDEA look and feel even more, read Customization.
(Since privacyIDEA 2.21)

custom_menu

type: string
The administrator can replace the file templates/menu.html with another template. This way he can change the
links to e.g. internal documentation or ticketing systems. The new file could be called mytemplates/mymenu.html.
This will only work with a valid subscription of privacyIDEA Enterprise Edition.

Note: This policy is evaluated before login. So any realm or user setting will have no effect. But you can specify
different menus for different client IP addresses.

If you want to adapt the privacyIDEA look and feel even more, read Customization.
(Since privacyIDEA 2.21)

1.7. Policies 167


privacyIDEA Authentication System, Release 3.8

hide_buttons

type: bool
Buttons for actions that a user is not allowed to perform, are hidden instead of being disabled.
(Since privacyIDEA 3.0)

deletion_confirmation

type: bool
To avoid careless deletion of important configurations, this policy can be activated. After activation, an additional
confirmation for the deletion is requested for policies, events, mresolvers, resolvers and periodic-tasks.
(Since privacyIDEA 3.9)

token_rollover

type: string
This is a whitespace separated list of tokentypes, for which a rollover button is displayed in the token details. This
button will generate a new token secret for the displayed token.
This e.g. enables a user to transfer a softtoken to a new device while keeping the token number restricted to 1.
(Since privacyIDEA 3.6)

login_text

type: string
This way the text “Please sign in” on the login dialog can be changed. Since the policy can also depend on the IP
address of the client, you can also choose different login texts depending on from where a user tries to log in.
(Since privacyIDEA 3.0)

show_android_privacyidea_authenticator

type: bool
If this policy is activated, the enrollment page for HOTP, TOTP and Push tokens will contain a QR code, that leads the
user to the Google Play Store where he can directly install the privacyIDEA Authenticator App for Android devices.
(Since privacyIDEA 3.3)

show_ios_privacyidea_authenticator

type: bool
If this policy is activated, the enrollment page for HOTP, TOTP and Push tokens will contain a QR code, that leads the
user to the Apple App Store where he can directly install the privacyIDEA Authenticator App for iOS devices.
(Since privacyIDEA 3.3)

168 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

show_custom_authenticator

type: string
If this policy is activated, the enrollment page for HOTP, TOTP and Push tokens will contain a QR code, that leads the
user to the given URL.
The idea is, that an organization running privacyIDEA can create its own URL, where the user is taken to, e.g.
• Show information about the used Authenticator apps. . .
• Do a device identification and automatically redirect the user to Google Play Store or Apple App Store. Thus
only need the user to show one QR code. . .
• If an organization has it’s own customized app or chooses to use another app, lead the user to another App in the
Google Play Store or Apple App Store.
Other scenarios are possible.
(Since privacyIDEA 3.3)

show_node

type: bool
If this policy is activated the UI will display the name of the privacyIDEA node in the top left corner next to the logo.
This is useful, if you have a lot of different privacyIDEA nodes in a redundant setup or if you have test instances and
productive instances. This way you can easily distinguish the different instances.
(Since privacyIDEA 3.5)

show_seed

type: bool
If this is checked, the token seed will be additionally displayed as text during enrollment.

indexedsecret_preset_attribute

type: string
The secret in the enrollment dialog of the tokentype indexedsecret is preset with the value of the given user attribute.
For more details of this token type see Indexed Secret Token.
(Since privacyIDEA 3.3)

admin_dashboard

type: bool
If this policy is activated, the static dashboard can be accessed by administrators. It is displayed as a starting page
in the WebUI and contains information about token numbers, authentication requests, recent administrative changes,
policies, event handlers and subscriptions.
(Since privacyIDEA 3.4)

1.7. Policies 169


privacyIDEA Authentication System, Release 3.8

dialog_no_token

type: bool
When activated, a welcome dialog will be displayed if a user, who has no token assigned, logs in to the Web UI. The
dialog is contained in the template dialog.no.token.html.

hide_welcome_info

type: bool
If this is checked, the administrator will not see the default welcome dialog anymore.

privacy_statement_link

type: str
With this policy you may specify a custom privacy statement link which is displayed in the WebUI baseline.

1.7.7 Register Policy

User registration

Starting with privacyIDEA 2.10 users are allowed to register with privacyIDEA. I.e. a user that does not exist in a
given realm and resolver can create a new account.

Note: Registering new users is only possible, if there is a writeable resolver and if the necessary policy in the scope
register is defined. For editable UserIdResolvers see UserIdResolvers.

If a register policy is defined, the login window of the Web UI gets a new link “Register”.

Fig. 56: Next to the login button is a new link ‘register’, so that new users are able to register.

A user who clicks the link to register a new account gets this registration dialog:
During registration the user is also enrolled Registration token. This registration code is sent to the user via a notification
email.

170 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Fig. 57: Registration form

1.7. Policies 171


privacyIDEA Authentication System, Release 3.8

Note: Thus - using the right policies in scope webui and authentication - the user could login with the password he
set during registration an the registration code he received via email.

Policy settings

In the scope register several settings define the behaviour of the registration process.

Fig. 58: Creating a new registration policy

172 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

realm

type: string
This is the realm, in which a new user will be registered. If this realm is not specified, the user will be registered in the
default realm.

resolver

type: string
This is the resolver, in which the new user will be registered. If this resolver is not specified, registration is not
possible!

Note: This resolver must be an editable resolver, otherwise the user can not be created in this resolver.

smtpconfig

type: string
This is the unique identifier of the SMTP server configuration. This SMTP server is used to send the notification email
with the registration code during the registration process.

Note: If there is no smtpconfig or set to a wrong identifier, the user will get no notification email.

requiredemail

type: string
This is a regular expression according to1 .
Only email addresses matching this regular expression are allowed to register.
Example: If you want to authenticate the user only by the OTP value, no matter what OTP PIN he enters, a policy
might look like this:

action: requiredemail=/.*@mydomain\..*/

This will allow all email addresses from the domains mydomain.com, mydomain.net etc. . .
1 https://docs.python.org/2/library/re.html

1.7. Policies 173


privacyIDEA Authentication System, Release 3.8

registration_body

type: str
The body of the registration email. Use the {regkey} as tag for the registration key.
You can define as many policies as you wish to. The logic of the policies in the scopes is additive.

Fig. 59: Policy Definition

Starting with privacyIDEA 2.5 you can use policy templates to ease the setup.

1.7.8 Policy Templates

Policy templates are defined in a Github repository which can be changed using a WebUI policy policy_template_url.
The templates are fetched from the given repository URL during runtime.

174 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

The policy templates are json files, which can contain common settings, that can be used to start your own polices.
When creating a new policy, you can select an existing policy template as a starting point.
You may also fork the github repository and commit pull request to improve the policy templates. Or you may fork the
github repository and use your own policy template URL for your policy templates.
A policy templates looks like this:

{
"name": "template_name1",
"scope": "enrollment",
"action": {
"tokenlabel": "<u>@<r>/<s>",
"autoassignment": true
}
}

realms, resolver and clients are not used in the templates.


A template must be referenced in a special index.json file:

{
"template_name1": "description1",
"template_name2": "description2"
}

where the key is the name of the template file and the value is a description displayed in the WebUI.
Each policy can contain the following attributes:
policy name
A unique name of the policy. The name is the identifier of the policy. If you create a new policy with the
same name, the policy is overwritten.

Note: In the web UI and the API policies can only be created with the characters 0-9, a-z, A-Z, “_”, “-”,
” ” and “.”. On a library level or during migration scripts policies with other characters could be created.

scope
The scope of the policy as described above.
action
This is the important part of the policy. Each scope provides its own set of actions. An action describes
that something is allowed or that some behaviour is configured. A policy can contain several actions.
Actions can be of type boolean, string or integer. Boolean actions are enabled by just adding this action -
like scope=user:action=disable, which allows the user to disable his own tokens. string and integer
actions require an additional value - like scope=authentication:action='otppin=userstore'.
user
This is the user, for whom this policy is valid. Depending on the scope the user is either an administrator
or a normal authenticating user.
If this field is left blank, this policy is valid for all users.
resolver

1.7. Policies 175


privacyIDEA Authentication System, Release 3.8

This policy will be valid for all users in this resolver.


If this field is left blank, this policy is valid for all resolvers.

Note: Starting with version 2.17 you can use the parameter check_all_resolvers. This is Check all
possible resolvers of a user to match the resolver in this policy in the Web UI.
Assume a user user@realm1 is contained in resolver1 and resolver2 in the realm realm1, where resolver1 is
the resolver with the highest priority. If the user authenticates as user@realm1, only policies for resolver1
will match, since the user is identified as user.resolver1@realm1.
If you also want to match a policy with resolver=resolver2, you need to select Check all possible
resolvers in this policy. Thus this policy will match for all users, which are also contained in resolver2 as
a secondary resolver.

realm
This is the realm, for which this policy is valid.
If this field is left blank, this policy is valid for all realms.
client
This is the requesting client, for which this action is valid. I.e. you can define different policies if the user
access is allowed to manage his tokens from different IP addresses like the internal network or remotely
via the firewall.
You can enter several IP addresses or subnets divided by comma. Exclude item by prepending a minus
sign (like 10.2.0.0/16, -10.2.0.1, 192.168.0.1).
privacyIDEA Node
(added in privacyIDEA 3.4)
If you have a redundant setup requests can hit different dedicated nodes of your privacyIDEA cluster. If
you want a policy to only be valid for certain privacyIDEA Nodes, you can set a list of allowed nodes.
This can be useful if you e.g. only want certain administrative actions on dedicated nodes.
The nodes are configured in pi.cfg. See The Config File.
time
(added in privacyIDEA 2.12)
In the time field of a policy you can define a list of time ranges. A time range can consist of day of weeks
(dow) and of times in 24h format. Possible values are:

<dow>: <hh>-<hh>
<dow>: <hh:mm>-<hh:mm>
<dow>-<dow>: <hh:mm>-<hh:mm>

You may use any combination of these. Like:

Mon-Fri: 8-18

to define certain policies to be active throughout working hours.

Note: If the time of a policy does not match, the policy is not found. Thus you can get effects you did not
plan. So think at least twice before using time restricted policies.

176 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

priority
(added in privacyIDEA 2.23)
The priority field of policies contains a positive number and defaults to 1. In case of policy conflicts,
policies with a lower priority number take precedence.
It can be used to resolve policy conflicts. An example is the passthru policy: Assume there are two passthru
policies pol1 and pol2 that define different action values, e.g. pol1 defines passthru=userstore and
pol2 defines passthru=radius1. If multiple policies match for an incoming authentication request, the
priority value is used to determine the policy that should take precedence: Assuming pol1 has a priority
of 3 and pol2 has a priority of 2, privacyIDEA will honor only the pol2 policy and authenticate the user
against the RADIUS server radius1.
Policy conflicts can still occur if multiple policies with the same priority specify different values for the
same action.
additional conditions
(added in privacyIDEA 3.1)
Using conditions, you can specify more advanced rules that determine whether a policy is valid for a
request.
Conditions are described in

1.7.9 Extended Policy Conditions

Since privacyIDEA 3.1, extended policy conditions allow to define more advanced rules for policy matching, i.e. for
determining which policies are valid for a specific request.
Conditions can be added to a policy via the WebUI. In order for a policy to take effect during the processing of a
request, the request has to match not only the ordinary policy attributes (see Policies), but also all additionally defined
conditions that are currently active. If no active conditions are defined, only the ordinary policy attributes are taken
into account.
Each policy condition performs a comparison of two values. The left value is taken from the current request. The
comparison operator (called Comparator) and the right value are entered in the policy definition. Each condition
consists of five parts:
• Active determines if the condition is currently active.
• Section refers to an aspect of the incoming request on which the condition is applied. The available sections
are predefined, see Sections.
• The meaning of Key depends on the chosen Section. Typically, it determines the exact property of the incoming
request on which the condition is applied.
• Comparator defines the comparison to be performed. The available comparators are predefined, see Compara-
tors.
• Value determines the value the property should be compared against.

1.7. Policies 177


privacyIDEA Authentication System, Release 3.8

Sections

privacyIDEA implements the sections userinfo, token, tokeninfo, HTTP Request Headers and HTTP
Environment.

userinfo

The section userinfo can be used to define conditions that are checked against attributes of the current user in the
request (the so-called handled user). The validity of a policy condition with section userinfo is determined as follows:
• privacyIDEA retrieves the userinfo of the currently handled user. These are the user attributes as they are deter-
mined by the respective resolver. This is configured via the attribute mappings of resolvers (see UserIdResolvers).
• Then, it retrieves the userinfo attribute given by Key
• Finally, it uses the Comparator to compare the contents of the userinfo attribute with the given Value. The
result of the comparison determines if the request matches the condition or not.

Note: There are situations in which the currently handled user cannot be determined. If privacyIDEA encounters a
policy with userinfo conditions in such a situation, it throws an error and the current request is aborted.
Likewise, privacyIDEA raises an error if Key refers to an unknown userinfo attribute, or if the condition definition is
invalid due to some other reasons. More detailed information are then written to the logfile.

As an example for a correct and useful userinfo condition, let us assume that you have configured a realm ldaprealm
with a single LDAP resolver called ldapres. This resolver is configured to fetch users from a OpenLDAP server, with
the following attribute mapping:

{ "phone": "telephoneNumber",
"mobile": "mobile",
"email": "mailPrimaryAddress",
"groups": "memberOf",
"surname": "sn",
"givenname": "givenName" }

You can further define groups to be a multi-value attribute by setting the Multivalue Attributes option to ["groups"].
According to this mapping, users of ldaprealm will have userinfo entries phone, mobile, email, groups, surname
and givenname which are filled with the respective values from the LDAP directory.
You can now configure a policy that disables the WebUI login for all users in the LDAP group cn=Restricted Login,
cn=groups,dc=test,dc=intranet with an email address ending in @example.com:
• Scope: webui
• Action: login_mode=disable
• 1) additional condition (active):
– Section: userinfo
– Key: email
– Comparator: matches
– Value: .*@example.com
2) additional condition (active):
– Section: userinfo

178 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

– Key: groups
– Comparator: contains
– Value: cn=Restricted Login,cn=groups,dc=test,dc=intranet
The policy only takes effect if the user that is trying to log in has a matching email address and is a member of the
specified group. In other words, members of the group with an email address ending in @privacyidea.org will still
be allowed to log in.

Note: Keep in mind that changes in the LDAP directory may not be immediately visible to privacyIDEA due to
caching settings (see LDAP resolver).

If the userinfo of the user that is trying to log in does not contain attributes email or groups (due to a resolver
misconfiguration, for example), privacyIDEA throws an error and the request is aborted.

tokeninfo

The tokeninfo condition works the same way as userinfo but matches the tokeninfo instead.

Note: Similar to the userinfo condition, a policy with an active tokeninfo condition will throw an exception whenever
the token object cannot be determined (usually from the serial).

token

The token condition works on the database columns of the token. This would be description, otplen, count,
serial, active but most importantly also failcount and tokentype.

Note: A policy with an active token condition will throw an exception whenever the token object cannot be determined.
It will also throw an error, if the request Key does not exist as a database column.

Note: The matching is case sensitive. Note, that e.g. token types are stored in lower case in the database.

Example: The administrator could define a dedicated policy in the scope user with the action delete and the token
condition active, <, 1. For an inactive token the attribute active would evaluate to 0 and thus be smaller than 1. An
active token would evaluate to 1. This would allow the user to delete only inactive tokens, but not still active tokens.

HTTP Request Header

The section HTTP Request header can be used to define conditions that are checked against the request header key-
value pairs.
The Key specifies the request header key. It is case-sensitive.
privacyIDEA uses the Comparator to check if the value of a header is equal or a substring of the required value.

Note: privacyIDEA raises an error if Key refers to an unknown request header. If the header in question is missing,
the policy can not get completely evaluated. Be aware that requests, that do not contain the header Key will always fail!

1.7. Policies 179


privacyIDEA Authentication System, Release 3.8

Thus, if you are using uncommon headers you should in addition restrict the policy e.g. to client IPs, to assure, that a
request from this certain IP address will always contain the header, that is to be checked.

HTTP Environment

The section HTTP Environment can be used to define conditions that are checked against the HTTP environment
key-value pairs.
The Key is case sensitive.
The environment contains information like the PATH_INFO which contains the name of the endpoint like /validate/
check or /auth.

Note: privacyIDEA raises an error if Key refers to an unknown environment key. The log file then contains information
about the available keys. The behaviour is similar to the extended conditions of HTTP Request Header.

Comparators

The following comparators can be used in definitions of policy conditions:


• equals evaluates to true if the left value is equal to the right value, according to Python semantics. !equals
evaluates to true if this is not the case.
• contains evaluates to true if the left value (a list) contains the right value as a member. !contains evaluates
to true if this is not the case.
• in evaluates to true if the left value is contained in the list of values given by the right value. The right value is
a comma-separated list of values. Individual values can be quoted using double-quotes. !in evaluates to true if
the left value is not found in the list given by the right value.
• matches evaluates to true if the left value completely matches the regular expression given by the right value.
!matches evaluates to true if this is not the case.

Error Handling

privacyIDEA’s error handling when checking policy conditions is quite strict, in order to prevent policy misconfigura-
tion from going unnoticed. If privacyIDEA encounters a policy condition that evaluates neither to true nor false, but
simply invalid due to a misconfiguration, privacyIDEA throws an error and the current request is aborted.

1.8 Event Handler

Added in version 2.12.


What is the difference between Policies and event handlers?
Policies are used to define the behaviour of the system. With policies you can change the way the system reacts.
With event handlers you do not change the way the system reacts. But on certain events you can trigger a new action
in addition to the behaviour defined in the policies.
These additional actions are also logged to the audit log. These actions are marked as EVENT in the audit log and you
can see, which event triggered these actions. Thus a single API call can cause several audit log entries: One for the
API call and more for the triggered actions.

180 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

1.8.1 Events

Each API call is an event and you can bind arbitrary actions to each event as you like. You can bind several actions to
one event. These actions are executed in the order of the priority one after another.

Note: An action, that is triggered by an event can not trigger a new action. Only events (API calls) can trigger actions.
E.g. if you are using the Token Handler Module to create a new token, the creation of the token is an action, not an
event. This means this creation of the token can not trigger a new action. For more complex actions, you might need
to look into the Script Handler Module.

Internally events are marked by a decorator “event” with an event identifier. At the moment not all events might be
tagged. Please drop us a note to tag all further API calls.

Fig. 60: An action is bound to the event token_init.

1.8.2 Pre and Post Handling

Added in Version 2.23.


With most event handlers you can decide if you want the action to be taken before the actual event or after the actual
event. I.e. if all conditions would trigger certain actions the action is either triggered before (pre) the API request is
processed or after (post) the request is processed.
Up to version 2.22 all actions where triggered after the request. In this case additional information from the response is
available. E.g. if a user successfully authenticated the event will know the serial number of the token, which the user
used to authenticate.
If the action is triggered before the API request is processed, the event can not know if the authentication request will
be successful or which serial number a token would have. However, triggering the action before the API request is
processed can have some interesting other advantages:

1.8. Event Handler 181


privacyIDEA Authentication System, Release 3.8

Example for Pre Handling

The administrator can define an event definition that would trigger on the event validate/check in case the the
authenticating user does not have any token assigned.
The pre event definition could call the Tokenhandler with the enroll action and enroll an email token with dy-
namic_email for this very user.
When the API request validate/check is now processed, the user actually now has an email token and can authenti-
cate via challenge response with this very email token without an administrator ever enrolling or assigning a token for
this user.

1.8.3 Handler Modules and Actions

The actions are defined in handler modules. So you bind a handler module and the action, defined in the handler
module, to the events.
The handler module can define several actions and each action in the handler module can require additional options.

Fig. 61: The event sendmail requires the option emailconfig.

182 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

1.8.4 Conditions

Added in version 2.14


An event handler module may also contain conditions. Only if all conditions are fulfilled, the action is triggered.
Conditions are defined in the class property conditions and checked in the method check_condition. The base class for
event handlers currently defines those conditions. So all event handlers come with the same conditions.

Note: In contrast to other conditions, the condition checking for tokenrealms, tokenresolvers, serial and
user_token_number also evaluates to true, if this information can not be checked. I.e. if a request does not contain
a serial or if the serial can not be determined, this condition will be evaluated as fulfilled.
Event Handlers are a mighty and complex tool to tweak the functioning of your privacyIDEA system. We recommend
to test your definitions thoroughly to assure your expected outcome.

Basic conditions

The basic event handler module has the following conditions.


client_ip
The action is triggered if the client IP matches this value. The value can be a comma-separated list of single addresses
or networks. To exclude entries, put a minus sign:

192.168.0.0/24,-192.168.0.12,10.0.0.2

count_auth
This can be ‘>100’, ‘<99’, or ‘=100’, to trigger the action, if the tokeninfo field ‘count_auth’ is bigger than 100, less
than 99 or exactly 100.
count_auth_fail
This can be ‘>100’, ‘<99’, or ‘=100’, to trigger the action, if the difference between the tokeninfo field ‘count_auth’
and ‘count_auth_success is bigger than 100, less than 99 or exactly 100.
count_auth_success
This can be ‘>100’, ‘<99’, or ‘=100’, to trigger the action, if the tokeninfo field ‘count_auth_success’ is bigger than
100, less than 99 or exactly 100.
failcounter
This is the failcount of the token. It is increased on failed authentication attempts. If it reaches max_failcount
increasing will stop and the token is locked. See Reset Fail Counter.
The condition can be set to ‘>9’, ‘=10’, or ‘<5’ and it will trigger the action accordingly.
detail_error_message
This condition checks a regular expression against the detail section in the API response. The field
detail->error->message is evaluated.
Error messages can be manyfold. In case of authentication you could get error messages like:
“The user can not be found in any resolver in this realm!”
With token/init you could get:
“missing Authorization header”

1.8. Event Handler 183


privacyIDEA Authentication System, Release 3.8

Note: The field detail->error->message is only available in case of an internal error, i.e.
if the response status is ``False.

detail_message
This condition checks a regular expression against the detail section in the API response. The field
detail->message is evaluated.
Those messages can be manyfold like:

"wrong otp pin"


"wrong otp value"
"Only 2 failed authentications per 1:00:00"

Note: The field detail->message is available in case of status True, like an authentication request that was handled
successfully but failed.

detail_message
Here you can enter a regular expression. The condition only applies if the regular expression matches the
detail->message in the response.
last_auth
This condition checks if the last authentication is older than the specified time delta. The timedelta is specified with
“h” (hours), “d” (days) or “y” (years). Specifying 180d would mean, that the action is triggered if the last successful
authentication with the token was performed more than 180 days ago.
This can be used to send notifications to users or administrators to inform them, that there is a token, that might be
orphaned.
logged_in_user
This condition checks if the logged in user is either an administrator or a normal user. This way the administrator can
bind actions to events triggered by normal users or e.g. by help desk users. If a help desk user enrolls a token for a
user, the user might get notified.
If a normal user enrolls some kind of token, the administrator might get notified.
otp_counter
The action is triggered, if the otp counter of a token has reached the given value. The value can either be an exact match
or greater (‘>100’) or less (‘<200’) then a specified limit.
The administrator can use this condition to e.g. automatically enroll a new paper token for the user or notify the user
that nearly all OTP values of a paper token have been spent.
realm
The condition realm matches the user realm. The action will only trigger, if the user in this event is located in the given
realm.
This way the administrator can bind certain actions to specific realms. E.g. some actions will only be triggered, if the
event happens for normal users, but not for users in admin- or helpdesk realms.
resolver
The resolver of the user, for which this event should apply.
result_status

184 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

The result.status within the response is True or False.


result_value
This condition checks the result of an event.
E.g. the result of the event validate_check can be a failed authentication. This can be the trigger to notify either the
token owner or the administrator.
rollout_state
This is the rollout_state of a token. A token can be rolled out in several steps like the 2step HOTP/TOTP token. In this
case the attribute “rollout_state” of the token contains certain values like clientwait or enrolled. This way actions
can be triggered, depending on the step during an enrollment process.
serial
The action will only be triggered, if the serial number of the token in the event does match the regular expression.
This is a good idea to combine with other conditions. E.g. only tokens with a certain kind of serial number like Google
Authenticator will be deleted automatically.
token_has_owner
The action is only triggered, if the token is or is not assigned to a user.
token_is_orphaned
The action is only triggered, if the user, to whom the token is assigned, does not exist anymore.
token_locked
The action is only triggered, if the token in the event is locked, i.e. the maximum failcounter is reached. In such a case
the user can not use the token to authenticate anymore. So an action to notify the user or enroll a new token can be
triggered.
token_validity_period
Checks if the token is in the current validity period or not. Can be set to True or False.

Note: token_validity_period==False will trigger an action if either the validity period is either over or has not
started, yet.

tokeninfo
The tokeninfo condition can compare any arbitrary tokeninfo field against a fixed value. You can compare strings and
integers. Integers are converted automatically. Valid compares are:

myValue == 1000
myValue > 1000
myValue < 99
myTokenInfoField == EnrollmentState
myTokenInfoField < ABC
myTokenInfoField > abc

“myValue” and “myTokenInfoField” being any possible tokeninfo fields.


Starting with version 2.20 you can also compare dates in the isoformat like that:

myValue > 2017-10-12T10:00+0200


myValue < 2020-01-01T00:00+0000

1.8. Event Handler 185


privacyIDEA Authentication System, Release 3.8

In addition you can also use the tag {now} to compare to the current time and you can add offsets to {now} in seconds,
minutes, hours or days:

myValue < {now}


myValue > {now}+10d
myValue < {now}-5h

Which would match if the tokeninfo myValue is a date, which is later than 10 days from now or it the tokeninfo myValue
is a date, which is 5 more than 5 hours in the past.
tokenrealm
In contrast to the realm this is the realm of the token - the tokenrealm. The action is only triggered, if the token within
the event has the given tokenrealm. This can be used in workflows, when e.g. hardware tokens which are not assigned
to a user are pushed into a kind of storage realm.
tokenresolver
The resolver of the token, for which this event should apply.
tokentype
The action is only triggered if the token in this event is of the given type. This way the administrator can design
workflows for enrolling and re-enrolling tokens. E.g. the tokentype can be a registration token and the registration
code can be easily and automatically sent to the user.
user_token_number
The action is only triggered, if the user in the event has the given number of tokens assigned.
This can be used to e.g. automatically enroll a token for the user if the user has no tokens left (token_number == 0)
of to notify the administrator if the user has to many tokens assigned.
counter
The counter condition can compare the value of any arbitrary event counter against a fixed value. Valid compares are:

myCounter == 1000
myCounter > 1000
myCounter < 1000

“myCounter” being any event counter set with the Counter Handler Module.

Note: A non-existing counter value will compare as 0 (zero).

1.8.5 Managing Events

Using the command pi-manage events you can list, delete, enable and disable events. You can also export the
complete event definitions to a file or import the event definitions from a file again. During import you can specify if
you want to remove all existing events or if you want to add the events from the file to the existing events in the database.

Note: Events are identified by an id! Due to database restrictions the id is ignored during import. So importing an
event with the same name will create a second event with the same name but another id.

186 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

1.8.6 Available Handler Modules

User Notification Handler Module

The user notification handler module is used to send emails token owners or administrators in case of any event.

Possible Actions

sendmail

The sendmail action sends an email to the specified email address each time the event handler is triggered.
emailconfig
• required Option
The email is sent via this SMTP server configuration.
To
• required Option
This specifies to which type of user the notification should be sent. Possible recipient types are:
• token owner,
• logged in user,
• admin realm,
• internal admin,
• email address.
Depending on the recipient type you can enter additional information. The recipient type email takes a comma separated
list of email addresses.
reply_to
Adds the specified Reply-To header to the email.
subject
The subject can take the same tags as the body, except for the {googleurl_img}.
mimetype
Possible mime types are:
• plain (default)
• html
You can choose if the email should be sent as plain text or HTML. If the email is sent as HTML, you can do the
following:

<a href={googleurl_value}>Your new token</a>

Which will create a clickable link. Clicked on the smartphone, the token will be imported to the smartphone app.
You can also do this:

<img src={googleurl_img}>

1.8. Event Handler 187


privacyIDEA Authentication System, Release 3.8

This will add the QR Code as an inline data image into the HTML email.

Warning: The KEY URI and the QR Code contain the secret OTP key in plain text. Everyone who receives this
data has a detailed copy of this token. Thus we very much recommend to never send these data in an unencrypted
email!

attach_qrcode
Instead of sending the QR-Code as an inline data image (which is not supported by some email clients (i.e. Outlook) or
GMail1 ), enabling this option sends the email as a multipart message with the QR-Code image as an attachment. The
attached image can be referenced in a HTML body via CID URL2 with the Content-ID token_image:

<img src="cid:token_image" alt="Token Image" style="..."/>

sendsms

The sendsms action sends an SMS to the specified number each time the event handler is triggered.
To
• required Option
Possible recipients are:
• tokenowner
smsconfig
• required Option
The SMS Gateway configuration for sending the notification.

savefile

The savefile action saves a file to a spool directory. Each time the event handler is triggered a new file is saved.
In the pi.cfg file you can use the setting PI_NOTIFICATION_HANDLER_SPOOLDIRECTORY to configure a spool
directory, where the notification files will be written. The default file location is /var/lib/privacyidea/
notifications/. The directory needs to be writable for the user privacyidea.
filename
• required option
• The filename of the saved file. It can contain the tag {random} which will create a 16 characters long alpha
numeric string. Thus you could have a filename like notification-{random}.csv.
In addition you can use all tags that can be used in the body also in the filename (some of them might not make a lot of
sense!).

Note: Existing files are overwritten.

1 https://stackoverflow.com/a/42014708/7036742
2 https://tools.ietf.org/html/rfc2392

188 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Body for all actions

All actions take the common option body:


body
• optional for sendmail and sendsms
• required for savefile
Here the administrator can specify the body of the notification, that is sent or saved. The body may contain the following
tags
• {admin} name of the logged in user.
• {realm} realm of the logged in user.
• {action} the action that the logged in user performed.
• {serial} the serial number of the token.
• {url} the URL of the privacyIDEA system.
• {user} the given name of the token owner.
• {givenname} the given name of the token owner.
• {surname} the surname of the token owner.
• {username} the loginname of the token owner.
• {userrealm} the realm of the token owner.
• {tokentype} the type of the token.
• {registrationcode} the registration code in the detail response.
• {recipient_givenname} the given name of the recipient.
• {recipient_surname} the surname of the recipient.
• {googleurl_value} is the KEY URI for a google authenticator.
• {googleurl_img} is the data image source of the google authenticator QR code.
• {time} the current server time in the format HH:MM:SS.
• {date} the current server date in the format YYYY-MM-DD
• {client_ip} the client IP of the client, which issued the original request.
• {ua_browser} the user agent of the client, which issued the original request.
• {ua_string} the complete user agent string (including version number), which issued the original request.
• {pin} the PIN of the token when set with /token/setrandompin. You can remove the PIN from the response
using the response mangler.

1.8. Event Handler 189


privacyIDEA Authentication System, Release 3.8

Code

This is the event handler module for user notifications. It can be bound to each event and can perform the action:
• sendmail: Send an email to the user/token owner
• sendsms: We can also notify the user with an SMS.
• savefile: Create a file which can be processed later
The module is tested in tests/test_lib_eventhandler_usernotification.py
class privacyidea.lib.eventhandler.usernotification.NOTIFY_TYPE
Allowed token owner
ADMIN_REALM = 'admin realm'
EMAIL = 'email'
INTERNAL_ADMIN = 'internal admin'
LOGGED_IN_USER = 'logged_in_user'
NO_REPLY_TO = ''
TOKENOWNER = 'tokenowner'
class privacyidea.lib.eventhandler.usernotification.UserNotificationEventHandler
An Eventhandler needs to return a list of actions, which it can handle.
It also returns a list of allowed action and conditions
It returns an identifier, which can be used in the eventhandling definitions
property actions
This method returns a dictionary of allowed actions and possible options in this handler module.
Returns dict with actions
property allowed_positions
This returns the allowed positions of the event handler definition. :return: list of allowed positions
description = 'This eventhandler notifies the user about actions on his tokens'
do(action, options=None)
This method executes the defined action in the given event.
Parameters
• action –
• options (dict) – Contains the flask parameters g, request, response and the handler_def
configuration
Returns
identifier = 'UserNotification'

190 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Token Handler Module

The token event handler module is used to perform actions on tokens in certain events.
This way you can define workflows to automatically modify tokens, delete or even create new tokens.

Possible Actions

set tokenrealm

Here you can set the token realms of the token.


E.g. You could use this action to automatically put all newly enrolled tokens into a special realm by attaching this
action to the event token_init.

delete

The token which was identified in the request will be deleted if all conditions are matched.

unassign

The token which was identified in the request will be unassign from the user if all conditions are matched.

disable

The token which was identified in the request will be disabled if all conditions are matched.

enable

The token which was identified in the request will be enabled if all conditions are matched.

enroll

If all conditions are matched a new token will be enrolled. This new token can be assigned to a user, which was
identified in the request.
The administrator can specify the tokentype and the realms of the new token. By default the generation of the token
will use the parameter genkey, to generate the otp key. (see Token endpoints).
The action enroll also can take the options dynamic_phone (in case of tokentype SMS) and dynamic_email (in case
of tokentype email). Then these tokens are created with a dynamic loadable phone number or email address, that is
read from the user store on each authentication request.
Finally the administrator can specify the option additional_params. This needs to be a dictionary with parameters,
that get passed to the init request. You can specify all parameters, that would be used in a /token/init request:
{“hashlib”: “sha256”, “type”: “totp”, “genkey”: 0, “otpkey”: “31323334”}

1.8. Event Handler 191


privacyIDEA Authentication System, Release 3.8

would create a TOTP token, that uses the SHA256 hashing algorithm instead of SHA1. genkey: 0 overrides the
default behaviour of generating an OTP secret. Instead the fixed OTP secret “31323334” (otpkey) is used.
If the tokentype is set to “email” or “sms”, you can also specify an SMTP server or SMS gateway configuration for the
token enrolled by selecting a configuration in the corresponding field (smtp_identifier or sms_identifier). If none is
selected, then the default system configuration will be used.

set description

If all conditions are matched the description of the token identified in the request will be set.
You can use the tag {current_time} or {now} to set the current timestamp. In addition you can append an offset
to current_time or now like {now}-12d or {now}+10m. This would write a timestamp which is 12 days in the past
or 10 minutes in the future. The plus or minus must follow without blank, allowed time identifiers are s (seconds), m
(minutes), h (hours) and d (days).
Other tags are {client_ip} for the client IP address and {ua_browser} and {ua_string} for information on the
user agent.

set validity

If all conditions are matched the validity period of the token will be set.
There are different possibilities to set the start and the end of the validity period. The event definition can either contain
a fixed date and time or if can contain a time offset.
Fixed Time
A fixed time can be specified in the following formats.
Only date without time:
• 2016/12/23
• 23.12.2016
Date with time:
• 2016/12/23 9:30am
• 2016/12/23 11:20:pm
• 23.12.2016 9:30
• 23.12.2016 23:20
Starting with version 2.19 we recommend setting the fixed time in the ISO 8601 corresponding time format
• 2016-12-23T15:30+0600
Time Offset
You can also specify a time offset. In this case the validity period will be set such many days after the event occurred.
This is indicated by using a “+” and a specifier for days (d), hours (h) and minutes (m).
E.g. +30m will set to start the validity period in 30 minutes after the event occurred.
+30d could set the validity period to end 30 days after an event occurred.

Note: This way you could easily define a event definition, which will set newly enrolled tokens to be only valid for a
certain amount of days.

192 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

set countwindow

Here the count window of a token can be set. This requires an integer value.

set tokeninfo

Using the action set tokeninfo you can set any arbitrary tokeninfo attribute for the token. You need to specify the
key of the tokeninfo and the value.
In the value field you can use the tag {current_time} to set the current timestamp. In addition you can append an
offset to current_time or now like {now}-12d or {now}+10m. This would write a timestamp which is 12 days in the
passt or 10 minutes in the future. The plus or minus must follow without blank, allowed time identifiers are s (seconds),
m (minutes), h (hours) and d (days).
Other tags are {client_ip} for the client IP address and {ua_browser} and {ua_string} for information on the
user agent and {username} and {realm} for information on the user in the parameters.

Note: Some tokens have token specific attributes that are stored in the tokeninfo. The TOTP token type has a
timeWindow. The TOTP and the HOTP token store the hashlib in the tokeninfo, the SMS token stores the phone
number.

Note: You can use this to set the timeWindow of a TOTP token for Automatic initial synchronization.

set failcounter

Using the action set failcounter you can reset the fail counter by setting it to 0 or also “block” the token by setting
the fail counter to what ever value the “max_fail” is, e.g. 10. Only integer values are allowed.
See Reset Fail Counter.

change failcounter

Using the action change failcounter you can increase or decrease the fail counter. Positive and negative integer
values are allowed. Positive values will increase the fail counter, negative values will decrease it.

Note: To limit a token handler in decreasing the fail counter, you may use the event handler condition failcounter (c.f.
Conditions) and set it to e.g. “>-5”. Once this condition is not met anymore, the event handler will not be triggered.

1.8. Event Handler 193


privacyIDEA Authentication System, Release 3.8

set max failcount

Using the action set max failcount you can set the maximum failcounter of a token to the specific value. Only
integer values are allowed.
See Reset Fail Counter.

set random pin

Sets a random PIN for the handled token. The PIN is then added to the response in detail->pin. This can be used
in the notification handler. Please take care, that probably the PIN needs to be removed from the response using the
response mangler handler after handling it with the notification handler.

add tokengroup

The token is assigned to the given tokengroup.

Note: A token can be assigned to several different tokengroups at the same time.

remove tokengroup

The token is unassigned from the given tokengroup.

Code

This is the event handler module for token actions. You can attach token actions like enable, disable, delete, unassign,. . .
of the
• current token
• all the user’s tokens
• all unassigned tokens
• all disabled tokens
• ...
class privacyidea.lib.eventhandler.tokenhandler.ACTION_TYPE
Allowed actions
ADD_TOKENGROUP = 'add tokengroup'
CHANGE_FAILCOUNTER = 'change failcounter'
DELETE = 'delete'
DELETE_TOKENINFO = 'delete tokeninfo'
DISABLE = 'disable'
ENABLE = 'enable'
INIT = 'enroll'
REMOVE_TOKENGROUP = 'remove tokengroup'

194 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

SET_COUNTWINDOW = 'set countwindow'


SET_DESCRIPTION = 'set description'
SET_FAILCOUNTER = 'set failcounter'
SET_MAXFAIL = 'set max failcount'
SET_RANDOM_PIN = 'set random pin'
SET_TOKENINFO = 'set tokeninfo'
SET_TOKENREALM = 'set tokenrealm'
SET_VALIDITY = 'set validity'
UNASSIGN = 'unassign'
class privacyidea.lib.eventhandler.tokenhandler.TokenEventHandler
An Eventhandler needs to return a list of actions, which it can handle.
It also returns a list of allowed action and conditions
It returns an identifier, which can be used in the eventhandlig definitions
property actions
This method returns a dictionary of allowed actions and possible options in this handler module.
Returns dict with actions
property allowed_positions
This returns the allowed positions of the event handler definition. :return: list of allowed positions
description = 'This event handler can trigger new actions on tokens.'
do(action, options=None)
This method executes the defined action in the given event.
Parameters
• action –
• options (dict) – Contains the flask parameters g, request, response and the handler_def
configuration
Returns
identifier = 'Token'
class privacyidea.lib.eventhandler.tokenhandler.VALIDITY
Allowed validity options
END = 'valid till'
START = 'valid from'

1.8. Event Handler 195


privacyIDEA Authentication System, Release 3.8

Script Handler Module

The script event handler module is used to trigger external scripts in case of certain events.
This way you can even add external actions to your workflows. You could trigger a database dump, an external printing
device, a backup and much more.

Possible Actions

The actions of the script event handler are the scripts located in a certain script directory. The default script directory
is /etc/privacyidea/scripts.
You can change the location of the script directory and give the new directory in the parameter
PI_SCRIPT_HANDLER_DIRECTORY in your pi.cfg file.

Possible Options

Options can be passed to the script. Your script has to take care of the parsing of these parameters.

logged_in_role

Add the role of the logged in user. This can be either admin or user. If there is no logged in user, none will be passed.
The script will be called with the parameter:

--logged_in_role <role>

logged_in_user

Add the logged in user. If there is no logged in user, none will be passed.
The script will be called with the parameter:

--logged_in_user <username>@<realm>

realm

Add --realm <realm> as script parameter. If no realm is given, none will be passed.

serial

Add --serial <serial number> as script parameter. If no serial number is given, none will be passed.

196 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

sync_to_database

Finish current transaction before running the script. This is useful if changes to the database should be made available
to the script or the running request.

user

Add --serial <username>' as script parameter. If no username is given, none will be passed.

Note: A possible script you could call is the privacyidea-get-unused-tokens.

Counter Handler Module

The counter event handler module is used to count certain events. You can define arbitrary counter names and each
occurrence of an event will modify the counter in the counter table according to the selected action.
These counters can be used to graph time series of failed authentication, assigned tokens, user numbers or any other
data with any condition over time.

Possible Actions

increase_counter

This action increases the counter in the database table eventcounter. If the counter does not exists, it will be created
and increased.

decrease_counter

This action decreases the counter in the database table eventcounter. If the counter does not exists, it will be created
and decreased.

Note: This action will not decrease the counter beyond zero unless the option allow_negative_values is
enabled.

reset_counter

This action resets the counter in the database table eventcounter to zero.

1.8. Event Handler 197


privacyIDEA Authentication System, Release 3.8

Possible Options

counter_name

This is the name of the counter in the database. You can have as many counters in as many event handlers as you like.

allow_negative_values

Only available for the decrease_counter action. Allows the counter to become negative. If set to False (de-
fault) decreasing stops at zero. .. note:: Since the option allow_negative_values is an attribute of the
counter event handler action (and not the counter itself in the database) it is possible to define multiple event
handler accessing the same counter. Thus if a negative counter is accessed by an event handler with the option
allow_negative_values set to true, the counter will be reset to zero

Federation Handler Module

The federation event handler can be used to configure relations between several privacyIDEA instances. Requests can
be forwarded to child privacyIDEA instances.

Note: The federation event handler can modify the original response. If the response was modified a new field origin
will be added to the detail section in the response. The origin will contain the URL of the privacyIDEA server that
finally handled the request.

Possible Actions

forward

A request (usually an authentication request validate_check) can be forwarded to another privacyIDEA instance. The
administrator can define privacyIDEA instances centrally at config -> privacyIDEA servers.
In addition to the privacyIDEA instance the action forward takes the following parameters:
client_ip The original client IP will be passed to the child privacyIDEA server. Otherwise the child privacyIDEA
server will use the parent privacyIDEA server as client.

Note: You need to configure the allow override client in the child privacyIDEA server.

realm The forwarding request will change the realm to the specified realm. This might be necessary since the
child privacyIDEA server could have different realms than the parent privacyIDEA server.
resolver The forwarding request will change the resolver to the specified resolver. This might be necessary since
the child privacyIDEA server could have different resolvers than the parent privacyIDEA server.
One simple possibility would be, that a user has a token in the parent privacyIDEA server and in the child privacyIDEA
server. Configuring a forward event handler on the parent with the condition result_value = False would have the
effect, that the user can either authenticate with the parent’s token or with the child’s token on the parent privacyIDEA
server.
Federation can be used, if privacyIDEA was introduced in a subdivision of a larger company. When privacyIDEA
should be enrolled to the complete company you can use federation. Instead of dropping the privacyIDEA instance

198 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

in the subdivision and installing on single central privacyIDEA, the subdivision can still go on using the original
privacyIDEA system (child) and the company will install a new top level privacyIDEA system (parent).
Using the federation handler you can setup many other, different scenarios we can not think of, yet.

Code

This is the event handler module for privacyIDEA federations. Requests can be forwarded to other privacyIDEA
servers.
class privacyidea.lib.eventhandler.federationhandler.ACTION_TYPE
Allowed actions
FORWARD = 'forward'
class privacyidea.lib.eventhandler.federationhandler.FederationEventHandler
An Eventhandler needs to return a list of actions, which it can handle.
It also returns a list of allowed action and conditions
It returns an identifier, which can be used in the eventhandling definitions
property actions
This method returns a dictionary of allowed actions and possible options in this handler module.
Returns dict with actions
description = 'This event handler can forward the request to other privacyIDEA
servers'
do(action, options=None)
This method executes the defined action in the given event.
Parameters
• action –
• options (dict) – Contains the flask parameters g, request, response and the handler_def
configuration
Returns
identifier = 'Federation'

RequestMangler Handler Module

The RequestMangler is a special handler module, that can modify the request parameters of an HTTP request. This
way privacyIDEA can change the data that is processed within the request.
Usually this handler is used in the pre location. However there might be occasions when you want to modify parameters
only before passing them to the next post handler. In this case you can also use the RequestMangler handler in the post
location.

1.8. Event Handler 199


privacyIDEA Authentication System, Release 3.8

Possible Actions

delete

This action simply deletes the given parameter from the request.
E.g. you could in certain cases delete the transaction_id from a /validate/check request. This way you would
render challenge response inactive.

set

This action is used to add or modify additional request parameters.


You can set a parameter with the value or substrings of another parameter.
This is why this action takes the additional options value, match_parameter and match_pattern. match_pattern always
needs to match the complete value of the match_parameter.
If you simply want to set a parameter to a fixed value you only need the options:
• parameter: as the name of the parameter you want to set and
• value: to set to a fixed value.
If you can to set a parameter based on the value of another parameter, you can use the regex notation () and the python
string formatting tags {0}, {1}.
Example 1
To set the realm based on the username parameter:

parameter: realm
match_parameter: username
match_pattern: .*@(.*)
value: {0}

A request like:

[email protected]
realm=

with an empty realm will be modified to:

[email protected]
realm=example.com

since, the pattern .*@(.*) will match the email address and extract the domain after the “@” sign. The python tag
“{0}” will be replaced with the matching domainname.
Example 2
To simply change the domain name in the very same parameter:

parameter: username
match_parameter: username
match_pattern: (.*)@example.com
value: {0}@newcompany.com

A request like:

200 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

[email protected]

will be modified to:

[email protected]

Note: The match_pattern in the above example will not match “[email protected]”, since it
always matches the complete value as mentioned above.

Code

This is the event handler module modifying request parameters.


class privacyidea.lib.eventhandler.requestmangler.ACTION_TYPE
Allowed actions
DELETE = 'delete'
SET = 'set'
class privacyidea.lib.eventhandler.requestmangler.RequestManglerEventHandler
An Eventhandler needs to return a list of actions, which it can handle.
It also returns a list of allowed action and conditions
It returns an identifier, which can be used in the eventhandlig definitions
property actions
This method returns a dictionary of allowed actions and possible options in this handler module.
Returns dict with actions
property allowed_positions
This returns the allowed positions of the event handler definition. :return: list of allowed positions
description = 'This event handler can modify the parameters in the request.'
do(action, options=None)
This method executes the defined action in the given event.
Parameters
• action –
• options (dict) – Contains the flask parameters g, request, response and the handler_def
configuration
Returns
identifier = 'RequestMangler'

1.8. Event Handler 201


privacyIDEA Authentication System, Release 3.8

ResponseMangler Handler Module

The ResponseMangler is a special handler module, that can modify the response of an HTTP request. This way priva-
cyIDEA can change the data sent back to the client, depending on certain conditions.
All actions take a JSON pointer, which looks like a path variable like /result/value.

Possible Actions

delete

This action simply deletes the given JSON pointer from the response.

Note: All keys underneath a node are deleted as well. So if the event handler deletes /detail, the entries /detail/
message and /detail/error will also be deleted.

Example
You can use this to delete /detail/googleurl, /detail/oathurl and /detail/otpkey in a /token/init event
to hide the created QR code from the helpdesk admin. This way the QR code could be used internally, but could be
hidden from the administrator.

set

This action is used to add additional pointers to the JSON response or to modify existing entries. Existing entries are
overwritten.
This action takes the additional attributes type and value.
The value can be returned as a string, an integer or a boolean.

Code

This is the event handler module that can mangle the JSON response. We can add or delete key or even subtrees in the
JSON response of a request.
The key is identified by a JSON Pointer (see https://tools.ietf.org/html/rfc6901)
class privacyidea.lib.eventhandler.responsemangler.ACTION_TYPE
Allowed actions
DELETE = 'delete'
SET = 'set'
class privacyidea.lib.eventhandler.responsemangler.ResponseManglerEventHandler
An Eventhandler needs to return a list of actions, which it can handle.
It also returns a list of allowed action and conditions
It returns an identifier, which can be used in the eventhandlig definitions
property actions
This method returns a dictionary of allowed actions and possible options in this handler module.
Returns dict with actions

202 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

property allowed_positions
This returns the allowed positions of the event handler definition. The ResponseMangler can only be located
at the “post” position
Returns list of allowed positions
description = 'This event handler can mangle the JSON response.'
do(action, options=None)
This method executes the defined action in the given event.
Parameters
• action –
• options (dict) – Contains the flask parameters g, request, response and the handler_def
configuration
Returns
identifier = 'ResponseMangler'

Logging Handler Module

The logging event handler can be used to log the occurrence of an event to the python logging facility. You can log
arbitrary events with a configurable log message, loglevel and logger instance. Several tags are available to customize
the log message.
The configuration to handle the log messages can be defined in detail with the Advanced Logging.

Possible Actions

logging

Emit a log message to the python logging facility when the specified event gets triggered (and the conditions match).
name
• default: pi-eventlogger
The name of the logger to use when emitting the log message. This can be used for a fine-grained control of the log
messages via Advanced Logging.

Note: Logger names beginning with privacyidea will be handled by the default privacyIDEA logger and will end
up in the privacyIDEA log.

level
• default: INFO
The log level for the emitted log message. The following levels are available:
• ERROR
• WARNING
• INFO
• DEBUG

1.8. Event Handler 203


privacyIDEA Authentication System, Release 3.8

message
• default: "event={action} triggered"
The message to send to the logging facility. This message can be customized with the following tags:
• {admin} The logged in user.
• {realm} The realm of the logged in user.
• {action} The action which triggered this event.
• {serial} The serial of a token used in this event.
• {url} The URL of the privacyIDEA system.
• {user} The given name of the token owner.
• {surname} The surname of the token owner.
• {givenname} The given name of the token owner.
• {username} The login of the token owner.
• {userrealm} The realm of the token owner.
• {tokentype} The type of the token.
• {time} The current server time (format: HH:MM:SS).
• {date} The current server date (format: YYYY-MM-DD).
• {client_ip} The IP of the client who triggered the event.
• {ua_browser} The user agent of the client, which issued the original request.
• {ua_string} The complete user agent string (including version number) which issued the original request.

Note: Not all tags are available in every event. It depends on the called API-Endpoint and passed parameter which
tags exist. If a tag does not exist during the event handling, an empty string will be inserted.

Custom User Attribute Handler Module

The custom user attribute handler module allows the administrator to set or delete custom user attributes automatically.
A specific event can thus set or delete a custom user attribute without any further intervention of the administrator or
helpdesk. To learn more about custom user attributes please check out Additional user attributes

Note: This event handler can also set attributes that can’t be set or deleted manually by the administrator or the
helpdesk users.

204 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Possible Actions

set_custom_user_attributes

This action sets a custom user attribute on a certain event.


The action takes the options attrkey, attrvalue and user.
attrkey and attrvalue can take fixed values. The custom user attribute with the name from attrkey will then be set
to the value of attrvalue.
With the user option, the custom user attribute can either be set for the acting, logged in user or for the user on whom
the administrator is acting on.
For example if a user failed to login too many times, the eventhandler can automatically set the custom attribute “this
user has login problems”.

delete_custom_user_attributes

This action deletes a custom user attribute on a certain event.


This event handler action takes the options attrkey and user as described above.
For example you could set a custom user attribute on the token enrollment process, that indicates, that this is a new
user and set a custom user attribute to “new user”. On the first successful login this custom user attribute could be
automatically deleted using this event handler action.

1.9 Periodic Tasks

Starting with version 2.23, privacyIDEA comes with the ability to define periodically recurring tasks in the Web UI.
The purpose of such tasks is to periodically execute certain processes automatically. The administrator defines which
tasks should be executed using task modules. Currently there are task modules for simple statistics and for handling
recorded events. Further task modules can be added easily.
As privacyIDEA is a web application, it can not actually execute the defined periodic tasks itself. For that, privacyIDEA
comes with a script privacyidea-cron which must be invoked by the system cron daemon. This can, for example,
be achieved by creating a file /etc/cron.d/privacyidea with the following contents (this is done automatically by
the Ubuntu package):

*/5 * * * * privacyidea privacyidea-cron run_scheduled -c

This tells the system cron daemon to invoke the privacyidea-cron script every five minutes. At each invocation, the
privacyidea-cron script determines which tasks should be executed and execute the scheduled tasks. The -c option
tells the script to be quiet and only print to stderr in case of an error (see The privacyidea-cron script).
Periodic tasks can be managed in the WebUI by navigating to Config->Periodic Tasks:
Every periodic task has the following attributes:
description A human-readable, unique identifier
active A boolean flag determining whether the periodic task should be run or not.
order A number (at least zero) that can be used to rearrange the order of periodic tasks. This is used by
privacyidea-cron to determine the running order of tasks if multiple periodic tasks are scheduled to be run.
Tasks with a lower number are run first.

1.9. Periodic Tasks 205


privacyIDEA Authentication System, Release 3.8

Fig. 62: Periodic task definitions

interval The periodicity of the task. This uses crontab notation, e.g. */30 * * * * runs the task every 30 minutes.
Keep in mind that the entry in the system crontab determines the minimal resolution of periodic tasks: If you
specify a periodic task that should be run every two minutes, but the privacyidea-cron script is invoked every
five minutes only, the periodic task will actually be executed every five minutes!
nodes The names of the privacyIDEA nodes on which the periodic task should be executed. This is useful in a redun-
dant master-master setup, because database-related tasks should then only be run on one of the nodes (because
the replication will take care of propagating the database changes to the other node). The name of the local node
as well as the names of remote nodes are configured in The Config File.
taskmodule The task module determines the actual activity of the task. privacyIDEA comes with several task modules,
see Task Modules.
options The options are a set of key-value pairs that configure the behavior of the task module. Each task module can
have it’s own allowed options.

1.9.1 Task Modules

privacyIDEA comes with the following task modules:

SimpleStats

The SimpleStats task module is a Periodic Tasks to collect some basic statistics from the token database and write
them to the time series database table MonitoringStats.

Options

The SimpleStats task module provides the following boolean options:


total_tokens
If activated, the total number of tokens in the token database will be monitored.
hardware_tokens
If activated, the total number of hardware tokens in the token database will be monitored.
software_tokens
If activated, the total number of software tokens in the token database will be monitored.
unassigned_hardware_tokens

206 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

If activated, the number of hardware tokens in the token database which are not assigned to a user will be
monitored.
assigned_tokens
If activated, the number of tokens in the token database which are assigned to users will be monitored.
user_with_token
If activated, the number of users which have at least one token assigned will be monitored.

Note: The statistics key, with which the time series is identified in the MonitoringStats table, is the same as the
option name.
Using a statistic with the same key in a different module, which writes to the MonitoringStats table, will corrupt
the data.

Note: For each of these basic statistic values the token database will be queried. To avoid excessive load on the
database, the SimpleStats task should not be executed too often.

EventCounter

The Event Counter task module can be used with the Periodic Tasks to create time series of certain events. An event
could be a failed authentication request. Using the Event Counter, privacyIDEA can create graphs that display the
development of failed authentication requests over time.
To do this, the Event Counter task module reads a counter value from the database table EventCounter and adds this
current value in a time series in the database table MonitoringStats. As the administrator can use the event handler
Counter Handler Module to record any arbitrary event under any condition, this task module can be used to graph any
metrics in privacyIDEA, be it failed authentication requests per time unit, the number of token delete requests or the
number of PIN resets per month.

Options

The Event Counter task module provides the following options:


event_counter
This is the name of the event counter key, that was defined in a Counter Handler Module definition and
that is read from the database table EventCounter.
stats_key
This is the name of the statistics key that is written to the MonitoringStats database table. The event
counter key stores the current number of counted events, the stats_key takes the current number and
stores it with the timestamp as a time series.
reset_event_counter
This is a boolean value. If it is set to true (the checkbox is checked), then the event counter will be reset to
zero, after the task module has read the key.
Resetting the the event counter results in a time series of “events per time interval”. The time interval is
specified by the time interval in which the Event Counter task module is called. If reset_event_counter
is not checked, then the event handler will continue to increase the counter value. Use this, if you want to
create a time series, that displays the absolute number of events.

1.9. Periodic Tasks 207


privacyIDEA Authentication System, Release 3.8

1.9.2 The privacyidea-cron script

The privacyidea-cron script is used to execute periodic tasks defined in the Web UI. The run_scheduled command
collects all active jobs that are scheduled to run on the current node and executes them. The order is determined by
their ordering values (tasks with low values are executed first). The -c option causes the script to is useful if the
script is executed via the system crontab, as it causes the script to only print to stderr in case of errors.
The list command can be used to get an overview of defined jobs, and the run_manually command can be used to
manually invoke tasks even though they are not scheduled to be run.

1.10 Audit

The systems provides a sophisticated audit log, that can be viewed in the WebUI.

Fig. 63: Audit Log

privacyIDEA comes with a default SQL audit module (see Audit log).
Starting with version 3.2 privacyIDEA also provides a Logger Audit and a Container Audit which can be used to send
privacyIDEA audit log messages to services like splunk or logstash.

1.10.1 SQL Audit

Cleaning up entries

The sqlaudit module writes audit entries to an SQL database. For performance reasons the audit module does no log
rotation during the logging process.
But you can set up a cron job to clean up old audit entries. Since version 2.19 audit entries can be either cleaned up
based on the number of entries or based on on the age. Cleaning based on the age takes precedence.

208 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Cleaning based on the number of entries:

You can specify a highwatermark and a lowwatermark. To clean up the audit log table, you can call pi-manage at
command line:

pi-manage rotate_audit --highwatermark 20000 --lowwatermark 18000

This will, if there are more than 20.000 log entries, clean all old log entries, so that only 18000 log entries remain.

Cleaning based on the age:

You can specify the number of days, how old an audit entry may be at a max:

pi-manage rotate_audit --age 365

will delete all audit entries that are older than one year.

Cleaning based on the config file:

Using a config file you can define different retention times for the audit data. E.g. this way you can define, that audit
entries about token listings can be deleted after one month, while the audit information about token creation will only
deleted after ten years.
The config file is a YAML format and looks like this:

# DELETE auth requests of nils after 10 days


- rotate: 10
user: nils
action: .*/validate/check.*

# DELETE auth requests of friedrich after 7 days


- rotate: 7
user: friedrich
action: .*/validate/check.*

# Delete nagios user test auth directly


- rotate: 0
user: nagiosuser
action: POST /validate/check.*

# Delete token listing after one month


- rotate: 30
action: ^GET /token

# Delete audit logs for token creating after 10 years


- rotate: 3650
action: POST /token/init

# Delete everything else after 6 months


- rotate: 180
action: .*

1.10. Audit 209


privacyIDEA Authentication System, Release 3.8

This is a list of rules. privacyIDEA iterates over all audit entries. The first matching rule for an entry wins. If the rule
matches, the audit entry is deleted if the entry is older than the days specified in “rotate”.
If is a good idea to have a catch-all rule at the end.

Note: The keys “user”, “action”. . . correspond to the column names of the audit table. You can use any column name
here like “date”, “action”, “action_detail”, “success”, “serial”, “administrator”, “user”, “realm”. . . for a complete list
see the model definition. You may use Python regular expressions for matching.

You can the add a call like:

pi-manage rotate_audit --config /etc/privacyidea/audit.yaml

in your crontab.

Access rights

You may also want to run the cron job with reduced rights. I.e. a user who has no read access to the original pi.cfg file,
since this job does not need read access to the SECRET or PEPPER in the pi.cfg file.
So you can simply specify a config file with only the content:

PI_AUDIT_SQL_URI = <your database uri>

Then you can call pi-manage like this:

PRIVACYIDEA_CONFIGFILE=/home/cornelius/src/privacyidea/audit.cfg \
pi-manage rotate_audit

This will read the configuration (only the database uri) from the config file audit.cfg.

Table size

Sometimes the entries to be written to the database may be longer than the column in the database. You should set:

PI_AUDIT_SQL_TRUNCATE = True

in pi.cfg. This will truncate each entry to the defined column length.
However, if you sill want to fetch more information in the audit log, you can increase the column length directly in
the database by the usual database means. However, privacyIDEA does not know about this, and will still truncate the
entries to the originally defined length.
To avoid this, you need to tell privacyIDEA about the changes. In Your config file add the setting like:

PI_AUDIT_SQL_COLUMN_LENGTH = {"user": 100,


"policies": 1000}

which will increase truncation of the user column to 100 and the policies column to 1000. Check the database schema
for the available columns.

210 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

1.10.2 Logger Audit

The Logger Audit module can be used to write audit log information to the Python logging facility and thus write log
messages to a plain file, a syslog daemon, an email address or any destination that is supported by the Python logging
mechanism. The log message passed to the python logging facility is a JSON-encoded string of the fields of the audit
entry.
You can find more information about this in Advanced Logging.
To activate the Logger Audit module you need to configure the following settings in your pi.cfg file:

PI_AUDIT_MODULE = "privacyidea.lib.auditmodules.loggeraudit"
PI_AUDIT_SERVERNAME = "your choice"
PI_LOGCONFIG = "/etc/privacyidea/logging.cfg"

You can optionally set a custom logging name for the logger audit with:

PI_AUDIT_LOGGER_QUALNAME = "pi-audit"

It defaults to the module name privacyidea.lib.auditmodules.loggeraudit. In contrast to the SQL Audit you
need a PI_LOGCONFIG otherwise the Logger Audit will not work correctly.
In the logging.cfg you then need to define the audit logger:

[logger_audit]
handlers=audit
qualname=privacyidea.lib.auditmodules.loggeraudit
level=INFO

[handler_audit]
class=logging.handlers.RotatingFileHandler
backupCount=14
maxBytes=10000000
formatter=detail
level=INFO
args=('/var/log/privacyidea/audit.log',)

Note, that the level always needs to be INFO. In this example the audit log will be written to the file /var/log/
privacyidea/audit.log.
Finally you need to extend the following settings with the defined audit logger and audit handler:

[handlers]
keys=file,audit

[loggers]
keys=root,privacyidea,audit

Note: The Logger Audit only allows to write audit information. It can not be used to read data. So if you are only
using the Audit Logger, you will not be able to view audit information in the privacyIDEA Web UI! To still be able to
read audit information, take a look at the Container Audit.

Note: The policies auth_max_success and auth_max_fail depend on reading the audit log. If you use a non readable

1.10. Audit 211


privacyIDEA Authentication System, Release 3.8

audit log like the Logger Audit these policies will not work.

1.10.3 Container Audit

The Container Audit module is a meta audit module, that can be used to write audit information to more than one audit
module.
It is configured in the pi.cfg like this:

PI_AUDIT_MODULE = 'privacyidea.lib.auditmodules.containeraudit'
PI_AUDIT_CONTAINER_WRITE = ['privacyidea.lib.auditmodules.sqlaudit','privacyidea.lib.
˓→auditmodules.loggeraudit']

PI_AUDIT_CONTAINER_READ = 'privacyidea.lib.auditmodules.sqlaudit'

The key PI_AUDIT_CONTAINER_WRITE contains a list of audit modules, to which the audit information should be
written. The listed audit modules need to be configured as mentioned in the corresponding audit module description.
The key PI_AUDIT_CONTAINER_READ contains one single audit module, that is capable of reading information. In this
case the SQL Audit module can be used. The Logger Audit module can not be used for reading!
Using the Container Audit module you can on the one hand send audit information to external services using the Logger
Audit but also keep the audit information visible within privacyIDEA using the SQL Audit module.

1.11 Machines

privacyIDEA lets you define Machine Resolvers to connect to existing machine stores. The idea is for users to be
able to authenticate on those client machines. Not in all cases an online authentication request is possible, so that
authentication items can be passed to those client machines.
In addition you need to define, which application on the client machine the user should authenticate to. Different
application require different authentication items.
Therefore privacyIDEA can define application types. At the moment privacyIDEA knows the application luks,
offline and ssh. You can write your own application class, which is defined in Application Class.
You need to assign an application and a token to a client machine. Each application type can work with certain token
types and each application type can use additional parameters.

Note: Not all tokens work well with all applications!

1.11.1 SSH

Currently working token types: SSH


Parameters:
user (optional, default=root)
When the SSH token type is assigned to a client, the user specified in the user parameter can login with the private key
of the SSH token.
In the sshd_config file you need to configure the AuthorizedKeysCommand. Set it to:

212 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

privacyidea-authorizedkeys

This will fetch the SSH public keys for the requesting machine.
The command expects a configuration file /etc/privacyidea/authorizedkeyscommand which looks like this:

[Default]
url=https://localhost
admin=admin
password=test
nosslcheck=False

Note: To disable a SSH key for all servers, you simple can disable the SSH token in privacyIDEA.

Warning: In a productive environment you should not set nosslcheck to true, otherwise you are vulnerable to
man in the middle attacks.

1.11.2 LUKS

Currently working token types: Yubikey Challenge Response


Parameters:
slot The slot to which the authentication information should be written
partition The encrypted partition (usually /dev/sda3 or /dev/sda5)
These authentication items need to be pulled on the client machine from the privacyIDEA server.
Thus, the following script need to be executed with root rights (able to write to LUKS) on the client machine:

privacyidea-luks-assign @secrets.txt --clearslot --name salt-minion

For more information please see the man page of this tool.

1.11.3 Offline

Currently working token types: HOTP.


Parameters:
user The local user, who should authenticate. (Only needed when calling machine/get_auth_items)
count The number of OTP values passed to the client.
The offline application also triggers when the client calls a /validate/check. If the user authenticates successfully with
the correct token (serial number) and this very token is attached to the machine with an offline application the response
to validate/check is enriched with a “auth_items” tree containing the salted SHA512 hashes of the next OTP values.
The client can cache these values to enable offline authentication. The caching is implemented in the privacyIDEA
PAM module.
The server increases the counter to the last offline cached OTP value, so that it will not be possible to authenticate with
those OTP values available offline on the client side.

1.11. Machines 213


privacyIDEA Authentication System, Release 3.8

1.12 Workflows and Tools

This section describes workflows and tools.

1.12.1 Import

Seed files that contain the secret keys of hardware tokens can be imported to the system via the menu Import.
The default import options are to import SafeNet XML file, OATH CSV files, Yubikey CSV files or PSKC files.

GPG Encryption

Starting with privacyIDEA 2.14 you can import GPG encrypted seed files. All files mentioned below can be encrypted
this way.
privacyIDEA needs its own GPG key. You may create one like this:

mkdir /etc/privacyidea/gpg
GNUPGHOME=/etc/privacyidea/gpg gpg --gen-key

Then make sure, that the directory /etc/privacyidea/gpg is chown 700 for the user privacyidea.
Now you can export the public key and hand it to your token vendor:

GNUPGHOME=/etc/privacyidea/gpg gpg -a --export <keyid>

Now the token vendor can send the seed file GPG encrypted. You do not need to decrypt the file and store the decrypted
file on a network folder. Just import the GPG encrypted file to privacyIDEA!

Note: Using the key PI_GNUPG_HOME in pi.cfg you can change the default above mentioned GNUPGHOME
directory.

Note: privacyIDEA imports an ASCII armored file. The file needs to be encrypted like this:
gpg -e -a -r <keyid> import.csv

OATH CSV

This is a very simple CSV file to import HOTP, TOTP or OATH tokens. You can also convert your seed easily to this
file format, to import the tokens.
The file format for TOTP tokens looks like this:

<serial>, <seed>, TOTP, <otp length>, <time step>

For HOTP tokens like:

<serial>, <seed>, [HOTP, <otp length>, <counter>]

For OCRA tokens it looks like this:

214 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

<serial>, <seed>, OCRA, <ocra suite>

serial is the serial number of the token that will also be used to identify the token in the database. Importing the same
serial number twice will overwrite the token data.
seed is the secret key, that is used to calculate the OTP value. The seed is provided in a hexadecimal notation. Depending
on the length either the SHA1 or SHA256 hash algorithm is identified.
type is either HOTP, TOTP or OCRA.
otp length is the length of the OTP value generated by the token. This is usually 6 or 8.
time step is the time step of TOTP tokens. This is usually 30 or 60.
ocra suite is the ocra suite of the OCRA token according to1 .
For TAN tokens it looks like this:

<serial>, <n/a>, TAN, <list of tans>

The list of tans is a whitespace separated list.

Note: The Hash algorithm (SHA1, SHA256, SHA512) is derived from the length of the seed. If the length of the
seed does not match any Hash algorithm, the default SHA1 is used.

Import format version 2

A new import format allows to prepend a user, to whom the imported token should be assigned.
The file format needs to start with the first line
# version: 2
and the first three colums will be the user:
<username>, <resolver>, <realm>, <serial>, <seed>, <type>, . . .

Note: The import will bail out, if a specified user does not exist.

Yubikey CSV

Here you can import the CSV file that is written by the Yubikey Personalization GUI 2 . privacyIDEA can import all
Yubikey modes, either Yubico mode or HOTP mode.

Note: The Yubikey in HOTP mode defaults to the Hash algorithm SHA1.

For more information about enrolling Yubikeys see Yubikey Enrollment Tools.
1 http://tools.ietf.org/html/rfc6287#section-6
2 http://www.yubico.com/products/services-software/personalization-tools/use/

1.12. Workflows and Tools 215


privacyIDEA Authentication System, Release 3.8

PSKC

The Portable Symmetric Key Container is specified in3 . OATH compliant token vendors provide the token seeds in a
PSKC file. privacyIDEA lets you import PSKC files. All necessary information (OTP length, Hash algorithm, token
type) are read from the file.

Note: In PSKC the Hash algorithm is specified in the <Suite> tag. If it is not specified, SHA1 is used as the default.
The length of the seed is not used to determine the Hash algorithm.

PSKC files can be encrypted - either with a password or an AES key. You can provide this during the upload.

SafeNet XML

Safenet or former Aladdin provided seed files in their own XML format. This is the format to choose, if you have a
file, that looks like this:

<Tokens>
<Token serial="00040008CFA5">
<CaseModel>5</CaseModel>
<Model>101</Model>
<ProductionDate>02/19/2009</ProductionDate>
<ProductName>Safeword Alpine</ProductName>
<Applications>
(continues on next page)
3 https://tools.ietf.org/html/rfc6030

216 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

(continued from previous page)


<Application ConnectorID="{ab1397d2-ddb6-4705-b66e-9f83f322deb9}">
<Seed>123412354</Seed>
<MovingFactor>1</MovingFactor>
</Application>
</Applications>
</Token>

<Token ...>
...
</Token>
</Tokens>

Note: The HASH algorithm defaults to SHA1. Unless the length of the seed is 64 characters, then SHA256 is assumed.

Note: This format is deprecated. Safenet nowadays might provide you an XML file, which is probably a PKCS file.
Please check the file contents!

1.12.2 Token Enrollment Wizard

The enrollment wizard helps the user to enroll his first token. When enrolling the first token, we assume, that the user
is not very familiar with the privacyIDEA web UI. So the enrollment wizard only contains a very reduced API.

Necessary requirements for the enrollment wizard

• The enrollment wizard will only be displayed, if the user has no token assigned, yet. Thus the user must be able
to login to the web UI with his userstore password. This is the default behaviour or set the corresponding policy.
• Set a policy in scope webui and activate the policy action tokenwizard.
• The user will not be able to choose a token type. But the default token type will be enrolled.
You can see the token enrollment wizard in action here: https://www.youtube.com/watch?v=diAGbsiG8_A

Customization

There are two dialog windows in the wizard. You can configure the text in the wizard in your html templates defined
in these files:
Before the token is enrolled you can add your custom text in these two files:

static/customize/views/includes/token.enroll.pre.top.html
static/customize/views/includes/token.enroll.pre.bottom.html

When it is enrolled and the user needs to do something (e.g. scanning the qr-code), you can modify the text here:

static/customize/views/includes/token.enroll.post.top.html
static/customize/views/includes/token.enroll.post.bottom.html

1.12. Workflows and Tools 217


privacyIDEA Authentication System, Release 3.8

Note: You can change the directory static/customize to a URL that fits your needs the best by defining a variable
PI_CUSTOMIZATION in the file pi.cfg. This way you can put all modifications in one place apart from the original
code.

Example

Your privacyIDEA system is running in the URL sub path /pi. The files could be addressed via a path component
mydesign (in this case pi/mydesign). Thus the WebUI will look for the files in the URL path /pi/mydesign/
views/includes/.
So you set in pi.cfg:

PI_CUSTOMIZATION = "/mydesign"

Your customized files are located in /etc/privacyidea/customize/views/includes/. In the Apache webserver


you need to map /pi/mydesign to /etc/privacyidea/customize:

Alias /pi/mydesign /etc/privacyidea/customize

1.12.3 Enrollment Tools

This section describes the usage of several software tools to facilitate and automate token enrollment with privacyIDEA.
This is especially important for hardware tokens whose secrets have to be brought to the system.

Yubikey Enrollment Tools

The Yubikey can be used with privacyIDEA in Yubico’s own AES mode (Yubico OTP), in the HOTP mode (OATH-
HOTP) or the seldom used static password mode.
This section describes tools which can be used to initialize and enroll a Yubikey with privacyIDEA.
If not using the Yubico mode, the Yubikey has to be initialized/configured which creates a new secret on the device that
has to be imported to privacyIDEA.
privacyIDEA ships tools to (mass-)enroll Yubikeys in AES mode (Yubikey Token) or HOTP mode (HOTP Token).

privacyidea CLI tool

For Linux Clients, there is the privacyidea command line client1 , to initialize the Yubikeys. You can use the mass
enrollment, which eases the process of initializing a whole bunch of tokens.
Run the command like this:

privacyidea -U https://your.privacyidea.server -a admin token \


yubikey_mass_enroll --yubimode YUBICO

This command initializes the device and creates a new token with the AES secret and prefix in privacyIDEA. You can
enroll Yubikeys in HOTP mode by using the option --yubimode HOTP which is also the default. You can choose
1 https://github.com/privacyidea/privacyideaadm/

218 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

the slot with --yubislot. For further help call privacyidea yubikey_mass_enroll with the --help option and
refer to the documentation of the tool2 .
You can also use yubikey_mass_enroll with the option --filename to write the token configuration to the specified
file, which can be imported later via the privacyIDEA WebUI at Select Tokens -> Import Tokens. There, select OATH
CSV and the file you just created.

Yubikey Personalization GUI

You can also initialize the Yubikey with the official Yubico personalization GUI3 and use the obtained secret to enroll
the Yubikey with privacyIDEA. For both AES (Yubico OTP) and OATH-HOTP mode, there are two possibilities to
initialize the Yubikey with privacyIDEA.

Manual token enrollment

To initialize a single Yubikey in AES mode (Yubico OTP) use the Quick button and copy the displayed secret labeled
with “Secret Key (16 bytes Hex)” to the field OTP Key on the enrollment form in the privacyIDEA WebUI.

Fig. 64: Initialize a Yubikey in AES mode (Yubikey OTP)

In the field “Test Yubikey” touch the Yubikey button. This will determine the length of the OTP value and the field
OTP length is automatically filled.

Note: The length of the unique passcode for each OTP is 32 characters at the end of the OTP value. The remaining
characters at the beginning of the OTP value form the Public ID of the device. They remain constant for each OTP4 .
privacyIDEA takes care of separating these parts but it needs to know the complete length of the OTP value to work
correctly.

2 https://github.com/privacyidea/privacyideaadm/blob/master/doc/index.rst
3 https://www.yubico.com/products/services-software/download/yubikey-personalization-tools/
4 https://developers.yubico.com/OTP/OTPs_Explained.html

1.12. Workflows and Tools 219


privacyIDEA Authentication System, Release 3.8

Fig. 65: Enroll a Yubikey AES mode token in privacyIDEA

The process is similar for the HOTP mode. You have to deselect OATH Token Identifier. Copy the displayed secret to
the HOTP Enrollment form in privacyIDEA.

Fig. 66: To initialize a single Yubikey in HOTP mode, deselect OATH Token Identifier.

Note: In the case of HOTP mode privacyIDEA can not necessarily distinguish a Yubikey in HOTP mode from a
smartphone App in HOTP mode. Using the above mentioned mass-enrollment, the token serial number is used to
distinguish these tokens.

220 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Mass enrollment

To initialize one or more Yubikeys it is convenient to write the created token secrets to a file which can be imported in
the privacyIDEA WebUI. To do this, activate Settings -> Log configuration output. We recommend to select Yubico
format since here privacyIDEA is able to detect the Yubikey mode and sets the serial accordingly prepending UBOM
or UBAM. PSKC format is also supported upon import. You may also use the Flexible format to set custom token
serials upon import with OATH CSV .
To set a custom serial for Yubikey Tokens, set the Flexible format to:

YUBIAES{serial}_{configSlot},{secretKeyTxt},yubikey

For Yubikeys in HOTP mode, set the output format as:

YUBIHOTP{serial}_{configSlot},{secretKeyTxt},hotp,{hotpDigits}

Upon clicking Write Configuration for the first time, you will be prompted to select an output file name and the generated
configuration is written both to the device and to the selected file. In the Advanced mode select Program Multiple
Yubikeys and Automatically program Yubikeys when inserted to program each Yubikey automatically after you insert
it.

Fig. 67: Write Configuration initializes the Yubikey

1.12. Workflows and Tools 221


privacyIDEA Authentication System, Release 3.8

During this process the token secrets are automatically appended to the selected export file. Note again, that for HOTP,
you have to deselect OATH Token Identifier.
After mass-initialization, the token secrets have to be imported to privacyIDEA according to the output format (see
Import).

1.12.4 Tools

privacyIDEA comes with a list of command line tools, which also help to automate tasks. The tools can be found in
the directory privacyidea/bin.

privacyidea-token-janitor

Starting with version 2.19 privacyIDEA comes with a token janitor script. This script can find orphaned tokens, unused
tokens or tokens of specific type, description or token info.
It can unassign, delete or disable those tokens, it can set additional tokeninfo or descriptions and perform other tasks
on the found tokens.
Starting with version 3.4 it can also set the tokenrealms of the found tokens.
If you are unsure to directly delete orphaned tokens, because there might be a glimpse in the connection to your user
store, you could as well in a first step mark the orphaned tokens. A day later you could run the script again and delete
those tokens, which are (still) orphaned and marked.
With version 3.7 it can also filter for token attributes and attribute values. It is also possible to check just for the
existence or not-existence of a certain tokeninfo-value.

Find

With the token-janitor you have the possibility to search for tokens in different ways. You can find tokens by providing
filter parameters. Note, that you can combine as many filter parameters as you want to. This way you can reduce the
set of found tokens. Several filter parameters allow to search with regular expressions.
Actions will then be performed only on this reduced set.
These are important filter parameters:

Orphaned

Searches for tokens, that are orphaned. Orphaned tokens are assigned to a user. But the user does not exist in the user
store anymore. This can happen e.g. if an LDAP user gets deleted in the LDAP directory.
Example:

privacyidea-token-janitor find --orphaned 1

This returns all orphaned tokens for later processing.

222 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Active

Searches for tokens that are either active or inactive, this means enabled or disabled.
Example:

privacyidea-token-janitor find --active False

This returns all disabled tokens. May you later want to delete these disabled tokens.

Assigned

Searches for tokens that are either assigned to a user or unassigned.


Example:

privacyidea-token-janitor find --assigned False

This returns all tokens, that are not assigned to a user. You could combine this with other filters like the tokenkind to
find out how many hardware tokens are not assigned and still available for assignment.

Last_auth

Searches for all tokens, where the last authentication happens longer ago than the given value:
Example:

privacyidea-token-janitor find --last_auth 10d

This will find all tokens, that did not authenticate within the last 10 days. You can also use “h” and “y” to specify hours
and years.
Since the last_auth is an entry in the tokeninfo table you could also search like this:

privacyidea-token-janitor find --tokeninfo-key last_auth --tokeninfo-value-after '2021-


˓→06-01 18:00:00+0200'

Description

Searches through all tokens and returns the ones with the selected description.
Example:

privacyidea-token-janitor find --description '^fo.*'

Return all tokens where the description begins with “fo”.

1.12. Workflows and Tools 223


privacyIDEA Authentication System, Release 3.8

Serial

Searches through all tokens and returns the ones with the selected serial.
Example:

privacyidea-token-janitor find --serial OATH0013B2B4

Return all tokens with the serial OATH0013B2B4.


By searching for regular expressions, it is e.g. possible to find Yubikeys, which might be a tokentype “HOTP”, but
where the serial starts with UBOM.
Example:

privacyidea-token-janitor find --serial '^UBOM.*'

Tokentype

Searches through all tokens and returns the ones with the selected tokentype.
Example:

privacyidea-token-janitor find --tokentype hotp

Return all tokens with the tokentype hotp.

Tokenattribute

Match for a certain token attribute from the database table token.
There are different ways of filtering here.

tokenattribute-value REGEX|INTEGER

The value of the token-attribute which should match.


Example:

privacyidea-token-janitor find --tokenattribute rollout_state --tokenattribute-value␣


˓→clientwait

Search for all tokens with the tokenattribute-key rollout_state and the associated tokenattribute-value clientwait.
Note that it is also possible to work with regular expressions here.

224 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

tokenattribute-value-less-than INTEGER

Match if the value of the token attribute is less than the given value.
Example:

privacyidea-token-janitor find --tokenattribute failcount --tokenattribute-value-less-


˓→than 10

Search for all tokens with the tokenattribute-key failcount and the associated tokenattribute-value below 10. This
way you can find tokens, where the fail counter is less than 10 and thus the tokens are not blocked.

tokenattribute-value-greater-than INTEGER

Match if the value of the token attribute is greater than the given value.
Example:

privacyidea-token-janitor find --tokenattribute failcount --tokenattribute-value-greater-


˓→than 10

Search for all tokens with the tokenattribute-key failcount and the associated tokenattribute-value greater than 10.
This way you can find tokens, where the fail counter is greater than 10 and thus the tokens are blocked.

Tokeninfo-key

This matches on values for tokeninfo, which is actually the database table tokeninfo.
There are different ways of filtering here.

has-tokeninfo-key

Filters for tokens that have given the specified tokeninfo-key no matter which value the key has.
Example:

privacyidea-token-janitor find --has-tokeninfo-key import_time

Searches for all tokens that have a tokeninfo-key import_time set.


Note, that it is not important, what value the “import_time” actually has!

has-not-tokeninfo-key

Filters for tokens that have not set the specified tokeninfo-key.
Example:

privacyidea-token-janitor find --has-not-tokeninfo-key import_time

Searches for all tokens that didn’t store the tokeninfo-key import_time.

1.12. Workflows and Tools 225


privacyIDEA Authentication System, Release 3.8

tokeninfo-value REGEX|INTEGER

The tokeninfo-value to match.


Example:

privacyidea-token-janitor find --tokeninfo-key tokenkind --tokeninfo-value software

Search for all tokens with the tokeninfo-key tokenkind and the associated tokeninfo-value software.

tokeninfo-value-less-than INTEGER

Interpret tokeninfo-values as integers and match only if they are smaller than the given integer.
Example:

privacyidea-token-janitor find --tokeninfo-key timeWindow --tokeninfo-value-less-than 200

Search for all tokens with the tokeninfo-key timeWindow and the associated tokeninfo-value below 200.

tokeninfo-value-greater-than INTEGER

Interpret tokeninfo-values as integers and match only if they are greater than the given integer.
Example:

privacyidea-token-janitor find --tokeninfo-key timeWindow --tokeninfo-value-greater-than␣


˓→100

Search for all tokens with the tokeninfo-key timeWindow and the associated tokeninfo-value greater than 100.

Actions

Actions are performed by the token janitor on all found tokens.


mark - disable - delete - unassign - export - listuser - tokenrealms

mark

Mark makes it possible to mark the found tokens in order to carry out further actions with them later.
The tokens are marked by setting a tokeninfo-key and an associated tokininfo-value.
Example:

privacyidea-token-janitor find --serial OATH0004C934 --action mark --set-tokeninfo-key␣


˓→unused --set-tokeninfo-value True

A new tokeninfo-key and the associated tokeninfo-value would be added for the token OAUTH0004C934 and are now
marked for later processing. If the token already containd this tokeninf-key, the value would be changed.

226 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

disable

With disable the found tokens can be disabled.


Example:

privacyidea-token-janitor find --serial OATH0004C934 --action disable

The token with the serial OAUTH0004C934 will be disabled.

delete

With delete the found tokens can be deleted.


Example:

privacyidea-token-janitor find --serial OATH0004C934 --action delete

The token with the serial OAUTH0004C934 will be deleted.

export

With export the found tokens can be exported as csv or pskc.


Export is only possible with HOTP and TOTP token.
Example:

privacyidea-token-janitor find --serial OATH0004C934 --action export > OAUTH0004C934.xml

The token with the serial OAUTH0004C934 will be exported and saved in an xml file.
Note that you need your encryption key for re-import.

listuser

With listuser the found tokens are listed in a summarized view.


Example:

privacyidea-token-janitor find --action listuser

lists all tokens in a summarized view.

sum

Sum and listuser together


For all found tokens the token janitor aggregate’s the users and lists how many tokens this user has.
A user without any assigned token is not listed here!
Example:

1.12. Workflows and Tools 227


privacyIDEA Authentication System, Release 3.8

privacyidea-token-janitor find --sum --action listuser

tokenrealms

Tokenrealms can be used to assign tokens to different realms.


To do this, the tokenrealms function is also required.
Please note that without a previous selection of a certain token, all found tokens will be assigned to the realm.
Example:

privacyidea-token-janitor find --serial OATH0005B88E --action tokenrealms --tokenrealms␣


˓→defrealm

Setting realms of token OATH0005B88E to defrealm.


You can also assign a list of realms by comma separating.
Example:

privacyidea-token-janitor find --serial OATH0005B88E --action tokenrealms --tokenrealms␣


˓→defrealm,realmA,realmB

Set

With the tokenjanitor it is possible to set new tokeninfo-values, tokeninfo-keys and descriptions.
It is important to note that this is only possible with a previously marked token.

set-tokeninfo-key and set-tokeninfo-value

Set a new tokeninfo-key and a new tokeninfo-value or update the tokeninfo-value of an existing key.
This will only work together it is not possible to set a tokeninfo-key or a tokenifno-value individually.
Example:

privacyidea-token-janitor find --serial OATH0004C934 --action mark --set-tokeninfo-key␣


˓→import_time --set-tokeninfo-value $(date --iso-8601=minutes)

Mark the token with the serial OATH0004C934 and set a new tokeninfo-key import_time and a new tokeninfo-value
$(date --iso-8601=minutes).

228 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

set description

Set a new description.


It is important to note that this is only possible with a previously marked token.
Example:

privacyidea-token-janitor find --serial OATH0004C934 --action mark --set-description L4

Mark the token with the serial OATH0004C934 and set the description example.

privacyidea-get-unused-tokens

The script privacyidea-get-unused-tokens allows you to search for tokens, which were not used for authentication
for a while. These tokens can be listed, disabled, marked or deleted.
You can specify how old the last authentication of such a token has to be. You can use the tags h (hours), d (day) and
y (year). Specifying 180d will find tokens, that were not used for authentication for the last 180 days.
The command:

privacyidea-get-unused-tokens disable 180d

will disable those tokens.


This script can be well used with the Script Handler Module.

1.12.5 Two Step Enrollment

Starting with version 2.21 privacyIDEA allows to enroll smartphone based tokens in a 2step enrollment.
With the rise of the smartphones and the fact that every user has a smartphone, carries it with him all the time and cares
about it a lot, using the smartphone for authentication gets more and more attractive to IT departments.
Google came up with the Key URI1 to use a QR code to easily enroll a smartphone token, i.e. transport the OTP secret
from the server to the phone. However this bears some security issues as already pointed out2 .
This is why privacyIDEA allows to generate the OTP secret from a server component and from a client component
(generated by the smartphone). This way the enrolled token is more tightly bound to this single smartphone and can
not be copied that easily anymore.

Workflow

In a two step enrollment process the user clicks in the Web UI to enroll a token. The server generates a QR code and
the user will scan this QR code with his smartphone app. The QR code contains the server component of the key and
the information, that a second component is needed.
The smartphone generates the second component and displays this to the user.
The user enters this second component into the privacyIDEA Web UI.
Both the smartphone and the server calculate the OTP secret from both components.
1 https://github.com/google/google-authenticator/wiki/Key-Uri-Format
2 https://netknights.it/en/the-problem-with-the-google-authenticator/

1.12. Workflows and Tools 229


privacyIDEA Authentication System, Release 3.8

Two Step policies

Two step enrollment is controlled by policies in the admin/user scope and in the enrollment scope.
Thus the administrator can allow or force a user (or other administrators) to do a two step enrollment. This way it is
possible to avoid the enrollment of insecure Google Authenticator QR codes in the complete installation. (hotp_2step
and totp_2step).
The default behaviour is to not allow a two step enrollment. Only if a corresponding admin or user policy is defined,
two step enrollment is possible.

Key generation

In addition the administrator can define an enrollment policy to specify necessary parameters for the key generation.
Two step enrollment is possible for HOTP and TOTP tokens. Thus the administrator can define to-
ken type specific policies in the scope enrollment: hotp_2step_clientsize, totp_2step_clientsize,
hotp_2step_difficulty. . . see {type}_2step_clientsize, {type}_2step_serversize, {type}_2step_difficulty.

privacyIDEA Authenticator

The privacyIDEA Authenticator3 that is available from the Google Play Store supports the two step enrollment.

Specification

The two step enrollment simply adds some parameters to the original Key URI.
2step_output
This is the resulting key size, which the smartphone should generate (in bytes).
2step_salt
This is the length of the client component that the smartphone should generate (in bytes).
2step_difficulty
This is the number of rounds for the PBKDF2 that the smartphone should use to generate the OTP secret.
The secret parameter of the Key URI contains the server component.
The smartphone app then generates the client component, which is 2step_salt random bytes. It is then displayed in
a human-readable format called base32check:

b32encode(sha1(client_component).digest()[0:4] + client_component).strip("=")

In other words, the first four bytes of the client component’s SHA-1 hash are concatenated with the actual client com-
ponent. The result is encoded using base32, whereas trailing padding characters are removed.
The second step of the enrollment process is realized as another request to the /token/init endpoint:

POST /token/init

serial=<token serial>
otpkey=<base32check(client_component)>
otpkeyformat=base32check

3 https://play.google.com/store/apps/details?id=it.netknights.piauthenticator

230 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Server and smartphone app then use PBKDF2 to generate the final secret (see4 for parameter names):

secret = PBKDF2(P=hexlify(<server component>),


S=<client component>,
c=<2step_difficulty>
dkLen=<2step_output>)

whereas hexlify(<server component>) denotes a hex-encoding (using lowercase letters) of the byte array which
comprises the server component.

Note: Please note that the two-step enrollment process is currently not designed to protect against malicious attackers.
Depending on the choice of iteration count and salt size, an attacker who knows the server component and an OTP
value may be able to obtain the client component with a brute-force approach. However, two-step enrollment is still
an improvement to the status quo, as a simple copy of the QR code does not immediately leak the OTP secret and
obtaining the OTP secret using brute-force is not trivial.

1.13 Job Queue

privacyIDEA workflows often entail some time-consuming tasks, such as sending mails or SMS or saving usage statis-
tics. Executing such tasks during the handling of API requests negatively affects performance. Starting with version
3.0, privacyIDEA allows to delegate certain tasks to external worker processes by using a job queue.
As an example, assume that privacyIDEA receives an authentication request by a user with an email token (see Email)
via HTTP. privacyIDEA will send a one-time password via E-Mail. In order to do so, it communicates with a SMTP
server. Normally, privacyIDEA handles all communication during the processing of the original authentication request,
which increases the response time for the HTTP request, especially if the SMTP server is at a remote location.
A job queue can help to reduce the response time as follows. Instead of communicating with the SMTP server during
request handling, privacyIDEA stores a so-called job in a job queue which says “Send an E-Mail to [email protected]
with content ‘. . . ’”. privacyIDEA does not wait for the E-Mail to be actually sent, but already sends an HTTP response.
An external worker process then retrieves the job from the queue and actually sends the corresponding E-Mail.
Using a job queue may improve the performance of your privacyIDEA server in case of a flaky connection to the
SMTP server. Authentication requests that send E-Mails are then handled faster (because the privacyIDEA server does
not actually communicate with the SMTP server), which means that the corresponding web server worker thread can
handle the next request faster.
privacyIDEA 3.0 implements a job queue based on huey which uses a Redis server to store jobs. As of version 3.0,
privacyIDEA allows to offload sending mails to the queue. Other jobs will be implemented in future versions.

1.13.1 Configuration

The job queue is disabled by default. In order to enable it, add the following configuration option to pi.cfg:

PI_JOB_QUEUE_CLASS = 'privacyidea.lib.queues.huey_queue.HueyQueue'

After a server restart, you will be able to instruct individual SMTP servers to send all mails via the job queue by
checking a corresponding box in the SMTP server configuration (see SMTP server configuration). This means that you
can have separate SMTP server configurations, some of which send mails via the job queue, some of which send mails
during the request processing.
4 https://www.ietf.org/rfc/rfc2898.txt

1.13. Job Queue 231


privacyIDEA Authentication System, Release 3.8

Note that you need to run a Redis server which is reachable for the privacyIDEA server. By default, huey assumes a
locally running Redis server. You can use a configuration option to provide a different URL (see here for information
on the URL format):

PI_JOB_QUEUE_URL = 'redis://somehost'

In addition to the privacyIDEA server, you will have to run a worker process which fetches jobs from the queue and
executes them. You can start it as follows:

privacyidea-queue-huey

By default, the worker process logs to privacyidea-queue.log in the current working directory. You can pass a
different logfile by using the -l option:

privacyidea-queue-huey -l /var/log/queue.log

As the script is heavily based on the huey consumer script, you can find information about additional options in the
huey documentation.
Note that a side-effect of the queue is that the privacyIDEA server will not throw or log errors if a mail could not be
sent. Hence, it is important to monitor the queue log file for errors.

1.14 Application Plugins

privacyIDEA comes with application plugins. These are plugins for applications like PAM, OTRS, Apache2, FreeRA-
DIUS, ownCloud, simpleSAMLphp or Keycloak which enable these application to authenticate users against priva-
cyIDEA.
You may also write your own application plugin or connect your own application to privacyIDEA. This is quite simple
using a REST API Validate endpoints. In order to support more sophisticated token types like challenge-response or
out-of-band tokens, you should take a look at the various Authentication Modes and Client Modes.

1.14.1 Pluggable Authentication Module

The PAM module of privacyIDEA directly communicates with the privacyIDEA server via the API. The PAM module
also supports offline authentication. In this case you need to configure an offline machine application. (See Offline)
You can install the PAM module by using the source code file. It is a python module, that requires python-pam:

git clone https://github.com/privacyidea/pam_python.git


cd pam_python
pip install -r requirements.txt
python ./setup.py install

The configuration could look like this:

... pam_python.so /path/to/privacyidea_pam.py


url=https://localhost prompt=privacyIDEA_Authentication

The URL parameter defaults to https://localhost. You can also add the parameters realm= and debug.
If you want to disable certificate validation, which you should not do in a productive environment, you can use the
parameter nosslverify.

232 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

A new parameter cacerts= lets you define a CA Cert-Bundle file, that contains the trusted certificate authorities in
PEM format.
The default behaviour is to trigger an online authentication request. If the request was successful, the user is logged
in. If the request was done with a token defined for offline authentication, then in addition all offline information is
passed to the client and cached on the client so that the token can be used to authenticate without the privacyIDEA
server available.

try_first_pass

Starting with version 2.8 privacyidea_pam supports try_first_pass. In this case the password that exists in the PAM
stack will be sent to privacyIDEA. If this password is successfully validated, than the user is logged in without additional
requests. If the password is not validated by privacyIDEA, the user is asked for an additional OTP value.

Note: This can be used in conjunction with the passthru policy. In this case users with no tokens will be able to login
with only the password in the PAM stack.

Use cases SSH and VPN

PrivacyIDEA can be easily used to setup a secure SSH login combining SSH keys with a second factor. The configu-
ration is given in SSH Keys and OTP: Really strong two factor authentication on the privacyIDEA website.
Read more about how to use PAM to do openvpn.

1.14.2 Using pam_yubico

If you are using Yubikey tokens you might also use pam_yubico. You can use Yubikey tokens for two more or less dis-
tinct applications. The first is using privacyideas PAM module as described above. In this case privacyidea handles the
policies for user access and password validation. This works fine, when you only use privacyidea for token validation.
The second mode is using the standard PAM module for Yubikeys from Yubico pam_yubico to handle the token
validation. The upside is that you can use the PAM module included with you distribution, but there are downsides as
well.
• You can’t set a token PIN in privacyidea, because pam_yubico tries to use the token PIN entered by the user as
a system password (which is likely to fail), i.e. the PIN will be stripped by pam_yubico and will not reach the
privacyIDEA system.
• Setting the policy which tokens are valid for which users is done either in ~/.yubico/authorized_keys or in
the file given by the authfile option in the PAM configuration. The api server will only validate the token, but
not check any kind of policy.
You can work around the restrictions by using a clever combination of tokentype Yubikey and Yubico as follows:
• enroll a Yubikey token with yubikey_mass_enroll --mode YUBICO.
• do not set a token password.
• do not assign the token to a user.
• please make a note of yubikey.prefix (12 characters starting with vv).
Now the token can be used with pam_yubico, but will not allow any user access in privacyidea. If you want to use the
token with pam_yubico see the manual page for details. You’ll want something like the following in your PAM config:

1.14. Application Plugins 233


privacyIDEA Authentication System, Release 3.8

auth required pam_yubico.so id=<apiid> key=<API key> \


urllist=https://<privacyidea-server>/ttype/yubikey authfile=/etc/yubikeys/
˓→authorized_yubikeys

The file /etc/yubikeys/authorized_yubikeys contains a line for each user with the username and the allowed
tokens delimited by “:”, for example:

<username>:<serial number1>:<prefix1>:<prefix2>

Now create a second token representing the Yubikey, but this time use the Yubico Cloud mode. Go to Tokens ->
Enroll Token and select Yubico Cloud mode. Enter the 12 characters prefix you noted above and assign this token to
a user and possibly set a token PIN. It would be nice to have the the serial number of the UBCM token correspond to
the UBAM token, but this is right now not possible with the WebUI.
In the WebUI, test the UBAM token without a Token PIN, test the UBCM token with the stored Token PIN, and check
the token info afterwards. Check the Yubikey token via /ttype/yubikey, for example with:

ykclient --debug --url https://<privacyidea>/ttype/yubikey --apikey "<API key>" "apiid"


˓→<otp>

There should be successful authentications (count_auth_success), but no failures.

1.14.3 FreeRADIUS

Starting with privacyIDEA 2.19, there are two ways to integrate FreeRADIUS:
• Using a Perl-based privacyIDEA plugin, which is available for FreeRADIUS 2.0.x and above. It supports
advanced use cases (such as challenge-response authentication or attribute mapping). Read more about it at
rlm_perl.
• Using the rlm_rest plugin provided by FreeRADIUS 3.0.x and above. However, this setup does not support
challenge-response or attribute mapping. Read more about it at rlm_rest.
With either setup, you can test the RADIUS setup using a command like this:

echo "User-Name=user, User-Password=password" | radclient -sx yourRadiusServer \


auth topsecret

Note: Do not forget to configure the clients.conf accordingly.

1.14.4 Microsoft NPS server

You can also use the Microsoft Network Protection Server with privacyIDEA. A full featured integration guide can be
found at the NetKnights webpage.

234 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

1.14.5 simpleSAMLphp Plugin

You can install the plugin for simpleSAMLphp using the source files from the GitHub Repository simplesamplphp-
module-privacyidea.
Follow the simpleSAMLphp instructions to configure your authsources.php. A usual configuration will look like this:

'example-privacyidea' => array(


'privacyidea:privacyidea',

/*
* The name of the privacyidea server and the protocol
* A port can be added by a colon
* Required.
*/
'privacyideaserver' => 'https://your.server.com',

/*
* Check if the hostname matches the name in the certificate
* Optional.
*/
'sslverifyhost' => False,

/*
* Check if the certificate is valid, signed by a trusted CA
* Optional.
*/
'sslverifypeer' => False,

/*
* The realm where the user is located in.
* Optional.
*/
'realm' => '',

/*
* This is the translation from privacyIDEA attribute names to
* SAML attribute names.
*/
'attributemap' => array('username' => 'samlLoginName',
'surname' => 'surName',
'givenname' => 'givenName',
'email' => 'emailAddress',
'phone' => 'telePhone',
'mobile' => 'mobilePhone',
),
),

1.14. Application Plugins 235


privacyIDEA Authentication System, Release 3.8

1.14.6 Keycloak

With the privacyIDEA Keycloak-provider, there is a plugin available for the Keycloak identity manager. It is available
from the GitHub repository keycloak-provider.
Like simpleSAMLphp, it can be used to realize single sign-on use cases with a strong second factor authentication.

1.14.7 TYPO3

You can install the privacyIDEA extension from the TYPO3 Extension Repository. The privacyIDEA extension is
easily configured.
privacyIDEA Server URL
This is the URL of your privacyIDEA installation. You do not need to add the path validate/check. Thus the URL for
a common installation would be https://yourServer/.
Check certificate
Whether the validity of the SSL certificate should be checked or not.

Warning: If the SSL certificate is not checked, the authentication request could be modified and the answer to the
request can be modified, easily granting access to an attacker.

Enable privacyIDEA for backend users


If checked, a user trying to authenticate at the backend, will need to authenticate against privacyIDEA.
Enable privacyIDEA for frontend users
If checked, a user trying to authenticate at the frontend, will need to authenticate against privacyIDEA.
Pass to other authentication module
If the authentication at privacyIDEA fails, the credential the user entered will be verified against the next authentication
module.
This can come in handy, if you are setting up the system and if you want to avoid locking yourself out.
Anyway, in a productive environment you probably want to uncheck this feature.

1.14.8 OTRS

The OTRS Plugin can be found in its own GitHub Repository.


This perl module needs to be installed to the directory Kernel/System/Auth.
To activate the OTP authentication you need to add the following to Kernel/Config.pm:

$Self->{'AuthModule'} = 'Kernel::System::Auth::privacyIDEA';
$Self->{'AuthModule::privacyIDEA::URL'} = \
"https://localhost/validate/check";
$Self->{'AuthModule::privacyIDEA::disableSSLCheck'} = "yes";

Note: As mentioned earlier you should only disable the checking of the SSL certificate if you are in a test environment.
For productive use you should never disable the SSL certificate checking.

236 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Note: This plugin requires, that you also add the path validate/check to the URL.

1.14.9 Apache2

The Apache plugin uses mod_wsgi and redis to provide a basic authentication on Apache2 side and validating the
credentials against privacyIDEA.
You need the authentication script privacyidea_apache.py and a valid configuration in /etc/privacyidea/
apache.conf. Both can be found on GitHub.
To activate the OTP authentication on a “Location” or “Directory” you need to configure Apache2 like this:

<Directory /var/www/html/secretdir>
AuthType Basic
AuthName "Protected Area"
AuthBasicProvider wsgi
WSGIAuthUserScript /usr/share/pyshared/privacyidea_apache.py
Require valid-user
</Directory>

Note: Basic Authentication sends the base64 encoded password on each request. So the browser will send the same one
time password with each request. Thus the authentication module needs to cache the password when the authentication
is successful. Redis is used for caching the password.

Warning: As redis per default is accessible by every user on the machine, you need to use this plugin with caution!
Every user on the machine can access the redis database to read the passwords of the users. The cached credentials
are stored as pbkdf2+sha512 hash.

1.14.10 NGINX

The NGINX plugin uses the internal scripting language lua of the NGINX webserver and redis as caching backend
to provide basic authentication against privacyIDEA.
You can retrieve the nginx plugin from GitHub.
To activate the OTP authentication on a “Location” you need to include the lua script that basically verifies the given
credentials against the caching backend. New authentications will be sent to a different (internal) location via subrequest
which points to the privacyIDEA authentication backend (via proxy_pass).
For the basic configuration you need to include the following lines to your location block:

location / {
# additional plugin configuration goes here #
access_by_lua_file 'privacyidea.lua';
}
location /privacyidea-validate-check {
internal;
proxy_pass https://privacyidea/validate/check;
}

1.14. Application Plugins 237


privacyIDEA Authentication System, Release 3.8

You can customize the authentication plugin by setting some of the following variables in the secured location block:

# redis host:port
# set $privacyidea_redis_host "127.0.0.1";
set $privacyidea_redis_post 6379;

# how long are accepted authentication allowed to be cached


# if expired, the user has to reauthenticate
set $privacyidea_ttl 900;

# privacyIDEA realm. leave empty == default


set $privacyidea_realm 'somerealm'; # (optional)

# pointer to the internal validation proxy pass


set $privacyidea_uri "/privacyidea-validate-check";

# the http realm presented to the user


set $privacyidea_http_realm "Secure zone (use PIN + OTP)";

Note: Basic Authentication sends the base64 encoded password on each request. So the browser will send the same
one time password with each reqeust. Thus the authentication module needs to cache the password as the successful
authentication. Redis is used for caching the password similar to the Apache2 plugin.

Warning: As redis per default is accessible by every user on the machine, you need to use this plugin with
caution! Every user on the machine can access the redis database to read the passwords of the users. The cached
credentials are stored as SHA1_HMAC hash. If you prefer a stronger hashing method feel free to extend the given
password_hash/verify functions using additional lua libraries (for example by using lua-resty-string).

1.14.11 ownCloud

The ownCloud plugin is a ownCloud user backend. The directory user_privacyidea needs to be copied to your
owncloud apps directory.

Fig. 68: Activating the ownCloud plugin

You can then activate the privacyIDEA ownCloud plugin by checking Use privacyIDEA to authenticate the users. All
users now need to be known to privacyIDEA and need to authenticate using the second factor enrolled in privacyIDEA
- be it an OTP token, Google Authenticator or SMS/Smartphone.

238 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Checking Also allow users to authenticate with their normal passwords. lets the user choose if he wants to authenticate
with the OTP token or with his original password from the original user backend.

Note: At the moment using a desktop client with a one time password is not supported.

ownCloud 9.1 and Nextcloud 10 come with a new two factor framework. The new privacyIDEA ownCloud App allows
you to add a second factor, that is centrally managed by privacyIDEA to the ownCloud or Nextcloud installation.
The ownCloud privacyIDEA App is available from the ownCloud App Store.
The App requires a subscription file to work for more than ten users. You can get the subscription file from NetKnights.

1.14.12 Django

You can add two factor authentication with privacyIDEA to Django using this Django plugin.
You can simply add PrivacyIDEA class to the AUTHENTICATION_BACKENDS settings of Django.

1.14.13 OpenVPN

Read more about how to use OpenVPN with privacyidea at openvpn.

1.14.14 Windows

Credential Provider

The privacyIDEA Credential Provider adds two factor authentication to the Windows desktop or Terminal server. See
http://privacyidea-credential-provider.readthedocs.io

Provider Class

There is a dot Net provider class, which you can use to integrate privacyIDEA authentication into other products and
worflows. See https://github.com/sbidy/privacyIDEA_dotnetProvider

1.14.15 Further plugins

You can find further plugins for Dokuwiki, Wordpress, Contao and Django at cornelinux Github page.

1.15 Code Documentation

The code roughly has three levels: API, LIB and DB.

1.15. Code Documentation 239


privacyIDEA Authentication System, Release 3.8

1.15.1 API level

The API level is used to access the system. For some calls you need to be authenticated as administrator, for some calls
you can be authenticated as normal user. These are the token and the audit endpoint. For calls to the validate API
you do not need to be authenticated at all.
At this level Authentication is performed. In the lower levels there is no authentication anymore.
The object g.logged_in_user is used to pass the authenticated user. The client gets a JSON Web Token to authen-
ticate every request.
API functions are decorated with the decorators admin_required and user_required to define access rules.

REST API

This is the REST API for privacyidea. It lets you create the system configuration, which is denoted in the system
endpoints.
Special system configuration is the configuration of
• the resolvers
• the realms
• the defaultrealm
• the policies.
Resolvers are dynamic links to existing user sources. You can find users in LDAP directories, SQL databases, flat
files or SCIM services. A resolver translates a loginname to a user object in the user source and back again. It is also
responsible for fetching all additional needed information from the user source.
Realms are collections of resolvers that can be managed by administrators and where policies can be applied.
Defaultrealm is a special endpoint to define the default realm. The default realm is used if no user realm is specified. If
a user from realm1 tries to authenticate or is addressed, the notation user@realm1 is used. If the @realm1 is omitted,
the user is searched in the default realm.
Policies are rules how privacyidea behaves and which user and administrator is allowed to do what.
Start to read about authentication to the API at Authentication endpoints.
Now you can take a look at the several REST endpoints. This REST API is used to authenticate the users. A user
needs to authenticate when he wants to use the API for administrative tasks like enrolling a token.
This API must not be confused with the validate API, which is used to check, if a OTP value is valid. See Validate
endpoints.
Authentication of users and admins is tested in tests/test_api_roles.py
You need to authenticate for all administrative tasks. If you are not authenticated, the API returns a 401 response.
To authenticate you need to send a POST request to /auth containing username and password.

240 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Audit endpoint

GET /audit/
return a paginated list of audit entries.
Params can be passed as key-value-pairs.
Httpparam timelimit A timelimit, that limits the recent audit entries. This param gets overwritten
by a policy auditlog_age. Can be 1d, 1m, 1h.
Example request:

GET /audit?realm=realm1 HTTP/1.1


Host: example.com
Accept: application/json

Example response:

HTTP/1.1 200 OK
Content-Type: application/json

{
"id": 1,
"jsonrpc": "2.0",
"result": {
"status": true,
"value": [
{
"serial": "....",
"missing_line": "..."
}
]
},
"version": "privacyIDEA unknown"
}

GET /audit/(csvfile)
Download the audit entry as CSV file.
Params can be passed as key-value-pairs.
Example request:

GET /audit/audit.csv?realm=realm1 HTTP/1.1


Host: example.com
Accept: text/csv

Example response:

HTTP/1.1 200 OK
Content-Type: text/csv

{
"id": 1,
"jsonrpc": "2.0",
"result": {
(continues on next page)

1.15. Code Documentation 241


privacyIDEA Authentication System, Release 3.8

(continued from previous page)


"status": true,
"value": [
{
"serial": "....",
"missing_line": "..."
}
]
},
"version": "privacyIDEA unknown"
}

Authentication endpoints

This REST API is used to authenticate the users. A user needs to authenticate when he wants to use the API for
administrative tasks like enrolling a token.
This API must not be confused with the validate API, which is used to check, if a OTP value is valid. See Validate
endpoints.
Authentication of users and admins is tested in tests/test_api_roles.py
You need to authenticate for all administrative tasks. If you are not authenticated, the API returns a 401 response.
To authenticate you need to send a POST request to /auth containing username and password.
GET /auth/rights
This returns the rights of the logged in user.
Request Headers
• Authorization – The authorization token acquired by /auth request
POST /auth
This call verifies the credentials of the user and issues an authentication token, that is used for the later API calls.
The authentication token has a validity, that is usually 1 hour.
JSON Parameters
• username – The username of the user who wants to authenticate to the API.
• password – The password/credentials of the user who wants to authenticate to the API.
• realm – The realm where the user will be searched.
Return A json response with an authentication token, that needs to be used in any further request.
Status Codes
• 200 OK – in case of success
• 401 Unauthorized – if authentication fails
Example Authentication Request:

POST /auth HTTP/1.1


Host: example.com
Accept: application/json

(continues on next page)

242 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

(continued from previous page)


username=admin
password=topsecret

Example Authentication Response:

HTTP/1.0 200 OK
Content-Length: 354
Content-Type: application/json

{
"id": 1,
"jsonrpc": "2.0",
"result": {
"status": true,
"value": {
"token": "eyJhbGciOiJIUz....jdpn9kIjuGRnGejmbFbM"
}
},
"version": "privacyIDEA unknown"
}

Response for failed authentication:

HTTP/1.1 401 UNAUTHORIZED


Content-Type: application/json
Content-Length: 203

{
"id": 1,
"jsonrpc": "2.0",
"result": {
"error": {
"code": -401,
"message": "missing Authorization header"
},
"status": false
},
"version": "privacyIDEA unknown",
"config": {
"logout_time": 30
}
}

Example Request:
Requests to privacyidea then should use this security token in the Authorization field in the header.

GET /users/ HTTP/1.1


Host: example.com
Accept: application/json
Authorization: eyJhbGciOiJIUz....jdpn9kIjuGRnGejmbFbM

1.15. Code Documentation 243


privacyIDEA Authentication System, Release 3.8

Validate endpoints

This module contains the REST API for doing authentication. The methods are tested in the file
tests/test_api_validate.py
Authentication is either done by providing a username and a password or a serial number and a password.
Authentication workflow
Authentication workflow is like this:
In case of authenticating a user:
• privacyidea.lib.token.check_user_pass()
• privacyidea.lib.token.check_token_list()
• privacyidea.lib.tokenclass.TokenClass.authenticate()
• privacyidea.lib.tokenclass.TokenClass.check_pin()
• privacyidea.lib.tokenclass.TokenClass.check_otp()
In case if authenticating a serial number:
• privacyidea.lib.token.check_serial_pass()
• privacyidea.lib.token.check_token_list()
• privacyidea.lib.tokenclass.TokenClass.authenticate()
• privacyidea.lib.tokenclass.TokenClass.check_pin()
• privacyidea.lib.tokenclass.TokenClass.check_otp()
GET /validate/triggerchallenge
An administrator can call this endpoint if he has the right of triggerchallenge (scope: admin). He can pass
a user name and or a serial number. privacyIDEA will trigger challenges for all native challenges response
tokens, possessed by this user or only for the given serial number.
The request needs to contain a valid PI-Authorization header.
Parameters
• user – The loginname/username of the user, who tries to authenticate.
• realm – The realm of the user, who tries to authenticate. If the realm is omitted, the user is
looked up in the default realm.
• serial – The serial number of the token.
• type – The tokentype of the tokens, that are taken into account during authentication. Re-
quires authz policy application_tokentype. Is ignored when a distinct serial is given.
Return a json result with a “result” of the number of matching challenge response tokens
Example response for a successful triggering of challenge:

HTTP/1.1 200 OK
Content-Type: application/json

{
"detail": {
"client_mode": "interactive",
"message": "please enter otp: , please enter otp: ",
(continues on next page)

244 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

(continued from previous page)


"messages": [
"please enter otp: ",
"please enter otp: "
],
"multi_challenge": [
{
"client_mode": "interactive",
"message": "please enter otp: ",
"serial": "TOTP000026CB",
"transaction_id": "11451135673179897001",
"type": "totp"
},
{
"client_mode": "interactive",
"message": "please enter otp: ",
"serial": "OATH0062752C",
"transaction_id": "11451135673179897001",
"type": "hotp"
}
],
"serial": "OATH0062752C",
"threadid": 140329819764480,
"transaction_id": "11451135673179897001",
"transaction_ids": [
"11451135673179897001",
"11451135673179897001"
],
"type": "hotp"
},
"id": 2,
"jsonrpc": "2.0",
"result": {
"status": true,
"value": 2
}

Example response for response, if the user has no challenge token:

HTTP/1.1 200 OK
Content-Type: application/json

{
"detail": {"messages": [],
"threadid": 140031212377856,
"transaction_ids": []},
"id": 1,
"jsonrpc": "2.0",
"result": {"status": true,
"value": 0},
"signature": "205530282...54508",
"time": 1484303812.346576,
"version": "privacyIDEA 2.17",
(continues on next page)

1.15. Code Documentation 245


privacyIDEA Authentication System, Release 3.8

(continued from previous page)


"versionnumber": "2.17"
}

Example response for a failed triggering of a challenge. In this case the status will be false.

HTTP/1.1 200 OK
Content-Type: application/json

{
"detail": null,
"id": 1,
"jsonrpc": "2.0",
"result": {"error": {"code": 905,
"message": "ERR905: The user can not be
found in any resolver in this realm!"},
"status": false},
"signature": "14468...081555",
"time": 1484303933.72481,
"version": "privacyIDEA 2.17"
}

POST /validate/triggerchallenge
An administrator can call this endpoint if he has the right of triggerchallenge (scope: admin). He can pass
a user name and or a serial number. privacyIDEA will trigger challenges for all native challenges response
tokens, possessed by this user or only for the given serial number.
The request needs to contain a valid PI-Authorization header.
Parameters
• user – The loginname/username of the user, who tries to authenticate.
• realm – The realm of the user, who tries to authenticate. If the realm is omitted, the user is
looked up in the default realm.
• serial – The serial number of the token.
• type – The tokentype of the tokens, that are taken into account during authentication. Re-
quires authz policy application_tokentype. Is ignored when a distinct serial is given.
Return a json result with a “result” of the number of matching challenge response tokens
Example response for a successful triggering of challenge:

HTTP/1.1 200 OK
Content-Type: application/json

{
"detail": {
"client_mode": "interactive",
"message": "please enter otp: , please enter otp: ",
"messages": [
"please enter otp: ",
"please enter otp: "
],
"multi_challenge": [
(continues on next page)

246 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

(continued from previous page)


{
"client_mode": "interactive",
"message": "please enter otp: ",
"serial": "TOTP000026CB",
"transaction_id": "11451135673179897001",
"type": "totp"
},
{
"client_mode": "interactive",
"message": "please enter otp: ",
"serial": "OATH0062752C",
"transaction_id": "11451135673179897001",
"type": "hotp"
}
],
"serial": "OATH0062752C",
"threadid": 140329819764480,
"transaction_id": "11451135673179897001",
"transaction_ids": [
"11451135673179897001",
"11451135673179897001"
],
"type": "hotp"
},
"id": 2,
"jsonrpc": "2.0",
"result": {
"status": true,
"value": 2
}

Example response for response, if the user has no challenge token:

HTTP/1.1 200 OK
Content-Type: application/json

{
"detail": {"messages": [],
"threadid": 140031212377856,
"transaction_ids": []},
"id": 1,
"jsonrpc": "2.0",
"result": {"status": true,
"value": 0},
"signature": "205530282...54508",
"time": 1484303812.346576,
"version": "privacyIDEA 2.17",
"versionnumber": "2.17"
}

Example response for a failed triggering of a challenge. In this case the status will be false.

1.15. Code Documentation 247


privacyIDEA Authentication System, Release 3.8

HTTP/1.1 200 OK
Content-Type: application/json

{
"detail": null,
"id": 1,
"jsonrpc": "2.0",
"result": {"error": {"code": 905,
"message": "ERR905: The user can not be
found in any resolver in this realm!"},
"status": false},
"signature": "14468...081555",
"time": 1484303933.72481,
"version": "privacyIDEA 2.17"
}

GET /validate/polltransaction/(transaction_id)
GET /validate/polltransaction
Given a mandatory transaction ID, check if any non-expired challenge for this transaction ID has been answered.
In this case, return true. If this is not the case, return false. This endpoint also returns false if no challenge with
the given transaction ID exists.
This is mostly useful for out-of-band tokens that should poll this endpoint to determine when to send an authen-
tication request to /validate/check.
JSON Parameters
• transaction_id – a transaction ID
POST /validate/offlinerefill
This endpoint allows to fetch new offline OTP values for a token, that is already offline. According to the definition
it will send the missing OTP values, so that the client will have as much otp values as defined.
Parameters
• serial – The serial number of the token, that should be refilled.
• refilltoken – The authorization token, that allows refilling.
• pass – the last password (maybe password+OTP) entered by the user
Return
GET /validate/samlcheck
GET /validate/radiuscheck
GET /validate/check
check the authentication for a user or a serial number. Either a serial or a user is required to authenti-
cate. The PIN and OTP value is sent in the parameter pass. In case of successful authentication it returns
result->value: true.
In case of a challenge response authentication a parameter exception=1 can be passed. This would result in a
HTTP 500 Server Error response if an error occurred during sending of SMS or Email.
In case /validate/radiuscheck is requested, the responses are modified as follows: A successful authentica-
tion returns an empty HTTP 204 response. An unsuccessful authentication returns an empty HTTP 400 response.
Error responses are the same responses as for the /validate/check endpoint.
Parameters

248 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

• serial – The serial number of the token, that tries to authenticate.


• user – The loginname/username of the user, who tries to authenticate.
• realm – The realm of the user, who tries to authenticate. If the realm is omitted, the user is
looked up in the default realm.
• type – The tokentype of the tokens, that are taken into account during authentication. Re-
quires the authz policy application_tokentype. It is ignored when a distinct serial is given.
• pass – The password, that consists of the OTP PIN and the OTP value.
• otponly – If set to 1, only the OTP value is verified. This is used in the management UI.
Only used with the parameter serial.
• transaction_id – The transaction ID for a response to a challenge request
• state – The state ID for a response to a challenge request
Return a json result with a boolean “result”: true
Example Validation Request:

POST /validate/check HTTP/1.1


Host: example.com
Accept: application/json

user=user
realm=realm1
pass=s3cret123456

Example response for a successful authentication:

HTTP/1.1 200 OK
Content-Type: application/json

{
"detail": {
"message": "matching 1 tokens",
"serial": "PISP0000AB00",
"type": "spass"
},
"id": 1,
"jsonrpc": "2.0",
"result": {
"status": true,
"value": true
},
"version": "privacyIDEA unknown"
}

Example response for this first part of a challenge response authentication:

HTTP/1.1 200 OK
Content-Type: application/json

{
"detail": {
(continues on next page)

1.15. Code Documentation 249


privacyIDEA Authentication System, Release 3.8

(continued from previous page)


"serial": "PIEM0000AB00",
"type": "email",
"transaction_id": "12345678901234567890",
"multi_challenge": [ {"serial": "PIEM0000AB00",
"transaction_id": "12345678901234567890",
"message": "Please enter otp from your email",
"client_mode": "interactive"},
{"serial": "PISM12345678",
"transaction_id": "12345678901234567890",
"message": "Please enter otp from your SMS",
"client_mode": "interactive"}
]
},
"id": 2,
"jsonrpc": "2.0",
"result": {
"status": true,
"value": false
},
"version": "privacyIDEA unknown"
}

In this example two challenges are triggered, one with an email and one with an SMS. The application and thus
the user has to decide, which one to use. They can use either.
The challenges also contain the information of the “client_mode”. This tells the plugin, whether it should display
an input field to ask for the OTP value or e.g. to poll for an answered authentication. Read more at Authentication
Modes and Client Modes.

Note: All challenge response tokens have the same transaction_id in this case.

Example response for a successful authentication with /samlcheck:


HTTP/1.1 200 OK
Content-Type: application/json

{
"detail": {
"message": "matching 1 tokens",
"serial": "PISP0000AB00",
"type": "spass"
},
"id": 1,
"jsonrpc": "2.0",
"result": {
"status": true,
"value": {"attributes": {
"username": "koelbel",
"realm": "themis",
"mobile": null,
"phone": null,
"myOwn": "/data/file/home/koelbel",
(continues on next page)

250 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

(continued from previous page)


"resolver": "themis",
"surname": "Kölbel",
"givenname": "Cornelius",
"email": null},
"auth": true}
},
"version": "privacyIDEA unknown"
}

The response in value->attributes can contain additional attributes (like “myOwn”) which you can define
in the LDAP resolver in the attribute mapping.
POST /validate/samlcheck
POST /validate/radiuscheck
POST /validate/check
check the authentication for a user or a serial number. Either a serial or a user is required to authenti-
cate. The PIN and OTP value is sent in the parameter pass. In case of successful authentication it returns
result->value: true.
In case of a challenge response authentication a parameter exception=1 can be passed. This would result in a
HTTP 500 Server Error response if an error occurred during sending of SMS or Email.
In case /validate/radiuscheck is requested, the responses are modified as follows: A successful authentica-
tion returns an empty HTTP 204 response. An unsuccessful authentication returns an empty HTTP 400 response.
Error responses are the same responses as for the /validate/check endpoint.
Parameters
• serial – The serial number of the token, that tries to authenticate.
• user – The loginname/username of the user, who tries to authenticate.
• realm – The realm of the user, who tries to authenticate. If the realm is omitted, the user is
looked up in the default realm.
• type – The tokentype of the tokens, that are taken into account during authentication. Re-
quires the authz policy application_tokentype. It is ignored when a distinct serial is given.
• pass – The password, that consists of the OTP PIN and the OTP value.
• otponly – If set to 1, only the OTP value is verified. This is used in the management UI.
Only used with the parameter serial.
• transaction_id – The transaction ID for a response to a challenge request
• state – The state ID for a response to a challenge request
Return a json result with a boolean “result”: true
Example Validation Request:

POST /validate/check HTTP/1.1


Host: example.com
Accept: application/json

user=user
realm=realm1
pass=s3cret123456

1.15. Code Documentation 251


privacyIDEA Authentication System, Release 3.8

Example response for a successful authentication:

HTTP/1.1 200 OK
Content-Type: application/json

{
"detail": {
"message": "matching 1 tokens",
"serial": "PISP0000AB00",
"type": "spass"
},
"id": 1,
"jsonrpc": "2.0",
"result": {
"status": true,
"value": true
},
"version": "privacyIDEA unknown"
}

Example response for this first part of a challenge response authentication:

HTTP/1.1 200 OK
Content-Type: application/json

{
"detail": {
"serial": "PIEM0000AB00",
"type": "email",
"transaction_id": "12345678901234567890",
"multi_challenge": [ {"serial": "PIEM0000AB00",
"transaction_id": "12345678901234567890",
"message": "Please enter otp from your email",
"client_mode": "interactive"},
{"serial": "PISM12345678",
"transaction_id": "12345678901234567890",
"message": "Please enter otp from your SMS",
"client_mode": "interactive"}
]
},
"id": 2,
"jsonrpc": "2.0",
"result": {
"status": true,
"value": false
},
"version": "privacyIDEA unknown"
}

In this example two challenges are triggered, one with an email and one with an SMS. The application and thus
the user has to decide, which one to use. They can use either.
The challenges also contain the information of the “client_mode”. This tells the plugin, whether it should display
an input field to ask for the OTP value or e.g. to poll for an answered authentication. Read more at Authentication
Modes and Client Modes.

252 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Note: All challenge response tokens have the same transaction_id in this case.

Example response for a successful authentication with /samlcheck:

HTTP/1.1 200 OK
Content-Type: application/json

{
"detail": {
"message": "matching 1 tokens",
"serial": "PISP0000AB00",
"type": "spass"
},
"id": 1,
"jsonrpc": "2.0",
"result": {
"status": true,
"value": {"attributes": {
"username": "koelbel",
"realm": "themis",
"mobile": null,
"phone": null,
"myOwn": "/data/file/home/koelbel",
"resolver": "themis",
"surname": "Kölbel",
"givenname": "Cornelius",
"email": null},
"auth": true}
},
"version": "privacyIDEA unknown"
}

The response in value->attributes can contain additional attributes (like “myOwn”) which you can define
in the LDAP resolver in the attribute mapping.

System endpoints

This is the REST API for system calls to create and read system configuration.
The code of this module is tested in tests/test_api_system.py
GET /system/names/caconnector
Return a list of defined CA connectors. Each item of the list is a dictionary with the CA connector information,
including the name and defined templates, but excluding the CA connector data. This endpoint requires the
enrollCERTIFICATE right.
GET /system/names/radius
Return the list of identifiers of all defined RADIUS servers. This endpoint requires the enrollRADIUS right.
GET /system/documentation
returns an restructured text document, that describes the complete configuration.
POST /system/setDefault
define default settings for tokens. These default settings are used when new tokens are generated. The default

1.15. Code Documentation 253


privacyIDEA Authentication System, Release 3.8

settings will not affect already enrolled tokens.


JSON Parameters
• DefaultMaxFailCount – Default value for the maximum allowed authentication failures
• DefaultSyncWindow – Default value for the synchronization window
• DefaultCountWindow – Default value for the counter window
• DefaultOtpLen – Default value for the OTP value length – usually 6 or 8
• DefaultResetFailCount – Default value, if the FailCounter should be reset on successful
authentication [True|False]
Return a json result with a boolean “result”: true
POST /system/setConfig
set a configuration key or a set of configuration entries
parameter are generic keyname=value pairs.
remark In case of key-value pairs the type information could be provided by an additional parameter with
same keyname with the postfix “.type”. Value could then be ‘password’ to trigger the storing of the value
in an encrypted form

JSON Parameters
• key – configuration entry name
• value – configuration value
• type – type of the value: int or string/text or password. password will trigger to store the
encrypted value
• description – additional information for this config entry

or
JSON Parameters
• pairs (key-value) – pair of &keyname=value pairs
Return a json result with a boolean “result”: true
Example request 1:

POST /system/setConfig
key=splitAtSign
value=true

Host: example.com
Accept: application/json

Example request 2:

POST /system/setConfig
BINDDN=myName
BINDPW=mySecretPassword
BINDPW.type=password

Host: example.com
Accept: application/json

254 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

GET /system/gpgkeys
Returns the GPG keys in the config directory specified by PI_GNUPG_HOME.
Return A json list of the public GPG keys
GET /system/random
This endpoint can be used to retrieve random keys from privacyIDEA. In certain cases the client might need
random data to initialize tokens on the client side. E.g. the command line client when initializing the yubikey or
the WebUI when creating Client API keys for the yubikey.
In this case, privacyIDEA can create the random data/keys.
Query Parameters
• len – The length of a symmetric key (byte)
• encode – The type of encoding. Can be “hex” or “b64”.
Return key material
POST /system/hsm
Set the password for the security module
GET /system/hsm
Get the status of the security module.
GET /system/(key)
GET /system/
This endpoint either returns all config entries or only the value of the one config key.
This endpoint can be called by the administrator but also by the normal user, so that the normal user gets necessary
information about the system config
Parameters
• key – The key to return.
Return A json response or a single value, when queried with a key.
Rtype json or scalar
POST /system/test/(tokentype)
The call /system/test/email tests the configuration of the email token.
DELETE /system/(key)
delete a configuration key
JSON Parameters
• key – configuration key name
Returns a json result with the deleted value

1.15. Code Documentation 255


privacyIDEA Authentication System, Release 3.8

Resolver endpoints

The code of this module is tested in tests/test_api_system.py


POST /resolver/test
Send the complete parameters of a resolver to the privacyIDEA server to test, if these settings will result in a
successful connection. If you are testing existing resolvers, you can send the “__CENSORED__” password.
privacyIDEA will use the already stored password from the database.
Return a json result with True, if the given values can create a working resolver and a description.
GET /resolver/(resolver)
GET /resolver/
returns a json list of the specified resolvers. The passwords of resolvers (e.g. Bind PW of the LDAP resolver or
password of the SQL resolver) will be returned as “__CENSORED__”. You can run a POST request to update
the data and privacyIDEA will ignore the “__CENSORED__” password or you can even run a testresolver.
Parameters
• resolver (str) – the name of the resolver
• type (str) – Only return resolvers of type (like passwdresolver..)
• editable (str) – Set to “1” if only editable resolvers should be returned.
Return a json result with the configuration of resolvers
POST /resolver/(resolver)
This creates a new resolver or updates an existing one. A resolver is uniquely identified by its name.
If you update a resolver, you do not need to provide all parameters. Parameters you do not provide are left
untouched. When updating a resolver you must not change the type! You do not need to specify the type, but if
you specify a wrong type, it will produce an error.
Parameters
• resolver (str) – the name of the resolver.
• type – the type of the resolver. Valid types are passwdresolver,
ldapresolver, sqlresolver, scimresolver :type type: str :return: a json result with the value being the database id
(>0)
Additional parameters depend on the resolver type.
LDAP:
• LDAPURI
• LDAPBASE
• AUTHTYPE
• BINDDN
• BINDPW
• TIMEOUT
• CACHE_TIMEOUT
• SIZELIMIT
• LOGINNAMEATTRIBUTE
• LDAPSEARCHFILTER

256 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

• LDAPFILTER
• LOGINNAMEATTRIBUTE
• MULTIVALUEATTRIBUTES
• USERINFO
• UIDTYPE
• NOREFERRALS - True|False
• NOSCHEMAS - True|False
• EDITABLE - True|False
• START_TLS - True|False
• TLS_VERIFY - True|False
• TLS_VERSION
SQL:
• Database
• Driver
• Server
• Port
• User
• Password
• Table
• Map
Passwd
• Filename
DELETE /resolver/(resolver)
This function deletes an existing resolver. A resolver can not be deleted, if it is contained in a realm
Parameters
• resolver – the name of the resolver to delete.
Return json with success or fail

Realm endpoints

The realm endpoints are used to define realms. A realm groups together many users. Administrators can manage the
tokens of the users in such a realm. Policies and tokens can be assigned to realms.
A realm consists of several resolvers. Thus you can create a realm and gather users from LDAP and flat file source into
one realm or you can pick resolvers that collect users from different points from your vast LDAP directory and group
these users into a realm.
You will only be able to see and use user object, that are contained in a realm.
The code of this module is tested in tests/test_api_system.py

1.15. Code Documentation 257


privacyIDEA Authentication System, Release 3.8

GET /realm/superuser
This call returns the list of all superuser realms as they are defined in pi.cfg. See The Config File for more
information about this.
Return a json result with a list of realms
Example request:

GET /superuser HTTP/1.1


Host: example.com
Accept: application/json

Example response:

HTTP/1.1 200 OK
Content-Type: application/json

{
"id": 1,
"jsonrpc": "2.0",
"result": {
"status": true,
"value": ["superuser",
"realm2"]
}
},
"version": "privacyIDEA unknown"
}

GET /realm/
This call returns the list of all defined realms. It takes no arguments.
Return a json result with a list of realms
Example request:

GET / HTTP/1.1
Host: example.com
Accept: application/json

Example response:

HTTP/1.1 200 OK
Content-Type: application/json

{
"id": 1,
"jsonrpc": "2.0",
"result": {
"status": true,
"value": {
"realm1_with_resolver": {
"default": true,
"resolver": [
{
"name": "reso1_with_realm",
(continues on next page)

258 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

(continued from previous page)


"type": "passwdresolver"
}
]
}
}
},
"version": "privacyIDEA unknown"
}

POST /realm/(realm)
This call creates a new realm or reconfigures a realm. The realm contains a list of resolvers.
In the result it returns a list of added resolvers and a list of resolvers, that could not be added.
Parameters
• realm – The unique name of the realm
• resolvers (string or list) – A comma separated list of unique resolver names or a list
object
• priority – Additional parameters priority.<resolvername> define the priority of the re-
solvers within this realm.
Return a json result with a list of Realms
Example request:
To create a new realm “newrealm”, that consists of the resolvers “reso1_with_realm” and “reso2_with_realm”
call:

POST /realm/newrealm HTTP/1.1


Host: example.com
Accept: application/json
Content-Length: 26
Content-Type: application/x-www-form-urlencoded

resolvers=reso1_with_realm, reso2_with_realm
priority.reso1_with_realm=1
priority.reso2_with_realm=2

Example response:

HTTP/1.1 200 OK
Content-Type: application/json

{
"id": 1,
"jsonrpc": "2.0",
"result": {
"status": true,
"value": {
"added": ["reso1_with_realm", "reso2_with_realm"],
"failed": []
}
}
(continues on next page)

1.15. Code Documentation 259


privacyIDEA Authentication System, Release 3.8

(continued from previous page)


"version": "privacyIDEA unknown"
}

DELETE /realm/(realm)
This call deletes the given realm.
Parameters
• realm – The name of the realm to delete
Return a json result with value=1 if deleting the realm was successful
Example request:

DELETE /realm/realm_to_delete HTTP/1.1


Host: example.com
Accept: application/json

Example response:

HTTP/1.1 200 OK
Content-Type: application/json

{
"id": 1,
"jsonrpc": "2.0",
"result": {
"status": true,
"value": 1
},
"version": "privacyIDEA unknown"
}

Default Realm endpoints

These endpoints are used to define the default realm, retrieve it and delete it.
DELETE /defaultrealm
This call deletes the default realm.
Return a json result with either 1 (success) or 0 (fail)
Example response:

{
"id": 1,
"jsonrpc": "2.0",
"result": {
"status": true,
"value": 1
},
"version": "privacyIDEA unknown"
}

260 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

GET /defaultrealm
This call returns the default realm
Return a json description of the default realm with the resolvers
Example response:

{
"id": 1,
"jsonrpc": "2.0",
"result": {
"status": true,
"value": {
"defrealm": {
"default": true,
"resolver": [
{
"name": "defresolver",
"type": "passwdresolver"
}
]
}
}
},
"version": "privacyIDEA unknown"
}

POST /defaultrealm/(realm)
This call sets the default realm.
Parameters
• realm – the name of the realm, that should be the default realm
Return a json result with either 1 (success) or 0 (fail)

Token endpoints

The token API can be accessed via /token.


You need to authenticate to gain access to these token functions. If you are authenticated as administrator, you can
manage all tokens. If you are authenticated as normal user, you can only manage your own tokens. Some API calls are
only allowed to be accessed by administrators.
To see how to authenticate read Authentication endpoints.
POST /token/setrandompin/(serial)
POST /token/setrandompin
Set the OTP PIN for a specific token to a random value.
The token is identified by the unique serial number.
JSON Parameters
• serial (basestring) – the serial number of the single token to reset
Return In “value” returns the number of PINs set. The detail-section contains the key “pin” with the
set PIN.

1.15. Code Documentation 261


privacyIDEA Authentication System, Release 3.8

Rtype json object


POST /token/description/(serial)
POST /token/description
This endpoint can be used by the user or by the admin to set the description of a token.
JSON Parameters
• description (basestring) – The description for the token
Parameters
• serial –
Return
GET /token/challenges/(serial)
GET /token/challenges/
This endpoint returns the active challenges in the database or returns the challenges for a single token by its serial
number
Query Parameters
• serial – The optional serial number of the token for which the challenges should be returned
• sortby – sort the output by column
• sortdir – asc/desc
• page – request a certain page
• pagesize – limit the number of returned tokens
• transaction_id – only returns challenges for this transaction_id. This is useful when
working with push or tiqr tokens.
Return json
POST /token/unassign
Unssign a token from a user. You can either provide “serial” as an argument to unassign this very token or you
can provide user and realm, to unassign all tokens of a user.
Return In case of success it returns the number of unassigned tokens in “value”.
Rtype JSON object
POST /token/copyuser
Copy the token user from one token to the other.
JSON Parameters
• from (basestring) – the serial number of the token, from where you want to copy the pin.
• to (basestring) – the serial number of the token, from where you want to copy the pin.
Return returns value=True in case of success
Rtype bool
POST /token/disable/(serial)
POST /token/disable
Disable a single token or all the tokens of a user either by providing the serial number of the single token or a
username and realm.
Disabled tokens can not be used to authenticate but can be enabled again.

262 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

JSON Parameters
• serial (basestring) – the serial number of the single token to disable
• user (basestring) – The login name of the user
• realm (basestring) – the realm name of the user
Return In case of success it returns the number of disabled tokens in “value”.
Rtype json object
POST /token/copypin
Copy the token PIN from one token to the other.
JSON Parameters
• from (basestring) – the serial number of the token, from where you want to copy the pin.
• to (basestring) – the serial number of the token, from where you want to copy the pin.
Return returns value=True in case of success
Rtype bool
POST /token/assign
Assign a token to a user.
JSON Parameters
• serial – The token, which should be assigned to a user
• user – The username of the user
• realm – The realm of the user
Return In case of success it returns “value”: True.
Rtype json object
POST /token/revoke/(serial)
POST /token/revoke
Revoke a single token or all the tokens of a user. A revoked token will usually be locked. A locked token can not
be used anymore. For certain token types additional actions might occur when revoking a token.
JSON Parameters
• serial (basestring) – the serial number of the single token to revoke
• user (basestring) – The login name of the user
• realm (basestring) – the realm name of the user
Return In case of success it returns the number of revoked tokens in “value”.
Rtype JSON object
POST /token/enable/(serial)
POST /token/enable
Enable a single token or all the tokens of a user.
JSON Parameters
• serial (basestring) – the serial number of the single token to enable
• user (basestring) – The login name of the user
• realm (basestring) – the realm name of the user

1.15. Code Documentation 263


privacyIDEA Authentication System, Release 3.8

Return In case of success it returns the number of enabled tokens in “value”.


Rtype json object
POST /token/resync/(serial)
POST /token/resync
Resync the OTP token by providing two consecutive OTP values.
JSON Parameters
• serial (basestring) – the serial number of the single token to reset
• otp1 (basestring) – First OTP value
• otp2 (basestring) – Second OTP value
Return In case of success it returns “value”=True
Rtype json object
POST /token/setpin/(serial)
POST /token/setpin
Set the the user pin or the SO PIN of the specific token. Usually these are smartcard or token specific PINs. E.g.
the userpin is used with mOTP tokens to store the mOTP PIN.
The token is identified by the unique serial number.
JSON Parameters
• serial (basestring) – the serial number of the single token to reset
• userpin (basestring) – The user PIN of a smartcard
• sopin (basestring) – The SO PIN of a smartcard
• otppin (basestring) – The OTP PIN of a token
Return In “value” returns the number of PINs set.
Rtype json object
POST /token/reset/(serial)
POST /token/reset
Reset the failcounter of a single token or of all tokens of a user.
JSON Parameters
• serial (basestring) – the serial number of the single token to reset
• user (basestring) – The login name of the user
• realm (basestring) – the realm name of the user
Return In case of success it returns “value”=True
Rtype json object
POST /token/init
create a new token.
JSON Parameters
• otpkey – required: the secret key of the token
• genkey – set to =1, if key should be generated. We either need otpkey or genkey
• keysize – the size (byte) of the key. Either 20 or 32. Default is 20

264 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

• serial – the serial number/identifier of the token


• description – A description for the token
• pin – the pin of the token. “OTP PIN”
• user – the login user name. This user gets the token assigned
• realm – the realm of the user.
• type – the type of the token
• tokenrealm – additional realms, the token should be put into
• otplen – length of the OTP value
• hashlib – used hashlib sha1, sha256 or sha512
• validity_period_start – The beginning of the validity period
• validity_period_end – The end of the validity period
• 2stepinit – set to =1 in conjunction with genkey=1 if you want a 2 step initialization
process. Additional policies have to be set see Two Step Enrollment.
• otpkeyformat – used to supply the OTP key in alternate formats, currently hex or
base32check (see Two Step Enrollment)
• rollover – Set this to 1 or true to indicate, that you want to rollover a token. This is
mandatory to rollover tokens, that are in the clientwait state.
Return a json result with a boolean “result”: true
Depending on the token type there can be additional parameters. In the tokenclass you can see additional param-
eters in the method update when looking for getParam functions.
Example response:

HTTP/1.1 200 OK
Content-Type: application/json

{
"detail": {
"googleurl": {
"description": "URL for google Authenticator",
"img": "<img width=250 src="data:image/png;base64,
˓→iVBORw0KGgoAAAANSUhEUgAAAcIAAAHCAQAAAABUY/

˓→ToAAADsUlEQVR4nO2czY3bMBCF34QCfKSALcClyB2kpCAlpQOxlBQQgDwaoPBy4I+p9W4OSRaWF28OgizxgylgMJw/

˓→0oi/k/

˓→DlL0FApEiRIkWKFCnyeKRVmdrjNAFh3srTMuSS2qjLg2cr8pDkQpKMgF3SBITz1QA4YolVfQA4kiT35CNmK/

˓→JQZLM8aQaWH+3pEkEgTZlhBojksgGAAS7/83+K/ORkOF/

˓→NLtismiCfYXbOd+AxZivygCTXdCLCDJRLfTbhTo4wW5FHIJtyeAJIAJb4AobLBIP/

˓→ZQRAwMcyakxIPtd3ivw4EqObXJzody9t1EKS63N9p8iPI4sO3QTwGSSbA1Q0x+cWunWRDolsUjSnxvau6VB0xMIMrp4EP

˓→i6WtedIhkXupS1MEsMRmaVafh7dVfXwGV0D+kMj3yXDOsIsngXQiV59R0tZIE7jC0b4VA3WE2Yo8CtkTPy7b8sPA8HWbW

˓→xOkR9B4maCbnF8c53vHGuuLVaTHRLZpBgYgweAVP0hLPElA+mFtVrvf3W/

˓→aTM+brYij0j23o8JthAweNc1J5cCmSFNYDCAS5wfOVuRRyT7QpVL9F6XLN/

˓→zjhG4ZSAHj1trmcgmLcfoWoq6/

˓→B4LZLeqBxmVpxb5WobYfl8vaxfU7DSA4mdLh0S+TW5W2xXTiaWZ0WbALqiXmi5KU/

˓→n5tN8p8r+TzaqUH936MKNW6/2uIkvZIZF/IEleDfAZZnYi1zSB/

˓→DmVpa2YJZtVLxP5JmnfWCutty5qwNcFrWSsV2xGxs3+03+K/

˓→Cxk74WtTWflDr652L0XtoZuylOLvJNb9H7XPzQ0DOX9RTokcpAhAzRYpN4LO5TsI1rQLx0SOci4z7VcSuvQZgxWX1gfbf

˓→dTe9U6RL6WtoIBqDs33NA7Xdey3SYzrWUi99L8IfJW4cC4pYNjg+Ow/
(continues on next page)
˓→+O5vlPkx5OpnSsUzler2cbS29g8pmBmWH6elGMU+UqaFwS0NBBa9O45Rmhr26Mof0jkTt440MNlC9aOGQqzA8McaQs34x

˓→cDZijwwGcxqs0c9gNFx5w9t7e18hNmKPBRZ7NDtXKF6V1qp2e9qtZ7DkOf6TpEiRYoUKVKkyPfkNyq7YXtdjZCIAAAAAE

"/>",
1.15. Code˓→Documentation 265
privacyIDEA Authentication System, Release 3.8

(continued from previous page)


"value": "otpauth://hotp/mylabel?
˓→secret=GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ&counter=0"

},
"oathurl": {
"description": "URL for OATH token",
"img": "<img width=250 src="data:image/png;base64,
˓→iVBORw0KGgoAAAANSUhEUgAAAcIAAAHCAQAAAABUY/

˓→ToAAADfElEQVR4nO2cTYrjMBCFX40EvZRvkKPIN5gz9c3so/

˓→QBBqxlwObNQpIlp2cYaBI6zrxamDjyhywo6leyEV+T+ccXQUCkSJEiRYoUKfL5SCviy7+zmZWBAbARmwGpPjXeZU6RL0Z

˓→MEBeAU/JoA52pOuk6Rd6f9H/

˓→60xBWbwCMyG7Mg0j3mlPky5OOiB9v5AQACCQnONr4yDlFnpisdigQQAIM4WpE2oyAWy0umyfCku1QX5A81zpFPo5EHybD

˓→J4rc+So+++S2zy1ofDVezMXmURtoZ1ynyEeRuh1xXSiwJPtCFRyUygupDIm+l5fa9Q+Na0rT8yCG3lw6JPEqtMZaCUNfm

˓→DK0cDWBXqapczY0ptxd5kFZjLEqzlJi6C4WyHYJjHZAOieyk2aGsSNyjoF2l0Jsg9TpE/

˓→oVMHpgvK8wupRZkIwDMQy0S5QMfbVfsOdcp8v5kF1M3N9ZaGrX/sbf2g+yQyFtpPdW2/

˓→75pTtGX5tWCcnuRt9L1OtguLcFve9DazmrpkMheOn3Ju4aA4tX6gVopiurbi7yV3Lc3IJ+vh0VuHoBbAWyeSH41hF+fzz

˓→J7z3UzG8PVSlqfPMrlm99W5FOSsUY8Noarmdkb+T7UTSF7Wv8kbyvyqcguL+u23k/

˓→7cDvdmm9Vpxb5LzLbobErObbc/

˓→lFzijw3eZtvcR4WAtjKx2Lmn1djztBAWN5ZPX3X24p8RrI719HcWNnsEVoz1vWPyJeJ7KXYoTln7A4Wcz6/

˓→eQL7xxxyRr95IlwNskMiezF941ykSJEiRYoU+Z+TvwF49nApsKFZZAAAAABJRU5ErkJggg=="/

˓→>",

"value": "oathtoken:///addToken?name=mylabel&lockdown=true&
˓→key=3132333435363738393031323334353637383930"

},
"otpkey": {
"description": "OTP seed",
"img": "<img width=200 src="data:image/png;base64,
˓→iVBORw0KGgoAAAANSUhEUgAAAUoAAAFKAQAAAABTUiuoAAAB70lEQVR4nO2aTY6jQAyFPw9IWYI0B+ijwNHhKH0DWLZU6

˓→CXkQkfIsnWRU/22ViZ4x/9pIQaKCBBhpooEeilqPGrAWzdjGYy8/

˓→94QICfQftJEkTAIsBlYBKkqSf6DECAn0HnfMRkj4fnjfrATOrzxEQ6I6oX74bYGJuzxIQ6H9kqySqSjCfISDQX6CNpKE8

˓→19B9PgQsbgnPEBDonrCXyZMB/HMaFZOnu6DWz2aMZqaBZ79Vw9gu0W/

˓→dBsU7qm4CL16aKq9geonhcq2BlqR4jirRSYImoaF8eO8c2boeXR38YnRavIwJkNFUsg1xudZAy5ywreSFyqcabgxr8lE7

˓→Ao2AJtXAYoIEYzsVi3i51kBz3Rq8O658RFhKVn4Rdesu6MYTemZoEm468kh+TejlWgNdjXoeMGVjOJXXnVJk6zboa1uFb

˓→"/>",

"value": "seed://3132333435363738393031323334353637383930"
},
"serial": "OATH00096020"
},
"id": 1,
"jsonrpc": "2.0",
"result": {
"status": true,
"value": true
},
"version": "privacyIDEA unknown"
}

2 Step Enrollment
Some tokens might need a 2 step initialization process like a smartphone app. This way you can create a shared
secret from a part generated by the privacyIDEA server and from a second part generated by the smartphone
app/client.
The first API call would be

266 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

POST /token/init

2stepinit=1

The response would contain the otpkey generated by the server and the serial number of the token. At this point,
the token is deactivated and marked as being in an enrollment state. The client would also generated a component
of the key and send his component to the privacyIDEA server:
The second API call would be

POST /token/init

serial=<serial from the previous response>


otpkey=<key part generated by the client>

Each tokenclass can define its own way to generate the secret key by overwriting the method
generate_symmetric_key. The Base Tokenclass contains an extremely simple way by concatenating the two
parts. See generate_symmetric_key()
verify enrollment
Some tokens can be configured via enrollment policy so that the user needs to provide some verification that e.g.
a QR code was scanned correctly or the token works correctly in general. The specific way depends on the token
class. The necessary token class functions are
• verify_enrollment()
• prepare_verify_enrollment()
The first API call to /token/init returns responses in:

{"detail": {"verify": {"message": "Please provide a valid OTP value."},


"rollout_state": "verify"}}

The second API call then needs to send the serial number and a response

POST /token/init

serial=<serial from the previous response>


verify=<e.g. the OTP value>

As long as the token is in state “verify” it can not be used for authentication.
POST /token/set/(serial)
POST /token/set
This API is only to be used by the admin! This can be used to set token specific attributes like
• description
• count_window
• sync_window
• count_auth_max
• count_auth_success_max
• hashlib,
• max_failcount

1.15. Code Documentation 267


privacyIDEA Authentication System, Release 3.8

• validity_period_start
• validity_period_end
The token is identified by the unique serial number or by the token owner. In the later case all tokens of the owner
will be modified.
The validity period needs to be provided in the format YYYY-MM-DDThh:mm+oooo
JSON Parameters
• serial (basestring) – the serial number of the single token to reset
• user (basestring) – The username of the token owner
• realm (basestring) – The realm name of the token owner
Return returns the number of attributes set in “value”
Rtype json object
GET /token/
Display the list of tokens. Using different parameters you can choose, which tokens you want to get and also in
which format you want to get the information (outform).
Query Parameters
• serial – Display the token data of this single token. You can do a not strict matching by
specifying a serial like “OATH”.
• type – Display only token of type. You ca do a non strict matching by specifying a tokentype
like “otp”, to file hotp and totp tokens.
• user – display tokens of this user
• tokenrealm – takes a realm, only the tokens in this realm will be displayed
• description (basestring) – Display token with this kind of description
• sortby – sort the output by column
• sortdir – asc/desc
• page – request a certain page
• assigned – Only return assigned (True) or not assigned (False) tokens
• active – Only return active (True) or inactive (False) tokens
• pagesize – limit the number of returned tokens
• outform – if set to “csv”, than the token list will be given in CSV
• rollout_state – only list tokens with the given rollout_state
• infokey – only list tokens, where the infokey has the given infovalue
• infovalue – only list tokens, where the infokey has the given infovalue
Return a json result with the data being a list of token dictionaries:

{ "data": [ { <token1> }, { <token2> } ]}

Rtype json

268 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

GET /token/getserial/(otp)
Get the serial number for a given OTP value. If the administrator has a token, he does not know to whom it
belongs, he can type in the OTP value and gets the serial number of the token, that generates this very OTP
value.
Query Parameters
• otp – The given OTP value
• type – Limit the search to this token type
• unassigned – If set=1, only search in unassigned tokens
• assigned – If set=1, only search in assigned tokens
• count – if set=1, only return the number of tokens, that will be searched
• serial – This can be a substring of serial numbers to search in.
• window – The number of OTP look ahead (default=10)
Return The serial number of the token found
POST /token/group/(serial)/
groupname
POST /token/group/(serial)
Assigns a token to a given tokengroup.
If no groupname is given, we expect a body data “groups”, that contains a list of tokengroups. tokengroups that
are not contained in this list, will be removed.
JSON Parameters
• serial (basestring) – the serial number of the token
• groupname (basestring) – The name of the tokengroup
• groups (list) – A list of tokengroups
Return
Rtype json object
DELETE /token/group/(serial)/
groupname Unassigned a token from a tokengroup.
JSON Parameters
• serial (basestring) – the serial number of the token
• groupname (basestring) – The name of the tokengroup
Return
Rtype json object
POST /token/realm/(serial)
Set the realms of a token. The token is identified by the unique serial number
You can call the function like this: POST /token/realm?serial=<serial>&realms=<something> POST /to-
ken/realm/<serial>?realms=<hash>

JSON Parameters
• serial (basestring) – the serial number of the single token to reset
• realms (basestring) – The realms the token should be assigned to. Comma separated

1.15. Code Documentation 269


privacyIDEA Authentication System, Release 3.8

Return returns value=True in case of success


Rtype bool

POST /token/info/(serial)/
key Add a specific tokeninfo entry to a token. Already existing entries with the same key are overwritten.
Parameters
• serial – the serial number/identifier of the token
• key – token info key that should be set
Query Parameters
• value – token info value that should be set
Return returns value=True in case the token info could be set
Rtype bool
DELETE /token/info/(serial)/
key Delete a specific tokeninfo entry of a token.
Parameters
• serial – the serial number/identifier of the token
• key – token info key that should be deleted
Return returns value=True in case a matching token was found, which does not necessarily mean
that the matching token had a tokeninfo value set in the first place. :rtype: bool
POST /token/load/(filename)
The call imports the given file containing token definitions. The file can be an OATH CSV file, an aladdin XML
file or a Yubikey CSV file exported from the yubikey initialization tool.
The function is called as a POST request with the file upload.
JSON Parameters
• filename – The name of the token file, that is imported
• type – The file type. Can be “aladdin-xml”, “oathcsv” or “yubikeycsv”.
• tokenrealms – comma separated list of realms.
• psk – Pre Shared Key, when importing PSKC
• pskcValidateMAC – Determines how invalid MACs should be handled when importing
PSKC. Allowed values are ‘no_check’, ‘check_fail_soft’ and ‘check_fail_hard’.
Return The number of the imported tokens
Rtype int
POST /token/lost/(serial)
Mark the specified token as lost and create a new temporary token. This new token gets the new serial number
“lost<old-serial>” and a certain validity period and the PIN of the lost token.
This method can be called by either the admin or the user on his own tokens.
You can call the function like this: POST /token/lost/serial

JSON Parameters
• serial (basestring) – the serial number of the lost token.

270 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Return returns value=dictionary in case of success


Rtype bool

DELETE /token/(serial)
Delete a token by its serial number.
JSON Parameters
• serial – The serial number of a single token.
Return In case of success it return the number of deleted tokens in “value”
Rtype json object

User endpoints

The user endpoints is a subset of the system endpoint.


GET /user/editable_attributes/
The resulting editable custom attributes according to the policies are returned. This can be a user specific result.
When a user is calling the endpoint the parameters will be implicitly set.
Httpparam user The username of the user, for whom the attribute should be set
Httpparam resolver The resolver of the user (optional)
Httpparam realm The realm of the user (optional)
Works for admins and normal users. :return:
POST /user/attribute
Set a custom attribute for a user. The user is specified by the usual parameters user, resolver and realm. When a
user is calling the endpoint the parameters will be implicitly set.
Httpparam user The username of the user, for whom the attribute should be set
Httpparam resolver The resolver of the user (optional)
Httpparam realm The realm of the user (optional)
Httpparam key The name of the attributes
Httpparam value The value of the attribute
Httpparam type an optional type of the attribute
The database id of the attribute is returned. The return value thus should be >=0.
GET /user/attribute
Return the custom attribute of the given user. This does not return the user attributes which are contained in the
user store! The user is specified by the usual parameters user, resolver and realm. When a user is calling the
endpoint the parameters will be implicitly set.
Httpparam user The username of the user, for whom the attribute should be set
Httpparam resolver The resolver of the user (optional)
Httpparam realm The realm of the user (optional)
Httpparam key The optional name of the attribute. If it is not specified all custom attributes of the
user are returned.

1.15. Code Documentation 271


privacyIDEA Authentication System, Release 3.8

GET /user/
list the users in a realm
A normal user can call this endpoint and will get information about his own account.
Parameters
• realm – a realm that contains several resolvers. Only show users from this realm
• resolver – a distinct resolvername
• <searchexpr> – a search expression, that depends on the ResolverClass
Return json result with “result”: true and the userlist in “value”.
Example request:

GET /user?realm=realm1 HTTP/1.1


Host: example.com
Accept: application/json

Example response:

HTTP/1.1 200 OK
Content-Type: application/json

{
"id": 1,
"jsonrpc": "2.0",
"result": {
"status": true,
"value": [
{
"description": "Cornelius Kölbel,,+49 151 2960 1417,+49 561 3166797,
˓→[email protected]",

"email": "[email protected]",
"givenname": "Cornelius",
"mobile": "+49 151 2960 1417",
"phone": "+49 561 3166797",
"surname": "Kölbel",
"userid": "1009",
"username": "cornelius",
"resolver": "name-of-resolver"
}
]
},
"version": "privacyIDEA unknown"
}

POST /user/
POST /user
Create a new user in the given resolver.
Example request:

POST /user
user=new_user
(continues on next page)

272 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

(continued from previous page)


resolver=<resolvername>
surname=...
givenname=...
email=...
mobile=...
phone=...
password=...
description=...

Host: example.com
Accept: application/json

PUT /user/
PUT /user
Edit a user in the user store. The resolver must have the flag editable, so that the user can be deleted. Only
administrators are allowed to edit users.
Example request:

PUT /user
user=existing_user
resolver=<resolvername>
surname=...
givenname=...
email=...
mobile=...
phone=...
password=...
description=...

Host: example.com
Accept: application/json

Note: Also a user can call this function to e.g. change his password. But in this case the parameter “user” and
“resolver” get overwritten by the values of the authenticated user, even if he specifies another username.

DELETE /user/attribute/(attrkey)/
username/realm Delete a specified custom attribute from the user. The user is specified by the positional pa-
rameters user and realm.
Httpparam user The username of the user, for whom the attribute should be set
Httpparam realm The realm of the user
Httpparam key The name of the attribute that should be deleted from the user.
Returns the number of deleted attributes.
DELETE /user/(resolvername)/
username Delete a User in the user store. The resolver must have the flag editable, so that the user can be deleted.
Only administrators are allowed to delete users.
Delete a user object in a user store by calling
Example request:

1.15. Code Documentation 273


privacyIDEA Authentication System, Release 3.8

DELETE /user/<resolvername>/<username>
Host: example.com
Accept: application/json

The code of this module is tested in tests/test_api_system.py

Policy endpoints

The policy endpoints are a subset of the system endpoint.


You can read more about policies at Policies.
GET /policy/check
This function checks, if the given parameters would match a defined policy or not.
Query Parameters
• user – the name of the user
• realm – the realm of the user or the realm the administrator want to do administrative tasks
on.
• resolver – the resolver of a user
• scope – the scope of the policy
• action – the action that is done - if applicable
• client (IP_Address) – the client, from which this request would be issued
Return a json result with the keys allowed and policy in the value key
Rtype json
Status Codes
• 200 OK – Policy created or modified.
• 401 Unauthorized – Authentication failed
Example request:

GET /policy/check?user=admin&realm=r1&client=172.16.1.1 HTTP/1.1


Host: example.com
Accept: application/json

Example response:

HTTP/1.0 200 OK
Content-Type: application/json

{
"id": 1,
"jsonrpc": "2.0",
"result": {
"status": true,
"value": {
"pol_update_del": {
"action": "enroll",
(continues on next page)

274 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

(continued from previous page)


"active": true,
"client": "172.16.0.0/16",
"name": "pol_update_del",
"realm": "r1",
"resolver": "test",
"scope": "selfservice",
"time": "",
"user": "admin"
}
}
},
"version": "privacyIDEA unknown"
}

GET /policy/defs/(scope)
GET /policy/defs
This is a helper function that returns the POSSIBLE policy definitions, that can be used to define your policies.
If the given scope is “conditions”, this returns a dictionary with the following keys:
• "sections", containing a dictionary mapping each condition section name to a dictionary with the
following keys:
– "description", a human-readable description of the section
• "comparators", containing a dictionary mapping each comparator to a dictionary with the following keys:

– "description", a human-readable description of the comparator


if the scope is “pinodes”, it returns a list of the configured privacyIDEA nodes.
Query Parameters
• scope – if given, the function will only return policy definitions for the given scope.
Return The policy definitions of the allowed scope with the actions and action types. The top level
key is the scope.
Rtype dict
GET /policy/export/(export)
GET /policy/(name)
GET /policy/
this function is used to retrieve the policies that you defined. It can also be used to export the policy to a file.
Query Parameters
• name – will only return the policy with the given name
• export – The filename needs to be specified as the third part of the URL like policy.cfg. It
will then be exported to this file.
• realm – will return all policies in the given realm
• scope – will only return the policies within the given scope
• active – Set to true or false if you only want to display active or inactive policies.
Return a json result with the configuration of the specified policies

1.15. Code Documentation 275


privacyIDEA Authentication System, Release 3.8

Rtype json
Status Codes
• 200 OK – Policy created or modified.
• 401 Unauthorized – Authentication failed
Example request:
In this example a policy “pol1” is created.

GET /policy/pol1 HTTP/1.1


Host: example.com
Accept: application/json

Example response:

HTTP/1.0 200 OK
Content-Type: application/json

{
"id": 1,
"jsonrpc": "2.0",
"result": {
"status": true,
"value": {
"pol_update_del": {
"action": "enroll",
"active": true,
"client": "1.1.1.1",
"name": "pol_update_del",
"realm": "r1",
"resolver": "test",
"scope": "selfservice",
"time": "",
"user": "admin"
}
}
},
"version": "privacyIDEA unknown"
}

POST /policy/disable/(name)
Disable a given policy by its name.
JSON Parameters
• name – The name of the policy
Return ID in the database
POST /policy/enable/(name)
Enable a given policy by its name.
JSON Parameters
• name – Name of the policy
Return ID in the database

276 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

POST /policy/import/(filename)
This function is used to import policies from a file.
JSON Parameters
• filename – The name of the file in the request
Form Parameters
• file – The uploaded file contents
Return A json response with the number of imported policies.
Status Codes
• 200 OK – Policy created or modified.
• 401 Unauthorized – Authentication failed
Example request:

POST /policy/import/backup-policy.cfg HTTP/1.1


Host: example.com
Accept: application/json

Example response:

HTTP/1.0 200 OK
Content-Type: application/json

{
"id": 1,
"jsonrpc": "2.0",
"result": {
"status": true,
"value": 2
},
"version": "privacyIDEA unknown"
}

POST /policy/(name)
Creates a new policy that defines access or behaviour of different actions in privacyIDEA
JSON Parameters
• name (basestring) – name of the policy
• scope – the scope of the policy like “admin”, “system”, “authentication” or “selfservice”
• adminrealm – Realm of the administrator. (only for admin scope)
• adminuser – Username of the administrator. (only for admin scope)
• action – which action may be executed
• realm – For which realm this policy is valid
• resolver – This policy is valid for this resolver
• user – The policy is valid for these users. string with wild cards or list of strings
• time – on which time does this policy hold
• client (IP address with subnet) – for which requesting client this should be

1.15. Code Documentation 277


privacyIDEA Authentication System, Release 3.8

• active – bool, whether this policy is active or not


• check_all_resolvers – bool, whether all all resolvers in which the user exists should be
checked with this policy.
• conditions – a (possibly empty) list of conditions of the policy. Each condition is en-
coded as a list with 5 elements: [section (string), key (string), comparator
(string), value (string), active (boolean)] Hence, the conditions parame-
ter expects a list of lists. When privacyIDEA checks if a defined policy should take effect,
all conditions of the policy must be fulfilled for the policy to match. Note that the order of
conditions is not guaranteed to be preserved.
Return a json result with success or error
Status Codes
• 200 OK – Policy created or modified.
• 401 Unauthorized – Authentication failed
Example request:
In this example a policy “pol1” is created.

POST /policy/pol1 HTTP/1.1


Host: example.com
Accept: application/json

scope=admin
realm=realm1
action=enroll, disable

The policy POST request can also take the parameter of conditions. This is a list of conditions sets: [ [ “user-
info”, “memberOf”, “equals”, “groupA”, “true” ], [ . . . ] ] With the entries being the section, the key, the
comparator, the value and active. For more on conditions see Extended Policy Conditions.
Example response:

HTTP/1.0 200 OK
Content-Length: 354
Content-Type: application/json

{
"id": 1,
"jsonrpc": "2.0",
"result": {
"status": true,
"value": {
"setPolicy pol1": 1
}
},
"version": "privacyIDEA unknown"
}

DELETE /policy/(name)
This deletes the policy of the given name.
JSON Parameters
• name – the policy with the given name

278 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Return a json result about the delete success. In case of success value > 0
Status Codes
• 200 OK – Policy created or modified.
• 401 Unauthorized – Authentication failed
Example request:
In this example a policy “pol1” is created.

DELETE /policy/pol1 HTTP/1.1


Host: example.com
Accept: application/json

Example response:

HTTP/1.0 200 OK
Content-Type: application/json

{
"id": 1,
"jsonrpc": "2.0",
"result": {
"status": true,
"value": 1
},
"version": "privacyIDEA unknown"
}

Event endpoints

This endpoint is used to create, modify, list and delete Event Handling Configuration. Event handling configuration is
stored in the database table “eventhandling”
The code of this module is tested in tests/test_api_events.py
GET /event/(eventid)
GET /event/
returns a json list of the event handling configuration
Or
returns a list of available events when calling as /event/available
Or
the available handler modules when calling as /event/handlermodules
POST /event
This creates a new event handling definition
Parameters
• name – A describing name of the event.bool
• id – (optional) when updating an existing event you need to specify the id
• event – A comma separated list of events

1.15. Code Documentation 279


privacyIDEA Authentication System, Release 3.8

• handlermodule – A handlermodule
• action – The action to perform
• ordering – An integer number
• position – “pre” or “post”
• conditions – Conditions, when the event will trigger
• options. – A list of possible options.
GET /event/conditions/(handlermodule)
Return the list of conditions a handlermodule provides.
Parameters
• handlermodule – Identifier of the handler module like “UserNotification”
Return list oft actions
GET /event/positions/(handlermodule)
Return the list of positions a handlermodule provides.
Parameters
• handlermodule – Identifier of the handler module like “UserNotification”
Return list oft actions
GET /event/actions/(handlermodule)
Return the list of actions a handlermodule provides.
Parameters
• handlermodule – Identifier of the handler module like “UserNotification”
Return list oft actions
POST /event/disable/(eventid)
Disable a given policy by its name.
JSON Parameters
• name – The name of the policy
Return ID in the database
POST /event/enable/(eventid)
Enable a given event by its id.
JSON Parameters
• eventid – ID of the event
Return ID in the database
DELETE /event/(eid)
this function deletes an existing event handling configuration
Parameters
• eid – The id of the event handling configuration
Return json with success or fail

280 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

This endpoint is used to create, modify, list and delete Machine Resolvers. Machine Resolvers fetch machine informa-
tion from remote machine stores like a hosts file or an Active Directory.
The code of this module is tested in tests/test_api_machineresolver.py

Machine Resolver endpoints

POST /machineresolver/test
This function tests, if the given parameter will create a working machine resolver. The Machine Resolver Class
itself verifies the functionality. This can also be network connectivity to a Machine Store.
Return a json result with bool
GET /machineresolver/
returns a json list of all machine resolver.
Parameters
• type – Only return resolvers of type (like “hosts”. . . )
POST /machineresolver/(resolver)
This creates a new machine resolver or updates an existing one. A resolver is uniquely identified by its name.
If you update a resolver, you do not need to provide all parameters. Parameters you do not provide are left
untouched. When updating a resolver you must not change the type! You do not need to specify the type, but if
you specify a wrong type, it will produce an error.
Parameters
• resolver (basestring) – the name of the resolver.
• type (string) – the type of the resolver. Valid types are. . . “hosts”
Return a json result with the value being the database id (>0)
Additional parameters depend on the resolver type.
hosts:
• filename
DELETE /machineresolver/(resolver)
this function deletes an existing machine resolver
Parameters
• resolver – the name of the resolver to delete.
Return json with success or fail
GET /machineresolver/(resolver)
This function retrieves the definition of a single machine resolver.
Parameters
• resolver – the name of the resolver
Return a json result with the configuration of a specified resolver

1.15. Code Documentation 281


privacyIDEA Authentication System, Release 3.8

Machine endpoints

This REST API is used to list machines from Machine Resolvers.


The code is tested in tests/test_api_machines
POST /machine/tokenoption
This sets a Machine Token option or deletes it, if the value is empty.
Parameters
• hostname – identify the machine by the hostname
• machineid – identify the machine by the machine ID and the resolver name
• resolver – identify the machine by the machine ID and the resolver name
• serial – identify the token by the serial number
• application – the name of the application like “luks” or “ssh”.
Parameters not listed will be treated as additional options.
Return
GET /machine/authitem/(application)
GET /machine/authitem
This fetches the authentication items for a given application and the given client machine.
Parameters
• challenge (basestring) – A challenge for which the authentication item is calculated. In
case of the Yubikey this can be a challenge that produces a response. The authentication item
is the combination of the challenge and the response.
• hostname (basestring) – The hostname of the machine
Return dictionary with lists of authentication items
Example response:

HTTP/1.1 200 OK
Content-Type: application/json

{
"id": 1,
"jsonrpc": "2.0",
"result": {
"status": true,
"value": { "ssh": [ { "username": "....",
"sshkey": "...."
}
],
"luks": [ { "slot": ".....",
"challenge": "...",
"response": "...",
"partition": "..."
]
}
},
(continues on next page)

282 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

(continued from previous page)


"version": "privacyIDEA unknown"
}

POST /machine/token
Attach an existing token to a machine with a certain application.
Parameters
• hostname – identify the machine by the hostname
• machineid – identify the machine by the machine ID and the resolver name
• resolver – identify the machine by the machine ID and the resolver name
• serial – identify the token by the serial number
• application – the name of the application like “luks” or “ssh”.
Parameters not listed will be treated as additional options.
Return json result with “result”: true and the machine list in “value”.
Example request:

POST /token HTTP/1.1


Host: example.com
Accept: application/json

{ "hostname": "puckel.example.com",
"machienid": "12313098",
"resolver": "machineresolver1",
"serial": "tok123",
"application": "luks" }

GET /machine/token
Return a list of MachineTokens either for a given machine or for a given token.
Parameters
• serial – Return the MachineTokens for a the given Token
• hostname – Identify the machine by the hostname
• machineid – Identify the machine by the machine ID and the resolver name
• resolver – Identify the machine by the machine ID and the resolver name
Return
GET /machine/
List all machines that can be found in the machine resolvers.
Parameters
• hostname – only show machines, that match this hostname as substring
• ip – only show machines, that exactly match this IP address
• id – filter for substring matching ids
• resolver – filter for substring matching resolvers
• any – filter for a substring either matching in “hostname”, “ip” or “id”

1.15. Code Documentation 283


privacyIDEA Authentication System, Release 3.8

Return json result with “result”: true and the machine list in “value”.
Example request:

GET /hostname?hostname=on HTTP/1.1


Host: example.com
Accept: application/json

Example response:

HTTP/1.1 200 OK
Content-Type: application/json

{
"id": 1,
"jsonrpc": "2.0",
"result": {
"status": true,
"value": [
{
"id": "908asljdas90ad0",
"hostname": [ "flavon.example.com", "test.example.com" ],
"ip": "1.2.3.4",
"resolver_name": "machineresolver1"
},
{
"id": "1908209x48x2183",
"hostname": [ "london.example.com" ],
"ip": "2.4.5.6",
"resolver_name": "machineresolver1"
}
]
},
"version": "privacyIDEA unknown"
}

DELETE /machine/token/(serial)/
machineid/resolver/application Detach a token from a machine with a certain application.
Parameters
• machineid – identify the machine by the machine ID and the resolver name
• resolver – identify the machine by the machine ID and the resolver name
• serial – identify the token by the serial number
• application – the name of the application like “luks” or “ssh”.
Return json result with “result”: true and the machine list in “value”.
Example request:

DELETE /token HTTP/1.1


Host: example.com
Accept: application/json

{ "hostname": "puckel.example.com",
(continues on next page)

284 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

(continued from previous page)


"resolver": "machineresolver1",
"application": "luks" }

privacyIDEA Server endpoints

This endpoint is used to create, update, list and delete privacyIDEA server definitions. privacyIDEA server definitions
can be used for Remote-Tokens and for Federation-Events.
The code of this module is tested in tests/test_api_privacyideaserver.py
POST /privacyideaserver/test_request
Test the privacyIDEA definition :return:
GET /privacyideaserver/
This call gets the list of privacyIDEA server definitions
POST /privacyideaserver/(identifier)
This call creates or updates a privacyIDEA Server definition
Parameters
• identifier – The unique name of the privacyIDEA server definition
• url – The URL of the privacyIDEA server
• tls – Set this to 0, if tls should not be checked
• description – A description for the definition
DELETE /privacyideaserver/(identifier)
This call deletes the specified privacyIDEA server configuration
Parameters
• identifier – The unique name of the privacyIDEA server definition

CA Connector endpoints

This is the REST API for managing CA connector definitions. The CA connectors are written to the database table
“caconnector”.
The code is tested in tests/test_api_caconnector.py.
GET /caconnector/(name)
GET /caconnector/
returns a json list of the available CA connectors
GET /caconnector/specific/(catype)
It requires the configuration data of a CA connector in the GET parameters and returns a dict of possible specific
options.
POST /caconnector/(name)
Create a new CA connector
DELETE /caconnector/(name)
Delete a specific CA connector

1.15. Code Documentation 285


privacyIDEA Authentication System, Release 3.8

Recover endpoints

This module provides the REST API for the password recovery for a user managed in privacyIDEA.
The methods are also tested in the file tests/test_api_register.py
POST /recover/reset
reset the password with a given recovery code. The recovery code was sent by get_recover_code and is bound to
a certain user.
JSON Parameters
• recoverycode – The recoverycode sent the the user
• password – The new password of the user
Return a json result with a boolean “result”: true
POST /recover
This method requests a recover code for a user. The recover code it sent via email to the user.
Query Parameters
• user – username of the user
• realm – realm of the user
• email – email of the user
Return JSON with value=True or value=False

Register endpoints

This module contains the REST API for registering as a new user. This endpoint can be used without any authentication,
since a new user can register.
The methods are tested in the file tests/test_api_register.py
GET /register
This endpoint returns the information if registration is allowed or not. This is used by the UI to either display the
registration button or not.
Return JSON with value=True or value=False
POST /register
Register a new user in the realm/userresolver. To do so, the user resolver must be writeable like an SQLResolver.
Registering a user in fact creates a new user and also creates the first token for the user. The following values are
needed to register the user:
• username (mandatory)
• givenname (mandatory)
• surname (mandatory)
• email address (mandatory)
• password (mandatory)
• mobile phone (optional)
• telephone (optional)

286 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

The user receives a registration token via email to be able to login with his self chosen password and the regis-
tration token.
JSON Parameters
• username – The login name of the new user. Check if it already exists
• givenname – The givenname of the new user
• surname – The surname of the new user
• email – The email address of the new user
• password – The password of the new user. This is the resolver password of the new user.
• mobile – The mobile phone number
• phone – The phone number (land line) of the new user
Return a json result with a boolean “result”: true

Monitoring endpoints

This endpoint is used fetch monitoring/statistics data


The code of this module is tested in tests/test_api_monitoring.py
GET /monitoring/(stats_key)
GET /monitoring/
return a list of all available statistics keys in the database if no stats_key is specified.
If a stats_key is specified it returns the data of this key. The parameters “start” and “end” can be used to specify
a time window, from which the statistics data should be fetched.
GET /monitoring/(stats_key)/last
Get the last value of the stats key
DELETE /monitoring/(stats_key)
Delete the statistics data of a certain stats_key.
You can specify the start date and the end date when to delete the monitoring data. You should specify the dates
including the timezone. Otherwise your client could send its local time and the server would interpret it as its
own local time which would result in deleting unexpected entries.
You can specify the dates like 2010-12-31 22:00+0200

Periodic Task endpoints

These endpoints are used to create, modify and delete periodic tasks.
This module is tested in tests/test_api_periodictask.py
GET /periodictask/taskmodules/
Return a list of task module identifiers.
GET /periodictask/nodes/
Return a list of available nodes
GET /periodictask/
Return a list of objects of defined periodic tasks.

1.15. Code Documentation 287


privacyIDEA Authentication System, Release 3.8

POST /periodictask/
Create or replace an existing periodic task definition.
Parameters
• id – ID of an existing periodic task definition that should be updated
• name – Name of the periodic task
• active – true if the periodic task should be active
• retry_if_failed – privacyIDEA will retry to execute the task if failed
• interval – Interval at which the periodic task should run (in cron syntax)
• nodes – Comma-separated list of nodes on which the periodic task should run
• taskmodule – Task module name of the task
• ordering – Ordering of the task, must be a number >= 0.
• options – A dictionary (possibly JSON) of periodic task options, mapping unicodes to
unicodes
Return ID of the periodic task
GET /periodictask/options/(taskmodule)
Return the available options for the given taskmodule.
Parameters
• taskmodule – Identifier of the task module
Return a dictionary mapping option keys to description dictionaries
POST /periodictask/disable/(ptaskid)
Disable a certain periodic task.
Parameters
• ptaskid – ID of the periodic task
Return ID of the periodic task
POST /periodictask/enable/(ptaskid)
Enable a certain periodic task.
Parameters
• ptaskid – ID of the periodic task
Return ID of the periodic task
GET /periodictask/(ptaskid)
Return the dictionary describing a periodic task.
Parameters
• ptaskid – ID of the periodic task
DELETE /periodictask/(ptaskid)
Delete a certain periodic task.
Parameters
• ptaskid – ID of the periodic task
Return ID of the periodic task

288 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

This endpoint is used to get the information from the server, which application types are known and which options
these applications provide.
Applications are used to attach tokens to machines.
The code of this module is tested in tests/test_api_applications.py

Application endpoints

GET /application/
returns a json list of the available applications

Tokentype endpoints

This API endpoint is a generic endpoint that can be used by any token type.
The tokentype needs to implement a classmethod api_endpoint and can then be called by /ttype/<tokentype>. This
way, each tokentype can create its own API without the need to change the core API.
The TiQR Token uses this API to implement its special functionalities. See TiQR Token.
GET /ttype/(ttype)
This is a special token function. Each token type can define an additional API call, that does not need authenti-
cation on the REST API level.
Return Token Type dependent
POST /ttype/(ttype)
This is a special token function. Each token type can define an additional API call, that does not need authenti-
cation on the REST API level.
Return Token Type dependent

SMTP server endpoints

This endpoint is used to create, update, list and delete SMTP server definitions. SMTP server definitions can be used
for several purposes like EMail-Token, SMS Token with SMTP gateway, notification like PIN handler and registration.
The code of this module is tested in tests/test_api_smtpserver.py
POST /smtpserver/send_test_email
Test the email configuration :return:
GET /smtpserver/
This call gets the list of SMTP server definitions
POST /smtpserver/(identifier)
This call creates or updates an SMTP server definition.
Parameters
• identifier – The unique name of the SMTP server definition
• server – The FQDN or IP of the mail server
• port – The port of the mail server
• username – The mail username for authentication at the SMTP server
• password – The password for authentication at the SMTP server

1.15. Code Documentation 289


privacyIDEA Authentication System, Release 3.8

• tls – If the server should do TLS


• description – A description for the definition
DELETE /smtpserver/(identifier)
This call deletes the specified SMTP server configuration
Parameters
• identifier – The unique name of the SMTP server definition

SMS Gateway endpoints

This endpoint is used to create, modify, list and delete SMS gateway definitions. These gateway definitions are written
to the database table “smsgateway” and “smsgatewayoption”.
The code of this module is tested in tests/test_api_smsgateway.py
GET /smsgateway/(gwid)
GET /smsgateway/
returns a json list of the gateway definitions
Or
returns a list of available sms providers with their configuration /smsgateway/providers
POST /smsgateway
This creates a new SMS gateway definition or updates an existing one.
JSON Parameters
• name – The unique identifier of the SMS gateway definition
• module – The providermodule name
• description – An optional description of the definition
• option.* – Additional options for the provider module (module specific)
• header.* – Additional headers for the provider module (module specific)
DELETE /smsgateway/option/(gwid)/
key this function deletes an option of a gateway definition
Parameters
• gwid – The id of the sms gateway definition
Return json with success or fail
DELETE /smsgateway/(identifier)
this function deletes an existing smsgateway definition
Parameters
• identifier – The name of the sms gateway definition
Return json with success or fail

290 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

RADIUS server endpoints

This endpoint is used to create, update, list and delete RADIUS server definitions. RADIUS server definitions can be
used for several purposes like RADIUS-Token or RADIUS-passthru policies.
The code of this module is tested in tests/test_api_radiusserver.py
POST /radiusserver/test_request
Test the RADIUS definition :return:
GET /radiusserver/
This call gets the list of RADIUS server definitions
POST /radiusserver/(identifier)
This call creates or updates a RADIUS server definition.
Parameters
• identifier – The unique name of the RADIUS server definition
• server – The FQDN or IP of the RADIUS server
• port – The port of the RADIUS server
• secret – The RADIUS secret of the RADIUS server
• description – A description for the definition
DELETE /radiusserver/(identifier)
This call deletes the specified RADIUS server configuration
Parameters
• identifier – The unique name of the RADIUS server definition

Subscriptions endpoints

This is the controller API for client component subscriptions like ownCloud plugin or RADIUS Credential Provider.
GET /subscriptions/(application)
GET /subscriptions/
Return the subscription object as JSON.
POST /subscriptions/
Upload a new subscription file
DELETE /subscriptions/(application)
Delete an existing subscription

Client endpoints

This is the audit REST API that can be used to retrieve the privacyIDDEA authentication clients, which used priva-
cyIDEA to authenticate.
GET /clients
GET /client/
return a list of authenticated clients grouped (dictionary) by the clienttype.
Example request:

1.15. Code Documentation 291


privacyIDEA Authentication System, Release 3.8

GET /client
Host: example.com
Accept: application/json

Example response:

HTTP/1.1 200 OK
Content-Type: application/json

{
"id": 1,
"jsonrpc": "2.0",
"result": {
"status": true,
"value": {"PAM": [],
"SAML": [],
},
"version": "privacyIDEA unknown"
}

1.15.2 LIB level

At the LIB level all library functions are defined. There is no authentication on this level. Also there is no
flask/Web/request code on this level.
Request information and the logged_in_user need to be passed to the functions as parameters, if they are needed.
If possible, policies are checked with policy decorators.

library functions

Based on the database models, which are tested in tests/test_db_model.py, there are different modules.
resolver.py contains functions to simply deal with resolver definitions. On this level users and realms are not know, yet.
realm.py contains functions to deal with realm. Realms are a list of several resolvers. So prior to bother the realm.py,
the resolver.py should be understood and working. On this level, users are not known, yet.
user.py contains functions to deal with users. A user object is an entity in a realm. And of course the user object itself
can be found in a resolver. But you need to have working resolver.py and realm.py to be able to work with user.py
For further details see the following modules:

Users

There are the library functions for user functions. It depends on the lib.resolver and lib.realm.
There are and must be no dependencies to the token functions (lib.token) or to webservices!
This code is tested in tests/test_lib_user.py
class privacyidea.lib.user.User(login='', realm='', resolver='', uid=None)

The user has the attributes login, realm and resolver.

292 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Usually a user can be found via “login@realm”.


A user object with an empty login and realm should not exist, whereas a user object could have an empty resolver.

property attributes
returns the custom attributes of a user :return: a dictionary of attributes with keys and values
check_password(password)
The password of the user is checked against the user source
Parameters password – The clear text password
Returns the username of the authenticated user. If unsuccessful, returns None
Return type string/None
delete()
This deletes the user in the user store. I.e. the user in the SQL database or the LDAP gets deleted.
Returns True in case of success
delete_attribute(attrkey=None)
Delete the given key as custom user attribute. If no key is given, then all attributes are deleted
Parameters attrkey – The key to delete
Returns The number of deleted rows
exist()
Check if the user object exists in the user store :return: True or False
get_ordererd_resolvers()
returns a list of resolvernames ordered by priority. The resolver with the lowest priority is the first. If
resolvers have the same priority, they are ordered alphabetically.
Returns list or resolvernames
get_search_fields()
Return the valid search fields of a user. The search fields are defined in the UserIdResolver class.
Returns searchFields with name (key) and type (value)
Return type dict
get_user_identifiers()
This returns the UserId information from the resolver object and the resolvertype and the resolvername
(former: getUserId) (former: getUserResolverId) :return: The userid, the resolver type and the resolver
name
like (1000, “passwdresolver”, “resolver1”)

Return type tuple

get_user_phone(phone_type='phone', index=None)
Returns the phone number or a list of phone numbers of a user.
Parameters
• phone_type (string) – The type of the phone, i.e. either mobile or phone (land line)
• index – The index of the selected phone number of list of the phones of the user. If the
index is given, this phone number as string is returned. If the index is omitted, all phone
numbers are returned.

1.15. Code Documentation 293


privacyIDEA Authentication System, Release 3.8

Returns list with phone numbers of this user object


get_user_realms()
Returns a list of the realms, a user belongs to. Usually this will only be one realm. But if the user object
has no realm but only a resolver, than all realms, containing this resolver are returned. This function is used
for the policy module
Returns realms of the user
Return type list
property info
return the detailed information for the user
Returns a dict with all the userinformation
Return type dict
is_empty()
login = ''
realm = ''
resolver = ''
set_attribute(attrkey, attrvalue, attrtype=None)
Set a custom attribute for a user
Parameters
• attrkey – The key of the attribute
• attrvalue – The value of the attribute
Returns The id of the attribute setting
update_user_info(attributes, password=None)
This updates the given attributes of a user. The attributes can be “username”, “surname”, “givenname”,
“email”, “mobile”, “phone”, “password”
Parameters
• attributes (dict) – A dictionary of the attributes to be updated
• password – The password of the user
Returns True in case of success
privacyidea.lib.user.create_user(resolvername, attributes, password=None)
This creates a new user in the given resolver. The resolver must be editable to do so.
The attributes is a dictionary containing the keys “username”, “email”, “phone”, “mobile”, “surname”, “given-
name”, “password”.
We return the UID and not the user object, since the user could be located in several realms!
Parameters
• resolvername (basestring) – The name of the resolver, in which the user should be cre-
ated
• attributes (dict) – Attributes of the user
• password – The password of the user
Returns The uid of the user object

294 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

privacyidea.lib.user.get_attributes(uid, resolver, realm_id)


Returns the attributes for the given user.
Parameters
• uid – The UID of the user
• resolver – The name of the resolver
• realm_id – The realm_id
Returns A dictionary of key/values
privacyidea.lib.user.get_user_from_param(param, optionalOrRequired=True)
Find the parameter user, realm and resolver and create a user object from these parameters.
An exception is raised, if a user in a realm is found in more than one resolver.
Parameters
• param (dict) – The dictionary of request parameters
• optionalOrRequired (bool) – whether the user is required
Returns User as found in the parameters
Return type User object
privacyidea.lib.user.get_user_list(param=None, user=None, custom_attributes=False)
This function returns a list of user dictionaries.
Parameters
• param (dict) – search parameters
• user (User object) – a specific user object to return
• custom_attributes (bool) – Set to True, if you want to receive custom attributes of ex-
ternal users.
Returns list of dictionaries
privacyidea.lib.user.get_username(userid, resolvername)
Determine the username for a given id and a resolvername.
Parameters
• userid (string) – The id of the user in a resolver
• resolvername – The name of the resolver
Returns the username or “” if it does not exist
Return type string
privacyidea.lib.user.is_attribute_at_all()
Check if there are custom user attributes at all :return: bool
privacyidea.lib.user.log_used_user(user, other_text='')
This creates a log message combined of a user and another text. The user information is only added, if user.login
!= user.used_login
Parameters
• user (User object) – A user to log
• other_text – Some additional text
Returns str

1.15. Code Documentation 295


privacyIDEA Authentication System, Release 3.8

privacyidea.lib.user.split_user(username)
Split the username of the form user@realm into the username and the realm splitting mye-
[email protected]@realm is also possible and will return ([email protected], realm).
If for a user@domain the “domain” does not exist as realm, the name is not split, since it might be the
user@domain in the default realm
If the Split@Sign configuration is disabled, the username won’t be split and the username and an empty realm
will be returned.
We can also split realmuser to (user, realm)
Parameters username (string) – the username to split
Returns username and realm
Return type tuple

Token Class

The following token types are known to privacyIDEA. All are inherited from the base tokenclass describe below.

4 Eyes Token

class privacyidea.lib.tokens.foureyestoken.FourEyesTokenClass(db_token)
The FourEyes token can be used to implement the Two Man Rule. The FourEyes token defines how many tokens
of which realms are required like:
• 2 tokens of RealmA
• 1 token of RealmB
Then users (the owners of those tokens) need to login by everyone entering their OTP PIN and OTP value. It does
not matter, in which order they enter the values. All their PINs and OTPs are concatenated into one password
field but need to be separated by the splitting sign.
The FourEyes token again splits the password value and tries to authenticate each of the these passwords in the
realms using the function check_realm_pass.
The FourEyes token itself does not provide an OTP PIN.
The token is initialized using additional parameters at token/init:
Example Authentication Request:

POST /auth HTTP/1.1


Host: example.com
Accept: application/json

type=4eyes
user=cornelius
realm=realm1
4eyes=realm1:2,realm2:1
separator=%20

Parameters db_token (database token object) – the token

296 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

authenticate(passw, user=None, options=None)


do the authentication on base of password / otp and user and options, the request parameters.
Here we contact the other privacyIDEA server to validate the OtpVal.
Parameters
• passw – the password / otp
• user – the requesting user
• options – the additional request parameters
Returns tuple of (success, otp_count - 0 or -1, reply)
check_challenge_response(user=None, passw=None, options=None)
This method verifies if the given response is the PIN + OTP of one of the remaining tokens. In case of
success it then returns 1
Parameters
• user (User object) – the requesting user
• passw (string) – the password: PIN + OTP
• options (dict) – additional arguments from the request, which could be token specific.
Usually “transaction_id”
Returns return 1 if the answer to the challenge is correct, -1 otherwise.
Return type int
static convert_realms(realms)
This function converts the realms as given by the API parameter to a dictionary:

"realm1:2,realm2:1" -> {"realm1":2,


"realm2":1}

Parameters realms (str) – a serialized list of realms


Returns dict of realms
Return type dict

create_challenge(transactionid=None, options=None)
This method creates a challenge, which is submitted to the user. The submitted challenge will be preserved
in the challenge database.
If no transaction id is given, the system will create a transaction id and return it, so that the response can
refer to this transaction.
Parameters
• transactionid – the id of this challenge
• options (dict) – the request context parameters / data
Returns tuple of (bool, message, transactionid, reply_dict)
Return type tuple
The return tuple builds up like this: bool if submit was successful; message which is displayed in the
JSON response; additional challenge reply_dict, which are displayed in the JSON challenges response.
static get_class_info(key=None, ret='all')
returns a subtree of the token definition

1.15. Code Documentation 297


privacyIDEA Authentication System, Release 3.8

Parameters
• key (string) – subsection identifier
• ret (user defined) – default return value, if nothing is found
Returns subsection if key exists or user defined
Return type dict or scalar
static get_class_prefix()
return the token type prefix
static get_class_type()
return the class type identifier
has_further_challenge(options=None)
Check if there are still more tokens to be authenticated :param options: Options dict :return: True, if further
challenge is required.
is_challenge_request(passw, user=None, options=None)
The 4eyes token can act as a challenge response token.
Either
• if the first passw given is the PIN of the 4eyes token or
• if the first passw given is the complete PIN+OTP from one of the admintokens.

Parameters
• passw (str) – password, which might be pin or pin+otp
• user (User object) – The user from the authentication request
• options (dict) – dictionary of additional request parameters
Returns true or false
Return type bool

static realms_dict_to_string(realms)
This function converts the realms - if it is a dictionary - to a string:

{"realm1": {"selected": True,


"count": 1 },
"realm2": {"selected": True,
"count": 2}}
-> "realm1:1,realm2:2"

Parameters realms (dict) – the realms as they are passed from the WebUI
Returns realms
Return type str

update(param)
This method is called during the initialization process. :param param: parameters from the token init :type
param: dict :return: None

298 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Certificate Token

class privacyidea.lib.tokens.certificatetoken.CertificateTokenClass(aToken)
Token to implement an X509 certificate. The certificate can be enrolled by sending a CSR to the server or the
keypair is created by the server. If the server creates the keypair, the user can download a PKCS12 file. The OTP
PIN is used as passphrase for the PKCS12 file.
privacyIDEA is capable of working with different CA connectors.
Valid parameters are request or certificate, both PEM encoded. If you pass a request you also need to pass the
ca that should be used to sign the request. Passing a certificate just uploads the certificate to a new token object.
A certificate token can be created by an administrative task with the token/init api like this:
Example Initialization Request:

POST /auth HTTP/1.1


Host: example.com
Accept: application/json

type=certificate
user=cornelius
realm=realm1
request=<PEM encoded request>
attestation=<PEM encoded attestation certificate>
ca=<name of the ca connector>

Example Initialization Request, key generation on servers side


In this case the certificate is created on behalf of another user.

POST /auth HTTP/1.1


Host: example.com
Accept: application/json

type=certificate
user=cornelius
realm=realm1
generate=1
ca=<name of the ca connector>

Example response:

HTTP/1.1 200 OK
Content-Type: application/json

{
"detail": {
"certificate": "...PEM..."
},
"id": 1,
"jsonrpc": "2.0",
"result": {
"status": true,
"value": true
},
(continues on next page)

1.15. Code Documentation 299


privacyIDEA Authentication System, Release 3.8

(continued from previous page)


"version": "privacyIDEA unknown"
}

Create a new token object.


Parameters db_token (Token) – A database token object
Returns A TokenClass object
get_as_dict()
This returns the token data as a dictionary. It is used to display the token list at /token/list.
The certificate token can add the PKCS12 file if it exists
Returns The token data as dict
Return type dict
static get_class_info(key=None, ret='all')
returns a subtree of the token definition
Parameters
• key (string) – subsection identifier
• ret (user defined) – default return value, if nothing is found
Returns subsection if key exists or user defined
Return type dict or scalar
static get_class_prefix()
static get_class_type()
classmethod get_default_settings(g, params)
This method returns a dictionary with additional settings for token enrollment. The settings that are eval-
uated are SCOPE.ADMIN|SCOPE.USER, action=trusted_Assertion_CA_path It sets a list of configured
paths.
The returned dictionary is added to the parameters of the API call. :param g: context object, see documen-
tation of Match :param params: The call parameters :type params: dict :return: default parameters
get_init_detail(params=None, user=None)
At the end of the initialization we return the certificate and the PKCS12 file, if the private key exists.
hKeyRequired = False
revoke()
This revokes the token. We need to determine the CA, which issues the certificate, contact the connector
and revoke the certificate
Some token types may revoke a token without locking it.
set_pin(pin, encrypt=False)
set the PIN of a token. The PIN of the certificate token is stored encrypted. It is used as passphrase for the
PKCS12 file.
Parameters
• pin (basestring) – the pin to be set for the token
• encrypt (bool) – If set to True, the pin is stored encrypted and can be retrieved from the
database again

300 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

update(param)
This method is called during the initialization process. :param param: parameters from the token init :type
param: dict :return: None
using_pin = False

Daplug Token

class privacyidea.lib.tokens.daplugtoken.DaplugTokenClass(a_token)
daplug token class implementation
create a token object
Parameters aToken (orm object) – instance of the orm db object
check_otp(anOtpVal, counter=None, window=None, options=None)
checkOtp - validate the token otp against a given otpvalue
Parameters
• anOtpVal (string, format: efekeiebekeh ) – the otpvalue to be verified
• counter (int) – the counter state, that should be verified
• window (int) – the counter +window, which should be checked
• options (dict) – the dict, which could contain token specific info
Returns the counter state or -1
Return type int
check_otp_exist(otp, window=10)
checks if the given OTP value is/are values of this very token. This is used to autoassign and to determine
the serial number of a token.
Parameters
• otp (string) – the to be verified otp value
• window (int) – the lookahead window for the counter
Returns counter or -1 if otp does not exist
Return type int
static get_class_info(key=None, ret='all')
returns a subtree of the token definition
Parameters
• key (string) – subsection identifier
• ret (user defined) – default return value, if nothing is found
Returns subsection if key exists or user defined
Return type dict or string
static get_class_prefix()
Return the prefix, that is used as a prefix for the serial numbers. :return: oath
static get_class_type()
return the token type shortname
Returns ‘hotp’

1.15. Code Documentation 301


privacyIDEA Authentication System, Release 3.8

Return type string


get_multi_otp(count=0, epoch_start=0, epoch_end=0, curTime=None, timestamp=None)
return a dictionary of multiple future OTP values of the HOTP/HMAC token
WARNING: the dict that is returned contains a sequence number as key. This it NOT the otp
counter!

Parameters
• count (int) – how many otp values should be returned
• epoch_start – Not used in HOTP
• epoch_end – Not used in HOTP
• curTime – Not used in HOTP
• timestamp – not used in HOTP
• counter_index – whether the counter should be used as index
Returns tuple of status: boolean, error: text and the OTP dictionary

get_otp(current_time=None)
return the next otp value
Parameters curTime – Not Used in HOTP
Returns next otp value and PIN if possible
Return type tuple
is_multichallenge_enrollable = False
resync(otp1, otp2, options=None)
resync the token based on two otp values - external method to do the resync of the token
Parameters
• otp1 (string) – the first otp value
• otp2 (string) – the second otp value
• options (dict or None) – optional token specific parameters
Returns counter or -1 if otp does not exist
Return type int
split_pin_pass(passw, user=None, options=None)
Split the password into the token PIN and the OTP value
take the given password and split it into the PIN and the OTP value. The splitting can be dependent of
certain policies. The policies may depend on the user.
Each token type may define its own way to slit the PIN and the OTP value.
Parameters
• passw – the password to split
• user (User object) – The user/owner of the token
• options (dict) – can be used be the token types.
Returns tuple of pin and otp value

302 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Returns tuple of (split status, pin, otp value)


Return type tuple

Email Token

class privacyidea.lib.tokens.emailtoken.EmailTokenClass(aToken)
Implementation of the EMail Token Class, that sends OTP values via SMTP. (Similar to SMSTokenClass)
Create a new HOTP Token object
Parameters db_token (DB object) – instance of the orm db object
EMAIL_ADDRESS_KEY = 'email'
can_verify_enrollment = True
check_otp(anOtpVal, counter=None, window=None, options=None)
check the otpval of a token against a given counter and the window
Parameters passw (string) – the to be verified passw/pin
Returns counter if found, -1 if not found
Return type int
create_challenge(transactionid=None, options=None)
create a challenge, which is submitted to the user
Parameters
• transactionid – the id of this challenge
• options – the request context parameters / data You can pass exception=1 to raise an
exception, if the Email could not be sent.
Returns
tuple of (success, message, transactionid, attributes)
• success: if submit was successful
• message: the text submitted to the user
• transactionid: the given or generated transactionid
• reply_dict: additional dictionary, which is added to the response
Return type tuple(bool, str, str, dict)
classmethod enroll_via_validate(g, content, user_obj)
This class method is used in the policy ENROLL_VIA_MULTICHALLENGE. It enrolls a new token of
this type and returns the necessary information to the client by modifying the content.
Parameters
• g – context object
• content – The content of a response
• user_obj – A user object
Returns None, the content is modified

1.15. Code Documentation 303


privacyIDEA Authentication System, Release 3.8

enroll_via_validate_2nd_step(passw, options=None)
This method is the optional second step of ENROLL_VIA_MULTICHALLENGE. It is used in situations
like the email token, sms token or push, when enrollment via challenge response needs two steps.
The passw is entered during the first authentication step and it contains the email address.
So we need to update the token with the email address and we need to create a new challenge for the final
authentication.
Parameters options –
Returns
static get_class_info(key=None, ret='all')
returns all or a subtree of the token definition
Parameters
• key (string) – subsection identifier
• ret (user defined) – default return value, if nothing is found
Returns subsection if key exists or user defined
Return type dict
static get_class_prefix()
Return the prefix, that is used as a prefix for the serial numbers. :return: oath
static get_class_type()
return the generic token class identifier
is_challenge_request(passw, user=None, options=None)
check, if the request would start a challenge
We need to define the function again, to get rid of the is_challenge_request-decorator of the HOTP-Token
Parameters
• passw – password, which might be pin or pin+otp
• options – dictionary of additional request parameters
Returns returns true or false
prepare_verify_enrollment()
This is called, if the token should be enrolled in a way, that the user needs to provide a proof, that the server
can verify, that the token was successfully enrolled. The email token needs to send an email with OTP.
The returned dictionary is added to the response in “detail” -> “verify”.
Returns A dictionary with information that is needed to trigger the verification.
classmethod test_config(params=None)
This method is used to test the token config. Some tokens require some special token configuration like the
SMS-Token or the Email-Token. To test this configuration, this classmethod is used.
It takes token specific parameters and returns a tuple of a boolean and a result description.
Parameters params (dict) – token specific parameters
Returns success, description
Return type tuple
update(param, reset_failcount=True)
update - process initialization parameters

304 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Parameters param (dict) – dict of initialization parameters


Returns nothing

HOTP Token

class privacyidea.lib.tokens.hotptoken.HotpTokenClass(db_token)
hotp token class implementation
Create a new HOTP Token object
Parameters db_token (DB object) – instance of the orm db object
can_verify_enrollment = True
check_otp(anOtpVal, counter=None, window=None, options=None)
check if the given OTP value is valid for this token.
Parameters
• anOtpVal (string) – the to be verified otpvalue
• counter (int) – the counter state, that should be verified
• window (int) – the counter +window, which should be checked
• options (dict) – the dict, which could contain token specific info
Returns the counter state or -1
Return type int
check_otp_exist(otp, window=10, symetric=False, inc_counter=True)
checks if the given OTP value is/are values of this very token. This is used to autoassign and to determine
the serial number of a token.
Parameters
• otp (string) – the to be verified otp value
• window (int) – the lookahead window for the counter
Returns counter or -1 if otp does not exist
Return type int
desc_hash_func = 'Specify the hashing function to be used. Can be SHA1, SHA256 or
SHA512.'
desc_key_gen = 'Force the key to be generated on the server.'
desc_otp_len = 'Specify the OTP length to be used. Can be 6 or 8 digits.'
desc_two_step_admin = 'Specify whether admins are allowed or forced to use two-step
enrollment.'
desc_two_step_user = 'Specify whether users are allowed or forced to use two-step
enrollment.'
classmethod enroll_via_validate(g, content, user_obj)
This class method is used in the policy ENROLL_VIA_MULTICHALLENGE. It enrolls a new token of
this type and returns the necessary information to the client by modifying the content.
Parameters
• g – context object

1.15. Code Documentation 305


privacyIDEA Authentication System, Release 3.8

• content – The content of a response


• user_obj – A user object
Returns None, the content is modified
generate_symmetric_key(server_component, client_component, options=None)
Generate a composite key from a server and client component using a PBKDF2-based scheme.
Parameters
• server_component (hex string) – The component usually generated by privacyIDEA
• client_component (hex string) – The component usually generated by the client (e.g.
smartphone)
• options –
Returns the new generated key as hex string
Return type str
static get_class_info(key=None, ret='all')
returns a subtree of the token definition Is used by lib.token.get_token_info
Parameters
• key (string) – subsection identifier
• ret (user defined) – default return value, if nothing is found
Returns subsection if key exists or user defined
Return type dict
static get_class_prefix()
Return the prefix, that is used as a prefix for the serial numbers. :return: oath
static get_class_type()
return the token type shortname
Returns ‘hotp’
Return type string
classmethod get_default_settings(g, params)
This method returns a dictionary with default settings for token enrollment. These default settings are
defined in SCOPE.USER or SCOPE.ADMIN and are hotp_hashlib, hotp_otplen. If these are set, the user
or admin will only be able to enroll tokens with these values.
The returned dictionary is added to the parameters of the API call. :param g: context object, see documen-
tation of Match :param params: The call parameters :type params: dict :return: default parameters
static get_import_csv(l)
Read the list from a csv file and return a dictionary, that can be used to do a token_init.
Parameters l (list) – The list of the line of a csv file
Returns A dictionary of init params
get_init_detail(params=None, user=None)
to complete the token initialization some additional details should be returned, which are displayed at the
end of the token initialization. This is the e.g. the enrollment URL for a Google Authenticator.
get_multi_otp(count=0, epoch_start=0, epoch_end=0, curTime=None, timestamp=None,
counter_index=False)
return a dictionary of multiple future OTP values of the HOTP/HMAC token

306 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

WARNING: the dict that is returned contains a sequence number as key. This it NOT the otp
counter!

Parameters
• count (int) – how many otp values should be returned
• epoch_start – Not used in HOTP
• epoch_end – Not used in HOTP
• curTime – Not used in HOTP
• timestamp – not used in HOTP
• counter_index – whether the counter should be used as index
Returns tuple of status: boolean, error: text and the OTP dictionary

get_otp(current_time=None)
return the next otp value
Parameters curTime – Not Used in HOTP
Returns next otp value and PIN if possible
Return type tuple
static get_setting_type(key)
This function returns the type of the token specific config/setting. This way a tokenclass can define settings,
that can be “public” or a “password”. If this setting is written to the database, the type of the setting is set
automatically in set_privacyidea_config
The key name needs to start with the token type.
Parameters key – The token specific setting key
Returns A string like “public”
static get_sync_timeout()
get the token sync timeout value
Returns timeout value in seconds
Return type int
has_further_challenge(options=None)

Parameters options –
Returns
property hashlib
is_multichallenge_enrollable = True
is_previous_otp(otp)
Check if the OTP values was previously used.
Parameters
• otp –
• window –
Returns

1.15. Code Documentation 307


privacyIDEA Authentication System, Release 3.8

prepare_verify_enrollment()
This is called, if the token should be enrolled in a way, that the user needs to provide a proof, that the server
can verify, that the token was successfully enrolled. E.g. with HOTP tokens the user might need to provide
a correct OTP value.
The returned dictionary is added to the response in “detail” -> “verify”.
Returns A dictionary with information that is needed to trigger the verification.
previous_otp_offset = 1
resync(otp1, otp2, options=None)
resync the token based on two otp values
Parameters
• otp1 (string) – the first otp value
• otp2 (string) – the second otp value
• options (dict or None) – optional token specific parameters
Returns counter or -1 if otp does not exist
Return type int
update(param, reset_failcount=True)
process the initialization parameters
Do we really always need an otpkey? the otpKey is handled in the parent class :param param: dict of
initialization parameters :type param: dict
Returns nothing
verify_enrollment(verify)
This is called during the 2nd step of the verified enrollment. This method verifies the actual response from
the user. Returns true, if the verification was successful.
Parameters verify – The response given by the user
Returns True

mOTP Token

class privacyidea.lib.tokens.motptoken.MotpTokenClass(db_token)
constructor - create a token object
Parameters a_token (orm object) – instance of the orm db object
check_otp(anOtpVal, counter=None, window=None, options=None)
validate the token otp against a given otpvalue
Parameters
• anOtpVal (str) – the to be verified otpvalue
• counter (int) – the counter state, that should be verified
• window (int) – the counter +window, which should be checked
• options (dict) – the dict, which could contain token specific info
Returns the counter state or -1
Return type int

308 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

static get_class_info(key=None, ret='all')


returns a subtree of the token definition Is used by lib.token.get_token_info
Parameters
• key (string) – subsection identifier
• ret (user defined) – default return value, if nothing is found
Returns subsection if key exists or user defined
:rtype : dict or string
static get_class_prefix()
static get_class_type()
get_init_detail(params=None, user=None)
to complete the token normalisation, the response of the initialization should be build by the token specific
method, the getInitDetails
update(param, reset_failcount=True)
update - process initialization parameters
Parameters param (dict) – dict of initialization parameters
Returns nothing

OCRA Token

The OCRA token is the base OCRA functionality. Usually it is created by importing a CSV or PSKC file.
This code is tested in tests/test_lib_tokens_tiqr.

Implementation

class privacyidea.lib.tokens.ocratoken.OcraTokenClass(db_token)
The OCRA Token Implementation
Create a new OCRA Token object from a database object
Parameters db_token (DB object) – instance of the orm db object
check_otp(otpval, counter=None, window=None, options=None)
This function is invoked by TokenClass.check_challenge_response and checks if the given password
matches the expected response for the given challenge.
Parameters
• otpval – the password (pin + otp)
• counter – ignored
• window – ignored
• options – dictionary that must contain “challenge”
Returns >=0 if the challenge matches, -1 otherwise
create_challenge(transactionid=None, options=None)
This method creates a challenge, which is submitted to the user. The submitted challenge will be preserved
in the challenge database.

1.15. Code Documentation 309


privacyIDEA Authentication System, Release 3.8

If no transaction id is given, the system will create a transaction id and return it, so that the response can
refer to this transaction.
Parameters
• transactionid – the id of this challenge
• options (dict) – the request context parameters / data
Returns tuple of (bool, message, transactionid, reply_dict)
Return type tuple
The return tuple builds up like this: bool if submit was successful; message which is displayed in the
JSON response; additional challenge reply_dict, which are displayed in the JSON challenges response.
static get_class_info(key=None, ret='all')
returns a subtree of the token definition
Parameters
• key (string) – subsection identifier
• ret (user defined) – default return value, if nothing is found
Returns subsection if key exists or user defined
Return type dict or scalar
static get_class_prefix()
Return the prefix, that is used as a prefix for the serial numbers. :return: OCRA :rtype: basestring
static get_class_type()
Returns the internal token type identifier :return: ocra :rtype: basestring
static get_import_csv(l)
Read the list from a csv file and return a dictionary, that can be used to do a token_init.
Parameters l (list) – The list of the line of a csv file
Returns A dictionary of init params
is_challenge_request(passw, user=None, options=None)
check, if the request would start a challenge In fact every Request that is not a response needs to start a
challenge request.
At the moment we do not think of other ways to trigger a challenge.
This function is not decorated with @challenge_response_allowed
as the OCRA token is always a challenge response token!
Parameters
• passw – The PIN of the token.
• options – dictionary of additional request parameters
Returns returns true or false
update(param)
This method is called during the initialization process.
Parameters param (dict) – parameters from the token init
Returns None

310 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

verify_response(passw=None, challenge=None)
This method verifies if the passw is the valid OCRA response to the challenge. In case of success we return
a value > 0
Parameters passw (string) – the password (pin+otp)
Returns return otp_counter. If -1, challenge does not match
Return type int

Paper Token

class privacyidea.lib.tokens.papertoken.PaperTokenClass(db_token)
The Paper Token allows to print out the next e.g. 100 OTP values. This sheet of paper can be used to authenticate
and strike out the used OTP values.
This creates a new Paper token object from a DB token object.
Parameters db_token (orm object) – instance of the orm db object
static get_class_info(key=None, ret='all')
returns a subtree of the token definition
Parameters
• key (string) – subsection identifier
• ret (user defined) – default return value, if nothing is found
Returns subsection if key exists or user defined
Return type dict or scalar
static get_class_prefix()
Return the prefix, that is used as a prefix for the serial numbers. :return: PPR
static get_class_type()
return the token type shortname
Returns ‘paper’
Return type string
is_multichallenge_enrollable = False
update(param, reset_failcount=True)
process the initialization parameters
Do we really always need an otpkey? the otpKey is handled in the parent class :param param: dict of
initialization parameters :type param: dict
Returns nothing

1.15. Code Documentation 311


privacyIDEA Authentication System, Release 3.8

PasswordToken

class privacyidea.lib.tokens.passwordtoken.PasswordTokenClass(aToken)
This Token does use a fixed Password as the OTP value. In addition, the OTP PIN can be used with this token.
This Token can be used for a scenario like losttoken
Create a new token object.
Parameters db_token (Token) – A database token object
Returns A TokenClass object
class SecretPassword(secObj)

check_password(password)

Parameters password (str) –


Returns result of password check: 0 if success, -1 if failed
Return type int
get_password()
check_otp(anOtpVal, counter=None, window=None, options=None)
This checks the static password
Parameters anOtpVal – This contains the “OTP” value, which is the static
password :return: result of password check, 0 in case of success, -1 if fail :rtype: int
static get_class_info(key=None, ret='all')
returns a subtree of the token definition
Parameters
• key (string) – subsection identifier
• ret (user defined) – default return value, if nothing is found
Returns subsection if key exists or user defined
Return type dict or scalar
static get_class_prefix()
static get_class_type()
get_init_detail(params=None, user=None)
At the end of the initialization we return the registration code.
password_detail_key = 'password'
update(param)
This method is called during the initialization process. :param param: parameters from the token init :type
param: dict :return: None

312 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Push Token

class privacyidea.lib.tokens.pushtoken.PushTokenClass(db_token)
The Push Token uses the Firebase service to send challenges to the user’s smartphone. The user confirms on the
smartphone, signs the challenge and sends it back to privacyIDEA.
The enrollment occurs in two enrollment steps:
Step 1: The device is enrolled using a QR code, which encodes the following URI:

otpauth://pipush/PIPU0006EF85?url=https://yourprivacyideaserver/enroll/this/
˓→token&ttl=120

Step 2: In the QR code is a URL, where the smartphone sends the remaining data for the enrollment:

POST /ttype/push HTTP/1.1


Host: https://yourprivacyideaserver/

enrollment_credential=<hex nonce>
serial=<token serial>
fbtoken=<Firebase token>
pubkey=<public key>

For more information see:


• https://github.com/privacyidea/privacyidea/issues/1342
• https://github.com/privacyidea/privacyidea/wiki/concept%3A-PushToken
Create a new token object.
Parameters db_token (Token) – A database token object
Returns A TokenClass object
classmethod api_endpoint(request, g)
This provides a function which is called by the API endpoint /ttype/push which is defined in Tokentype
endpoints
The method returns a tuple ("json", {})
This endpoint provides several functionalities:
• It is used for the 2nd enrollment step of the smartphone. It accepts the following parameters:

POST /ttype/push HTTP/1.1


Host: https://yourprivacyideaserver

serial=<token serial>
fbtoken=<Firebase token>
pubkey=<public key>

• It is also used when the smartphone sends the signed response to the challenge during authentication.
The following parameters are accepted:

POST /ttype/push HTTP/1.1


Host: https://yourprivacyideaserver

serial=<token serial>
(continues on next page)

1.15. Code Documentation 313


privacyIDEA Authentication System, Release 3.8

(continued from previous page)


nonce=<the actual challenge>
signature=<signature over {nonce}|{serial}>

• The smartphone can also decline the authentication request, by sending a response to the server:

POST /ttype/push HTTP/1.1


Host: https://yourprivacyideaserver

serial=<token serial>
nonce=<the actual challenge>
decline=1
signature=<signature over {nonce}|{serial}|decline

• In some cases the Firebase service changes the token of a device. This needs to be communicated
to privacyIDEA through this endpoint (https://github.com/privacyidea/privacyidea/wiki/concept%
3A-pushtoken-poll#update -firebase-token):

POST /ttype/push HTTP/1.1


Host: https://yourprivacyideaserver

new_fb_token=<new Firebase token>


serial=<token serial>
timestamp=<timestamp>
signature=SIGNATURE(<new_fb_token>|<serial>|<timestamp>)

• And it also acts as an endpoint for polling challenges:

GET /ttype/push HTTP/1.1


Host: https://yourprivacyideaserver

serial=<tokenserial>
timestamp=<timestamp>
signature=SIGNATURE(<tokenserial>|<timestamp>)

More on polling can be found here: https://github.com/privacyidea/privacyidea/wiki/concept%


3A-pushtoken-poll

Parameters
• request – The Flask request
• g – The Flask global object g
Returns The json string representing the result dictionary
Return type tuple(“json”, str)

authenticate(passw, user=None, options=None)


High level interface which covers the check_pin and check_otp This is the method that verifies single shot
authentication. The challenge is send to the smartphone app and privacyIDEA waits for the response to
arrive.
Parameters
• passw (string) – the password which could be pin+otp value
• user (User object) – The authenticating user

314 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

• options (dict) – dictionary of additional request parameters


Returns
returns tuple of
1. true or false for the pin match,
2. the otpcounter (int) and the
3. reply (dict) that will be added as additional information in the JSON response of /
validate/check.
Return type tuple
check_challenge_response(user=None, passw=None, options=None)
This function checks, if the challenge for the given transaction_id was marked as answered correctly. For
this we check the otp_status of the challenge with the transaction_id in the database.
We do not care about the password
Parameters
• user (User object) – the requesting user
• passw (string) – the password (pin+otp)
• options (dict) – additional arguments from the request, which could be token specific.
Usually “transaction_id”
Returns return otp_counter. If -1, challenge does not match
Return type int
check_if_disabled = False
client_mode = 'poll'
create_challenge(transactionid=None, options=None)
This method creates a challenge, which is submitted to the user. The submitted challenge will be preserved
in the challenge database.
If no transaction id is given, the system will create a transaction id and return it, so that the response can
refer to this transaction.
Parameters
• transactionid – the id of this challenge
• options (dict) – the request context parameters / data
Returns tuple of (bool, message, transactionid, attributes)
Return type tuple
The return tuple builds up like this: bool if submit was successful; message which is displayed in the
JSON response; additional challenge reply_dict, which are displayed in the JSON challenges response.
classmethod enroll_via_validate(g, content, user_obj)
This class method is used in the policy ENROLL_VIA_MULTICHALLENGE. It enrolls a new token of
this type and returns the necessary information to the client by modifying the content.
Parameters
• g – context object
• content – The content of a response

1.15. Code Documentation 315


privacyIDEA Authentication System, Release 3.8

• user_obj – A user object


Returns None, the content is modified
static get_class_info(key=None, ret='all')
returns all or a subtree of the token definition
Parameters
• key (str) – subsection identifier
• ret (user defined) – default return value, if nothing is found
Returns subsection if key exists or user defined
Return type dict
static get_class_prefix()
static get_class_type()
return the generic token class identifier
get_init_detail(params=None, user=None)
This returns the init details during enrollment.
In the 1st step the QR Code is returned.
is_challenge_request(passw, user=None, options=None)
check, if the request would start a challenge
We need to define the function again, to get rid of the is_challenge_request-decorator of the base class
Parameters
• passw – password, which might be pin or pin+otp
• options – dictionary of additional request parameters
Returns returns true or false
is_multichallenge_enrollable = True
mode = ['authenticate', 'challenge', 'outofband']
update(param, reset_failcount=True)
process the initialization parameters
We need to distinguish the first authentication step and the second authentication step.
1. step: param contains:
• type
• genkey
2. step: param contains:
• serial
• fbtoken
• pubkey

Parameters param (dict) – dict of initialization parameters


Returns nothing

316 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Questionnaire Token

class privacyidea.lib.tokens.questionnairetoken.QuestionnaireTokenClass(db_token)
This is a Questionnaire Token. The token stores a list of questions and answers in the tokeninfo database table.
The answers are encrypted. During authentication a random answer is selected and presented as challenge. The
user has to remember and pass the right answer.
Create a new QUST Token object from a database token
Parameters db_token (DB object) – instance of the orm db object
check_answer(given_answer, challenge_object)
Check if the given answer is the answer to the sent question. The question for this challenge response was
stored in the challenge_object.
Then we get the answer from the tokeninfo.
Parameters
• given_answer – The answer given by the user
• challenge_object – The challenge object as stored in the database
Returns in case of success: 1
check_challenge_response(user=None, passw=None, options=None)
This method verifies if there is a matching question for the given passw and also verifies if the answer is
correct.
It then returns the the otp_counter = 1
Parameters
• user (User object) – the requesting user
• passw (string) – the password - in fact it is the answer to the question
• options (dict) – additional arguments from the request, which could be token specific.
Usually “transaction_id”
Returns return 1 if the answer to the question is correct, -1 otherwise.
Return type int
create_challenge(transactionid=None, options=None)
This method creates a challenge, which is submitted to the user. The submitted challenge will be preserved
in the challenge database.
The challenge is a randomly selected question of the available questions for this token.
If no transaction id is given, the system will create a transaction id and return it, so that the response can
refer to this transaction.
Parameters
• transactionid – the id of this challenge
• options (dict) – the request context parameters / data
Returns tuple of (bool, message, transactionid, reply_dict)
Return type tuple
The return tuple builds up like this: bool if submit was successful; message which is displayed in the
JSON response; additional challenge reply_dict, which are displayed in the JSON challenges response.

1.15. Code Documentation 317


privacyIDEA Authentication System, Release 3.8

classmethod get_class_info(key=None, ret='all')


returns a subtree of the token definition
Parameters
• key (string) – subsection identifier
• ret (user defined) – default return value, if nothing is found
Returns subsection if key exists or user defined
Return type dict or scalar
static get_class_prefix()
Return the prefix, that is used as a prefix for the serial numbers. :return: QUST :rtype: basestring
static get_class_type()
Returns the internal token type identifier :return: qust :rtype: basestring
static get_setting_type(key)
The setting type of questions is public, so that the user can also read the questions.
Parameters key – The key of the setting
Returns “public” string
has_further_challenge(options=None)
Check if there are still more questions to be asked.
Parameters options – Options dict
Returns True, if further challenge is required.
is_challenge_request(passw, user=None, options=None)
The questionnaire token is always a challenge response token. The challenge is triggered by providing the
PIN as the password.
Parameters
• passw (string) – password, which might be pin or pin+otp
• user (User object) – The user from the authentication request
• options (dict) – dictionary of additional request parameters
Returns true or false
Return type bool
update(param)
This method is called during the initialization process.
Parameters param (dict) – parameters from the token init
Returns None

318 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

RADIUS Token

class privacyidea.lib.tokens.radiustoken.RadiusTokenClass(db_token)
constructor - create a token class object with it’s db token binding
Parameters aToken – the db bound token
authenticate(passw, user=None, options=None)
do the authentication on base of password / otp and user and options, the request parameters.
This is only called after it is verified, that the upper level is no challenge-request or challenge-response
The “options” are read-only in this method. They are not modified here. authenticate is the last method in
the loop check_token_list.
communication with RADIUS server: yes, if is no previous “radius_result” If there is a “radius” re-
sult in the options, we do not query the radius server
modification of options: options can be modified if we query the radius server. However, this is not
important since authenticate is the last call.

Parameters
• passw – the password / otp
• user – the requesting user
• options – the additional request parameters
Returns tuple of (success, otp_count - 0 or -1, reply)

check_challenge_response(user=None, passw=None, options=None)


This method verifies if there is a matching question for the given passw and also verifies if the answer is
correct.
It then returns the the otp_counter = 1
Parameters
• user (User object) – the requesting user
• passw (string) – the password - in fact it is the answer to the question
• options (dict) – additional arguments from the request, which could be token specific.
Usually “transaction_id”
Returns return otp_counter. If -1, challenge does not match
Return type int
check_otp(otpval, counter=None, window=None, options=None)
Originally check_otp returns an OTP counter. I.e. in a failed attempt we return -1. In case of success we
return 1 :param otpval: :param counter: :param window: :param options: :return:
property check_pin_local
lookup if pin should be checked locally or on radius host
Returns bool
create_challenge(transactionid=None, options=None)
create a challenge, which is submitted to the user
This method is called after is_challenge_request has verified, that a challenge needs to be created.
communication with RADIUS server: no modification of options: no

1.15. Code Documentation 319


privacyIDEA Authentication System, Release 3.8

Parameters
• transactionid – the id of this challenge
• options – the request context parameters / data
Returns
tuple of (bool, message and data) bool, if submit was successful message is submitted to the
user data is preserved in the challenge reply_dict - additional attributes, which are displayed
in the
output
static get_class_info(key=None, ret='all')
returns a subtree of the token definition
Parameters
• key (string) – subsection identifier
• ret (user defined) – default return value, if nothing is found
Returns subsection if key exists or user defined
Return type dict or string
static get_class_prefix()
return the token type prefix
static get_class_type()
return the class type identifier
is_challenge_request(passw, user=None, options=None)
This method checks, if this is a request, that triggers a challenge. It depends on the way, the pin is checked -
either locally or remotely. In addition, the RADIUS token has to be configured to allow challenge response.
communication with RADIUS server: yes modification of options: The communication with the RADIUS
server can
change the options, radius_state, radius_result, radius_message

Parameters
• passw (string) – password, which might be pin or pin+otp
• user (User object) – The user from the authentication request
• options (dict) – dictionary of additional request parameters
Returns true or false

is_challenge_response(passw, user=None, options=None)


This method checks, if this is a request, that is the response to a previously sent challenge. But we do not
query the RADIUS server.
This is the first method in the loop check_token_list.
communication with RADIUS server: no modification of options: The “radius_result” key is set to None
Parameters
• passw (string) – password, which might be pin or pin+otp
• user (User object) – the requesting user
• options (dict) – dictionary of additional request parameters

320 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Returns true or false


Return type bool
split_pin_pass(passw, user=None, options=None)
Split the PIN and the OTP value. Only if it is locally checked and not remotely.
update(param)
second phase of the init process - updates parameters
Parameters param – the request parameters
Returns
• nothing -

Registration Code Token

class privacyidea.lib.tokens.registrationtoken.RegistrationTokenClass(aToken)
Token to implement a registration code. It can be used to create a registration code or a “TAN” which can be
used once by a user to authenticate somewhere. After this registration code is used, the token is automatically
deleted.
The idea is to provide a workflow, where the user can get a registration code by e.g. postal mail and then use this
code as the initial first factor to authenticate to the UI to enroll real tokens.
A registration code can be created by an administrative task with the token/init api like this:
Example Authentication Request:

POST /token/init HTTP/1.1


Host: example.com
Accept: application/json

type=registration
user=cornelius
realm=realm1

Example response:

HTTP/1.1 200 OK
Content-Type: application/json

{
"detail": {
"registrationcode": "12345808124095097608"
},
"id": 1,
"jsonrpc": "2.0",
"result": {
"status": true,
"value": true
},
"version": "privacyIDEA unknown"
}

Create a new token object.

1.15. Code Documentation 321


privacyIDEA Authentication System, Release 3.8

Parameters db_token (Token) – A database token object


Returns A TokenClass object
static get_class_info(key=None, ret='all')
returns a subtree of the token definition
Parameters
• key (string) – subsection identifier
• ret (user defined) – default return value, if nothing is found
Returns subsection if key exists or user defined
Return type dict or scalar
static get_class_prefix()
static get_class_type()
password_detail_key = 'registrationcode'
post_success()
Delete the registration token after successful authentication
update(param)
This method is called during the initialization process. :param param: parameters from the token init :type
param: dict :return: None

Remote Token

class privacyidea.lib.tokens.remotetoken.RemoteTokenClass(db_token)
The Remote token forwards an authentication request to another privacyIDEA server. The request can be for-
warded to a user on the other server or to a serial number on the other server. The PIN can be checked on the
local privacyIDEA server or on the remote server.
Using the Remote token you can assign one physical token to many different users.
constructor - create a token class object with it’s db token binding
Parameters aToken – the db bound token
authenticate(passw, user=None, options=None)
do the authentication on base of password / otp and user and options, the request parameters.
Here we contact the other privacyIDEA server to validate the OtpVal.
Parameters
• passw – the password / otp
• user – the requesting user
• options – the additional request parameters
Returns tuple of (success, otp_count - 0 or -1, reply)
check_otp(otpval, counter=None, window=None, options=None)
run the http request against the remote host
Parameters
• otpval – the OTP value
• counter (int) – The counter for counter based otp values

322 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

• window – a counter window


• options (dict) – additional token specific options
Returns counter of the matching OTP value.
Return type int
property check_pin_local
lookup if pin should be checked locally or on remote host
Returns bool
static get_class_info(key=None, ret='all')

Parameters
• key (string) – subsection identifier
• ret (user defined) – default return value, if nothing is found
Returns subsection if key exists or user defined
Return type dict or string
static get_class_prefix()
return the token type prefix
static get_class_type()
return the class type identifier
is_challenge_request(passw, user=None, options=None)
This method checks, if this is a request, that triggers a challenge. It depends on the way, the pin is checked
- either locally or remote
Parameters
• passw (string) – password, which might be pin or pin+otp
• user (User object) – The user from the authentication request
• options (dict) – dictionary of additional request parameters
Returns true or false
update(param)
second phase of the init process - updates parameters
Parameters param – the request parameters
Returns
• nothing -

1.15. Code Documentation 323


privacyIDEA Authentication System, Release 3.8

SMS Token

class privacyidea.lib.tokens.smstoken.SmsTokenClass(db_token)
The SMS token sends an SMS containing an OTP via some kind of gateway. The gateways can be an SMTP or
HTTP gateway or the special sipgate protocol. The Gateways are defined in the SMSProvider Modules.
The SMS token is a challenge response token. I.e. the first request needs to contain the correct OTP PIN. If the
OTP PIN is correct, the sending of the SMS is triggered. The second authentication must either contain the OTP
PIN and the OTP value or the transaction_id and the OTP value.
Example 1st Authentication Request:

POST /validate/check HTTP/1.1


Host: example.com
Accept: application/json

user=cornelius
pass=otppin

Example 1st response:

HTTP/1.1 200 OK
Content-Type: application/json

{
"detail": {
"transaction_id": "xyz"
},
"id": 1,
"jsonrpc": "2.0",
"result": {
"status": true,
"value": false
},
"version": "privacyIDEA unknown"
}

After this, the SMS is triggered. When the SMS is received the second part of authentication looks like this:
Example 2nd Authentication Request:

POST /validate/check HTTP/1.1


Host: example.com
Accept: application/json

user=cornelius
transaction_id=xyz
pass=otppin

Example 1st response:

HTTP/1.1 200 OK
Content-Type: application/json

{
(continues on next page)

324 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

(continued from previous page)


"detail": {
},
"id": 1,
"jsonrpc": "2.0",
"result": {
"status": true,
"value": true
},
"version": "privacyIDEA unknown"
}

Create a new HOTP Token object


Parameters db_token (DB object) – instance of the orm db object
check_otp(anOtpVal, counter=None, window=None, options=None)
check the otpval of a token against a given counter and the window
Parameters passw (string) – the to be verified passw/pin
Returns counter if found, -1 if not found
Return type int
create_challenge(transactionid=None, options=None)
create a challenge, which is submitted to the user
Parameters
• transactionid – the id of this challenge
• options – the request context parameters / data You can pass exception=1 to raise an
exception, if the SMS could not be sent.
Returns tuple of (bool, message and data) bool, if submit was successful message is submitted to
the user data is preserved in the challenge reply_dict - additional reply_dict, which is added
to the response
classmethod enroll_via_validate(g, content, user_obj)
This class method is used in the policy ENROLL_VIA_MULTICHALLENGE. It enrolls a new token of
this type and returns the necessary information to the client by modifying the content.
Parameters
• g – context object
• content – The content of a response
• user_obj – A user object
Returns None, the content is modified
enroll_via_validate_2nd_step(passw, options=None)
This method is the optional second step of ENROLL_VIA_MULTICHALLENGE. It is used in situations
like the email token, sms token or push, when enrollment via challenge response needs two steps.
The passw is entered during the first authentication step and it contains the email address.
So we need to update the token with the email address and we need to create a new challenge for the final
authentication.
Parameters options –

1.15. Code Documentation 325


privacyIDEA Authentication System, Release 3.8

Returns
static get_class_info(key=None, ret='all')
returns all or a subtree of the token definition
Parameters
• key (string) – subsection identifier
• ret (user defined) – default return value, if nothing is found
Returns subsection if key exists or user defined
:rtype : s.o.
static get_class_prefix()
Return the prefix, that is used as a prefix for the serial numbers. :return: oath
static get_class_type()
return the generic token class identifier
is_challenge_request(passw, user=None, options=None)
check, if the request would start a challenge
We need to define the function again, to get rid of the is_challenge_request-decorator of the HOTP-Token
Parameters
• passw – password, which might be pin or pin+otp
• options – dictionary of additional request parameters
Returns returns true or false
prepare_verify_enrollment()
This is called, if the token should be enrolled in a way, that the user needs to provide a proof, that the server
can verify, that the token was successfully enrolled. The email token needs to send an email with OTP.
The returned dictionary is added to the response in “detail” -> “verify”.
Returns A dictionary with information that is needed to trigger the verification.
update(param, reset_failcount=True)
process initialization parameters
Parameters param (dict) – dict of initialization parameters
Returns nothing

SPass Token

class privacyidea.lib.tokens.spasstoken.SpassTokenClass(db_token)
This is a simple pass token. It does have no OTP component. The OTP checking will always succeed. Of course,
an OTP PIN can be used.
Create a new token object.
Parameters db_token (Token) – A database token object
Returns A TokenClass object
authenticate(passw, user=None, options=None)
in case of a wrong passw, we return a bad matching pin, so the result will be an invalid token

326 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

check_otp(otpval, counter=None, window=None, options=None)


As we have no otp value we always return true. (counter == 0)
static get_class_info(key=None, ret='all')
returns a subtree of the token definition Is used by lib.token.get_token_info
Parameters
• key (string) – subsection identifier
• ret (user defined) – default return value, if nothing is found
Returns subsection if key exists or user defined
Return type dict
static get_class_prefix()
static get_class_type()
static is_challenge_request(passw, user, options=None)
The spass token does not support challenge response :param passw: :param user: :param options: :return:
static is_challenge_response(passw, user, options=None, challenges=None)
This method checks, if this is a request that is supposed to be the answer to a previous challenge.
The default behaviour to check if this is the response to a previous challenge is simply by checking if the
request contains a parameter state or transactionid i.e. checking if the options parameter contains
a key state or transactionid.
This method does not try to verify the response itself! It only determines, if this is a response for a challenge
or not. If the challenge still exists, is checked in has_db_challenge_response. The response is verified in
check_challenge_response.
Parameters
• passw (string) – password, which might be pin or pin+otp
• user (User object) – the requesting user
• options (dict) – dictionary of additional request parameters
Returns true or false
Return type bool
update(param)
Update the token object
Parameters param – a dictionary with different params like keysize, description, genkey, otpkey,
pin
Type param: dict

1.15. Code Documentation 327


privacyIDEA Authentication System, Release 3.8

SSHKey Token

class privacyidea.lib.tokens.sshkeytoken.SSHkeyTokenClass(db_token)
The SSHKeyTokenClass provides a TokenClass that stores the public SSH key. This can be used to manage SSH
keys and retrieve the public ssh key to import it to authorized keys files.
Create a new token object.
Parameters db_token (Token) – A database token object
Returns A TokenClass object
static get_class_info(key=None, ret='all')
returns a subtree of the token definition
Parameters
• key (string) – subsection identifier
• ret (user defined) – default return value, if nothing is found
Returns subsection if key exists or user defined
Return type dictionary
static get_class_prefix()
static get_class_type()
get_sshkey()
returns the public SSH key
Returns SSH pub key
Return type string
mode = ['authenticate']
update(param)
The key holds the public ssh key and this is required
The key probably is of the form “ssh-rsa BASE64 comment”
using_pin = False

TiQR Token

The TiQR token is a special App based token, which allows easy login and which is based on OCRA.
It generates an enrollment QR code, which contains a link with the more detailed enrollment information.
For a description of the TiQR protocol see
• https://www.usenix.org/legacy/events/lisa11/tech/full_papers/Rijswijk.pdf
• https://github.com/SURFnet/tiqr/wiki/Protocol-documentation.
• https://tiqr.org
The TiQR token is based on the OCRA algorithm. It lets you authenticate with your smartphone by scanning a QR
code.
The TiQR token is enrolled via /token/init, but it requires no otpkey, since the otpkey is generated on the smartphone
and pushed to the privacyIDEA server in a seconds step.

328 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Enrollment

1. Start enrollment with /token/init


2. Scan the QR code in the details of the JSON result. The QR code contains a link to /ttype/tiqr?action=metadata
3. The TiQR Smartphone App will fetch this link and get more information
4. The TiQR Smartphone App will push the otpkey to a link /ttype/tiqr?action=enrollment and the token will be
ready for use.

Authentication

An application that wants to use the TiQR token with privacyIDEA has to use the token in challenge response.
1. Call /validate/check?user=<user>&pass=<pin> with the PIN of the TiQR token
2. The details of the JSON response contain a QR code, that needs to be shown to the user. In addition the application
needs to save the transaction_id in the response.
3. The user scans the QR code.
4. The TiQR App communicates with privacyIDEA via the API /ttype/tiqr. In this step the response of the App
to the challenge is verified. The successful authentication is stored in the Challenge DB table. (No need for the
application to take any action)
5. Now, the application needs to poll /validate/polltransaction?transaction_id=<transaction_id> to
check the transaction status. If the endpoint returns false, the challenge has not been answered yet.
6. Once /validate/polltransaction returns true, the application needs to finalize the authentication with a
request /validate/check?user=<user>&transaction_id=<transaction_id>&pass=. The pass can be
empty. If value=true is returned, the user authenticated successfully with the TiQR token.
This code is tested in tests/test_lib_tokens_tiqr.

Implementation

class privacyidea.lib.tokens.tiqrtoken.TiqrTokenClass(db_token)
The TiQR Token implementation.
Create a new TiQR Token object from a database object
Parameters db_token (DB object) – instance of the orm db object
classmethod api_endpoint(request, g)
This provides a function to be plugged into the API endpoint /ttype/<tokentype> which is defined in
api/ttype.py See Tokentype endpoints.
Parameters
• request – The Flask request
• g – The Flask global object g
Returns Flask Response or text
check_challenge_response(user=None, passw=None, options=None)
This function checks, if the challenge for the given transaction_id was marked as answered correctly. For
this we check the otp_status of the challenge with the transaction_id in the database.
We do not care about the password

1.15. Code Documentation 329


privacyIDEA Authentication System, Release 3.8

Parameters
• user (User object) – the requesting user
• passw (string) – the password (pin+otp)
• options (dict) – additional arguments from the request, which could be token specific.
Usually “transaction_id”
Returns return otp_counter. If -1, challenge does not match
Return type int
client_mode = 'poll'
create_challenge(transactionid=None, options=None)
This method creates a challenge, which is submitted to the user. The submitted challenge will be preserved
in the challenge database.
If no transaction id is given, the system will create a transaction id and return it, so that the response can
refer to this transaction.
Parameters
• transactionid – the id of this challenge
• options (dict) – the request context parameters / data
Returns tuple of (bool, message, transactionid, reply_dict)
Return type tuple
The return tuple builds up like this: bool if submit was successful; message which is displayed in the
JSON response; additional challenge reply_dict, which are displayed in the JSON challenges response.
static get_class_info(key=None, ret='all')
returns a subtree of the token definition
Parameters
• key (string) – subsection identifier
• ret (user defined) – default return value, if nothing is found
Returns subsection if key exists or user defined
Return type dict or scalar
static get_class_prefix()
Return the prefix, that is used as a prefix for the serial numbers. :return: TiQR :rtype: basestring
static get_class_type()
Returns the internal token type identifier :return: tiqr :rtype: basestring
get_init_detail(params=None, user=None)
At the end of the initialization we return the URL for the TiQR App.
mode = ['authenticate', 'challenge', 'outofband']
update(param)
This method is called during the initialization process.
Parameters param (dict) – parameters from the token init
Returns None

330 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

TOTP Token

class privacyidea.lib.tokens.totptoken.TotpTokenClass(db_token)
Create a new TOTP token object from a DB Token object
Parameters db_token (orm object) – instance of the orm db object
check_otp(anOtpVal, counter=None, window=None, options=None)
validate the token otp against a given otpvalue
Parameters
• anOtpVal (string) – the to be verified otpvalue
• counter – the counter state, that should be verified. For TOTP
this is the unix system time (seconds) divided by 30/60 :type counter: int :param window: the counter
+window (sec), which should be checked :type window: int :param options: the dict, which could contain
token specific info :type options: dict :return: the counter or -1 :rtype: int
check_otp_exist(otp, window=None, options=None, symetric=True, inc_counter=True)
checks if the given OTP value is/are values of this very token at all. This is used to autoassign and to
determine the serial number of a token. In fact it is a check_otp with an enhanced window.
Parameters
• otp (string) – the to be verified otp value
• window (int) – the lookahead window for the counter in seconds!!!
Returns counter or -1 if otp does not exist
Return type int
desc_timestep = 'Specify the time step of the time-based OTP token.'
static get_class_info(key=None, ret='all')
returns a subtree of the token definition
Parameters
• key (string) – subsection identifier
• ret (user defined) – default return value, if nothing is found
Returns subsection if key exists or user defined
Return type dict or scalar
static get_class_prefix()
Return the prefix, that is used as a prefix for the serial numbers. :return: TOTP
static get_class_type()
return the token type shortname
Returns ‘totp’
Return type string
classmethod get_default_settings(g, params)
This method returns a dictionary with default settings for token enrollment. These default settings are
defined in SCOPE.USER or SCOPE.ADMIN and are totp_hashlib, totp_timestep and totp_otplen. If these
are set, the user or admin will only be able to enroll tokens with these values.
The returned dictionary is added to the parameters of the API call. :param g: context object, see documen-
tation of Match :param params: The call parameters :type params: dict :return: default parameters

1.15. Code Documentation 331


privacyIDEA Authentication System, Release 3.8

static get_import_csv(l)
Read the list from a csv file and return a dictionary, that can be used to do a token_init.
Parameters l (list) – The list of the line of a csv file
Returns A dictionary of init params
get_multi_otp(count=0, epoch_start=0, epoch_end=0, curTime=None, timestamp=None)
return a dictionary of multiple future OTP values of the HOTP/HMAC token
Parameters
• count (int) – how many otp values should be returned
• epoch_start – not implemented
• epoch_end – not implemented
• curTime (datetime) – Simulate the servertime
• timestamp (epoch time) – Simulate the servertime
Returns tuple of status: boolean, error: text and the OTP dictionary
get_otp(current_time=None, do_truncation=True, time_seconds=None, challenge=None)
get the next OTP value
Parameters current_time – the current time, for which the OTP value
should be calculated for. :type current_time: datetime object :param time_seconds: the current time, for
which the OTP value should be calculated for (date +%s) :type: time_seconds: int, unix system time sec-
onds :return: next otp value, and PIN, if possible :rtype: tuple
static get_setting_type(key)
This function returns the type of the token specific config/setting. This way a tokenclass can define settings,
that can be “public” or a “password”. If this setting is written to the database, the type of the setting is set
automatically in set_privacyidea_config
The key name needs to start with the token type.
Parameters key – The token specific setting key
Returns A string like “public”
property hashlib
previous_otp_offset = 0
resync(otp1, otp2, options=None)
resync the token based on two otp values external method to do the resync of the token
Parameters
• otp1 (string) – the first otp value
• otp2 (string) – the second otp value
• options (dict or None) – optional token specific parameters
Returns counter or -1 if otp does not exist
Return type int
property timeshift
property timestep
property timewindow

332 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

update(param, reset_failcount=True)
This is called during initialization of the token to add additional attributes to the token object.
Parameters param (dict) – dict of initialization parameters
Returns nothing

U2F Token

U2F is the “Universal 2nd Factor” specified by the FIDO Alliance. The register and authentication process is described
here:
https://fidoalliance.org/specs/fido-u2f-v1.0-nfc-bt-amendment-20150514/fido-u2f-raw-message-formats.html
But you do not need to be aware of this. privacyIDEA wraps all FIDO specific communication, which should make it
easier for you, to integrate the U2F tokens managed by privacyIDEA into your application.
U2F Tokens can be either
• registered by administrators for users or
• registered by the users themselves.

Enrollment

The enrollment/registering can be completely performed within privacyIDEA.


But if you want to enroll the U2F token via the REST API you need to do it in two steps:

1. Step

POST /token/init HTTP/1.1


Host: example.com
Accept: application/json

type=u2f

This step returns a serial number.

2. Step

POST /token/init HTTP/1.1


Host: example.com
Accept: application/json

type=u2f
serial=U2F1234578
clientdata=<clientdata>
regdata=<regdata>

clientdata and regdata are the values returned by the U2F device.
You need to call the javascript function

1.15. Code Documentation 333


privacyIDEA Authentication System, Release 3.8

u2f.register([registerRequest], [], function(u2fData) {} );

and the responseHandler needs to send the clientdata and regdata back to privacyIDEA (2. step).

Authentication

The U2F token is a challenge response token. I.e. you need to trigger a challenge e.g. by sending the OTP PIN/Password
for this token.

Get the challenge

POST /validate/check HTTP/1.1


Host: example.com
Accept: application/json

user=cornelius
pass=tokenpin

Response

HTTP/1.1 200 OK
Content-Type: application/json

{
"detail": {
"attributes": {
"hideResponseInput": true,
"img": ...imageUrl...
"u2fSignRequest": {
"challenge": "...",
"appId": "...",
"keyHandle": "...",
"version": "U2F_V2"
}
},
"message": "Please confirm with your U2F token (Yubico U2F EE ...)"
"transaction_id": "02235076952647019161"
},
"id": 1,
"jsonrpc": "2.0",
"result": {
"status": true,
"value": false,
},
"version": "privacyIDEA unknown"
}

334 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Send the Response

The application now needs to call the javascript function u2f.sign with the u2fSignRequest from the response.
var signRequests = [ error.detail.attributes.u2fSignRequest ]; u2f.sign(signRequests, function(u2fResult)
{} );
The response handler function needs to call the /validate/check API again with the signatureData and clientData re-
turned by the U2F device in the u2fResult:

POST /validate/check HTTP/1.1


Host: example.com
Accept: application/json

user=cornelius
pass=
transaction_id=<transaction_id>
signaturedata=signatureData
clientdata=clientData

Implementation

class privacyidea.lib.tokens.u2ftoken.U2fTokenClass(db_token)
The U2F Token implementation.
Create a new U2F Token object from a database object
Parameters db_token (DB object) – instance of the orm db object
classmethod api_endpoint(request, g)
This provides a function to be plugged into the API endpoint /ttype/u2f
The u2f token can return the facet list at this URL.
Parameters
• request – The Flask request
• g – The Flask global object g
Returns Flask Response or text
check_otp(otpval, counter=None, window=None, options=None)
This checks the response of a previous challenge.
Parameters
• otpval – N/A
• counter – The authentication counter
• window – N/A
• options – contains “clientdata”, “signaturedata” and “transaction_id”
Returns A value > 0 in case of success
client_mode = 'u2f'
create_challenge(transactionid=None, options=None)
This method creates a challenge, which is submitted to the user. The submitted challenge will be preserved
in the challenge database.

1.15. Code Documentation 335


privacyIDEA Authentication System, Release 3.8

If no transaction id is given, the system will create a transaction id and return it, so that the response can
refer to this transaction.
Parameters
• transactionid – the id of this challenge
• options (dict) – the request context parameters / data
Returns tuple of (bool, message, transactionid, attributes)
Return type tuple
The return tuple builds up like this: bool if submit was successful; message which is displayed in the
JSON response; additional challenge reply_dict, which are displayed in the JSON challenges response.
static get_class_info(key=None, ret='all')
returns a subtree of the token definition
Parameters
• key (string) – subsection identifier
• ret (user defined) – default return value, if nothing is found
Returns subsection if key exists or user defined
Return type dict or scalar
static get_class_prefix()
Return the prefix, that is used as a prefix for the serial numbers. :return: U2F :rtype: basestring
static get_class_type()
Returns the internal token type identifier :return: u2f :rtype: basestring
get_init_detail(params=None, user=None)
At the end of the initialization we ask the user to press the button
is_challenge_request(passw, user=None, options=None)
check, if the request would start a challenge In fact every Request that is not a response needs to start a
challenge request.
At the moment we do not think of other ways to trigger a challenge.
This function is not decorated with @challenge_response_allowed as the U2F token is always a chal-
lenge response token!
Parameters
• passw – The PIN of the token.
• options – dictionary of additional request parameters
Returns returns true or false
update(param, reset_failcount=True)
This method is called during the initialization process.
Parameters param (dict) – parameters from the token init
Returns None

336 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Vasco Token

WebAuthn Token

WebAuthn is the Web Authentication API specified by the FIDO Alliance. The register and authentication process is
described here:
https://w3c.github.io/webauthn/#sctn-rp-operations
But you do not need to be aware of this. privacyIDEA wraps all FIDO specific communication, which should make it
easier for you, to integrate the U2F tokens managed by privacyIDEA into your application.
WebAuthn tokens can be either
• registered by administrators for users or
• registered by the users themselves.
Be aware that WebAuthn tokens can only be used if the privacyIDEA server and the applications and services the user
needs to access all reside under the same domain or subdomains thereof.
This means a WebAuthn token registered by privacyidea.mycompany.com can be used to sign in to sites like my-
company.com and vpn.mycompany.com, but not (for example) mycompany.someservice.com.

Enrollment

The enrollment/registering can be completely performed within privacyIDEA.


But if you want to enroll the WebAuthn token via the REST API you need to do it in two steps:
Step 1

POST /token/init HTTP/1.1


Host: <privacyIDEA server>
Accept: application/json

type=webauthn
user=<username>

The request returns:

HTTP/1.1 200 OK
Content-Type: application/json

{
"detail": {
"serial": "<serial number>",
"webAuthnRegisterRequest": {
"attestation": "direct",
"authenticatorSelection": {
"userVerification": "preferred"
},
"displayName": "<user.resolver@realm>",
"message": "Please confirm with your WebAuthn token",
"name": "<username>",
"nonce": "<nonce>",
(continues on next page)

1.15. Code Documentation 337


privacyIDEA Authentication System, Release 3.8

(continued from previous page)


"pubKeyCredAlgorithms": [
{
"alg": -7,
"type": "public-key"
},
{
"alg": -37,
"type": "public-key"
}
],
"relyingParty": {
"id": "<relying party ID>",
"name": "<relying party name>"
},
"serialNumber": "<serial number>",
"timeout": 60000,
"transaction_id": "<transaction ID>"
}
},
"result": {
"status": true,
"value": true
},
"version": "<privacyIDEA version>"
}

This step returns a webAuthnRegisterRequest which contains a nonce, a relying party (containing a name and an ID
generated from your domain), a serial number along with a transaction ID and a message to display to the user. It will
also contain some additional options regarding timeout, which authenticators are acceptable, and what key types are
acceptable to the server.
With the received data You need to call the javascript function

navigator
.credentials
.create({
challenge: <nonce>,
rp: <relyingParty>,
user: {
id: Uint8Array.from(<serialNumber>, c => c.charCodeAt(0)),
name: <name>,
displayName: <displayName>
},
pubKeyCredParams: <pubKeyCredAlgorithms>,
authenticatorSelection: <authenticatorSelection>,
timeout: <timeout>,
attestation: <attestation>,
extensions: {
authnSel: <authenticatorSelectionList>
}
})
.then(function(credential) { <responseHandler> })
.catch(function(error) { <errorHandler> });

338 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Here nonce, relyingParty, serialNumber, pubKeyCredAlgorithms, authenticatorSelection, timeout, attestation, authen-


ticatorSelectionList, name, and displayName are the values provided by the server in the webAuthnRegisterRequest
field in the response from the first step. authenticatorSelection, timeout, attestation, and authenticatorSelectionList are
optional. If attestation is not provided, the client should default to direct attestation. If timeout is not provided, it may
be omitted, or a sensible default chosen. Any other optional values must be omitted, if the server has not sent them.
Please note that the nonce will be a binary, encoded using the web-safe base64 algorithm specified by WebAuthn, and
needs to be decoded and passed as Uint8Array.
If an authenticationSelectionList was given, the responseHandler needs to verify, that the field authnSel of creden-
tial.getExtensionResults() contains true. If this is not the case, the responseHandler should abort and call the er-
rorHandler, displaying an error telling the user to use his company-provided token.
The responseHandler needs to then send the clientDataJSON, attestationObject, and registrationClientExtensions con-
tained in the response field of the credential back to the server. If enrollment succeeds, the server will send a response
with a webAuthnRegisterResponse field, containing a subject field with the description of the newly created token.
Step 2

POST /token/init HTTP/1.1


Host: <privacyIDEA server>
Accept: application/json

type=webauthn
transaction_id=<transaction_id>
description=<description>
clientdata=<clientDataJSON>
regdata=<attestationObject>
registrationclientextensions=<registrationClientExtensions>

The values clientDataJSON and attestationObject are returned by the WebAuthn authenticator. description is an op-
tional description string for the new token.
The server expects the clientDataJSON and attestationObject encoded as web-safe base64 as defined by the WebAuthn
standard. This encoding is similar to standard base64, but ‘-’ and ‘_’ should be used in the alphabet instead of ‘+’ and
‘/’, respectively, and any padding should be omitted.
The registrationClientExtensions are optional and should simply be omitted, if the client does not provide them. If
the registrationClientExtensions are available, they must be encoded as a utf-8 JSON string, then sent to the server as
web-safe base64.
Please beware that the btoa() function provided by ECMA-Script expects a 16-bit encoded string where all characters are
in the range 0x0000 to 0x00FF. The attestationObject contains CBOR-encoded binary data, returned as an ArrayBuffer.
The problem and ways to solve it are described in detail in this MDN-Article:
https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding#The_
Unicode_Problem

1.15. Code Documentation 339


privacyIDEA Authentication System, Release 3.8

Authentication

The WebAuthn token is a challenge response token. I.e. you need to trigger a challenge, either by sending the OTP
PIN/Password for this token to the /validate/check endpoint, or by calling the /validate/triggerchallenge endpoint using
a service account with sufficient permissions.

Get the challenge (using /validate/check)

The /validate/check endpoint can be used to trigger a challenge using the PIN for the token (without requiring any
special permissions).
Request:
POST /validate/check HTTP/1.1
Host: <privacyIDEA server>
Accept: application/json

user=<username>
pass=<password>

Response:
HTTP/1.1 200 OK
Content-Type: application/json

{
"detail": {
"attributes": {
"hideResponseInput": true,
"img": "<image URL>",
"webAuthnSignRequest": {
"allowCredentials": [
{
"id": "<credential ID>",
"transports": [
"<allowed transports>"
],
"type": "<credential type>"
}
],
"challenge": "<nonce>",
"rpId": "<relying party ID>",
"timeout": 60000,
"userVerification": "<user verification requirement>"
}
},
"client_mode": "webauthn",
"message": "Please confirm with your WebAuthn token",
"serial": "<token serial>",
"transaction_id": "<transaction ID>",
"type": "webauthn"
},
"id": 1,
(continues on next page)

340 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

(continued from previous page)


"jsonrpc": "2.0",
"result": {
"authentication": "CHALLENGE",
"status": true,
"value": false
},
"version": "<privacyIDEA version>"
}

Get the challenge (using /validate/triggerchallenge)

The /validate/triggerchallenge endpoint can be used to trigger a challenge using a service account (without requiring
the PIN for the token).
Request

POST /validate/triggerchallenge HTTP/1.1


Host: <privacyIDEA server>
Accept: application/json
PI-Authorization: <authToken>

user=<username>
serial=<tokenSerial>

Providing the tokenSerial is optional. If just a user is provided, a challenge will be triggered for every challenge response
token the user has.
Response

HTTP/1.1 200 OK
Content-Type: application/json

{
"detail": {
"attributes": {
"hideResponseInput": true,
"img": "<image URL>",
"webAuthnSignRequest": {
"challenge": "<nonce>",
"allowCredentials": [{
"id": "<credential ID>",
"transports": [
"<allowed transports>"
],
"type": "<credential type>",
}],
"rpId": "<relying party ID>",
"userVerification": "<user verification requirement>",
"timeout": 60000
}
},
"message": "Please confirm with your WebAuthn token",
(continues on next page)

1.15. Code Documentation 341


privacyIDEA Authentication System, Release 3.8

(continued from previous page)


"messages": ["Please confirm with your WebAuthn token"],
"multi_challenge": [{
"attributes": {
"hideResponseInput": true,
"img": "<image URL>",
"webAuthnSignRequest": {
"challenge": "<nonce>",
"allowCredentials": [{
"id": "<credential ID>",
"transports": [
"<allowedTransports>"
],
"type": "<credential type>",
}],
"rpId": "<relying party ID>",
"userVerification": "<user verification requirement>",
"timeout": 60000
}
},
"message": "Please confirm with your WebAuthn token",
"serial": "<token serial>",
"transaction_id": "<transaction ID>",
"type": "webauthn"
}],
"serial": "<token serial>",
"transaction_id": "<transaction ID>",
"transaction_ids": ["<transaction IDs>"],
"type": "webauthn"
},
"id": 1,
"jsonrpc": "2.0",
"result": {
"status": true,
"value": 1
},
"version": "<privacyIDEA version>"
}

Send the Response

The application now needs to call the javascript function navigator.credentials.get with the publicKeyCredentialRe-
questOptions built using the nonce, credentialId, allowedTransports, userVerificationRequirement and timeout from
the server. The timeout is optional and may be omitted, if not provided, the client may also pick a sensible default.
Please note that the nonce will be a binary, encoded using the web-safe base64 algorithm specified by WebAuthn, and
needs to be decoded and passed as Uint8Array.
const publicKeyCredentialRequestOptions = {
challenge: <nonce>,
allowCredentials: [{
id: Uint8Array.from(<credentialId>, c=> c.charCodeAt(0)),
type: <credentialType>,
(continues on next page)

342 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

(continued from previous page)


transports: <allowedTransports>
}],
userVerification: <userVerificationRequirement>,
rpId: <relyingPartyId>,
timeout: <timeout>
}
navigator
.credentials
.get({publicKey: publicKeyCredentialRequestOptions})
.then(function(assertion) { <responseHandler> })
.catch(function(error) { <errorHandler> });

The responseHandler needs to call the /validate/check API providing the serial of the token the user is signing in with,
and the transaction_id, for the current challenge, along with the id, returned by the WebAuthn device in the assertion
and the authenticatorData, clientDataJSON and signature, userHandle, and assertionClientExtensions contained in
the response field of the assertion.
clientDataJSON, authenticatorData and signature should be encoded as web-safe base64 without padding. For more
detailed instructions, refer to “2. Step” under “Enrollment” above.
The userHandle and assertionClientExtensions are optional and should be omitted, if not provided by the authenticator.
The assertionClientExtensions – if available – must be encoded as a utf-8 JSON string, and transmitted to the server as
web-safe base64. The userHandle is simply passed as a string, note – however – that it may be necessary to re-encode
this to utf-16, since the authenticator will return utf-8, while the library making the http request will likely require all
parameters in the native encoding of the language (usually utf-16).

POST /validate/check HTTP/1.1


Host: example.com
Accept: application/json

user=<user>
pass=
transaction_id=<transaction_id>
credentialid=<id>
clientdata=<clientDataJSON>
signaturedata=<signature>
authenticatordata=<authenticatorData>
userhandle=<userHandle>
assertionclientextensions=<assertionClientExtensions>

Implementation

class privacyidea.lib.tokens.webauthntoken.WebAuthnTokenClass(db_token)
The WebAuthn Token implementation.
Create a new WebAuthn Token object from a database object
Parameters db_token (DB object) – instance of the orm db object
check_otp(otpval, counter=None, window=None, options=None)
This checks the response of a previous challenge.
Since this is not a traditional token, otpval and window are unused. The information from the client is
instead passed in the fields serial, id, assertion, authenticatorData, clientDataJSON, and signature of the

1.15. Code Documentation 343


privacyIDEA Authentication System, Release 3.8

options dictionary.
Parameters
• otpval (None) – Unused for this token type
• counter (int) – The authentication counter
• window (None) – Unused for this token type
• options (dict) – Contains the data from the client, along with policy configurations.
Returns A numerical value where values larger than zero indicate success.
Return type int
client_mode = 'webauthn'
create_challenge(transactionid=None, options=None)
Create a challenge for challenge-response authentication.
This method creates a challenge, which is submitted to the user. The submitted challenge will be preserved
in the challenge database.
If no transaction id is given, the system will create a transaction id and return it, so that the response can
refer to this transaction.
This method will return a tuple containing a bool value, indicating whether a challenge was successfully
created, along with a message to display to the user, the transaction id, and a dictionary containing all
parameters and data needed to respond to the challenge, as per the api.
Parameters
• transactionid (basestring) – The id of this challenge
• options (dict) – The request context parameters and data
Returns Success status, message, transaction id and reply_dict
Return type (bool, basestring, basestring, dict)
decrypt_otpkey()
This method fetches a decrypted version of the otp_key.
This method becomes necessary, since the way WebAuthn is implemented in PrivacyIdea, the otpkey of a
WebAuthn token is the credential_id, which may encode important information and needs to be sent to the
client to allow the client to create an assertion for the authentication process.
Returns The otpkey decrypted and encoded as WebAuthn base64.
Return type basestring
static get_class_info(key=None, ret='all')
returns a subtree of the token definition
Parameters
• key (string) – subsection identifier
• ret (user defined) – default return value, if nothing is found
Returns subsection if key exists or user defined
Return type dict or scalar
static get_class_prefix()
Return the prefix, that is used as a prefix for the serial numbers.

344 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Returns WAN
Return type basestring
static get_class_type()
Returns the internal token type identifier
Returns webauthn
Return type basestring
get_init_detail(params=None, user=None)
At the end of the initialization we ask the user to confirm the enrollment with his token.
This will prepare all the information the client needs to build the publicKeyCredentialCreationOptions to
call navigator.credentials.create() with. It will then be called again, once the token is created and provide
confirmation of the successful enrollment to the client.
Parameters
• params (dict) – A dictionary with parameters from the request.
• user (User) – The user enrolling the token.
Returns The response detail returned to the client.
Return type dict
static get_setting_type(key)
Fetch the type of a setting specific to WebAuthn tokens.
The WebAuthn token defines several public settings. When these are written to the database, the type of
the setting is automatically stored along with the setting by set_privacyidea_config().
The key name needs to be in WEBAUTHN_TOKEN_SPECIFIC_SETTINGS.keys() and match /^webau-
thn./. If the specified setting does not exist, a ValueError will be thrown.
Parameters key (basestring) – The token specific setting key
Returns The setting type
Return type “public”
is_challenge_request(passw, user=None, options=None)
Check if the request would start a challenge.
Every request that is not a response needs to spawn a challenge.
Note: This function does not need to be decorated with @challenge_response_allowed, as the WebAuthn
token is always a challenge response token!
Parameters
• passw (basestring) – The PIN of the token
• user (User) – The User making the request
• options (dict) – Dictionary of additional request parameters
Returns Whether to trigger a challenge
Return type bool
update(param, reset_failcount=True)
This method is called during the initialization process.
Parameters

1.15. Code Documentation 345


privacyIDEA Authentication System, Release 3.8

• param (dict) – Parameters from the token init.


• reset_failcount (bool) – Whether to reset the fail count.
Returns Nothing
Return type None

Yubico Token

class privacyidea.lib.tokens.yubicotoken.YubicoTokenClass(db_token)
Create a new token object.
Parameters db_token (Token) – A database token object
Returns A TokenClass object
check_otp(anOtpVal, counter=None, window=None, options=None)
Here we contact the Yubico Cloud server to validate the OtpVal.
static get_class_info(key=None, ret='all')

Parameters
• key (string) – subsection identifier
• ret (user defined) – default return value, if nothing is found
Returns subsection if key exists or user defined
Return type dict or string
static get_class_prefix()
static get_class_type()
update(param)
Update the token object
Parameters param – a dictionary with different params like keysize, description, genkey, otpkey,
pin
Type param: dict

Yubikey Token

class privacyidea.lib.tokens.yubikeytoken.YubikeyTokenClass(db_token)
The Yubikey Token in the Yubico AES mode
Create a new token object.
Parameters db_token (Token) – A database token object
Returns A TokenClass object
classmethod api_endpoint(request, g)
This provides a function to be plugged into the API endpoint /ttype/yubikey which is defined in api/ttype.py
The endpoint /ttype/yubikey is used for the Yubico validate request according to https://developers.yubico.
com/yubikey-val/Validation_Protocol_V2.0.html
Parameters

346 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

• request – The Flask request


• g – The Flask global object g
Returns Flask Response or text
Required query parameters
Query id The id of the client to identify the correct shared secret
Query otp The OTP from the yubikey in the yubikey mode
Query nonce 16-40 bytes of random data
Optional parameters h, timestamp, sl, timeout are not supported at the moment.
check_otp(anOtpVal, counter=None, window=None, options=None)
validate the token otp against a given otpvalue
Parameters
• anOtpVal (string) – the to be verified otpvalue
• counter (int) – the counter state. It is not used by the Yubikey because the current counter
value is sent encrypted inside the OTP value
• window (int) – the counter +window, which is not used in the Yubikey because the current
counter value is sent encrypted inside the OTP, allowing a simple comparison between the
encrypted counter value and the stored counter value
• options (dict) – the dict, which could contain token specific info
Returns the counter state or an error code (< 0):
-1 if the OTP is old (counter < stored counter) -2 if the private_uid sent in the OTP is wrong (different from
the one stored with the token) -3 if the CRC verification fails :rtype: int
check_otp_exist(otp, window=None)
checks if the given OTP value is/are values of this very token. This is used to autoassign and to determine
the serial number of a token.
static check_yubikey_pass(passw)
if the Token has set a PIN the user must also enter the PIN for authentication!
This checks the output of a yubikey in AES mode without providing the serial number. The first 12 (of
44) or 16 of 48) characters are the tokenid, which is stored in the tokeninfo yubikey.tokenid or the prefix
yubikey.prefix.
Parameters passw (string) – The password that consist of the static yubikey prefix and the otp
Returns True/False and the User-Object of the token owner
Return type dict
static get_class_info(key=None, ret='all')
returns a subtree of the token definition
Parameters
• key (string) – subsection identifier
• ret (user defined) – default return value, if nothing is found
Returns subsection if key exists or user defined
Return type s.o.
static get_class_prefix()

1.15. Code Documentation 347


privacyIDEA Authentication System, Release 3.8

static get_class_type()
is_challenge_request(passw, user=None, options=None)
This method checks, if this is a request, that triggers a challenge.
Parameters
• passw (string) – password, which might be pin or pin+otp
• user (User object) – The user from the authentication request
• options (dict) – dictionary of additional request parameters
Returns true or false
update(param, reset_failcount=True)
Update the token object
Parameters param – a dictionary with different params like keysize, description, genkey, otpkey,
pin
Type param: dict
class privacyidea.lib.tokenclass.TokenClass(db_token)
Create a new token object.
Parameters db_token (Token) – A database token object
Returns A TokenClass object
add_init_details(key, value)
(was addInfo) Adds information to a volatile internal dict
add_tokengroup(tokengroup=None, tokengroup_id=None)
Adds a new tokengroup to this token.
Parameters
• tokengroup (basestring) – The name of the token group to add
• tokengroup_id (int) – The id of the tokengroup to add
Returns True
add_tokeninfo(key, value, value_type=None)
Add a key and a value to the DB tokeninfo
Parameters
• key –
• value –
Returns
add_user(user, report=None)
Set the user attributes (uid, resolvername, resolvertype) of a token.
Parameters
• user – a User() object, consisting of loginname and realm
• report – tbdf.
Returns None

348 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

classmethod api_endpoint(request, g)
This provides a function to be plugged into the API endpoint /ttype/<tokentype> which is defined in
api/ttype.py
The method should return return “json”, {}
or return “text”, “OK”

Parameters
• request – The Flask request
• g – The Flask global object g
Returns Flask Response or text

authenticate(passw, user=None, options=None)


High level interface which covers the check_pin and check_otp This is the method that verifies single shot
authentication like they are done with push button tokens.
It is a high level interface to support other tokens as well, which do not have a pin and otp separation - they
could overwrite this method
If the authentication succeeds an OTP counter needs to be increased, i.e. the OTP value that was used for
this authentication is invalidated!
Parameters
• passw (string) – the password which could be pin+otp value
• user (User object) – The authenticating user
• options (dict) – dictionary of additional request parameters
Returns
returns tuple of
1. true or false for the pin match,
2. the otpcounter (int) and the
3. reply (dict) that will be added as additional information in the JSON response of /
validate/check.
Return type tuple(bool, int, dict)
can_verify_enrollment = False
static challenge_janitor()
Just clean up all challenges, for which the expiration has expired.
Returns None
check_all(message_list)
Perform all checks on the token. Returns False if the token is either: * auth counter exceeded * not active
* fail counter exceeded * validity period exceeded
This is used in the function token.check_token_list
Parameters message_list – A list of messages
Returns False, if any of the checks fail

1.15. Code Documentation 349


privacyIDEA Authentication System, Release 3.8

check_auth_counter()
This function checks the count_auth and the count_auth_success. If the counters are less or equal than the
maximum allowed counters it returns True. Otherwise False.
Returns success if the counter is less than max
Return type bool
check_challenge_response(user=None, passw=None, options=None)
This method verifies if there is a matching challenge for the given passw and also verifies if the response is
correct.
It then returns the new otp_counter of the token.
In case of success the otp_counter will be >= 0.
Parameters
• user (User object) – the requesting user
• passw (string) – the password (pin+otp)
• options (dict) – additional arguments from the request, which could be token specific.
Usually “transactionid”
Returns return otp_counter. If -1, challenge does not match
Return type int
check_failcount()
Checks if the failcounter is exceeded. It returns True, if the failcounter is less than maxfail
Returns True or False
Return type bool
check_if_disabled = True
check_last_auth_newer(last_auth)
Check if the last successful authentication with the token is newer than the specified time delta which is
passed as 10h, 7d or 1y.
It returns True, if the last authentication with this token is newer than the specified delta or by any chance
exactly the same.
It returns False, if the last authentication is older or if the data in the token can not be parsed.
Parameters last_auth (basestring) – 10h, 7d or 1y
Returns bool
check_otp(otpval, counter=None, window=None, options=None)
This checks the OTP value, AFTER the upper level did the checkPIN
In the base class we do not know, how to calculate the OTP value. So we return -1. In case of success, we
should return >=0, the counter
Parameters
• otpval – the OTP value
• counter (int) – The counter for counter based otp values
• window – a counter window
• options (dict) – additional token specific options
Returns counter of the matching OTP value.

350 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Return type int


check_otp_exist(otp, window=None)
checks if the given OTP value is/are values of this very token. This is used to autoassign and to determine
the serial number of a token.
Parameters
• otp – the OTP value
• window (int) – The look ahead window
Returns True or a value > 0 in case of success
check_pin(pin, user=None, options=None)
Check the PIN of the given Password. Usually this is only dependent on the token itself, but the user object
can cause certain policies.
Each token could implement its own PIN checking behaviour.
Parameters
• pin (string) – the PIN (static password component), that is to be checked.
• user (User object) – for certain PIN policies (e.g. checking against the user store) this
is the user, whose password would be checked. But at the moment we are checking against
the userstore in the decorator “auth_otppin”.
• options – the optional request parameters
Returns If the PIN is correct, return True
Return type bool
check_reset_failcount()
Checks if we should reset the failcounter due to the FAILCOUNTER_CLEAR_TIMEOUT
Returns True, if the failcounter was reset
check_validity_period()
This checks if the datetime.now() is within the validity period of the token.
Returns success
Return type bool
client_mode = 'interactive'
create_challenge(transactionid=None, options=None)
This method creates a challenge, which is submitted to the user. The submitted challenge will be preserved
in the challenge database.
If no transaction id is given, the system will create a transaction id and return it, so that the response can
refer to this transaction.
Parameters
• transactionid – the id of this challenge
• options (dict) – the request context parameters / data
Returns tuple of (bool, message, transactionid, reply_dict)
Return type tuple
The return tuple builds up like this: bool if submit was successful; message which is displayed in the
JSON response; additional challenge reply_dict, which are displayed in the JSON challenges response.

1.15. Code Documentation 351


privacyIDEA Authentication System, Release 3.8

static decode_otpkey(otpkey, otpkeyformat)


Decode the otp key which is given in a specific format.
Supported formats:
• hex, in which the otpkey is returned verbatim
• base32check, which is specified in decode_base32check
In case the OTP key is malformed or if the format is unknown, a ParameterError is raised.
Parameters
• otpkey – OTP key passed by the user
• otpkeyformat – “hex” or “base32check”
Returns hex-encoded otpkey
del_tokengroup(tokengroup=None, tokengroup_id=None)
Removes a token group from a token. You either need to specify the name or the ID of the tokengroup.
Parameters
• tokengroup (basestring) – The name of the tokengroup
• tokengroup_id (int) – The ID of the tokengroup
Returns True in case of success
del_tokeninfo(key=None)
delete_token()
delete the database token
enable(enable=True)
classmethod enroll_via_validate(g, content, user_obj)
This class method is used in the policy ENROLL_VIA_MULTICHALLENGE. It enrolls a new token of
this type and returns the necessary information to the client by modifying the content.
Parameters
• g – context object
• content – The content of a response
• user_obj – A user object
Returns None, the content is modified
enroll_via_validate_2nd_step(passw, options=None)
This method is the optional second step of ENROLL_VIA_MULTICHALLENGE. It is used in situations
like the email token, sms token or push, when enrollment via challenge response needs two steps.
Parameters options –
Returns
generate_symmetric_key(server_component, client_component, options=None)
This method generates a symmetric key, from a server component and a client component. This key gen-
eration could be based on HMAC, KDF or even Diffie-Hellman.
The basic key-generation is simply replacing the last n byte of the server component with bytes of the client
component.
Parameters

352 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

• server_component (str) – The component usually generated by privacyIDEA. This is


a hex string
• client_component (str) – The component usually generated by the client (e.g. smart-
phone). This is a hex string.
• options –
Returns the new generated key as hex string
Return type str
get_as_dict()
This returns the token data as a dictionary. It is used to display the token list at /token/list.
Returns The token data as dict
Return type dict
static get_class_info(key=None, ret='all')
static get_class_prefix()
static get_class_type()
get_count_auth()
Return the number of all authentication tries
get_count_auth_max()
Return the number of maximum allowed authentications
get_count_auth_success()
Return the number of successful authentications
get_count_auth_success_max()
Return the maximum allowed successful authentications
get_count_window()
classmethod get_default_settings(g, params)
This method returns a dictionary with default settings for token enrollment. These default settings depend
on the token type and the defined policies.
The returned dictionary is added to the parameters of the API call.
Parameters
• g – context object, see documentation of Match
• params (dict) – The call parameters
Returns default parameters
get_failcount()
static get_hashlib(hLibStr)
Returns a hashlib function for a given string
Parameters hLibStr (string) – the hashlib
Returns the hashlib
Return type function
static get_import_csv(l)
Read the list from a csv file and return a dictionary, that can be used to do a token_init.
Parameters l (list) – The list of the line of a csv file

1.15. Code Documentation 353


privacyIDEA Authentication System, Release 3.8

Returns A dictionary of init params


get_init_detail(params=None, user=None)
to complete the token initialization, the response of the initialization should be build by this token specific
method. This method is called from api/token after the token is enrolled
get_init_detail returns additional information after an admin/init like the QR code of an HOTP/TOTP token.
Can be anything else.
Parameters
• params (dict) – The request params during token creation token/init
• user (User object) – the user, token owner
Returns additional descriptions
Return type dict
get_init_details()
return the status of the token rollout
Returns return the status dict.
Return type dict
get_max_failcount()
get_multi_otp(count=0, epoch_start=0, epoch_end=0, curTime=None, timestamp=None)
This returns a dictionary of multiple future OTP values of a token.
Parameters
• count – how many otp values should be returned
• epoch_start – time based tokens: start when
• epoch_end – time based tokens: stop when
• curTime (datetime object) – current time for TOTP token (for selftest)
• timestamp (int) – unix time, current time for TOTP token (for selftest)
Returns True/False, error text, OTP dictionary
Return type Tuple
get_otp(current_time='')
The default token does not support getting the otp value will return a tuple of four values a negative value
is a failure.
Returns something like: (1, pin, otpval, combined)
get_otp_count()
get_otp_count_window()
get_otplen()
get_pin_hash_seed()
get_realms()
Return a list of realms the token is assigned to
Returns realms
Return type list
get_serial()

354 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

static get_setting_type(key)
This function returns the type of the token specific config/setting. This way a tokenclass can define settings,
that can be “public” or a “password”. If this setting is written to the database, the type of the setting is set
automatically in set_privacyidea_config
The key name needs to start with the token type.
Parameters key – The token specific setting key
Returns A string like “public”
get_sync_window()
get_tokeninfo(key=None, default=None)
return the complete token info or a single key of the tokeninfo. When returning the complete token info
dictionary encrypted entries are not decrypted. If you want to receive a decrypted value, you need to call it
directly with the key.
Parameters
• key (string) – the key to return
• default (string) – the default value, if the key does not exist
Returns the value for the key
Return type int or str or dict
get_tokentype()
get_type()
get_user_displayname()
Returns a tuple of a user identifier like user@realm and the displayname of “givenname surname”.
Returns tuple
get_user_id()
get_validity_period_end()
returns the end of validity period (if set) if not set, “” is returned.
Returns the end of the validity period
Return type str
get_validity_period_start()
returns the start of validity period (if set) if not set, “” is returned.
Returns the start of the validity period
Return type str
hKeyRequired = False
has_db_challenge_response(passw, user=None, options=None)
This method checks, if the given transaction_id is actually the response to a real challenge. To do so, it
verifies, if there is a DB entry for the given serial number and transaction_id. This is to avoid side effects
by passing non-existent transaction_ids.
This method checks, if the token still has a challenge
Parameters
• passw –
• user –

1.15. Code Documentation 355


privacyIDEA Authentication System, Release 3.8

• options –
Returns
has_further_challenge(options=None)
Returns true, if a token requires more than one challenge during challenge response authentication. This
could be a 4eyes token or indexed secret token, that queries more than on input.
Parameters options – Additional options from the request
Returns True, if this very token requires further challenges
inc_count_auth()
Increase the counter, that counts authentications - successful and unsuccessful
inc_count_auth_success()
Increase the counter, that counts successful authentications Also increase the auth counter
inc_failcount()
inc_otp_counter(counter=None, increment=1, reset=True)
Increase the otp counter and store the token in the database
Before increasing the token.count the token.count can be set using the parameter counter.
Parameters
• counter (int) – if given, the token counter is first set to counter and then increased by
increment
• increment (int) – increase the counter by this amount
• reset (bool) – reset the failcounter if set to True
Returns the new counter value
is_active()
is_challenge_request(passw, user=None, options=None)
This method checks, if this is a request, that triggers a challenge.
The default behaviour to trigger a challenge is, if the passw parameter only contains the correct token pin
and the request contains a data or a challenge key i.e. if the options parameter contains a key data or
challenge.
Each token type can decide on its own under which condition a challenge is triggered by overwriting this
method.

Note: in case of pin policy == 2 (no pin is required) the check_pin would always return true! Thus
each request containing a data or challenge would trigger a challenge!

The Challenge workflow is like this.


When an authentication request is issued, first it is checked if this is a request which will create a new
challenge (is_challenge_request) or if this is a response to an existing challenge (is_challenge_response).
In these two cases during request processing the following functions are called:

is_challenge_request or is_challenge_response <-------+


| | |
V V |
create_challenge check_challenge_response create_challenge
| | ^
(continues on next page)

356 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

(continued from previous page)


| | |
| has_further_challenge [yes] ---+
| [no]
| |
V V
challenge_janitor challenge_janitor

Parameters
• passw (string) – password, which might be pin or pin+otp
• user (User object) – The user from the authentication request
• options (dict) – dictionary of additional request parameters
Returns true or false
Return type bool

is_challenge_response(passw, user=None, options=None)


This method checks, if this is a request that is supposed to be the answer to a previous challenge.
The default behaviour to check if this is the response to a previous challenge is simply by checking if the
request contains a parameter state or transactionid i.e. checking if the options parameter contains
a key state or transactionid.
This method does not try to verify the response itself! It only determines, if this is a response for a challenge
or not. If the challenge still exists, is checked in has_db_challenge_response. The response is verified in
check_challenge_response.
Parameters
• passw (string) – password, which might be pin or pin+otp
• user (User object) – the requesting user
• options (dict) – dictionary of additional request parameters
Returns true or false
Return type bool
is_fit_for_challenge(messages, options=None)
This method is called if a cryptographically matching response to a challenge was found. This method
may implement final checks, if there is anything that should deny the success of the authentication with the
response to the challenge.
The options dictionary can also contain the transaction_id, so even the challenge table for this token can be
used for checking.
Parameters
• options (dict) –
• messages (list) – This is a list of messages. This method can append new information
to this message list.
Returns True or False
is_locked()
Check if the token is in a locked state A locked token can not be modified
Returns True, if the token is locked.

1.15. Code Documentation 357


privacyIDEA Authentication System, Release 3.8

is_multichallenge_enrollable = False
is_orphaned()
Return True if the token is orphaned.
An orphaned token means, that it has a user assigned, but the user does not exist in the user store (anymore)
Returns True / False
Return type bool
classmethod is_outofband()
is_pin_change(password=False)
Returns true if the pin of the token needs to be changed.
Parameters password (bool) – Whether the password needs to be changed.
Returns True or False
is_previous_otp(otp, window=10)
checks if a given OTP value is a previous OTP value, that lies in the past or has a lower counter.
This is used in case of a failed authentication to return the information, that this OTP values was used
previously and is invalid.
Parameters
• otp (basestring) – The OTP value.
• window (int) – A counter window, how far we should look into the past.
Returns bool
is_revoked()
Check if the token is in the revoked state
Returns True, if the token is revoked
mode = ['authenticate', 'challenge']
post_success()
Run anything after a token was used for successful authentication
prepare_verify_enrollment()
This is called, if the token should be enrolled in a way, that the user needs to provide a proof, that the server
can verify, that the token was successfully enrolled. E.g. with HOTP tokens the user might need to provide
a correct OTP value.
The returned dictionary is added to the response in “detail” -> “verify”.
Returns A dictionary with information that is needed to trigger the verification.
reset()
Reset the failcounter
resync(otp1, otp2, options=None)
revoke()
This revokes the token. By default it 1. sets the revoked-field 2. set the locked field 3. disables the token.
Some token types may revoke a token without locking it.
property rollout_state
save()
Save the database token

358 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

set_count_auth(count)
Sets the counter for the occurred login attepms as key “count_auth” in token info
Parameters count (int) – a number
set_count_auth_max(count)
Sets the counter for the maximum allowed login attempts as key “count_auth_max” in token info
Parameters count (int) – a number
set_count_auth_success(count)
Sets the counter for the occurred successful logins as key “count_auth_success” in token info
Parameters count (int) – a number
set_count_auth_success_max(count)
Sets the counter for the maximum allowed successful logins as key “count_auth_success_max” in token
info
Parameters count (int) – a number
set_count_window(countWindow)
set_defaults()
Set the default values on the database level
set_description(description)
Set the description on the database level
Parameters description (string) – description of the token
set_failcount(failcount)
Set the failcounter in the database
set_hashlib(hashlib)
set_init_details(details)
set_maxfail(maxFail)
set_next_pin_change(diff=None, password=False)
Sets the timestamp for the next_pin_change. Provide a difference like 90d (90 days).
Parameters
• diff (basestring) – The time delta.
• password – Do no set next_pin_change but next_password_change
Returns None
set_otp_count(otpCount)
set_otpkey(otpKey)
set_otplen(otplen)
set_pin(pin, encrypt=False)
set the PIN of a token. Usually the pin is stored in a hashed way.
Parameters
• pin (basestring) – the pin to be set for the token
• encrypt (bool) – If set to True, the pin is stored encrypted and can be retrieved from the
database again
set_pin_hash_seed(pinhash, seed)

1.15. Code Documentation 359


privacyIDEA Authentication System, Release 3.8

set_realms(realms, add=False)
Set the list of the realms of a token.
Parameters
• realms (list) – realms the token should be assigned to
• add (boolean) – if the realms should be added and not replaced
set_so_pin(soPin)
set_sync_window(syncWindow)
set_tokengroups(tokengroups, add=False)
Set the list of the tokengroups of a token.
Parameters
• tokengroups (list) – realms the token should be assigned to
• add (boolean) – if the tokengroups should be added and not replaced
set_tokeninfo(info)
Set the tokeninfo field in the DB. Old values will be deleted.
Parameters info (dict) – dictionary with key and value
Returns
set_type(tokentype)
Set the tokentype in this object and also in the underlying database-Token-object.
Parameters tokentype (string) – The type of the token like HOTP or TOTP
set_user_pin(userPin)
set_validity_period_end(end_date)
sets the end date of the validity period for a token
Parameters end_date (str) – the end date in the format YYYY-MM-DDTHH:MM+OOOO if
the format is wrong, the method will throw an exception
set_validity_period_start(start_date)
sets the start date of the validity period for a token
Parameters start_date (str) – the start date in the format YYYY-MM-DDTHH:MM+OOOO
if the format is wrong, the method will throw an exception
split_pin_pass(passw, user=None, options=None)
Split the password into the token PIN and the OTP value
take the given password and split it into the PIN and the OTP value. The splitting can be dependent of
certain policies. The policies may depend on the user.
Each token type may define its own way to slit the PIN and the OTP value.
Parameters
• passw – the password to split
• user (User object) – The user/owner of the token
• options (dict) – can be used be the token types.
Returns tuple of pin and otp value
Returns tuple of (split status, pin, otp value)

360 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Return type tuple


status_validation_fail()
callback to enable a status change, if auth failed
status_validation_success()
callback to enable a status change, if auth succeeds
static test_config(params=None)
This method is used to test the token config. Some tokens require some special token configuration like the
SMS-Token or the Email-Token. To test this configuration, this classmethod is used.
It takes token specific parameters and returns a tuple of a boolean and a result description.
Parameters params (dict) – token specific parameters
Returns success, description
Return type tuple
update(param, reset_failcount=True)
Update the token object
Parameters param – a dictionary with different params like keysize, description, genkey, otpkey,
pin
Type param: dict
property user
return the user (owner) of a token If the token has no owner assigned, we return None
Returns The owner of the token
Return type User object or None
using_pin = True
verify_enrollment(response)
This is called during the 2nd step of the verified enrollment. This method verifies the actual response from
the user. Returns true, if the verification was successful.
Parameters response – The response given by the user
Returns True

Token Functions

This module contains all top level token functions. It depends on the models, lib.user and lib.tokenclass (which depends
on the tokenclass implementations like lib.tokens.hotptoken)
This is the middleware/glue between the HTTP API and the database
privacyidea.lib.token.add_tokeninfo(serial, info, value=None, value_type=None, user=None)
Sets a token info field in the database. The info is a dict for each token of key/value pairs.
Parameters
• serial (basestring) – The serial number of the token
• info – The key of the info in the dict
• value – The value of the info
• value_type (basestring) – The type of the value. If set to “password” the value is stored
encrypted

1.15. Code Documentation 361


privacyIDEA Authentication System, Release 3.8

• user (User object) – The owner of the tokens, that should be modified
Returns the number of modified tokens
Return type int
privacyidea.lib.token.assign_token(serial, user, pin=None, encrypt_pin=False, err_message=None)
Assign token to a user. If the PIN is given, the PIN is reset.
Parameters
• serial (basestring) – The serial number of the token
• user (User object) – The user, to whom the token should be assigned.
• pin (basestring) – The PIN for the newly assigned token.
• encrypt_pin (bool) – Whether the PIN should be stored in an encrypted way
• err_message (basestring) – The error message, that is displayed in case the token is
already assigned
privacyidea.lib.token.assign_tokengroup(serial, tokengroup=None, tokengroup_id=None)
Assign a new tokengroup to a token
Parameters
• serial – The serial number of the token
• tokengroup – The name of the tokengroup
• tokengroup_id – alternatively the id of the tokengroup
Returns True
privacyidea.lib.token.check_otp(serial, otpval)
This function checks the OTP for a given serial number
Parameters
• serial –
• otpval –
Returns tuple of result and dictionary containing a message if the verification failed
Return type tuple(bool, dict)
privacyidea.lib.token.check_realm_pass(realm, passw, options=None, include_types=None,
exclude_types=None)
This function checks, if the given passw matches any token in the given realm. This can be used for the 4-eyes
token. Only tokens that are assigned are tested.
The options dictionary may contain a key/value pair ‘exclude_types’ or ‘include_types’ with the value containing
a list of token types to exclude/include from/in the search.
It returns the res True/False and a reply_dict, which contains the serial number of the matching token.
Parameters
• realm – The realm of the user
• passw – The password containing PIN+OTP
• options (dict) – Additional options that are passed to the tokens
• include_types (list or str) – List of token types to use for the check
• exclude_types (list or str) – List to token types not to use for the check

362 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Returns tuple of bool and dict


privacyidea.lib.token.check_serial(serial)
This checks, if the given serial number can be used for a new token. it returns a tuple (result, new_serial) result
being True if the serial does not exist, yet. new_serial is a suggestion for a new serial number, that does not exist,
yet.
Parameters serial (str) – Serial number to check if it can be used for a new token.
Result result of check and (new) serial number
Return type tuple(bool, str)
privacyidea.lib.token.check_serial_pass(serial, passw, options=None)
This function checks the otp for a given serial
If the OTP matches, True is returned and the otp counter is increased.
The function tries to determine the user (token owner), to derive possible additional policies from the user.
Parameters
• serial (basestring) – The serial number of the token
• passw (basestring) – The password usually consisting of pin + otp
• options (dict) – Additional options. Token specific.
Returns tuple of result (True, False) and additional dict
Return type tuple
privacyidea.lib.token.check_token_list(tokenobject_list, passw, user=None, options=None,
allow_reset_all_tokens=False)
this takes a list of token objects and tries to find the matching token for the given passw. It also tests, * if the
token is active or * the max fail count is reached, * if the validity period is ok. . .
This function is called by check_serial_pass, check_user_pass and check_yubikey_pass.
Parameters
• tokenobject_list – list of identified tokens
• passw – the provided passw (mostly pin+otp)
• user – the identified use - as class object
• options – additional parameters, which are passed to the token
• allow_reset_all_tokens – If set to True, the policy reset_all_user_tokens is evaluated
to reset all user tokens accordingly. Note: This parameter is used in the decorator.
Returns tuple of success and optional response
Return type (bool, dict)
privacyidea.lib.token.check_user_pass(user, passw, options=None)
This function checks the otp for a given user. It is called by the API /validate/check
If the OTP matches, True is returned and the otp counter is increased.
Parameters
• user (User object) – The user who is trying to authenticate
• passw (basestring) – The password usually consisting of pin + otp
• options (dict) – Additional options. Token specific.

1.15. Code Documentation 363


privacyIDEA Authentication System, Release 3.8

Returns tuple of result (True, False) and additional dict


Return type tuple
class privacyidea.lib.token.clob_to_varchar(*clauses, **kwargs)
Construct a FunctionElement.
Parameters
• *clauses – list of column expressions that form the arguments of the SQL function call.
• **kwargs – additional kwargs are typically consumed by subclasses.
See also:
func
Function
name = 'clob_to_varchar'
privacyidea.lib.token.copy_token_pin(serial_from, serial_to)
This function copies the token PIN from one token to the other token. This can be used for workflows like lost
token.
In fact the PinHash and the PinSeed are transferred
Parameters
• serial_from (basestring) – The token to copy from
• serial_to (basestring) – The token to copy to
Returns True. In case of an error raise an exception
Return type bool
privacyidea.lib.token.copy_token_realms(serial_from, serial_to)
Copy the realms of one token to the other token
Parameters
• serial_from – The token to copy from
• serial_to – The token to copy to
Returns None
privacyidea.lib.token.copy_token_user(serial_from, serial_to)
This function copies the user from one token to the other token. In fact the user_id, resolver and resolver type
are transferred.
Parameters
• serial_from (basestring) – The token to copy from
• serial_to (basestring) – The token to copy to
Returns True. In case of an error raise an exception
Return type bool
privacyidea.lib.token.create_challenges_from_tokens(token_list, reply_dict, options=None)
Get a list of active tokens and create challenges for these tokens. The reply_dict is modified accordingly. The
transaction_id and the messages are added to the reply_dict.
Parameters
• token_list – The list of the token objects, that can do challenge response

364 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

• reply_dict – The dictionary that is passed to the API response


• options – Additional options. Passed from the upper layer
Returns None
privacyidea.lib.token.create_tokenclass_object(db_token)
(was createTokenClassObject) create a token class object from a given type If a tokenclass for this type does not
exist, the function returns None.
Parameters db_token (database token object) – the database referenced token
Returns instance of the token class object
Return type tokenclass object
privacyidea.lib.token.delete_tokeninfo(serial, key, user=None)
Delete a specific token info field in the database.
Parameters
• serial (basestring) – The serial number of the token
• key – The key of the info in the dict
• user (User object) – The owner of the tokens, that should be modified
Returns the number of tokens matching the serial and user. This number also includes tokens that
did not have the token info key set in the first place!
Return type int
privacyidea.lib.token.enable_token(serial, enable=True, user=None)
Enable or disable a token, or all tokens of a single user. This can be checked with is_token_active.
Enabling an already active token will return 0.
Parameters
• serial (basestring) – The serial number of the token
• enable (bool) – False is the token should be disabled
• user (User object) – all tokens of the user will be enabled or disabled
Returns Number of tokens that were enabled/disabled
Return type
privacyidea.lib.token.fn_clob_to_varchar_default(element, compiler, **kw)
privacyidea.lib.token.fn_clob_to_varchar_oracle(element, compiler, **kw)
privacyidea.lib.token.gen_serial(tokentype=None, prefix=None)
generate a serial for a given tokentype
Parameters
• tokentype (str) – the token type prefix is done by a lookup on the tokens
• prefix (str) – A prefix to the serial number
Returns serial number
Return type str
privacyidea.lib.token.get_dynamic_policy_definitions(scope=None)
This returns the dynamic policy definitions that come with the new loaded token classes.

1.15. Code Documentation 365


privacyIDEA Authentication System, Release 3.8

Parameters scope – an optional scope parameter. Only return the policies of this scope.
Returns The policy definition for the token or only for the scope.
privacyidea.lib.token.get_multi_otp(serial, count=0, epoch_start=0, epoch_end=0, curTime=None,
timestamp=None)
This function returns a list of OTP values for the given Token. Please note, that the tokentype needs to support
this function.
Parameters
• serial (basestring) – the serial number of the token
• count – number of the next otp values (to be used with event or time based tokens)
• epoch_start – unix time start date (used with time based tokens)
• epoch_end – unix time end date (used with time based tokens)
• curTime (datetime) – Simulate the servertime
• timestamp (int) – Simulate the servertime (unix time in seconds)
Returns dictionary of otp values
Return type dictionary
privacyidea.lib.token.get_num_tokens_in_realm(realm, active=True)
This returns the number of tokens in one realm.
Parameters
• realm (basestring) – The name of the realm
• active (bool) – If only active tokens should be taken into account
Returns The number of tokens in the realm
Return type int
privacyidea.lib.token.get_one_token(*args, **kwargs)
Fetch exactly one token according to the given filter arguments, which are passed to get_tokens. Raise
ResourceNotFoundError if no token was found. Raise ParameterError if more than one token was found.
privacyidea.lib.token.get_otp(serial, current_time=None)
This function returns the current OTP value for a given Token. The tokentype needs to support this function. if
the token does not support getting the OTP value, a -2 is returned. If the token could not be found, ResourceNot-
FoundError is raised.
Parameters
• serial – serial number of the token
• current_time (datetime) – a fake servertime for testing of TOTP token
Returns tuple with (result, pin, otpval, passw)
Return type tuple
privacyidea.lib.token.get_realms_of_token(serial, only_first_realm=False)
This function returns a list of the realms of a token
Parameters
• serial (basestring) – the exact serial number of the token
• only_first_realm (bool) – Wheather we should only return the first realm

366 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Returns list of the realm names


Return type list
privacyidea.lib.token.get_serial_by_otp(token_list, otp='', window=10)
Returns the serial for a given OTP value The tokenobject_list would be created by get_tokens()
Parameters
• token_list (list of token objects) – the list of token objects to be investigated
• otp – the otp value, that needs to be found
• window (int) – the window of search
Returns the serial for a given OTP value and the user
Return type basestring
privacyidea.lib.token.get_token_by_otp(token_list, otp='', window=10)
search the token in the token_list, that creates the given OTP value. The tokenobject_list would be created by
get_tokens()
Parameters
• token_list (list of token objects) – the list of token objects to be investigated
• otp (basestring) – the otp value, that needs to be found
• window (int) – the window of search
Returns The token, that creates this OTP value
Return type Tokenobject
privacyidea.lib.token.get_token_owner(serial)
returns the user object, to which the token is assigned. the token is identified and retrieved by it’s serial number
If the token has no owner, None is returned
Wildcards in the serial number are ignored. This raises ResourceNotFoundError if the token could not be
found.
Parameters serial (basestring) – serial number of the token
Returns The owner of the token
Return type User object or None
privacyidea.lib.token.get_token_type(serial)
Returns the tokentype of a given serial number. If the token does not exist or can not be determined, an empty
string is returned.
Parameters serial (string) – the serial number of the to be searched token
Returns tokentype
Return type string
privacyidea.lib.token.get_tokenclass_info(tokentype, section=None)
return the config definition of a dynamic token
Parameters
• tokentype (basestring) – the tokentype of the token like “totp” or “hotp”
• section (basestring) – subsection of the token definition - optional
Returns dict - if nothing found an empty dict

1.15. Code Documentation 367


privacyIDEA Authentication System, Release 3.8

Return type dict


privacyidea.lib.token.get_tokens(tokentype=None, realm=None, assigned=None, user=None, serial=None,
serial_wildcard=None, active=None, resolver=None,
rollout_state=None, count=False, revoked=None, locked=None,
tokeninfo=None, maxfail=None)
(was getTokensOfType) This function returns a list of token objects of a * given type, * of a realm * or tokens
with assignment or not * for a certain serial number or * for a User
E.g. thus you can get all assigned tokens of type totp.
Parameters
• tokentype (basestring) – The type of the token. If None, all tokens are returned.
• realm (basestring) – get tokens of a realm. If None, all tokens are returned.
• assigned (bool) – Get either assigned (True) or unassigned (False) tokens. If None get all
tokens.
• user (User Object) – Filter for the Owner of the token
• serial (basestring) – The exact serial number of a token
• serial_wildcard (basestring) – A wildcard to match token serials
• active (bool) – Whether only active (True) or inactive (False) tokens should be returned
• resolver (basestring) – filter for the given resolver name
• rollout_state – returns a list of the tokens in the certain rollout state. Some tokens are
not enrolled in a single step but in multiple steps. These tokens are then identified by the
DB-column rollout_state.
• count (bool) – If set to True, only the number of the result and not the list is returned.
• revoked (bool) – Only search for revoked tokens or only for not revoked tokens
• locked (bool) – Only search for locked tokens or only for not locked tokens
• tokeninfo (dict) – Return tokens with the given tokeninfo. The tokeninfo is a key/value
dictionary
• maxfail – If only tokens should be returned, which failcounter reached maxfail
Returns A list of tokenclasses (lib.tokenclass).
Return type list
privacyidea.lib.token.get_tokens_from_serial_or_user(serial, user, **kwargs)
Fetch tokens, either by (exact) serial, or all tokens of a single user. In case a serial number is given, check that
exactly one token is returned and raise a ResourceNotFoundError if that is not the case. In case a user is given,
the result can also be empty.
Parameters
• serial – exact serial number or None
• user – a user object or None
• kwargs – additional argumens to get_tokens
Returns a (possibly empty) list of tokens
Return type list

368 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

privacyidea.lib.token.get_tokens_in_resolver(resolver)
Return a list of the token ojects, that contain this very resolver
Parameters resolver (basestring) – The resolver, the tokens should be in
Returns list of tokens with this resolver
Return type list of token objects
privacyidea.lib.token.get_tokens_paginate(tokentype=None, realm=None, assigned=None, user=None,
serial=None, active=None, resolver=None,
rollout_state=None,
sortby=<sqlalchemy.orm.attributes.InstrumentedAttribute
object>, sortdir='asc', psize=15, page=1, description=None,
userid=None, allowed_realms=None, tokeninfo=None,
hidden_tokeninfo=None)
This function is used to retrieve a token list, that can be displayed in the Web UI. It supports pagination. Each
retrieved page will also contain a “next” and a “prev”, indicating the next or previous page. If either does not
exist, it is None.
Parameters
• tokentype –
• realm –
• assigned (bool) – Returns assigned (True) or not assigned (False) tokens
• user (User object) – The user, whose token should be displayed
• serial – a pattern for matching the serial
• active – Returns active (True) or inactive (False) tokens
• resolver (basestring) – A resolver name, which may contain “*” for filtering.
• userid (basestring) – A userid, which may contain “*” for filtering.
• rollout_state –
• sortby (A Token column or a string.) – Sort by a certain Token DB field. The de-
fault is Token.serial. If a string like “serial” is provided, we try to convert it to the DB
column.
• sortdir (basestring) – Can be “asc” (default) or “desc”
• psize (int) – The size of the page
• page (int) – The number of the page to view. Starts with 1 ;-)
• allowed_realms (list) – A list of realms, that the admin is allowed to see
• tokeninfo – Return tokens with the given tokeninfo. The tokeninfo is a key/value dictionary
Returns dict with tokens, prev, next and count
Return type dict
privacyidea.lib.token.get_tokens_paginated_generator(tokentype=None, realm=None, assigned=None,
user=None, serial_wildcard=None,
active=None, resolver=None,
rollout_state=None, revoked=None,
locked=None, tokeninfo=None, maxfail=None,
psize=1000)
Fetch chunks of psize tokens that match the filter criteria from the database and generate lists of token objects.

1.15. Code Documentation 369


privacyIDEA Authentication System, Release 3.8

See get_tokens for information on the arguments.


Note that individual lists may contain less than psize elements if a token entry has an invalid type.
Parameters psize – Maximum size of chunks that are fetched from the database
Returns This is a generator that generates non-empty lists of token objects.
privacyidea.lib.token.import_token(serial, token_dict, tokenrealms=None)
This function is used during the import of a PSKC file.
Parameters
• serial (str) – The serial number of the token
• token_dict (dict) – A dictionary describing the token like

{
"type": ...,
"description": ...,
"otpkey": ...,
"counter: ...,
"timeShift": ...
}

• tokenrealms (list) – List of realms to set as realms of the token


Returns the token object
privacyidea.lib.token.init_token(param, user=None, tokenrealms=None, tokenkind=None)
create a new token or update an existing token
Parameters
• param (dict) – initialization parameters like

{
"serial": ..., (optional)
"type": ...., (optional, default=hotp)
"otpkey": ...
}

• user (User Object) – the token owner


• tokenrealms (list) – the realms, to which the token should belong
• tokenkind – The kind of the token, can be “software”, “hardware” or “virtual”
Returns token object or None
Return type TokenClass
privacyidea.lib.token.is_token_active(serial)
Return True if the token is active, otherwise false Raise ResourceError if the token could not be found.
Parameters serial (basestring) – The serial number of the token
Returns True or False
Return type bool
privacyidea.lib.token.is_token_owner(serial, user)
Check if the given user is the owner of the token with the given serial number
Parameters

370 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

• serial (str) – The serial number of the token


• user (User object) – The user that needs to be checked
Returns Return True or False
Return type bool
privacyidea.lib.token.list_tokengroups(tokengroup=None)
Return a list of tokens that are assigned to a certain tokengroup If no tokengroup is specified, all groups/tokens
are returned.
:param tokengroup. The name of the token group :return:
privacyidea.lib.token.lost_token(serial, new_serial=None, password=None, validity=10, contents='8',
pw_len=16, options=None)
This is the workflow to handle a lost token. The token <serial> is lost and will be disabled. A new token of type
password token will be created and assigned to the user. The PIN of the lost token will be copied to the new
token. The new token will have a certain validity period.
Parameters
• serial – Token serial number
• new_serial – new serial number
• password – new password
• validity (int) – Number of days, the new token should be valid
• contents (str) – The contents of the generated password. Can be a string like "Ccn".
– ”C”: upper case characters
– ”c”: lower case characters
– ”n”: digits
– ”s”: special characters
– ”8”: base58
• pw_len (int) – The length of the generated password
• options (dict) – optional values for the decorator passed from the upper API level
Returns result dictionary
Return type dict
privacyidea.lib.token.remove_token(serial=None, user=None)
remove the token that matches the serial number or all tokens of the given user and also remove the realm
associations and all its challenges
Parameters
• user (User object) – The user, who’s tokens should be deleted.
• serial (basestring) – The serial number of the token to delete (exact)
Returns The number of deleted token
Return type int
privacyidea.lib.token.reset_token(serial, user=None)
Reset the failcounter of a single token, or of all tokens of one user.
Parameters

1.15. Code Documentation 371


privacyIDEA Authentication System, Release 3.8

• serial – serial number (exact)


• user –
Returns The number of tokens, that were reset
Return type int
privacyidea.lib.token.resync_token(serial, otp1, otp2, options=None, user=None)
Resynchronize the token of the given serial number and user by searching the otp1 and otp2 in the future otp
values.
Parameters
• serial (str) – token serial number (exact)
• otp1 (str) – first OTP value
• otp2 (str) – second OTP value, directly after the first
• options (dict) – additional options like the servertime for TOTP token
Returns result of the resync
Return type bool
privacyidea.lib.token.revoke_token(serial, user=None)
Revoke a token, or all tokens of a single user.
Parameters
• serial (basestring) – The serial number of the token (exact)
• user (User object) – all tokens of the user will be enabled or disabled
Returns Number of tokens that were enabled/disabled
Return type int
privacyidea.lib.token.set_count_auth(serial, count, user=None, max=False, success=False)
The auth counters are stored in the token info database field. There are different counters, that can be set:

count_auth -> max=False, success=False


count_auth_max -> max=True, success=False
count_auth_success -> max=False, success=True
count_auth_success_max -> max=True, success=True

Parameters
• count (int) – The counter value
• user (User object) – The user owner of the tokens tokens to modify
• serial (basestring) – The serial number of the one token to modify (exact)
• max (bool) – True, if either count_auth_max or count_auth_success_max are to be modified
• success (bool) – True, if either count_auth_success or count_auth_success_max
are to be modified
Returns number of modified tokens
Return type int

372 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

privacyidea.lib.token.set_count_window(serial, countwindow=10, user=None)


The count window is used during authentication to find the matching OTP value. This sets the count window
per token.
Parameters
• serial (basestring) – The serial number of the token (exact)
• countwindow (int) – the size of the window
• user (User object) – The owner of the tokens, which should be modified
Returns number of modified tokens
Return type int
privacyidea.lib.token.set_defaults(serial)
Set the default values for the token with the given serial number (exact)
Parameters serial (basestring) – token serial
Returns None
privacyidea.lib.token.set_description(serial, description, user=None)
Set the description of a token
Parameters
• serial (basestring) – The serial number of the token (exact)
• description (str) – The description for the token
• user (User object) – The owner of the tokens, which should be modified
Returns number of modified tokens
Return type int
privacyidea.lib.token.set_failcounter(serial, counter, user=None)
Set the fail counter of a token.
Parameters
• serial – The serial number of the token (exact)
• counter – THe counter to which the fail counter should be set
• user – An optional user
Returns Number of tokens, where the fail counter was set.
privacyidea.lib.token.set_hashlib(serial, hashlib='sha1', user=None)
Set the hashlib in the tokeninfo. Can be something like sha1, sha256. . .
Parameters
• serial (basestring) – The serial number of the token (exact)
• hashlib (basestring) – The hashlib of the token
• user (User object) – The User, for who’s token the hashlib should be set
Returns the number of token infos set
Return type int
privacyidea.lib.token.set_max_failcount(serial, maxfail, user=None)
Set the maximum fail counts of tokens. This is the maximum number a failed authentication is allowed.

1.15. Code Documentation 373


privacyIDEA Authentication System, Release 3.8

Parameters
• serial (basestring) – The serial number of the token (exact)
• maxfail (int) – The maximum allowed failed authentications
• user (User object) – The owner of the tokens, which should be modified
Returns number of modified tokens
Return type int
privacyidea.lib.token.set_otplen(serial, otplen=6, user=None)
Set the otp length of the token defined by serial or for all tokens of the user. The OTP length is usually 6 or 8.
Parameters
• serial (basestring) – The serial number of the token (exact)
• otplen (int) – The length of the OTP value
• user (User object) – The owner of the tokens
Returns number of modified tokens
Return type int
privacyidea.lib.token.set_pin(serial, pin, user=None, encrypt_pin=False)
Set the token PIN of the token. This is the static part that can be used to authenticate.
Parameters
• pin (str) – The pin of the token
• user (User object) – If the user is specified, the pins for all tokens of this user will be set
• serial – If the serial is specified, the PIN for this very token will be set. (exact)
Returns The number of PINs set (usually 1)
Return type int
privacyidea.lib.token.set_pin_so(serial, so_pin, user=None)
Set the SO PIN of a smartcard. The SO Pin can be used to reset the PIN of a smartcard. The SO PIN is stored
in the database, so that it could be used for automatic processes for User PIN resetting.
Parameters
• serial (basestring) – The serial number of the token (exact)
• so_pin (basestring) – The Security Officer PIN
Returns The number of SO PINs set. (usually 1)
Return type int
privacyidea.lib.token.set_pin_user(serial, user_pin, user=None)
This sets the user pin of a token. This just stores the information of the user pin for (e.g. an eTokenNG, Smartcard)
in the database
Parameters
• serial (basestring) – The serial number of the token (exact)
• user_pin (str) – The user PIN
Returns The number of PINs set (usually 1)
Return type int

374 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

privacyidea.lib.token.set_realms(serial, realms=None, add=False)


Set all realms of a token. This sets the realms new. I.e. it does not add realms. So realms that are not contained
in the list will not be assigned to the token anymore.
If the token could not be found, a ResourceNotFoundError is raised.
Thus, setting realms=[] clears all realms assignments.
Parameters
• serial (basestring) – the serial number of the token (exact)
• realms (list) – A list of realm names
• add (bool) – if the realms should be added and not replaced
privacyidea.lib.token.set_sync_window(serial, syncwindow=1000, user=None)
The sync window is the window that is used during resync of a token. Such many OTP values are calculated
ahead, to find the matching otp value and counter.
Parameters
• serial (basestring) – The serial number of the token (exact)
• syncwindow (int) – The size of the sync window
• user (User object) – The owner of the tokens, which should be modified
Returns number of modified tokens
Return type int
privacyidea.lib.token.set_tokengroups(serial, tokengroups=None, add=False)
Set a list of tokengroups for one token
Parameters
• serial – The serial of the token
• tokengroups – The list of tokengroups (names)
• add – Whether the list of tokengropus should be added
Returns
privacyidea.lib.token.set_validity_period_end(serial, user, end)
Set the validity period for the given token.
Parameters
• serial – serial number (exact)
• user –
• end (basestring) – Timestamp in the format DD/MM/YY HH:MM
privacyidea.lib.token.set_validity_period_start(serial, user, start)
Set the validity period for the given token.
Parameters
• serial – serial number (exact)
• user –
• start (basestring) – Timestamp in the format DD/MM/YY HH:MM
privacyidea.lib.token.token_exist(serial)
returns true if the token with the exact given serial number exists

1.15. Code Documentation 375


privacyIDEA Authentication System, Release 3.8

Parameters serial – the serial number of the token


privacyidea.lib.token.unassign_token(serial, user=None)
unassign the user from the token, or all tokens of a user
Parameters
• serial – The serial number of the token to unassign (exact). Can be None
• user – A user whose tokens should be unassigned
Returns number of unassigned tokens
privacyidea.lib.token.unassign_tokengroup(serial, tokengroup=None, tokengroup_id=None)
Removes a tokengroup from a token
Parameters
• serial – The serial number of the token
• tokengroup – The name of the tokengroup
• tokengroup_id – alternatively the id of the tokengroup
Returns True
privacyidea.lib.token.weigh_token_type(token_obj)
This method returns a weight of a token type, which is used to sort the tokentype list. Other weighing functions
can be implemented.
The Push token weighs the most, so that it will be sorted to the end.
Parameters token_obj – token object
Returns weight of the tokentype
Return type int

Application Class

privacyidea.lib.applications.MachineApplicationBase
alias of privacyidea.lib.applications.base.MachineApplication

Policy Module

Base function to handle the policy entries in the database. This module only depends on the db/models.py
The functions of this module are tested in tests/test_lib_policy.py
A policy has the attributes
• name
• scope
• action
• realm
• resolver
• user
• client

376 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

• active
name is the unique identifier of a policy. scope is the area, where this policy is meant for. This can be values like
admin, selfservice, authentication. . . scope takes only one value.
active is bool and indicates, whether a policy is active or not.
action, realm, resolver, user and client can take a comma separated list of values.

realm and resolver

If these are empty ‘*’, this policy matches each requested realm.

user

If the user is empty or ‘*’, this policy matches each user. You can exclude users from matching this policy, by prepending
a ‘-’ or a ‘!’. *, -admin will match for all users except the admin.
You can also use regular expressions to match the user like customer_.* to match any user, starting with customer_.

Note: Regular expression will only work for exact matches. user1234 will not match user1 but only user1. . .

client

The client is identified by its IP address. A policy can contain a list of IP addresses or subnets. You can exclude clients
from subnets by prepending the client with a ‘-’ or a ‘!’. 172.16.0.0/24, -172.16.0.17 will match each client in
the subnet except the 172.16.0.17.

time

You can specify a time in which the policy should be active. Time formats are:

<dow>-<dow>:<hh>:<mm>-<hh>:<mm>, ...
<dow>:<hh>:<mm>-<hh>:<mm>
<dow>:<hh>-<hh>

and any combination of it. dow being day of week Mon, Tue, Wed, Thu, Fri, Sat, Sun.
class privacyidea.lib.policy.ACTION
This is the list of usual actions.
ADDRESOLVERINRESPONSE = 'add_resolver_in_response'
ADDUSER = 'adduser'
ADDUSERINRESPONSE = 'add_user_in_response'
ADMIN_DASHBOARD = 'admin_dashboard'
APIKEY = 'api_key_required'
APPIMAGEURL = 'appimageurl'
APPLICATION_TOKENTYPE = 'application_tokentype'

1.15. Code Documentation 377


privacyIDEA Authentication System, Release 3.8

ASSIGN = 'assign'
AUDIT = 'auditlog'
AUDITPAGESIZE = 'audit_page_size'
AUDIT_AGE = 'auditlog_age'
AUDIT_DOWNLOAD = 'auditlog_download'
AUTHITEMS = 'fetch_authentication_items'
AUTHMAXFAIL = 'auth_max_fail'
AUTHMAXSUCCESS = 'auth_max_success'
AUTHORIZED = 'authorized'
AUTH_CACHE = 'auth_cache'
AUTOASSIGN = 'autoassignment'
CACONNECTORDELETE = 'caconnectordelete'
CACONNECTORREAD = 'caconnectorread'
CACONNECTORWRITE = 'caconnectorwrite'
CHALLENGERESPONSE = 'challenge_response'
CHALLENGETEXT = 'challenge_text'
CHALLENGETEXT_FOOTER = 'challenge_text_footer'
CHALLENGETEXT_HEADER = 'challenge_text_header'
CHANGE_PIN_EVERY = 'change_pin_every'
CHANGE_PIN_FIRST_USE = 'change_pin_on_first_use'
CHANGE_PIN_VIA_VALIDATE = 'change_pin_via_validate'
CLIENTTYPE = 'clienttype'
CONFIGDOCUMENTATION = 'system_documentation'
COPYTOKENPIN = 'copytokenpin'
COPYTOKENUSER = 'copytokenuser'
CUSTOM_BASELINE = 'custom_baseline'
CUSTOM_MENU = 'custom_menu'
DEFAULT_TOKENTYPE = 'default_tokentype'
DELETE = 'delete'
DELETEUSER = 'deleteuser'
DELETE_USER_ATTRIBUTES = 'delete_custom_user_attributes'
DELETION_CONFIRMATION = 'deletion_confirmation'
DIALOG_NO_TOKEN = 'dialog_no_token'
DISABLE = 'disable'
EMAILCONFIG = 'smtpconfig'
ENABLE = 'enable'

378 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

ENCRYPTPIN = 'encrypt_pin'
ENROLLPIN = 'enrollpin'
ENROLL_VIA_MULTICHALLENGE = 'enroll_via_multichallenge'
EVENTHANDLINGREAD = 'eventhandling_read'
EVENTHANDLINGWRITE = 'eventhandling_write'
FORCE_APP_PIN = 'force_app_pin'
GDPR_LINK = 'privacy_statement_link'
GETCHALLENGES = 'getchallenges'
GETRANDOM = 'getrandom'
GETSERIAL = 'getserial'
HIDE_AUDIT_COLUMNS = 'hide_audit_columns'
HIDE_BUTTONS = 'hide_buttons'
HIDE_TOKENINFO = 'hide_tokeninfo'
HIDE_WELCOME = 'hide_welcome_info'
IMPORT = 'importtokens'
INCREASE_FAILCOUNTER_ON_CHALLENGE = 'increase_failcounter_on_challenge'
LASTAUTH = 'last_auth'
LOGINMODE = 'login_mode'
LOGIN_TEXT = 'login_text'
LOGOUTTIME = 'logout_time'
LOGOUT_REDIRECT = 'logout_redirect'
LOSTTOKEN = 'losttoken'
LOSTTOKENPWCONTENTS = 'losttoken_PW_contents'
LOSTTOKENPWLEN = 'losttoken_PW_length'
LOSTTOKENVALID = 'losttoken_valid'
MACHINELIST = 'machinelist'
MACHINERESOLVERDELETE = 'mresolverdelete'
MACHINERESOLVERREAD = 'mresolverread'
MACHINERESOLVERWRITE = 'mresolverwrite'
MACHINETOKENS = 'manage_machine_tokens'
MANAGESUBSCRIPTION = 'managesubscription'
MANGLE = 'mangle'
MAXACTIVETOKENUSER = 'max_active_token_per_user'
MAXTOKENREALM = 'max_token_per_realm'
MAXTOKENUSER = 'max_token_per_user'
NODETAILFAIL = 'no_detail_on_fail'

1.15. Code Documentation 379


privacyIDEA Authentication System, Release 3.8

NODETAILSUCCESS = 'no_detail_on_success'
OTPPIN = 'otppin'
OTPPINCONTENTS = 'otp_pin_contents'
OTPPINMAXLEN = 'otp_pin_maxlength'
OTPPINMINLEN = 'otp_pin_minlength'
OTPPINRANDOM = 'otp_pin_random'
OTPPINSETRANDOM = 'otp_pin_set_random'
PASSNOTOKEN = 'passOnNoToken'
PASSNOUSER = 'passOnNoUser'
PASSTHRU = 'passthru'
PASSTHRU_ASSIGN = 'passthru_assign'
PASSWORDRESET = 'password_reset'
PASSWORD_CONTENTS = 'pw.contents'
PASSWORD_LENGTH = 'pw.length'
PERIODICTASKREAD = 'periodictask_read'
PERIODICTASKWRITE = 'periodictask_write'
PINHANDLING = 'pinhandling'
POLICYDELETE = 'policydelete'
POLICYREAD = 'policyread'
POLICYTEMPLATEURL = 'policy_template_url'
POLICYWRITE = 'policywrite'
PREFERREDCLIENTMODE = 'preferred_client_mode'
PRIVACYIDEASERVERREAD = 'privacyideaserver_read'
PRIVACYIDEASERVERWRITE = 'privacyideaserver_write'
RADIUSSERVERREAD = 'radiusserver_read'
RADIUSSERVERWRITE = 'radiusserver_write'
REALM = 'realm'
REALMDROPDOWN = 'realm_dropdown'
REGISTERBODY = 'registration_body'
REGISTRATIONCODE_CONTENTS = 'registration.contents'
REGISTRATIONCODE_LENGTH = 'registration.length'
REMOTE_USER = 'remote_user'
REQUIREDEMAIL = 'requiredemail'
RESET = 'reset'
RESETALLTOKENS = 'reset_all_user_tokens'
RESOLVER = 'resolver'

380 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

RESOLVERDELETE = 'resolverdelete'
RESOLVERREAD = 'resolverread'
RESOLVERWRITE = 'resolverwrite'
RESYNC = 'resync'
RESYNC_VIA_MULTICHALLENGE = 'resync_via_multichallenge'
REVOKE = 'revoke'
SEARCH_ON_ENTER = 'search_on_enter'
SERIAL = 'serial'
SET = 'set'
SETDESCRIPTION = 'setdescription'
SETHSM = 'set_hsm_password'
SETPIN = 'setpin'
SETRANDOMPIN = 'setrandompin'
SETREALM = 'setrealm'
SETTOKENINFO = 'settokeninfo'
SET_USER_ATTRIBUTES = 'set_custom_user_attributes'
SHOW_ANDROID_AUTHENTICATOR = 'show_android_privacyidea_authenticator'
SHOW_CUSTOM_AUTHENTICATOR = 'show_custom_authenticator'
SHOW_IOS_AUTHENTICATOR = 'show_ios_privacyidea_authenticator'
SHOW_NODE = 'show_node'
SHOW_SEED = 'show_seed'
SMSGATEWAYREAD = 'smsgateway_read'
SMSGATEWAYWRITE = 'smsgateway_write'
SMTPSERVERREAD = 'smtpserver_read'
SMTPSERVERWRITE = 'smtpserver_write'
STATISTICSDELETE = 'statistics_delete'
STATISTICSREAD = 'statistics_read'
SYSTEMDELETE = 'configdelete'
SYSTEMREAD = 'configread'
SYSTEMWRITE = 'configwrite'
TIMEOUT_ACTION = 'timeout_action'
TOKENGROUPS = 'tokengroups'
TOKENGROUP_ADD = 'tokengroup_add'
TOKENGROUP_DELETE = 'tokengroup_delete'
TOKENGROUP_LIST = 'tokengroup_list'
TOKENINFO = 'tokeninfo'

1.15. Code Documentation 381


privacyIDEA Authentication System, Release 3.8

TOKENISSUER = 'tokenissuer'
TOKENLABEL = 'tokenlabel'
TOKENLIST = 'tokenlist'
TOKENPAGESIZE = 'token_page_size'
TOKENREALMS = 'tokenrealms'
TOKENROLLOVER = 'token_rollover'
TOKENTYPE = 'tokentype'
TOKENWIZARD = 'tokenwizard'
TOKENWIZARD2ND = 'tokenwizard_2nd_token'
TRIGGERCHALLENGE = 'triggerchallenge'
UNASSIGN = 'unassign'
UPDATEUSER = 'updateuser'
USERDETAILS = 'user_details'
USERLIST = 'userlist'
USERPAGESIZE = 'user_page_size'
VERIFY_ENROLLMENT = 'verify_enrollment'
class privacyidea.lib.policy.ACTIONVALUE
This is a list of usual action values for e.g. policy action-values like otppin.
DISABLE = 'disable'
NONE = 'none'
TOKENPIN = 'tokenpin'
USERSTORE = 'userstore'
class privacyidea.lib.policy.AUTHORIZED

ALLOW = 'grant_access'
DENY = 'deny_access'
class privacyidea.lib.policy.AUTOASSIGNVALUE
This is the possible values for autoassign
NONE = 'any_pin'
USERSTORE = 'userstore'
class privacyidea.lib.policy.CONDITION_CHECK
The available check methods for extended conditions
CHECK_AND_RAISE_EXCEPTION_ON_MISSING = None
DO_NOT_CHECK_AT_ALL = 1
ONLY_CHECK_USERINFO = ['userinfo']
class privacyidea.lib.policy.CONDITION_SECTION
This is a list of available sections for conditions of policies
HTTP_ENVIRONMENT = 'HTTP Environment'

382 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

HTTP_REQUEST_HEADER = 'HTTP Request header'


TOKEN = 'token'
TOKENINFO = 'tokeninfo'
USERINFO = 'userinfo'
class privacyidea.lib.policy.GROUP
These are the allowed policy action groups. The policies will be grouped in the UI.
CONDITIONS = 'conditions'
ENROLLMENT = 'enrollment'
GENERAL = 'general'
MACHINE = 'machine'
MODIFYING_RESPONSE = 'modifying response'
PIN = 'pin'
SETTING_ACTIONS = 'setting actions'
SYSTEM = 'system'
TOKEN = 'token'
TOKENGROUP = 'tokengroup'
TOOLS = 'tools'
USER = 'user'
class privacyidea.lib.policy.LOGINMODE
This is the list of possible values for the login mode.
DISABLE = 'disable'
PRIVACYIDEA = 'privacyIDEA'
USERSTORE = 'userstore'
class privacyidea.lib.policy.MAIN_MENU
These are the allowed top level menu items. These are used to toggle the visibility of the menu items depending
on the rights of the user
AUDIT = 'audit'
COMPONENTS = 'components'
CONFIG = 'config'
MACHINES = 'machines'
TOKENS = 'tokens'
USERS = 'users'
class privacyidea.lib.policy.Match(g, **kwargs)
This class provides a high-level API for policy matching.
It should not be instantiated directly. Instead, code should use one of the provided classmethods to construct a
Match object. See the respective classmethods for details.
A Match object encapsulates a policy matching operation, i.e. a call to privacyidea.lib.policy.
PolicyClass.match_policies(). In order to retrieve the matching policies, one should use one of

1.15. Code Documentation 383


privacyIDEA Authentication System, Release 3.8

policies(), action_values() and any(). By default, these functions write the matched policies to the
audit log. This behavior can be explicitly disabled.
Every classmethod expects a so-called “context object” as its first argument. The context object implements the
following attributes:
• audit_object: an Audit object which is used to write the used policies to the audit log. In case False
is passed for write_to_audit_log, the audit object may be None.
• policy_object: a PolicyClass object that is used to retrieve the matching policies.
• client_ip: the IP of the current client, as a string
• logged_in_user: a dictionary with keys “username”, “realm”, “role” that describes the currently
logged-in (managing) user
In our case, this context object is usually the flask.g object.
classmethod action_only(g, scope, action)
Match active policies solely based on a scope and an action, which may also be None. The client IP is
matched implicitly.
Parameters
• g – context object
• scope – the policy scope. SCOPE.ADMIN cannot be passed, admin must be used instead.
• action – the policy action, or None
Return type Match
action_values(unique, allow_white_space_in_action=False, write_to_audit_log=True)
Return a dictionary of action values extracted from the matching policies.
The dictionary maps each action value to a list of policies which define this action value.
Parameters
• unique – If True, return only the prioritized action value. See privacyidea.lib.
policy.PolicyClass.get_action_values() for details.
• allow_white_space_in_action – If True, allow whitespace in action values. See
privacyidea.lib.policy.PolicyClass.get_action_values() for details.
• write_to_audit_log – If True, augment the audit log with the names of all policies
whose action values are returned
Return type dict
classmethod admin(g, action, user_obj=None)
Match admin policies with an action and, optionally, a realm. Assumes that the currently logged-in user
is an admin, and throws an error otherwise. Policies will be matched against the admin’s username and
adminrealm, and optionally also the provided user_obj on which the admin is acting The client IP is matched
implicitly.
Parameters
• g – context object
• action – the policy action
• user_obj (User or None) – the user against which policies should be matched. Can be
None.
Return type Match

384 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

classmethod admin_or_user(g, action, user_obj)


Depending on the role of the currently logged-in user, match either scope=ADMIN or scope=USER poli-
cies. If the currently logged-in user is an admin, match policies against the username, adminrealm and the
given user_obj on which the admin is acting. If the currently logged-in user is a user, match policies against
the username and the given realm. The client IP is matched implicitly.
Parameters
• g – context object
• action – the policy action
• user_obj – the user_obj on which the administrator is acting
Return type Match
allowed(write_to_audit_log=True)
Determine if the matched action is allowed in the scope admin or user.
This is the case
• either if there are no active policies defined in the matched scope
• or the action is explicitly allowed by a policy in the matched scope
Example usage:

is_allowed = Match.user(g, scope=SCOPE.USER, action=ACTION.ENROLLPIN, user=user_


˓→object).allowed()

# is_allowed is now true


# either if there is no active policy defined with scope=SCOPE.USER at all
# or if there is a policy matching the given scope, action, user and client IP.

Parameters write_to_audit_log – If True, write the list of matching policies to the audit log
Returns True or False

any(write_to_audit_log=True)
Return True if at least one policy matches.
Parameters write_to_audit_log – If True, write the list of matching policies to the audit log
Returns True or False
classmethod generic(g, scope=None, realm=None, resolver=None, user=None, user_object=None,
client=None, action=None, adminrealm=None, adminuser=None, time=None,
active=True, sort_by_priority=True, serial=None,
extended_condition_check=None)
Low-level legacy policy matching interface: Search for active policies and return them sorted by priority.
All parameters that should be used for matching have to be passed explicitly. The client IP has to be passed
explicitly. See privacyidea.lib.policy.PolicyClass.match_policies() for details.
Return type Match
policies(write_to_audit_log=True)
Return a list of policies. The list is sorted by priority, which means that prioritized policies appear first.
Parameters write_to_audit_log – If True, write the list of matching policies to the audit log
Returns a list of policy dictionaries
Return type list

1.15. Code Documentation 385


privacyIDEA Authentication System, Release 3.8

classmethod realm(g, scope, action, realm)


Match active policies with a scope, an action and a user realm. The client IP is matched implicitly.
Parameters
• g – context object
• scope – the policy scope. SCOPE.ADMIN cannot be passed, admin must be used instead.
• action – the policy action
• realm – the realm to match
Return type Match
classmethod token(g, scope, action, token_obj)
Match active policies with a scope, an action and a token object. The client IP is matched implicitly. From
the token object we try to determine the user as the owner. If the token has no owner, we try to determine
the tokenrealm. We fallback to realm=None
Parameters
• g – context object
• scope – the policy scope. SCOPE.ADMIN cannot be passed, admin must be used instead.
• action – the policy action
• token_obj – The token where the user object or the realm should match.
Return type Match
classmethod user(g, scope, action, user_object)
Match active policies with a scope, an action and a user object (which may be None). The client IP is
matched implicitly.
Parameters
• g – context object
• scope – the policy scope. SCOPE.ADMIN cannot be passed, admin must be used instead.
• action – the policy action
• user_object (User or None) – the user object to match. Might also be None, which
means that the policy attributes user, realm and resolver are ignored.
Return type Match
exception privacyidea.lib.policy.MatchingError(description='server error!', id=903)
class privacyidea.lib.policy.PolicyClass
A policy object can be used to query the current set of policies. The policy object itself does not store any policies.
Instead, every query uses get_config_object to retrieve the request-local config object which contains the
current set of policies.
Hence, reloading the request-local config object also reloads the set of policies.
static check_for_conflicts(policies, action)
Given a (not necessarily sorted) list of policy dictionaries and an action name, check that there are no action
value conflicts.
This raises a PolicyError if there are multiple policies with the highest priority which define different values
for action.
Otherwise, the function just returns nothing.

386 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Parameters
• policies – list of dictionaries
• action – string
static extract_action_values(policies, action, unique=False, allow_white_space_in_action=False)
Given an action, extract all values the given policies specify for that action.
Parameters
• policies (list) – a list of policy dictionaries
• action (action) – a policy action
• unique (bool) – if True, only consider the policy with the highest priority and check for
policy conflicts (in this case, raise a PolicyError).
• allow_white_space_in_action – Some policies like emailtext would allow entering
text with whitespaces. These whitespaces must not be used to separate action values!
Returns a dictionary mapping action values to lists of matching policies.
filter_policies_by_conditions(policies, user_object=None, request_headers=None, serial=None,
extended_condition_check=None)
Given a list of policy dictionaries and a current user object (if any), return a list of all policies whose con-
ditions match the given user object. Raises a PolicyError if a condition references an unknown section.
:param policies: a list of policy dictionaries :param user_object: a User object, or None if there is no
current user :param request_headers: The HTTP headers :type request_headers: Request object :param ex-
tended_condition_check: A list of sections to check or None. :return: generates a list of policy dictionaries
get_action_values(action, scope='authorization', realm=None, resolver=None, user=None, client=None,
unique=False, allow_white_space_in_action=False, adminrealm=None,
adminuser=None, user_object=None, audit_data=None)
Get the defined action values for a certain actions.
Calling the function with parameters like:

scope: authorization
action: tokentype

would return a dictionary of {tokentype: policyname}.


A call with the parameters:

scope: authorization
action: serial

would return a dictionary of {serial: policyname}


All parameters not described below are covered in the documentation of match_policies.
Parameters
• unique – if set, the function will only consider the policy with the highest priority and
check for policy conflicts.
• allow_white_space_in_action (bool) – Some policies like emailtext would allow en-
tering text with whitespaces. These whitespaces must not be used to separate action values!
• audit_data – This is a dictionary, that can take audit_data in the g object. If set, this
dictionary will be filled with the list of triggered policynames in the key “policies”. This
can be useful for policies like ACTION.OTPPIN - where it is clear, that the found policy

1.15. Code Documentation 387


privacyIDEA Authentication System, Release 3.8

will be used. It could make less sense with an action like ACTION.LASTAUTH - where
the value of the action needs to be evaluated in a more special case.
Return type dict
list_policies(name=None, scope=None, realm=None, active=None, resolver=None, user=None,
client=None, action=None, pinode=None, adminrealm=None, adminuser=None,
sort_by_priority=True)
Return the policies, filtered by the given values.
The following rule holds for all filter arguments:
If None is passed as a value, policies are not filtered according to the argument at all. As an example, if
realm=None is passed, policies are matched regardless of their realm attribute. If any value is passed
(even the empty string), policies are filtered according to the given value. As an example, if realm='' is
passed, only policies that have a matching (or empty) realm attribute are returned.
The only exception is the client parameter, which does not accept the empty string, and throws a Param-
eterError if the empty string is passed.
Parameters
• name – The name of the policy
• scope – The scope of the policy
• realm – The realm in the policy
• active – One of None, True, False: All policies, only active or only inactive policies
• resolver – Only policies with this resolver
• pinode – Only policies with this privacyIDEA node
• user (basestring) – Only policies with this user
• client –
• action – Only policies, that contain this very action.
• adminrealm – This is the realm of the admin. This is only evaluated in the scope admin.
• adminuser – This is the username of the admin. This in only evaluated in the scope admin.
• sort_by_priority (bool) – If true, sort the resulting list by priority, ascending by their
policy numbers.
Returns list of policies
Return type list of dicts
match_policies(name=None, scope=None, realm=None, active=None, resolver=None, user=None,
user_object=None, pinode=None, client=None, action=None, adminrealm=None,
adminuser=None, time=None, sort_by_priority=True, audit_data=None,
request_headers=None, serial=None, extended_condition_check=None)
Return all policies matching the given context. Optionally, write the matching policies to the audit log.
In order to retrieve policies matching the current user, callers can either pass a user(name), resolver and
realm, or pass a user object from which login name, resolver and realm will be read. In case of conflicting
parameters, a ParameterError will be raised.
This function takes all parameters taken by list_policies, plus some additional parameters.
Parameters
• name – see list_policies

388 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

• scope – see list_policies


• realm – see list_policies
• active – see list_policies
• resolver – see list_policies
• user – see list_policies
• client – see list_policies
• action – see list_policies
• adminrealm – see list_policies
• adminuser – see list_policies
• pinode – see list_policies
• sort_by_priority –
• user_object (User or None) – the currently active user, or None
• time (datetime or None) – return only policies that are valid at the specified time. De-
faults to the current time.
• audit_data (dict or None) – A dictionary with audit data collected during a request.
This method will add found policies to the dictionary.
• request_headers – A dict with HTTP headers
Returns a list of policy dictionaries
property policies
Shorthand to retrieve the set of policies of the request-local config object
ui_get_enroll_tokentypes(client, logged_in_user)
Return a dictionary of the allowed tokentypes for the logged in user. This used for the token enrollment UI.
It looks like this:
{“hotp”: “HOTP: event based One Time Passwords”, “totp”: “TOTP: time based One Time
Passwords”, “spass”: “SPass: Simple Pass token. Static passwords”, “motp”: “mOTP: clas-
sical mobile One Time Passwords”, “sshkey”: “SSH Public Key: The public SSH key”, “yu-
bikey”: “Yubikey AES mode: One Time Passwords with Yubikey”, “remote”: “Remote To-
ken: Forward authentication request to another server”, “yubico”: “Yubikey Cloud mode:
Forward authentication request to YubiCloud”, “radius”: “RADIUS: Forward authentication
request to a RADIUS server”, “email”: “EMail: Send a One Time Passwort to the users email
address”, “sms”: “SMS: Send a One Time Password to the users mobile phone”, “certificate”:
“Certificate: Enroll an x509 Certificate Token.”}

Parameters
• client (basestring) – Client IP address
• logged_in_user (dict) – The Dict of the logged in user
Returns list of token types, the user may enroll

ui_get_main_menus(logged_in_user, client=None)
Get the list of allowed main menus derived from the policies for the given user - admin or normal user. It
fetches all policies for this user and compiles a list of allowed menus to display or hide in the UI.
Parameters

1.15. Code Documentation 389


privacyIDEA Authentication System, Release 3.8

• logged_in_user – The logged in user, a dictionary with keys “username”, “realm” and
“role”.
• client – The IP address of the client
Returns A list of MENUs to be displayed
ui_get_rights(scope, realm, username, client=None)
Get the rights derived from the policies for the given realm and user. Works for admins and normal users.
It fetches all policies for this user and compiles a maximum list of allowed rights, that can be used to hide
certain UI elements.
Parameters
• scope – Can be SCOPE.ADMIN or SCOPE.USER
• realm – Is either user users realm or the adminrealm
• username – The loginname of the user
• client – The HTTP client IP
Returns A list of actions
class privacyidea.lib.policy.REMOTE_USER
The list of possible values for the remote_user policy.
ACTIVE = 'allowed'
DISABLE = 'disable'
FORCE = 'force'
class privacyidea.lib.policy.SCOPE
This is the list of the allowed scopes that can be used in policy definitions.
ADMIN = 'admin'
AUDIT = 'audit'
AUTH = 'authentication'
AUTHZ = 'authorization'
ENROLL = 'enrollment'
REGISTER = 'register'
USER = 'user'
WEBUI = 'webui'
class privacyidea.lib.policy.TIMEOUT_ACTION
This is a list of actions values for idle users
LOCKSCREEN = 'lockscreen'
LOGOUT = 'logout'
class privacyidea.lib.policy.TYPE

BOOL = 'bool'
INT = 'int'
STRING = 'str'

390 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

privacyidea.lib.policy.check_pin(g, pin, tokentype, user_obj)


get the policies for minimum length, maximum length and PIN contents first try to get a token specific policy -
otherwise fall back to default policy.
Raises an exception, if the PIN does not comply to the policies.
Parameters
• g–
• pin –
• tokentype –
• user_obj –
privacyidea.lib.policy.delete_all_policies()
privacyidea.lib.policy.delete_policy(name)
Function to delete one named policy. Raise ResourceNotFoundError if there is no such policy.
Parameters name – the name of the policy to be deleted
Returns the ID of the deleted policy
Return type int
privacyidea.lib.policy.enable_policy(name, enable=True)
Enable or disable the policy with the given name :param name: :return: ID of the policy
privacyidea.lib.policy.export_policies(policies)
This function takes a policy list and creates an export file from it
Parameters policies (list of policy dictionaries) – a policy definition
Returns the contents of the file
Return type string
privacyidea.lib.policy.export_policy(name=None)
Export given or all policy configuration
privacyidea.lib.policy.get_action_values_from_options(scope, action, options)
This function is used in the library level to fetch policy action values from a given option dictionary.
The matched policies are not written to the audit log.
Returns A scalar, string or None
privacyidea.lib.policy.get_allowed_custom_attributes(g, user_obj)
Return the list off allowed custom user attributes that can be set and deleted. Returns a dictionary with the two
keys “delete” and “set.
Parameters
• g–
• user_obj – The User object to check the allowed attributes for
Returns dict
privacyidea.lib.policy.get_policy_condition_comparators()

Returns a dictionary mapping comparators to dictionaries with the following keys: *


"description", a human-readable description of the comparator

1.15. Code Documentation 391


privacyIDEA Authentication System, Release 3.8

privacyidea.lib.policy.get_policy_condition_sections()

Returns a dictionary mapping condition sections to dictionaries with the following keys: *
"description", a human-readable description of the section
privacyidea.lib.policy.get_static_policy_definitions(scope=None)
These are the static hard coded policy definitions. They can be enhanced by token based policy definitions, that
can be found in lib.token.get_dynamic_policy_definitions.
Parameters scope (basestring) – Optional the scope of the policies
Returns allowed scopes with allowed actions, the type of action and a description.
Return type dict
privacyidea.lib.policy.import_policies(file_contents)
This function imports policies from a file.
The file has a config_object format, i.e. the text file has a header:

[<policy_name>]
key = value

and key value pairs.


Parameters file_contents (basestring) – The contents of the file
Returns number of imported policies
Return type int
privacyidea.lib.policy.import_policy(data, name=None)
Import policy configuration
privacyidea.lib.policy.set_policy(name=None, scope=None, action=None, realm=None, resolver=None,
user=None, time=None, client=None, active=True, adminrealm=None,
adminuser=None, priority=None, check_all_resolvers=False,
conditions=None, pinode=None)
Function to set a policy.
If the policy with this name already exists, it updates the policy. It expects a dict of with the following keys:
Parameters
• name – The name of the policy
• scope – The scope of the policy. Something like “admin” or “authentication”
• action – A scope specific action or a comma separated list of actions
• realm – A realm, for which this policy is valid
• resolver – A resolver, for which this policy is valid
• user – A username or a list of usernames
• time – N/A if type()
• client – A client IP with optionally a subnet like 172.16.0.0/16
• active (bool) – If the policy is active or not
• adminrealm (str) – The name of the realm of administrators
• adminuser (str) – A comma separated list of administrators

392 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

• priority (int) – the priority of the policy (smaller values having higher priority)
• check_all_resolvers (bool) – If all the resolvers of a user should be checked with this
policy
• conditions – A list of 5-tuples (section, key, comparator, value, active) of policy conditions
• pinode – A privacyIDEA node or a list of privacyIDEA nodes.
Returns The database ID od the the policy
Return type int

Job Queue

The following queue classes are known to privacyIDEA

Huey Queue Class

class privacyidea.lib.queues.huey_queue.HueyQueue(options)

enqueue(name, args, kwargs)


Schedule an invocation of a job on the external job queue.
Parameters
• name – Unique job name
• args – Tuple of positional arguments
• kwargs – Dictionary of keyword arguments
Returns None
property huey
property jobs
register_job(name, func)
Add a job to the internal registry.
Parameters
• name – Unique job name
• func – Function that should be executed by an external job queue
privacyidea.lib.queue.JOB_COLLECTOR = <privacyidea.lib.queue.JobCollector object>
A singleton is fine here, because it is only used at import time and once when a new app is created. Afterwards,
the object is unused.
class privacyidea.lib.queue.JobCollector
For most third-party job queue modules, the jobs are discovered by tracking all functions decorated with a @job
decorator. However, in order to invoke the decorator, one usually needs to provide the queue configuration (e.g.
the redis server) already. In privacyIDEA, we cannot do that, because the app config is not known yet – it will be
known when create_app is called! Thus, we cannot directly use the @job decorator, but need a job collector
that collects jobs in privacyIDEA code and registers them with the job queue module when create_app has
been called.
property jobs

1.15. Code Documentation 393


privacyIDEA Authentication System, Release 3.8

register_app(app)
Create an instance of a BaseQueue subclass according to the app config’s PI_JOB_QUEUE_CLASS option
and store it in the job_queue config. Register all collected jobs with this application. This instance is
shared between threads! This function should only be called once per process.
Parameters app – privacyIDEA app
register_job(name, func, args, kwargs)
Register a job with the collector.
Parameters
• name – unique name of the job
• func – function of the job
• args – arguments passed to the job queue’s register_job method
• kwargs – keyword arguments passed to the job queue’s register_job method
privacyidea.lib.queue.get_job_queue()
Get the job queue registered with the current app. If no job queue is configured, raise a ServerError.
privacyidea.lib.queue.has_job_queue()
Return a boolean describing whether the current app has an app queue configured.
privacyidea.lib.queue.job(name, *args, **kwargs)
Decorator to mark a job to be collected by the job collector. All arguments are passed to register_job.
privacyidea.lib.queue.register_app(app)
Register the app app with the global job collector, if a PI_JOB_QUEUE_CLASS is non-empty. Do nothing
otherwise.
privacyidea.lib.queue.wrap_job(name, result)
Wrap a job and return a function that can be used like the original function. The returned function will always
return result. This assumes that a queue is configured! Otherwise, calling the resulting function will fail with
a ServerError.
Returns a function

Base class

class privacyidea.lib.queues.base.BaseQueue(options)
A queue object represents an external job queue and is configured with a dictionary of options. It allows to register
jobs, which are Python functions that may be executed outside of the request lifecycle. Every job is identified by
a unique job name. It then allows to delegate (or “enqueue”) an invocation of a job (which is identified by its job
name) to the external job queue. Currently, the queue only supports fire-and-forget jobs, i.e. jobs without any
return value.
enqueue(name, args, kwargs)
Schedule an invocation of a job on the external job queue.
Parameters
• name – Unique job name
• args – Tuple of positional arguments
• kwargs – Dictionary of keyword arguments
Returns None

394 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

register_job(name, func)
Add a job to the internal registry.
Parameters
• name – Unique job name
• func – Function that should be executed by an external job queue

API Policies

Pre Policies

These are the policy decorators as PRE conditions for the API calls. I.e. these conditions are executed before the
wrapped API call. This module uses the policy base functions from privacyidea.lib.policy but also components from
flask like g.
Wrapping the functions in a decorator class enables easy modular testing.
The functions of this module are tested in tests/test_api_lib_policy.py
privacyidea.api.lib.prepolicy.allowed_audit_realm(request=None, action=None)
This decorator function takes the request and adds additional parameters to the request according to the policy
for the SCOPE.ADMIN or ACTION.AUDIT :param request: :param action: :return: True
privacyidea.api.lib.prepolicy.api_key_required(request=None, action=None)
This is a decorator for check_user_pass and check_serial_pass. It checks, if a policy scope=auth, ac-
tion=apikeyrequired is set. If so, the validate request will only performed, if a JWT token is passed with
role=validate.
privacyidea.api.lib.prepolicy.auditlog_age(request=None, action=None)
This pre condition checks for the policy auditlog_age and set the “timelimit” parameter of the audit search API.
Check ACTION.AUDIT_AGE
The decorator can wrap GET /audit/
Parameters
• request (Request Object) – The request that is intercepted during the API call
• action (basestring) – An optional Action
Returns Always true. Modified the parameter request
privacyidea.api.lib.prepolicy.check_admin_tokenlist(request=None, action=None)
Depending on the policy scope=admin, action=tokenlist, the allowed_realms parameter is set to define, the token
of which realms and administrator is allowed to see.
Sets the allowed_realms None: means the admin has no restrictions []: the admin can not see any realms
[“realm1”, “realm2”. . . ]: the admin can see these realms
Parameters request –
Returns
privacyidea.api.lib.prepolicy.check_anonymous_user(request=None, action=None)
This decorator function takes the request and verifies the given action for the SCOPE USER without an authen-
ticated user but the user from the parameters.
This is used with password_reset
Parameters

1.15. Code Documentation 395


privacyIDEA Authentication System, Release 3.8

• request –
• action –
Returns True otherwise raises an Exception
privacyidea.api.lib.prepolicy.check_application_tokentype(request=None, action=None)
This pre policy checks if the request is allowed to specify the tokentype. If the policy is not set, a possibly set
parameter “type” is removed from the request.
Check ACTION.APPLICATION_TOKENTYPE
This decorator should wrap /validate/check, /validate/samlcheck and /validate/triggerchallenge.

Parameters
• request (Request Object) – The request that is intercepted during the API call
• action (basestring) – An optional Action
Returns Always true. Modified the parameter request

privacyidea.api.lib.prepolicy.check_base_action(request=None, action=None, anonymous=False)


This decorator function takes the request and verifies the given action for the SCOPE ADMIN or USER.
Parameters
• request –
• action –
• anonymous – If set to True, the user data is taken from the request parameters.
Returns True otherwise raises an Exception
privacyidea.api.lib.prepolicy.check_custom_user_attributes(request=None, action=None)
This pre condition checks for the policies delete_custom_user_attributes and set_custom_user_attributes, if the
user or admin is allowed to set or deleted the requested attribute.
It decorates POST /user/attribute and DELETE /user/attribute/. . .
Parameters
• request (Request Object) – The request that is intercepted during the API call
• action – An optional action, (would be set/delete)
Returns Raises a PolicyError, if the wrong attribute is given.
privacyidea.api.lib.prepolicy.check_external(request=None, action='init')
This decorator is a hook to an external check function, that is called before the token/init or token/assign API.
Parameters
• request (flask Request object) – The REST request
• action (basestring) – This is either “init” or “assign”
Returns either True or an Exception is raised
privacyidea.api.lib.prepolicy.check_max_token_realm(request=None, action=None)
Pre Policy This checks the maximum token per realm. Check ACTION.MAXTOKENREALM
This decorator can wrap: /token/init (with a realm and user) /token/assign /token/tokenrealms

Parameters

396 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

• req (Request Object) – The request that is intercepted during the API call
• action (basestring) – An optional Action
Returns True otherwise raises an Exception

privacyidea.api.lib.prepolicy.check_max_token_user(request=None, action=None)
Pre Policy This checks the maximum token per user policy. Check ACTION.MAXTOKENUSER Check AC-
TION.MAXACTIVETOKENUSER
This decorator can wrap: /token/init (with a realm and user) /token/assign

Parameters
• req –
• action –
Returns True otherwise raises an Exception

privacyidea.api.lib.prepolicy.check_otp_pin(request=None, action=None)
This policy function checks if the OTP PIN that is about to be set follows the OTP PIN policies AC-
TION.OTPPINMAXLEN, ACTION.OTPPINMINLEN and ACTION.OTPPINCONTENTS and token-type-
specific PIN policy actions in the SCOPE.USER or SCOPE.ADMIN. It is used to decorate the API functions.
The pin is investigated in the params as “otppin” or “pin”
In case the given OTP PIN does not match the requirements an exception is raised.
privacyidea.api.lib.prepolicy.check_token_init(request=None, action=None)
This decorator function takes the request and verifies if the requested tokentype is allowed to be enrolled in the
SCOPE ADMIN or the SCOPE USER. :param request: :param action: :return: True or an Exception is raised
privacyidea.api.lib.prepolicy.check_token_upload(request=None, action=None)
This decorator function takes the request and verifies the given action for scope ADMIN :param req: :param
filename: :return:
privacyidea.api.lib.prepolicy.encrypt_pin(request=None, action=None)
This policy function is to be used as a decorator for several API functions. E.g. token/assign, token/setpin, to-
ken/init If the policy is set to define the PIN to be encrypted, the request.all_data is modified like this: encryptpin
= True
It uses the policy SCOPE.ENROLL, ACTION.ENCRYPTPIN
privacyidea.api.lib.prepolicy.enroll_pin(request=None, action=None)
This policy function is used as decorator for init token. It checks, if the user or the admin is allowed to set a token
PIN during enrollment. If not, it deleted the PIN from the request.
privacyidea.api.lib.prepolicy.hide_audit_columns(request=None, action=None)
This pre condition checks for the policy hide_audit_columns and sets the “hidden_columns” parameter for the
audit search. The given columns will be removed from the returned audit dict.
Check ACTION.HIDE_AUDIT_COLUMNS
The decorator should wrap GET /audit/
Parameters
• request (Request Object) – The request that is intercepted during the API call
• action (basestring) – An optional Action
Returns Always true. Modified the parameter request

1.15. Code Documentation 397


privacyIDEA Authentication System, Release 3.8

privacyidea.api.lib.prepolicy.hide_tokeninfo(request=None, action=None)
This decorator checks for the policy hide_tokeninfo and sets the hidden_tokeninfo parameter.
The given tokeninfo keys will be removed from the response.
The decorator wraps GET /token/
Parameters
• request (Request Object) – The request that is intercepted during the API call
• action (str) – An optional Action
Returns Always true. Modifies the parameter request
Return type bool
privacyidea.api.lib.prepolicy.increase_failcounter_on_challenge(request=None, action=None)
This is a decorator for /validate/check, validate/triggerchallenge and auth which sets the parameter in-
crease_failcounter_on_challenge
privacyidea.api.lib.prepolicy.indexedsecret_force_attribute(request, action)
This is a token specific wrapper for indexedsecret token for the endpoint /token/init The otpkey is overwrit-
ten with the value from the user attribute specified in policy scope=SCOPE.USER and SCOPE.ADMIN, ac-
tion=PIIXACTION.FORCE_ATTRIBUTE. :param request: :param action: :return:
privacyidea.api.lib.prepolicy.init_ca_connector(request=None, action=None)
This is a pre decorator for the endpoint ‘/token/init’. It reads the policy scope=enrollment, ac-
tion=certificate_ca_connector and sets the API parameter “ca” accordingly.
Parameters request – The request to enhance
Returns None, but we modify the request
privacyidea.api.lib.prepolicy.init_ca_template(request=None, action=None)
This is a pre decorator for the endpoint ‘/token/init’. It reads the policy scope=enrollment, ac-
tion=certificate_template and sets the API parameter “template” accordingly.
Parameters request – The request to enhance
Returns None, but we modify the request
privacyidea.api.lib.prepolicy.init_random_pin(request=None, action=None)
This policy function is to be used as a decorator in the API init function If the policy is set accordingly it adds a
random PIN to the request.all_data like.
It uses the policy SCOPE.ENROLL, ACTION.OTPPINRANDOM and ACTION.OTPPINCONTENTS to set a
random OTP PIN during Token enrollment
privacyidea.api.lib.prepolicy.init_subject_components(request=None, action=None)
This is a pre decorator for the endpoint ‘/token/init’. It reads the policy scope=enrollment, ac-
tion=certificate_request_subject_component and sets the API parameter “subject_component” accordingly.
Parameters request – The request to enhance
Returns None, but we modify the request
privacyidea.api.lib.prepolicy.init_token_defaults(request=None, action=None)
This policy function is used as a decorator for the API init function. Depending on policy settings it can add
token specific default values like totp_hashlib, hotp_hashlib, totp_otplen. . .
privacyidea.api.lib.prepolicy.init_token_length_contents(request=None, action=None)
This policy function is to be used as a decorator in the API token init function.

398 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

It can set the parameters for automatic code or password created in regards to length and contents for the token-
types ‘registration’ and ‘pw’.
If there is a valid policy set the action values of REGISTRATIONCODE_LENGTH / PASSWORD_LENGTH
and REGISTRATIONCODE_CONTENTS / PASSWORD_CONTENTS are added to request.all_data as
{ ‘registration.length’: ‘10’, ‘registration.contents’: ‘cn’ } or { ‘pw.length’: ‘10’, ‘pw.contents’: ‘cn’ }
privacyidea.api.lib.prepolicy.init_tokenlabel(request=None, action=None)
This policy function is to be used as a decorator in the API init function. It adds the tokenlabel definition to the
params like this: params : { “tokenlabel”: “<u>@<r>” }
In addition it adds the tokenissuer to the params like this: params : { “tokenissuer”: “privacyIDEA instance” }
It also checks if the force_app_pin policy is set and adds the corresponding value to params.
It uses the policy SCOPE.ENROLL, ACTION.TOKENLABEL and ACTION.TOKENISSUER to set the token-
label and tokenissuer of Smartphone tokens during enrollment and this fill the details of the response.
privacyidea.api.lib.prepolicy.is_remote_user_allowed(req, write_to_audit_log=True)
Checks if the REMOTE_USER server variable is allowed to be used.

Note: This is not used as a decorator!

Parameters
• req – The flask request, containing the remote user and the client IP
• write_to_audit_log (bool) – whether the policy name should be added to the audit log
entry
Returns Return a value or REMOTE_USER, can be “disable”, “active” or “force”.
Return type str

privacyidea.api.lib.prepolicy.mangle(request=None, action=None)
This pre condition checks if either of the parameters pass, user or realm in a validate/check request should be
rewritten based on an authentication policy with action “mangle”. See mangle for an example.
Check ACTION.MANGLE
This decorator should wrap /validate/check

Parameters
• request (Request Object) – The request that is intercepted during the API call
• action (basestring) – An optional Action
Returns Always true. Modified the parameter request

privacyidea.api.lib.prepolicy.mock_fail(req, action)
This is a mock function as an example for check_external. This function creates a problem situation and the
token/init or token/assign will show this exception accordingly.
privacyidea.api.lib.prepolicy.mock_success(req, action)
This is a mock function as an example for check_external. This function returns success and the API call will go
on unmodified.

1.15. Code Documentation 399


privacyIDEA Authentication System, Release 3.8

privacyidea.api.lib.prepolicy.papertoken_count(request=None, action=None)
This is a token specific wrapper for paper token for the endpoint /token/init. According to the policy
scope=SCOPE.ENROLL, action=PAPERACTION.PAPER_COUNT it sets the parameter papertoken_count to
enroll a paper token with such many OTP values.
Parameters
• request –
• action –
Returns
class privacyidea.api.lib.prepolicy.prepolicy(function, request, action=None)
This is the decorator wrapper to call a specific function before an API call. The prepolicy decorator is to be used
in the API calls. A prepolicy decorator then will modify the request data or raise an exception
Parameters
• function (function) – This is the policy function the is to be called
• request (Request Object) – The original request object, that needs to be passed
privacyidea.api.lib.prepolicy.pushtoken_add_config(request, action)
This is a token specific wrapper for push token for the endpoint /token/init According to the policy
scope=SCOPE.ENROLL, action=SSL_VERIFY or action=FIREBASE_CONFIG the parameters are added to
the enrollment step. :param request: :param action: :return:
privacyidea.api.lib.prepolicy.pushtoken_disable_wait(request, action)
This is used for the /auth endpoint and sets the PUSH_ACTION.WAIT parameter to False.
Parameters
• request –
• action –
Returns
privacyidea.api.lib.prepolicy.pushtoken_wait(request, action)
This is a auth specific wrapper to decorate /validate/check According to the policy scope=SCOPE.AUTH, ac-
tion=push_wait
Parameters
• request –
• action –
Returns
privacyidea.api.lib.prepolicy.realmadmin(request=None, action=None)
This decorator adds the first REALM to the parameters if the administrator, calling this API is a realm admin.
This way, if the admin calls e.g. GET /user without realm parameter, he will not see all users, but only users in
one of his realms.
TODO: If a realm admin is allowed to see more than one realm, this is not handled at the moment. We need
to change the underlying library functions!

Parameters
• request – The HTTP reqeust
• action – The action like ACTION.USERLIST

400 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

privacyidea.api.lib.prepolicy.required_email(request=None, action=None)
This precondition checks if the “email” parameter matches the regular expression in the policy scope=register,
action=requiredemail. See requiredemail.
Check ACTION.REQUIREDEMAIL
This decorator should wrap POST /register
Parameters
• request – The Request Object
• action – An optional Action
Returns Modifies the request parameters or raises an Exception
privacyidea.api.lib.prepolicy.required_piv_attestation(request, action=None)
This is a token specific decorator for certificate tokens for the endpoint /token/init According to the policy
scope=SCOPE.ENROLL, action=REQUIRE_ATTESTATION an exception is raised, if no attestation param-
eter is given.
It also checks the policy if the attestation should be verified and sets the parameter verify_attestation accordingly.
Parameters
• request –
• action –
Returns
privacyidea.api.lib.prepolicy.save_client_application_type(request, action)
This decorator is used to write the client IP and the HTTP user agent ( clienttype) to the database.
In fact this is not a policy decorator, as it checks no policy. In fact, we could however one day define this as a
policy, too. :param req: :return:
privacyidea.api.lib.prepolicy.set_random_pin(request=None, action=None)
This policy function is to be used as a decorator in the API setrandompin function If the policy is set accordingly
it adds a random PIN to the request.all_data like.
It uses the policy ACTION.OTPPINSETRANDOM in SCOPE.ADMIN or SCOPE.USER to set a random OTP
PIN
privacyidea.api.lib.prepolicy.set_realm(request=None, action=None)
Pre Policy This pre condition gets the current realm and verifies if the realm should be rewritten due to the policy
definition. I takes the realm from the request and - if a policy matches - replaces this realm with the realm defined
in the policy
Check ACTION.SETREALM
This decorator should wrap /validate/check

Parameters
• request (Request Object) – The request that is intercepted during the API call
• action (basestring) – An optional Action
Returns Always true. Modified the parameter request

privacyidea.api.lib.prepolicy.sms_identifiers(request=None, action=None)
This is a token specific wrapper for sms tokens to be used with the endpoint /token/init. According to the policy
scope=SCOPE.ADMIN or scope=SCOPE.USER action=SMSACTION.GATEWAYS the sms.identifier is only
allowed to be set to the listed gateways.

1.15. Code Documentation 401


privacyIDEA Authentication System, Release 3.8

Parameters
• request –
• action –
Returns
privacyidea.api.lib.prepolicy.tantoken_count(request=None, action=None)
This is a token specific wrapper for tan token for the endpoint /token/init. According to the policy
scope=SCOPE.ENROLL, action=TANACTION.TANTOKEN_COUNT it sets the parameter tantoken_count to
enroll a tan token with such many OTP values.
Parameters
• request –
• action –
Returns
privacyidea.api.lib.prepolicy.twostep_enrollment_activation(request=None, action=None)
This policy function enables the two-step enrollment process according to the configured policies. It is used to
decorate the /token/init endpoint.
If a <type>_2step policy matches, the 2stepinit parameter is handled according to the policy. If no policy
matches, the 2stepinit parameter is removed from the request data.
privacyidea.api.lib.prepolicy.twostep_enrollment_parameters(request=None, action=None)
If the 2stepinit parameter is set to true, this policy function reads additional configuration from policies and
adds it to request.all_data, that is:
• {type}_2step_serversize is written to 2step_serversize
• {type}_2step_clientsize is written to 2step_clientsize
• {type}_2step_difficulty is written to 2step_difficulty
If no policy matches, the value passed by the user is kept.
This policy function is used to decorate the /token/init endpoint.
privacyidea.api.lib.prepolicy.u2ftoken_allowed(request, action)

This is a token specific wrapper for u2f token for the endpoint /token/init. According to the policy
scope=SCOPE.ENROLL, action=U2FACTION.REQ it checks, if the assertion certificate is an allowed
U2F token type.
If the token, which is enrolled contains a non allowed attestation certificate, we bail out.

Parameters
• request –
• action –
Returns

privacyidea.api.lib.prepolicy.u2ftoken_verify_cert(request, action)
This is a token specific wrapper for u2f token for the endpoint /token/init According to the policy
scope=SCOPE.ENROLL, action=U2FACTION.NO_VERIFY_CERT it can add a parameter to the enrollment
parameters to not verify the attestation certificate. The default is to verify the cert. :param request: :param action:
:return:

402 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

privacyidea.api.lib.prepolicy.verify_enrollment(request=None, action=None)
This is used to verify an already enrolled token. The parameter “verify” is used to do so. If successful, the current
rollout_state “verify” of the token will be changed to “enrolled”.
Parameters
• request –
• action –
Returns
privacyidea.api.lib.prepolicy.webauthntoken_allowed(request, action)
This is a token specific wrapper for WebAuthn token for the endpoint /token/init.
According to the policy scope=SCOPE.ENROLL, action=WEBAUTHNACTION.REQ it checks, if the asser-
tion certificate is for an allowed WebAuthn token type. According to the policy scope=SCOPE.ENROLL,
action=WEBAUTHNACTION.AUTHENTICATOR_SELECTION_LIST it checks, whether the AAGUID is
whitelisted. Note: If self-attestation is allowed, it is – of course – possible to bypass the check for WEBAU-
THNACTION.REQ
If the token, which is being enrolled does not contain an allowed attestation certificate, or does not have an
allowed AAGUID, we bail out.
A very similar check (same policy actions, different policy scope) is performed during authorization, however
due to architectural limitations, this lives within the token implementation itself.
Parameters
• request –
• action –
Returns
Return type
privacyidea.api.lib.prepolicy.webauthntoken_auth(request, action)
This is a WebAuthn token specific wrapper for the endpoints /validate/triggerchallenge, /validate/check, and
/auth.
This will enrich the challenge creation request for WebAuthn tokens with the necessary configuration information
from policy actions with scope=SCOPE.AUTH. The request will be augmented with the allowed transports and
the text to display to the user when asking to confirm the challenge on the token, as specified by the actions
WEBAUTHNACTION.ALLOWED_TRANSPORTS, and ACTION.CHALLENGETEXT, respectively.
Both of these policies are optional, and have sensible defaults.
Parameters
• request –
• action –
Returns
Return type
privacyidea.api.lib.prepolicy.webauthntoken_authz(request, action)
This is a WebAuthn token specific wrapper for the /auth, and /validate/check endpoints.
This will enrich the authorization request for WebAuthn tokens with the necessary configuration information
from policy actions with scope=SCOPE.AUTHZ. This is currently the authorization pendant to webauthnto-
ken_allowed(), but maybe expanded to cover other authorization policies in the future, should any be added. The
request will as of now simply be augmented with the policies the attestation certificate is to be matched against.

1.15. Code Documentation 403


privacyIDEA Authentication System, Release 3.8

Parameters
• request –
• action –
Returns
Return type
privacyidea.api.lib.prepolicy.webauthntoken_enroll(request, action)
This is a token specific wrapper for the WebAuthn token for the endpoint /token/init.
This will enrich the initialization request for WebAuthn tokens with the necessary configuration information
from policy actions with scope=SCOPE.ENROLL. The request will be augmented with a name and id for
the relying party, as specified by the with actions WEBAUTHNACTION.RELYING_PARTY_NAME and
WEBAUTHNACTION.RELYING_PARTY_ID, respectively, authenticator attachment preference, public
key credential algorithm preferences, authenticator attestation requirement level, authenticator attestation
requirement form, allowed AAGUIDs, and the text to display to the user when asking to confirm the challenge
on the token, as specified by the actions WEBAUTHNACTION.AUTHENTICATOR_ATTACHMENT,
WEBAUTHNACTION.PUBLIC_KEY_CREDENTIAL_ALGORITHM_PREFERENCE,
WEBAUTHNACTION.AUTHENTICATOR_ATTESTATION_LEVEL, WEBAU-
THNACTION.AUTHENTICATOR_ATTESTATION_FORM, WEAUTHNAC-
TION.AVOID_DOUBLE_REGISTRATION, WEBAUTHNACTION.AUTHENTICATOR_SELECTION_LIST,
and ACTION.CHALLENGETEXT, respectively.
Setting WEBAUTHNACTION.RELYING_PARTY_NAME and WEBAUTHNAC-
TION.RELYING_PARTY_ID is mandatory, and if either of these is not set, we bail out.
Parameters
• request –
• action –
Returns
Return type
privacyidea.api.lib.prepolicy.webauthntoken_request(request, action)
This is a WebAuthn token specific wrapper for all endpoints using WebAuthn tokens.
This wraps the endpoints /token/init, /validate/triggerchallenge, /auth, and /validate/check. It will add WebAuthn
configuration information to the requests, wherever a piece of information is needed for several different requests
and thus cannot be provided by one of the more specific wrappers without adding unnecessary redundancy.
Depending on the type of request, the request will be augmented with some (or all) of the
authenticator timeout, user verification requirement and list of allowed AAGUIDs for the current
scope, as specified by the policies with the determined scope and the actions WEBAUTHNAC-
TION.TIMEOUT, WEBAUTHNACTION.USER_VERIFICATION_REQUIREMENT, and WEBAUTHNAC-
TION.AUTHENTICATOR_SELECTION_LIST, respectively.
The value of the ORIGIN http header will also be added to the request for the ENROLL and AUTHZ scopes.
This is to make the unit tests not require mocking.
Parameters
• request –
• action –
Returns
Return type

404 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Post Policies

These are the policy decorators as POST conditions for the API calls. I.e. these conditions are executed after the
wrapped API call. This module uses the policy base functions from privacyidea.lib.policy but also components from
flask like g.
Wrapping the functions in a decorator class enables easy modular testing.
The functions of this module are tested in tests/test_api_lib_policy.py
privacyidea.api.lib.postpolicy.add_user_detail_to_response(request, response)
This policy decorated is used in the AUTHZ scope. If the boolean value add_user_in_response is set, the details
will contain a dictionary “user” with all user details.
Parameters
• request –
• response –
Returns
privacyidea.api.lib.postpolicy.autoassign(request, response)
This decorator decorates the function /validate/check. Depending on ACTION.AUTOASSIGN it checks if the
user has no token and if the given OTP-value matches a token in the users realm, that is not yet assigned to any
user.
If a token can be found, it assigns the token to the user also taking into account ACTION.MAXTOKENUSER
and ACTION.MAXTOKENREALM. :return:
privacyidea.api.lib.postpolicy.check_serial(request, response)
This policy function is to be used in a decorator of an API function. It checks, if the token, that was used in the
API call has a serial number that is allowed to be used.
If not, a PolicyException is raised.
Parameters response (Response object) – The response of the decorated function
Returns A new (maybe modified) response
privacyidea.api.lib.postpolicy.check_tokeninfo(request, response)
This policy function is used as a decorator for the validate API. It checks after a successful authentication if the
token has a matching tokeninfo field. If it does not match, authorization is denied. Then a PolicyException is
raised.
Parameters response (Response object) – The response of the decorated function
Returns A new modified response
privacyidea.api.lib.postpolicy.check_tokentype(request, response)
This policy function is to be used in a decorator of an API function. It checks, if the token, that was used in the
API call is of a type that is allowed to be used.
If not, a PolicyException is raised.
Parameters response (Response object) – The response of the decorated function
Returns A new (maybe modified) response
privacyidea.api.lib.postpolicy.check_verify_enrollment(request, response)
This policy decorator is used in the ENROLL scope to decorate the /token/init It will check for ac-
tion=verify_enrollment and ask the user in a 2nd step to provide information to verify, that the token was suc-
cessfully enrolled.
Parameters

1.15. Code Documentation 405


privacyIDEA Authentication System, Release 3.8

• request –
• response –
Returns
privacyidea.api.lib.postpolicy.construct_radius_response(request, response)
This decorator implements the /validate/radiuscheck endpoint. In case this URL was requested, a successful
authentication results in an empty response with a HTTP 204 status code. An unsuccessful authentication results
in an empty response with a HTTP 400 status code. :return:
privacyidea.api.lib.postpolicy.get_webui_settings(request, response)
This decorator is used in the /auth API to add configuration information like the logout_time or the pol-
icy_template_url to the response. :param request: flask request object :param response: flask response object
:return: the response
privacyidea.api.lib.postpolicy.is_authorized(request, response)
This policy decorator is used in the AUTHZ scope to decorate the /validate/check and /validate/triggerchallenge
endpoint. It will cause authentication to fail, if the policy authorized=deny_access is set.
Parameters
• request –
• response –
Returns
privacyidea.api.lib.postpolicy.mangle_challenge_response(request, response)
This policy decorator is used in the AUTH scope to decorate the /validate/check endpoint. It can modify the
contents of the response “detail”->”message” to allow a better readability for a challenge response text.
Parameters
• request –
• response –
Returns
privacyidea.api.lib.postpolicy.multichallenge_enroll_via_validate(request, response)
This is a post decorator to allow enrolling tokens via /validate/check. It checks the AUTH policy EN-
ROLL_VIA_MULTICHALLENGE and enrolls the corresponding token type. It also modifies the response
accordingly, so that the client/plugin can display necessary data for the enrollment to the user.
Parameters
• request –
• response –
Returns
privacyidea.api.lib.postpolicy.no_detail_on_fail(request, response)
This policy function is used with the AUTHZ scope. If the boolean value no_detail_on_fail is set, the details
will be stripped if the authentication request failed.
Parameters
• request –
• response –
Returns

406 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

privacyidea.api.lib.postpolicy.no_detail_on_success(request, response)
This policy function is used with the AUTHZ scope. If the boolean value no_detail_on_success is set, the details
will be stripped if the authentication request was successful.
Parameters
• request –
• response –
Returns
privacyidea.api.lib.postpolicy.offline_info(request, response)
This decorator is used with the function /validate/check. It is not triggered by an ordinary policy but by a Ma-
chineToken definition. If for the given Token an offline application is defined, the response is enhanced with the
offline information - the hashes of the OTP.
class privacyidea.api.lib.postpolicy.postpolicy(function, request=None)
Decorator that allows one to call a specific function after the decorated function. The postpolicy decorator is to
be used in the API calls.
Parameters
• function (function) – This is the policy function the is to be called
• request (Request Object) – The original request object, that needs to be passed
class privacyidea.api.lib.postpolicy.postrequest(function, request=None)
Decorator that is supposed to be used with after_request.
Parameters
• function (function) – This is the policy function the is to be called
• request (Request Object) – The original request object, that needs to be passed
privacyidea.api.lib.postpolicy.preferred_client_mode(request, response)
This policy function is used to add the preferred client mode. The admin can set the list of client modes in the
policy in the same order as he preferred them. The faction will pick the first client mode from the list, that is also
in the multichallenge and set it as preferred client mode
Parameters
• request –
• response –
Returns
privacyidea.api.lib.postpolicy.save_pin_change(request, response, serial=None)
This policy function checks if the next_pin_change date should be stored in the tokeninfo table.
1. Check scope:enrollment and ACTION.CHANGE_PIN_FIRST_USE. This action is used, when the admin-
istrator enrolls a token or sets a PIN
2. Check scope:enrollment and ACTION.CHANGE_PIN_EVERY is used, if the user changes the PIN.
This function decorates /token/init and /token/setpin. The parameter “pin” and “otppin” is investigated.
Parameters
• request –
• action –
Returns

1.15. Code Documentation 407


privacyIDEA Authentication System, Release 3.8

privacyidea.api.lib.postpolicy.sign_response(request, response)
This decorator is used to sign the response. It adds the nonce from the request, if it exist and adds the nonce and
the signature to the response.

Note: This only works for JSON responses. So if we fail to decode the JSON, we just pass on.

The usual way to use it is, to wrap the after_request, so that we can also sign errors.
@postrequest(sign_response, request=request) def after_request(response):
Parameters
• request – The Request object
• response – The Response object

Policy Decorators

These are the policy decorator functions for internal (lib) policy decorators. policy decorators for the API (pre/post)
are defined in api/lib/policy
The functions of this module are tested in tests/test_lib_policy_decorator.py
privacyidea.lib.policydecorators.auth_cache(wrapped_function, user_object, passw, options=None)
Decorate lib.token:check_user_pass. Verify, if the authentication can be found in the auth_cache.
Parameters
• wrapped_function – usually “check_user_pass”
• user_object – User who tries to authenticate
• passw – The PIN and OTP
• options – Dict containing values for “g” and “clientip”.
Returns Tuple of True/False and reply-dictionary
privacyidea.lib.policydecorators.auth_lastauth(wrapped_function, user_or_serial, passw,
options=None)
This decorator checks the policy settings of ACTION.LASTAUTH If the last authentication stored in tokeninfo
last_auth_success of a token is exceeded, the authentication is denied.
The wrapped function is usually token.check_user_pass, which takes the arguments (user, passw, options={})
OR token.check_serial_pass with the arguments (user, passw, options={})
Parameters
• wrapped_function – either check_user_pass or check_serial_pass
• user_or_serial – either the User user_or_serial or a serial
• passw –
• options – Dict containing values for “g” and “clientip”
Returns Tuple of True/False and reply-dictionary
privacyidea.lib.policydecorators.auth_otppin(wrapped_function, *args, **kwds)
Decorator to decorate the tokenclass.check_pin function.
Depending on the ACTION.OTPPIN it

408 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

• either simply accepts an empty pin


• checks the pin against the userstore
• or passes the request to the wrapped_function

Parameters
• wrapped_function – In this case the wrapped function should be privacyidea.lib.
tokenclass.TokenClass.check_pin()
• *args – args[1] is the pin
• **kwds – kwds[“options”] contains the flask g
Returns True or False

privacyidea.lib.policydecorators.auth_user_does_not_exist(wrapped_function, user_object, passw,


options=None)
This decorator checks, if the user does exist at all. If the user does exist, the wrapped function is called.
The wrapped function is usually token.check_user_pass, which takes the arguments (user, passw, options={})
Parameters
• wrapped_function –
• user_object –
• passw –
• options – Dict containing values for “g” and “clientip”
Returns Tuple of True/False and reply-dictionary
privacyidea.lib.policydecorators.auth_user_has_no_token(wrapped_function, user_object, passw,
options=None)
This decorator checks if the user has a token at all. If the user has a token, the wrapped function is called.
The wrapped function is usually token.check_user_pass, which takes the arguments (user, passw, options={})
Parameters
• wrapped_function –
• user_object –
• passw –
• options – Dict containing values for “g” and “clientip”
Returns Tuple of True/False and reply-dictionary
privacyidea.lib.policydecorators.auth_user_passthru(wrapped_function, user_object, passw,
options=None)
This decorator checks the policy settings of ACTION.PASSTHRU. If the authentication against the userstore is
not successful, the wrapped function is called.
The wrapped function is usually token.check_user_pass, which takes the arguments (user, passw, options={})
Parameters
• wrapped_function –
• user_object –
• passw –

1.15. Code Documentation 409


privacyIDEA Authentication System, Release 3.8

• options – Dict containing values for “g” and “clientip”


Returns Tuple of True/False and reply-dictionary
privacyidea.lib.policydecorators.auth_user_timelimit(wrapped_function, user_object, passw,
options=None)
This decorator checks the policy settings of ACTION.AUTHMAXSUCCESS, ACTION.AUTHMAXFAIL If
the authentication was successful, it checks, if the number of allowed successful authentications is exceeded
(AUTHMAXSUCCESS).
If the AUTHMAXFAIL is exceed it denies even a successful authentication.
The wrapped function is usually token.check_user_pass, which takes the arguments (user, passw, options={})
Parameters
• wrapped_function –
• user_object –
• passw –
• options – Dict containing values for “g” and “clientip”
Returns Tuple of True/False and reply-dictionary
privacyidea.lib.policydecorators.challenge_response_allowed(func)
This decorator is used to wrap tokenclass.is_challenge_request. It checks, if a challenge response authentication
is allowed for this token type. To allow this, the policy
scope:authentication, action:challenge_response must be set.
If the tokentype is not allowed for challenge_response, this decorator returns false.
See challenge_response.
Parameters func – wrapped function
privacyidea.lib.policydecorators.config_lost_token(wrapped_function, *args, **kwds)
Decorator to decorate the lib.token.lost_token function. Depending on ACTION.LOSTTOKENVALID, AC-
TION.LOSTTOKENPWCONTENTS, ACTION.LOSTTOKENPWLEN it sets the check_otp parameter, to sig-
nal how the lostToken should be generated.
Parameters
• wrapped_function – Usually the function lost_token()
• *args – argument “serial” as the old serial number
• **kwds – keyword arguments like “validity”, “contents”, “pw_len” kwds[“options”] con-
tains the flask g
Returns calls the original function with the modified “validity”, “contents” and “pw_len” argument
class privacyidea.lib.policydecorators.libpolicy(decorator_function)
This is the decorator wrapper to call a specific function before a library call in contrast to prepolicy and postpolicy,
which are to be called in API Calls.
The decorator expects a named parameter “options”. In this options dict it will look for the flask global “g”.
Parameters decorator_function – This is the policy function that is to be
called :type decorator_function: function
privacyidea.lib.policydecorators.login_mode(wrapped_function, *args, **kwds)
Decorator to decorate the lib.auth.check_webui_user function. Depending on ACTION.LOGINMODE it sets
the check_otp parameter, to signal that the authentication should be performed against privacyIDEA.

410 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Parameters
• wrapped_function – Usually the function check_webui_user
• *args – arguments user_obj and password
• **kwds – keyword arguments like options and !check_otp! kwds[“options”] contains the
flask g
Returns calls the original function with the modified “check_otp” argument
privacyidea.lib.policydecorators.reset_all_user_tokens(wrapped_function, *args, **kwds)
Resets all tokens if the corresponding policy is set.
Parameters
• token – The successful token, the tokenowner is used to find policies.
• tokenobject_list – The list of all the tokens of the user
• options – options dictionary containing g.
Returns None

Event Handler

The following event handlers are known to privacyIDEA

Event Handler Base Class

class privacyidea.lib.eventhandler.base.BaseEventHandler
An Eventhandler needs to return a list of actions, which it can handle.
It also returns a list of allowed action and conditions
It returns an identifier, which can be used in the eventhandlig definitions
property actions
This method returns a list of available actions, that are provided by this event handler. :return: dictionary
of actions.
property allowed_positions
This returns the allowed positions of the event handler definition. This can be “post” or “pre” or both.
:return: list of allowed positions
check_condition(options)
Check if all conditions are met and if the action should be executed. The the conditions are met, we return
“True” :return: True
property conditions
The UserNotification can filter for conditions like * type of logged in user and * successful or failed
value.success
allowed types are str, multi, text, regexp
Returns dict
description = 'This is the base class of an EventHandler with no functionality'
do(action, options=None)
This method executes the defined action in the given event.

1.15. Code Documentation 411


privacyIDEA Authentication System, Release 3.8

Parameters
• action –
• options (dict) – Contains the flask parameters g and request and the handler_def con-
figuration
Returns
property events
This method returns a list allowed events, that this event handler can be bound to and which it can handle
with the corresponding actions.
An eventhandler may return an asterisk [“*”] indicating, that it can be used in all events. :return: list of
events
identifier = 'BaseEventHandler'

User Notification Event Handler

class privacyidea.lib.eventhandler.usernotification.UserNotificationEventHandler
An Eventhandler needs to return a list of actions, which it can handle.
It also returns a list of allowed action and conditions
It returns an identifier, which can be used in the eventhandling definitions
property actions
This method returns a dictionary of allowed actions and possible options in this handler module.
Returns dict with actions
property allowed_positions
This returns the allowed positions of the event handler definition. :return: list of allowed positions
description = 'This eventhandler notifies the user about actions on his tokens'
do(action, options=None)
This method executes the defined action in the given event.
Parameters
• action –
• options (dict) – Contains the flask parameters g, request, response and the handler_def
configuration
Returns
identifier = 'UserNotification'
class privacyidea.lib.event.EventConfiguration
This class is supposed to contain the event handling configuration during the Request. The currently defined
events are fetched from the request-local config object.
property events
Shortcut for retrieving the currently defined event handlers from the request-local config object.
get_event(eventid)
Return the reduced list with the given eventid. This list should only have one element.
Parameters eventid (int or None) – id of the event
Returns list with one element

412 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

get_handled_events(eventname, position='post')
Return a list of the event handling definitions for the given eventname and the given position.
Parameters
• eventname – The name of the event
• position – the position of the event definition
Returns
privacyidea.lib.event.delete_event(event_id)
Delete the event configuration with this given ID. :param event_id: The database ID of the event. :type event_id:
int :return:
privacyidea.lib.event.enable_event(event_id, enable=True)
Enable or disable the and event :param event_id: ID of the event :return:
class privacyidea.lib.event.event(eventname, request, g)
This is the event decorator that calls the event handler in the handler module. This event decorator can be used
at any API call
privacyidea.lib.event.export_event(name=None)
Export given or all event configuration
privacyidea.lib.event.get_handler_object(handlername)
Return an event handler object based on the Name of the event handler class
Parameters handlername – The identifier of the Handler Class
Returns
privacyidea.lib.event.import_event(data, name=None)
Import policy configuration
privacyidea.lib.event.set_event(name=None, event=None, handlermodule=None, action=None,
conditions=None, ordering=0, options=None, id=None, active=True,
position='post')
Set an event handling configuration. This writes an entry to the database eventhandler.
Parameters
• name – The name of the event definition
• event (basestring) – The name of the event to react on. Can be a single event or a comma
separated list.
• handlermodule (basestring) – The identifier of the event handler module. This is an
identifier string like “UserNotification”
• action (basestring) – The action to perform. This is an action defined by the handler
module
• conditions (dict) – A condition. Only if this condition is met, the action is performed.
• ordering (integer) – An optional ordering of the event definitions.
• options (dict) – Additional options, that are needed as parameters for the action
• id (int) – The DB id of the event. If the id is given, the event is updated. Otherwise a new
entry is generated.
• position (basestring) – The position of the event handler being “post” or “pre”
Returns The id of the event.

1.15. Code Documentation 413


privacyIDEA Authentication System, Release 3.8

SMS Provider

The following SMS providers are know to privacyIDEA

HTTP SMS Provider

class privacyidea.lib.smsprovider.HttpSMSProvider.HttpSMSProvider(db_smsprovider_object=None,
smsgateway=None)
Create a new SMS Provider object fom a DB SMS provider object
Parameters
• db_smsprovider_object – The database object
• smsgateway – The SMS gateway object from the database table SMS gateway. The options
can be accessed via self.smsgateway.option_dict
Returns An SMS provider object
classmethod parameters()
Return a dictionary, that describes the parameters and options for the SMS provider. Parameters are required
keys to values.
Returns dict
submit_message(phone, message)
send a message to a phone via an http sms gateway
Parameters
• phone – the phone number
• message – the message to submit to the phone
Returns

Sipgate SMS Provider

class privacyidea.lib.smsprovider.SipgateSMSProvider.SipgateSMSProvider(db_smsprovider_object=None,
smsgateway=None)
Create a new SMS Provider object fom a DB SMS provider object
Parameters
• db_smsprovider_object – The database object
• smsgateway – The SMS gateway object from the database table SMS gateway. The options
can be accessed via self.smsgateway.option_dict
Returns An SMS provider object
classmethod parameters()
Return a dictionary, that describes the parameters and options for the SMS provider. Parameters are required
keys to values.
Returns dict
submit_message(phone, message)
Sends the SMS. It should return a bool indicating if the SMS was sent successfully.
In case of SMS send fail, an Exception should be raised. :return: Success :rtype: bool

414 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

SMTP SMS Provider

class privacyidea.lib.smsprovider.SmtpSMSProvider.SmtpSMSProvider(db_smsprovider_object=None,
smsgateway=None)
Create a new SMS Provider object fom a DB SMS provider object
Parameters
• db_smsprovider_object – The database object
• smsgateway – The SMS gateway object from the database table SMS gateway. The options
can be accessed via self.smsgateway.option_dict
Returns An SMS provider object
classmethod parameters()
Return a dictionary, that describes the parameters and options for the SMS provider. Parameters are required
keys to values.
Returns dict
submit_message(phone, message)
Submits the message for phone to the email gateway.
Returns true in case of success
In case of a failure an exception is raised
SMSProvider is the base class for submitting SMS. It provides 3 different implementations:
• HTTP: submitting SMS via an HTTP gateway of an SMS provider
• SMTP: submitting SMS via an SMTP gateway of an SMS provider
• Sipgate: submitting SMS via Sipgate service

Base Class

class privacyidea.lib.smsprovider.SMSProvider.ISMSProvider(db_smsprovider_object=None,
smsgateway=None)
the SMS Provider Interface - BaseClass
Create a new SMS Provider object fom a DB SMS provider object
Parameters
• db_smsprovider_object – The database object
• smsgateway – The SMS gateway object from the database table SMS gateway. The options
can be accessed via self.smsgateway.option_dict
Returns An SMS provider object
check_configuration()
This method checks the sanity of the configuration of this provider. If there is a configuration error, than
an exception is raised. :return:
load_config(config_dict)
Load the configuration dictionary
Parameters config_dict (dict) – The conifugration of the SMS provider
Returns None

1.15. Code Documentation 415


privacyIDEA Authentication System, Release 3.8

classmethod parameters()
Return a dictionary, that describes the parameters and options for the SMS provider. Parameters are required
keys to values with defined keys, while options can be any combination.
Each option is the key to another dict, that describes this option, if it is required, a description and which
values it can take. The values are optional.
Additional options can not be named in advance. E.g. some provider specific HTTP parameters of HTTP
gateways are options. The HTTP parameter for the SMS text could be “text” at one provider and “sms” at
another one.
The options can be fixed values or also take the tags {otp}, {user}, {phone}.
Returns dict
submit_message(phone, message)
Sends the SMS. It should return a bool indicating if the SMS was sent successfully.
In case of SMS send fail, an Exception should be raised. :return: Success :rtype: bool

UserIdResolvers

The useridresolver is responsible for getting userids for loginnames and vice versa.
This base module contains the base class UserIdResolver.UserIdResolver and also the community class PasswdIdRe-
solver.IdResolver, that is inherited from the base class.

Base class

class privacyidea.lib.resolvers.UserIdResolver.UserIdResolver

add_user(attributes=None)
Add a new user in the useridresolver. This is only possible, if the UserIdResolver supports this and if we
have write access to the user store.
Parameters
• username (basestring) – The login name of the user
• attributes – Attributes according to the attribute mapping
Returns The new UID of the user. The UserIdResolver needs to
determine the way how to create the UID.
checkPass(uid, password)
This function checks the password for a given uid. returns true in case of success false if password does
not match
Parameters
• uid (string or int) – The uid in the resolver
• password (string) – the password to check. Usually in cleartext
Returns True or False
Return type bool
close()
Hook to close down the resolver after one request

416 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

delete_user(uid)
Delete a user from the useridresolver. The user is referenced by the user id. :param uid: The uid of the user
object, that should be deleted. :type uid: basestring :return: Returns True in case of success :rtype: bool
property editable
Return true, if the Instance! of this resolver is configured editable. :return:
classmethod getResolverClassDescriptor()
return the descriptor of the resolver, which is - the class name and - the config description
Returns resolver description dict
Return type dict
static getResolverClassType()
provide the resolver type for registration
static getResolverDescriptor()
return the descriptor of the resolver, which is - the class name and - the config description
Returns resolver description dict
Return type dict
getResolverId()
get resolver specific information :return: the resolver identifier string - empty string if not exist
static getResolverType()
getResolverType - return the type of the resolver
Returns returns the string ‘ldapresolver’
Return type string
getUserId(loginName)
The loginname is resolved to a user_id. Depending on the resolver type the user_id can be an ID (like in
/etc/passwd) or a string (like the DN in LDAP)
It needs to return an empty string, if the user does not exist.
Parameters loginName (sting) – The login name of the user
Returns The ID of the user
Return type str
getUserInfo(userid)
This function returns all user information for a given user object identified by UserID. :param userid: ID
of the user in the resolver :type userid: int or string :return: dictionary, if no object is found, the dictionary
is empty :rtype: dict
getUserList(searchDict=None)
This function finds the user objects, that have the term ‘value’ in the user object field ‘key’
Parameters searchDict (dict) – dict with key values of user attributes - the key may be some-
thing like ‘loginname’ or ‘email’ the value is a regular expression.
Returns list of dictionaries (each dictionary contains a user object) or an empty string if no object
is found.
Return type list of dicts
getUsername(userid)
Returns the username/loginname for a given userid :param userid: The userid in this resolver :type userid:
string :return: username :rtype: string

1.15. Code Documentation 417


privacyIDEA Authentication System, Release 3.8

property has_multiple_loginnames
Return if this resolver has multiple loginname attributes :return: bool
loadConfig(config)
Load the configuration from the dict into the Resolver object. If attributes are missing, need to set default
values. If required attributes are missing, this should raise an Exception.
Parameters config (dict) – The configuration values of the resolver
classmethod testconnection(param)
This function lets you test if the parameters can be used to create a working resolver. The implementation
should try to connect to the user store and verify if users can be retrieved. In case of success it should return
a text like “Resolver config seems OK. 123 Users found.”
Parameters param (dict) – The parameters that should be saved as the resolver
Returns returns True in case of success and a descriptive text
Return type tuple
update_user(uid, attributes=None)
Update an existing user. This function is also used to update the password. Since the attribute mapping
know, which field contains the password, this function can also take care for password changing.
Attributes that are not contained in the dict attributes are not modified.
Parameters
• uid (basestring) – The uid of the user object in the resolver.
• attributes (dict) – Attributes to be updated.
Returns True in case of success

PasswdResolver

class privacyidea.lib.resolvers.PasswdIdResolver.IdResolver
simple constructor
checkPass(uid, password)
This function checks the password for a given uid. returns true in case of success false if password does
not match
We do not support shadow passwords. so the seconds column of the passwd file needs to contain the
encrypted password
If the password is a unicode object, it is encoded according to ENCODING first.
Parameters
• uid (int) – The uid of the user
• password (sting) – The password in cleartext
Returns True or False
Return type bool
checkUserId(line, pattern)
Check if a userid matches a pattern. A pattern can be “=1000”, “>=1000”, “<2000” or “between
1000,2000”.
Parameters

418 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

• line (dict) – the dictionary of a user


• pattern (string) – match pattern with <, <=. . .
Returns True or False
Return type bool
checkUserName(line, pattern)
check for user name
classmethod getResolverClassDescriptor()
return the descriptor of the resolver, which is - the class name and - the config description
Returns resolver description dict
Return type dict
static getResolverClassType()
provide the resolver type for registration
static getResolverDescriptor()
return the descriptor of the resolver, which is - the class name and - the config description
Returns resolver description dict
Return type dict
getResolverId()
return the resolver identifier string, which in fact is filename, where it points to.
static getResolverType()
getResolverType - return the type of the resolver
Returns returns the string ‘ldapresolver’
Return type string
getSearchFields(searchDict=None)
show, which search fields this userIdResolver supports
TODO: implementation is not completed
Parameters searchDict (dict) – fields, which can be queried
Returns dict of all searchFields
Return type dict
getUserId(LoginName)
search the user id from the login name
Parameters LoginName – the login of the user (as unicode)
Returns the userId
Return type str
getUserInfo(userId, no_passwd=False)
get some info about the user as we only have the loginId, we have to traverse the dict for the value
Parameters
• userId – the to be searched user
• no_passwd – return no password
Returns dict of user info

1.15. Code Documentation 419


privacyIDEA Authentication System, Release 3.8

getUserList(searchDict=None)
get a list of all users matching the search criteria of the searchdict
Parameters searchDict – dict of search expressions
getUsername(userId)
Returns the username/loginname for a given userid :param userid: The userid in this resolver :type userid:
string :return: username :rtype: str
loadConfig(configDict)
The UserIdResolver could be configured from the pylons app config - here this could be the passwd file ,
whether it is /etc/passwd or /etc/shadow
loadFile()
Loads the data of the file initially. if the self.fileName is empty, it loads /etc/passwd. Empty lines are
ignored.
static setup(config=None, cache_dir=None)
this setup hook is triggered, when the server starts to serve the first request
Parameters config (the privacyidea config dict) – the privacyidea config

LDAPResolver

class privacyidea.lib.resolvers.LDAPIdResolver.IdResolver

add_user(attributes=None)
Add a new user to the LDAP directory. The user can only be created in the LDAP using a DN. So we have
to construct the DN out of the given attributes.
attributes are these “username”, “surname”, “givenname”, “email”, “mobile”, “phone”, “password”
Parameters attributes (dict) – Attributes according to the attribute mapping
Returns The new UID of the user. The UserIdResolver needs to
determine the way how to create the UID.
checkPass(uid, password)
This function checks the password for a given uid. - returns true in case of success - false if password does
not match
static create_connection(authtype=None, server=None, user=None, password=None,
auto_bind='NONE', client_strategy='SYNC', check_names=True,
auto_referrals=False, receive_timeout=5, start_tls=False, keytabfile=None)
Create a connection to the LDAP server.
Parameters
• authtype –
• server –
• user –
• password –
• auto_bind –
• client_strategy –
• check_names –

420 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

• auto_referrals –
• receive_timeout (float) – At the moment we do not use this, since receive_timeout is
not supported by ldap3 < 2
• start_tls (bool) – Use startTLS for connection to server
• keytabfile (str) – Path to keytab file for service account
Returns
classmethod create_serverpool(urilist, timeout, get_info=None, tls_context=None, rounds=2,
exhaust=30, pool_cls=<class 'ldap3.core.pooling.ServerPool'>)
This create the serverpool for the ldap3 connection. The URI from the LDAP resolver can contain a comma
separated list of LDAP servers. These are split and then added to the pool.
See https://github.com/cannatag/ldap3/blob/master/docs/manual/source/servers.rst#server-pool
Parameters
• urilist (basestring) – The list of LDAP URIs, comma separated
• timeout (float) – The connection timeout
• get_info – The get_info type passed to the ldap3.Sever constructor. default:
ldap3.SCHEMA, should be ldap3.NONE in case of a bind.
• tls_context – A ldap3.tls object, which defines if certificate verification should be per-
formed
• rounds – The number of rounds we should cycle through the server pool before giving up
• exhaust – The seconds, for how long a non-reachable server should be removed from the
serverpool
• pool_cls – ldap3.ServerPool subclass that should be instantiated
Returns Server Pool
Return type serverpool_cls
delete_user(uid)
Delete a user from the LDAP Directory.
The user is referenced by the user id. :param uid: The uid of the user object, that should be deleted. :type
uid: basestring :return: Returns True in case of success :rtype: bool
property editable
Return true, if the instance of the resolver is configured editable :return:
classmethod getResolverClassDescriptor()
return the descriptor of the resolver, which is - the class name and - the config description
Returns resolver description dict
Return type dict
static getResolverClassType()
provide the resolver type for registration
static getResolverDescriptor()
return the descriptor of the resolver, which is - the class name and - the config description
Returns resolver description dict
Return type dict

1.15. Code Documentation 421


privacyIDEA Authentication System, Release 3.8

getResolverId()
Returns the resolver Id This should be an Identifier of the resolver, preferable the type and the name of the
resolver.
Returns the id of the resolver
Return type str
static getResolverType()
getResolverType - return the type of the resolver
Returns returns the string ‘ldapresolver’
Return type string
getUserId(LoginName)
resolve the loginname to the userid.
Parameters LoginName (str) – The login name from the credentials
Returns UserId as found for the LoginName
Return type str
getUserInfo(userId)
This function returns all user info for a given userid/object.
Parameters userId (string) – The userid of the object
Returns A dictionary with the keys defined in self.userinfo
Return type dict
getUserList(searchDict=None)

Parameters searchDict (dict) – A dictionary with search parameters


Returns list of users, where each user is a dictionary
getUsername(user_id)
Returns the username/loginname for a given user_id :param user_id: The user_id in this resolver :type
user_id: string :return: username :rtype: string
get_persistent_serverpool(get_info=None)
Return a process-level instance of LockingServerPool for the current LDAP resolver configuration. Re-
trieve it from the app-local store. If such an instance does not exist yet, create one. :param get_info: one of
ldap3.SCHEMA, ldap3.NONE, ldap3.ALL :return: a LockingServerPool instance
get_serverpool_instance(get_info=None)
Return a ServerPool instance that should be used. If SERVERPOOL_PERSISTENT is enabled, invoke
get_persistent_serverpool to retrieve a per-process server pool instance. If it is not enabled, in-
voke create_serverpool to retrieve a per-request server pool instance. :param get_info: one of
ldap3.SCHEMA, ldap3.NONE, ldap3.ALL :return: a ServerPool/LockingServerPool instance
property has_multiple_loginnames
Return if this resolver has multiple loginname attributes :return: bool
loadConfig(config)
Load the config from conf.
Parameters config (dict) – The configuration from the Config Table

422 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

‘#ldap_uri’: ‘LDAPURI’, ‘#ldap_basedn’: ‘LDAPBASE’, ‘#ldap_binddn’: ‘BINDDN’, ‘#ldap_password’:


‘BINDPW’, ‘#ldap_timeout’: ‘TIMEOUT’, ‘#ldap_sizelimit’: ‘SIZELIMIT’, ‘#ldap_loginattr’: ‘LOGIN-
NAMEATTRIBUTE’, ‘#ldap_searchfilter’: ‘LDAPSEARCHFILTER’, ‘#ldap_mapping’: ‘USERINFO’,
‘#ldap_uidtype’: ‘UIDTYPE’, ‘#ldap_noreferrals’ : ‘NOREFERRALS’, ‘#ldap_editable’ : ‘EDITABLE’,
‘#ldap_certificate’: ‘CACERTIFICATE’, ‘#ldap_keytabfile’: ‘KEYTABFILE’,
static split_uri(uri)
Splits LDAP URIs like: * ldap://server * ldaps://server * ldap[s]://server:1234 * server :param uri: The
LDAP URI :return: Returns a tuple of Servername, Port and SSL(bool)
classmethod testconnection(param)
This function lets you test the to be saved LDAP connection.
Parameters param (dict) – A dictionary with all necessary parameter to test the connection.
Returns Tuple of success and a description
Return type (bool, string)

Parameters are: BINDDN, BINDPW, LDAPURI, TIMEOUT, LDAPBASE, LOGINNAMEAT-


TRIBUTE, LDAPSEARCHFILTER, USERINFO, SIZELIMIT, NOREFERRALS, CACERTIFI-
CATE, AUTHTYPE, TLS_VERIFY, TLS_VERSION, TLS_CA_FILE, SERVERPOOL_ROUNDS,
SERVERPOOL_SKIP

update_user(uid, attributes=None)
Update an existing user. This function is also used to update the password. Since the attribute mapping
know, which field contains the password, this function can also take care for password changing.
Attributes that are not contained in the dict attributes are not modified.
Parameters
• uid (basestring) – The uid of the user object in the resolver.
• attributes (dict) – Attributes to be updated.
Returns True in case of success

Audit log

Base class

class privacyidea.lib.auditmodules.base.Audit(config=None, startdate=None)


Create a new audit object.
Parameters
• config (dict) – The web config is passed to the audit module, so that the special module
implementation can get its configuration.
• startdate (datetime) – The datetime of the beginning of the request
Returns Audit object
add_policy(policyname)
This method adds a triggered policyname to the list of triggered policies.
Parameters policyname – A string or a list of strings as policynames
Returns

1.15. Code Documentation 423


privacyIDEA Authentication System, Release 3.8

add_to_log(param, add_with_comma=False)
Add to existing log entry.
Parameters
• param –
• add_with_comma – If set to true, new values will be appended comma separated
Returns
audit_entry_to_dict(audit_entry)
If the search_query returns an iterator with elements that are not a dictionary, the audit module needs to
provide this function, to convert the audit entry to a dictionary.
property available_audit_columns
csv_generator(param=None, user=None, timelimit=None)
A generator that can be used to stream the audit log
Parameters param –
Returns
finalize_log()
This method is called to finalize the audit_data. I.e. sign the data and write it to the database. It should
hash the data and do a hash chain and sign the data
get_audit_id()
get_count(search_dict, timedelta=None, success=None)
Returns the number of found log entries. E.g. used for checking the timelimit.
Parameters param – List of filter parameters
Returns number of found entries
get_total(param, AND=True, display_error=True, timelimit=None)
This method returns the total number of audit entries in the audit store
property has_data
initialize_log(param)
This method initialized the log state. The fact, that the log state was initialized, also needs to be logged.
Therefor the same parameters are passed as in the log method.
is_readable = False
log(param)
This method is used to log the data. During a request this method can be called several times to fill the
internal audit_data dictionary.
Add new log details in param to the internal log data self.audit_data.
Parameters param (dict) – Log data that is to be added
Returns None
log_token_num(count)
Log the number of the tokens. Can be passed like log_token_num(get_tokens(count=True))
Parameters count (int) – Number of tokens
Returns
read_keys(pub, priv)
Set the private and public key for the audit class. This is achieved by passing the values:

424 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

priv = config.get("privacyideaAudit.key.private")
pub = config.get("privacyideaAudit.key.public")

Parameters
• pub (string with filename) – Public key, used for verifying the signature
• priv (string with filename) – Private key, used to sign the audit entry
Returns None

search(search_dict, page_size=15, page=1, sortorder='asc', timelimit=None)


This function is used to search audit events.
Param Search parameters can be passed.
Returns A pagination object
search_query(search_dict, page_size=15, page=1, sortorder='asc', sortname='number', timelimit=None)
This function returns the audit log as an iterator on the result

SQL Audit module

class privacyidea.lib.auditmodules.sqlaudit.Audit(config=None, startdate=None)


This is the SQLAudit module, which writes the audit entries to an SQL database table.
It requires the following configuration parameters in The Config File:
• PI_AUDIT_KEY_PUBLIC
• PI_AUDIT_KEY_PRIVATE
If you want to host the SQL Audit database in another DB than the token DB, you can use:
• PI_AUDIT_SQL_URI and
• PI_AUDIT_SQL_OPTIONS
With PI_AUDIT_SQL_OPTIONS = {} You can pass options to the DB engine creation. If
PI_AUDIT_SQL_OPTIONS is not set, SQLALCHEMY_ENGINE_OPTIONS will be used.
This module also takes the following optional parameters:
• PI_AUDIT_POOL_SIZE
• PI_AUDIT_POOL_RECYCLE
• PI_AUDIT_SQL_TRUNCATE
• PI_AUDIT_NO_SIGN
• PI_CHECK_OLD_SIGNATURES
You can use PI_AUDIT_NO_SIGN = True to avoid signing of the audit log.
If PI_CHECK_OLD_SIGNATURES = True old style signatures (text-book RSA) will be checked as well, otherwise
they will be marked as FAIL.
Create a new audit object.
Parameters
• config (dict) – The web config is passed to the audit module, so that the special module
implementation can get its configuration.

1.15. Code Documentation 425


privacyIDEA Authentication System, Release 3.8

• startdate (datetime) – The datetime of the beginning of the request


Returns Audit object
audit_entry_to_dict(audit_entry)
If the search_query returns an iterator with elements that are not a dictionary, the audit module needs to
provide this function, to convert the audit entry to a dictionary.
clear()
Deletes all entries in the database table. This is only used for test cases! :return:
csv_generator(param=None, user=None, timelimit=None)
Returns the audit log as csv file.
Parameters
• timelimit (datetime.timedelta) – Limit the number of dumped entries by time
• param (dict) – The request parameters
• user – The user, who issued the request
Returns None. It yields results as a generator
finalize_log()
This method is used to log the data. It should hash the data and do a hash chain and sign the data
get_count(search_dict, timedelta=None, success=None)
Returns the number of found log entries. E.g. used for checking the timelimit.
Parameters param – List of filter parameters
Returns number of found entries
get_total(param, AND=True, display_error=True, timelimit=None)
This method returns the total number of audit entries in the audit store
search(search_dict, page_size=15, page=1, sortorder='asc', timelimit=None)
This function returns the audit log as a Pagination object.
Parameters timelimit (timedelta) – Only audit entries newer than this timedelta will be
searched
search_query(search_dict, page_size=15, page=1, sortorder='asc', sortname='number', timelimit=None)
This function returns the audit log as an iterator on the result
Parameters timelimit (timedelta) – Only audit entries newer than this timedelta will be
searched

Monitoring

Base class

class privacyidea.lib.monitoringmodules.base.Monitoring(config=None)

add_value(stats_key, stats_value, timestamp, reset_values=False)


This method adds a measurement point to the statistics key “stats_key”. If reset_values is set to True, all
old values of this stats_key are deleted.
Parameters
• stats_key – Identifier of the stats

426 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

• stats_value – measured value


• timestamp (timezone aware datetime) – the timestamp of the measurement
• reset_values – boolean to indicate the reset
Returns None
delete(stats_key, start_timestamp, end_timestamp)
Delete all entries of the stats_key for the given time frame. The start_timestamp and end_timestamp are
also deleted.
Parameters
• stats_key – Identifier of the stats
• start_timestamp (timezone aware datetime) – beginning of the time frame
• end_timestamp (timezone aware datetime) – end of the time frame
Returns number of deleted entries
get_keys()
Return a list of the available statistic keys.
Returns list of identifiers
get_last_value(stats_key)
returns the last value of the given stats_key in time. :param stats_key: The identifier of the stats :return: a
string value.
get_values(stats_key, start_timestamp=None, end_timestamp=None)
Return a list of tuples of (timestamp, value) for the requested stats_key.
Parameters
• stats_key – Identifier of the stats
• start_timestamp (timezone aware datetime) – start of the time frame
• end_timestamp (timezone aware datetime) – end of the time frame
Returns

SQL Statistics module

class privacyidea.lib.monitoringmodules.sqlstats.Monitoring(config=None)

add_value(stats_key, stats_value, timestamp, reset_values=False)


This method adds a measurement point to the statistics key “stats_key”. If reset_values is set to True, all
old values of this stats_key are deleted.
Parameters
• stats_key – Identifier of the stats
• stats_value – measured value
• timestamp (timezone aware datetime) – the timestamp of the measurement
• reset_values – boolean to indicate the reset
Returns None

1.15. Code Documentation 427


privacyIDEA Authentication System, Release 3.8

delete(stats_key, start_timestamp, end_timestamp)


Delete all entries of the stats_key for the given time frame. The start_timestamp and end_timestamp are
also deleted.
Parameters
• stats_key – Identifier of the stats
• start_timestamp (timezone aware datetime) – beginning of the time frame
• end_timestamp (timezone aware datetime) – end of the time frame
Returns number of deleted entries
get_keys()
Return a list of all stored keys. :return:
get_last_value(stats_key)
returns the last value of the given stats_key in time. :param stats_key: The identifier of the stats :return: a
string value.
get_values(stats_key, start_timestamp=None, end_timestamp=None, date_strings=False)
Return a list of tuples of (timestamp, value) for the requested stats_key.
Parameters
• stats_key – Identifier of the stats
• start_timestamp (timezone aware datetime) – start of the time frame
• end_timestamp (timezone aware datetime) – end of the time frame
Returns

Machine Resolvers

Machine Resolvers are used to find machines in directories like LDAP, Active Directory or the /etc/hosts file.
Machines can then be used to assign applications and tokens to those machines.

Base class

class privacyidea.lib.machines.base.BaseMachineResolver(name, config=None)

Parameters
• name – The identifying name of the resolver
• config –
Returns
static get_config_description()
Returns a description what config values are expected and allowed.
Returns dict
get_machine_id(hostname=None, ip=None)
Returns the machine id for a given hostname or IP address.
If hostname and ip is given, the resolver should also check that the hostname matches the IP. If it can check
this and hostname and IP do not match, then an Exception must be raised.

428 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Parameters
• hostname (basestring) – The hostname of the machine
• ip (netaddr) – IP address of the machine
Returns The machine ID, which depends on the resolver
Return type basestring
get_machines(machine_id=None, hostname=None, ip=None, any=None, substring=False)
Return a list of all machine objects in this resolver
Parameters substring – If set to true, it will also match search_hostnames,
that only are a subnet of the machines hostname. :type substring: bool :param any: a substring that matches
EITHER hostname, machineid or ip :type any: basestring :return: list of machine objects
load_config(config)
This loads the configuration dictionary, which contains the necessary information for the machine resolver
to find and connect to the machine store.
Parameters config (dict) – The configuration dictionary to run the machine resolver
Returns None
static testconnection(params)
This method can test if the passed parameters would create a working machine resolver.
Parameters params –
Returns tupple of success and description
Return type (bool, string)

Hosts Machine Resolver

class privacyidea.lib.machines.hosts.HostsMachineResolver(name, config=None)

Parameters
• name – The identifying name of the resolver
• config –
Returns
classmethod get_config_description()
Returns a description what config values are expected and allowed.
Returns dict
get_machine_id(hostname=None, ip=None)
Returns the machine id for a given hostname or IP address.
If hostname and ip is given, the resolver should also check that the hostname matches the IP. If it can check
this and hostname and IP do not match, then an Exception must be raised.
Parameters
• hostname (basestring) – The hostname of the machine
• ip (netaddr) – IP address of the machine
Returns The machine ID, which depends on the resolver

1.15. Code Documentation 429


privacyIDEA Authentication System, Release 3.8

Return type basestring


get_machines(machine_id=None, hostname=None, ip=None, any=None, substring=False)
Return matching machines.
Parameters
• machine_id – can be matched as substring
• hostname – can be matched as substring
• ip – can not be matched as substring
• substring (bool) – Whether the filtering should be a substring matching
• any (basestring) – a substring that matches EITHER hostname, machineid or ip
Returns list of Machine Objects
load_config(config)
This loads the configuration dictionary, which contains the necessary information for the machine resolver
to find and connect to the machine store.
Parameters config (dict) – The configuration dictionary to run the machine resolver
Returns None
static testconnection(params)
Test if the given filename exists.
Parameters params –
Returns

PinHandler

This module provides the PIN Handling base class. In case of enrolling a token, a PIN Handling class can be used to
send the PIN via Email, call an external program or print a letter.
This module is not tested explicitly. It is tested in conjunction with the policy decorator init_random_pin in
tests/test_api_lib_policy.py

Base class

class privacyidea.lib.pinhandling.base.PinHandler(options=None)
A PinHandler Class is responsible for handling the OTP PIN during enrollment.
It receives the necessary data like
• the PIN
• the serial number of the token
• the username
• all other user data:
– given name, surname
– email address
– telephone
– mobile (if the module would deliver via SMS)

430 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

• the administrator name (who enrolled the token)


send(pin, serial, user, tokentype=None, logged_in_user=None, userdata=None, options=None)

Parameters
• pin – The PIN in cleartext
• user (user object) – the owner of the token
• tokentype (basestring) – the type of the token
• logged_in_user (dict) – The logged in user, who enrolled the token
• userdata (dict) – Handler-specific user data like email, mobile. . .
• options (dict) – Handler-specific additional options
Returns True in case of success
Return type bool

1.15.3 DB level

On the DB level you can simply modify all objects.

The database model

class privacyidea.models.Admin(**kwargs)
The administrators for managing the system. To manage the administrators use the command pi-manage.
In addition certain realms can be defined to be administrative realms.
Parameters
• username (basestring) – The username of the admin
• password (basestring) – The password of the admin (stored using PBKDF2, salt and
pepper)
• email (basestring) – The email address of the admin (not used at the moment)
A simple constructor that allows initialization from kwargs.
Sets attributes on the constructed instance using the names and values in kwargs.
Only keys that are present as attributes of the instance’s class are allowed. These could be, for example, any
mapped columns or relationships.
class privacyidea.models.Audit(action='', success=0, serial='', token_type='', user='', realm='', resolver='',
administrator='', action_detail='', info='', privacyidea_server='', client='',
loglevel='default', clearance_level='default', thread_id='0', policies='',
startdate=None, duration=None)
This class stores the Audit entries
class privacyidea.models.AuthCache(username, realm, resolver, authentication, first_auth=None,
last_auth=None)
class privacyidea.models.CAConnector(name, catype)
The table “caconnector” contains the names and types of the defined CA connectors. Each connector has a
different configuration, that is stored in the table “caconnectorconfig”.

1.15. Code Documentation 431


privacyIDEA Authentication System, Release 3.8

class privacyidea.models.CAConnectorConfig(caconnector_id=None, Key=None, Value=None,


caconnector=None, Type='', Description='')
Each CAConnector can have multiple configuration entries. Each CA Connector type can have different required
config values. Therefor the configuration is stored in simple key/value pairs. If the type of a config entry is set
to “password” the value of this config entry is stored encrypted.
The config entries are referenced by the id of the resolver.
class privacyidea.models.Challenge(serial, transaction_id=None, challenge='', data='', session='',
validitytime=120)
Table for handling of the generic challenges.
get(timestamp=False)
return a dictionary of all vars in the challenge class
Parameters timestamp (bool) – if true, the timestamp will given in a readable format 2014-
11-29 21:56:43.057293
Returns dict of vars
get_otp_status()
This returns how many OTPs were already received for this challenge. and if a valid OTP was received.
Returns tuple of count and True/False
Return type tuple
is_valid()
Returns true, if the expiration time has not passed, yet. :return: True if valid :rtype: bool
set_data(data)
set the internal data of the challenge :param data: unicode data :type data: string, length 512
class privacyidea.models.ClientApplication(**kwargs)
This table stores the clients, which sent an authentication request to privacyIDEA. This table is filled automati-
cally by authentication requests.
A simple constructor that allows initialization from kwargs.
Sets attributes on the constructed instance using the names and values in kwargs.
Only keys that are present as attributes of the instance’s class are allowed. These could be, for example, any
mapped columns or relationships.
class privacyidea.models.Config(Key, Value, Type='', Description='')
The config table holds all the system configuration in key value pairs.
Additional configuration for realms, resolvers and machine resolvers is stored in specific tables.
class privacyidea.models.CustomUserAttribute(user_id, resolver, realm_id, Key, Value, Type=None)
The table “customuserattribute” is used to store additional, custom attributes for users.
A user is identified by the user_id, the resolver_id and the realm_id.
The additional attributes are stored in Key and Value. The Type can hold extra information like e.g. an encrypted
value / password.
Note: Since the users are external, i.e. no objects in this database, there is not logic reference on a database
level. Since users could be deleted from user stores without privacyIDEA realizing that, this table could
pile up with remnants of attributes.
Create a new customuserattribute for a user tuple

432 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

class privacyidea.models.EventCounter(name, value=0, node='')


This table stores counters of the event handler “Counter”.
Note that an event counter name does not correspond to just one, but rather several table rows, because we store
event counters for each privacyIDEA node separately. This is intended to improve the performance of replicated
setups, because each privacyIDEA node then only writes to its own “private” table row. This way, we avoid
locking issues that would occur if all nodes write to the same table row.
decrease()
Decrease the value of a counter. :return:
increase()
Increase the value of a counter :return:
class privacyidea.models.EventHandler(name, event, handlermodule, action, condition='', ordering=0,
options=None, id=None, conditions=None, active=True,
position='post')
This model holds the list of defined events and actions to this events. A handler module can be bound to an event
with the corresponding condition and action.
get()
Return the serialized eventhandler object including the options
Returns complete dict
Rytpe dict
class privacyidea.models.EventHandlerCondition(eventhandler_id, Key, Value, comparator='equal')
Each EventHandler entry can have additional conditions according to the handler module
class privacyidea.models.EventHandlerOption(eventhandler_id, Key, Value, Type='', Description='')
Each EventHandler entry can have additional options according to the handler module.
class privacyidea.models.MachineResolver(name, rtype)
This model holds the definition to the machinestore. Machines could be located in flat files, LDAP directory or
in puppet services or other. . .
The usual MachineResolver just holds a name and a type and a reference to its config
class privacyidea.models.MachineResolverConfig(resolver_id=None, Key=None, Value=None,
resolver=None, Type='', Description='')
Each Machine Resolver can have multiple configuration entries. The config entries are referenced by the id of
the machine resolver
class privacyidea.models.MachineToken(machineresolver_id=None, machineresolver=None,
machine_id=None, token_id=None, serial=None,
application=None)
The MachineToken assigns a Token and an application type to a machine. The Machine is represented as the
tuple of machineresolver.id and the machine_id. The machine_id is defined by the machineresolver.
This can be an n:m mapping.
class privacyidea.models.MachineTokenOptions(machinetoken_id, key, value)
This class holds an Option for the token assigned to a certain client machine. Each Token-Clientmachine-
Combination can have several options.
class privacyidea.models.MethodsMixin
This class mixes in some common Class table functions like delete and save
class privacyidea.models.MonitoringStats(timestamp, key, value)
This is the table that stores measured, arbitrary statistic points in time.

1.15. Code Documentation 433


privacyIDEA Authentication System, Release 3.8

This could be used to store time series but also to store current values, by simply fetching the last value from the
database.
Create a new database entry in the monitoring stats table :param timestamp: The time of the measurement point
:type timestamp: timezone-naive datetime :param key: The key of the measurement :type key: basestring :param
value: The value of the measurement :type value: Int
class privacyidea.models.PasswordReset(recoverycode, username, realm, resolver='', email=None,
timestamp=None, expiration=None, expiration_seconds=3600)
Table for handling password resets. This table stores the recoverycodes sent to a given user
The application should save the HASH of the recovery code. Just like the password for the Admins the application
shall salt and pepper the hash of the recoverycode. A database admin will not be able to inject a rogue recovery
code.
A user can get several recoverycodes. A recovery code has a validity period
Optional: The email to which the recoverycode was sent, can be stored.
class privacyidea.models.PeriodicTask(name, active, interval, node_list, taskmodule, ordering,
options=None, id=None, retry_if_failed=True)
This class stores tasks that should be run periodically.
Parameters
• name – Unique name of the periodic task as unicode
• active – a boolean
• retry_if_failed – a boalean
• interval – a unicode specifying the periodicity of the task
• node_list – a list of unicodes, denoting the node names that should execute that task. If we
update an existing PeriodicTask entry, PeriodicTaskLastRun entries referring to nodes that
are not present in node_list any more will be deleted.
• taskmodule – a unicode
• ordering – an integer. Lower tasks are executed first.
• options – a dictionary of options, mapping unicode keys to values. Values will be con-
verted to unicode. If we update an existing PeriodicTask entry, all options that have been set
previously but are not present in options will be deleted.
• id – the ID of an existing entry, if any
property aware_last_update
Return self.last_update with attached UTC tzinfo
get()
Return the serialized periodic task object including the options and last runs. The last runs are returned as
timezone-aware UTC datetimes.
Returns complete dict
save()
If the entry has an ID set, update the entry. If not, create one. Set last_update to the current time. :return:
the entry ID
set_last_run(node, timestamp)
Store the information that the last run of the periodic job occurred on node at timestamp. :param node:
Node name as a string :param timestamp: Timestamp as UTC datetime (without timezone information)
:return:

434 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

class privacyidea.models.PeriodicTaskLastRun(periodictask_id, node, timestamp)


Each PeriodicTask entry stores, for each node, the timestamp of the last successful run.
Parameters
• periodictask_id – ID of the periodic task we are referring to
• node – Node name as unicode
• timestamp – Time of the last run as a datetime. A timezone must not be set! We require
the time to be given in UTC.
property aware_timestamp
Return self.timestamp with attached UTC tzinfo
save()
Create or update a PeriodicTaskLastRun entry, depending on the value of self.id. :return: the entry id
class privacyidea.models.PeriodicTaskOption(periodictask_id, key, value)
Each PeriodicTask entry can have additional options according to the task module.
save()
Create or update a PeriodicTaskOption entry, depending on the value of self.id :return: the entry ID
class privacyidea.models.Policy(name, active=True, scope='', action='', realm='', adminrealm='',
adminuser='', resolver='', user='', client='', time='', pinode='', priority=1,
check_all_resolvers=False, conditions=None)
The policy table contains the policy definitions.
The Policies control the behaviour in the scopes
• enrollment
• authentication
• authorization
• administration
• user actions
• webui
get(key=None)
Either returns the complete policy entry or a single value :param key: return the value for this key :type
key: string :return: complete dict or single value :rytpe: dict or value
get_conditions_tuples()

Returns a list of 5-tuples (section, key, comparator, value, active).


set_conditions(conditions)
Replace the list of conditions of this policy with a new list of conditions, i.e. a list of 5-tuples (section, key,
comparator, value, active).
class privacyidea.models.PolicyCondition(**kwargs)
A simple constructor that allows initialization from kwargs.
Sets attributes on the constructed instance using the names and values in kwargs.
Only keys that are present as attributes of the instance’s class are allowed. These could be, for example, any
mapped columns or relationships.
as_tuple()

1.15. Code Documentation 435


privacyIDEA Authentication System, Release 3.8

Returns the condition as a tuple (section, key, comparator, value, active)


class privacyidea.models.PrivacyIDEAServer(**kwargs)
This table can store remote privacyIDEA server definitions
A simple constructor that allows initialization from kwargs.
Sets attributes on the constructed instance using the names and values in kwargs.
Only keys that are present as attributes of the instance’s class are allowed. These could be, for example, any
mapped columns or relationships.
class privacyidea.models.RADIUSServer(**kwargs)
This table can store configurations of RADIUS servers. https://github.com/privacyidea/privacyidea/issues/321
It saves * a unique name * a description * an IP address a * a Port * a secret * timeout in seconds (default 5) *
retries (default 3)
These RADIUS server definition can be used in RADIUS tokens or in a radius passthru policy.
A simple constructor that allows initialization from kwargs.
Sets attributes on the constructed instance using the names and values in kwargs.
Only keys that are present as attributes of the instance’s class are allowed. These could be, for example, any
mapped columns or relationships.
save()
If a RADIUS server with a given name is save, then the existing RADIUS server is updated.
class privacyidea.models.Realm(realm)
The realm table contains the defined realms. User Resolvers can be grouped to realms. This very table contains
just contains the names of the realms. The linking to resolvers is stored in the table “resolverrealm”.
class privacyidea.models.Resolver(name, rtype)
The table “resolver” contains the names and types of the defined User Resolvers. As each Resolver can have
different required config values the configuration of the resolvers is stored in the table “resolverconfig”.
class privacyidea.models.ResolverConfig(resolver_id=None, Key=None, Value=None, resolver=None,
Type='', Description='')
Each Resolver can have multiple configuration entries. Each Resolver type can have different required config
values. Therefor the configuration is stored in simple key/value pairs. If the type of a config entry is set to
“password” the value of this config entry is stored encrypted.
The config entries are referenced by the id of the resolver.
class privacyidea.models.ResolverRealm(resolver_id=None, realm_id=None, resolver_name=None,
realm_name=None, priority=None)
This table stores which Resolver is located in which realm This is a N:M relation
class privacyidea.models.SMSGateway(identifier, providermodule, description=None, options=None,
headers=None)
This table stores the SMS Gateway definitions. See https://github.com/privacyidea/privacyidea/wiki/concept:
-Delivery-Gateway
It saves the * unique name * a description * the SMS provider module
All options and parameters are saved in other tables.
as_dict()
Return the object as a dictionary
Returns complete dict
Rytpe dict

436 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

delete()
When deleting an SMS Gateway we also delete all the options. :return:
property header_dict
Return all connected headers as a dictionary
Returns dict
property option_dict
Return all connected options as a dictionary
Returns dict
class privacyidea.models.SMSGatewayOption(gateway_id, Key, Value, Type=None)
This table stores the options, parameters and headers for an SMS Gateway definition.
Create a new gateway_option for the gateway_id
class privacyidea.models.SMTPServer(**kwargs)
This table can store configurations for SMTP servers. Each entry represents an SMTP server. EMail Token,
SMS SMTP Gateways or Notifications like PIN handlers are supposed to use a reference to to a server definition.
Each Machine Resolver can have multiple configuration entries. The config entries are referenced by the id of
the machine resolver
A simple constructor that allows initialization from kwargs.
Sets attributes on the constructed instance using the names and values in kwargs.
Only keys that are present as attributes of the instance’s class are allowed. These could be, for example, any
mapped columns or relationships.
get()

Returns the configuration as a dictionary


class privacyidea.models.Subscription(**kwargs)
This table stores the imported subscription files.
A simple constructor that allows initialization from kwargs.
Sets attributes on the constructed instance using the names and values in kwargs.
Only keys that are present as attributes of the instance’s class are allowed. These could be, for example, any
mapped columns or relationships.
get()
Return the database object as dict :return:
class privacyidea.models.TimestampMethodsMixin
This class mixes in the table functions including update of the timestamp
class privacyidea.models.Token(serial, tokentype='', isactive=True, otplen=6, otpkey='', userid=None,
resolver=None, realm=None, **kwargs)
The “Token” table contains the basic token data.
It contains data like
• serial number
• secret key
• PINs
• ...

1.15. Code Documentation 437


privacyIDEA Authentication System, Release 3.8

The table privacyidea.models.TokenOwner contains the owner information of the specified token. The table
privacyidea.models.TokenInfo contains additional information that is specific to the tokentype.
del_info(key=None)
Deletes tokeninfo for a given token. If the key is omitted, all Tokeninfo is deleted.
Parameters key – searches for the given key to delete the entry
Returns
del_tokengroup(tokengroup=None, tokengroup_id=None)
Deletes the tokengroup from the given token. If tokengroup name and id are omitted, all tokengroups are
deleted.
Parameters
• tokengroup (str) – The name of the tokengroup
• tokengroup_id (int) – The id of the tokengroup
Returns
get(key=None, fallback=None, save=False)
simulate the dict behaviour to make challenge processing easier, as this will have to deal as well with ‘dict
only challenges’
Parameters
• key – the attribute name - in case of key is not provided, a dict of all class attributes are
returned
• fallback – if the attribute is not found, the fallback is returned
• save – in case of all attributes and save==True, the timestamp is converted to a string
representation
get_hashed_pin(pin)
calculate a hash from a pin Fix for working with MS SQL servers MS SQL servers sometimes return a
‘<space>’ when the column is empty: ‘’
Parameters pin (str) – the pin to hash
Returns hashed pin with current pin_seed
Return type str
get_info()

Returns The token info as dictionary


get_realms()
return a list of the assigned realms :return: realms :rtype: list
get_user_pin()
return the userPin :rtype : the PIN as a secretObject
set_hashed_pin(pin)
Set the pin of the token in hashed format
Parameters pin (str) – the pin to hash
Returns the hashed pin
Return type str

438 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

set_info(info)
Set the additional token info for this token
Entries that end with “.type” are used as type for the keys. I.e. two entries sshkey=”XYZ” and
sshkey.type=”password” will store the key sshkey as type “password”.
Parameters info (dict) – The key-values to set for this token
set_pin(pin, hashed=True)
set the OTP pin in a hashed way
set_realms(realms, add=False)
Set the list of the realms.
This is done by filling the privacyidea.models.TokenRealm table.
Parameters
• realms (list[str]) – realms
• add (bool) – If set, the realms are added. I.e. old realms are not deleted
set_so_pin(soPin)
For smartcards this sets the security officer pin of the token
:rtype : None
set_tokengroups(tokengroups, add=False)
Set the list of the tokengroups.
This is done by filling the privacyidea.models.TokenTokengroup table.
Parameters
• tokengroups (list[str]) – the tokengroups
• add (bool) – If set, the tokengroups are added. I.e. old tokengroups are not deleted
update_otpkey(otpkey)
in case of a new hOtpKey we have to do some more things
update_type(typ)
in case the previous has been different type we must reset the counters But be aware, ray, this could also be
upper and lower case mixing. . .
class privacyidea.models.TokenInfo(token_id, Key, Value, Type=None, Description=None)
The table “tokeninfo” is used to store additional, long information that is specific to the tokentype. E.g. the
tokentype “TOTP” has additional entries in the tokeninfo table for “timeStep” and “timeWindow”, which are
stored in the column “Key” and “Value”.
The tokeninfo is reference by the foreign key to the “token” table.
Create a new tokeninfo for a given token_id
class privacyidea.models.TokenOwner(token_id=None, serial=None, user_id=None, resolver=None,
realm_id=None, realmname=None)
This tables stores the owner of a token. A token can be assigned to several users.
Create a new token assignment to a user.
Parameters
• token_id – The database ID of the token
• serial – The alternate serial number of the token
• resolver – The identifying name of the resolver

1.15. Code Documentation 439


privacyIDEA Authentication System, Release 3.8

• realm_id – The database ID of the realm


• realmname – The alternate name of realm
class privacyidea.models.TokenRealm(realm_id=0, token_id=0, realmname=None)
This table stores to which realms a token is assigned. A token is in the realm of the user it is assigned to. But a
token can also be put into many additional realms.
Create a new TokenRealm entry. :param realm_id: The id of the realm :param token_id: The id of the token
save()
We only save this, if it does not exist, yet.
class privacyidea.models.TokenTokengroup(tokengroup_id=0, token_id=0, tokengroupname=None)
This table stores the assignment of tokens to tokengroups. A token can be assigned to several different token
groups.
Create a new TokenTokengroup assignment :param tokengroup_id: The id of the token group :param token-
groupname: the name of the tokengroup :param token_id: The id of the token
save()
We only save this, if it does not exist, yet.
class privacyidea.models.Tokengroup(groupname, description=None)
The tokengroup table contains the definition of available token groups. A token can then be assigned to several
of these tokengroups.
class privacyidea.models.UserCache(username, used_login, resolver, user_id, timestamp)
privacyidea.models.cleanup_challenges()
Delete all challenges, that have expired.
Returns None
privacyidea.models.get_machineresolver_id(resolvername)
Return the database ID of the machine resolver :param resolvername: :return:
privacyidea.models.get_machinetoken_ids(machine_id, resolver_name, serial, application)
Returns a list of the ID in the machinetoken table
Parameters
• machine_id (basestring) – The resolverdependent machine_id
• resolver_name (basestring) – The name of the resolver
• serial (basestring) – the serial number of the token
• application (basestring) – The application type
Returns A list of IDs of the machinetoken entry
Return type list of int
privacyidea.models.get_token_id(serial)
Return the database token ID for a given serial number :param serial: :return: token ID :rtpye: int
privacyidea.models.save_config_timestamp(invalidate_config=True)
Save the current timestamp to the database, and optionally invalidate the current request-local config object.
:param invalidate_config: defaults to True

440 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

1.16 Frequently Asked Questions

1.16.1 Customization

There are several different ways to customize the UI of privacyIDEA.

Templates

You can change the HTML templates of the web UI as follows. You can create a copy of the orignial templates, modify
them and use rewrite rules of your webserver to call your new, modified templates.
This way updates will not affect your modifications.
All HTML views are contained in:

static/components/<component>/views/<view>.html

You can find them on GitHub or at the according location in your installation.
Follow these basic steps:
1. Create a new location, where you will keep your modifications safe from updates. You should create a directory
like /etc/privacyidea/customization/ and put your modified views in there.
2. Activate the rewrite rules in your web server. E.g. in the Apache configuration you can add entries like:

RewriteEngine On
RewriteRule "/static/components/login/views/login.html" \
"/etc/privacyidea/customization/mylogin.html"

and apply all required changes to the file mylogin.html.

Note: In this case you need to create a RewriteRule for each file, you want to modify. Alternatively the
following configuration only rewrites the URL if the template file exists in the customization tree:

RewriteEngine on
RewriteCond /etc/privacyidea/customization/%{REQUEST_URI} -f
RewriteRule "^(.*)$" "/etc/privacyidea/customization/%{REQUEST_URI}"

3. Now activate mod_rewrite and reload apache2.

Warning: Of course - if there are functional enhancements or bug fixes in the original templates - your template
will also not be affected by these.

1.16. Frequently Asked Questions 441


privacyIDEA Authentication System, Release 3.8

Translating templates

The translation in privacyIDEA is very flexible (see Setup translation). But if you change the templates the normal
translation with PO files can get a bit tricky.
Starting with privacyIDEA 3.0.1 you can use the scope variable browserLanguage in your custom templates.
You can print the browser language like this {{ browserLanguage }}.
And you can display text in different languages in divs like this:

<div ng-show="browserLanguage === 'de'">


Das ist ein deutscher Text.
</div>
<div ng-show="browserLanguage === 'en'">
This is an English text.
</div>

Themes

You can adapt the style and colors by changing CSS. There are at least two ways to do this.

Providing your own stylesheet in the config file

You can create your own CSS file to adapt the look and feel of the Web UI. The default CSS is the bootstrap CSS
theme. Using PI_CSS in pi.cfg you can specify the URL of your own CSS file. The default CSS file url is
/static/contrib/css/bootstrap-theme.css. The file in the file system is located at privacyidea/static/contrib/css. You
might add a directory privacyidea/static/custom/css/ and add your CSS file there.
The CSS you specify here adds to the already existing styles. Thus a convenient way for using this setting is to help
you distinguish different privacyIDEA instances like “testing”, “acceptances” and “production” or different nodes in a
redundant setup.
You can create a simple CSS file [..]/privacyidea/static/custom/css/testing.css like:

body {
background-color: green;
}

and then set in the pi.cfg:

PI_CSS = "/static/custom/css/testing.css"

This way your testing instance will be immediately distinguishable due to the green background.

442 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Use web server rewrite modules

Again you can also use the Apache rewrite module to replace the original css file:

RewriteEngine On
RewriteRule "/static/contrib/css/bootstrap-theme.css" \
"/etc/privacyidea/customization/my.css"

A good stating point might be the themes at http://bootswatch.com.

Note: If you add your own CSS file, the file bootstrap-theme.css will not be loaded anymore. So you might start with
a copy of the original file.

Use web server substitute module

You can also use the substitute module of the Apache webserver. It is not clear how much performance impact you get,
since this module can scan and replace any text that is delivered by the web server.
If you for example want to replace the title of the webpages, you could do it like this:

<Location "/">
AddOutputFilterByType SUBSTITUTE text/html
Substitute "s/>privacyidea Authentication System</>My own 2FA system</ni"
</Location>

Logo

The default logo is located at privacyidea/static/css/privacyIDEA1.png. If you want to use your own logo,
you can put your file “mylogo.png” just in the same folder and set
PI_LOGO = “mylogo.png”
in the pi.cfg config file.

Page title

You can configure the page title by setting PI_PAGE_TITLE in the pi.cfg file.

Menu

The administrator can adapt the menu of the web UI using policies or of course web server rewrite rules. The original
menu is located in static/templates/menu.html.
Note that policies are also dependent on the client IP, this way different clients could see different menus.
Read more about it at the web UI policies at the custom_menu.

1.16. Frequently Asked Questions 443


privacyIDEA Authentication System, Release 3.8

Headers and Footers

The administrator can change the header and footer of each page. We call this the baseline of the web UI. The original
baseline is contained in static/templates/baseline.html. You can use a web UI policy to change this baseline
or - of course - could use the web server rewrite module.
Read more about changing it via the web UI policies at custom_baseline.

Tokenwizard

You can add additional HTML elements above and underneath the enrollment wizard pages. Read the Token Enrollment
Wizard and tokenwizard to learn more about those code snippets.

Token customization

Some tokens allow a special customization.


The paper token allows you to add CSS for styling the printed output and add additional headers and footers. Read
more about it at the paper token Customization.

New token classes

You can add new token types to privacyIDEA by writing your own Python token class. A token class in privacyIDEA
is inherited from privacyidea.lib.tokenclass.TokenClass. You can either inherit from this base class directly
or from another token class. E.g. the TOTP token class is inherited from HOTP. Take a look in the directory priva-
cyidea/lib/tokens/ to get an idea of token classes.
A token class can have many different methods which you can find in the base class TokenClass. Depending on
the token type you are going to implement, you will need to implement several of these. Probably the most important
methods are check_otp, which validates the 2nd factor and the method update, which is called during the initialization
process of the token and gathers and writes all token specific attributes.
You should only add one token class per Python module.
You can install your new Python module, wherever you want to like myproject.cooltoken.
If these tokens need additional enrollment data in the UI, you can specify two templates, that are dis-
played during enrollment and after the token is enrolled. These HTML templates need to be located
at privacyidea/static/components/token/views/token.enroll.<tokentype>.html and privacyidea/
static/components/token/views/token.enrolled.<tokentype>.html.

Note: In this example the python module myproject.cooltoken should contain a class CoolTokenClass. The
tokentype of this token, should be named “cool”. And thus the HTML templates included by privacyIDEA are token.
enroll.cool.html and token.enrolled.cool.html.

The list of the token modules you want to add, must be specified in pi.cfg. See 3rd party token types.

444 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Custom Web UI

You can also write your complete new WebUI. To do so you need to specify files and folders in pi.cfg. Read more
about this at Custom Web UI.

1.16.2 How can I create users in the privacyIDEA Web UI?

So you installed privacyIDEA and want to enroll tokens to the users and are wondering how to create users.
privacyIDEA can read users from different existing sources like LDAP, SQL, flat files and SCIM.
You very much likely already have an application (like your VPN or a Web Application. . . ) for which you want to
increase the logon security. Then this application already knows users. Either in an LDAP or in an SQL database.
Most web applications keep their users in a (My)SQL database. And you also need to create users in this very user
database for the user to be able to use this application.
Please read the sections UserIdResolvers and Users for more details.
But you also can define and editable SQL resolver. I.e. you can edit and create new users in an SQL user store.
If you do not have an existing SQL database with users, you can simple create a new database with one table for the
users and according rows.

1.16.3 So what’s the thing with all the admins?

privacyIDEA comes with its own admins, who are stored in a database table Admin in its own database (The database
model). You can use the tool pi-manage to manage those admins from the command line as the system’s root user.
(see Installation)
These admin users can logon to the WebUI using the admin’s user name and the specified password. These admins are
used to get a simple quick start.
Then you can define realms (see Realms), that should be administrative realms. I.e. each user in this realm will have
administrative rights in the WebUI.

Note: You need to configure these realms within privacyIDEA. Only after these realms exist, you can raise their rights
to an administrative role.

Note: Use this carefully. Imagine you defined a resolver to a specific group in your Active Directory to be the prica-
cyIDEA admins. Then the Active Directory domain admins can simply add users to be administrator in privacyIDEA.

You define the administrative realms in the config file pi.cfg, which is usually located at /etc/privacyidea/pi.
cfg:

SUPERUSER_REALM = ["adminrealm1", "super", "boss"]

In this case all the users in the realms “adminrealm1”, “super” and “boss” will have administrative rights in the WebUI,
when they login with this realm.
As for all other users, you can use the login_mode to define, if these administrators should login to the WebUI with
their userstore password or with an OTP token.

1.16. Frequently Asked Questions 445


privacyIDEA Authentication System, Release 3.8

1.16.4 What are possible rollout strategies?

There are different ways to enroll tokens to a big number of users. Here are some selected high level ideas, you can do
with privacyIDEA.

Autoenrollment

Using the autoassignment policy you can distribute physical tokens to the users. The users just start using the tokens.

Registration Code

If your users are physically not available and spread around the world, you can send a Registration code to the users
by postal mail. The registration code is a special token type which can be used by the user to authenticate with 2FA.
If used once, the registration token gets deleted and can not be used anymore. While logged in, the user can enroll a
token on his own.

Automatic initial synchronization

Hardware TOTP tokens may get out of sync due to clock shift. HOTP tokens may get out of sync due to unused key
presses. To cope with this you can activate Automatic resync during authentication.
But if you are importing hardware tokens, the clock in the TOTP token may already be out of sync and you do not want
the user to authenticate twice, where the first authentication fails.
In this case you can use the following workflow.
In the TOTP token settings you can set the timeWindow to a very high value. Note that this timeWindow are the
seconds that privacyIDEA will search for the valid OTP value before and after the current time. E.g. you can set this
to 86400. This way you allow the clock in the TOTP token to have drifted for a maximum of one day.
As you do not want such a big window for all authentications, you can automatically reset the timeWindow. You can
achieve this by creating an event definition:
• event: validate_check
• handler: token
• condition: * tokentype=TOTP * count_auth_success=1
• action=set tokeninfo * key=*timeWindow* * value=*180*
This way with the first successful authentication of a TOTP token the timeWindow of the TOTP token is set to 180
seconds.

1.16.5 How can I translate to my language?

The web UI can be translated into different languages. The system determines the preferred language of you browser
and displays the web UI accordingly.
At the moment “en” and “de” are available.

446 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

1.16.6 What are possible migration strategies?

You are already running an OTP system like RSA SecurID, SafeNet or Vasco (alphabetical order) but you would like
to migrate to privacyIDEA.
There are different migration strategies using the RADIUS token or the RADIUS passthru policy.

RADIUS token migration strategy

Configure your application like your VPN to authenticate against the privacyIDEA RADIUS server and not against the
old deprecated RADIUS server.
Now, you can enroll a RADIUS token for each user, who is supposed to login to this application. Configure the RADIUS
token for each user so that the RADIUS request is forwarded to the old RADIUS server.
Now you can start to enroll tokens for the users within privacyIDEA. After enrolling a new token in privacyIDEA you
can delete the RADIUS token for this user.
When all RADIUS tokens are deleted, you can switch off the old RADIUS server.
For strategies on enrolling token see What are possible rollout strategies?.

RADIUS PASSTHRU policy migration strategy

Configure your application like your VPN to authenticate against the privacyIDEA RADIUS server and not against the
old deprecated RADIUS server.
Starting with privacyIDEA 2.11 the passthru policy was enhanced. You can define a system wide RADIUS server.
Then you can create a authentication policy with the passthru action pointing to this RADIUS server. This means that
- as long as a user trying to authenticate - has not token assigned, all authentication request with this very username
and the password are forwarded to this RADIUS server.
As soon as you enroll a new token for this user in privacyIDEA the user will authenticate with this very token within
privacyIDEA an his authentication request will not be forwarded anymore.
As soon as all users have a new token within privacyIDEA, you can switch of the old RADIUS server.
For strategies on enrolling token see What are possible rollout strategies?.

1.16.7 Setup translation

We are using weblate to allow the community to participate in translation.


You can go to https://hosted.weblate.org/engage/privacyidea/ and check, which languages need support. This is the
most important part you can do: Added words and sentences in the right language!
Note, that new languages need to be added to the directive “translate” in the top level Makefile. Also new languages
can be added in the “best match” in app.py and login.py.

1.16. Frequently Asked Questions 447


privacyIDEA Authentication System, Release 3.8

1.16.8 How can I setup HA (High Availability) with privacyIDEA?

privacyIDEA does not track any state internally. All information is kept in the database. Thus you can configure several
privacyIDEA instances against one DBMS1 and have the DBMS do the high availability.

Note: The passwords and OTP key material in the database is encrypted using the encKey. Thus it is possible to put
the database onto a DBMS that is controlled by another database administrator in another department.

HA setups

When running HA you need to assure to configure the pi.cfg file on all privacyIDEA instances accordingly. You might
need to adapt the SQLALCHEMY_DATABASE_URI accordingly.
Be sure to set the same SECRET_KEY and PI_PEPPER on all instances.
Then you need to provide the same encryption key (file encKey) and the same audit signing keys on all instances.

Using one central DBMS

If you already have a high available, redundant DBMS - like MariaDB Galera Cluster - which might even be ad-
dressable via one cluster IP address the configuration is fairly simple. In such a case you can configure the same
SQLALCHEMY_DATABASE_URI on all instances.
1 Database management system

448 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Using MySQL master-master-replication

If you have no DBMS or might want to use a dedicated database server for privacyIDEA, you can setup one MySQL
server per privacyIDEA instance and configure the MySQL servers to run in a master-master-replication.

Note: The master-master-replication only works with two MySQL servers.

There are some good howtos out there like2 .

1.16.9 MySQL database connect string

You can use the python package MySQL-python or PyMySQL.


PyMySQL is a pure python implementation. MySQL-python is a wrapper for a C implementation. I.e. when installing
MySQL-python your python virtualenv, you also need to install packages like python-dev and libmysqlclient-dev.
Depending on whether you are using MySQL-python or PyMySQL you need to specify different connect strings in
SQLALCHEMY_DATABASE_URI.
2 https://www.digitalocean.com/community/tutorials/how-to-set-up-mysql-master-master-replication.

1.16. Frequently Asked Questions 449


privacyIDEA Authentication System, Release 3.8

MySQL-python

connect string: mysql://u:p@host/db

Installation

Install a package libmysqlclient-dev from your distribution. The name may vary depending on which distribution you
are running:

pip install MySQL-python

PyMySQL

connect string: pymysql://u:p@host/db

Installation

Install in your virtualenv:

pip install pymysql-sa


pip install PyMySQL

1.16.10 Are there shortcuts to use the Web UI?

I do not like using the mouse. Are there hotkeys or shortcuts to use the Web UI?
With version 2.6 we started to add hotkeys to certain functions. You can use ? to get a list of the available hotkeys in
the current window.
E.g. you can use alt-e to go to the Enroll Token Dialog and alt-r to actually enroll the token.
For any further ideas about shortcuts/hotkeys please drop us a note at GitHub.

1.16.11 How to copy a resolver definition?

Creating a user resolver can be a time consuming task. Especially an LDAP resolver needs many parameters to be
entered. Sometimes you need to create a second resolver, that looks rather the same like the first resolver. So copying
or duplicating this resolver would be great.
You can create a similar second resolver by editing the exiting resolver and entering a new resolver name. This will
save this modified resolver definition under this new name. Thus you have a resolver with the old name and another
one with the new name.

450 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

1.16.12 Cryptographic considerations of privacyIDEA

Encryption keys

The encryption key is a set of 3 256bit AES keys. Usually this key is located in a 96 byte long file “enckey” specified
by PI_ENCFILE in The Config File. The encryption key can be encrypted with a password.
The three encryption keys are used to encrypt
• data like the OTP seeds and secret keys stored in the Token table,
• password of resolvers to connect to LDAP/AD or SQL (stored in the ResolverConfig table)
• and optional additional values.
OTP seeds and passwords are needed in clear text to calculate OTP values or to connect to user stores. So these values
need to be stored in a decryptable way.

Token Hash Algorithms

OTP values according to HOTP and TOTP can be calculated using SHA1, SHA2-256 and SHA2-512.

PIN Hashing

Token PINs are managed by privacyIDEA as the first of the two factors. Each token has its own token PIN. The token
PIN is hashed with Argon2 (9 rounds) and stored in the Token database table.
This PIN hashing is performed in lib.crypto:hash.

Administrator Passwords

privacyIDEA can manage internal administrators using The pi-manage Script. Internal administrators are stored in the
database table Admin.
The password is stored using Argon2 (9 rounds) with an additional pepper. While Argon2 uses a salt which is stored
in the Admin table created randomly for each admin password the pepper is unique for one privacyIDEA installation
and stored in the pi.cfg file.
This way a database administrator is not able to inject rogue password hashes.
The admin password hashing is performed in lib.crypto:hash_with_pepper.

Audit Signing

The audit log is digitally signed. (see Audit and The Config File).
The audit log can be handled by different modules. privacyIDEA comes with an SQL Audit Module.
For signing the audit log the SQL Audit Module uses the RSA keys specified with the values PI_AUDIT_KEY_PUBLIC
and PI_AUDIT_KEY_PRIVATE in The Config File.
By default the installer generates 2048bit RSA keys.
The audit signing is performed in lib.crypto:Sign.sign using SHA2-256 as hash function.

1.16. Frequently Asked Questions 451


privacyIDEA Authentication System, Release 3.8

1.16.13 Time is sensitive in privacyIDEA

The time of your system is used at many different scenarios. It is crucial that your privacyIDEA system has a correct,
well defined time.

Tokens

TOTP tokens are operating based on the unix system time. If the time of your system is not set correctly, TOTP tokens
might not work at all. If the time of your system is drifting, TOTP tokens, that once worked could stop working if the
time drift gets to big to quick.
Push tokens use the time during enrollment, for synchronization and for the poll functionality. To avoid replay attacks
the Push tokens send a timestamp during the poll request. If you system is off only by a few minutes, the poll mechanism
of Push tokens will not work.

System and Logs

If you have a redundant setup, you need to ensure, that both systems have the same - preferably the correct - time.
Otherwise you will get an unsorted audit log.
For a useful audit log and for a useful log file you should ensure that your system has the correct time. Otherwise you
will not be able to correlate events with other systems.

Set up NTP

On a Linux system running systemd you can use the timesyncd.


If your privacyIDEA system is running in a Windows domain, each domain controller also acts as a NTP server. In the
file /etc/systemd/timesyncd.conf you can configure your local NTP servers like:

[Time]
NTP=dc01.your.domain dc02.your.domain dc03.your.domain

You can restart the service:

systemctl restart systemd-timesyncd

and check the status with:

timedatectl status
systemctl status systemd-timesyncd

1.16.14 Policies

How to disable policies?

I create an evil admin policy and locked myself out. How can I disable a policy?
You can use the pi-manage command line tool to list, enable and disable policies. See
pi-manage policy -h

452 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

How do policies work anyway?

Policies are just a set of definitions. These definitions are meant to modify the way privacyIDEA reacts on requests.
Different policies have different scopes where they act.
admin policies define, what an administrator is allowed to do. These policies influence endpoints like /token, /realm
and all other endpoints, which are used to configure the system. (see Admin policies)
user policies define, how the system reacts if a user is managing his own tokens. (see User Policies)
authentication and authorization policies influence the /validate/ endpoint (Validate endpoints).
The Authentication policies define if an authentication request would be successful at all. So it defines how to really
check the authentication request. E.g. this is done by defining if the user has to add a specific OTP PIN or his LDAP
password (see otppin).
The Authorization policies decide, if a user, who would authentication successfully is allowed to issue this request. I.e.
a user may present the right credentials, but he is not allowed to login from a specific IP address or with a not secure
token type (see tokentype).

How is this technically achieved?

At the beginning of a request the complete policy set is read from the database into a policy object, which is a singleton
of PolicyClass (see Policy Module).
The logical part is performed by policy decorators. The decorators modify the behaviour of the above mentioned
endpoints.
Each policy has its own decorator. The decorator can be used on different functions, methods, endpoints. The decorators
are implemented in api/lib/prepolicy.py and api/lib/postpolicy.py.
PrePolicy decorators are executed at the beginning of a request, PostPolicy decorators at the end of the request.
A policy decorator uses one of the methods get_action_value or get_policies.
get_policies is used to determine boolean actions like passOnNoToken.
get_action_value is used to get the defined value of non-boolean policies like otppin.
All policies can depend on IP address, user and time. So these values are taken into account by the decorator when
determining the defined policy.

Note: Each decorator represents one policy and defines its own logic i.e. checking filtering for IP address and fetching
the necessary policy sets from the policy object.

1.16.15 Performance considerations

You can test performace using the apache bench from the apache utils. Creating a simple pass token for a user, eases
the performance testing.
Then you can run:

ab -l -n 200 -c 8 -s 30 'https://localhost/validate/check?user=yourUser&pass=yourPassword
˓→'

The performance depends on several aspects like the connection speed to your database and the connection speed to
your user stores.

1.16. Frequently Asked Questions 453


privacyIDEA Authentication System, Release 3.8

Processes

You should run several processes and threads. You might start with the number of processes equal to the number of
your CPU cores. But you should evaluate, which is the best number of processes to get the highest performance.

Config caching

Starting with privacyIDEA 2.15 privacyIDEA uses a Cache per instance and process to cache system configuration,
resolver, realm and policies.
As the configuration might have been changed in the database by another process or another instance, privacyIDEA
compares a cache timestamp with the timestamp in the database. Thus at the beginning of the request privacyIDEA
reads the timestamp from the database.
You can configure how often the timestamp should be read using the pi.cfg variable PI_CHECK_RELOAD_CONFIG. You
can set this to seconds. If you use this config value to set values higher than 0, you will improve your performance. But:
other processes or instances will learn later about configuration changes which might lead to unexpected behaviour.

Logging

Choose a logging level like WARNING or ERROR. Setting the logging level to INFO or DEBUG will produce much log
output and lead to a decrease in performance.

Response

You can strip the authentication response to get a slight increase in performance by using the policy
no_details_on_success.

Clean configuration

Remove unused resolvers and policies. Have a realm with several resolvers is a bit slower than one realm with one
resolver. Finding the user in the first resolver is faster than in the last resolver. Although e.g. the LDAP resolver utilizes
caching.
Also see What happens in the tokenview?.

1.16.16 What happens in the tokenview?

A question which comes up often is why you can not view hundreds of tokens in the tokenview. Well - you are doing -
you are just paging through the list ;-)
Ok, here it what happens in the tokenview.
The tokenview fetches a slice of the tokens from the token database. So, if you configure the tokenview to display 15
tokens, only 15 tokens will be fetched using the LIMIT and OFFSET mechanisms of SQL.
But what really influences the performance is the user resolver part. privacyIDEA does not store username, givenname
or surname of the token owner. The token table only contains a “pointer” to the user object in the userstore. This pointer
consists of the userresolver ID and the user ID in this resolver. This is useful, since the username or the surname of the
user may change. At least in Germany the givenname only changes in very rare cases.
This means that privacyIDEA needs to contact the userstore, to resolve the user ID to a username and a surname,
givenname. Now you know that you will create 100 LDAP requests, if you choose to display 100 tokens on one page.

454 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Although we are doing some LDAP caching, this will not help with new pages.
We very much recommend using the search capabilities of the tokenview.

1.16.17 How to mitigate brute force and lock tokens

For each failed authentication attempt privacyIDEA will increase a fail counter of a token. If the maximum allowed
fail counter is reached, authentication with this token is not possible anymore. The token gets a timestamp mark, when
the maximum fail counter was reached. Starting with version 2.20 the administrator can define a timeout in minutes.
If the last failed authentication is more than these specified minutes ago, a successful authentication will reset the fail
counter and access will be granted. See Clear failcounter after x minutes.
The failcounter avoids brute force attacks which guess passwords or OTP values. Choose a failcounter clearing timeout,
which is not too long. Otherwise brute force would also lock the token of the user forever.
Another possibility to mitigate brute force is to define an authorization policy with the action auth_max_fail.
This will check, if there are too many failed authentication requests during the specified time period. If there are, even
a successful authentication will fail. This technique uses the audit log, to search for failed authentication requests. See
auth_max_fail.

1.17 Glossary

Admins privacyIDEA comes with its own admins, who are stored in a database table Admin in its own database (The
database model). You can use the tool pi-manage to manage those admins from the command line as the
system’s root user. (see Installation)
These admin users can logon to the WebUI using the admin’s user name and the specified password. These
admins are used to get a simple quick start.
Then you can define realms (see Realms), that should be administrative realms. I.e. each user in this realm will
have administrative rights in the WebUI.

Note: You need to configure these realms within privacyIDEA. Only after these realms exist, you can raise their
rights to an administrative role.

Note: Use this carefully. Imagine you defined a resolver to a specific group in your Active Directory to be the
pricacyIDEA admins. Then the Active Directory domain admins can simply add users to be administrator in
privacyIDEA.

You define the administrative realms in the config file pi.cfg, which is usually located at /etc/privacyidea/
pi.cfg:

SUPERUSER_REALM = ["adminrealm1", "super", "boss"]

In this case all the users in the realms “adminrealm1”, “super” and “boss” will have administrative rights in the
WebUI, when they login with this realm.
As for all other users, you can use the login_mode to define, if these administrators should login to the WebUI
with their userstore password or with an OTP token.
Application Plugins There are some plugins for privacyIDEA. These are plugins for applications like PAM, OTRS,
Apache2, FreeRADIUS, ownCloud, simpleSAMLphp or Keycloak which enable these application to authenticate
users against privacyIDEA.

1.17. Glossary 455


privacyIDEA Authentication System, Release 3.8

You may also write your own application plugin or connect your own application to privacyIDEA. This is quite
simple using a REST API Validate endpoints. In order to support more sophisticated token types like challenge-
response or out-of-band tokens, you should take a look at the various Authentication Modes and Client Modes.
Audit The systems provides a sophisticated audit log, that can be viewed in the WebUI.
The Audit log is essentially a record of events and changes.

Fig. 69: Audit Log

privacyIDEA comes with a default SQL audit module (see Audit log).
Starting with version 3.2 privacyIDEA also provides a Logger Audit and a Container Audit which can be used
to send privacyIDEA audit log messages to services like splunk or logstash.
Challenge
Multi Challenge If a user wants to authenticate with his username and password, privacyIDEA will check whether
an active challenge response token exists for this user. In this case, the challenge is triggered and privacyIDEA
expects a response. If the user now gives the answer expected from the server, the response is accepted and the
authentication is successful.
Multi Challenge is basically a chain of challenges. It can be used to reset a PIN, with the 4 Eyes Token e.g..
Challenges are triggered by:
• The user entering the PIN/Password of the token
• Programmatically via a call to /validate/triggerchallenge
Count
Counter The token property count in privacyIDEA is used to calculate the OTP Value using the HMAC-type algo-
rithms HOTP or TOTP.
Custom User Attributes The table “customuserattribute” is used to store additional, custom attributes for users.
privacyIDEA working with user resolvers, which means users are already located somewhere for example in an
Active Directory.
The interesting thing is that often the administrator who’s responsible for managing the tokens in privacyIDEA
does not have any access to the Active Directory. The administrator can define policies to allow other admins,

456 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

help desk users or even the user to manage custom attributes in privacyIDEA.
A user is identified by the user_id, the resolver_id and the realm_id. The additional attributes are stored in Key
and Value. The Type can hold extra information like e.g. an encrypted value / password.

Note: Since the users are external, i.e. no objects in this database, there is not logic reference on a database
level. Since users could be deleted from user stores without privacyIDEA realizing that, this table could pile up
with remnants of attributes.

Disabled Token Tokens can be disabled. Disabled tokens still belong to the assigned user but those tokens can not
be used to authenticate. Disabled tokens can be enabled again.
Events Each API call is an event and you can bind arbitrary actions to each event as you like. You can bind several
actions to one event. These actions are executed in the order of the priority one after another.

Note: An action, that is triggered by an event can not trigger a new action. Only events (API calls) can trigger
actions. E.g. if you are using the Token Handler Module to create a new token, the creation of the token is
an action, not an event. This means this creation of the token can not trigger a new action. For more complex
actions, you might need to look into the Script Handler Module.

Internally events are marked by a decorator “event” with an event identifier. At the moment not all events might
be tagged. Please drop us a note to tag all further API calls.

Fig. 70: An action is bound to the event token_init.

Extended Policy Conditions Since privacyIDEA 3.1, Extended Policy Conditions allow to define more advanced
rules for policy matching, i.e. for determining which policies are valid for a specific request.
Conditions can be added to a policy via the WebUI. In order for a policy to take effect during the processing of
a request, the request has to match not only the ordinary policy attributes (see Policies), but also all additionally
defined conditions that are currently active. If no active conditions are defined, only the ordinary policy attributes
are taken into account.
FailCount
MaxFail The FailCount count the number of failed login attempts.
If the login fail counter reaches the MaxFail the user can not login with this token anymore.

1.17. Glossary 457


privacyIDEA Authentication System, Release 3.8

Note: The failcounter is not increased anymore, when it has reached MaxFail.

The administrator or help desk user can select those tokens and click the button reset failcounter to reset the fail
counter to zero. The tokens can be used for authentication again.
Orphaned Token An orphaned token means, that it has a user assigned, but the user does not exist in the user store
(anymore).
OTP PIN The OTP PIN is the secret password with which the user authenticates against privacyIDEA. The policy
action otppin sets the type of password. With this password privacyIDEA will identify the tokens for which
further actions are taken (trigger a challenge or check a given OTP Value). In terms of two factor authentication
the OTP PIN is the first factor, the knowledge.
OTP Value A one-time password, which is generated by some mathematical algorithm, usually HMAC, based on a
seed. The term OTP value is used frequently by privacyIDEA to distinguish the changing value from the OTP
PIN. In terms of two factor authentication the OTP Value is actually the 2nd factor, the possion factor, since it
is usually only possible to calculage, if the user is in the possession of the smartphone app or a hardware token.
The OTP Value is calculated using the secret cryptographic Seed.
Radius Attribute Mapping The Radius plugin can use information from the detail section (see Validate endpoints)
of the privacyIDEA response to map these values to arbitrary RADIUS Attribute-Value pairs.
To do this use the [Mapping] section in the rlm_perl.ini file.
Using the Token serial number:
In case of a successful authentication privacyIDEA returns the serial number of the token used.
If available (see no_detail_on_success and no_detail_on_fail) the FreeRADIUS server can receive this serial
number.
In rlm_perl_ini use:

[Mapping]
serial = privacyIDEA-Serial

This will map the detail->serial in the privacyIDEA response and add an attribute privacyIDEA-Serial
in your RADIUS response.
To use the privacyIDEA-Serial in the RADIUS response, you need to include the dictionary.netknights
in your FreeRADIUS dictionary. You can get it here [#netknights_dict]_.
Return user attributes:
If the authorization policy add_user_in_response is configured the privacyIDEA response contains an additional
tree detail->user with user information.
The FreeRADIUS plugin can also map these user information to RADIUS Attribute-Value pairs. Certain VPN
systems use RADIUS return values to put users into certain groups to allow access to special sub networks.
If you want to map such user values you need to add a section in rlm_perl.ini:

[Mapping user]
a_user_attribute = any_RADIUS_Attribute_even_vendor_specific

This way you can map any user attribute like name, email, realm, group to any arbitrary RADIUS attribute.
You can also address different sections in the privacyIDEA detail response by changing the keyword in
rlm_perl.ini to [Mapping other_section].
You can find a detailed explanation here.

458 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

Realms Realms are meant for general logical user grouping. Users need to be in realms to have tokens assigned. A
user, who is not member of a realm can not have a token assigned and can not authenticate.
You can combine several different UserIdResolvers (see UserIdResolvers) into a realm.
The system knows one default realm. Users within this default realm can authenticate with their username.
Users in realms, that are not the default realm, need to be additionally identified. Therefore the users need to
authenticate with their username and the realm like this:

user@realm

Resolver(Machine) Machine Resolvers are used to find machines in directories like LDAP, Active Directory or the
/etc/hosts file.
The idea is for users to be able to authenticate on those client machines. Not in all cases an online authentication
request is possible, so that authentication items can be passed to those client machines.
In addition you need to define, which application on the client machine the user should authenticate to. Different
application require different authentication items.
Therefore privacyIDEA can define application types. At the moment privacyIDEA knows the application luks,
offline and ssh.
Resolver(UserId) UserIdResolvers are connectors to those user stores, the locations, where the users are managed.
Nowadays this can be LDAP directories or especially Active Directory, some times FreeIPA or the Redhat 389
service. But classically users are also located in files like /etc/passwd on standalone unix systems. Web
services often use SQL databases as user store.
Today with many more online cloud services SCIM is also an uprising protocol to access userstores.
privacyIDEA already comes with UserIdResolvers to talk to all these user stores:
• Flatfile resolver
• LDAP resolver
• SQL resolver
• SCIM resolver
• HTTP resolver
Revoked Token Tokens can be revoked. Usually this means the token is disabled and locked. A locked token
can not be modified anymore. It can only be deleted. Certain token types like certificate may define special
actions when revoking a token.
Rollout State A token can be rolled out in several steps like the 2step HOTP/TOTP token. In this case the attribute
“rollout_state” of the token contains certain values. This way actions can be triggered, depending on the
step during an enrollment process.
Rollout States are:
• Clientwait
The rollout is pending in the backend, like CSRs that need to be approved.
• Pending
• Verify
This means the user needs to authenticate to verify that the token was successfully enrolled.
• Enrolled
• Failed

1.17. Glossary 459


privacyIDEA Authentication System, Release 3.8

Note: Not all tokens have the rollout state “enrolled” set consistently. An empty rollout state means “enrolled”.

Scope A scope is the area, where a policy is meant for. This can be values like:
• ADMIN = ‘admin’
• AUDIT = ‘audit’
• AUTH = ‘authentication’
• AUTHZ = ‘authorization’
• ENROLL = ‘enrollment’
• REGISTER = ‘register’
• USER = ‘user’
• WEBUI = ‘webui’
scope takes only one value.
Seed The seed is a cryptographic secret which is shared between the privacyIDEA server and the client like the smart-
phone app or a hardware token. One-time passwords are calculated based on the seed.
SplitAtSign splitAtSign defines if the username like user@company given during authentication should be split
into the loginname user and the realm name company. In most cases this is the wanted behaviour so this is
enabled by default.
But given your users log in with email addresses like [email protected] and [email protected] you probably
do not want to split.
How a user is related to a realm is described here: Relate User to a Realm
This option also affects the login via the Authentication endpoints
Subscription A subscription for support, warranty and enterprise packaging.
privacyIDEA is enterprise software. Managing lots of authentication devices for lots of users is a task that occurs
in a company network. privacyIDEA is licensed under an Open Source license. This guarantees, that a company
using the Open Source software privacyIDEA can use this software for life. In contrast proprietary software or
software-as-a-service (SaaS) can be changed, billed differently or even completely deleted. You could not do
anything about it. The Open Source privacyIDEA is under your control – forever.
The Open Source license dos not mean that a company has no costs in regards to two factor authentication. At
least they need to pay the administrator. In any case the Open Source license states that this software comes
without any warranty. Getting a subscription provides this warranty. A company using privacyIDEA needs to
be aware of this.
For the product privacyIDEA we provide the suitable support with a defined response time and with fixed costs.
Time Step A TOTP token can have a timestep of 30/60 seconds. It can still be used, if this 30/60 seconds are over.
Technically the timestep is the divider by which the seconds since 1.1.1970 (unix system time) are divided to
calculate the OTP value.
The timestep is different to the Time Window.
Time Window Timewindow in which the given OTP value is valid for authentication. Timestep and timewindow
are completely similar to the counter and countwindow (tokeninfo) of HOTP tokens.
Token PrivacyIDEA supports a great variety of different token types. They each have different requirements concern-
ing configuration and how the authentication works. This chapter explains the authentication modes, lists the

460 Chapter 1. Table of Contents


privacyIDEA Authentication System, Release 3.8

supported hardware and software tokens and explains how the token types can be used with privacyIDEA. Tools
which facilitate and automate token enrollment are found in Enrollment Tools.
• Authentication Modes and Client Modes
• Hardware and Software Tokens
• Token types in privacyIDEA
Tokeninfo The table “tokeninfo” is used to store additional, long information that is specific to the Token types in pri-
vacyIDEA. E.g. the tokentype “TOTP” has additional entries in the tokeninfo table for “timeStep” and “timeWin-
dow”, which are stored in the column “Key” and “Value”.
The tokeninfo is reference by the foreign key to the “token” table.
Token info can be viewed and partially edited in the WebUI. In addition, the Token-Janitor can be used to output
token info, filter for tokens that have specific tokeninfo and set user-defined tokeninfos.
Tokenowner The owner of a token is the user for whom the token was rolled out.
UserID The id of the user in a Resolver(UserId). A user is identified by the user_id.
Userinfo These are the user attributes as they are determined by the respective resolver. This is configured via the
attribute mappings of resolvers (see UserIdResolvers).
Userstore Are the locations, where the users are managed. This can be LDAP directories or especially Active Direc-
tory, some times FreeIPA or the Redhat 389 service. But classically users are also located in files like /etc/passwd
on standalone unix systems. Web services often use SQL databases as user store.
WebUI privacyIDEA comes with a web-based user interface which is used to manage and configure the privacyIDEA
server.
It is also used a self-service portal for the average user, who manages his own tokens. This section gives an
overview on the interface and links the respective sections in the documentation.
• Dashboard
• Tokens
• Users
• Machines
• Config
• Audit
• Components
If you are missing any information or descriptions file an issue at github (which would be the preferred way), drop a
note to info(@)privacyidea.org or go to the Community Forum.
This will help us a lot to improve documentation to your needs.
Thanks a lot!

1.17. Glossary 461


privacyIDEA Authentication System, Release 3.8

462 Chapter 1. Table of Contents


CHAPTER

TWO

INDICES AND TABLES

• genindex
• modindex
• search

463
privacyIDEA Authentication System, Release 3.8

464 Chapter 2. Indices and tables


PYTHON MODULE INDEX

p privacyidea.lib.monitoringmodules, 426
privacyidea.api, 240 privacyidea.lib.pinhandling.base, 430
privacyidea.api.application, 289 privacyidea.lib.policy, 376
privacyidea.api.auth, 242 privacyidea.lib.policydecorators, 408
privacyidea.api.caconnector, 285 privacyidea.lib.queue, 393
privacyidea.api.clienttype, 291 privacyidea.lib.resolvers, 416
privacyidea.api.event, 279 privacyidea.lib.smsprovider, 415
privacyidea.api.lib.postpolicy, 405 privacyidea.lib.token, 361
privacyidea.api.lib.prepolicy, 395 privacyidea.lib.tokens.ocratoken, 309
privacyidea.api.machine, 282 privacyidea.lib.tokens.tiqrtoken, 328
privacyidea.api.machineresolver, 281 privacyidea.lib.tokens.u2ftoken, 333
privacyidea.api.monitoring, 287 privacyidea.lib.tokens.webauthntoken, 337
privacyidea.api.periodictask, 287 privacyidea.lib.user, 292
privacyidea.api.policy, 274 privacyidea.models, 431
privacyidea.api.privacyideaserver, 285
privacyidea.api.radiusserver, 291
privacyidea.api.realm, 257
privacyidea.api.recover, 286
privacyidea.api.register, 286
privacyidea.api.resolver, 256
privacyidea.api.smsgateway, 290
privacyidea.api.smtpserver, 289
privacyidea.api.subscriptions, 291
privacyidea.api.system, 253
privacyidea.api.token, 261
privacyidea.api.ttype, 289
privacyidea.api.user, 271
privacyidea.api.validate, 244
privacyidea.lib, 292
privacyidea.lib.auditmodules, 423
privacyidea.lib.event, 412
privacyidea.lib.eventhandler.federationhandler,
199
privacyidea.lib.eventhandler.requestmangler,
201
privacyidea.lib.eventhandler.responsemangler,
202
privacyidea.lib.eventhandler.tokenhandler,
194
privacyidea.lib.eventhandler.usernotification,
190
privacyidea.lib.machines, 428

465
privacyIDEA Authentication System, Release 3.8

466 Python Module Index


HTTP ROUTING TABLE

/application GET /machine/token, 283


GET /application/, 289 POST /machine/token, 283
POST /machine/tokenoption, 282
/audit DELETE /machine/token/(serial)/(machineid)/(resolver)/(app
284
GET /audit/, 241
GET /audit/(csvfile), 241 /machineresolver
/auth GET /machineresolver/, 281
GET /machineresolver/(resolver), 281
GET /auth/rights, 242
POST /machineresolver/(resolver), 281
POST /auth, 242
POST /machineresolver/test, 281
DELETE /machineresolver/(resolver), 281
/caconnector
GET /caconnector/, 285 /monitoring
GET /caconnector/(name), 285
GET /monitoring/, 287
GET /caconnector/specific/(catype), 285
GET /monitoring/(stats_key), 287
POST /caconnector/(name), 285
GET /monitoring/(stats_key)/last, 287
DELETE /caconnector/(name), 285
DELETE /monitoring/(stats_key), 287
/client /periodictask
GET /client/, 291
GET /periodictask/, 287
GET /periodictask/(ptaskid), 288
/defaultrealm GET /periodictask/nodes/, 287
GET /defaultrealm, 260 GET /periodictask/options/(taskmodule), 288
POST /defaultrealm/(realm), 261 GET /periodictask/taskmodules/, 287
DELETE /defaultrealm, 260 POST /periodictask/, 287
POST /periodictask/disable/(ptaskid), 288
/event POST /periodictask/enable/(ptaskid), 288
GET /event/, 279 DELETE /periodictask/(ptaskid), 288
GET /event/(eventid), 279
GET /event/actions/(handlermodule), 280 /policy
GET /event/conditions/(handlermodule), 280 GET /policy/, 275
GET /event/positions/(handlermodule), 280 GET /policy/(name), 275
POST /event, 279 GET /policy/check, 274
POST /event/disable/(eventid), 280 GET /policy/defs, 275
POST /event/enable/(eventid), 280 GET /policy/defs/(scope), 275
DELETE /event/(eid), 280 GET /policy/export/(export), 275
POST /policy/(name), 277
/machine POST /policy/disable/(name), 276
GET /machine/, 283 POST /policy/enable/(name), 276
GET /machine/authitem, 282 POST /policy/import/(filename), 276
GET /machine/authitem/(application), 282 DELETE /policy/(name), 278

467
privacyIDEA Authentication System, Release 3.8

/privacyideaserver /system
GET /privacyideaserver/, 285 GET /system/, 255
POST /privacyideaserver/(identifier), 285 GET /system/(key), 255
POST /privacyideaserver/test_request, 285 GET /system/documentation, 253
DELETE /privacyideaserver/(identifier), 285 GET /system/gpgkeys, 254
GET /system/hsm, 255
/radiusserver GET /system/names/caconnector, 253
GET /radiusserver/, 291 GET /system/names/radius, 253
POST /radiusserver/(identifier), 291 GET /system/random, 255
POST /radiusserver/test_request, 291 POST /system/hsm, 255
DELETE /radiusserver/(identifier), 291 POST /system/setConfig, 254
POST /system/setDefault, 253
/realm POST /system/test/(tokentype), 255
GET /realm/, 258 DELETE /system/(key), 255
GET /realm/superuser, 257
POST /realm/(realm), 259 /token
DELETE /realm/(realm), 260 GET /token/, 268

/recover /token/(serial)
POST /recover, 286 DELETE /token/(serial), 271
POST /recover/reset, 286
/token/assign
/register POST /token/assign, 263
GET /register, 286
POST /register, 286 /token/challenges
GET /token/challenges/, 262
/resolver GET /token/challenges/(serial), 262
GET /resolver/, 256
GET /resolver/(resolver), 256 /token/copypin
POST /resolver/(resolver), 256 POST /token/copypin, 263
POST /resolver/test, 256
DELETE /resolver/(resolver), 257 /token/copyuser
POST /token/copyuser, 262
/smsgateway
GET /smsgateway/, 290 /token/description
GET /smsgateway/(gwid), 290 POST /token/description, 262
POST /smsgateway, 290 POST /token/description/(serial), 262
DELETE /smsgateway/(identifier), 290
DELETE /smsgateway/option/(gwid)/(key), 290 /token/disable
POST /token/disable, 262
/smtpserver POST /token/disable/(serial), 262
GET /smtpserver/, 289
POST /smtpserver/(identifier), 289 /token/enable
POST /smtpserver/send_test_email, 289 POST /token/enable, 263
DELETE /smtpserver/(identifier), 290 POST /token/enable/(serial), 263
/subscriptions /token/getserial
GET /subscriptions/, 291 GET /token/getserial/(otp), 268
GET /subscriptions/(application), 291
POST /subscriptions/, 291 /token/group
DELETE /subscriptions/(application), 291
POST /token/group/(serial), 269
POST /token/group/(serial)/(groupname), 269

468 HTTP Routing Table


privacyIDEA Authentication System, Release 3.8

DELETE /token/group/(serial)/(groupname), 269 GET /user/editable_attributes/, 271


POST /user, 272
/token/info POST /user/, 272
POST /token/info/(serial)/(key), 270 POST /user/attribute, 271
DELETE /token/info/(serial)/(key), 270 PUT /user, 273
PUT /user/, 273
/token/init DELETE /user/(resolvername)/(username), 273
POST /token/init, 264 DELETE /user/attribute/(attrkey)/(username)/(realm),
273
/token/load /validate
POST /token/load/(filename), 270
GET /validate/check, 248
/token/lost GET /validate/polltransaction, 248
GET /validate/polltransaction/(transaction_id),
POST /token/lost/(serial), 270 248
GET /validate/radiuscheck, 248
/token/realm GET /validate/samlcheck, 248
POST /token/realm/(serial), 269 GET /validate/triggerchallenge, 244
POST /validate/check, 251
/token/reset POST /validate/offlinerefill, 248
POST /token/reset, 264 POST /validate/radiuscheck, 251
POST /token/reset/(serial), 264 POST /validate/samlcheck, 251
POST /validate/triggerchallenge, 246
/token/resync
POST /token/resync, 264
POST /token/resync/(serial), 264

/token/revoke
POST /token/revoke, 263
POST /token/revoke/(serial), 263

/token/set
POST /token/set, 267
POST /token/set/(serial), 267

/token/setpin
POST /token/setpin, 264
POST /token/setpin/(serial), 264

/token/setrandompin
POST /token/setrandompin, 261
POST /token/setrandompin/(serial), 261

/token/unassign
POST /token/unassign, 262

/ttype
GET /ttype/(ttype), 289
POST /ttype/(ttype), 289

/user
GET /user/, 271
GET /user/attribute, 271

HTTP Routing Table 469


privacyIDEA Authentication System, Release 3.8

470 HTTP Routing Table


INDEX

Symbols add_policy() (privacyidea.lib.auditmodules.base.Audit


2step, 229 method), 423
4 Eyes, 90 add_to_log() (privacyidea.lib.auditmodules.base.Audit
method), 423
A ADD_TOKENGROUP (priva-
cyidea.lib.eventhandler.tokenhandler.ACTION_TYPE
ACTION (class in privacyidea.lib.policy), 377
attribute), 194
action_only() (privacyidea.lib.policy.Match class
add_tokengroup() (priva-
method), 384
cyidea.lib.tokenclass.TokenClass method),
ACTION_TYPE (class in priva-
348
cyidea.lib.eventhandler.federationhandler),
add_tokeninfo() (in module privacyidea.lib.token),
199
361
ACTION_TYPE (class in priva-
add_tokeninfo() (priva-
cyidea.lib.eventhandler.requestmangler),
cyidea.lib.tokenclass.TokenClass method),
201
348
ACTION_TYPE (class in priva-
add_user() (privacyidea.lib.resolvers.LDAPIdResolver.IdResolver
cyidea.lib.eventhandler.responsemangler),
method), 420
202
add_user() (privacyidea.lib.resolvers.UserIdResolver.UserIdResolver
ACTION_TYPE (class in priva-
method), 416
cyidea.lib.eventhandler.tokenhandler), 194
add_user() (privacyidea.lib.tokenclass.TokenClass
action_values() (privacyidea.lib.policy.Match
method), 348
method), 384
add_user_detail_to_response() (in module priva-
Actions, 182
cyidea.api.lib.postpolicy), 405
actions (privacyidea.lib.eventhandler.base.BaseEventHandler
add_value() (privacyidea.lib.monitoringmodules.base.Monitoring
property), 411
method), 426
actions (privacyidea.lib.eventhandler.federationhandler.FederationEventHandler
add_value() (privacyidea.lib.monitoringmodules.sqlstats.Monitoring
property), 199
method), 427
actions (privacyidea.lib.eventhandler.requestmangler.RequestManglerEventHandler
Additional User Attributes, 38
property), 201
ADDRESOLVERINRESPONSE (priva-
actions (privacyidea.lib.eventhandler.responsemangler.ResponseManglerEventHandler
cyidea.lib.policy.ACTION attribute), 377
property), 202
ADDUSER (privacyidea.lib.policy.ACTION attribute), 377
actions (privacyidea.lib.eventhandler.tokenhandler.TokenEventHandler
ADDUSERINRESPONSE (privacyidea.lib.policy.ACTION
property), 195
attribute), 377
actions (privacyidea.lib.eventhandler.usernotification.UserNotificationEventHandler
Admin (class in privacyidea.models), 431
property), 190, 412
ADMIN (privacyidea.lib.policy.SCOPE attribute), 390
ACTIONVALUE (class in privacyidea.lib.policy), 382
admin accounts, 445
ACTIVE (privacyidea.lib.policy.REMOTE_USER at-
admin dashboard, 169
tribute), 390
admin policies, 113
Active Directory, 39, 42
admin realm, 113
Add User, 36, 121
admin tool, 218
add_init_details() (priva-
admin() (privacyidea.lib.policy.Match class method),
cyidea.lib.tokenclass.TokenClass method),
384
348

471
privacyIDEA Authentication System, Release 3.8

ADMIN_DASHBOARD (privacyidea.lib.policy.ACTION at- as_dict() (privacyidea.models.SMSGateway method),


tribute), 377 436
admin_or_user() (privacyidea.lib.policy.Match class as_tuple() (privacyidea.models.PolicyCondition
method), 384 method), 435
ADMIN_REALM (privacyidea.lib.eventhandler.usernotification.NOTIFY_TYPE
ASSIGN (privacyidea.lib.policy.ACTION attribute), 377
attribute), 190 assign_token() (in module privacyidea.lib.token), 362
Admins, 455 assign_tokengroup() (in module priva-
ALLOW (privacyidea.lib.policy.AUTHORIZED attribute), cyidea.lib.token), 362
382 attestation, 92
allowed() (privacyidea.lib.policy.Match method), 385 attributes (privacyidea.lib.user.User property), 293
allowed_audit_realm() (in module priva- Audit, 208, 456
cyidea.api.lib.prepolicy), 395 Audit (class in privacyidea.lib.auditmodules.base), 423
allowed_positions (priva- Audit (class in privacyidea.lib.auditmodules.sqlaudit),
cyidea.lib.eventhandler.base.BaseEventHandler 425
property), 411 Audit (class in privacyidea.models), 431
allowed_positions (priva- AUDIT (privacyidea.lib.policy.ACTION attribute), 378
cyidea.lib.eventhandler.requestmangler.RequestManglerEventHandler
AUDIT (privacyidea.lib.policy.MAIN_MENU attribute),
property), 201 383
allowed_positions (priva- AUDIT (privacyidea.lib.policy.SCOPE attribute), 390
cyidea.lib.eventhandler.responsemangler.ResponseManglerEventHandler
Audit Log Rotate, 208
property), 202 audit modules, 423
allowed_positions (priva- Audit view page size, 165
cyidea.lib.eventhandler.tokenhandler.TokenEventHandler
AUDIT_AGE (privacyidea.lib.policy.ACTION attribute),
property), 195 378
allowed_positions (priva- AUDIT_DOWNLOAD (privacyidea.lib.policy.ACTION
cyidea.lib.eventhandler.usernotification.UserNotificationEventHandler
attribute), 378
property), 190, 412 audit_entry_to_dict() (priva-
any() (privacyidea.lib.policy.Match method), 385 cyidea.lib.auditmodules.base.Audit method),
API, 240 424
api, 49 audit_entry_to_dict() (priva-
api_endpoint() (priva- cyidea.lib.auditmodules.sqlaudit.Audit
cyidea.lib.tokenclass.TokenClass class method), 426
method), 348 auditlog_age() (in module priva-
api_endpoint() (priva- cyidea.api.lib.prepolicy), 395
cyidea.lib.tokens.pushtoken.PushTokenClass AUDITPAGESIZE (privacyidea.lib.policy.ACTION at-
class method), 313 tribute), 378
api_endpoint() (priva- AUTH (privacyidea.lib.policy.SCOPE attribute), 390
cyidea.lib.tokens.tiqrtoken.TiqrTokenClass AUTH_CACHE (privacyidea.lib.policy.ACTION attribute),
class method), 329 378
api_endpoint() (priva- auth_cache() (in module priva-
cyidea.lib.tokens.u2ftoken.U2fTokenClass cyidea.lib.policydecorators), 408
class method), 335 auth_lastauth() (in module priva-
api_endpoint() (priva- cyidea.lib.policydecorators), 408
cyidea.lib.tokens.yubikeytoken.YubikeyTokenClassauth_otppin() (in module priva-
class method), 346 cyidea.lib.policydecorators), 408
api_key_required() (in module priva- auth_user_does_not_exist() (in module priva-
cyidea.api.lib.prepolicy), 395 cyidea.lib.policydecorators), 409
APIKEY (privacyidea.lib.policy.ACTION attribute), 377 auth_user_has_no_token() (in module priva-
APPIMAGEURL (privacyidea.lib.policy.ACTION attribute), cyidea.lib.policydecorators), 409
377 auth_user_passthru() (in module priva-
appliance, 79 cyidea.lib.policydecorators), 409
Application Plugins, 232, 455 auth_user_timelimit() (in module priva-
APPLICATION_TOKENTYPE (priva- cyidea.lib.policydecorators), 410
cyidea.lib.policy.ACTION attribute), 377 AuthCache, 141

472 Index
privacyIDEA Authentication System, Release 3.8

AuthCache (class in privacyidea.models), 431 BaseMachineResolver (class in priva-


authenticate() (priva- cyidea.lib.machines.base), 428
cyidea.lib.tokenclass.TokenClass method), BaseQueue (class in privacyidea.lib.queues.base), 394
349 BOOL (privacyidea.lib.policy.TYPE attribute), 390
authenticate() (priva- brute force, 455
cyidea.lib.tokens.foureyestoken.FourEyesTokenClass
method), 296 C
authenticate() (priva- CA, 58, 92
cyidea.lib.tokens.pushtoken.PushTokenClass caching, 50
method), 314 CAConnector (class in privacyidea.models), 431
authenticate() (priva- CAConnectorConfig (class in privacyidea.models), 431
cyidea.lib.tokens.radiustoken.RadiusTokenClass CACONNECTORDELETE (privacyidea.lib.policy.ACTION
method), 319 attribute), 378
authenticate() (priva- CACONNECTORREAD (privacyidea.lib.policy.ACTION at-
cyidea.lib.tokens.remotetoken.RemoteTokenClass tribute), 378
method), 322 caconnectors, 58
authenticate() (priva- CACONNECTORWRITE (privacyidea.lib.policy.ACTION at-
cyidea.lib.tokens.spasstoken.SpassTokenClass tribute), 378
method), 326 can_verify_enrollment (priva-
authenticating client, 56 cyidea.lib.tokenclass.TokenClass attribute),
Authentication Cache, 141 349
authentication policies, 134 can_verify_enrollment (priva-
AUTHITEMS (privacyidea.lib.policy.ACTION attribute), cyidea.lib.tokens.emailtoken.EmailTokenClass
378 attribute), 303
AUTHMAXFAIL (privacyidea.lib.policy.ACTION attribute), can_verify_enrollment (priva-
378 cyidea.lib.tokens.hotptoken.HotpTokenClass
AUTHMAXSUCCESS (privacyidea.lib.policy.ACTION attribute), 305
attribute), 378 CentOS, 8
authorization policies, 146 Certificate Authority, 58
AUTHORIZED (class in privacyidea.lib.policy), 382 Certificate Templates, 62
AUTHORIZED (privacyidea.lib.policy.ACTION attribute), certificate token, 58
378 certificates, 92
AUTHZ (privacyidea.lib.policy.SCOPE attribute), 390 CertificateTokenClass (class in priva-
AUTOASSIGN (privacyidea.lib.policy.ACTION attribute), cyidea.lib.tokens.certificatetoken), 299
378 Challenge, 456
autoassign() (in module priva- Challenge (class in privacyidea.models), 432
cyidea.api.lib.postpolicy), 405 Challenge Text Policy, 143
autoassignment, 152 challenge_janitor() (priva-
AUTOASSIGNVALUE (class in privacyidea.lib.policy), 382 cyidea.lib.tokenclass.TokenClass static
autoresync, 55 method), 349
autosync, 55 challenge_response_allowed() (in module priva-
available_audit_columns (priva- cyidea.lib.policydecorators), 410
cyidea.lib.auditmodules.base.Audit property), CHALLENGERESPONSE (privacyidea.lib.policy.ACTION
424 attribute), 378
aware_last_update (privacyidea.models.PeriodicTask CHALLENGETEXT (privacyidea.lib.policy.ACTION at-
property), 434 tribute), 378
aware_timestamp (priva- CHALLENGETEXT_FOOTER (priva-
cyidea.models.PeriodicTaskLastRun property), cyidea.lib.policy.ACTION attribute), 378
435 CHALLENGETEXT_HEADER (priva-
cyidea.lib.policy.ACTION attribute), 378
B Change PIN, 153, 154
Backup, 22, 82 Change User Password, 36
BaseEventHandler (class in priva- CHANGE_FAILCOUNTER (priva-
cyidea.lib.eventhandler.base), 411 cyidea.lib.eventhandler.tokenhandler.ACTION_TYPE

Index 473
privacyIDEA Authentication System, Release 3.8

attribute), 194 check_failcount() (priva-


CHANGE_PIN_EVERY (privacyidea.lib.policy.ACTION at- cyidea.lib.tokenclass.TokenClass method),
tribute), 378 350
CHANGE_PIN_FIRST_USE (priva- check_for_conflicts() (priva-
cyidea.lib.policy.ACTION attribute), 378 cyidea.lib.policy.PolicyClass static method),
CHANGE_PIN_VIA_VALIDATE (priva- 386
cyidea.lib.policy.ACTION attribute), 378 check_if_disabled (priva-
check_admin_tokenlist() (in module priva- cyidea.lib.tokenclass.TokenClass attribute),
cyidea.api.lib.prepolicy), 395 350
check_all() (privacyidea.lib.tokenclass.TokenClass check_if_disabled (priva-
method), 349 cyidea.lib.tokens.pushtoken.PushTokenClass
CHECK_AND_RAISE_EXCEPTION_ON_MISSING (pri- attribute), 315
vacyidea.lib.policy.CONDITION_CHECK check_last_auth_newer() (priva-
attribute), 382 cyidea.lib.tokenclass.TokenClass method),
check_anonymous_user() (in module priva- 350
cyidea.api.lib.prepolicy), 395 check_max_token_realm() (in module priva-
check_answer() (priva- cyidea.api.lib.prepolicy), 396
cyidea.lib.tokens.questionnairetoken.QuestionnaireTokenClass
check_max_token_user() (in module priva-
method), 317 cyidea.api.lib.prepolicy), 397
check_application_tokentype() (in module priva- check_otp() (in module privacyidea.lib.token), 362
cyidea.api.lib.prepolicy), 396 check_otp() (privacyidea.lib.tokenclass.TokenClass
check_auth_counter() (priva- method), 350
cyidea.lib.tokenclass.TokenClass method), check_otp() (privacyidea.lib.tokens.daplugtoken.DaplugTokenClass
349 method), 301
check_base_action() (in module priva- check_otp() (privacyidea.lib.tokens.emailtoken.EmailTokenClass
cyidea.api.lib.prepolicy), 396 method), 303
check_challenge_response() (priva- check_otp() (privacyidea.lib.tokens.hotptoken.HotpTokenClass
cyidea.lib.tokenclass.TokenClass method), method), 305
350 check_otp() (privacyidea.lib.tokens.motptoken.MotpTokenClass
check_challenge_response() (priva- method), 308
cyidea.lib.tokens.foureyestoken.FourEyesTokenClasscheck_otp() (privacyidea.lib.tokens.ocratoken.OcraTokenClass
method), 297 method), 309
check_challenge_response() (priva- check_otp() (privacyidea.lib.tokens.passwordtoken.PasswordTokenClass
cyidea.lib.tokens.pushtoken.PushTokenClass method), 312
method), 315 check_otp() (privacyidea.lib.tokens.radiustoken.RadiusTokenClass
check_challenge_response() (priva- method), 319
cyidea.lib.tokens.questionnairetoken.QuestionnaireTokenClass
check_otp() (privacyidea.lib.tokens.remotetoken.RemoteTokenClass
method), 317 method), 322
check_challenge_response() (priva- check_otp() (privacyidea.lib.tokens.smstoken.SmsTokenClass
cyidea.lib.tokens.radiustoken.RadiusTokenClass method), 325
method), 319 check_otp() (privacyidea.lib.tokens.spasstoken.SpassTokenClass
check_challenge_response() (priva- method), 326
cyidea.lib.tokens.tiqrtoken.TiqrTokenClass check_otp() (privacyidea.lib.tokens.totptoken.TotpTokenClass
method), 329 method), 331
check_condition() (priva- check_otp() (privacyidea.lib.tokens.u2ftoken.U2fTokenClass
cyidea.lib.eventhandler.base.BaseEventHandler method), 335
method), 411 check_otp() (privacyidea.lib.tokens.webauthntoken.WebAuthnTokenClass
check_configuration() (priva- method), 343
cyidea.lib.smsprovider.SMSProvider.ISMSProvidercheck_otp() (privacyidea.lib.tokens.yubicotoken.YubicoTokenClass
method), 415 method), 346
check_custom_user_attributes() (in module priva- check_otp() (privacyidea.lib.tokens.yubikeytoken.YubikeyTokenClass
cyidea.api.lib.prepolicy), 396 method), 347
check_external() (in module priva- check_otp_exist() (priva-
cyidea.api.lib.prepolicy), 396 cyidea.lib.tokenclass.TokenClass method),

474 Index
privacyIDEA Authentication System, Release 3.8

351 check_verify_enrollment() (in module priva-


check_otp_exist() (priva- cyidea.api.lib.postpolicy), 405
cyidea.lib.tokens.daplugtoken.DaplugTokenClass check_yubikey_pass() (priva-
method), 301 cyidea.lib.tokens.yubikeytoken.YubikeyTokenClass
check_otp_exist() (priva- static method), 347
cyidea.lib.tokens.hotptoken.HotpTokenClass checkPass() (privacyidea.lib.resolvers.LDAPIdResolver.IdResolver
method), 305 method), 420
check_otp_exist() (priva- checkPass() (privacyidea.lib.resolvers.PasswdIdResolver.IdResolver
cyidea.lib.tokens.totptoken.TotpTokenClass method), 418
method), 331 checkPass() (privacyidea.lib.resolvers.UserIdResolver.UserIdResolver
check_otp_exist() (priva- method), 416
cyidea.lib.tokens.yubikeytoken.YubikeyTokenClasscheckUserId() (priva-
method), 347 cyidea.lib.resolvers.PasswdIdResolver.IdResolver
check_otp_pin() (in module priva- method), 418
cyidea.api.lib.prepolicy), 397 checkUserName() (priva-
check_password() (priva- cyidea.lib.resolvers.PasswdIdResolver.IdResolver
cyidea.lib.tokens.passwordtoken.PasswordTokenClass.SecretPassword
method), 419
method), 312 cleanup_challenges() (in module priva-
check_password() (privacyidea.lib.user.User method), cyidea.models), 440
293 clear() (privacyidea.lib.auditmodules.sqlaudit.Audit
check_pin() (in module privacyidea.lib.policy), 390 method), 426
check_pin() (privacyidea.lib.tokenclass.TokenClass Clickatel, 74
method), 351 client, 56
check_pin_local (priva- client certificates, 92
cyidea.lib.tokens.radiustoken.RadiusTokenClass client machines, 212
property), 319 client policies, 128
check_pin_local (priva- client_mode (privacyidea.lib.tokenclass.TokenClass at-
cyidea.lib.tokens.remotetoken.RemoteTokenClass tribute), 351
property), 323 client_mode (privacyidea.lib.tokens.pushtoken.PushTokenClass
check_realm_pass() (in module priva- attribute), 315
cyidea.lib.token), 362 client_mode (privacyidea.lib.tokens.tiqrtoken.TiqrTokenClass
check_reset_failcount() (priva- attribute), 330
cyidea.lib.tokenclass.TokenClass method), client_mode (privacyidea.lib.tokens.u2ftoken.U2fTokenClass
351 attribute), 335
check_serial() (in module priva- client_mode (privacyidea.lib.tokens.webauthntoken.WebAuthnTokenClass
cyidea.api.lib.postpolicy), 405 attribute), 344
check_serial() (in module privacyidea.lib.token), 363 ClientApplication (class in privacyidea.models), 432
check_serial_pass() (in module priva- CLIENTTYPE (privacyidea.lib.policy.ACTION attribute),
cyidea.lib.token), 363 378
check_token_init() (in module priva- clob_to_varchar (class in privacyidea.lib.token), 364
cyidea.api.lib.prepolicy), 397 close() (privacyidea.lib.resolvers.UserIdResolver.UserIdResolver
check_token_list() (in module priva- method), 416
cyidea.lib.token), 363 Components, 39
check_token_upload() (in module priva- COMPONENTS (privacyidea.lib.policy.MAIN_MENU
cyidea.api.lib.prepolicy), 397 attribute), 383
check_tokeninfo() (in module priva- CONDITION_CHECK (class in privacyidea.lib.policy), 382
cyidea.api.lib.postpolicy), 405 CONDITION_SECTION (class in privacyidea.lib.policy),
check_tokentype() (in module priva- 382
cyidea.api.lib.postpolicy), 405 conditions, 183
check_user_pass() (in module privacyidea.lib.token), conditions (privacyidea.lib.eventhandler.base.BaseEventHandler
363 property), 411
check_validity_period() (priva- CONDITIONS (privacyidea.lib.policy.GROUP attribute),
cyidea.lib.tokenclass.TokenClass method), 383
351 Config (class in privacyidea.models), 432

Index 475
privacyIDEA Authentication System, Release 3.8

CONFIG (privacyidea.lib.policy.MAIN_MENU attribute), create_challenge() (priva-


383 cyidea.lib.tokens.u2ftoken.U2fTokenClass
config file, 13 method), 335
config_lost_token() (in module priva- create_challenge() (priva-
cyidea.lib.policydecorators), 410 cyidea.lib.tokens.webauthntoken.WebAuthnTokenClass
CONFIGDOCUMENTATION (privacyidea.lib.policy.ACTION method), 344
attribute), 378 create_challenges_from_tokens() (in module pri-
configuration, 39 vacyidea.lib.token), 364
construct_radius_response() (in module priva- create_connection() (priva-
cyidea.api.lib.postpolicy), 406 cyidea.lib.resolvers.LDAPIdResolver.IdResolver
Contao, 239 static method), 420
convert_realms() (priva- create_serverpool() (priva-
cyidea.lib.tokens.foureyestoken.FourEyesTokenClass cyidea.lib.resolvers.LDAPIdResolver.IdResolver
static method), 297 class method), 421
copy_token_pin() (in module privacyidea.lib.token), create_tokenclass_object() (in module priva-
364 cyidea.lib.token), 365
copy_token_realms() (in module priva- create_user() (in module privacyidea.lib.user), 294
cyidea.lib.token), 364 Creating Users, 445
copy_token_user() (in module privacyidea.lib.token), Crypto considerations, 451
364 CSR, 92
COPYTOKENPIN (privacyidea.lib.policy.ACTION at- CSS, 442
tribute), 378 csv_generator() (priva-
COPYTOKENUSER (privacyidea.lib.policy.ACTION at- cyidea.lib.auditmodules.base.Audit method),
tribute), 378 424
Count, 456 csv_generator() (priva-
Counter, 456 cyidea.lib.auditmodules.sqlaudit.Audit
Counter Handler, 197 method), 426
create_challenge() (priva- Custom User Attribute Handler, 204
cyidea.lib.tokenclass.TokenClass method), Custom User Attributes, 456
351 CUSTOM_BASELINE (privacyidea.lib.policy.ACTION at-
create_challenge() (priva- tribute), 378
cyidea.lib.tokens.emailtoken.EmailTokenClass CUSTOM_MENU (privacyidea.lib.policy.ACTION attribute),
method), 303 378
create_challenge() (priva- customize, 441, 442
cyidea.lib.tokens.foureyestoken.FourEyesTokenClass
Customize baseline, 167
method), 297 customize footer, 167
create_challenge() (priva- Customize menu, 167
cyidea.lib.tokens.ocratoken.OcraTokenClass CustomUserAttribute (class in privacyidea.models),
method), 309 432
create_challenge() (priva-
cyidea.lib.tokens.pushtoken.PushTokenClass D
method), 315 DaplugTokenClass (class in priva-
create_challenge() (priva- cyidea.lib.tokens.daplugtoken), 301
cyidea.lib.tokens.questionnairetoken.QuestionnaireTokenClass
dashboard, 33, 169
method), 317 database, 431
create_challenge() (priva- DB2, 46
cyidea.lib.tokens.radiustoken.RadiusTokenClass debug, 13
method), 319 Debugging, 18
create_challenge() (priva- decode_otpkey() (priva-
cyidea.lib.tokens.smstoken.SmsTokenClass cyidea.lib.tokenclass.TokenClass static
method), 325 method), 351
create_challenge() (priva- decrease() (privacyidea.models.EventCounter
cyidea.lib.tokens.tiqrtoken.TiqrTokenClass method), 433
method), 330

476 Index
privacyIDEA Authentication System, Release 3.8

decrypt_otpkey() (priva- DELETEUSER (privacyidea.lib.policy.ACTION attribute),


cyidea.lib.tokens.webauthntoken.WebAuthnTokenClass 378
method), 344 DELETION_CONFIRMATION (priva-
default realm, 51 cyidea.lib.policy.ACTION attribute), 378
Default tokentype, 165 DENY (privacyidea.lib.policy.AUTHORIZED attribute),
DEFAULT_TOKENTYPE (privacyidea.lib.policy.ACTION 382
attribute), 378 desc_hash_func (priva-
del_info() (privacyidea.models.Token method), 438 cyidea.lib.tokens.hotptoken.HotpTokenClass
del_tokengroup() (priva- attribute), 305
cyidea.lib.tokenclass.TokenClass method), desc_key_gen (privacyidea.lib.tokens.hotptoken.HotpTokenClass
352 attribute), 305
del_tokengroup() (privacyidea.models.Token desc_otp_len (privacyidea.lib.tokens.hotptoken.HotpTokenClass
method), 438 attribute), 305
del_tokeninfo() (priva- desc_timestep (priva-
cyidea.lib.tokenclass.TokenClass method), cyidea.lib.tokens.totptoken.TotpTokenClass
352 attribute), 331
DELETE (privacyidea.lib.eventhandler.requestmangler.ACTION_TYPE
desc_two_step_admin (priva-
attribute), 201 cyidea.lib.tokens.hotptoken.HotpTokenClass
DELETE (privacyidea.lib.eventhandler.responsemangler.ACTION_TYPE attribute), 305
attribute), 202 desc_two_step_user (priva-
DELETE (privacyidea.lib.eventhandler.tokenhandler.ACTION_TYPE cyidea.lib.tokens.hotptoken.HotpTokenClass
attribute), 194 attribute), 305
DELETE (privacyidea.lib.policy.ACTION attribute), 378 description (privacyidea.lib.eventhandler.base.BaseEventHandler
Delete User, 121 attribute), 411
delete() (privacyidea.lib.monitoringmodules.base.Monitoringdescription (privacyidea.lib.eventhandler.federationhandler.FederationEv
method), 427 attribute), 199
delete() (privacyidea.lib.monitoringmodules.sqlstats.Monitoring
description (privacyidea.lib.eventhandler.requestmangler.RequestMangle
method), 427 attribute), 201
delete() (privacyidea.lib.user.User method), 293 description (privacyidea.lib.eventhandler.responsemangler.ResponseMan
delete() (privacyidea.models.SMSGateway method), attribute), 203
436 description (privacyidea.lib.eventhandler.tokenhandler.TokenEventHandl
delete_all_policies() (in module priva- attribute), 195
cyidea.lib.policy), 391 description (privacyidea.lib.eventhandler.usernotification.UserNotificatio
delete_attribute() (privacyidea.lib.user.User attribute), 190, 412
method), 293 DIALOG_NO_TOKEN (privacyidea.lib.policy.ACTION at-
delete_event() (in module privacyidea.lib.event), 413 tribute), 378
delete_policy() (in module privacyidea.lib.policy), DISABLE (privacyidea.lib.eventhandler.tokenhandler.ACTION_TYPE
391 attribute), 194
delete_token() (priva- DISABLE (privacyidea.lib.policy.ACTION attribute), 378
cyidea.lib.tokenclass.TokenClass method), DISABLE (privacyidea.lib.policy.ACTIONVALUE at-
352 tribute), 382
DELETE_TOKENINFO (priva- DISABLE (privacyidea.lib.policy.LOGINMODE at-
cyidea.lib.eventhandler.tokenhandler.ACTION_TYPE tribute), 383
attribute), 194 DISABLE (privacyidea.lib.policy.REMOTE_USER at-
delete_tokeninfo() (in module priva- tribute), 390
cyidea.lib.token), 365 Disabled Token, 457
delete_user() (priva- Django, 239
cyidea.lib.resolvers.LDAPIdResolver.IdResolver do() (privacyidea.lib.eventhandler.base.BaseEventHandler
method), 421 method), 411
delete_user() (priva- do() (privacyidea.lib.eventhandler.federationhandler.FederationEventHand
cyidea.lib.resolvers.UserIdResolver.UserIdResolver method), 199
method), 416 do() (privacyidea.lib.eventhandler.requestmangler.RequestManglerEventHa
DELETE_USER_ATTRIBUTES (priva- method), 201
cyidea.lib.policy.ACTION attribute), 378 do() (privacyidea.lib.eventhandler.responsemangler.ResponseManglerEven

Index 477
privacyIDEA Authentication System, Release 3.8

method), 203 enroll_pin() (in module privacyidea.api.lib.prepolicy),


do() (privacyidea.lib.eventhandler.tokenhandler.TokenEventHandler 397
method), 195 ENROLL_VIA_MULTICHALLENGE (priva-
do() (privacyidea.lib.eventhandler.usernotification.UserNotificationEventHandler
cyidea.lib.policy.ACTION attribute), 379
method), 190, 412 enroll_via_validate() (priva-
DO_NOT_CHECK_AT_ALL (priva- cyidea.lib.tokenclass.TokenClass class
cyidea.lib.policy.CONDITION_CHECK method), 352
attribute), 382 enroll_via_validate() (priva-
Dokuwiki, 239 cyidea.lib.tokens.emailtoken.EmailTokenClass
class method), 303
E enroll_via_validate() (priva-
Edit User, 36, 121, 132 cyidea.lib.tokens.hotptoken.HotpTokenClass
Edit Users, 36 class method), 305
editable (privacyidea.lib.resolvers.LDAPIdResolver.IdResolver
enroll_via_validate() (priva-
property), 421 cyidea.lib.tokens.pushtoken.PushTokenClass
editable (privacyidea.lib.resolvers.UserIdResolver.UserIdResolver class method), 315
property), 417 enroll_via_validate() (priva-
Editable Resolver, 36 cyidea.lib.tokens.smstoken.SmsTokenClass
EMAIL (privacyidea.lib.eventhandler.usernotification.NOTIFY_TYPE class method), 325
attribute), 190 enroll_via_validate_2nd_step() (priva-
EMail policy, 137 cyidea.lib.tokenclass.TokenClass method),
Email policy, 138 352
Email subject, 138 enroll_via_validate_2nd_step() (priva-
Email text, 137 cyidea.lib.tokens.emailtoken.EmailTokenClass
Email Token, 72 method), 303
Email token, 94 enroll_via_validate_2nd_step() (priva-
EMAIL_ADDRESS_KEY (priva- cyidea.lib.tokens.smstoken.SmsTokenClass
cyidea.lib.tokens.emailtoken.EmailTokenClass method), 325
attribute), 303 ENROLLMENT (privacyidea.lib.policy.GROUP attribute),
EMAILCONFIG (privacyidea.lib.policy.ACTION attribute), 383
378 enrollment policies, 150
EmailTokenClass (class in priva- Enrollment Wizard, 217
cyidea.lib.tokens.emailtoken), 303 ENROLLPIN (privacyidea.lib.policy.ACTION attribute),
ENABLE (privacyidea.lib.eventhandler.tokenhandler.ACTION_TYPE 379
attribute), 194 event (class in privacyidea.lib.event), 413
ENABLE (privacyidea.lib.policy.ACTION attribute), 378 Event Handler, 180, 183, 411, 412
enable() (privacyidea.lib.tokenclass.TokenClass EventConfiguration (class in privacyidea.lib.event),
method), 352 412
enable_event() (in module privacyidea.lib.event), 413 EventCounter (class in privacyidea.models), 432
enable_policy() (in module privacyidea.lib.policy), EventHandler (class in privacyidea.models), 433
391 EventHandlerCondition (class in priva-
enable_token() (in module privacyidea.lib.token), 365 cyidea.models), 433
encrypt_pin() (in module priva- EventHandlerOption (class in privacyidea.models),
cyidea.api.lib.prepolicy), 397 433
Encrypted Seed File, 214 EVENTHANDLINGREAD (privacyidea.lib.policy.ACTION
ENCRYPTPIN (privacyidea.lib.policy.ACTION attribute), attribute), 379
378 EVENTHANDLINGWRITE (privacyidea.lib.policy.ACTION
END (privacyidea.lib.eventhandler.tokenhandler.VALIDITY attribute), 379
attribute), 195 Events, 457
enqueue() (privacyidea.lib.queues.base.BaseQueue events, 180
method), 394 events (privacyidea.lib.event.EventConfiguration prop-
enqueue() (privacyidea.lib.queues.huey_queue.HueyQueue erty), 412
method), 393 events (privacyidea.lib.eventhandler.base.BaseEventHandler
ENROLL (privacyidea.lib.policy.SCOPE attribute), 390 property), 412

478 Index
privacyIDEA Authentication System, Release 3.8

exist() (privacyidea.lib.user.User method), 293 GENERAL (privacyidea.lib.policy.GROUP attribute), 383


Expired Users, 46 generate_symmetric_key() (priva-
export_event() (in module privacyidea.lib.event), 413 cyidea.lib.tokenclass.TokenClass method),
export_policies() (in module privacyidea.lib.policy), 352
391 generate_symmetric_key() (priva-
export_policy() (in module privacyidea.lib.policy), cyidea.lib.tokens.hotptoken.HotpTokenClass
391 method), 306
Extended Policy Conditions, 457 generic() (privacyidea.lib.policy.Match class method),
external hook, 13 385
extract_action_values() (priva- get() (privacyidea.models.Challenge method), 432
cyidea.lib.policy.PolicyClass static method), get() (privacyidea.models.EventHandler method), 433
387 get() (privacyidea.models.PeriodicTask method), 434
get() (privacyidea.models.Policy method), 435
F get() (privacyidea.models.SMTPServer method), 437
fail counter, 455 get() (privacyidea.models.Subscription method), 437
FailCount, 457 get() (privacyidea.models.Token method), 438
FAQ, 441 get_action_values() (priva-
Federation Handler, 198 cyidea.lib.policy.PolicyClass method), 387
FederationEventHandler (class in priva- get_action_values_from_options() (in module pri-
cyidea.lib.eventhandler.federationhandler), vacyidea.lib.policy), 391
199 get_allowed_custom_attributes() (in module pri-
FIDO, 110 vacyidea.lib.policy), 391
FIDO2, 112 get_as_dict() (privacyidea.lib.tokenclass.TokenClass
filter_policies_by_conditions() (priva- method), 353
cyidea.lib.policy.PolicyClass method), 387 get_as_dict() (priva-
finalize_log() (priva- cyidea.lib.tokens.certificatetoken.CertificateTokenClass
cyidea.lib.auditmodules.base.Audit method), method), 300
424 get_attributes() (in module privacyidea.lib.user),
finalize_log() (priva- 294
cyidea.lib.auditmodules.sqlaudit.Audit get_audit_id() (priva-
method), 426 cyidea.lib.auditmodules.base.Audit method),
Firebase service, 100, 142 424
flatfile resolver, 42 get_class_info() (priva-
fn_clob_to_varchar_default() (in module priva- cyidea.lib.tokenclass.TokenClass static
cyidea.lib.token), 365 method), 353
fn_clob_to_varchar_oracle() (in module priva- get_class_info() (priva-
cyidea.lib.token), 365 cyidea.lib.tokens.certificatetoken.CertificateTokenClass
FORCE (privacyidea.lib.policy.REMOTE_USER at- static method), 300
tribute), 390 get_class_info() (priva-
FORCE_APP_PIN (privacyidea.lib.policy.ACTION at- cyidea.lib.tokens.daplugtoken.DaplugTokenClass
tribute), 379 static method), 301
FORWARD (privacyidea.lib.eventhandler.federationhandler.ACTION_TYPE
get_class_info() (priva-
attribute), 199 cyidea.lib.tokens.emailtoken.EmailTokenClass
Four Eyes, 90 static method), 304
FourEyesTokenClass (class in priva- get_class_info() (priva-
cyidea.lib.tokens.foureyestoken), 296 cyidea.lib.tokens.foureyestoken.FourEyesTokenClass
FreeIPA, 42 static method), 297
FreeOTP, 152 get_class_info() (priva-
FreeRADIUS, 232 cyidea.lib.tokens.hotptoken.HotpTokenClass
static method), 306
G get_class_info() (priva-
GDPR_LINK (privacyidea.lib.policy.ACTION attribute), cyidea.lib.tokens.motptoken.MotpTokenClass
379 static method), 308
gen_serial() (in module privacyidea.lib.token), 365 get_class_info() (priva-

Index 479
privacyIDEA Authentication System, Release 3.8

cyidea.lib.tokens.ocratoken.OcraTokenClass cyidea.lib.tokens.certificatetoken.CertificateTokenClass
static method), 310 static method), 300
get_class_info() (priva- get_class_prefix() (priva-
cyidea.lib.tokens.papertoken.PaperTokenClass cyidea.lib.tokens.daplugtoken.DaplugTokenClass
static method), 311 static method), 301
get_class_info() (priva- get_class_prefix() (priva-
cyidea.lib.tokens.passwordtoken.PasswordTokenClass cyidea.lib.tokens.emailtoken.EmailTokenClass
static method), 312 static method), 304
get_class_info() (priva- get_class_prefix() (priva-
cyidea.lib.tokens.pushtoken.PushTokenClass cyidea.lib.tokens.foureyestoken.FourEyesTokenClass
static method), 316 static method), 298
get_class_info() (priva- get_class_prefix() (priva-
cyidea.lib.tokens.questionnairetoken.QuestionnaireTokenClass
cyidea.lib.tokens.hotptoken.HotpTokenClass
class method), 317 static method), 306
get_class_info() (priva- get_class_prefix() (priva-
cyidea.lib.tokens.radiustoken.RadiusTokenClass cyidea.lib.tokens.motptoken.MotpTokenClass
static method), 320 static method), 309
get_class_info() (priva- get_class_prefix() (priva-
cyidea.lib.tokens.registrationtoken.RegistrationTokenClass cyidea.lib.tokens.ocratoken.OcraTokenClass
static method), 322 static method), 310
get_class_info() (priva- get_class_prefix() (priva-
cyidea.lib.tokens.remotetoken.RemoteTokenClass cyidea.lib.tokens.papertoken.PaperTokenClass
static method), 323 static method), 311
get_class_info() (priva- get_class_prefix() (priva-
cyidea.lib.tokens.smstoken.SmsTokenClass cyidea.lib.tokens.passwordtoken.PasswordTokenClass
static method), 326 static method), 312
get_class_info() (priva- get_class_prefix() (priva-
cyidea.lib.tokens.spasstoken.SpassTokenClass cyidea.lib.tokens.pushtoken.PushTokenClass
static method), 327 static method), 316
get_class_info() (priva- get_class_prefix() (priva-
cyidea.lib.tokens.sshkeytoken.SSHkeyTokenClass cyidea.lib.tokens.questionnairetoken.QuestionnaireTokenClass
static method), 328 static method), 318
get_class_info() (priva- get_class_prefix() (priva-
cyidea.lib.tokens.tiqrtoken.TiqrTokenClass cyidea.lib.tokens.radiustoken.RadiusTokenClass
static method), 330 static method), 320
get_class_info() (priva- get_class_prefix() (priva-
cyidea.lib.tokens.totptoken.TotpTokenClass cyidea.lib.tokens.registrationtoken.RegistrationTokenClass
static method), 331 static method), 322
get_class_info() (priva- get_class_prefix() (priva-
cyidea.lib.tokens.u2ftoken.U2fTokenClass cyidea.lib.tokens.remotetoken.RemoteTokenClass
static method), 336 static method), 323
get_class_info() (priva- get_class_prefix() (priva-
cyidea.lib.tokens.webauthntoken.WebAuthnTokenClass cyidea.lib.tokens.smstoken.SmsTokenClass
static method), 344 static method), 326
get_class_info() (priva- get_class_prefix() (priva-
cyidea.lib.tokens.yubicotoken.YubicoTokenClass cyidea.lib.tokens.spasstoken.SpassTokenClass
static method), 346 static method), 327
get_class_info() (priva- get_class_prefix() (priva-
cyidea.lib.tokens.yubikeytoken.YubikeyTokenClass cyidea.lib.tokens.sshkeytoken.SSHkeyTokenClass
static method), 347 static method), 328
get_class_prefix() (priva- get_class_prefix() (priva-
cyidea.lib.tokenclass.TokenClass static cyidea.lib.tokens.tiqrtoken.TiqrTokenClass
method), 353 static method), 330
get_class_prefix() (priva- get_class_prefix() (priva-

480 Index
privacyIDEA Authentication System, Release 3.8

cyidea.lib.tokens.totptoken.TotpTokenClass cyidea.lib.tokens.registrationtoken.RegistrationTokenClass
static method), 331 static method), 322
get_class_prefix() (priva- get_class_type() (priva-
cyidea.lib.tokens.u2ftoken.U2fTokenClass cyidea.lib.tokens.remotetoken.RemoteTokenClass
static method), 336 static method), 323
get_class_prefix() (priva- get_class_type() (priva-
cyidea.lib.tokens.webauthntoken.WebAuthnTokenClass cyidea.lib.tokens.smstoken.SmsTokenClass
static method), 344 static method), 326
get_class_prefix() (priva- get_class_type() (priva-
cyidea.lib.tokens.yubicotoken.YubicoTokenClass cyidea.lib.tokens.spasstoken.SpassTokenClass
static method), 346 static method), 327
get_class_prefix() (priva- get_class_type() (priva-
cyidea.lib.tokens.yubikeytoken.YubikeyTokenClass cyidea.lib.tokens.sshkeytoken.SSHkeyTokenClass
static method), 347 static method), 328
get_class_type() (priva- get_class_type() (priva-
cyidea.lib.tokenclass.TokenClass static cyidea.lib.tokens.tiqrtoken.TiqrTokenClass
method), 353 static method), 330
get_class_type() (priva- get_class_type() (priva-
cyidea.lib.tokens.certificatetoken.CertificateTokenClass cyidea.lib.tokens.totptoken.TotpTokenClass
static method), 300 static method), 331
get_class_type() (priva- get_class_type() (priva-
cyidea.lib.tokens.daplugtoken.DaplugTokenClass cyidea.lib.tokens.u2ftoken.U2fTokenClass
static method), 301 static method), 336
get_class_type() (priva- get_class_type() (priva-
cyidea.lib.tokens.emailtoken.EmailTokenClass cyidea.lib.tokens.webauthntoken.WebAuthnTokenClass
static method), 304 static method), 345
get_class_type() (priva- get_class_type() (priva-
cyidea.lib.tokens.foureyestoken.FourEyesTokenClass cyidea.lib.tokens.yubicotoken.YubicoTokenClass
static method), 298 static method), 346
get_class_type() (priva- get_class_type() (priva-
cyidea.lib.tokens.hotptoken.HotpTokenClass cyidea.lib.tokens.yubikeytoken.YubikeyTokenClass
static method), 306 static method), 347
get_class_type() (priva- get_conditions_tuples() (priva-
cyidea.lib.tokens.motptoken.MotpTokenClass cyidea.models.Policy method), 435
static method), 309 get_config_description() (priva-
get_class_type() (priva- cyidea.lib.machines.base.BaseMachineResolver
cyidea.lib.tokens.ocratoken.OcraTokenClass static method), 428
static method), 310 get_config_description() (priva-
get_class_type() (priva- cyidea.lib.machines.hosts.HostsMachineResolver
cyidea.lib.tokens.papertoken.PaperTokenClass class method), 429
static method), 311 get_count() (privacyidea.lib.auditmodules.base.Audit
get_class_type() (priva- method), 424
cyidea.lib.tokens.passwordtoken.PasswordTokenClass get_count() (privacyidea.lib.auditmodules.sqlaudit.Audit
static method), 312 method), 426
get_class_type() (priva- get_count_auth() (priva-
cyidea.lib.tokens.pushtoken.PushTokenClass cyidea.lib.tokenclass.TokenClass method),
static method), 316 353
get_class_type() (priva- get_count_auth_max() (priva-
cyidea.lib.tokens.questionnairetoken.QuestionnaireTokenClasscyidea.lib.tokenclass.TokenClass method),
static method), 318 353
get_class_type() (priva- get_count_auth_success() (priva-
cyidea.lib.tokens.radiustoken.RadiusTokenClass cyidea.lib.tokenclass.TokenClass method),
static method), 320 353
get_class_type() (priva- get_count_auth_success_max() (priva-

Index 481
privacyIDEA Authentication System, Release 3.8

cyidea.lib.tokenclass.TokenClass method), method), 306


353 get_init_detail() (priva-
get_count_window() (priva- cyidea.lib.tokens.motptoken.MotpTokenClass
cyidea.lib.tokenclass.TokenClass method), method), 309
353 get_init_detail() (priva-
get_default_settings() (priva- cyidea.lib.tokens.passwordtoken.PasswordTokenClass
cyidea.lib.tokenclass.TokenClass class method), 312
method), 353 get_init_detail() (priva-
get_default_settings() (priva- cyidea.lib.tokens.pushtoken.PushTokenClass
cyidea.lib.tokens.certificatetoken.CertificateTokenClass method), 316
class method), 300 get_init_detail() (priva-
get_default_settings() (priva- cyidea.lib.tokens.tiqrtoken.TiqrTokenClass
cyidea.lib.tokens.hotptoken.HotpTokenClass method), 330
class method), 306 get_init_detail() (priva-
get_default_settings() (priva- cyidea.lib.tokens.u2ftoken.U2fTokenClass
cyidea.lib.tokens.totptoken.TotpTokenClass method), 336
class method), 331 get_init_detail() (priva-
get_dynamic_policy_definitions() (in module pri- cyidea.lib.tokens.webauthntoken.WebAuthnTokenClass
vacyidea.lib.token), 365 method), 345
get_event() (privacyidea.lib.event.EventConfiguration get_init_details() (priva-
method), 412 cyidea.lib.tokenclass.TokenClass method),
get_failcount() (priva- 354
cyidea.lib.tokenclass.TokenClass method), get_job_queue() (in module privacyidea.lib.queue),
353 394
get_handled_events() (priva- get_keys() (privacyidea.lib.monitoringmodules.base.Monitoring
cyidea.lib.event.EventConfiguration method), method), 427
412 get_keys() (privacyidea.lib.monitoringmodules.sqlstats.Monitoring
get_handler_object() (in module priva- method), 428
cyidea.lib.event), 413 get_last_value() (priva-
get_hashed_pin() (privacyidea.models.Token cyidea.lib.monitoringmodules.base.Monitoring
method), 438 method), 427
get_hashlib() (privacyidea.lib.tokenclass.TokenClass get_last_value() (priva-
static method), 353 cyidea.lib.monitoringmodules.sqlstats.Monitoring
get_import_csv() (priva- method), 428
cyidea.lib.tokenclass.TokenClass static get_machine_id() (priva-
method), 353 cyidea.lib.machines.base.BaseMachineResolver
get_import_csv() (priva- method), 428
cyidea.lib.tokens.hotptoken.HotpTokenClass get_machine_id() (priva-
static method), 306 cyidea.lib.machines.hosts.HostsMachineResolver
get_import_csv() (priva- method), 429
cyidea.lib.tokens.ocratoken.OcraTokenClass get_machineresolver_id() (in module priva-
static method), 310 cyidea.models), 440
get_import_csv() (priva- get_machines() (priva-
cyidea.lib.tokens.totptoken.TotpTokenClass cyidea.lib.machines.base.BaseMachineResolver
static method), 331 method), 429
get_info() (privacyidea.models.Token method), 438 get_machines() (priva-
get_init_detail() (priva- cyidea.lib.machines.hosts.HostsMachineResolver
cyidea.lib.tokenclass.TokenClass method), method), 430
354 get_machinetoken_ids() (in module priva-
get_init_detail() (priva- cyidea.models), 440
cyidea.lib.tokens.certificatetoken.CertificateTokenClass
get_max_failcount() (priva-
method), 300 cyidea.lib.tokenclass.TokenClass method),
get_init_detail() (priva- 354
cyidea.lib.tokens.hotptoken.HotpTokenClass get_multi_otp() (in module privacyidea.lib.token),

482 Index
privacyIDEA Authentication System, Release 3.8

366 get_realms_of_token() (in module priva-


get_multi_otp() (priva- cyidea.lib.token), 366
cyidea.lib.tokenclass.TokenClass method), get_search_fields() (privacyidea.lib.user.User
354 method), 293
get_multi_otp() (priva- get_serial() (privacyidea.lib.tokenclass.TokenClass
cyidea.lib.tokens.daplugtoken.DaplugTokenClass method), 354
method), 302 get_serial_by_otp() (in module priva-
get_multi_otp() (priva- cyidea.lib.token), 367
cyidea.lib.tokens.hotptoken.HotpTokenClass get_serverpool_instance() (priva-
method), 306 cyidea.lib.resolvers.LDAPIdResolver.IdResolver
get_multi_otp() (priva- method), 422
cyidea.lib.tokens.totptoken.TotpTokenClass get_setting_type() (priva-
method), 332 cyidea.lib.tokenclass.TokenClass static
get_num_tokens_in_realm() (in module priva- method), 354
cyidea.lib.token), 366 get_setting_type() (priva-
get_one_token() (in module privacyidea.lib.token), cyidea.lib.tokens.hotptoken.HotpTokenClass
366 static method), 307
get_ordererd_resolvers() (priva- get_setting_type() (priva-
cyidea.lib.user.User method), 293 cyidea.lib.tokens.questionnairetoken.QuestionnaireTokenClass
get_otp() (in module privacyidea.lib.token), 366 static method), 318
get_otp() (privacyidea.lib.tokenclass.TokenClass get_setting_type() (priva-
method), 354 cyidea.lib.tokens.totptoken.TotpTokenClass
get_otp() (privacyidea.lib.tokens.daplugtoken.DaplugTokenClass static method), 332
method), 302 get_setting_type() (priva-
get_otp() (privacyidea.lib.tokens.hotptoken.HotpTokenClass cyidea.lib.tokens.webauthntoken.WebAuthnTokenClass
method), 307 static method), 345
get_otp() (privacyidea.lib.tokens.totptoken.TotpTokenClass
get_sshkey() (privacyidea.lib.tokens.sshkeytoken.SSHkeyTokenClass
method), 332 method), 328
get_otp_count() (priva- get_static_policy_definitions() (in module pri-
cyidea.lib.tokenclass.TokenClass method), vacyidea.lib.policy), 392
354 get_sync_timeout() (priva-
get_otp_count_window() (priva- cyidea.lib.tokens.hotptoken.HotpTokenClass
cyidea.lib.tokenclass.TokenClass method), static method), 307
354 get_sync_window() (priva-
get_otp_status() (privacyidea.models.Challenge cyidea.lib.tokenclass.TokenClass method),
method), 432 355
get_otplen() (privacyidea.lib.tokenclass.TokenClass get_token_by_otp() (in module priva-
method), 354 cyidea.lib.token), 367
get_password() (priva- get_token_id() (in module privacyidea.models), 440
cyidea.lib.tokens.passwordtoken.PasswordTokenClass.SecretPassword
get_token_owner() (in module privacyidea.lib.token),
method), 312 367
get_persistent_serverpool() (priva- get_token_type() (in module privacyidea.lib.token),
cyidea.lib.resolvers.LDAPIdResolver.IdResolver 367
method), 422 get_tokenclass_info() (in module priva-
get_pin_hash_seed() (priva- cyidea.lib.token), 367
cyidea.lib.tokenclass.TokenClass method), get_tokeninfo() (priva-
354 cyidea.lib.tokenclass.TokenClass method),
get_policy_condition_comparators() (in module 355
privacyidea.lib.policy), 391 get_tokens() (in module privacyidea.lib.token), 368
get_policy_condition_sections() (in module pri- get_tokens_from_serial_or_user() (in module pri-
vacyidea.lib.policy), 391 vacyidea.lib.token), 368
get_realms() (privacyidea.lib.tokenclass.TokenClass get_tokens_in_resolver() (in module priva-
method), 354 cyidea.lib.token), 368
get_realms() (privacyidea.models.Token method), 438 get_tokens_paginate() (in module priva-

Index 483
privacyIDEA Authentication System, Release 3.8

cyidea.lib.token), 369 cyidea.lib.resolvers.UserIdResolver.UserIdResolver


get_tokens_paginated_generator() (in module pri- class method), 417
vacyidea.lib.token), 369 getResolverClassType() (priva-
get_tokentype() (priva- cyidea.lib.resolvers.LDAPIdResolver.IdResolver
cyidea.lib.tokenclass.TokenClass method), static method), 421
355 getResolverClassType() (priva-
get_total() (privacyidea.lib.auditmodules.base.Audit cyidea.lib.resolvers.PasswdIdResolver.IdResolver
method), 424 static method), 419
get_total() (privacyidea.lib.auditmodules.sqlaudit.Audit getResolverClassType() (priva-
method), 426 cyidea.lib.resolvers.UserIdResolver.UserIdResolver
get_type() (privacyidea.lib.tokenclass.TokenClass static method), 417
method), 355 getResolverDescriptor() (priva-
get_user_displayname() (priva- cyidea.lib.resolvers.LDAPIdResolver.IdResolver
cyidea.lib.tokenclass.TokenClass method), static method), 421
355 getResolverDescriptor() (priva-
get_user_from_param() (in module priva- cyidea.lib.resolvers.PasswdIdResolver.IdResolver
cyidea.lib.user), 295 static method), 419
get_user_id() (privacyidea.lib.tokenclass.TokenClass getResolverDescriptor() (priva-
method), 355 cyidea.lib.resolvers.UserIdResolver.UserIdResolver
get_user_identifiers() (privacyidea.lib.user.User static method), 417
method), 293 getResolverId() (priva-
get_user_list() (in module privacyidea.lib.user), 295 cyidea.lib.resolvers.LDAPIdResolver.IdResolver
get_user_phone() (privacyidea.lib.user.User method), method), 421
293 getResolverId() (priva-
get_user_pin() (privacyidea.models.Token method), cyidea.lib.resolvers.PasswdIdResolver.IdResolver
438 method), 419
get_user_realms() (privacyidea.lib.user.User getResolverId() (priva-
method), 294 cyidea.lib.resolvers.UserIdResolver.UserIdResolver
get_username() (in module privacyidea.lib.user), 295 method), 417
get_validity_period_end() (priva- getResolverType() (priva-
cyidea.lib.tokenclass.TokenClass method), cyidea.lib.resolvers.LDAPIdResolver.IdResolver
355 static method), 422
get_validity_period_start() (priva- getResolverType() (priva-
cyidea.lib.tokenclass.TokenClass method), cyidea.lib.resolvers.PasswdIdResolver.IdResolver
355 static method), 419
get_values() (privacyidea.lib.monitoringmodules.base.Monitoring
getResolverType() (priva-
method), 427 cyidea.lib.resolvers.UserIdResolver.UserIdResolver
get_values() (privacyidea.lib.monitoringmodules.sqlstats.Monitoring
static method), 417
method), 428 getSearchFields() (priva-
get_webui_settings() (in module priva- cyidea.lib.resolvers.PasswdIdResolver.IdResolver
cyidea.api.lib.postpolicy), 406 method), 419
getchallenges, 120 getserial, 120
GETCHALLENGES (privacyidea.lib.policy.ACTION at- GETSERIAL (privacyidea.lib.policy.ACTION attribute),
tribute), 379 379
getrandom, 120 getUserId() (privacyidea.lib.resolvers.LDAPIdResolver.IdResolver
GETRANDOM (privacyidea.lib.policy.ACTION attribute), method), 422
379 getUserId() (privacyidea.lib.resolvers.PasswdIdResolver.IdResolver
getResolverClassDescriptor() (priva- method), 419
cyidea.lib.resolvers.LDAPIdResolver.IdResolver getUserId() (privacyidea.lib.resolvers.UserIdResolver.UserIdResolver
class method), 421 method), 417
getResolverClassDescriptor() (priva- getUserInfo() (priva-
cyidea.lib.resolvers.PasswdIdResolver.IdResolver cyidea.lib.resolvers.LDAPIdResolver.IdResolver
class method), 419 method), 422
getResolverClassDescriptor() (priva- getUserInfo() (priva-

484 Index
privacyIDEA Authentication System, Release 3.8

cyidea.lib.resolvers.PasswdIdResolver.IdResolver has_multiple_loginnames (priva-


method), 419 cyidea.lib.resolvers.UserIdResolver.UserIdResolver
getUserInfo() (priva- property), 417
cyidea.lib.resolvers.UserIdResolver.UserIdResolver
hashlib (privacyidea.lib.tokens.hotptoken.HotpTokenClass
method), 417 property), 307
getUserList() (priva- hashlib (privacyidea.lib.tokens.totptoken.TotpTokenClass
cyidea.lib.resolvers.LDAPIdResolver.IdResolver property), 332
method), 422 header_dict (privacyidea.models.SMSGateway prop-
getUserList() (priva- erty), 437
cyidea.lib.resolvers.PasswdIdResolver.IdResolver help desk, 113
method), 419 HIDE_AUDIT_COLUMNS (privacyidea.lib.policy.ACTION
getUserList() (priva- attribute), 379
cyidea.lib.resolvers.UserIdResolver.UserIdResolver
hide_audit_columns() (in module priva-
method), 417 cyidea.api.lib.prepolicy), 397
getUsername() (priva- HIDE_BUTTONS (privacyidea.lib.policy.ACTION at-
cyidea.lib.resolvers.LDAPIdResolver.IdResolver tribute), 379
method), 422 HIDE_TOKENINFO (privacyidea.lib.policy.ACTION
getUsername() (priva- attribute), 379
cyidea.lib.resolvers.PasswdIdResolver.IdResolver hide_tokeninfo() (in module priva-
method), 420 cyidea.api.lib.prepolicy), 397
getUsername() (priva- HIDE_WELCOME (privacyidea.lib.policy.ACTION at-
cyidea.lib.resolvers.UserIdResolver.UserIdResolver tribute), 379
method), 417 hKeyRequired (privacyidea.lib.tokenclass.TokenClass
GPG encryption, 214 attribute), 355
GROUP (class in privacyidea.lib.policy), 383 hKeyRequired (privacyidea.lib.tokens.certificatetoken.CertificateTokenCla
attribute), 300
H hook, 13
HA, 448 HostsMachineResolver (class in priva-
Handler Modules, 182, 187, 191, 196–199, 202–204 cyidea.lib.machines.hosts), 429
Hardware Security Module, 24 hotkeys, 450
Hardware Tokens, 88 HOTP Token, 73
has_data (privacyidea.lib.auditmodules.base.Audit HOTP tokens, 95
property), 424 HotpTokenClass (class in priva-
has_db_challenge_response() (priva- cyidea.lib.tokens.hotptoken), 305
cyidea.lib.tokenclass.TokenClass method), HSM, 24
355 HTML views, 441
has_further_challenge() (priva- http, 49
cyidea.lib.tokenclass.TokenClass method), HTTP Provider, 67
356 HTTP resolver, 49
has_further_challenge() (priva- HTTP_ENVIRONMENT (priva-
cyidea.lib.tokens.foureyestoken.FourEyesTokenClass cyidea.lib.policy.CONDITION_SECTION
method), 298 attribute), 382
has_further_challenge() (priva- HTTP_REQUEST_HEADER (priva-
cyidea.lib.tokens.hotptoken.HotpTokenClass cyidea.lib.policy.CONDITION_SECTION
method), 307 attribute), 382
has_further_challenge() (priva- HttpSMSProvider (class in priva-
cyidea.lib.smsprovider.HttpSMSProvider),
cyidea.lib.tokens.questionnairetoken.QuestionnaireTokenClass
method), 318 414
has_job_queue() (in module privacyidea.lib.queue), huey (privacyidea.lib.queues.huey_queue.HueyQueue
394 property), 393
has_multiple_loginnames (priva- HueyQueue (class in privacyidea.lib.queues.huey_queue),
cyidea.lib.resolvers.LDAPIdResolver.IdResolver 393
property), 422

Index 485
privacyIDEA Authentication System, Release 3.8

I cyidea.api.lib.prepolicy), 398
init_subject_components()
identifier (privacyidea.lib.eventhandler.base.BaseEventHandler (in module priva-
attribute), 412 cyidea.api.lib.prepolicy), 398
init_token() (in module
identifier (privacyidea.lib.eventhandler.federationhandler.FederationEventHandler privacyidea.lib.token), 370
attribute), 199 init_token_defaults() (in module priva-
cyidea.api.lib.prepolicy),
identifier (privacyidea.lib.eventhandler.requestmangler.RequestManglerEventHandler 398
attribute), 201 init_token_length_contents() (in module priva-
cyidea.api.lib.prepolicy), 398
identifier (privacyidea.lib.eventhandler.responsemangler.ResponseManglerEventHandler
attribute), 203 init_tokenlabel() (in module priva-
cyidea.api.lib.prepolicy),
identifier (privacyidea.lib.eventhandler.tokenhandler.TokenEventHandler 399
attribute), 195 initialize_log() (priva-
cyidea.lib.auditmodules.base.Audit
identifier (privacyidea.lib.eventhandler.usernotification.UserNotificationEventHandler method),
attribute), 190, 412 424
IdResolver (class in priva- instances, 21
cyidea.lib.resolvers.LDAPIdResolver), 420 INT (privacyidea.lib.policy.TYPE attribute), 390
IdResolver (class in priva- INTERNAL_ADMIN (priva-
cyidea.lib.resolvers.PasswdIdResolver), 418 cyidea.lib.eventhandler.usernotification.NOTIFY_TYPE
import, 214 attribute), 190
IMPORT (privacyidea.lib.policy.ACTION attribute), 379 is_active() (privacyidea.lib.tokenclass.TokenClass
import_event() (in module privacyidea.lib.event), 413 method), 356
import_policies() (in module privacyidea.lib.policy), is_attribute_at_all() (in module priva-
392 cyidea.lib.user), 295
import_policy() (in module privacyidea.lib.policy), is_authorized() (in module priva-
392 cyidea.api.lib.postpolicy), 406
import_token() (in module privacyidea.lib.token), 370 is_challenge_request() (priva-
inc_count_auth() (priva- cyidea.lib.tokenclass.TokenClass method),
cyidea.lib.tokenclass.TokenClass method), 356
356 is_challenge_request() (priva-
inc_count_auth_success() (priva- cyidea.lib.tokens.emailtoken.EmailTokenClass
cyidea.lib.tokenclass.TokenClass method), method), 304
356 is_challenge_request() (priva-
inc_failcount() (priva- cyidea.lib.tokens.foureyestoken.FourEyesTokenClass
cyidea.lib.tokenclass.TokenClass method), method), 298
356 is_challenge_request() (priva-
inc_otp_counter() (priva- cyidea.lib.tokens.ocratoken.OcraTokenClass
cyidea.lib.tokenclass.TokenClass method), method), 310
356 is_challenge_request() (priva-
increase() (privacyidea.models.EventCounter cyidea.lib.tokens.pushtoken.PushTokenClass
method), 433 method), 316
INCREASE_FAILCOUNTER_ON_CHALLENGE (priva- is_challenge_request() (priva-
cyidea.lib.policy.ACTION attribute), 379 cyidea.lib.tokens.questionnairetoken.QuestionnaireTokenClass
increase_failcounter_on_challenge() (in module method), 318
privacyidea.api.lib.prepolicy), 398 is_challenge_request() (priva-
Indexed Secret Token, 97 cyidea.lib.tokens.radiustoken.RadiusTokenClass
indexedsecret_force_attribute() (in module pri- method), 320
vacyidea.api.lib.prepolicy), 398 is_challenge_request() (priva-
info (privacyidea.lib.user.User property), 294 cyidea.lib.tokens.remotetoken.RemoteTokenClass
INIT (privacyidea.lib.eventhandler.tokenhandler.ACTION_TYPE method), 323
attribute), 194 is_challenge_request() (priva-
init_ca_connector() (in module priva- cyidea.lib.tokens.smstoken.SmsTokenClass
cyidea.api.lib.prepolicy), 398 method), 326
init_ca_template() (in module priva- is_challenge_request() (priva-
cyidea.api.lib.prepolicy), 398 cyidea.lib.tokens.spasstoken.SpassTokenClass
init_random_pin() (in module priva- static method), 327

486 Index
privacyIDEA Authentication System, Release 3.8

is_challenge_request() (priva- attribute), 424


cyidea.lib.tokens.u2ftoken.U2fTokenClass is_remote_user_allowed() (in module priva-
method), 336 cyidea.api.lib.prepolicy), 399
is_challenge_request() (priva- is_revoked() (privacyidea.lib.tokenclass.TokenClass
cyidea.lib.tokens.webauthntoken.WebAuthnTokenClass method), 358
method), 345 is_token_active() (in module privacyidea.lib.token),
is_challenge_request() (priva- 370
cyidea.lib.tokens.yubikeytoken.YubikeyTokenClassis_token_owner() (in module privacyidea.lib.token),
method), 348 370
is_challenge_response() (priva- is_valid() (privacyidea.models.Challenge method),
cyidea.lib.tokenclass.TokenClass method), 432
357 ISMSProvider (class in priva-
is_challenge_response() (priva- cyidea.lib.smsprovider.SMSProvider), 415
cyidea.lib.tokens.radiustoken.RadiusTokenClass
method), 320 J
is_challenge_response() (priva- job queue, 231
cyidea.lib.tokens.spasstoken.SpassTokenClass job() (in module privacyidea.lib.queue), 394
static method), 327 JOB_COLLECTOR (in module privacyidea.lib.queue), 393
is_empty() (privacyidea.lib.user.User method), 294 JobCollector (class in privacyidea.lib.queue), 393
is_fit_for_challenge() (priva- jobs (privacyidea.lib.queue.JobCollector property), 393
cyidea.lib.tokenclass.TokenClass method), jobs (privacyidea.lib.queues.huey_queue.HueyQueue
357 property), 393
is_locked() (privacyidea.lib.tokenclass.TokenClass JSON Web Token, 239
method), 357 JWT, 239
is_multichallenge_enrollable (priva-
cyidea.lib.tokenclass.TokenClass attribute), K
357 Kerberos, 42
is_multichallenge_enrollable (priva-
cyidea.lib.tokens.daplugtoken.DaplugTokenClass L
attribute), 302
LASTAUTH (privacyidea.lib.policy.ACTION attribute),
is_multichallenge_enrollable (priva-
379
cyidea.lib.tokens.hotptoken.HotpTokenClass
LDAP, 39
attribute), 307
LDAP resolver, 42
is_multichallenge_enrollable (priva-
libpolicy (class in privacyidea.lib.policydecorators),
cyidea.lib.tokens.papertoken.PaperTokenClass
410
attribute), 311
library, 292
is_multichallenge_enrollable (priva-
list_policies() (privacyidea.lib.policy.PolicyClass
cyidea.lib.tokens.pushtoken.PushTokenClass
method), 388
attribute), 316
list_tokengroups() (in module priva-
is_orphaned() (privacyidea.lib.tokenclass.TokenClass
cyidea.lib.token), 371
method), 358
load_config() (priva-
is_outofband() (priva-
cyidea.lib.machines.base.BaseMachineResolver
cyidea.lib.tokenclass.TokenClass class
method), 429
method), 358
load_config() (priva-
is_pin_change() (priva-
cyidea.lib.machines.hosts.HostsMachineResolver
cyidea.lib.tokenclass.TokenClass method),
method), 430
358
load_config() (priva-
is_previous_otp() (priva-
cyidea.lib.smsprovider.SMSProvider.ISMSProvider
cyidea.lib.tokenclass.TokenClass method),
method), 415
358
loadConfig() (privacyidea.lib.resolvers.LDAPIdResolver.IdResolver
is_previous_otp() (priva-
method), 422
cyidea.lib.tokens.hotptoken.HotpTokenClass
loadConfig() (privacyidea.lib.resolvers.PasswdIdResolver.IdResolver
method), 307
method), 420
is_readable (privacyidea.lib.auditmodules.base.Audit

Index 487
privacyIDEA Authentication System, Release 3.8

loadConfig() (privacyidea.lib.resolvers.UserIdResolver.UserIdResolver
MachineResolverConfig (class in priva-
method), 418 cyidea.models), 433
loadFile() (privacyidea.lib.resolvers.PasswdIdResolver.IdResolver
MACHINERESOLVERDELETE (priva-
method), 420 cyidea.lib.policy.ACTION attribute), 379
LOCKSCREEN (privacyidea.lib.policy.TIMEOUT_ACTION MACHINERESOLVERREAD (privacyidea.lib.policy.ACTION
attribute), 390 attribute), 379
log() (privacyidea.lib.auditmodules.base.Audit MACHINERESOLVERWRITE (priva-
method), 424 cyidea.lib.policy.ACTION attribute), 379
log_token_num() (priva- machines, 212
cyidea.lib.auditmodules.base.Audit method), MACHINES (privacyidea.lib.policy.MAIN_MENU at-
424 tribute), 383
log_used_user() (in module privacyidea.lib.user), 295 MachineToken (class in privacyidea.models), 433
LOGGED_IN_USER (priva- MachineTokenOptions (class in privacyidea.models),
cyidea.lib.eventhandler.usernotification.NOTIFY_TYPE 433
attribute), 190 MACHINETOKENS (privacyidea.lib.policy.ACTION at-
Logging, 18 tribute), 379
Logging Handler, 203 MAIN_MENU (class in privacyidea.lib.policy), 383
login (privacyidea.lib.user.User attribute), 294 MANAGESUBSCRIPTION (privacyidea.lib.policy.ACTION
login mode, 163 attribute), 379
Login Policy, 163 MANGLE (privacyidea.lib.policy.ACTION attribute), 379
login_mode() (in module priva- Mangle authentication request, 138
cyidea.lib.policydecorators), 410 Mangle policy, 138
LOGIN_TEXT (privacyidea.lib.policy.ACTION attribute), mangle() (in module privacyidea.api.lib.prepolicy), 399
379 mangle_challenge_response() (in module priva-
LOGINMODE (class in privacyidea.lib.policy), 383 cyidea.api.lib.postpolicy), 406
LOGINMODE (privacyidea.lib.policy.ACTION attribute), map client, 56
379 Match (class in privacyidea.lib.policy), 383
loglevel, 13 match_policies() (privacyidea.lib.policy.PolicyClass
LOGOUT (privacyidea.lib.policy.TIMEOUT_ACTION at- method), 388
tribute), 390 MatchingError, 386
logout time, 164, 165 MAXACTIVETOKENUSER (privacyidea.lib.policy.ACTION
LOGOUT_REDIRECT (privacyidea.lib.policy.ACTION at- attribute), 379
tribute), 379 MaxFail, 457
LOGOUTTIME (privacyidea.lib.policy.ACTION attribute), MAXTOKENREALM (privacyidea.lib.policy.ACTION at-
379 tribute), 379
lost token, 155 MAXTOKENUSER (privacyidea.lib.policy.ACTION at-
lost_token() (in module privacyidea.lib.token), 371 tribute), 379
LOSTTOKEN (privacyidea.lib.policy.ACTION attribute), MethodsMixin (class in privacyidea.models), 433
379 Migration, 103
LOSTTOKENPWCONTENTS (privacyidea.lib.policy.ACTION migration, 135, 136, 447
attribute), 379 migration strategy, 447
LOSTTOKENPWLEN (privacyidea.lib.policy.ACTION mock_fail() (in module privacyidea.api.lib.prepolicy),
attribute), 379 399
LOSTTOKENVALID (privacyidea.lib.policy.ACTION mock_success() (in module priva-
attribute), 379 cyidea.api.lib.prepolicy), 399
mode (privacyidea.lib.tokenclass.TokenClass attribute),
M 358
MACHINE (privacyidea.lib.policy.GROUP attribute), 383 mode (privacyidea.lib.tokens.pushtoken.PushTokenClass
Machine Resolvers, 428 attribute), 316
MachineApplicationBase (in module priva- mode (privacyidea.lib.tokens.sshkeytoken.SSHkeyTokenClass
cyidea.lib.applications), 376 attribute), 328
MACHINELIST (privacyidea.lib.policy.ACTION attribute), mode (privacyidea.lib.tokens.tiqrtoken.TiqrTokenClass
379 attribute), 330
MachineResolver (class in privacyidea.models), 433 MODIFYING_RESPONSE (privacyidea.lib.policy.GROUP

488 Index
privacyIDEA Authentication System, Release 3.8

attribute), 383 privacyidea.lib.tokens.webauthntoken, 337


module privacyidea.lib.user, 292
privacyidea.api, 240 privacyidea.models, 431
privacyidea.api.application, 289 Monitoring (class in priva-
privacyidea.api.auth, 240, 242 cyidea.lib.monitoringmodules.base), 426
privacyidea.api.caconnector, 285 Monitoring (class in priva-
privacyidea.api.clienttype, 291 cyidea.lib.monitoringmodules.sqlstats), 427
privacyidea.api.event, 279 monitoring modules, 426
privacyidea.api.lib.postpolicy, 405 MonitoringStats (class in privacyidea.models), 433
privacyidea.api.lib.prepolicy, 395 MotpTokenClass (class in priva-
privacyidea.api.machine, 282 cyidea.lib.tokens.motptoken), 308
privacyidea.api.machineresolver, 281 Multi Challenge, 456
privacyidea.api.monitoring, 287 multichallenge_enroll_via_validate() (in mod-
privacyidea.api.periodictask, 287 ule privacyidea.api.lib.postpolicy), 406
privacyidea.api.policy, 274 MySQL, 46
privacyidea.api.privacyideaserver, 285
privacyidea.api.radiusserver, 291 N
privacyidea.api.realm, 257 name (privacyidea.lib.token.clob_to_varchar attribute),
privacyidea.api.recover, 286 364
privacyidea.api.register, 286 no_detail_on_fail() (in module priva-
privacyidea.api.resolver, 256 cyidea.api.lib.postpolicy), 406
privacyidea.api.smsgateway, 290 no_detail_on_success() (in module priva-
privacyidea.api.smtpserver, 289 cyidea.api.lib.postpolicy), 406
privacyidea.api.subscriptions, 291 NO_REPLY_TO (privacyidea.lib.eventhandler.usernotification.NOTIFY_TYPE
privacyidea.api.system, 253 attribute), 190
privacyidea.api.token, 261 NODETAILFAIL (privacyidea.lib.policy.ACTION at-
privacyidea.api.ttype, 289 tribute), 379
privacyidea.api.user, 271 NODETAILSUCCESS (privacyidea.lib.policy.ACTION at-
privacyidea.api.validate, 244 tribute), 379
privacyidea.lib, 292 NONE (privacyidea.lib.policy.ACTIONVALUE attribute),
privacyidea.lib.auditmodules, 423 382
privacyidea.lib.event, 412 NONE (privacyidea.lib.policy.AUTOASSIGNVALUE
privacyidea.lib.eventhandler.federationhandler, attribute), 382
199 NOTIFY_TYPE (class in priva-
privacyidea.lib.eventhandler.requestmangler, cyidea.lib.eventhandler.usernotification),
201 190
Novell eDirectory, 42
privacyidea.lib.eventhandler.responsemangler,
202 NTP, 452
privacyidea.lib.eventhandler.tokenhandler,
194 O
privacyidea.lib.eventhandler.usernotification,
OATH CSV, 214
190 OCRA, 97, 109
privacyidea.lib.machines, 428 OcraTokenClass (class in priva-
privacyidea.lib.monitoringmodules, 426 cyidea.lib.tokens.ocratoken), 309
privacyidea.lib.pinhandling.base, 430 offline, 232
privacyidea.lib.policy, 376 offline_info() (in module priva-
privacyidea.lib.policydecorators, 408 cyidea.api.lib.postpolicy), 407
privacyidea.lib.queue, 393 ONLY_CHECK_USERINFO (priva-
privacyidea.lib.resolvers, 416 cyidea.lib.policy.CONDITION_CHECK
privacyidea.lib.smsprovider, 415 attribute), 382
privacyidea.lib.token, 361 OpenLDAP, 42
privacyidea.lib.tokens.ocratoken, 309 openssl, 58
privacyidea.lib.tokens.tiqrtoken, 328 OpenVPN, 239
privacyidea.lib.tokens.u2ftoken, 333

Index 489
privacyIDEA Authentication System, Release 3.8

option_dict (privacyidea.models.SMSGateway prop- password_detail_key (priva-


erty), 437 cyidea.lib.tokens.passwordtoken.PasswordTokenClass
Oracle, 46 attribute), 312
Orphaned Token, 458 password_detail_key (priva-
orphaned tokens, 222 cyidea.lib.tokens.registrationtoken.RegistrationTokenClass
OTP PIN, 458 attribute), 322
OTP Value, 458 PASSWORD_LENGTH (privacyidea.lib.policy.ACTION at-
OTPPIN (privacyidea.lib.policy.ACTION attribute), 380 tribute), 380
OTPPINCONTENTS (privacyidea.lib.policy.ACTIONPasswordReset (class in privacyidea.models), 434
attribute), 380 PASSWORDRESET (privacyidea.lib.policy.ACTION at-
OTPPINMAXLEN (privacyidea.lib.policy.ACTION at- tribute), 380
tribute), 380 PasswordTokenClass (class in priva-
OTPPINMINLEN (privacyidea.lib.policy.ACTION at- cyidea.lib.tokens.passwordtoken), 312
tribute), 380 PasswordTokenClass.SecretPassword (class in pri-
OTPPINRANDOM (privacyidea.lib.policy.ACTION at- vacyidea.lib.tokens.passwordtoken), 312
tribute), 380 Penrose, 42
OTPPINSETRANDOM (privacyidea.lib.policy.ACTION at- periodic task, 205
tribute), 380 PeriodicTask (class in privacyidea.models), 434
OTRS, 232 PeriodicTaskLastRun (class in privacyidea.models),
Override client, 56 434
overview, 3 PeriodicTaskOption (class in privacyidea.models),
ownCloud, 232, 238 435
PERIODICTASKREAD (privacyidea.lib.policy.ACTION at-
P tribute), 380
PAM, 232, 233 PERIODICTASKWRITE (privacyidea.lib.policy.ACTION
pam_yubico, 233 attribute), 380
Paper Token, 99 pi-manage, 22, 445
papertoken_count() (in module priva- PIN (privacyidea.lib.policy.GROUP attribute), 383
cyidea.api.lib.prepolicy), 399 PIN policies, 153, 154
PaperTokenClass (class in priva- PIN policy, 116, 131
cyidea.lib.tokens.papertoken), 311 PinHandler, 153, 430
PinHandler (class in privacyidea.lib.pinhandling.base),
parameters() (privacyidea.lib.smsprovider.HttpSMSProvider.HttpSMSProvider
class method), 414 430
PINHANDLING (privacyidea.lib.policy.ACTION attribute),
parameters() (privacyidea.lib.smsprovider.SipgateSMSProvider.SipgateSMSProvider
class method), 414 380
pip install, 4
parameters() (privacyidea.lib.smsprovider.SMSProvider.ISMSProvider
class method), 415 policies, 113, 170, 174
policies (privacyidea.lib.policy.PolicyClass property),
parameters() (privacyidea.lib.smsprovider.SmtpSMSProvider.SmtpSMSProvider
class method), 415 389
PASSNOTOKEN (privacyidea.lib.policy.ACTION attribute), policies() (privacyidea.lib.policy.Match method), 385
380 Policy (class in privacyidea.models), 435
PASSNOUSER (privacyidea.lib.policy.ACTION attribute), policy template URL, 165
380 policy templates, 174
passOnNoToken, 136 PolicyClass (class in privacyidea.lib.policy), 386
passOnNoUser, 136 PolicyCondition (class in privacyidea.models), 435
passthru, 135, 136 POLICYDELETE (privacyidea.lib.policy.ACTION at-
PASSTHRU (privacyidea.lib.policy.ACTION attribute), tribute), 380
380 POLICYREAD (privacyidea.lib.policy.ACTION attribute),
PASSTHRU_ASSIGN (privacyidea.lib.policy.ACTION at- 380
tribute), 380 POLICYTEMPLATEURL (privacyidea.lib.policy.ACTION
password reset, 132 attribute), 380
PASSWORD_CONTENTS (privacyidea.lib.policy.ACTION POLICYWRITE (privacyidea.lib.policy.ACTION attribute),
attribute), 380 380
Post Handling, 181

490 Index
privacyIDEA Authentication System, Release 3.8

post_success() (priva- privacyidea.api.lib.prepolicy


cyidea.lib.tokenclass.TokenClass method), module, 395
358 privacyidea.api.machine
post_success() (priva- module, 282
cyidea.lib.tokens.registrationtoken.RegistrationTokenClass
privacyidea.api.machineresolver
method), 322 module, 281
PostgreSQL, 46 privacyidea.api.monitoring
postpolicy (class in privacyidea.api.lib.postpolicy), module, 287
407 privacyidea.api.periodictask
postrequest (class in privacyidea.api.lib.postpolicy), module, 287
407 privacyidea.api.policy
Pre Handling, 181 module, 274
preferred_client_mode() (in module priva- privacyidea.api.privacyideaserver
cyidea.api.lib.postpolicy), 407 module, 285
PREFERREDCLIENTMODE (privacyidea.lib.policy.ACTION privacyidea.api.radiusserver
attribute), 380 module, 291
prepare_verify_enrollment() (priva- privacyidea.api.realm
cyidea.lib.tokenclass.TokenClass method), module, 257
358 privacyidea.api.recover
prepare_verify_enrollment() (priva- module, 286
cyidea.lib.tokens.emailtoken.EmailTokenClass privacyidea.api.register
method), 304 module, 286
prepare_verify_enrollment() (priva- privacyidea.api.resolver
cyidea.lib.tokens.hotptoken.HotpTokenClass module, 256
method), 307 privacyidea.api.smsgateway
prepare_verify_enrollment() (priva- module, 290
cyidea.lib.tokens.smstoken.SmsTokenClass privacyidea.api.smtpserver
method), 326 module, 289
prepolicy (class in privacyidea.api.lib.prepolicy), 400 privacyidea.api.subscriptions
preseeded, 95 module, 291
previous_otp_offset (priva- privacyidea.api.system
cyidea.lib.tokens.hotptoken.HotpTokenClass module, 253
attribute), 308 privacyidea.api.token
previous_otp_offset (priva- module, 261
cyidea.lib.tokens.totptoken.TotpTokenClass privacyidea.api.ttype
attribute), 332 module, 289
PRIVACYIDEA (privacyidea.lib.policy.LOGINMODE at- privacyidea.api.user
tribute), 383 module, 271
privacyIDEA Authenticator, 229 privacyidea.api.validate
privacyIDEA server, 64 module, 244
privacyidea.api privacyidea.lib
module, 240 module, 292
privacyidea.api.application privacyidea.lib.auditmodules
module, 289 module, 423
privacyidea.api.auth privacyidea.lib.event
module, 240, 242 module, 412
privacyidea.api.caconnector privacyidea.lib.eventhandler.federationhandler
module, 285 module, 199
privacyidea.api.clienttype privacyidea.lib.eventhandler.requestmangler
module, 291 module, 201
privacyidea.api.event privacyidea.lib.eventhandler.responsemangler
module, 279 module, 202
privacyidea.api.lib.postpolicy privacyidea.lib.eventhandler.tokenhandler
module, 405 module, 194

Index 491
privacyIDEA Authentication System, Release 3.8

privacyidea.lib.eventhandler.usernotification Q
module, 190 Question Token, 102
privacyidea.lib.machines Questionnaire Token, 102
module, 428 QuestionnaireTokenClass (class in priva-
privacyidea.lib.monitoringmodules cyidea.lib.tokens.questionnairetoken), 317
module, 426 queue, 231
privacyidea.lib.pinhandling.base
module, 430 R
privacyidea.lib.policy Radius Attribute Mapping, 458
module, 376 radius migration, 447
privacyidea.lib.policydecorators RADIUS server, 56, 64
module, 408 radius server, 447
privacyidea.lib.queue RADIUS token, 103
module, 393 RADIUSServer (class in privacyidea.models), 436
privacyidea.lib.resolvers RADIUSSERVERREAD (privacyidea.lib.policy.ACTION at-
module, 416 tribute), 380
privacyidea.lib.smsprovider RADIUSSERVERWRITE (privacyidea.lib.policy.ACTION
module, 415 attribute), 380
privacyidea.lib.token RadiusTokenClass (class in priva-
module, 361 cyidea.lib.tokens.radiustoken), 319
privacyidea.lib.tokens.ocratoken read_keys() (privacyidea.lib.auditmodules.base.Audit
module, 309 method), 424
privacyidea.lib.tokens.tiqrtoken Realm (class in privacyidea.models), 436
module, 328 REALM (privacyidea.lib.policy.ACTION attribute), 380
privacyidea.lib.tokens.u2ftoken realm (privacyidea.lib.user.User attribute), 294
module, 333 realm autocreation, 53
privacyidea.lib.tokens.webauthntoken realm edit, 52
module, 337 realm relation, 51
privacyidea.lib.user realm() (privacyidea.lib.policy.Match class method),
module, 292 385
privacyidea.models realmadmin() (in module privacyidea.api.lib.prepolicy),
module, 431 400
privacyideaadm, 218 Realmbox, 166
PrivacyIDEAServer (class in privacyidea.models), 436 REALMDROPDOWN (privacyidea.lib.policy.ACTION at-
PRIVACYIDEASERVERREAD (priva- tribute), 380
cyidea.lib.policy.ACTION attribute), 380 Realms, 459
PRIVACYIDEASERVERWRITE (priva- realms, 51
cyidea.lib.policy.ACTION attribute), 380 realms_dict_to_string() (priva-
proxies, 56 cyidea.lib.tokens.foureyestoken.FourEyesTokenClass
PSKC, 214 static method), 298
push direct authentication, 142 recurring task, 205
Push Token, 100 Red Hat, 8
push token, 142, 143 REGISTER (privacyidea.lib.policy.SCOPE attribute), 390
pushtoken_add_config() (in module priva- register policy, 170
cyidea.api.lib.prepolicy), 400 register_app() (in module privacyidea.lib.queue), 394
pushtoken_disable_wait() (in module priva- register_app() (privacyidea.lib.queue.JobCollector
cyidea.api.lib.prepolicy), 400 method), 393
pushtoken_wait() (in module priva- register_job() (privacyidea.lib.queue.JobCollector
cyidea.api.lib.prepolicy), 400 method), 394
PushTokenClass (class in priva- register_job() (priva-
cyidea.lib.tokens.pushtoken), 313 cyidea.lib.queues.base.BaseQueue method),
pw token, 154 394
register_job() (priva-
cyidea.lib.queues.huey_queue.HueyQueue

492 Index
privacyIDEA Authentication System, Release 3.8

method), 393 ResolverRealm (class in privacyidea.models), 436


REGISTERBODY (privacyidea.lib.policy.ACTION at- RESOLVERWRITE (privacyidea.lib.policy.ACTION at-
tribute), 380 tribute), 381
registration, 89 ResponseMangler, 202
registration token, 154 ResponseManglerEventHandler (class in priva-
REGISTRATIONCODE_CONTENTS (priva- cyidea.lib.eventhandler.responsemangler),
cyidea.lib.policy.ACTION attribute), 380 202
REGISTRATIONCODE_LENGTH (priva- REST, 240
cyidea.lib.policy.ACTION attribute), 380 Restore, 22, 82
RegistrationTokenClass (class in priva- RESYNC (privacyidea.lib.policy.ACTION attribute), 381
cyidea.lib.tokens.registrationtoken), 321 resync() (privacyidea.lib.tokenclass.TokenClass
Remote token, 104 method), 358
remote_user, 163 resync() (privacyidea.lib.tokens.daplugtoken.DaplugTokenClass
REMOTE_USER (class in privacyidea.lib.policy), 390 method), 302
REMOTE_USER (privacyidea.lib.policy.ACTION attribute), resync() (privacyidea.lib.tokens.hotptoken.HotpTokenClass
380 method), 308
RemoteTokenClass (class in priva- resync() (privacyidea.lib.tokens.totptoken.TotpTokenClass
cyidea.lib.tokens.remotetoken), 322 method), 332
remove_token() (in module privacyidea.lib.token), 371 resync_token() (in module privacyidea.lib.token), 372
REMOVE_TOKENGROUP (priva- RESYNC_VIA_MULTICHALLENGE (priva-
cyidea.lib.eventhandler.tokenhandler.ACTION_TYPE cyidea.lib.policy.ACTION attribute), 381
attribute), 194 retention time, 209
request, 92 REVOKE (privacyidea.lib.policy.ACTION attribute), 381
RequestMangler, 199 revoke() (privacyidea.lib.tokenclass.TokenClass
RequestManglerEventHandler (class in priva- method), 358
cyidea.lib.eventhandler.requestmangler), 201 revoke() (privacyidea.lib.tokens.certificatetoken.CertificateTokenClass
required_email() (in module priva- method), 300
cyidea.api.lib.prepolicy), 400 revoke_token() (in module privacyidea.lib.token), 372
required_piv_attestation() (in module priva- Revoked Token, 459
cyidea.api.lib.prepolicy), 401 RFC6030, 214
REQUIREDEMAIL (privacyidea.lib.policy.ACTION at- RHEL, 8
tribute), 380 Rollout State, 459
RESET (privacyidea.lib.policy.ACTION attribute), 380 rollout strategy, 446
reset password, 132 rollout_state (privacyidea.lib.tokenclass.TokenClass
reset() (privacyidea.lib.tokenclass.TokenClass property), 358
method), 358 RPM, 11
reset_all_user_tokens() (in module priva-
cyidea.lib.policydecorators), 411 S
reset_token() (in module privacyidea.lib.token), 371 SAML, 232
RESETALLTOKENS (privacyidea.lib.policy.ACTION SAML attributes, 42, 55
attribute), 380 save() (privacyidea.lib.tokenclass.TokenClass method),
resolver, 49 358
Resolver (class in privacyidea.models), 436 save() (privacyidea.models.PeriodicTask method), 434
RESOLVER (privacyidea.lib.policy.ACTION attribute), save() (privacyidea.models.PeriodicTaskLastRun
380 method), 435
resolver (privacyidea.lib.user.User attribute), 294 save() (privacyidea.models.PeriodicTaskOption
resolver priority, 52 method), 435
Resolver(Machine), 459 save() (privacyidea.models.RADIUSServer method),
Resolver(UserId), 459 436
ResolverConfig (class in privacyidea.models), 436 save() (privacyidea.models.TokenRealm method), 440
RESOLVERDELETE (privacyidea.lib.policy.ACTION save() (privacyidea.models.TokenTokengroup method),
attribute), 380 440
RESOLVERREAD (privacyidea.lib.policy.ACTION at- save_client_application_type() (in module priva-
tribute), 381 cyidea.api.lib.prepolicy), 401

Index 493
privacyIDEA Authentication System, Release 3.8

save_config_timestamp() (in module priva- set_count_window() (priva-


cyidea.models), 440 cyidea.lib.tokenclass.TokenClass method),
save_pin_change() (in module priva- 359
cyidea.api.lib.postpolicy), 407 SET_COUNTWINDOW (priva-
SCIM resolver, 48 cyidea.lib.eventhandler.tokenhandler.ACTION_TYPE
Scope, 460 attribute), 195
scope, 113 set_data() (privacyidea.models.Challenge method),
SCOPE (class in privacyidea.lib.policy), 390 432
Script Handler, 196 set_defaults() (in module privacyidea.lib.token), 373
Search on Enter, 167 set_defaults() (priva-
search() (privacyidea.lib.auditmodules.base.Audit cyidea.lib.tokenclass.TokenClass method),
method), 425 359
search() (privacyidea.lib.auditmodules.sqlaudit.Audit SET_DESCRIPTION (priva-
method), 426 cyidea.lib.eventhandler.tokenhandler.ACTION_TYPE
SEARCH_ON_ENTER (privacyidea.lib.policy.ACTION at- attribute), 195
tribute), 381 set_description() (in module privacyidea.lib.token),
search_query() (priva- 373
cyidea.lib.auditmodules.base.Audit method), set_description() (priva-
425 cyidea.lib.tokenclass.TokenClass method),
search_query() (priva- 359
cyidea.lib.auditmodules.sqlaudit.Audit set_event() (in module privacyidea.lib.event), 413
method), 426 set_failcount() (priva-
Security Module, 24 cyidea.lib.tokenclass.TokenClass method),
Seed, 460 359
seedable, 95 SET_FAILCOUNTER (priva-
selfservice policies, 128 cyidea.lib.eventhandler.tokenhandler.ACTION_TYPE
send() (privacyidea.lib.pinhandling.base.PinHandler attribute), 195
method), 431 set_failcounter() (in module privacyidea.lib.token),
SERIAL (privacyidea.lib.policy.ACTION attribute), 381 373
SET (privacyidea.lib.eventhandler.requestmangler.ACTION_TYPE
set_hashed_pin() (privacyidea.models.Token
attribute), 201 method), 438
SET (privacyidea.lib.eventhandler.responsemangler.ACTION_TYPE
set_hashlib() (in module privacyidea.lib.token), 373
attribute), 202 set_hashlib() (privacyidea.lib.tokenclass.TokenClass
SET (privacyidea.lib.policy.ACTION attribute), 381 method), 359
set_attribute() (privacyidea.lib.user.User method), set_info() (privacyidea.models.Token method), 438
294 set_init_details() (priva-
set_conditions() (privacyidea.models.Policy cyidea.lib.tokenclass.TokenClass method),
method), 435 359
set_count_auth() (in module privacyidea.lib.token), set_last_run() (privacyidea.models.PeriodicTask
372 method), 434
set_count_auth() (priva- set_max_failcount() (in module priva-
cyidea.lib.tokenclass.TokenClass method), cyidea.lib.token), 373
358 SET_MAXFAIL (privacyidea.lib.eventhandler.tokenhandler.ACTION_TYPE
set_count_auth_max() (priva- attribute), 195
cyidea.lib.tokenclass.TokenClass method), set_maxfail() (privacyidea.lib.tokenclass.TokenClass
359 method), 359
set_count_auth_success() (priva- set_next_pin_change() (priva-
cyidea.lib.tokenclass.TokenClass method), cyidea.lib.tokenclass.TokenClass method),
359 359
set_count_auth_success_max() (priva- set_otp_count() (priva-
cyidea.lib.tokenclass.TokenClass method), cyidea.lib.tokenclass.TokenClass method),
359 359
set_count_window() (in module priva- set_otpkey() (privacyidea.lib.tokenclass.TokenClass
cyidea.lib.token), 372 method), 359

494 Index
privacyIDEA Authentication System, Release 3.8

set_otplen() (in module privacyidea.lib.token), 374 set_user_pin() (priva-


set_otplen() (privacyidea.lib.tokenclass.TokenClass cyidea.lib.tokenclass.TokenClass method),
method), 359 360
set_pin() (in module privacyidea.lib.token), 374 SET_VALIDITY (privacyidea.lib.eventhandler.tokenhandler.ACTION_TYPE
set_pin() (privacyidea.lib.tokenclass.TokenClass attribute), 195
method), 359 set_validity_period_end() (in module priva-
set_pin() (privacyidea.lib.tokens.certificatetoken.CertificateTokenClass
cyidea.lib.token), 375
method), 300 set_validity_period_end() (priva-
set_pin() (privacyidea.models.Token method), 439 cyidea.lib.tokenclass.TokenClass method),
set_pin_hash_seed() (priva- 360
cyidea.lib.tokenclass.TokenClass method), set_validity_period_start() (in module priva-
359 cyidea.lib.token), 375
set_pin_so() (in module privacyidea.lib.token), 374 set_validity_period_start() (priva-
set_pin_user() (in module privacyidea.lib.token), 374 cyidea.lib.tokenclass.TokenClass method),
set_policy() (in module privacyidea.lib.policy), 392 360
SET_RANDOM_PIN (priva- SETDESCRIPTION (privacyidea.lib.policy.ACTION
cyidea.lib.eventhandler.tokenhandler.ACTION_TYPE attribute), 381
attribute), 195 SETHSM (privacyidea.lib.policy.ACTION attribute), 381
set_random_pin() (in module priva- SETPIN (privacyidea.lib.policy.ACTION attribute), 381
cyidea.api.lib.prepolicy), 401 SETRANDOMPIN (privacyidea.lib.policy.ACTION at-
set_realm() (in module privacyidea.api.lib.prepolicy), tribute), 381
401 SETREALM (privacyidea.lib.policy.ACTION attribute),
set_realms() (in module privacyidea.lib.token), 374 381
set_realms() (privacyidea.lib.tokenclass.TokenClass SETTING_ACTIONS (privacyidea.lib.policy.GROUP at-
method), 359 tribute), 383
set_realms() (privacyidea.models.Token method), 439 SETTOKENINFO (privacyidea.lib.policy.ACTION at-
set_so_pin() (privacyidea.lib.tokenclass.TokenClass tribute), 381
method), 360 setup tool, 79
set_so_pin() (privacyidea.models.Token method), 439 setup() (privacyidea.lib.resolvers.PasswdIdResolver.IdResolver
set_sync_window() (in module privacyidea.lib.token), static method), 420
375 shortcuts, 450
set_sync_window() (priva- SHOW_ANDROID_AUTHENTICATOR (priva-
cyidea.lib.tokenclass.TokenClass method), cyidea.lib.policy.ACTION attribute), 381
360 SHOW_CUSTOM_AUTHENTICATOR (priva-
set_tokengroups() (in module privacyidea.lib.token), cyidea.lib.policy.ACTION attribute), 381
375 SHOW_IOS_AUTHENTICATOR (priva-
set_tokengroups() (priva- cyidea.lib.policy.ACTION attribute), 381
cyidea.lib.tokenclass.TokenClass method), SHOW_NODE (privacyidea.lib.policy.ACTION attribute),
360 381
set_tokengroups() (privacyidea.models.Token SHOW_SEED (privacyidea.lib.policy.ACTION attribute),
method), 439 381
SET_TOKENINFO (priva- sign_response() (in module priva-
cyidea.lib.eventhandler.tokenhandler.ACTION_TYPE cyidea.api.lib.postpolicy), 407
attribute), 195 Sipgate, 74
set_tokeninfo() (priva- SipgateSMSProvider (class in priva-
cyidea.lib.tokenclass.TokenClass method), cyidea.lib.smsprovider.SipgateSMSProvider),
360 414
SET_TOKENREALM (priva- SMS, 89
cyidea.lib.eventhandler.tokenhandler.ACTION_TYPE SMS automatic resend, 137
attribute), 195 SMS Gateway, 67, 74
set_type() (privacyidea.lib.tokenclass.TokenClass SMS policy, 136
method), 360 SMS Provider, 67, 414
SET_USER_ATTRIBUTES (privacyidea.lib.policy.ACTION SMS text, 136
attribute), 381 SMS Token, 73

Index 495
privacyIDEA Authentication System, Release 3.8

SMS token, 106 361


sms_identifiers() (in module priva- STRING (privacyidea.lib.policy.TYPE attribute), 390
cyidea.api.lib.prepolicy), 401 submit_message() (priva-
SMSGateway (class in privacyidea.models), 436 cyidea.lib.smsprovider.HttpSMSProvider.HttpSMSProvider
SMSGatewayOption (class in privacyidea.models), 437 method), 414
SMSGATEWAYREAD (privacyidea.lib.policy.ACTION submit_message() (priva-
attribute), 381 cyidea.lib.smsprovider.SipgateSMSProvider.SipgateSMSProvider
SMSGATEWAYWRITE (privacyidea.lib.policy.ACTION at- method), 414
tribute), 381 submit_message() (priva-
SmsTokenClass (class in priva- cyidea.lib.smsprovider.SMSProvider.ISMSProvider
cyidea.lib.tokens.smstoken), 324 method), 416
SMTP server, 63 submit_message() (priva-
SMTPServer (class in privacyidea.models), 437 cyidea.lib.smsprovider.SmtpSMSProvider.SmtpSMSProvider
SMTPSERVERREAD (privacyidea.lib.policy.ACTION method), 415
attribute), 381 Subscription, 460
SMTPSERVERWRITE (privacyidea.lib.policy.ACTION at- Subscription (class in privacyidea.models), 437
tribute), 381 superuser realm, 113
SmtpSMSProvider (class in priva- SYSTEM (privacyidea.lib.policy.GROUP attribute), 383
cyidea.lib.smsprovider.SmtpSMSProvider), system config, 53
415 SYSTEMDELETE (privacyidea.lib.policy.ACTION at-
Software Tokens, 88 tribute), 381
SPass token, 106 SYSTEMREAD (privacyidea.lib.policy.ACTION attribute),
SpassTokenClass (class in priva- 381
cyidea.lib.tokens.spasstoken), 326 SYSTEMWRITE (privacyidea.lib.policy.ACTION attribute),
split_pin_pass() (priva- 381
cyidea.lib.tokenclass.TokenClass method),
360 T
split_pin_pass() (priva- TAN Token, 108
cyidea.lib.tokens.daplugtoken.DaplugTokenClass tantoken_count() (in module priva-
method), 302 cyidea.api.lib.prepolicy), 402
split_pin_pass() (priva- task queue, 231
cyidea.lib.tokens.radiustoken.RadiusTokenClass templates, 441
method), 321 test_config() (privacyidea.lib.tokenclass.TokenClass
split_uri() (privacyidea.lib.resolvers.LDAPIdResolver.IdResolver static method), 361
static method), 423 test_config() (priva-
split_user() (in module privacyidea.lib.user), 295 cyidea.lib.tokens.emailtoken.EmailTokenClass
SplitAtSign, 460 class method), 304
SQL resolver, 46 testconnection() (priva-
sqlite, 46 cyidea.lib.machines.base.BaseMachineResolver
SSH Key, 89 static method), 429
SSH keys, 106 testconnection() (priva-
SSHkeyTokenClass (class in priva- cyidea.lib.machines.hosts.HostsMachineResolver
cyidea.lib.tokens.sshkeytoken), 328 static method), 430
START (privacyidea.lib.eventhandler.tokenhandler.VALIDITYtestconnection() (priva-
attribute), 195 cyidea.lib.resolvers.LDAPIdResolver.IdResolver
STATISTICSDELETE (privacyidea.lib.policy.ACTION at- class method), 423
tribute), 381 testconnection() (priva-
STATISTICSREAD (privacyidea.lib.policy.ACTION cyidea.lib.resolvers.UserIdResolver.UserIdResolver
attribute), 381 class method), 418
status_validation_fail() (priva- themes, 442
cyidea.lib.tokenclass.TokenClass method), Time, 452
361 Time server, 452
status_validation_success() (priva- Time Step, 460
cyidea.lib.tokenclass.TokenClass method), Time Window, 460

496 Index
privacyIDEA Authentication System, Release 3.8

timeout, 165 attribute), 383


timeout action, 165 TOKENISSUER (privacyidea.lib.policy.ACTION attribute),
TIMEOUT_ACTION (class in privacyidea.lib.policy), 390 381
TIMEOUT_ACTION (privacyidea.lib.policy.ACTION TOKENLABEL (privacyidea.lib.policy.ACTION attribute),
attribute), 381 382
timeshift (privacyidea.lib.tokens.totptoken.TotpTokenClass TOKENLIST (privacyidea.lib.policy.ACTION attribute),
property), 332 382
TimestampMethodsMixin (class in priva- Tokenowner, 461
cyidea.models), 437 TokenOwner (class in privacyidea.models), 439
timestep (privacyidea.lib.tokens.totptoken.TotpTokenClassTOKENOWNER (privacyidea.lib.eventhandler.usernotification.NOTIFY_TYPE
property), 332 attribute), 190
timewindow (privacyidea.lib.tokens.totptoken.TotpTokenClassTOKENPAGESIZE (privacyidea.lib.policy.ACTION at-
property), 332 tribute), 382
TiQR, 89, 109 TOKENPIN (privacyidea.lib.policy.ACTIONVALUE
TiQR Token, 74 attribute), 382
TiqrTokenClass (class in priva- TokenRealm (class in privacyidea.models), 440
cyidea.lib.tokens.tiqrtoken), 329 TOKENREALMS (privacyidea.lib.policy.ACTION attribute),
Token, 460 382
token, 3 TOKENROLLOVER (privacyidea.lib.policy.ACTION at-
Token (class in privacyidea.models), 437 tribute), 382
TOKEN (privacyidea.lib.policy.CONDITION_SECTION TOKENS (privacyidea.lib.policy.MAIN_MENU attribute),
attribute), 383 383
TOKEN (privacyidea.lib.policy.GROUP attribute), 383 tokensview, 33
token configuration, 71 TokenTokengroup (class in privacyidea.models), 440
token default settings, 53 TOKENTYPE (privacyidea.lib.policy.ACTION attribute),
Token Enrollment Wizard, 217 382
Token Handler, 191 TOKENWIZARD (privacyidea.lib.policy.ACTION attribute),
Token Image, 152 382
Token specific PIN policy, 116, 131 TOKENWIZARD2ND (privacyidea.lib.policy.ACTION
token types, 89 attribute), 382
Token view page size, 165 tools, 222
Token wizard, 166 TOOLS (privacyidea.lib.policy.GROUP attribute), 383
token() (privacyidea.lib.policy.Match class method), TOTP Token, 76
386 TotpTokenClass (class in priva-
token_exist() (in module privacyidea.lib.token), 375 cyidea.lib.tokens.totptoken), 331
TokenClass (class in privacyidea.lib.tokenclass), 348 transaction_id, 74
TokenEventHandler (class in priva- TRIGGERCHALLENGE (privacyidea.lib.policy.ACTION at-
cyidea.lib.eventhandler.tokenhandler), 195 tribute), 382
Tokengroup (class in privacyidea.models), 440 Two Man, 90
TOKENGROUP (privacyidea.lib.policy.GROUP attribute), twostep, 229
383 twostep_enrollment_activation() (in module pri-
TOKENGROUP_ADD (privacyidea.lib.policy.ACTION vacyidea.api.lib.prepolicy), 402
attribute), 381 twostep_enrollment_parameters() (in module pri-
TOKENGROUP_DELETE (privacyidea.lib.policy.ACTION vacyidea.api.lib.prepolicy), 402
attribute), 381 TYPE (class in privacyidea.lib.policy), 390
TOKENGROUP_LIST (privacyidea.lib.policy.ACTION at-
tribute), 381 U
TOKENGROUPS (privacyidea.lib.policy.ACTION attribute), U2F, 110
381 U2F Token, 76
Tokeninfo, 461 u2ftoken_allowed() (in module priva-
TokenInfo (class in privacyidea.models), 439 cyidea.api.lib.prepolicy), 402
TOKENINFO (privacyidea.lib.policy.ACTION attribute), u2ftoken_verify_cert() (in module priva-
381 cyidea.api.lib.prepolicy), 402
TOKENINFO (privacyidea.lib.policy.CONDITION_SECTION

Index 497
privacyIDEA Authentication System, Release 3.8

U2fTokenClass (class in priva- method), 332


cyidea.lib.tokens.u2ftoken), 335 update() (privacyidea.lib.tokens.u2ftoken.U2fTokenClass
ubuntu, 6 method), 336
ui_get_enroll_tokentypes() (priva- update() (privacyidea.lib.tokens.webauthntoken.WebAuthnTokenClass
cyidea.lib.policy.PolicyClass method), 389 method), 345
ui_get_main_menus() (priva- update() (privacyidea.lib.tokens.yubicotoken.YubicoTokenClass
cyidea.lib.policy.PolicyClass method), 389 method), 346
ui_get_rights() (privacyidea.lib.policy.PolicyClass update() (privacyidea.lib.tokens.yubikeytoken.YubikeyTokenClass
method), 390 method), 348
UNASSIGN (privacyidea.lib.eventhandler.tokenhandler.ACTION_TYPE
update_otpkey() (privacyidea.models.Token method),
attribute), 195 439
UNASSIGN (privacyidea.lib.policy.ACTION attribute), update_type() (privacyidea.models.Token method),
382 439
unassign_token() (in module privacyidea.lib.token), update_user() (priva-
376 cyidea.lib.resolvers.LDAPIdResolver.IdResolver
unassign_tokengroup() (in module priva- method), 423
cyidea.lib.token), 376 update_user() (priva-
update() (privacyidea.lib.tokenclass.TokenClass cyidea.lib.resolvers.UserIdResolver.UserIdResolver
method), 361 method), 418
update() (privacyidea.lib.tokens.certificatetoken.CertificateTokenClass
update_user_info() (privacyidea.lib.user.User
method), 300 method), 294
update() (privacyidea.lib.tokens.emailtoken.EmailTokenClass UPDATEUSER (privacyidea.lib.policy.ACTION attribute),
method), 304 382
update() (privacyidea.lib.tokens.foureyestoken.FourEyesTokenClass
User (class in privacyidea.lib.user), 292
method), 298 USER (privacyidea.lib.policy.GROUP attribute), 383
update() (privacyidea.lib.tokens.hotptoken.HotpTokenClassUSER (privacyidea.lib.policy.SCOPE attribute), 390
method), 308 user (privacyidea.lib.tokenclass.TokenClass property),
update() (privacyidea.lib.tokens.motptoken.MotpTokenClass 361
method), 309 User Attributes, 38
update() (privacyidea.lib.tokens.ocratoken.OcraTokenClass user cache, 50
method), 310 User Notification, 187, 412
update() (privacyidea.lib.tokens.papertoken.PaperTokenClass user policies, 128
method), 311 user registration, 170
update() (privacyidea.lib.tokens.passwordtoken.PasswordTokenClass
User view page size, 165
method), 312 user() (privacyidea.lib.policy.Match class method), 386
update() (privacyidea.lib.tokens.pushtoken.PushTokenClass UserCache (class in privacyidea.models), 440
method), 316 USERDETAILS (privacyidea.lib.policy.ACTION attribute),
update() (privacyidea.lib.tokens.questionnairetoken.QuestionnaireTokenClass
382
method), 318 UserID, 461
update() (privacyidea.lib.tokens.radiustoken.RadiusTokenClass
UserIdResolver (class in priva-
method), 321 cyidea.lib.resolvers.UserIdResolver), 416
update() (privacyidea.lib.tokens.registrationtoken.RegistrationTokenClass
useridresolvers, 39, 416
method), 322 Userinfo, 461
update() (privacyidea.lib.tokens.remotetoken.RemoteTokenClass
USERINFO (privacyidea.lib.policy.CONDITION_SECTION
method), 323 attribute), 383
update() (privacyidea.lib.tokens.smstoken.SmsTokenClass USERLIST (privacyidea.lib.policy.ACTION attribute),
method), 326 382
update() (privacyidea.lib.tokens.spasstoken.SpassTokenClass UserNotificationEventHandler (class in priva-
method), 327 cyidea.lib.eventhandler.usernotification), 190,
update() (privacyidea.lib.tokens.sshkeytoken.SSHkeyTokenClass 412
method), 328 USERPAGESIZE (privacyidea.lib.policy.ACTION at-
update() (privacyidea.lib.tokens.tiqrtoken.TiqrTokenClass tribute), 382
method), 330 Users, 121
update() (privacyidea.lib.tokens.totptoken.TotpTokenClassUSERS (privacyidea.lib.policy.MAIN_MENU attribute),

498 Index
privacyIDEA Authentication System, Release 3.8

383 weigh_token_type() (in module priva-


Userstore, 461 cyidea.lib.token), 376
USERSTORE (privacyidea.lib.policy.ACTIONVALUE at- Windows, 239
tribute), 382 Wizard, 166
USERSTORE (privacyidea.lib.policy.AUTOASSIGNVALUE Wordpress, 239
attribute), 382 wrap_job() (in module privacyidea.lib.queue), 394
USERSTORE (privacyidea.lib.policy.LOGINMODE wsgi, 20, 21
attribute), 383
using_pin (privacyidea.lib.tokenclass.TokenClass at- Y
tribute), 361 Yubico, 89
using_pin (privacyidea.lib.tokens.certificatetoken.CertificateTokenClass
Yubico AES mode, 113, 218
attribute), 301 Yubico Cloud mode, 78, 112
using_pin (privacyidea.lib.tokens.sshkeytoken.SSHkeyTokenClass
YubicoTokenClass (class in priva-
attribute), 328 cyidea.lib.tokens.yubicotoken), 346
Yubikey, 89, 112, 113, 218, 219
V Yubikey AES mode, 79
VALIDITY (class in priva- Yubikey CSV, 214
cyidea.lib.eventhandler.tokenhandler), 195 Yubikey OATH-HOTP mode, 218
VASCO, 111 Yubikey personalization GUI, 219
VERIFY_ENROLLMENT (privacyidea.lib.policy.ACTION Yubikey personalization tool, 219
attribute), 382 YubikeyTokenClass (class in priva-
verify_enrollment() (in module priva- cyidea.lib.tokens.yubikeytoken), 346
cyidea.api.lib.prepolicy), 402 YUM, 11
verify_enrollment() (priva-
cyidea.lib.tokenclass.TokenClass method),
361
verify_enrollment() (priva-
cyidea.lib.tokens.hotptoken.HotpTokenClass
method), 308
verify_response() (priva-
cyidea.lib.tokens.ocratoken.OcraTokenClass
method), 310
virtual environment, 4

W
WebAuth, 112
WebAuthn Token, 77
webauthntoken_allowed() (in module priva-
cyidea.api.lib.prepolicy), 403
webauthntoken_auth() (in module priva-
cyidea.api.lib.prepolicy), 403
webauthntoken_authz() (in module priva-
cyidea.api.lib.prepolicy), 403
webauthntoken_enroll() (in module priva-
cyidea.api.lib.prepolicy), 404
webauthntoken_request() (in module priva-
cyidea.api.lib.prepolicy), 404
WebAuthnTokenClass (class in priva-
cyidea.lib.tokens.webauthntoken), 343
WebUI, 33, 461
webui, 33
WEBUI (privacyidea.lib.policy.SCOPE attribute), 390
WebUI Login, 163
WebUI Policy, 163

Index 499

You might also like