5. Authentication and Security
5.1. Authentication methods
ELZA supports these methods of authentication:
Internal accounts - users and passwords stored in ELZA (always available).
Active Directory (LDAP) - the user’s name and password are verified against an Active Directory domain.
Kerberos (SPNEGO) - single sign-on in a Windows domain, and optionally verification of the name and password against the KDC.
SSO header - a reverse proxy that has authenticated the user passes the user name in an HTTP header.
OAuth2 / JWT - requests carry a bearer token issued by an identity provider.
Personal API keys - for integrations calling the REST API.
The methods can be combined. When a user logs in with a name and a password (the login form or HTTP Basic), they are tried in this order: Active Directory, Kerberos, internal password. The first method that accepts the password wins.
Except for OAuth2, every method only verifies the identity: the user must already exist in ELZA with the same user name, and must be active. Users are not created automatically, and groups or roles from the directory are not used; permissions are always assigned in ELZA.
5.2. The first administrator
While the database contains no user, the application offers the
Initial setup, which creates the first administrator; see
First administrator. Its endpoints (/api/v1/setup) are
available without login and create a user only while no user exists.
Until then, anyone who can reach the application can create the first
administrator, so create it before the application is made available on
the network. Once any user exists, the setup is closed for good.
An administrator can also be set in the configuration with
elza.security.admin.username and elza.security.admin.password;
see Administrator from the configuration. They are applied at every startup:
a missing user is created as an administrator, an existing user gets the
configured password and is activated if deactivated (its permissions do
not change). The password is in plain text, and while the keys are set, a
password changed in the application returns to the configured one and a
deactivated account is activated again at the next restart; remove the
keys once they are no longer needed.
5.3. The default user
A new installation contains a built-in user admin with the password
admin and the administrator permission. It exists only in the
configuration, not in the database, and it is available while no user of
the same name exists in the database.
Warning
Disable the default user as soon as the administrator accounts exist:
elza:
security:
allowDefaultUser: false
The default user is recognised by its name alone. While it is enabled,
the SSO header, Kerberos, Active Directory and OAuth2 methods accept
the identity admin without a password and grant it administrator
rights. Always disable the default user when any of these methods is
used. Also avoid creating a database user named admin while the
default user is enabled: its own password and permissions are then
ignored.
Key |
Default |
Meaning |
|---|---|---|
|
|
Enables the default user. |
|
|
Name of the default user. |
|
hash of |
Password of the default user as an encoded hash ( |
5.4. Internal accounts and passwords
Users are created in Administration > Users. Passwords are stored as bcrypt hashes. Passwords from old versions stored with SHA-256 are converted to bcrypt at the user’s next login with the password.
When a deactivated user logs in with the correct password, the login form says that the account is deactivated. With a wrong password, the form shows the same message as for an unknown user (“Invalid user name or password”), so it does not reveal whether an account exists or is deactivated.
elza.security.salt is used only to verify these old SHA-256 hashes.
Do not change it: users whose password has not been converted yet could
no longer log in, and an administrator would have to reset their
passwords.
Users who still have a password in the old format (they have not logged in with the password since the upgrade) are listed by:
SELECT u.username FROM usr_user u
JOIN usr_authentication a ON a.user_id = u.user_id
WHERE a.auth_type = 'PASSWORD' AND a.auth_value NOT LIKE '{%';
5.4.1. Password rules
The rules for internal passwords are set in Administration > Users > Password rules; the button requires the permission User and permission management (or the administrator permission). The rules apply to the whole instance:
- Password validity (days)
How long a password is valid after it was set.
- Minimum password length
The minimum number of characters.
- Minimum number of character groups
From how many of the four groups - lowercase letters, uppercase letters, digits, other characters - the password must contain at least one character (1-4).
An empty value or 0 turns the rule off; a new installation has all rules off. An empty password is never accepted.
The length and character groups are checked whenever a password is set: when a user changes their own password, when an administrator sets a password of a user, and when a user is created or edited with a new password. Administrators are not exempt; a weak temporary password is not accepted either. Existing passwords are not checked until they are changed.
The validity is counted from the moment the password was last set. The conversion of an old SHA-256 hash at login does not change the password and does not restart the period.
Warning
Passwords set before the upgrade to the version with password rules count as set on 1 January 2016. Turning the validity on therefore makes every password not changed since the upgrade expired at once: each such user has to change the password at the next login.
5.4.2. Expired and required password change
When an administrator sets a password of a user (Administration > Users > Change password), two options are available:
- Require a password change at next login
Typical for a temporary password handed over to the user.
- Password never expires
Exempts the account from the validity, for example a technical account.
After a login with an internal password that has expired or whose change is required, the login succeeds and the application opens a dialog that cannot be closed until the user sets a new password. The new password must meet the rules. After the change, the requirement is cleared and the validity period starts again.
The password change is enforced by the web client only. Requests to the REST API made in such a session are not blocked.
The validity and the required change apply only to logins with the
internal password. Users logged in through Active Directory, Kerberos,
the SSO header, OAuth2 or an API key are never asked to change their
password; with Active Directory or Kerberos verifying passwords, the
internal password is used only when the domain rejects the password. The
default user is never asked either: its password is set in the
configuration only (elza.security.defaultPassword) and cannot be
changed in the application.
5.4.3. Recovering access to an account
When an administrator has forgotten their password and no other administrator can set a new one, a temporary recovery password can be set in the configuration:
elza:
security:
recovery:
username: jan.novak
password: a-temporary-password
Key |
Default |
Meaning |
|---|---|---|
|
(none) |
The user who may log in with the recovery password. |
|
(none) |
The recovery password, as plain text. Recovery is active only when both keys are set. |
Procedure:
Set both keys in
elza.yamland restart ELZA.Log in as the user with the recovery password. The application asks for a new password at once.
Enter the recovery password as the old password and set a new password.
Remove both keys from
elza.yamland restart ELZA.
While recovery is active, ELZA logs a warning at startup and at each login
with the recovery password, and the user’s own password keeps working as
well. Recovery works only for users who have an internal password; it
does not apply to the default user, whose password is changed in the
configuration (elza.security.defaultPassword). Never leave recovery
configured longer than needed.
Access can also be recovered with elza.security.admin.username and
elza.security.admin.password (see Administrator from the configuration).
The difference: recovery only allows a temporary login and makes the
user set a new password, while elza.security.admin.* sets the
configured password itself - and creates the user as an administrator if
it does not exist.
5.5. Active Directory
elza:
security:
ldap:
ad-domain: archive.example
ad-server: ldap://dc1.archive.example/
ad-domainThe Active Directory domain. Setting it enables the method.
ad-serverURL of a domain controller.
The user logs in with the domain user name and password. After the domain has accepted the password, ELZA looks up the user by the name as entered; create the ELZA users with the same names as in the domain. When the domain rejects the password, the internal password is tried.
With Active Directory configured, the health check (see Monitoring) also checks the connection to the domain controller.
5.6. Kerberos (SPNEGO)
elza:
security:
kerberos:
service-principal: HTTP/elza.archive.example@ARCHIVE.EXAMPLE
keytab-location: /etc/elza/elza.keytab
authenticate-with-password: true
service-principalThe service principal name of ELZA. Setting it enables the method.
keytab-locationPath to the keytab file with the key of the service principal. The file must be readable by the service user only.
authenticate-with-passwordAlso verify names and passwords from the login form against the KDC (default
true).kerberos-client-debug,ticket-validator-debugDebug output of the Kerberos client and of the ticket validation (default
false).
The Kerberos configuration of the JVM (the realm and the KDC,
krb5.conf) is taken from the operating system or from the Java
settings.
With Kerberos configured, the login dialog offers single sign-on. The
browser then authenticates with the user’s domain ticket; the browser
must be allowed to use integrated authentication for the ELZA address.
The realm is removed from the principal and the user is looked up by the
rest of the name (jan.novak@ARCHIVE.EXAMPLE becomes jan.novak).
The realm itself is not checked. When single sign-on fails, the user can
log in with the form.
5.7. SSO header
A reverse proxy or an access gateway that authenticates users can pass the user name in an HTTP header:
elza:
security:
allowDefaultUser: false
sso-header:
user-header: X-SSO-User
ELZA looks up the user by the value of the header. When the header names another user than the current session, the session is replaced.
Warning
ELZA trusts the header completely. It is secure only when:
ELZA is reachable exclusively through the proxy (bind it to
127.0.0.1or restrict the port by a firewall),the proxy removes or overwrites the header on every request, so a client cannot send it,
the default user is disabled.
Set elza.security.logoutUrl to the logout address of the gateway, so
that logging out of ELZA also ends the session at the gateway.
5.8. OAuth2 / JWT
ELZA can accept bearer tokens (Authorization: Bearer ...) issued by
an identity provider. It acts only as a resource server; there is no
login redirect to the provider.
elza:
security:
o-auth2:
key-url: https://idp.archive.example/oauth/token_key
permissions:
- authority: ELZA_ADMIN
permissions: [ADMIN]
key-urlURL returning the public key for verifying token signatures, as JSON with the PEM-encoded RSA key in the field
value. The key is read once at startup; the application does not start when it cannot be read. Tokens must be signed with RS256.permissionsMapping of values of the token’s
authoritiesclaim to ELZA permissions.scoperestricts a permission to a scope of archival entities, by its code.user-scope,user-ap-typeScope and class of the archival entities of users created from tokens; default
JWT_USERSandPERSON_INDIVIDUAL. The class must be offered by the rule set of the scope.
The token’s sub claim is the user name and name the display name.
Unlike the other methods, a user who does not exist is created, together
with an archival entity of the person in the scope user-scope. The
user’s directly assigned permissions are replaced by those mapped from
the token. User data are cached for five minutes, so a change of
permissions or deactivation takes effect within five minutes.
5.9. Personal API keys
Integrations call the REST API with a personal API key instead of a user’s password. A key belongs to a user and acts with that user’s permissions; create a dedicated user for each integration.
Users create and revoke their own keys in their user settings (category Elza). The full key is shown only once, when it is created; ELZA stores only its hash. Administrators can list and revoke the keys of other users. Keys can be created and revoked only after an interactive login, not with another API key.
The key is sent in a header:
curl -H "X-API-Key: elza_..." https://elza.archive.example/api/v1/...
Key |
Default |
Meaning |
|---|---|---|
|
|
Accept API keys. With |
|
|
Name of the header. |
|
365 |
Validity of a new key when the user does not choose one. |
|
730 |
Maximum validity of a key. |
A rejected key is answered with HTTP 401 and a JSON body with the reason
(MALFORMED_TOKEN, UNKNOWN_KEY, INVALID_SECRET, EXPIRED,
REVOKED, USER_INACTIVE).
5.10. Security audit log
With elza.siemLogFile set (see Configuration Reference), ELZA writes
authentication and account events to a separate log in JSON, one event per line,
suitable for a SIEM system:
login_success- the user, the method (PASSWORD,ACTIVE_DIRECTORY,KERBEROS,SSO_HEADER,JWT,API_KEY) and the source address,login_failed- the user name, the source address and the reason,api_key_createdandapi_key_revoked- who created or revoked which key of which user,config_admin_user_created,config_admin_password_setandconfig_admin_user_activated- the user created, its password set or its account activated at startup fromelza.security.admin.*(the actor isconfiguration),config_admin_failed-elza.security.admin.*could not be applied, with the user and the reason.
The log is rotated daily and kept for 90 days. Behind a reverse proxy, the source address is the address of the proxy.
5.11. Other settings
Key |
Default |
Meaning |
|---|---|---|
|
|
Accept |
|
(none) |
Address the browser opens after logging out, for example the logout page of an SSO gateway. |
|
|
Show the user menu in the application header. |
Sessions expire after the standard timeout of the embedded server (30
minutes of inactivity), which can be changed with
server.servlet.session.timeout. One user can have at most ten
sessions at a time; logging in an eleventh time ends the oldest one.
The monitoring endpoints do not require authentication and must stay reachable only locally (see Monitoring).