---
version: "v3.9.1"
language: "en"
---
# Product Documentation

## Documentation

### [Release Notes](https://docs.veridiumid.com/docs/v3.9.1/release-notes.md)

### [Top features](https://docs.veridiumid.com/docs/v3.9.1/top-features.md)

### [VeridiumID Server Guide Overview \& Architecture](https://docs.veridiumid.com/docs/v3.9.1/veridiumid-server-guide-overview-architecture.md)

### [Self Service Portal Guide](https://docs.veridiumid.com/docs/v3.9.1/self-service-portal-guide.md)

### [Administration Guide](https://docs.veridiumid.com/docs/v3.9.1/administration-guide.md)

### [Windows Integration](https://docs.veridiumid.com/docs/v3.9.1/windows-integration.md)

### [Integrations](https://docs.veridiumid.com/docs/v3.9.1/integrations.md)

### [VeridiumID Mobile SDKs](https://docs.veridiumid.com/docs/v3.9.1/veridiumid-mobile-sdks.md)

### [ILP Documentation](https://docs.veridiumid.com/docs/v3.9.1/ilp-documentation.md)

### [Security](https://docs.veridiumid.com/docs/v3.9.1/security.md)

---
version: "v3.9.1"
language: "en"
---
# 4Finger-ID

Last updated: September 21, 2026

---
version: "v3.9.1"
language: "en"
---
# 4FingerID Touchless Showcase App

The TouchlessID Showcase App includes features to support contactless print data collection and remote upload of data to Veridium's secure storage.  
By using the App, you are agreeing to the terms as stated in the Privacy Policy and Veridium web site, and are responsible for abiding by local laws regarding data privacy.

## Setup For Local Data Collection

* Request from a Veridium representative an invite to the Touchless Showcase App. You will receive an agreement by email to complete prior to invites being set.

* On your device, follow the invite links. On Android install via the Firebase link. For iOS, install via the Testflight link. Note that the app requires internet access for licence activation.

If internet access is not available, or user accounts are restricted, please contact Veridium to request APK and IPA packages for manual installation. To sign the iSO app Veridium will require the UDID of any Apple device you wish to use.

* On the home screen (A), select `Settings` (gear icon, top right). Make the following changes:

  * Set the `Export Format` to ZIP. This is the simplest format to store and access processed fingerprints. Alternatively, choose JSON. Veridium can provide a Python script for JSON parsing on request.

  * Enable `Collection Mode`. This adds an option to the home screen to set a label for saved data files (C) and disables display of the instruction screen.

  * Enable `Logging`: This enables additional output (see section **Saved Data Access and Contents**) and the ability to force a capture by bypassing quality checking (D).

  * Optional: Enable `Two Shot Optimise`. This mode uses two captures of the hand in offset positions to improve quality on for all fingers.

|-----------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------|
| ![home_screen.png](https://docs.veridiumid.com/__attachments/a_e107873e6d575d2948fe020b73607bbb03ce58b07b80dce6311a5fabdb6940e2/home_screen.png?cb=38d876e62cd4c3f2b2e634c22e33bc73) | ![settings.png](https://docs.veridiumid.com/__attachments/a_e5070822e23a418fa58348b73739359b73c2c85adc8853e502a2a525e0525749/settings.png?cb=0a3daee9d28fac6cb0a58eceab399f52) | ![home_collection.png](https://docs.veridiumid.com/__attachments/a_05ba40e5f1e1d21c798f18b8e950893c89cf6fb82e76ce291b379a77eef43cca/home_collection.png?cb=bcb62ac6cb5591c80b2d17376ba167b4) | ![capture_screen.jpg](https://docs.veridiumid.com/__attachments/a_937099297b342050096f6337b896232fab69283006188eaf140e18847c397596/capture_screen.jpg?cb=9da15b2c8a569670cef0a8e1eaeac647) |

* Under settings, you can also choose the digits to capture using options `Export Capture Mode`, `Thumb Mode` or `Single Digit Mode`.

* Hit `Save` to return to the Home Screen. You should now see buttons to `Send Logs` and set a data label.

* Select `Current Label` and type a data label in the prompt.

* Select `Export` to perform fingerprint capture. Data is saved to local device storage.

No data is sent out from the device unless `Send Logs` is selected

## Saved Data Access and Contents

* Connect the device to a desktop machine via USB. For Android, you can use Windows Explorer, Android Studio, or Android File Transfer to browse the Android filesystem. Data is saved in the App's cache at `sdcard/Android-data/com.veridumid.demo.touchlessshowcase/Veridium` (E)

* On iOS, navigate to the mounted device in Finder, select the `Files` tab, expand out `TouchlessID Showcase`, and drag-and-drop the `Veridium` folder to a location on your Mac.

* /TouchlessID contains exported files in the chosen format, and a `.collection.zip` containing additional raw image data (F), and a text file with metadata (G).

* /LOGDATA contains detailed debug information about the capture process logged to`.csv` files, and image data to `.dat` files. This is not necessary to process for data collection, but can be provided to Veridium to diagnose issues.

|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------|
| ![android_file_location.png](https://docs.veridiumid.com/__attachments/a_91e9661f2fe1037fc1b7b922447406c33ecc1f6cfe5f0334d34cf2bd58d27375/android_file_location.png?cb=c2b0e6d446362cf66d1333825d13e7dc) | ![collection_zip.png](https://docs.veridiumid.com/__attachments/a_9e55ad4c046c6062cbc4e9d9753952de63da490290198e2a94148321e0d74c66/collection_zip.png?cb=c6f88c208ddb3209be202835aee5a6e7) | ![metadata.png](https://docs.veridiumid.com/__attachments/a_6d0bffee73d8427aed62715b293dd9c3c0ed23d5941a350a4e5b4ba3a945ff4e/metadata.png?cb=e296e5c863b1c13eb582009bf9647028) |

Proprietary and Confidential. Copyright © Veridium IP Ltd., 2024. All rights reserved.

Last updated: September 21, 2026

---
version: "v3.9.1"
language: "en"
---
# Ability to update CA in Admin manager

This is part of the user experience improvements for the Certificate Authority manipulation in Admin manager. In the latest version, a new mechanism was added to upload either a file with passwords and alias, or a certificate content with passwords and alias.  
![Screenshot 2024-08-02 at 12.41.41.png](https://docs.veridiumid.com/__attachments/a_a06ad76409882d70f7e0e7627389e2fe4f56085421780f313805a6ec3b19bdfa/Screenshot%202024-08-02%20at%2012.41.41.png?cb=5078cab2dbc8e6fc8ba9da0516b470c5)

The view is the same as the one for displaying a certificate, with *Action* button that will provide a more detailed view. In the right side menu there is a *"Regenerate Default Certificate"* that serves as a GUI controller to switch the *"is_admin_initialize"* parameter to "false" (from *"system_status"*) in order to recreate the default admin.

For the upload part, the content of the certificate, password and alias are needed. First the input is validated, then if all ok, it can be saved.

When the certificate is saved, the Admin will be restarted.

The data is saved in the *config.json → ca fields* and in the *truststore.json*  
![Screenshot 2024-08-02 at 12.47.16.png](https://docs.veridiumid.com/__attachments/a_dda224702bd585ad9a4d463344b74fd41006843a193485d4cd743399fc414684/Screenshot%202024-08-02%20at%2012.47.16.png?cb=08f93679760ce60fd49260125d627e6e)

For this functionality to work correctly, we need to have a alias set. This can be achieved with:

    openssl pkcs12 -export -in my-cert.crt -inkey my-priv-key.key -certfile my-ca-bundle -out my-pfx.pfx -name "alias"

Last updated: September 21, 2026

---
version: "v3.9.1"
language: "en"
---
# Ability to update SAML keystore for Admin manager and SSP

This functionality aims to improve the keystore manipulation for SAML admin and SSP, by allowing the admin user to upload a desired keystore. For this a new modal was added that allows the user to upload either a file with passwords and alias, or a certificate content with passwords and alias.

![Screenshot 2024-07-11 at 14.09.02.png](https://docs.veridiumid.com/__attachments/a_fde6fae6bd668346bea10ab6aa4d60b1e6745f532898b565576223108aa27155/Screenshot%202024-07-11%20at%2014.09.02.png?cb=1cc5d7c1043743cad963746ae2f60c09)

For example in the admin auth settings, we can see that the right side menu action **Renew Keystore** and **Update Keystore**are available only if the user clicks in SAML key management tab.

For the renew keystore, nothing is changed. For update keystore action, a new modal will be displayed:

![Screenshot 2024-07-11 at 14.13.00.png](https://docs.veridiumid.com/__attachments/a_eaedfd233a75bc9ab7e0fa8e7d5bd9b29f7021d1c8cae5f300d6fce05ad6aa04/Screenshot%202024-07-11%20at%2014.13.00.png?cb=23c6e7175cbde931ba2b29155ee707dd)

From this modal, the mandatory thing will be the file upload / content and the alias because the keystore password can be present or not. The first action after data entering is form validation, via a button. After the validation is successful, the save button will be enabled.

For this functionality to work correctly, an alias needs to be set. This can be achieved with:

    openssl pkcs12 -export -in my-cert.crt -inkey my-priv-key.key -certfile my-ca-bundle -out my-pfx.pfx -name "alias"

Last updated: September 21, 2026

---
version: "v3.9.1"
language: "en"
---
# Account and device history improvements

In the latest version, information about accounts and device history have been introduced in the following dashboard sections:  
The new tables are visible only for administrators and for users with "VIEW_ACCOUNT_HISTORY" and "VIEW_DEVICE_HISTORY" permissions, respectively.

![image-20240625-124546.png](https://docs.veridiumid.com/__attachments/a_df340311ca87eeecb50473c5ccd5ebeb93a04b4cb50081cc73f3ff7a23ace9c4/image-20240625-124546.png?cb=94c518bfdeb741c9ddf24f2826060586)

1. In *Admin / Identities / Identity Details* - **History** section. The action button will display the raw format.

![image-20240625-122618.png](https://docs.veridiumid.com/__attachments/a_3f58424a637b304f7a1239bb58a40e5c96cfe06997fe520617bbbddab0ba660c/image-20240625-122618.png?cb=20bc0f3f073490bddc21e3916a6864ac)

2. In *Admin / Settings / Administrators*- the Action "eye" button will redirect to a log containing that admin's activity. Same as in the global Audit - Action Logs section, the action button will display the raw format.

![image-20240625-122125.png](https://docs.veridiumid.com/__attachments/a_307d7ba712b2dc4c65716f97b0ecfe6e7ebdf53c7182495de8938bcba6bd9a52/image-20240625-122125.png?cb=6200a61f430158ba426e263944216014)  
![image-20240625-122313.png](https://docs.veridiumid.com/__attachments/a_d8785dc4aa0c15a68979a1d8338cfead66e150278e3b8027dfe1932e10b04c35/image-20240625-122313.png?cb=1ed6a214a3bfb5250a24d6a0d4562e73)

Last updated: September 21, 2026

---
version: "v3.9.1"
language: "en"
---
# Accounts

Veridium maintains internally the list of accounts. An account can be either imported from the external source (Active Directory) or created internally only (like administrator accounts).

Each account gets an unique internal ID in form of UUID, regardless it's imported externally or local one.

When an account is imported from Active Directory the common details such as name, email, first, last name are filled by automatically by default and additional references like:

* the external ID

* external identity public ID (such as `"S-1-5-21-1346520962-2386629273-538639937-1113"`)

* external status (ACTIVE, DISABLED or LOCKED_OUT)

![Untitled Diagram-1719826940833.drawio.png](https://docs.veridiumid.com/__attachments/a_a26dbdf93105fbf23d6fa5beb56b27f2731aed947a90a5bd31afcff64cc4d6f4/Untitled%20Diagram-1719826940833.drawio.png?cb=5e6440cb9b69fff114b877917530ef62)

Veridium Server has a internal accounts management policy with groups and roles.

Each account is part of one or more user groups and each group has a list of associated roles. The internal roles are used to gain access for certain internal Verridium resources.

Other fields:

* Accepted License - whether the user has accepted the license agreement. For administrators only.

* The registration and activation time of the account

* The status of the account - it can be NONE, ACTIVATION_PENDING, ACTIVE, BLOCKED, BLOCKED_BY_ADMIN

* The account's locale (e.g: en, de, it...)

* Whether the account is a system account or not

## Storage format in Elasticsearch

In Elastic, account related data is stored in two index aliases:

* **accounts**- holds the current state of each account (serialized as JSON) together with a compact array of history logs.

* **account_history**- holds each history log of an account in a separate document. It contains information about the action, the entire state of the account in that moment and the set of field changes brought by that specific action.

**Accounts Index**

Accounts are distributed in multiple indices, using an elasticsearch rollover policy that automatically creates and writes into a new index when the size of the current index goes beyond 50GB. The first index will be called **accounts-000001,** the second **accounts-000002** and so on. The first index is manually created by the ElasticSearchSettingsUpdate migration task.

A document in an accounts index contains two main fields: account (holding the current state of the account) and actionLogs (compact array of history logs, NOT indexed). It can be used for searching data related to the current state of accounts.

The account field contains the following searchable fields:  

|    **Field path**     | **Functional Meaning** | **Mapping types** |                                           **Notes**                                            |                **Example value**                 |
|-----------------------|------------------------|-------------------|------------------------------------------------------------------------------------------------|--------------------------------------------------|
| `id`                  |                        | `keyword`         | searchable as keyword only                                                                     | `"d86f4522-51b7-4b7a-acc6-23e663a0c315"`         |
| `externalId`          |                        | `keyword`         | searchable as keyword only                                                                     | `"johndoe@veridiumid.com"`                       |
| `emailAddressInfo`    |                        | `text`            | full text search (individual terms, partial terms, lower/upper case)                           | `johndoe@veridiumid.com`                         |
| `applicationId`       |                        | `keyword`         | searchable as keyword only                                                                     | `AD`                                             |
| `groups`              |                        | `keyword`         | searchable as keyword only                                                                     | `["Guests"]`                                     |
| `registrationTime`    |                        | `date`            |                                                                                                | `"2024-02-27T22:13:30.851+00:00"`                |
| `external`            |                        | `boolean`         |                                                                                                | `false`                                          |
| `accountStatus`       |                        | `keyword`         | searchable as keyword only                                                                     | `"ACTIVE"`                                       |
| `acceptedLicense`     |                        | `boolean`         |                                                                                                | `false`                                          |
| `locale`              |                        | `keyword`         | searchable as keyword only                                                                     | `"en"`                                           |
| `deviceRecognition`   |                        | `boolean`         |                                                                                                | `true`                                           |
| `primaryProfileExtId` |                        | `keyword`         | searchable as keyword only                                                                     | `"S-1-5-21-410015106-2063711249-828150371-1211"` |
| `primaryProfileDefId` |                        | `keyword`         | searchable as keyword only                                                                     | `"d2535f4f-f510-4875-8991-55974a566a69"`         |
| `systemAccount`       |                        | `boolean`         |                                                                                                | `false`                                          |
| `acceptedLicense`     |                        | `boolean`         |                                                                                                | `false`                                          |
| `activationTime`      |                        | `date`            |                                                                                                | `"2023-07-27T09:55:09.145+00:00"`                |
| `commonName`          |                        | `keyword`, `text` | searchable as keyword only,                                                                    | `"CN=John Doe,OU=Users,OU=Dev,DC=dev,DC=local"`  |
| `domain`              |                        | `keyword, text`   | searchable as keyword and full text search (individual terms, partial terms, lower/upper case) | `"dev.local"`                                    |
| `externalStatus`      |                        | `keyword`         | searchable as keyword only                                                                     | `"ACTIVE"`                                       |
| `firstName`           |                        | `keyword`, `text` | searchable as keyword and full text search (individual terms, partial terms, lower/upper case) | `"John Doe"`                                     |
| `lastName`            |                        | `keyword`, `text` | searchable as keyword and full text search (individual terms, partial terms, lower/upper case) | `"John Doe"`                                     |
| `name`                |                        | `keyword`, `text` | searchable as keyword and full text search (individual terms, partial terms, lower/upper case) | `"John Doe"`                                     |
| `phoneNumber`         |                        | `keyword`, `text` | searchable as keyword and full text search (individual terms, partial terms, lower/upper case) | `"+40700000001"`                                 |

Example of a document:

     {
        "id": "8b40ad7f-b077-4325-96b7-0e4f87607b6a",
        "account": {
          "id": "8b40ad7f-b077-4325-96b7-0e4f87607b6a",
          "externalId": "johndoe@veridiumid.com",
          "emailAddressInfo": "johndoe@veridiumid.com",
          "phoneNumber": "+40700000001",
          "applicationId": "AD",
          "groups": [
            "tester",
            "Administrators"
          ],
          "name": "John Doe",
          "firstName": "John Doe",
          "lastName": "John Doe",
          "domain": "dev.local",
          "commonName": "CN=John Doe,OU=Users,OU=Dev,DC=dev,DC=local",
          "registrationTime": "2022-03-08T11:51:32.411+00:00",
          "external": true,
          "externalStatus": "ACTIVE",
          "accountStatus": "ACTIVE",
          "acceptedLicense": true,
          "locale": "en",
          "deviceRecognition": true,
          "primaryProfileExtId": "S-1-5-21-1346520962-2386629273-538639937-1113",
          "primaryProfileDefId": "d2535f4f-f510-4875-8991-55974a566a69",
          "authenticationFailedCount": 0,
          "systemAccount": false
        },
        "actionLogs": [...]// NOT INDEXED
        }

**Accounts History index**

Account history documents are distributed in indices using time window pattern. An index for each month following the pattern **veridium.account_history-YYYY-MM** (++veridium.account_history-2024-02++).

The index is automatically created when the first account history index request is received for the current month.

Documents are never individually deleted, only the entire index gets deleted according to the lifecycle policy.

A document in the account history index contains searchable fields related to the action itself (actionId, type, time, location, authorAccountId, authorDeviceId). Also, it contains the entire state of the account in that moment (the account field, the same searchable fields as above) and a set of fieldChanges, storing all the searchable fields that have changed compared to the previous version, with their previous and current value. It can be used for searching data related to specific mutations of an account.

An example of document:

    {
        "id": "e96782f2-8720-4277-89b1-c34bd491ac3f",
        "actionTime": "2024-02-27T22:13:30.925+00:00",
        "actionType": "UPDATED",
        "location": {
          "ip": "79.115.63.208",
          "countryCode": "RO",
          "countryName": "Romania",
          "regionCode": "IF",
          "regionName": "Ilfov",
          "city": "Otopeni",
          "postalCode": "075100",
          "coordinates": {
            "lat": 44.55,
            "lon": 26.0724
          },
        },
        "authorAccountId": "b974def7-bdc7-4fac-b51d-33da86848387",
        "authorDeviceId": "ssp_dc1",
        "account": {...} //the account state in the moment of the history event, has the same structure as above
        "fieldChanges": {
          "accountStatus": {
            "previousValue": "ACTIVATION_PENDING",
            "currentValue": "ACTIVE"
          },
          //... other field changes if exist
        }
      }

Last updated: September 21, 2026

---
version: "v3.9.1"
language: "en"
---
# Action logs

Action logs represents all actions in VeridiumID configuration done via the Veridium Manager.

Actions are registered on API calls level.

This section offers also a detailed view of each entry and supports searching, similar to the Authentication Session audit.  
![image-20230530-102650.png](https://docs.veridiumid.com/__attachments/a_33d9a9a611bca6798c49b617b543629a109fe7b4a56da726b7b9f95539e52a50/image-20230530-102650.png?cb=dc99853377c64ddce115575c9d06abe4)  
![image-20230530-102732.png](https://docs.veridiumid.com/__attachments/a_b12d8ae6ca488d13b4225069321c075287d19f7644d3eb953df1d388174b5f46/image-20230530-102732.png?cb=3b7bcc1a3abbb1927f0b4c44d23c2e93)

Last updated: September 21, 2026

---
version: "v3.9.1"
language: "en"
---
# Activate Lost mode

Activate Lost Mode is used when a user (identity) has lost one authenticator. In order to restrict possible use of unwanted user, the authenticator can be marked as lost.

Starting with version 3.7, Lost Mode has received some enhancements in both operation and functionality - [***please consult the dedicated page***](https://docs.veridiumid.com/docs/v3.9.1/new-enhancement-on-lost-mode-procedure-complete-guide.md)***.***

1. Click on Activate Lost Mode.

   ![image-20230331-200527.png](https://docs.veridiumid.com/__attachments/a_9f1113dda69695229443522d043c52f8334c918fec2ec61a9c516d613adb820d/image-20230331-200527.png?cb=c67e4d3bf78e31953c102308caeec851)

2. Choose the Duration of Lost Mode.

![lost duration.png](https://docs.veridiumid.com/__attachments/a_f71d459758734687e86c227035bd151595a779f35817ed520a07258c292dd7db/lost%20duration.png?cb=796d8ceb1324dec99e5f1b866e7bbb47)

3. Type Description why do you want to activate Lost Mode.

![lost description.png](https://docs.veridiumid.com/__attachments/a_bd4e9f2aa7d5728eea4f0aa6109b457af1dc6fcb5bc514f905268d6dfa19c2ff/lost%20description.png?cb=3b966f0548a5d03356c5081fa73abe7d)

4. Select Delivery Type. Selecting SMS or email Email means the authentication code will be sent to the inserted phone no/email; and Verbal means the code will appear in Admin Console and needs to be sent to the user.

![lost delivery.png](https://docs.veridiumid.com/__attachments/a_b855eaf36e4004b988135239664d267c77094d1fe371cd173dea89ba76e482a5/lost%20delivery.png?cb=1eb169dfb79e4ec6d7748651e5e3a805)

5. Choose Device that you want to activate Lost Mode on.

![lost device.png](https://docs.veridiumid.com/__attachments/a_c2366bffc31ee1c332a6936dccb9ed0cf2d8ce4340f5919239d54e752fce7815/lost%20device.png?cb=e91acac2f643aafbf1b5c0d41553280a)

6. Select the type of the lost mode: temporary or permanent.

![lost type.png](https://docs.veridiumid.com/__attachments/a_cae70b0817601fcb789f43d1e8a33d9f2bd94578e2768115aaa490900a6bfaae/lost%20type.png?cb=61769fcff801e637b12728325fbf8754)

7. Click Activate.

   ![image-20230331-200634.png](https://docs.veridiumid.com/__attachments/a_3d05681d2f8fa0a21b0f4ba8b4a3c9f79bdbcf304209b57a45530892e907800c/image-20230331-200634.png?cb=b627c1bfdc9632d6e7b317c37814c812)

8. If you selected VERBAL, this is how Code is shown, click OK.

   ![image-20230331-200644.png](https://docs.veridiumid.com/__attachments/a_72762f7af953db82e171d504145652a66afcf3ecf947cd818fdaacd4b75665ed/image-20230331-200644.png?cb=fec7e0838bc695142616b3ac68f636d7)

9. Device is marked as lost.

   ![1.png](https://docs.veridiumid.com/__attachments/a_b23efa34f398b8f0df5d5df2a12c3bf975e1d1964e2dd88d07c2d4411f50b997/1.png?cb=16bec7dccd60a3ac911559fb3e481794)

Last updated: September 21, 2026

---
version: "v3.9.1"
language: "en"
---
# Active Directory Password Self-Management

This feature enables Veridium users to **reset or renew their Active Directory (AD) account passwords** directly within the **Self Service Provider flows or Veridium Windows Credential Provider** . Its purpose is to **reduce helpdesk workload** while providing users with a more **convenient and self-service experience**.

To use this feature, a user must **successfully authenticate at least once using their LDAP password through Veridium** . This initial authentication creates an **LDAP password authenticator**, which is stored in the user's list of authenticators.

During every subsequent authentication, Veridium verifies the presence of the LDAP password authenticator. After the authentication is successfully validated, the system checks the database and **creates or updates the authenticator as required**, ensuring that user information remains consistent and up to date.

The feature can be first enabled from the **Administration interface**. Configuration flags are available to control and fine-tune the supported functional flows from **Settings → General → Ad Password Self Manage**, as described in the sections below.

## **Password Self-Management -- Configuration Flags**

This section describes the configuration flags that control **Active Directory (AD) password self-management** behavior. These settings define **when** , **how** , and **from where** users are allowed to reset or renew their AD passwords.

Go to **Settings → General → Ad Password Self Manage**

*** ** * ** ***

![image-20260120-132441.png](https://docs.veridiumid.com/__attachments/a_20e0657c7482adaad5cb7b869705ea4800eab69f979d53c33a046ae461d5f010/image-20260120-132441.png?cb=fcc7c0114a013e5104f347fb3a7e7359)

### **Enabled**

**Description**

Master switch that enables or disables **AD Password Self-Management** functionality.

**Behavior**

* When **disabled**, all password reset and renewal features are turned off.

* When **enabled**, the options below determine the allowed flows and channels.

*** ** * ** ***

### **AD Password Self Reset**

**Description**

Allows users to **reset** their AD password when they **do not know their current password** or when the password is **expired**.

**Used When**

* The user forgot their password

* The password has expired

* Account recovery scenarios

**Notes**

* This flow does **not** require the current password.

*** ** * ** ***

### **AD Password Self Renewal**

**Description**

Allows users to **renew (change)** their AD password when they **know their current password** and the password is **not expired**.

**Used When**

* User wants to proactively change their password

* Password is still valid

**Requirements**

* Current password must be provided

* Password policy rules are enforced by AD

*** ** * ** ***

### **Accept Expired Password**

**Description**

Controls whether **expired passwords are accepted** during LDAP authentication.

**Behavior**

* **Enabled**:

  * Expired passwords are accepted for authentication

  * Allows the user to proceed with **password renewal**

* **Disabled**:

  * Expired passwords are rejected

**Important Note**

* When using **Windows Credential Provider** , password renewal is **mandatory** to complete the Windows logon session.

* This flag is especially important for seamless password expiration handling.

* If the **AD Password Self Renewal**flag is enabled, the user will be prompted to change the password

*** ** * ** ***

### **Allow IdP**

**Description**

Allows users to **renew or reset their password via the browser-based Identity Provider (IdP) interface** . Without this setting enabled, the users will not be able to renew the AD password on any browser based IDPs event though the feature is enabled (in both **Ad Password Self Manage** and **LDAP Connection**)

**Behavior**

* **Enabled** → Password operations are allowed in web flows

* **Disabled** → Browser-based password management is blocked

**Typical Use Case**

* Self-service portals

* Web login flows

*** ** * ** ***

### **Allow Windows Logon**

**Description**

Allows users to **renew their password directly on a Windows machine** during the Windows logon process.

**Behavior**

* **Enabled** → Password renewal is allowed via Windows Credential Provider

* **Disabled** → Windows-based password renewal is blocked

## **Summary Table**

|         **Flag**         |                  **Purpose**                  |
|--------------------------|-----------------------------------------------|
| Enabled                  | Master switch for AD password self-management |
| AD Password Self Reset   | Reset password without knowing the old one    |
| AD Password Self Renewal | Change password when the old one is known     |
| Accept Expired Password  | Allow expired passwords for renewal flows     |
| Allow IdP                | Enable browser-based password management      |
| Allow Windows Logon      | Enable Windows logon password renewal         |

If those flags are set on true, the user will have the options to reset/renew the password from the SSP.

In the **SSP interface** , under the **Authenticators** section, users will see a new **LDAP authenticator** . Next to it, the **Reset** and **Renew** actions will be available, allowing users to manage their AD passwords directly from the self-service portal.  
![image-20231117-110517.png](https://docs.veridiumid.com/__attachments/a_32fd79b91579789a0633c821396540433527069cfdad9435dda21676c9f02a15/image-20231117-110517.png?cb=7ea4dbfed83be2ab3c52f42a4e708f7e)  
![image-20231117-110653.png](https://docs.veridiumid.com/__attachments/a_a066e662ca3db16b49dc6336c8917cc21425ebd37b58f3e722770ee06d0e9208/image-20231117-110653.png?cb=a4ad07319f3f32fcf018c65f5cf9c244)
*Reset form*  
![image-20231117-110551.png](https://docs.veridiumid.com/__attachments/a_7a7584457dea2c9a72c9cf709f9b86a2cacb6489d4ecab8b113b2f5f7fdc15e8/image-20231117-110551.png?cb=a86589c17fe0dfd134c659b63868735d)  
![image-20231117-103001.png](https://docs.veridiumid.com/__attachments/a_8750eb677bc70f899529b50a41b87bcff1a8c899febf15f4a8ffca43777c3795/image-20231117-103001.png?cb=c148fd80bd8001e3644fb60c3b28f397)
*Renew form*

These actions follow the standard enrollment steps, similar to PIN reset action for example, meaning that the user will have to provide a code validation also, if so configured in the integration.

*** ** * ** ***

## **Password Self-Management -- LDAP Connection Granularity**

Password self-management can be controlled at **two levels**:

1. **Global level** -- applies system-wide

2. **LDAP connection level** -- applies per LDAP connection

**Both levels must allow the feature for password self-management to be active.**

### **LDAP Connection: Allow Password Self-Management**

Each LDAP connection has its own **Allow Password Self-Management** flag.

This flag controls whether password self-management is allowed **for users authenticating through that specific LDAP connection**.  
![image-20260120-133707.png](https://docs.veridiumid.com/__attachments/a_46881f2a78d9ce9bdb716ab150eb30ffc60558c07770cc94b0db9620925698c1/image-20260120-133707.png?cb=f832bb4d48f7d128b5fbbd49b619b7d7)

**Behavior**

* If **disabled** , password self-management is **blocked** for that LDAP connection

* If **enabled**, password self-management follows the global configuration

### **Precedence Rules (Global vs LDAP)**

Password self-management is enabled **only if both conditions are met**:

* Global **Enabled** flag is set to **true**

* LDAP connection **Allow Password Self-Management** flag is set to **true**

### **User Experience When Changing Global Enabled Flag**

When an administrator **enables** the global **Password Self-Management** flag:

* The system prompts the administrator:

  *"Enabling this feature allows password self-management. Would you like to enable it for all LDAP connections? Otherwise, the feature may not work for every LDAP connection."*

If the administrator confirms:

* The **Allow Password Self-Management** flag is set to **true** on **all existing LDAP connections**

* Password self-management becomes immediately available (subject to other settings)

If the administrator declines:

* The global flag is enabled

* LDAP connection flags remain unchanged

* Password self-management will only be active for LDAP connections where the flag is already enabled

### **Important Notes**

* Disabling the **global Enabled** flag **always disables** password self-management, regardless of LDAP connection settings

* Enabling the global flag **does not automatically enable LDAP connections**, unless explicitly confirmed

*** ** * ** ***

## **Global Catalog vs Domain Connection**

When an LDAP connection is configured to use a **Global Catalog (GC)** , some AD operations cannot be performed directly through the GC. This includes operations that require **full domain context**, such as:

* Password **reset**

* Password **renewal**

* Retrieving attributes like pwdLastSet or msDS-PasswordExpiryTimeComputed (e.g., for password expiration checks)

To support these operations, the **"Use Domain Connection"** option allows the system to **temporarily use a standard domain connection** for these specific actions, even if the primary connection is to a Global Catalog.  
![image-20260120-134333.png](https://docs.veridiumid.com/__attachments/a_5fa5078d59a93e4916e72a7e291f38c6026343d5ec2ba098f11c24a116d19881/image-20260120-134333.png?cb=70c6a5850ae74d42b18fdc7345174844)

### **Configuration Flags**

|        **Setting**        |                                                                                                                       **Description**                                                                                                                       |
|---------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **Use Domain Connection** | If enabled, the system will use a standard domain connection for operations that require full domain context, such as password reset, renewal, or retrieving attributes not available in the GC. This ensures **password self-management works correctly**. |
| **LDAPS Port**            | Port number for **secure LDAP (LDAPS)** domain connection. Default is **636**.                                                                                                                                                                              |
| **LDAP Port**             | Port number for **non-secure LDAP** domain connection. Default is **389**.                                                                                                                                                                                  |

**Important Note:**

Without enabling the **Use Domain Connection** flag, password self-management may **fail for LDAP connections on the Global Catalog**, because Global Catalog connections do not provide the necessary attributes or context required for these operations.

*** ** * ** ***

## **Security**

The LDAP password reset flow follows the same security procedures as the PIN reset process. Users must complete all required **security steps** , including **verification codes or other validation methods**, before they can reset their LDAP password. This ensures that password changes are performed securely and only by authorized users.

*** ** * ** ***

## **Configuration**

![image-20231117-103103.png](https://docs.veridiumid.com/__attachments/a_2d615400f22c4aefe4aede98a822cacfdd872df3fd66add1db4921469bb84cbd/image-20231117-103103.png?cb=8fd76ba0c55aea7cc11671dffada4ecc)

### **LDAP Password Pattern**

**Description**

The **LDAP password pattern** enforces a specific format that user passwords must follow. The pattern is defined using a **regular expression (regex)**, allowing you to control password complexity and structure.

**Behavior**

* Users must create passwords that match the configured pattern.

* The system will reject any passwords that do not comply with the pattern.

**Important Considerations**

* The pattern configured in Veridium (VID) **must be at least as restrictive as the Active Directory (AD) password policy**.

* This setting **does not synchronize automatically** with AD; changes in AD password policies must be reflected manually in Veridium if needed.

*** ** * ** ***

### **LDAP Password Expiration Notice**

**Description**

The **LDAP password expiration notice** determines when users are prompted that their password is approaching expiration. This allows users to proactively renew their passwords within the Veridium self-service flow.

**Behavior**

* Enter the number of days before expiration to trigger the notification.

* For example, if the field is set to **11** , and a user's password is set to expire in fewer than 11 days, the **Veridium Self Service flow** will prompt the user to change the password during authentication.

*** ** * ** ***

## **Renew Password When It Is About to Expire or Has Expired**

After a user successfully authenticates, the system checks the **difference between the LDAP password expiration date and the authentication date**.

* If the password is **approaching expiration** (i.e., the difference is smaller than the configured notification threshold), the user is prompted to **renew their LDAP password** within the Veridium self-service flow.

* If the password has **already expired** , the system requires the user to **reset their password** before proceeding with any other actions.

This ensures that users update their passwords in a timely manner, preventing account lockouts while maintaining a smooth self-service experience.  
![image-20231107-154024.png](https://docs.veridiumid.com/__attachments/a_96f609ca969fe80e8b430a04c439f980de766ce2e96dd19d03a6dd4b04fd4941/image-20231107-154024.png?cb=613704628afa8168f1fb9060bb1fcfc0)

If the password is **about to expire** , the system will **prompt the user to change their password** but still allow them to **continue using the system without updating it**.  
![image-20231120-115544.png](https://docs.veridiumid.com/__attachments/a_a890b3af9f126326fc5d6a65b0efd1d5ec360cf64d4870b40d79302ea55c5c9f/image-20231120-115544.png?cb=06fb66d4a249926eae1d94ff834f6be3)

*** ** * ** ***

## **Technical Aspects and Key Takeaways**

* The **LDAP authenticator** is created or updated **after each successful authentication** during identity synchronization.

* The LDAP authenticator is created **only if password self-management is enabled globally** and the relevant **feature flags** (Reset Password or Renew Password) are activated.

* Password self-management for a user is effective **only if the corresponding LDAP connection has the "Allow Password Self-Management" flag enabled** . If the global flag is enabled but the LDAP connection flag is **disabled**, the password self-management flow will not occur.

* **Password Reset**:

  * Can only be performed if the feature is **enabled from the admin page** (Reset Password flag).

  * In Shibboleth flows, the reset is available **only when the password is already expired**.

* **Password Renewal**:

  * Can only be performed if the feature is **enabled from the admin page** (Renew Password flag).

  * In Shibboleth flows, renewal is available **only when the password is approaching expiration**.

  * The **current password** will be requested to perform the renewal.

* For **Global Catalog LDAP connections** , some operations (password reset/renewal, retrieving pwdLastSet or msDS-PasswordExpiryTimeComputed) require using a **standard domain connection** . This is controlled via the **"Use Domain Connection"** flag on the LDAP connection. Without this, **password self-management may fail**.

To change the password, the LDAP connection must be secured.  
In order to renew AD user password, the user must know the old password and it must be active.  
If needed, the timeout on the http client configuration can be increased.  
Some Active Directory attributes that can affect password policy if configured in Active Directory, such as "pwdINHistory" and "pwdLockout" do not return explicit error messages for the user in this release. This means that for cases in which the new user password does not meet these criteria, the flow will fail with no relevant error in GUI.  

|        **Use case**        |                                                             **Settings needed enabled**                                                             |
|----------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------|
| Change AD pass via browser | Ad Password Self Manage + Allow Idp + Ad Password Self Renewal + Allow Password Self-Management (from LDAP connection configured)                   |
| Change AD pass via CP      | Ad Password Self Manage enabled + Allow Windows Logon + Ad Password Self Renewal + Allow Password Self-Management (from LDAP connection configured) |

As a general conceptual path explanation for further reference \& troubleshooting, this is the logic for **Accept Expired Password ON** :

### **1. The "Enforcement Loop" (All Settings ON)**

* **User Experience:** Forced Password Change.

* **Why:** This is the "Gold Standard" configuration. The system has permission to manage the account (`Self Manage`), the portal is available (`Allow IdP`), and the automated task to update the password is active (`Self Renewal`). Even though the server *can* accept an expired password, the policy dictates that if the tools exist to fix it, the user **must** fix it before proceeding.

### **2. The "Gatekeeper" Bypass (Allow IdP OFF or Self-Renewal OFF)**

* **User Experience:** User can authenticate with expired password.

* **Why:** \* **Allow IdP OFF:** The Identity Provider (IdP) is the component that typically serves the "Password Reset" UI to the user. Without it, the system cannot present the reset forms, so it honors the `Accept Expired Password: ON` setting and lets the user in.

  * **Self-Renewal OFF:** This flag controls the backend's ability to actually write the new password to Active Directory. If this is disabled, the system knows a reset attempt will fail, so it allows the expired login to proceed to avoid a total lockout.

### **3. The "Method Block" (Self-Management OFF)**

* **User Experience:** AD password fails; other methods work for "Expiring" status only.

* **Why:** When `Allow Password Self-Management` is **OFF**, the Veridium orchestrator is essentially "blind" to remediation steps. It sees an expired credential and, lacking the authority to manage it, simply rejects the AD method as a failure. The user is then forced to use secondary methods (like FIDO or Bio) if they are in an "Expiring" (but not yet hard-expired) state.

#### **4. Credential Provider (CP) Context**

* **User Experience:** Mandatory change triggered only if **all** CP flags are ON.

* **Why:** In version 3.8.4, the Windows Credential Provider requires a "Tight Loop" of configuration to trigger a change. This is to ensure that if a user changes their password, the new registry key `WorkstationLockAfterPasswordChange` can successfully trigger a lock to refresh the certificate in the offline cache. If any flag is missing, the CP defaults to standard Windows behavior to prevent a "broken" reset flow at the login screen.

##### **4-1. The "All-or-Nothing" Enforcement**

* **Logical Reason:** For a password that is merely **Expiring** (not yet expired), the Credential Provider acts as a proactive tool. The logic requires a "Perfect Path" to be available.

* **Why it works:** Because every management flag is enabled, the system has full authority to:

  1. Recognize the expiring state (`Self Manage`).

  2. Use the Windows login UI for the flow (`Allow Windows Logon`).

  3. Write the change back to AD (`Self Renewal`).

  4. Allow the user to initiate the action (`Self-Management`).

* **Technical Context:** This ensures that when the user changes the password, the new v3.8.4 registry key `WorkstationLockAfterPasswordChange` can trigger correctly to refresh the certificate in the offline cache.

##### **4-2. The "Expiring Bypass"**

* **Logical Reason:** If even **one** link in the management chain is missing, the CP prioritizes **user availability** over **proactive maintenance**.

* **Why it works:** If `Self Renewal` is OFF, the CP knows it cannot successfully complete the write-back to AD. Rather than starting a process that will eventually fail and frustrate the user, it allows the "Expiring" password to work normally, assuming the user will fix it via another channel (like a web portal or office PC).

#### **4-3. The "Expired" Hard-Stop**

* **Logical Reason:** **Security Policy vs. User Convenience.**

* **Why it works:** Unlike an *expiring* password (which is still technically valid), an **expired** password is a security violation.

* **Technical Enforcement:** In the CP context, the "Expired" status triggers a kernel-level rejection from Active Directory. Veridium intercepts this and, regardless of the individual "Self Manage" toggles, enforces a reset. An expired pass is never allowed to "bypass" into a session because that would compromise the integrity of the Windows workstation lock and the user's primary identity.

Last updated: September 21, 2026

---
version: "v3.9.1"
language: "en"
---
# Activity

Activity shows authentication done by selected identity.  
![1.png](https://docs.veridiumid.com/__attachments/a_0ad2271c08e62303df1a55828e4f8fee553cc81224e808fa17e748f57bf6374d/1.png?cb=315b3f847d41dee0c75c1e0bcd3a17ae)

Clicking the three dots from the right top of the chart, will redirect to Authentication session page.  
![2.png](https://docs.veridiumid.com/__attachments/a_d332c56518349f880b6554f837e03262b43c9c805460cec6e7de4fd33b6c7106/2.png?cb=2cd6857d6bf11434331f1a0060126a4b)

Highlighted area allows export data in SVG, PNG or CSV format.  
![image-20230331-183930.png](https://docs.veridiumid.com/__attachments/a_63f3bc8045d81638ac133236ddffda65318b93ab49bd6928e8063bd696d8b2ef/image-20230331-183930.png?cb=afb2048f78257adca95060536d06fbba)

Last updated: September 21, 2026

---
version: "v3.9.1"
language: "en"
---
# AD CS Configuration Hardening for VeridiumID Certificate Templates

*Advisory Type: Informational --- Severity: Low*

*Date Published: 19 November 2025*

## **1. Executive Summary**

As part of Veridium's commitment to secure deployment practices, we have updated our guidance on configuring Active Directory Certificate Services (AD CS) certificate templates used with VeridiumID.

This advisory is **informational only** .

It does **not** describe a vulnerability in Veridium software.

It provides **deployment hardening recommendations** to help customers ensure that their AD CS template permissions follow least-privilege best practices.

## **2. Description**

In some AD CS environments, granting certificate enrollment permissions to broad Active Directory groups (such as *Authenticated Users* , *Domain Users* , or *Domain Computers*) can introduce unnecessary exposure. While VeridiumID does not require these permissions, earlier documentation did not explicitly discourage them.

The documentation has now been updated to clearly define the recommended secure configuration:

* Only the Veridium service/computer account should have enrollment permissions

* Broad AD groups should not have any access

* The Veridium account should be treated as a Tier 0 identity

This aligns Veridium guidance with Microsoft AD CS hardening and current industry recommendations.

## **3. Impact Assessment**

* No defect or vulnerability exists in Veridium software

* This advisory applies **only** to AD CS configuration choices

* Customers following least-privilege practices are **not impacted**

* No exploitation or misuse has been observed

**Severity:** *Informational / Low*

## **4. Recommended Customer Actions**

The following actions need to be applied on Veridium Enrollment Agent certificate template. (BopsRA template).

### **4.1 Required Template Permissions**

Grant the following permissions **only** to the Veridium service/computer account:

* **Read** (Allowed)

* **Enroll** (Allowed)

* **Autoenroll** (Not required; leave disabled)

* **Write / Modify / Full Control** (Not permitted)

### **4.2 Remove Broad Group Permissions**

Verify that none of the following groups have any permissions on the Veridium certificate template:

* *Authenticated Users*

* *Domain Users*

* *Domain Computers*

* *Users*

* *Everyone*

If any appear, remove them.

### **4.3 Treat the Veridium Account as Tier 0**

The Veridium service/computer account should be handled with the same protections as:

* Domain Controllers

* AD FS servers

* Privileged identity infrastructure

This includes isolation, strong credential protection, and privileged-access workstation usage.

### **4.4 Optional: Audit Previously Issued Certificates**

Customers may review certificates issued from their VeridiumID template to identify:

* Unexpected subject names or SANs

* Certificates issued to unexpected accounts

* Enrollment events from systems outside the Veridium deployment

If needed, revoke certificates and publish an updated CRL.

## **5. Updated Documentation**

The revised deployment guidance is available here:

<https://docs.veridiumid.com/docs/v3.8.3/3-3-create-the-bopsra-template>

Customers should ensure all future and existing deployments follow this updated configuration.

## **6. Support and Disclosure Contacts**

For assistance reviewing your configuration:

[**support@veridiumid.com**](mailto:support@veridiumid.com)

Last updated: September 21, 2026

---
version: "v3.9.1"
language: "en"
---
# Add a new administrator

Note: In order to align with the current security recommended practices, the administrator certificate and its password will no longer be sent in the same email, when generated from **Veridium Manager - Settings - Administrators -** *Add Administrator* function. The rest of the general administrator create procedure remains the same.

New configuration options are available in **Veridium Manager - General** - **Administrators Settings** submenu settings:

* "Send Admin Certificate Password Via Sms" new toggle that by default is set on *false*. In this case the password will be displayed in the admin view.

* Enabling it will send the password via SMS on the mobile phone associated with the administrator account. This mobile phone number is set during administrator creation via a new field in the form. The phone number field is optional. If it is omitted, and the certificate is sent via SMS to create an administrator, the certificate password will not be sent, resulting in an error display.

![Screenshot 2023-06-14 at 17.04.29.png](https://docs.veridiumid.com/__attachments/a_ec4517412dcc6bae5e0c1d1cf820d40fb818290160570f4c2f46bc8236d21536/Screenshot%202023-06-14%20at%2017.04.29.png?cb=096a38750a17a367c6c00d14d8772c34)

* Because the password can be send on a different device, a configuration form for the password length (between \[4-20\] lowercase and numeric digits_ is present:

![Screenshot 2023-06-14 at 17.07.14.png](https://docs.veridiumid.com/__attachments/a_67ca1fa114a311cf8c3b7593780b38fe0cdb6ba30bad512b6f9efe7996d1541f/Screenshot%202023-06-14%20at%2017.07.14.png?cb=b5f2307eeea598fe5ef0646d4061b783)

1. Click on Settings tab.

   ![image-20230329-171824.png](https://docs.veridiumid.com/__attachments/a_fa4c48789e2dfa34b3bfefc389be1e8c7c0e2b73d5f717cc00f37ee0d565d81a/image-20230329-171824.png?cb=e41b33f3bb41b86f22ff573e527aaa68)

2. Scroll down to Administrators section, and click on it.

   ![Screenshot 2023-11-24 at 12.13.59.png](https://docs.veridiumid.com/__attachments/a_2c60c3c6dede7247013ec4507c733106eca411cbe5db93216357b74876d41c3c/Screenshot%202023-11-24%20at%2012.13.59.png?cb=b566573f0db0cbe53ded7175123c4512)

3. Creation of administrator

   1. Click on Add Admin from external directory

      ![Screenshot 2023-11-24 at 12.23.24.png](/__attachments/a_5b04add9f36212f91efcdc2c3ac90eb34a0c12d56f1f0db7b3ca9112e4a47c22/Screenshot%202023-11-24%20at%2012.23.24.png?cb=c033379df48b1e8d7df1dc92404a11e5)

      This action will be automatically populated based on the information retrieved from the searched identity in Active Directory input field.

      ![Screenshot 2023-11-24 at 12.41.09.png](/__attachments/a_f92cbbec4092f010d9608fea9344e17481ad0a25f3bfba420793109f65a2025c/Screenshot%202023-11-24%20at%2012.41.09.png?cb=468405e19a8087fffe34fe98550c2c71)
   2. Click on Add Veridium internal Admin

      ![Screenshot 2023-11-24 at 12.47.21.png](/__attachments/a_863b78d2ddcb13b2c2e85c8881955c1411289661b6bdc0c13cc550afd95c32a2/Screenshot%202023-11-24%20at%2012.47.21.png?cb=c265428070bb9d5d195c7738a7766fa8)

   This action will direct you to a form where you must manually input the required information for administrator creation. From this form, the mandatory fields will be:

   **Name** → is mandatory for display and search.

   **Email** → acts like a username, and allows search and display.

   **Groups**

   **Account external Id**

4. For the "Get user certificate" select whether you want to download certificate locally or send it to email. This is the same for both way to create administrator.

   ![image-20230329-172852.png](https://docs.veridiumid.com/__attachments/a_681bc7d87dbe48db7ecc3a60b70b4ddd88aed378f611e77460245f17c5015814/image-20230329-172852.png?cb=e779fe1f9dd017661e372ea6460fc988)

5. Select Administrators in groups section.

   ![image-20230329-172912.png](https://docs.veridiumid.com/__attachments/a_7ad7cf542a5ce293cfab53ad2e77d76a2d99c2d9507b954e2cd718f098dad3de/image-20230329-172912.png?cb=4b3d445a520426591502a7faa1d71dc4)

6. Click Save.

   ![image-20230329-172924.png](https://docs.veridiumid.com/__attachments/a_663e1e8c4654382b8946ce2481a706557e8657cc867ccb1a1c706ba6c6bb1a6f/image-20230329-172924.png?cb=c083ddb8d0bdae63c8479ee30cf860de)

7. The password is copied to the clipboard and the certificate is downloaded (if the option "Download here" was selected for "Get user certificate". If "Via email" was selected, the certificate will be sent to the email entered.)

   ![image-20230329-172935.png](https://docs.veridiumid.com/__attachments/a_501895dae9111eaad3161204812e38537a559ee2510585d9573a3246ccdfdec3/image-20230329-172935.png?cb=1dfe192426f20b2943075bdf91c60f9a)

Last updated: September 21, 2026

---
version: "v3.9.1"
language: "en"
---
# Add a second DC to create a CDCR

## 1) Backup and Restore config

On OLD webapp node 1:

    mkdir -p /tmp/veridium/haproxy
    cp /etc/veridiumid/haproxy/client-ca.pem /tmp/veridium/haproxy/
    cp /etc/veridiumid/haproxy/server.pem /tmp/veridium/haproxy/
    cp /etc/veridiumid/haproxy/haproxy.cfg /tmp/veridium/haproxy/
    mkdir -p /tmp/veridium/shib
    cp /opt/veridiumid/shibboleth-idp/credentials/idp-signing.crt /tmp/veridium/shib/
    cp /opt/veridiumid/shibboleth-idp/credentials/idp-signing.key /tmp/veridium/shib/
    cp /opt/veridiumid/shibboleth-idp/credentials/sealer.jks /tmp/veridium/shib/
    cp /opt/veridiumid/shibboleth-idp/credentials/idp-encryption.crt /tmp/veridium/shib/
    cp /opt/veridiumid/shibboleth-idp/credentials/idp-encryption.key /tmp/veridium/shib/
    cp /etc/veridiumid/zookeeper.properties /tmp/veridium/zookeeper.properties

    mkdir -p /tmp/veridium/filebeat
    cp /opt/veridiumid/filebeat/config/filebeat.yml /tmp/veridium/filebeat/
    cp /opt/veridiumid/filebeat/config/certs/ca.pem /tmp/veridium/filebeat/

    mkdir -p /tmp/veridium/kibana
    cp /opt/veridiumid/kibana/config/kibana.yml /tmp/veridium/kibana/
    cp /opt/veridiumid/kibana/config/certs/ca.pem /tmp/veridium/kibana/

    mkdir -p /tmp/veridium/opa
    cp /opt/veridiumid/opa/certs/* /tmp/veridium/opa/

    tar -czvf /tmp/configs.tar.gz /tmp/veridium

    ll /tmp/con*
    -rw-r--r--. 1 root root 10685 Apr 18 09:33 /tmp/configs.tar.gz
    --> copy file to new webapp nodes

Copy configs.tar.gz to all new WebApp nodes into the /tmp directory

On all new WebApp nodes:

    sudo su -
    ver_stop
    cd /tmp
    tar -xvf configs.tar.gz
    \cp tmp/veridium/haproxy/client-ca.pem /opt/veridiumid/haproxy/conf/
    \cp tmp/veridium/haproxy/server.pem /opt/veridiumid/haproxy/conf/
    \cp tmp/veridium/haproxy/haproxy.cfg /opt/veridiumid/haproxy/conf/
    \cp tmp/veridium/shib/sealer.jks /opt/veridiumid/shibboleth-idp/credentials/
    \cp tmp/veridium/shib/idp-signing.crt /opt/veridiumid/shibboleth-idp/credentials/
    \cp tmp/veridium/shib/idp-signing.key /opt/veridiumid/shibboleth-idp/credentials/
    \cp tmp/veridium/shib/idp-encryption.crt /opt/veridiumid/shibboleth-idp/credentials/
    \cp tmp/veridium/shib/idp-encryption.key /opt/veridiumid/shibboleth-idp/credentials/
    \cp tmp/veridium/kibana/ca.pem /opt/veridiumid/kibana/config/certs/ca.pem
    \cp tmp/veridium/filebeat/ca.pem /opt/veridiumid/filebeat/config/certs/ca.pem
    \cp tmp/veridium/opa/* /opt/veridiumid/opa/certs/
    \cp tmp/veridium/zookeeper.properties /tmp/zookeeper.properties

    mkdir -p /tmp/veridium/opa
    cp /opt/veridiumid/opa/certs/* /tmp/veridium/opa/

    ## on each new WEBAPP run (put IP_OLD the IP from where the file was copied; put IP_NEW each IP in the new DC):
    sed -i 's|IP_OLD|IP_NEW|g' /opt/veridiumid/haproxy/conf/haproxy.cfg

    elkpass=`grep elasticsearch.password tmp/veridium/kibana/kibana.yml`
    sed -i "s|elasticsearch.password.*|$elkpass|g" /opt/veridiumid/kibana/config/kibana.yml

    filebeatkey=`grep "  api_key:" tmp/veridium/filebeat/filebeat.yml`
    sed -i "s|  api_key.*|$filebeatkey|g" /opt/veridiumid/filebeat/config/filebeat.yml

    haproxypass=`cat /opt/veridiumid/haproxy/conf/haproxy.cfg | grep proxy-secret | rev | cut -d" " -f1 | rev | uniq`

    sed -i "s|proxySecret=\".*\"|proxySecret=\"$haproxypass\"|" /opt/veridiumid/tomcat/conf/context.xml

    ## check also proxyName and proxyPort to be the same in the new datacenter as in the old datacenter, for both SHIBBOLETH and Catalina
    /opt/veridiumid/tomcat/conf/server.xml

On old persistence node 1:

    sudo su -
    mkdir -p /tmp/veridium/cassandra
    cp /opt/veridiumid/cassandra/conf/KeyStore.jks /tmp/veridium/cassandra
    cp /opt/veridiumid/cassandra/conf/TrustStore.jks /tmp/veridium/cassandra
    cp /opt/veridiumid/cassandra/conf/cqlsh_cassandra_cert.pem /tmp/veridium/cassandra
    cp /opt/veridiumid/cassandra/conf/cqlsh_cassandra_key.pem /tmp/veridium/cassandra
    cp /opt/veridiumid/cassandra/conf/cassandra.yaml /tmp/veridium/cassandra
    mkdir -p /tmp/veridium/elastic
    cp /opt/veridiumid/elasticsearch/config/elasticsearch.keystore /tmp/veridium/elastic/
    cp /opt/veridiumid/elasticsearch/config/certs/KeyStore.p12 /tmp/veridium/elastic/
    cp /opt/veridiumid/elasticsearch/config/certs/TrustStore.p12 /tmp/veridium/elastic/
    mkdir -p /tmp/veridium/filebeat
    cp /opt/veridiumid/filebeat/config/filebeat.yml /tmp/veridium/filebeat/
    cp /opt/veridiumid/filebeat/config/certs/ca.pem /tmp/veridium/filebeat/
    cp /etc/veridiumid/zookeeper.properties /tmp/veridium/zookeeper.properties

    tar -czvf /tmp/configs.tar.gz /tmp/veridium
    ll /tmp/con*
    -rw-r--r--. 1 root root 10685 Apr 18 09:33 /tmp/configs.tar.gz
    --> copy file to all new persistence nodes

On all new persistence nodes -Restore config on all new persistence nodes:

    ver_stop
    cd /tmp
    tar -xvf configs.tar.gz
    \cp tmp/veridium/cassandra/KeyStore.jks /opt/veridiumid/cassandra/conf/
    \cp tmp/veridium/cassandra/TrustStore.jks /opt/veridiumid/cassandra/conf/
    \cp tmp/veridium/cassandra/cqlsh_cassandra_cert.pem /opt/veridiumid/cassandra/conf/
    \cp tmp/veridium/cassandra/cqlsh_cassandra_key.pem /opt/veridiumid/cassandra/conf/
    \cp tmp/veridium/elastic/elasticsearch.keystore /opt/veridiumid/elasticsearch/config/
    \cp tmp/veridium/elastic/KeyStore.p12 /opt/veridiumid/elasticsearch/config/certs/
    \cp tmp/veridium/elastic/TrustStore.p12 /opt/veridiumid/elasticsearch/config/certs/
    \cp tmp/veridium/filebeat/ca.pem /opt/veridiumid/filebeat/config/certs/ca.pem
    \cp tmp/veridium/zookeeper.properties /tmp/zookeeper.properties

    filebeatkey=`grep "  api_key:" tmp/veridium/filebeat/filebeat.yml`
    sed -i "s|api_key.*|$filebeatkey|g" /opt/veridiumid/filebeat/config/filebeat.yml

    casspass=`cat tmp/veridium/cassandra/cassandra.yaml | grep keystore_password | tail -n 1| tr -d [:space:]| cut -d":" -f2`
    sed -i "s|keystore_password.*|keystore_password: $casspass|g" /opt/veridiumid/cassandra/conf/cassandra.yaml
    sed -i "s|truststore_password.*|truststore_password: $casspass|g" /opt/veridiumid/cassandra/conf/cassandra.yaml

3. **cassandra migration**

On old persistence node 1, run full repair to replicate data to all nodes

    /opt/veridiumid/cassandra/bin/nodetool repair --full

On all new persistence nodes, stop cassandra

    systemctl stop ver_cassandra

On all new persistence nodes, verify cassandra properties

    less /opt/veridiumid/cassandra/conf/cassandra-rackdc.properties
    dc=DC2
    rack=rack1

On all new persistence nodes, update cassandra settings

    vi /opt/veridiumid/cassandra/conf/cassandra-env.sh
    # add this line at the very end:
    grep -Fxq "JVM_OPTS=\"\$JVM_OPTS -Dcassandra.ignore_dc=true\"" /opt/veridiumid/cassandra/conf/cassandra-env.sh || sed -i "\$a JVM_OPTS=\"\$JVM_OPTS -Dcassandra.ignore_dc=true\"" /opt/veridiumid/cassandra/conf/cassandra-env.sh
    # add this line to the very end of the YAML file:
    grep -Fxq "auto_bootstrap: true" /opt/veridiumid/cassandra/conf/cassandra.yaml || sed -i "\$a auto_bootstrap: true" /opt/veridiumid/cassandra/conf/cassandra.yaml

    vi /opt/veridiumid/cassandra/conf/cassandra.yaml
    # cassandra recommendation: 4 seeds for 6 nodes cluster
    - seeds: "IP1_DC1:7001,IP2_DC1:7001,IP1_DC2:7001,IP2_DC2:7001"

On all new persistence nodes, run this on all three nodes - one after the other!

    systemctl stop ver_cassandra
    rm -fr /opt/veridiumid/cassandra/data/*
    rm -fr /opt/veridiumid/cassandra/commitlog/*
    # Now restart the service where dc2 will join the cluster
    systemctl start ver_cassandra; tail -f /var/log/veridiumid/cassandra/system.log
    #once done, run on first node:
    nodetool status

On old persistence node 1:

    #on old DC - extend replication to new nodes
    /opt/veridiumid/cassandra/bin/cqlsh --ssl --cqlshrc=/opt/veridiumid/cassandra/conf/veridiumid_cqlshrc
    #
    ALTER KEYSPACE system_auth WITH REPLICATION = {'class' : 'NetworkTopologyStrategy','dc1' : 3, 'dc2' : 3};
    ALTER KEYSPACE system_traces WITH REPLICATION = {'class' : 'NetworkTopologyStrategy','dc1' : 3, 'dc2' : 3};
    ALTER KEYSPACE system_distributed WITH REPLICATION = {'class' :'NetworkTopologyStrategy', 'dc1' : 3, 'dc2' : 3};
    ALTER KEYSPACE veridium WITH REPLICATION = {'class' : 'NetworkTopologyStrategy','dc1' : 3, 'dc2' : 3};
    quit
    #once done, run on first node:
    nodetool status

On all new persistence nodes - one after the other:

    /opt/veridiumid/cassandra/bin/nodetool rebuild -dc dc1

4. **zookeeper migration**

On one persistence node from the primary datacenter make a backup of the current Zookeeper configuration

    ## zookeeper - create backup 
    bash /opt/veridiumid/migration/bin/migration.sh -d /tmp/DC1backup

    #Make a copy of it that will be uploaded after we change the values
    \cp -R /tmp/DC1backup /tmp/newConf

    # Modify JSON configuration to include all persistence nodes addresses
    # Create list of IP Addresses of all persistence nodes (starting with the primary datacenter)
    DC1_ZOO=( "IP1_DC1", "IP2_DC1", "IP3_DC1" )
    DC2_ZOO=( "IP1_DC2", "IP2_DC2", "IP3_DC2" )

    dc1_addr=$( IFS=$','; echo "${DC1_ZOO[*]}" )
    dc2_addr=$( IFS=$','; echo "${DC2_ZOO[*]}" )

    # Update json files
    jq ".cassandra.hosts = \"${dc1_addr},${dc2_addr}\"" /tmp/newConf/config.json > tmp.json & mv tmp.json /tmp/newConf/config.json
    jq ".clientConnection.hosts = \"${dc1_addr},${dc2_addr}\"" /tmp/newConf/elasticsearch.json > tmp.json & mv tmp.json /tmp/newConf/elasticsearch.json

    # Upload new configuration to Zookeeper
    bash /opt/veridiumid/migration/bin/migration.sh -u /tmp/newConf

On all persistence nodes (**new and old**) run the following (one at a time):

    # Create list of IP Addresses of all persistence nodes (starting with the primary datacenter)
    DC1_ZOO=( "IP1_DC1", "IP2_DC1", "IP3_DC1" )
    DC2_ZOO=( "IP1_DC2", "IP2_DC2", "IP3_DC2" )

    # Stop Zookeeper
    systemctl stop ver_zookeeper

    # Make copy of current configuration file
    \cp /etc/veridiumid/zookeeper/zoo.cfg /etc/veridiumid/zookeeper/zoo.cfg_before_cdcr

    # Make backup of myid file
    \cp /opt/veridiumid/zookeeper/data/myid /opt/veridiumid/zookeeper/data/myid_before_cdcr
     
    # Get current ID and IP of node
    current_id=`cat /opt/veridiumid/zookeeper/data/myid | tr -d [:space:]`
    current_ip=`cat /opt/veridiumid/zookeeper/conf/zoo.cfg | grep "server.${current_id}" | cut -d"=" -f2 | cut -d":" -f1 | tr -d [:space:]`

    # Remove current server configs from zoo.cfg
    sed -i '/^server.*/d' /opt/veridiumid/zookeeper/conf/zoo.cfg

    # Add configurations
    grep -q "standaloneEnabled=false" /opt/veridiumid/zookeeper/conf/zoo.cfg; if [ $? -ne 0 ]; then echo -ne "standaloneEnabled=false\n" >> /opt/veridiumid/zookeeper/conf/zoo.cfg; fi
    grep -q "localSessionsEnabled=true" /opt/veridiumid/zookeeper/conf/zoo.cfg; if [ $? -ne 0 ]; then echo -ne "localSessionsEnabled=true\n" >> /opt/veridiumid/zookeeper/conf/zoo.cfg; fi
    grep -q "localSessionsUpgradingEnabled=true" /opt/veridiumid/zookeeper/conf/zoo.cfg; if [ $? -ne 0 ]; then echo -ne "localSessionsUpgradingEnabled=true\n" >> /opt/veridiumid/zookeeper/conf/zoo.cfg; fi

    # Add servers
    new_id=0
    for ip_addr in ${DC1_ZOO[@]};
    do
    	new_id=$((new_id+1))
    	echo -ne "server.${new_id}=${ip_addr}:2888:3888:participant;${ip_addr}:2181\n" >> /opt/veridiumid/zookeeper/conf/zoo.cfg
    	if [[ "${ip_addr}" == "${current_ip}" ]];
    	then
    		echo "${new_id}" > /opt/veridiumid/zookeeper/data/myid
    	fi
    done
    for ip_addr in ${DC2_ZOO[@]};
    do
    	new_id=$((new_id+1))
    	echo -ne "server.${new_id}=${ip_addr}:2888:3888:observer;${ip_addr}:2181\n" >> /opt/veridiumid/zookeeper/conf/zoo.cfg
    	if [[ "${ip_addr}" == "${current_ip}" ]];
    	then
    		echo "${new_id}" > /opt/veridiumid/zookeeper/data/myid
    	fi
    done

    # !!!!! Only on the SECOND DATACENTER nodes remove the content of the data directory
    rm -rf /opt/veridiumid/zookeeper/data/version-2

    # Start zookeeper
    systemctl start ver_zookeeper

    ## run check services, to see zookeeper cluster status
    check_services

Run on all nodes in the secondary datacenter (**webapp and persistence**).

    # On all nodes in the secondary datacenter modify the contents of the zookeeper.properties file with the values from the file from the first datacenter
    # Make copy of current zookeeper.properties file
    \cp /etc/veridiumid/zookeeper.properties /etc/veridiumid/zookeeper.properties_before_cdcr

    cp /tmp/tmp/veridium/zookeeper.properties /tmp/zookeeper.properties

    # Get values from file in first datacenter
    zoo_user=`cat /tmp/zookeeper.properties | grep username | cut -d"=" -f2 | tr -d [:space:]`
    zoo_pass=`cat /tmp/zookeeper.properties | grep password | cut -d"=" -f2 | tr -d [:space:]`
    zoo_salt=`cat /tmp/zookeeper.properties | grep salt | cut -d"=" -f2 | tr -d [:space:]`

    # Modify values
    sed -i "s|username=.*|username=${zoo_user}|g" /etc/veridiumid/zookeeper.properties
    sed -i "s|password=.*|password=${zoo_pass}|g" /etc/veridiumid/zookeeper.properties
    sed -i "s|salt=.*|salt=${zoo_salt}|g" /etc/veridiumid/zookeeper.properties

!!! Only on webapp nodes in the secondary datacenter restart all applications after changing the values in zookeeper.properties file

    # Stop all services
    bash /etc/veridiumid/scripts/veridium_services.sh stop

    # Start all services
    bash /etc/veridiumid/scripts/veridium_services.sh start

5. Elasticsearch migration

On all new persistence nodes:

    # extend cluster
    service ver_elasticsearch stop
    vi /opt/veridiumid/elasticsearch/config/elasticsearch.yml
    --> Add IPs of other nodes in front of the existing values!
    discovery.seed_hosts: ["IP1_DC1","IP2_DC1","IP3_DC1","IP1_DC2","IP2_DC2","IP3_DC2"]
    cluster.initial_master_nodes: [ "IP1_DC1","IP2_DC1","IP3_DC1" ]
    cluster.routing.allocation.awareness.force.zone.values: dc1, dc2

On all old persistence nodes:

    vi /opt/veridiumid/elasticsearch/config/elasticsearch.yml
    discovery.seed_hosts: ["IP1_DC1","IP2_DC1","IP3_DC1","IP1_DC2","IP2_DC2","IP3_DC2"]
    cluster.routing.allocation.awareness.force.zone.values: dc1, dc2

On all new persistence nodes:

    rm -rf /opt/veridiumid/elasticsearch/data/*
    # restart elasticsearch on all new nodes - one after the other!!!
    systemctl restart ver_elasticsearch
    check_services
    eops -l

On new persistence node 1:

    eops -x=PUT -p=/veridium.*/_settings -d='{"index":{"number_of_replicas":3}}'
    check_services
    eops -l

On all old persistence node - one after the other :

    systemctl restart ver_elasticsearch
    check_services

6. start services on new webapps

    systemctl start ver_websecadmin;tail -f /var/log/veridiumid/websecadmin/websecadmin.log
    systemctl start ver_tomcat;tail -f /var/log/veridiumid/tomcat/catalina.out
    ver_start
    check_services
    ##also check on persistence if all services are up
    ver_start
    check_services

8. renew Certificates in new websecadmin

    -> Settings - Certificates - Service Credentials 
    Press renew for System Services and also for OPA
    ## for OPA also run
    #Click "Renew" → Certificate will be downloaded
    #Copy certificate to both new webapp nodes to /tmp
    #Apply new certificate on both new webapp nodes (one after the other)
    /opt/veridiumid/opa/bin/config-opa.sh -c /tmp/opa-cert.zip
    systemctl restart ver_opa

9. Other configs

Change crontab on all persistence nodes

    crontab -e
    # Change maintenance task on all new persistence nodes:
    ## Hour should be 23
    ## Day should be
    ### persistence node 1: 5
    ### persistence node 2: 4
    ### persistence node 3: 3
    0 1 * * 5 bash /opt/veridiumid/cassandra/conf/cassandra_maintenance.sh -c /opt/veridiumid/cassandra/conf/maintenance.conf
    to
    0 23 * * 5 bash /opt/veridiumid/cassandra/conf/cassandra_maintenance.sh -c /opt/veridiumid/cassandra/conf/maintenance.conf

It might be necessary to have different server.pem, because node names has changed. If this is the case, generate from local infrastructure a new certificate p12 and set it on the new machines.

    Usage: ./convert_haproxy_cert.sh PATH_TO_PKCS_FILE
    Example: 
    bash /etc/veridiumid/scripts/convert_haproxy_cert.sh /home/veridiumid/veridium.p12
    # the following error might appear
    # error: 40CC49630D7F0000:error:0308010C:digital envelope
    # routines:inner_evp_generic_fetch:unsupported:crypto/evp/evp_fetch.c:373:Global
    # default library context, Algorithm (RC2-40-CBC : 0), Properties ()
    cd/tmp
    openssl pkcs12 -in keystore_vid.p12 -legacy -nodes -nocerts -out privateKey_enc.pem -passin pass:[KEYSTORE_PASSWORD]
    openssl rsa -in privateKey_enc.pem -out /privateKeyFull.pem -passin pass: [KEYSTORE_PASSWORD]
    openssl pkcs12 -in keystore_vid.p12 -legacy -nokeys -out publicCertFull.pem -passin pass:[KEYSTORE_PASSWORD]
    cat privateKey_enc.pem > server.pem
    cat publicCertFull.pem >> server.pem
    cp server.pem /opt/veridiumid/haproxy/conf/server.pem
    rm /tmp/server.pem
    rm /tmp/keystore*

Last updated: September 21, 2026

---
version: "v3.9.1"
language: "en"
---
# Add connection

## To add a new LDAP connection:

1. Click Add Connection.

   ![image-20230405-153910.png](https://docs.veridiumid.com/__attachments/a_97e50fdbcf1fd62e09b75d9587b389361df13fa959f77fbde0ecef70b8f2133f/image-20230405-153910.png?cb=31e20fcf68ae57066e4c38cb89299b3f)

### Following chapters describes the parameters required when creating the connection:

* [Basic Details](https://docs.veridiumid.com/docs/v3.9.1/basic-details.md)
* [Certificate-Based LDAP Authentication](https://docs.veridiumid.com/docs/v3.9.1/certificate-based-ldap-authentication.md)
* [Display name attributes](https://docs.veridiumid.com/docs/v3.9.1/display-name-attributes.md)
* [Search by attributes](https://docs.veridiumid.com/docs/v3.9.1/search-by-attributes.md)
* [Attribute name mapping](https://docs.veridiumid.com/docs/v3.9.1/attribute-name-mapping.md)
* [Extended attributes](https://docs.veridiumid.com/docs/v3.9.1/extended-attributes.md)

Last updated: September 21, 2026

---
version: "v3.9.1"
language: "en"
---
# Add manually Zookeeper Datacenter to an existing CDCR

This article will provide a step by step procedure for adding 2 DC's to an existing DC.

On all persistence nodes (in all datacenters) run the following (one node at a time):

1. stop webapp services in DC2 and DC3

       bash /etc/veridiumid/scripts/veridium_services.sh stop

2. stop zookeeper only in DC2 and DC3 and **remove old content only on non main DC**.

       systemctl stop ver_zookeeper
       rm -rf /opt/veridiumid/zookeeper/data/version-2

3. reconfigure zookeeper in DC1, DC2, DC3, by running below commands, on each persistence node, one node at a time.

Bash

    # Create list of IP Addresses of all persistence nodes (starting with the primary datacenter)
    DC1_ZOO=( "IP1_DC1" "IP2_DC1" "IP3_DC1" )
    DC2_ZOO=( "IP1_DC2" "IP2_DC2" "IP3_DC2" )
    DC3_ZOO=( "IP1_DC3" "IP2_DC3" "IP3_DC3" )

    # Stop Zookeeper
    systemctl stop ver_zookeeper

    # Make copy of current configuration file
    \cp /etc/veridiumid/zookeeper/zoo.cfg /etc/veridiumid/zookeeper/zoo.cfg_before_cdcr

    # Make backup of myid file
    \cp /opt/veridiumid/zookeeper/data/myid /opt/veridiumid/zookeeper/data/myid_before_cdcr

    # Get current ID and IP of node
    current_id=`cat /opt/veridiumid/zookeeper/data/myid | tr -d [:space:]`
    current_ip=`cat /opt/veridiumid/zookeeper/conf/zoo.cfg | grep "server.${current_id}" | cut -d"=" -f2 | cut -d":" -f1 | tr -d [:space:]`

    # Remove current server configs from zoo.cfg
    sed -i '/^server.*/d' /opt/veridiumid/zookeeper/conf/zoo.cfg

    # Add configurations
    grep -q "standaloneEnabled=false" /opt/veridiumid/zookeeper/conf/zoo.cfg; if [ $? -ne 0 ]; then echo -ne "standaloneEnabled=false\n" >> /opt/veridiumid/zookeeper/conf/zoo.cfg; fi
    grep -q "localSessionsEnabled=true" /opt/veridiumid/zookeeper/conf/zoo.cfg; if [ $? -ne 0 ]; then echo -ne "localSessionsEnabled=true\n" >> /opt/veridiumid/zookeeper/conf/zoo.cfg; fi
    grep -q "localSessionsUpgradingEnabled=true" /opt/veridiumid/zookeeper/conf/zoo.cfg; if [ $? -ne 0 ]; then echo -ne "localSessionsUpgradingEnabled=true\n" >> /opt/veridiumid/zookeeper/conf/zoo.cfg; fi
    echo "" >> /opt/veridiumid/zookeeper/conf/zoo.cfg

    new_id=0
    for ip_addr in ${DC1_ZOO[@]};
    do
    	new_id=$((new_id+1))
    	echo -ne "server.${new_id}=${ip_addr}:2888:3888:participant;${ip_addr}:2181\n" >> /opt/veridiumid/zookeeper/conf/zoo.cfg
    	if [[ "${ip_addr}" == "${current_ip}" ]];
    	then
    		echo "${new_id}" > /opt/veridiumid/zookeeper/data/myid
    	fi
    done
    for ip_addr in ${DC2_ZOO[@]};
    do
    	new_id=$((new_id+1))
        echo -ne "server.${new_id}=${ip_addr}:2888:3888:observer;${ip_addr}:2181\n" >> /opt/veridiumid/zookeeper/conf/zoo.cfg
    	if [[ "${ip_addr}" == "${current_ip}" ]];
    	then
    		echo "${new_id}" > /opt/veridiumid/zookeeper/data/myid
    	fi
    done

    for ip_addr in ${DC3_ZOO[@]};
    do
    	new_id=$((new_id+1))
        echo -ne "server.${new_id}=${ip_addr}:2888:3888:observer;${ip_addr}:2181\n" >> /opt/veridiumid/zookeeper/conf/zoo.cfg
    	if [[ "${ip_addr}" == "${current_ip}" ]];
    	then
    		echo "${new_id}" > /opt/veridiumid/zookeeper/data/myid
    	fi
    done
    # Start zookeeper
    systemctl start ver_zookeeper
    check_services

4. On all nodes in the DC2 and DC3 adjust zookeeper.properties file, as on first node.

   1. First get the configurations from DC1, by runnning this on one node in DC1 (webapp or persistence)

      Bash

          zoo_user=`cat /etc/veridiumid/zookeeper.properties | grep username | cut -d"=" -f2 | tr -d [:space:]`
          zoo_pass=`cat /etc/veridiumid/zookeeper.properties | grep password | cut -d"=" -f2 | tr -d [:space:]`
          zoo_salt=`cat /etc/veridiumid/zookeeper.properties | grep salt | cut -d"=" -f2 | tr -d [:space:]`
          echo "zoo_user=$zoo_user"
          echo "zoo_pass=$zoo_pass"
          echo "zoo_salt=$zoo_salt"

   2. take the ouput of previous command and run it on all nodes togather with below sed's:

      Bash

          zoo_user=....
          zoo_pass=....
          zoo_salt=....
          \cp /etc/veridiumid/zookeeper.properties /etc/veridiumid/zookeeper.properties_before_cdcr
          sed -i "s|:2181/.*/|:2181/$zoo_user/|g" /etc/veridiumid/zookeeper.properties
          sed -i "s|username=.*|username=${zoo_user}|g" /etc/veridiumid/zookeeper.properties
          sed -i "s|password=.*|password=${zoo_pass}|g" /etc/veridiumid/zookeeper.properties
          sed -i "s|salt=.*|salt=${zoo_salt}|g" /etc/veridiumid/zookeeper.properties

5. Start webapp services in DC2 and DC3

Bash

    # Start all services
    bash /etc/veridiumid/scripts/veridium_services.sh start

Last updated: September 21, 2026

---
version: "v3.9.1"
language: "en"
---
# Adding SAML Service Provider applications in SSP.

The self-service portal experience was enhanced by introducing a comprehensive list of SAML service provider applications. This improvement aims to elevate the visibility of existing applications and allows the user to directly access them.

## Overview

### New fields added in the admin Applications

To enhance the list' appearance in SSP, a new field (optional) called "**logo file** " has been introduced. The limitation in size of this field will be 100 kilobytes. The image will be shrink in the backend to desired **2 MB** max to be store in the ZK.  
![Screenshot 2024-02-09 at 09.38.58.png](https://docs.veridiumid.com/__attachments/a_4591e2d929b043b432a060117ea9810c15bd7f94ad86c397226d8d66612fc66b/Screenshot%202024-02-09%20at%2009.38.58.png?cb=2eea4de9ea8f6dc7fd3f6c8dbd23c178)

Introducing this new field for applications may lead to a conflict with SSP logo uploads. In such instances, any upload action within SSP, whether through the SSP settings page, personalization page or the application setting page, will result in modifying the image in both JSON files (ssp.json and service-provider.json).  
Another aspect is that the application that will be displayed in the SSP will be only the **SAML applications that have a redirect URL configured.**  
The Veridium Manager and SSP application that can be configured from Settings-\>Admin auth it is an exception for this feature. This means that for this in particular it will not show any option to upload the logo and will not be displayed in SSP.  
![Screenshot 2024-03-04 at 18.18.22.png](https://docs.veridiumid.com/__attachments/a_4aacc58f995a45d7aa776c55862dbca246ab13bd93e0e9954e32fb3d90a537ea/Screenshot%202024-03-04%20at%2018.18.22.png?cb=1d3f6e66de28f3cc9847c7f6b5bd0d1d)

#### Configurable property for displaying the application list in SSP

To make this feature configurable, a configuration flag is included in the SSP settings. This flag enables the option to display or hide the new header in SSP based on user preferences. By default this field is set on false, that means the new header will be by default not displayed in SSP.  
![Screenshot 2024-01-29 at 09.17.22.png](https://docs.veridiumid.com/__attachments/a_7a8118c3755c5bd373ef53d31a5aea4de52f8b2b3055bb415fcdee22dfc608b6/Screenshot%202024-01-29%20at%2009.17.22.png?cb=093833925f006faf41c7416c653efa23)

Ultimately, the new header in SSP, designed to showcase application content, will feature the application logo, application name **OR** friendly name, and redirect link if clicks on the card. The list of application has implemented infinity scroll mechanism in order to not fetch the entire list of application that have also the logo images.  
![image-20240329-085534.png](https://docs.veridiumid.com/__attachments/a_323c6e2936951e814ad60bd6739e61a580fef7559b8244c1d006016cc525814b/image-20240329-085534.png?cb=f5f6c79dfced2c049f537cf54c00005c)

Last updated: September 21, 2026

---
version: "v3.9.1"
language: "en"
---
# ADFS can´t communicate with VeridiumID server

TODO:

## Symptoms

## Root cause

## Resolution

Last updated: September 21, 2026

---
version: "v3.9.1"
language: "en"
---
# ADFS - Configuration

* [Obtain a VeridiumID Custom Service Certificate (CSC)](https://docs.veridiumid.com/docs/v3.9.1/obtain-a-veridiumid-custom-service-certificate-csc.md)
* [Configure the VeridiumID ADFS Server](https://docs.veridiumid.com/docs/v3.9.1/configure-the-veridiumid-adfs-server.md)
* [High Availabiliy](https://docs.veridiumid.com/docs/v3.9.1/high-availabiliy.md)
* [Extending authentication token for new custom claims](https://docs.veridiumid.com/docs/v3.9.1/extending-authentication-token-for-new-custom-claims.md)

Last updated: September 21, 2026

---
version: "v3.9.1"
language: "en"
---
# ADFS Troubleshooting

* [ADFS can´t communicate with VeridiumID server](https://docs.veridiumid.com/docs/v3.9.1/adfs-can-t-communicate-with-veridiumid-server.md)

Last updated: September 21, 2026

---
version: "v3.9.1"
language: "en"
---
# Admin auth

Last updated: September 21, 2026

---
version: "v3.9.1"
language: "en"
---
# Admin - Logs Export

## Overview

The Log Export feature allows administrators to download Elasticsearch logs associated with a specific:

* Identity

* Device

* Authentication Session

* Passkey Session

The exported archive contains matching records from:

* Application Logs: `logs-application-*`

* Access Logs: `logs-access-*`

The logs are exported as NDJSON files inside a ZIP archive. The exported ZIP archive contains:

* Application logs

* Access logs

* A manifest with general information about the export

### Identity Logs Export

The **Export Logs** action is available in the right-side menu of the Identity Details page.

To export the logs:

1. Open the required identity.

2. Select **Export Logs** from the right-side menu.

   ![Screenshot 2026-09-18 at 18.01.40-20260918-150157.png](https://docs.veridiumid.com/__attachments/a_f890af2a2c8d875079bcfcfba1db4161f8fe09c5c2bb7a6ba240af892a5f2159/Screenshot%202026-09-18%20at%2018.01.40-20260918-150157.png?cb=ad97b81b32863f9878e95e4aa71adff4)
3. Select the required period.

   ![Screenshot 2026-09-18 at 18.03.09-20260918-150314.png](https://docs.veridiumid.com/__attachments/a_6c712a59f65425a532b3e47337540d7b7aa82ae4e8ca6f4204827f631541d79e/Screenshot%202026-09-18%20at%2018.03.09-20260918-150314.png?cb=896a5e168b52bce2bd00f0cb3d607286)
4. Click **Export**.

   ![Screenshot 2026-09-18 at 18.03.09-20260918-150405.png](https://docs.veridiumid.com/__attachments/a_f8dfd05215ece140c823a153949598b91b5a5a61aa8b586794addb19c9406a10/Screenshot%202026-09-18%20at%2018.03.09-20260918-150405.png?cb=4f26f4abf90a3fd4fd3f741158160c79)
5. The ZIP archive is downloaded automatically.

The export contains Application Logs and Access Logs associated with the selected Identity.

### Device Logs Export

The **Export Logs** action is available in the right-side menu of the Device Details page.

The action is available for the following device types:

* Phone

* Desktop

To export the logs:

1. Open the required device.

2. Select **Export Logs** from the right-side menu.

   ![Screenshot 2026-09-18 at 18.05.33-20260918-150558.png](https://docs.veridiumid.com/__attachments/a_2b6682aaa61325705467d9e46322a0d31f13c2aa55e80af59f3faa196d94060d/Screenshot%202026-09-18%20at%2018.05.33-20260918-150558.png?cb=ad8a8c5d1f410e17296a484f9d3211ad)
3. Select the required period.

   ![Screenshot 2026-09-18 at 18.07.35-20260918-150741.png](https://docs.veridiumid.com/__attachments/a_c1b3e8c97f9b7ab06562fec741408ce87115e5d279c68a273c1ffce144c92aec/Screenshot%202026-09-18%20at%2018.07.35-20260918-150741.png?cb=0b287bad74befdba7a5378ccde7e9c42)
4. Click **Export** .

   ![Screenshot 2026-09-18 at 18.07.35-20260918-150827.png](https://docs.veridiumid.com/__attachments/a_a75194763347c4b51371b37d50833243e3bce3e75c3fad21ee81b6449d5c34c2/Screenshot%202026-09-18%20at%2018.07.35-20260918-150827.png?cb=a4e858864267d66113b880d6cbb59eed)
5. The ZIP archive is downloaded automatically.

The export contains Application Logs and Access Logs associated with the selected Device.

### Authentication and Passkey Session Logs Export

The **Export Logs** button is available at the top of the Authentication Session Details page, next to the **Raw** button.

To export the logs:

1. Open the required Authentication Session.

2. Click **Export Logs**.

   ![Screenshot 2026-09-18 at 18.10.40-20260918-151108.png](https://docs.veridiumid.com/__attachments/a_4088dbd8912ba48a90ae4e2ff84f83a0d71b399d36bd564cf56293946a788a28/Screenshot%202026-09-18%20at%2018.10.40-20260918-151108.png?cb=76e20e74e724027b9a3d5e8e1c040f9e)
3. Select the required period.

   ![image-20260918-151241.png](https://docs.veridiumid.com/__attachments/a_89b6b90df1c5ffd3c2285d57ce3d29ad4f7c8254961c6799d9614377e522ee3e/image-20260918-151241.png?cb=20087e5cea63a7a121af76112c47bda1)
4. Click **Export**.

   ![Screenshot 2026-09-18 at 18.12.33-20260918-151352.png](https://docs.veridiumid.com/__attachments/a_8af109946d8e53125b96fa6fa43b3850edd42c8b8012a07730062288cbc3e981/Screenshot%202026-09-18%20at%2018.12.33-20260918-151352.png?cb=cd10a396abbca7994e791188fea8aa98)
5. The ZIP archive is downloaded automatically.

The export contains Application Logs and Access Logs associated with the selected Authentication/Passkey Session.

Last updated: September 21, 2026

---
version: "v3.9.1"
language: "en"
---
# Administration and operations without SSH

Here is the new documentation for all actions from websecadmin. A must for all functionalities to work is for veridiumid user to be able to restart services (sudo priviledges to details). This is the default in veridium installations - if the client changes this, most functionality will not work. Complete list of sudoers commands for veridiumid user is below  

|       |                                                                                                      |                                                                                                                                                                                                                           |
|-------|------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 3.9   | Easier configuration of CBA                                                                          | [CERTIFICATE authentication method](https://docs.veridiumid.com/docs/v3.9.1/certificate-authentication-method.md)                                                                                                                                    |
| 3.9   | Elasticsearch cluster management                                                                     | [Elasticsearch troubleshooting \& useful commands](https://docs.veridiumid.com/docs/v3.9.1/elasticsearch-troubleshooting-useful-commands.md)                                                                                                         |
| 3.9   | Fido configuration                                                                                   | [FIDO relying party - changing the default fido origin](https://docs.veridiumid.com/docs/v3.9.1/fido-relying-party-changing-the-default-fido-origin.md)                                                                                              |
| 3.9   | All configurations should be done in websecadmin                                                     | All templates must be modifed from now on from websecadmin and propagated to nodes.                                                                                                                                       |
| 3.9   | Custom reports generation                                                                            | [Reports](https://docs.veridiumid.com/docs/v3.9.1/reports.md)                                                                                                                                                                                        |
| 3.9   | Traceability and Logs Reporting                                                                      | [Enhanced Traceability and Device Log Reporting](https://docs.veridiumid.com/docs/v3.9.1/enhanced-traceability-and-device-log-reporting.md)                                                                                                          |
| 3.9   | Live change of DEBUG in log4j.xml                                                                    | [Changing the Log Level at Runtime](https://docs.veridiumid.com/docs/v3.9.1/changing-the-log-level-at-runtime.md)                                                                                                                                    |
| 3.9   | Application CA renewal or change with a different one                                                | [Application CA Lifecycle Management from Veridium Admin](https://docs.veridiumid.com/docs/v3.9.1/application-ca-lifecycle-management-from-veridium-admin.md)                                                                                        |
| 3.9   | On fresh install there are created more journeys for different scenarious                            | [Journey examples](https://docs.veridiumid.com/docs/v3.9.1/journey-examples.md)                                                                                                                                                                      |
| 3.9   | CDCR improved process - only by pointing to proper zookeeper config file                             | [VeridiumID Server On-Prem - Cross DataCenter Replication using the same CA (VeridiumID 3.8.4+)](https://docs.veridiumid.com/docs/v3.9.1/veridiumid-server-on-prem-cross-datacenter-replication-using-the-same-ca-veridiumid-3-8-4.md)               |
| 3.9   | Default installation - ports are switched between shibboleth and websec.                             | Now exteranal shibboleth is on 443 (no certificate) and websec on 8944 (client certificate)                                                                                                                               |
| 3.9   | Renewal of OPA certificate                                                                           | Renewal is done from websecadmin and automatically propagated to nodes - [Renew internal application certificates](https://docs.veridiumid.com/docs/v3.9.1/renew-internal-application-certificates.md)                                               |
| 3.9   | Better visibility on certificate expiration dates                                                    | [Display new certificates in dashboard](https://docs.veridiumid.com/docs/v3.9.1/display-new-certificates-in-dashboard.md) Also for AD and Default certs - to review the certificate documentation ; also include renewal in admin and ssp IDP certs. |
| 3.9.1 | Freeradius clients configuration and json logs                                                       | [Centralized FreeRADIUS Client Management](https://docs.veridiumid.com/docs/v3.9.1/centralized-freeradius-client-management.md)                                                                                                                      |
| 3.9.1 | Renew Persistence Veridium CA and change of Certificates (veridium or client) for persistence layer. | [Renew Veridium persistance CA and replace certificate exposed by persistance services](https://docs.veridiumid.com/docs/v3.9.1/renew-veridium-persistance-ca-and-replace-certificate-exposed-by-persistance-services.md)                            |
| 3.9.1 | Export logs for sessions/devices and identity.                                                       | [Admin - Logs Export](https://docs.veridiumid.com/docs/v3.9.1/admin-logs-export.md)                                                                                                                                                                  |

    /etc/sudoers.d/veridiumid-user

    veridiumid ALL=(root) NOPASSWD: /bin/systemctl stop ver_*
    veridiumid ALL=(root) NOPASSWD: /bin/systemctl start ver_*
    veridiumid ALL=(root) NOPASSWD: /bin/systemctl enable ver_*
    veridiumid ALL=(root) NOPASSWD: /bin/systemctl disable ver_*
    veridiumid ALL=(root) NOPASSWD: /bin/systemctl restart ver_*
    veridiumid ALL=(root) NOPASSWD: /bin/systemctl status ver_*

To restrict access to infrastructure-related operations and custom reporting, a new **admin-limited** role has been introduced. The role grants all administrative permissions except **INFRA** and **CUSTOMREPORTS**, enabling day-to-day platform administration while keeping critical infrastructure and reporting capabilities restricted.

Last updated: September 21, 2026

---
version: "v3.9.1"
language: "en"
---
# Administration Guide

[Overview - Admin Console](https://docs.veridiumid.com/docs/v3.9.1/overview-admin-console.md) [Authentication, Authorization and Audit in Veridium Manager](https://docs.veridiumid.com/docs/v3.9.1/authentication-authorization-and-audit-in-veridium-manager.md) [Dashboard](https://docs.veridiumid.com/docs/v3.9.1/dashboard.md) [Identities - Admin Console](https://docs.veridiumid.com/docs/v3.9.1/identities-admin-console.md)
* [Devices - Admin Console](https://docs.veridiumid.com/docs/v3.9.1/devices-admin-console.md)
[Orchestrator](https://docs.veridiumid.com/docs/v3.9.1/orchestrator.md) [Settings](https://docs.veridiumid.com/docs/v3.9.1/settings.md) [Applications](https://docs.veridiumid.com/docs/v3.9.1/applications.md) [Audit](https://docs.veridiumid.com/docs/v3.9.1/audit.md)
* [Search](https://docs.veridiumid.com/docs/v3.9.1/search.md)
[Statistics](https://docs.veridiumid.com/docs/v3.9.1/statistics.md)

Last updated: September 21, 2026

---
version: "v3.9.1"
language: "en"
---
# Administrator deprovisioning improvements

## **Overview**

Administrator deprovisioning extends the existing deprovisioning functionality in Veridium Manager to automatically identify and remove administrator access from accounts that no longer meet the requirements for administrative access.

The purpose of this functionality is to ensure that administrator permissions remain aligned with the configured administrator authentication sources and that inactive or invalid administrator accounts are automatically detected and reviewed.

The functionality targets administrators authenticated through external identity providers.  
![image-20260724-080857.png](https://docs.veridiumid.com/__attachments/a_380e676971cafb709a9c763ad57b0297e61194087c1e8bd1f187273109a9b2c9/image-20260724-080857.png?cb=b15a0fc3a45a72bd1a1ef96d2236b145)

## **Administrator Definition**

An account is considered an administrator when it has administrative access to Veridium Manager through one or more of the following mechanisms:

* An associated device with `type = admin`

* Membership in one or more groups that grant administrator permissions

*** ** * ** ***

## **Configuration**

A new **Administrators** tab will be added under `Settings → Deprovisioning → Administrator`

The tab will contain the following configuration options.

### **Automatic Scanning**

Enables or disables the Administrator Deprovisioning job.

When disabled, no automatic administrator deprovisioning checks are performed.

**Default:** Disabled

*** ** * ** ***

### **Scanning Frequency**

Cron expression used to schedule the Administrator Deprovisioning job.

The job executes periodically and evaluates administrator accounts against the configured deprovisioning rules.

Example `0 0 * * *` (run daily at midnight)

*** ** * ** ***

### **Identity Inactive Days**

Number of days since the administrator last used Veridium Manager.

If an administrator has no activity during the configured period, the administrator may be marked as deprovisioned.

Special values:  

| **Value** |           **Behavior**           |
|-----------|----------------------------------|
| \<= 0     | Inactivity check disabled        |
| \> 0      | Administrator activity evaluated |

**Default:** 90 days

*** ** * ** ***

### **Automatically Delete Administrators**

When enabled, administrators identified during the **Administrator Synchronization** job as no longer eligible for administrative access are automatically removed from the system.

During synchronization, administrators are first **marked for deprovisioning**. If this setting is enabled, they are then automatically deprovisioned without requiring manual intervention.

Automatic deletion applies to administrators marked with one of the following statuses:

* **Disabled** -- The administrator account is disabled in the external identity provider.

* **Not Found** -- The administrator no longer exists in the external identity provider and could not be found during synchronization.

* **No Permissions** -- The administrator no longer belongs to any group that grants administrative permissions in the external system.

* **No Auth Method** -- The administrator no longer has a valid authentication method configured.

* **Inactive** -- The administrator has not been active for the configured number of days.If this setting is disabled, administrators are only **marked for deprovisioning** and must be reviewed and deprovisioned manually from the **Administrators Deprovisioning** page.

If this setting is disabled, administrators are only **marked for deprovisioning** and must be reviewed and deprovisioned manually from the **Administrators Deprovisioning** page.

*** ** * ** ***

## **Administrator Deprovisioning Job**

The Administrator deprovisioning job periodically evaluates administrator accounts and determines whether they should be marked as deprovisioned.

The job does not immediately delete administrator accounts.

Instead, it marks them for review and places them in the Deprovisioned Administrators list.

*** ** * ** ***

## **Deprovisioning Conditions**

### **Missing Administrator Permissions**

The system verifies that external administrators are still members of the Active Directory groups mapped for administrator authentication.

#### Validation

For each external administrator:

1. Determine all groups configured for administrator authentication.

2. Verify that the administrator still belongs to at least one valid mapped group.

#### Result

If no valid administrator permissions are found the administrator is deprovisioned with reason `No permissions found`.

### **Missing Authentication Method**

The system verifies that administrator accounts have an associated authentication method.

#### Validation

Check whether the account has at least one device of type `admin`.

#### Result

If no administrator authentication device exists the administrator is deprovisioned with reason `No authentication method`.

### **Inactive Administrator**

The system verifies recent administrator activity.

#### Validation

Check the administrator's last activity in Veridium Manager.

#### Result

if `Current Date - Last Activity > Admin Inactive Days` the administrator is considered inactive, and the administrator is deprovisioned with reason `Inactive`.

*** ** * ** ***

## **Deprovisioned Administrators**

A new page will be added to display administrators marked for deprovisioning.

The page should follow the same principles and behavior as the existing **Manage Deprovision Identities** page.  
![image-20260609-135641.png](https://docs.veridiumid.com/__attachments/a_1d0f7bc15800275da4f2851e45e339fd89d1c29c8616fab1ac1b9f333920c17d/image-20260609-135641.png?cb=5613ad964f47cc57f108255fcdec782a)

### **Administrator Details Integration**

#### Available Actions

Administrators should be able to:

* Review deprovisioned administrators

* Delete selected administrators

* Delete all deprovisioned administrators

* Search and filter results

* Export results

#### Deprovisioned Status Indicator

When viewing the **Administrator Details** page for a deprovisioned administrator, a visual indicator should be displayed to clearly communicate the current status of the account.

A badge should be displayed at the top of the page:  
![image-20260609-140044.png](https://docs.veridiumid.com/__attachments/a_a38a14ffca4676e3c2bd1f4f3c269b1028226f34d2e7ec82d7e21f5f5eea1598/image-20260609-140044.png?cb=aaa23aa684762e2ee60f1f13606add68)

*** ** * ** ***

## **Administrator Removal**

Deleting a deprovisioned administrator triggers cleanup actions depending on the deprovisioning reason.

### General Rule

An account may be permanently deleted only if:

* No identities are associated with the account

* No devices are associated with the account

If either condition is not satisfied, the account remains in the system and only administrator-related resources are removed.

*** ** * ** ***

### Reason: No Permissions Found

#### Actions

Remove:

* All associated devices with type `admin`

The account remains available if identities or other device types still exist.

### Reason: No Authentication Method

#### Actions

Remove:

* All administrator permission assignments granted through groups

**TBD:** Define exactly which groups should be removed and whether this applies to local groups, external groups, or both.

### Reason: Inactive

#### Actions

Remove:

* All associated devices with type `admin`

* All administrator permission assignments

**TBD:** Define exact group removal behavior.  
![image-20260609-140432.png](https://docs.veridiumid.com/__attachments/a_442206f353865aa26b8027877fa53b04888eb126546464e868d41c5223249637/image-20260609-140432.png?cb=a4bab7fea7bd8cc5ac86dd9749f9bbc9)

*** ** * ** ***

### Final Account Removal

After the cleanup actions associated with the deprovisioning reason have been executed, the system must evaluate whether the administrator account can be permanently removed.

#### Validation

The account can be permanently deleted only if:

* No identities are associated with the account.

* No devices are associated with the account.

#### Account Deletion

If both conditions are met, the account shall be permanently removed from Veridium Manager.

#### Account Retention

If at least one identity or device remains associated with the account, the account shall not be deleted.

In this case:

* The administrator access remains revoked.

* The account remains available for identity-related or authentication-related functionality.

* Only administrator-specific resources and permissions removed during the cleanup process remain deleted.

![image-20260609-140823.png](https://docs.veridiumid.com/__attachments/a_00cd51c67297acc7e08b834e4b08eb55a8fe6a06dd9553644d91b74079558118/image-20260609-140823.png?cb=8136a636899b2c09d8398dbcde5e5229)

*** ** * ** ***

## **Auditing**

All administrator deprovisioning actions should generate audit events.

Last updated: September 21, 2026

---
version: "v3.9.1"
language: "en"
---
# Administrators

This section allow control of administrative rights across VeridiumID platform. Detail operations are described in a separate section in this documentation, at: [**Administration Guide - Manage Administrators**](https://docs.veridiumid.com/docs/v3.9.1/manage-administrators.md)**.**

Last updated: September 21, 2026

---
version: "v3.9.1"
language: "en"
---
# Advanced

Advanced Enrollment options allows to edit advanced configuration files (JSON) used for Veridium server configuration.

This is an expert feature, and shouldn't be changed without deep knowledge of the impact.

Wrong use of this feature might lead to solution unavailability.

Last updated: September 21, 2026

---
version: "v3.9.1"
language: "en"
---
# Advanced - Generic integration

Advanced Enrollment options allows to edit advanced configuration files (JSON) used for Veridium server configuration.

This is a expert feature, and shouldn't be changed without deep knowledge of the impact.

Wrong use of this feature might lead to solution unavailability.

Last updated: September 21, 2026

---
version: "v3.9.1"
language: "en"
---
# Advanced search

Advanced search can be performed, upon clicking on highlighted arrow down multiple search criteria will be visible:  
![image-20230331-180106.png](https://docs.veridiumid.com/__attachments/a_6389a0761f45d0f9417d4d234ba53cd9907d7277cad77650281f43b41a6798cb/image-20230331-180106.png?cb=cf7f72f151a8328cac7083684e0dabf8)

Than you can search using also other search criteria:

* Name

* Email

* Phone

* UPN

* External ID (in Active Directory External ID is represented by user SID)

* Identity ID (is GUID representing key in VeridiumID in GUID format)

Confirm your search criteria by pressing Search button.

There is also the option to use time filter representing the date of user registration. By default the date filter is "All time":  
![image-20230331-180233.png](https://docs.veridiumid.com/__attachments/a_0a55a852e7c3037e46fd4fdc6fde364108319364a3406aa10251cb4d5b9727f0/image-20230331-180233.png?cb=9a5b87f76aa9c6109f7e788e8f99ab79)

Last updated: September 21, 2026

---
version: "v3.9.1"
language: "en"
---
# Advanced Settings

Advanced settings allows to edit advanced configuration files (JSON) used for Veridium server configuration.

**This is a expert feature, and shouldn't be changed without deep knowledge of the impact.**

**Wrong use of this feature might lead to solution unavailability.**  
![1.png](https://docs.veridiumid.com/__attachments/a_2df05743752e5acbe66f86969b0f5fd95e4ede11214125593694413be1fb9287/1.png?cb=1f4fd4df958339d2c3e513d35cd68c73)

Last updated: September 21, 2026

---
version: "v3.9.1"
language: "en"
---
# Advisory

Last updated: September 21, 2026

---
version: "v3.9.1"
language: "en"
---
# Aggregation table

## Overview

This type of table is used for displaying different aggregations over authentication sessions, grouped by one or multiple fields. For example, the "Top Identities By Number of Sessions" aggregation table groups the authentication sessions by Identity External Id and Identity Display Name (first two columns), and presents some aggregations in the following columns (Session count, distinct Authentication methods used, and so on).

![Screenshot 2024-05-08 at 17.37.27.png](https://docs.veridiumid.com/__attachments/a_aebab918b0c5e1c7af75bb4dbce814c78cc29b722df7a3e7934fce5c0457e563/Screenshot%202024-05-08%20at%2017.37.27.png?cb=80c2ed5ae31e026592810f418ec3a40b)

## Extra options

The user can expand or shrink the width of a column by drag and drop. Also, the user can sort the table by a column, reset the width to the initial value or hide the column from the table by using the column's options.

![Screenshot 2024-05-08 at 17.40.04.png](https://docs.veridiumid.com/__attachments/a_9b28d211434d6c165226787df9f286b028a03cebd80e0f50bf989a32a386587f/Screenshot%202024-05-08%20at%2017.40.04.png?cb=e5aeda23fc126d2f790555d3a7129a5a)

## Filtering

**In or Out filters** can be added on **grouping**columns by using the buttons near the column's value. Some aggregation tables also have the possibility to navigate the user to a different dashboard based on the value of the column.

![Screenshot 2024-05-08 at 17.48.52.png](https://docs.veridiumid.com/__attachments/a_244d795cf45741fab29194ace807960e2b509a2a821d0cebf05fa18d331813d1/Screenshot%202024-05-08%20at%2017.48.52.png?cb=5c3ea02147c5fdbe4870adf4c8be1a00)

Last updated: September 21, 2026

---
version: "v3.9.1"
language: "en"
---
# Allow Not-Registered Users to Access Veridium Self Service Portal (SSP) via External IdP Authentication

## Summary

Many customers use external Identity Providers (IdPs) for authentication in Veridium Self Service Portal (SSP). Currently, SSP allows access only to users already registered in Veridium. This feature extends SSP to permit access for not-registered users, enabling them to initiate enrollment of Veridium credentials.

Example use case: users registered in Entra hybrid joined domains can authenticate with their Entra-side credentials in Veridium, without prior Veridium account enrolment.

### Current process

1. After validating the SAML token, SSP calls Websec to verify the user status based on the subject received in the SAML token.

2. In the current version, if the user is not registered in Veridium, Websec returns "user not found," and access to SSP is denied.

### **Implementation Details**

* Introduce a new API in Websec to verify and create users when necessary.

  The endpoint is present at **/enterprise/friend/GetOrCreateStaticProfile.**

* Ensure the API maintains existing group synchronization, permissions, and access rules.

* Modify SSP authentication flow to use the new API instead of the current verification call.

* Ensure existing workflows that rely on user verification remain unaffected.

* Method should follows these steps:

  1. **Check if the profile exists** based on implicit UPN or external ID.

  2. **Retrieve external identity details** using an adaptor if the profile is not found.

  3. **Create a new profile** if external authentication creation is enabled and the user details are available.

  4. **Validate account status**, ensuring only active accounts can proceed.

  5. **Return the profile** if found or successfully created, otherwise deny access.

### Expected Benefits

* Seamless onboarding for new users via external IdP authentication.

* Improved user experience by enabling credential enrollment within SSP.

* Enhanced flexibility for customers managing access via external IdPs.

![image-20250305-095107.png](https://docs.veridiumid.com/__attachments/a_184a121e2637f0fc6aa27b48ee1ea9ee72954d86c6112886cef2d6878bdb77ac/image-20250305-095107.png?cb=073b63632d7c01a0d7e352f2f822a0f9)  
Make sure the flag for creation profile is enabled in *Settings / General /* **"Create profile When Authenticated Externally"**

Last updated: September 21, 2026

---
version: "v3.9.1"
language: "en"
---
# Android

Last updated: September 21, 2026

---
version: "v3.9.1"
language: "en"
---
# Android C++ Standard Library

The VeridiumID Mobile SDK includes components written in C++ and built with the Android NDK. If you have multiple C++ dependencies your app must include one version of the C++ standard library, provided by the Android NDK, that is compatible with them all.

## Background: C++ Standard Library

Android requires that the C++ standard library, libc++, is distributed with your app as it is not part of the OS. You can only have one instance of the C++ standard library linked into a program. The best option is to use the shared variant of libc++, referred to by the NDK as `c++_shared`.

\[The other alternative, using `c++_static`, is problematic unless the app includes exactly one C++ shared library; each shared library would link in the static C++ standard library, and so end up duplicating it\]

## Pitfalls

When building with Android Studio, the build process collects all C++/native libraries to bundle into the APK. If there are multiple copies of libraries with same filename, it may error out or pick one of them arbitrarily. It also can strip the standard library to remove unused symbols to reduce code size. This can cause incompatibilities to arise, where libraries refuse to load with unresolved symbol errors.

Android NDK r23b introduced a backward compatibility breakage. C++ components built with r23b or later may fail to link to older versions of the standard library (forwards compatibility is unaffected). If a dependancy, other than the Veridium SDK, includes the C++ shared library from an older NDK it can be arbitrarily included and cause a missing symbol error when initialising the Veridium SDK.

## Troubleshooting

Scanning the app's APK dependencies using this python script [version_check.py](https://docs.veridiumid.com/__attachments/a_50fa337880676ec87cb85be34a86d8e69356a62cb55f2b456a1466bb81529cb0/version_check.py.md?cb=3e3249a099f05fd10dfa80d8b9585329) will provide a list of native libraries and identify those causing compatibility issues.

## Solutions

### 1. Update Dependencies

The most effective solution is to update dependencies to versions that use r23b or later. As r23b is from 2021, it is likely there are newer builds available.

### 2. Use a Build Task to Replace libc++_shared.so

As part of the Gradle build tree for android apps (as provided by the Gradle plugin `'com.android.application'`) the task `merge<flavor><buildType>NativeLibs`, where `<flavor>` is the flavor name (if defined) and `<builtType>` is the name of the selected build type, complies together all native libraries. We can add a finaliser task using `finalizedBy()` to copy a version of libc++_shared.so to `/intermediates/merged_native_libs/`.

Edit the app's `build.gradle`, The example below has two build types, `release` and `debug`, and so configures two tasks; `mergeReleaseNativeLibs`and mergeDebugNativeLibs. (You can observe the list of tasks in Android Studio in the Gradle tab). Within `afterEvaluate`, add a finaliser task `replaceStdLib()` to every merge task to copy the contents of `stdlib_nkd\lib`(located one directory up from the build directory) to all `lib` directories under `intermediates/merged_native_libs`.
Groovy

    apply plugin: 'com.android.application'
    android {
      buildTypes {
        debug { ... }
        release { ... }
      }
    }

    tasks.register('replaceStdLib') {
        // Location to copy libc++_shared.so to
        def destDir = file("$buildDir/intermediates/merged_native_libs/")

        inputs.dir("$buildDir/../stdlib_ndk")
        inputs.dir("$buildDir/intermediates/merged_native_libs/")

        doLast {
            // Find all lib folders under the merged_native_libs directory (for all builds/flavors)
            def libFolders = []
            destDir.traverse(type: groovy.io.FileType.DIRECTORIES) { dir ->
                if (dir.name == 'lib') {
                    libFolders << dir
                }
            }

            // Copy .so files to each lib folder
            libFolders.each { libFolder ->
                copy {
                    from(fileTree("$buildDir/../stdlib_ndk/lib").include('**/*.so'))
                    into libFolder
                }
                logger.lifecycle("Merged stdlib_ndk libc++_shared.so to $libFolder")
            }
        }
    }

    afterEvaluate {
        // Set replaceStdLib to finalize all merge native libs tasks
        def mergeNativeLibsTasks = tasks.matching {
            it.name.startsWith("merge") && it.name.endsWith("NativeLibs")
        }
        mergeNativeLibsTasks.all { task ->
            task.finalizedBy(replaceStdLib)
        }
    }

![gradle_tasks.png](https://docs.veridiumid.com/__attachments/a_52bb27c40eec295e7b30e28f1004f1436647a039a3d35e5d624b45faa954a38c/gradle_tasks.png?cb=526a41fe7664269bc36b12507d6adeb9)
Android Studio - Gradle task list

![stdlib_ndk_lib.png](https://docs.veridiumid.com/__attachments/a_ddb335265c20fd4a5e60dbe69f0ba11f53e6c61a963df2de1f2138e41804340a/stdlib_ndk_lib.png?cb=a2bea8a8ebf328c4b614ac9549ae7155)
Required path layout of new libraries to copy

`stdlib_nkd\` can contain `libc++_shared.so` files taken directly from the Android NDK installation at \[*/sources/cxx-stl/llvm-libc++/libs/*\] or for NDK\>=25 \[/toolchains/llvm/prebuilt/darwin-x86_64/sysroot/usr/lib/\], but Veridium can provide this on request.

Note, the NDK libraries include all symbols, including debug symbols. Unnecessary symbols will be stripped when the app apk is constructed later in the build process (depending on your configuration).

### 3. Manually remove libc++_shared.so

Manually remove `libc++_shared.so` from all dependency `.aar` files and instead include `libc++_shared.so` via a "dummy" C++ library.

Change the extension of `veridium-core-release.aar` to `.zip`, extract the contents, remove every instance of `libc++_shared.so`, then re-zip it and change the extension back to `.aar`. Remove any included libc++_shared.so from third-party `.aar` dependencies using the same method.

#### Configure your own C++ libraries

Any C++ libraries you build as part of your Android Studio project must link with `c++_shared` rather than the default `c++_static`. The NDK has [documentation](https://developer.android.com/ndk/guides/cpp-support#selecting_a_c_runtime) for this, but in summary:

#### CMake

The section of the Gradle file which invokes CMake should set the `ANDROID_STL` variable.

    externalNativeBuild {
        cmake {
            arguments '-DANDROID_STL=libc++_shared'
            cppFlags ''
        }
    }

#### ndk-build

Set `APP_STL` in the [http://Application.mk](http://application.mk/) file:

    APP_STL := c++_shared

#### Create a 'dummy' C++ library

If you're not already building your own C++ library, you can create an empty C++ library in Android Studio and configure it as described in the previous section; this will cause Android Studio to bundle libc++_shared.so into the app.

Last updated: September 21, 2026

---
version: "v3.9.1"
language: "en"
---
# Android Integration

4Finger-ID can function in an Enrol-Authentication use case, or act as an exporter whereby fingerprint data is output in a chosen format for 3rd party matching / storage outside of the Veridium SDK. In either case, integration follows the same steps.

This guide covers the use of the 4FingerID biometric specifically and its use in the Veridium SDK. However, we demonstrate the necessary steps to use the 4FingerID biometric from the SDK, and the UI customisation that it allows.

## Requirements

4FingerID requires a minimum Android API level of 21, a rear camera with a minimum resolution of 8 MP, and a rear LED for illumination.

## Modules

* `veridium-fourf-release.aar` - This contains the core logic of the biometric and the Activity from which the biometric is run. (package name: `com.veridiumid.sdk.fourf`

* `veridium-fourf-ui-release.aar`- A UI for portrait mode, self capture, as used in the Veridium Authenticator app. (package name: `com.veridiumid.sdk.fourf.ui`)

In addition to the 4FingerID modules you must also include the following dependencies from the Veridium SDK:

* `veridium-analytics-release`

* `veridium-core-release`

* `veridium-sdk-release`

* `veridium-secure-data-release`

* `veridium-support-release`

## Base Activity

The 4FingerID base activity,`FourFBiometricsActivity`, is contained within the `veridium-fourf` module. Create an Android activity within your own application that extends the base activity. Here you can customise some aspects of the biometric, such as the UI fragment to use, or the biometric storage location.

    package my.app.package

    import com.veridiumid.sdk.fourf.FourFBiometricsActivity;

    public class FourFCaptureActivity extends FourFBiometricsActivity {
        ....
    }

## Meta-data configuration

To configure the SDK use the built-in biometric `AndroidManifest.xml` meta-data mechanism. Add a manifest entry for your 4FingerID activity extending `FourFBiometricsActivity`.

`AndroidManifest.xml` allows the insertion of `<meta-data>` tags that can be parsed/extracted at runtime. The SDK extracts each Activity's meta-data with the property 'android:name="com.veridiumid.sdk.component.config'.

Below is a sample configuration for the 4FingerID biometric, identified by the UID `4F`:

    <activity
        android:name="my.app.package.FourFCaptureActivity"
        android:screenOrientation="portrait">
        <meta-data
            android:name="com.veridiumid.sdk.component.config"
            android:value="uid=4F,optional=false,validator=com.veridiumid.sdk.fourf.FourFValidator" />
    </activity>

The default configuration string format is comma-separated key=value pairs.

    android:value="parameterName=parameterValue, anotherParameterName=anotherParameterValue"

The `validator` value is an `IBiometricValidator` that detects if the biometric component has all its dependencies met to function properly on the target device.

In full, the supported parameters are:

* `uid=stringValue` - unique biometric identifier used to resolve desired biometric components. Use `uid=4F` for 4FingerID.

* `optional=booleanStringValue` - `true|false` indicates that enrolment of this component could be skipped.

* `validatorClass=stringClassName` - the full class name of an IBiometricsValidator implementation. Use the provided class `com.veridiumid.sdk.fourf.FourFValidator`

## Permissions

1. Required camera permissions:

    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.CAMERA" />

    <uses-feature
        android:name="android.hardware.camera"
        android:required="true" />
    <uses-feature
        android:name="android.hardware.camera.autofocus"
        android:required="true" />

1. Required connectivity permissions:

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

## Initialization and Licensing

Your Veridium representative will provide you with either an Online or Offline licence. Licences are simply text strings. They are are tied to your app(s) `applicationId`, which you will need to provide for licence generation.

### Online Licensing

A single licence certificate will activate the SDK within your app, over the internet, for all licensed features. Your Veridium representative will provide you the licence. The licence string is read from the app's `AndroidManifest.xml`. Add the following `<meta-data>` tag to `<application>` and paste in the licence string:
XML

      <application
          <meta-data
              android:name="com.veridiumid.sdk.LICENSE"
              android:value="<licence_string_here>" />
      </application>

(Alternatively, you can define the licence string in your `build.gradle`. See the Quickstart sample app for an example.)

To initialise the SDK call `VeridiumSDK.initAsync()` (non blocking) with appropriate initialisers :
Java

    VeridiumSDK.initAsync(getApplicationContext(),
          new DefaultVeridiumSDKModelFactory(getApplicationContext()),
          new IVeridiumSDKInitializerCallback() {
              @Override
              public void onInitSuccessful() {
                  try {
                      // Initial data storage and check access to the VeridiumSDK singleton
                      DataStorage.init(getApplicationContext());
                      IVeridiumSDK veridiumSDK = VeridiumSDK.getSingleton();
                  } catch (LicenseException e) {
                      // Catch getSingleton() exceptions here
                  }
              }

              @Override
              public void onInitFailed(final SDKInitializationException e) {
                  // Deal with failure to init here.
              }
          },
          new VeridiumSDKFourFInitializer(),
          new VeridiumSDKDataInitializer()
    );

The singleton return by `VeridiumSDK.getSingleton()`is the access point for all biometric operations.

### Offline Licensing

For offline initialisation each biometric requires its own licence string in addition to the SDK licence string, hence multiple `.lic` files. Use the licence string in `sdk.lic` in your `AndroidManifest.xml`, as described in [Online Licensing](https://docs.veridiumid.com/docs/v3.9.1/android-integration.md#Online-Licensing).

Call `VeridiumSDK.init()`(blocking) and provide the `4f_sdk.lic` licence string to `VeridiumSDKFourFInitializer`:
Java

    try {
        String FfidLicense = "Ffid_licence_here";
        VeridiumSDK.init(this,
                new DefaultVeridiumSDKModelFactory(this),
                new VeridiumSDKDataInitializer(),
                new VeridiumSDKFourFInitializer(FfidLicense));
        try {
            IVeridiumSDK veridiumSDK = VeridiumSDK.getSingleton();
        } catch (LicenseException e) {
            // catch getSingleton exceptions here
        }
    } catch (SDKInitializationException e) {
        // Catch init excpetions here
    }

## Liveness

This version uses passive liveness. No additional action by the user is required.

Failure to pass liveness halts the capture process and the SDK returns a `IVeridiumSDK#LIVENESS_FAILED` result.

Turning liveness on/off is now controlled using `ExportConfig`:

    ExportConfig.setUseLiveness(true);

## Configuration with ExportConfig

In brief, to configure 4Finger ID, import the `ExportConfig` class and alter its parameters. These take effect during capture. For example:

    import com.veridiumid.sdk.fourf.ExportConfig;

    ...

    // Configure to capture the left hand without allowing the user to switch hands.
    ExportConfig.setFingersToCapture(ExportConfig.ExportMode.FOUR_F_LEFT_ENFORCED);

    ExportConfig.setCalculate_NFIQ(true);

Many options are available to configure capture and export. Refer to [formats and configuration](https://productdocs.veridiumid.com/docs/veridiumid-sdks/4finger-id/formats-and-configuration) for details as to the options available.

## Invoking an Operation

Start an operation by invoking the corresponding `IVeridiumSDK` interface methods:

1. `IVeridiumSDK#enroll(String[] biometricUids)`

   * Generate enrolment templates

   * `String[] biometricUids` - biometric unique identifiers, as registered by the supplied `IConfiguration#detectComponents()` implementation.

2. `IVeridiumSDK#authenticate(String[] biometricUids)`

   * `String[] biometricUids` - biometric unique identifiers, as registered by the supplied `IConfiguration#detectComponents()` implementation.

3. `IVeridiumSDK#export(String[] biometricUids)`

   * Fingerprint capture only, no enrolment or authentication

   * `String[] biometricUids` - biometric unique identifiers, as registered by the supplied `IConfiguration#detectComponents()` implementation.

The methods return an `Intent` object which the calling activity uses to receive the result.

After getting the intent (by calling the above methods), the parent activity must call `startActivityForResult([biometric_intent], [requestCode])`;

where `requestCode` is an integer identifier for the result.

For example, to run the `export` operation :

    import com.veridiumid.sdk.fourf.FourFInterface;

    static final int REQUEST_CAPTURE = 100

    try {
        Intent fourFIntent = VeridiumSDK.getSingleton().export(FourFInterface.UID);
        startActivityForResult(fourFIntent, REQUEST_CAPTURE);
    } catch (LicenseException e) {
        e.printStackTrace();
    }

where `FourFInterface.UID` provides the biometric UID string ("4F").

### External parameters

Any operation has support to send external parameters using [Intent Extras](https://developer.android.com/guide/components/intents-filters#Building). In order to avoid collision between external parameters and the internal parameters that SDK uses, all the external parameters are encapsulated within a [Bundle](https://developer.android.com/reference/android/os/Bundle) and set on the reserved key `IVeridiumSDK.EXTRA_KEY_EXTERNAL_PARAMETERS`

#### Sending external parameters:

    public class MainActivity{

        private void capture4F(){}
            try {
                String sessionId = UUID.randomUUID().toString();
                Intent fourFIntent = VeridiumSDK.getSingleton().export(FourFInterface.UID);
                fourfIntent.putExtra("sessionId", sessionId )
                startActivityForResult(fourFIntent, REQUEST_CAPTURE);
            } catch (LicenseException e) {
                e.printStackTrace();
            }
        }

    }

#### Reading external parameters:

    public class FourFCaptureActivity extends FourFBiometricsActivity {
        
        private String mSessionId;

        @Override
        protected void onCreate(final Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            
            Bundle externalParams =  getIntent().getExtras().getBundle(IVeridiumSDK.EXTRA_KEY_EXTERNAL_PARAMETERS);
            mSessionId = externalParams.getString("sessionId");

        }
    }

## Handling An Operational Result

To receive the operation result the calling activity implements the `onActivityResult()` method.

You receive three parameters: `requestCode`, `resultCode`, `data`

* `requestCode` integer identifier for the result.

* `resultCode` contains the biometric operation result. **Note:** its value can be one of the examples specified in the **Result codes** section.

* `data` Intent containing additional information, such as error messages.

To access biometric data you must use the `BiometricResultsParser`. Implement the `IVBiometricResultsHandler` interface to customise actions and pass it to the `BiometricResultsParser`, along with the `resultCode` and intent `data`:

    IVBiometricResultsHandler customResultHandler = new IVBiometricResultsHandler() {
        @Override
        public void handleSuccess(Map<String, byte[][]> results) {
            // handle template data here
        }

        @Override
        public void handleFailure(String reason, int code) {
        }

        @Override
        public void handleCancellation() {
        }

        @Override
        public void handleError(String message, int code) {
        }
    };

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        if (requestCode == REQUEST_CODE_FOURF_CAPTURE) {
            BiometricResultsParser.parse(resultCode, data, customResultHandler);
        } else {
            super.onActivityResult(requestCode, resultCode, data);
        }
    }

### *public void handleSuccess(Map\\\<String, byte\[\]\[\]\> results)*

Results are received for all the biometrics run. Access the data for 4FingerID using its UID, for example, one `handleSuccess()` implementation may contain:

    byte[] template = null;
    byte[] export_data = null;
    byte[] dev_data = null;

    for (Map.Entry<String, byte[][]> entry : results.entrySet()) {
        String bio_key = entry.getKey();
        byte[][] data = entry.getValue();

        if(bio_key.equals(FourFInterface.UID)){
            template = data[0];    // enrolment data
            template = data[1];    // export data
            dev_data = data[2];    // development info (in zip format)
        }
    }

Dimension of the byte array are as follows:

* byte\[0\]\[\] - Enrolment template data.

* byte\[1\]\[\] - Export template data in the configured format

* byte\[2\]\[\] - Development output contained in zip format

*Note* To receive development data set `ExportConfig.setPackDevOutput(true)`.

### *public void handleFailure(String reason, int code)*

The operation was unsuccessful, despite the users efforts, for one of the following reasons:

* Reason "`MISMATCH`": Biometric authentication with the enrolment failed.

* Reason "`TIMEOUT`":Timeout or maximum allowed capture attempts were reached. Capture failed due to failure to detect fingers or reach an acceptable quality.

* Reason "`LIVENESS`":Liveness failed

### *public void handleCancellation()*

A user chooses to cancel during an operation and not capture any data. The operation finishes without returning any biometric data. The user did not exhausted their opportunities to capture. Once data has been captured the user is not able to cancel the operation. Using the provided UI, a cancelation may occur in the following ways:

* Pressing 'Cancel' on the instruction screen.

* Pressing the `X` icon on the capture screen.

* Interaction with OS navigation buttons interrupting the capture.

### *public void handleError(String message, int code)*

An unexpected error occurred during the operation preventing completion. This may occur due to the following:

* **Reason "** `BAD_CONFIG`**": Incorrect configuration** (message: *Platform submitted an unsupported config request*). You should resolve this during app development. It will not occur again once configuration is corrected.

* **Reason "** `EXCEPTION`**": Code Exception** (message: *Library threw an otherwise unhandled exception.*) The operation threw an exception that could not be recovered from. For example, the camera disconnected during capture.

* Reason "UNKNOWN": An unknown error.

Please report the code to Veridium.

## Data Storage Customization

The biometric default activity `FourFBiometricsActivity` contains the overridable method:

    @Override
       protected IKVStore openStorage() {
    }

This returns a Key-Value Storage object, `IKVStore`. The SDK provides two storage types:

* `InMemoryKVStore` Data stored in memory only (data is lost on application and never written to disk)

* `SecureKVStore` Data is written to secure preferences. This type should be used via the provided `com.veridiumid.sdk.defaultdata.DataSorage` class.

For example, to have data written only to memory, and accessed externally, override the `openStorage()` method:

    private static InMemoryKVStore myMemoryKVStore = new InMemoryKVStore();

    @Override
    protected IKVStore openStorage() {
        return myMemoryKVStore;
    }

To create a secure preferences storage object, for example to create multiple enrolments for multiple users, use the `DataStorage` class with your own keys:

    private static String ENROL_KEY_A =  "enrol_storage_a";
    private static String ENROL_KEY_B =  "enrol_storage_b";

    @Override
    protected IKVStore openStorage() {
        if(use_storage_A){
            return DataStorage.openStorage(ENROL_KEY_A);
        }else{
            return DataStorage.openStorage(ENROL_KEY_B);
        }
    }

## Device Support Definition

Certain Android devices may behave more reliably if using Camera 1 API, or a different mechanism of manual focus.

Internally, Veridium stores lists of devices that require alterations to the capture system as work arounds for API inconsistencies.

However, additional devices can be added to custom lists for on-the-fly adjustments to correct device that are failing to capture. 4Finger ID supports four types of adjustments for a device:

1. **Force use of Camera 1 API**. Some devices do not conform correctly to the Camera 2 API, and will likely function better using Camera API 1.

2. **Device blocking**. Devices known to be incomparable can be blocked from using 4F and will return failures.

3. **Force manual focusing**. 4F can take control of the focus system if auto-focus is not functioning. This is only possible on a limited range of devices that support control of lens positioning.

4. **Forcing a field-of-view**. Some devices incorrectly report the FOV of the camera leading to incorrect judgement of distance by 4F. Consult the device specifications to attain the true FOV.

Import the static class `com.veridiumid.sdk.fourf.SupportDefinition`. Devices are identified with a string ID built from their manufacturer and model number using `SupportDefinition.getDeviceName().` Create custom lists of devices.
Java

    import com.veridiumid.sdk.fourf.SupportDefinition;

    private String[] force_cam1_list = {
            "Samsung SM-G973F"
    };

    private String[] block_list = {
            "NXT-G877G"
    };

    private String[] force_manual_focus = {
            "LG H930H"
    };

    private final Map<String, Integer> forced_fov_map = Map.of(
            "forced_fov_dev", 65
    );

    // Set custom lists
    SupportDefinition.setCustomCamera1List(force_cam1_list);
    SupportDefinition.setCustomBlockList(block_list);
    SupportDefinition.setCustomManualFocusList(force_manual_focus);
    SupportDefinition.setForcedFOVMap(forced_fov_map);

The device support definition also allows interception of a limited number of values at runtime. These values are not predetermined, hence are reported for logging or alteration at runtime. Currently, only the determined camera field-of-view is supported.

Create a `FourFInterceptor`and set it in the `SupportDefinition`, for example within your activity's `onCreate()`, taking care to null it on activity destruction:
Java

    import com.veridiumid.sdk.fourf.FourFInterceptor;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // Example intercepting a value for alteration at runtime
        SupportDefinition.setInterceptor( new FourFInterceptor() {
            @Override
            public float fovIntercept(float input) {
                return input; // can be logged or altered, eg. Math.max(input, 68.f);
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        SupportDefinition.setInterceptor(null);
    }

## Finger Selector Module

The `veridium-finger-selector` module provides a simple UI for user finger selection. The user is displayed a graphic of a hand, and can tap those fingers that they wish to capture.

\[Note, this a feature for Export only, and not Enrol / Authenticate use cases.\]

The finger selector is not a required component, so is provided in the Android Quick Start project. It can be used directly, or as an example for building a custom UI for finger selection. Usage is demonstrated in the `sample-ffid-export` app.

Launch the `FingerSelectionActivity`:

    import com.veridiumid.sdk.fingerselector.FingerSelectionActivity;
    ...
    Intent intent = new Intent(MainFragmentActivity.this, FingerSelectionActivity.class);
    startActivityForResult(intent, REQUEST_ID_FINGER_SELECT);

Catch the result and read extra data key `IndividualCapture` for success or failed user selection:

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_ID_FINGER_SELECT) {
            bool success = data.getBooleanExtra("IndividualCapture", false);
        } 

        // complete
        super.onActivityResult(requestCode, resultCode, data);
    }

No further action is needed to configure the fingers to capture.

\[The necessary Export config settings are be applied by `FingerSelectionActivity` according to the fingers selected by the user, via `ExportConfig.setFingersToCapture()`.\]

## User Interface

4FingerID provides single UI as a separate module:

* `veridium-fourf-ui-release.aar` - UI for portrait mode, self capture, as used in the Veridium Authenticator app.

The UI is implemented as fragment which is displayed full screen. It is composed of a main capture screen and an optional help screen (shown prior to biometric capture).

You can design your own fragment for display by implementing the required interface `FourFUIInterface` and making requests via the `FourFUIIntegrationWrapper`. However, it is recommended to extend the provided UI and override methods as needed.

### Specifying a UI fragment

To use the desired UI fragment, override the `fragmentToShow()` method of your 4FingerID activity. For example, the default UI:

    import com.veridiumid.sdk.fourf.FourFBiometricsActivity;
    import com.veridiumid.sdk.fourf.ui.FourFUIFragment;

    public class FourFCaptureActivity extends FourFBiometricsActivity
    {
        ...

        @Override
        protected <FourFFragmentInterfaceUnion extends Fragment & FourFUIInterface> FourFFragmentInterfaceUnion fragmentToShow() {
            return (FourFFragmentInterfaceUnion) new FourFUIFragment();
        }
    }

### Introduction Screen

By default, the instruction screen will show before fingerprint capture for Enrol and Export operations. Control it manually by overriding

    protected boolean showInstructionScreen()

## UI Customisation

### UI Customisation: UI Source Project

Any aspect of the UI can be altered by importing the project `veridium-fourf-ui` and editing its source. The following example demonstrates this using the `sample-ffid-export` app provided in the Android Quickstart package.

1. In Android Studio, open *quickstart-android* as an existing project (open the root folder). You should see `sample-ffid-export` and `veridium-fourf-ui` listed.

   ![image-20230828-083307.png](https://docs.veridiumid.com/__attachments/a_be47c2d2d60a2a104fabed6d2c1c5d1357dc4569e085ce8383c29c762739fd61/image-20230828-083307.png?cb=7d6f93bb3ddfe756cb4abbfca8e8c49f)
2. Build and run `sample-ffid-export.app` and ensure it runs successfully.

3. Replace the pre-packaged `veridium-fourf-ui-release.aar` with the source project. In *quickstart-android/sample-ffid-export/app/build.gradle* , under *dependencies* , remove `implementation(name: 'veridium-fourf-ui-release', ext: 'aar')` and instead add `implementation project(':veridium-fourf-ui')`.

   ![image-20230828-083321.png](https://docs.veridiumid.com/__attachments/a_0944faa12409011652092dc7891a56633e3234733debcc604e1f6fdbe25d500a/image-20230828-083321.png?cb=55a811ed308b9953a8ad1e031dbb052e)
4. Clean and build `sample-ffid-export.app`. It will now be using `veridium-fourf-ui` project source and edits can be made.

   ![image-20230828-083349.png](https://docs.veridiumid.com/__attachments/a_bfd6c692fe9e9ce81b4659c369e57ec34ea1ac382f38c8656c8d596cb60b1128/image-20230828-083349.png?cb=dc394deb27b4e3b2fcae8c3934b58acc)

### UI Customisation: Extending the Default UI

The simplest method of customisation is to extend the provided UI and override its methods.

For example, create a custom UI class by extending `FourFUIFragment`:

    import com.veridiumid.sdk.fourf.ui.FourFUIFragment;

    public class customFourFUI extends FourFUIFragment{
    }

, and then overload `fragmentToShow()` in a custom Base Activity, along with any methods you wish to alter, for example,

    public class CustomFourFActivity extends FourFBiometricsActivity {
        @Override
        protected <FourFFragmentInterfaceUnion extends Fragment & FourFUIInterface> FourFFragmentInterfaceUnion fragmentToShow(){
            return (FourFFragmentInterfaceUnion) new customFourFUI();
        }
        
        @Override
        protected boolean useBlobs(){
            return true;
        }
        
         @Override
        protected boolean useMitten(){
            return false;
        }

         @Override
        protected boolean useMeter(){
            return true;
        }
    }

### UI fragment Principles

Here we describe the main principles behind the UI fragment. For a complete description of all UI interface methods see the included JavaDoc for `FourFUIInterface` and `FourFUIIntegrationWrapper`.

Create a class extending `Fragment` and implementing `FourFUIInterface`. Import the `onFourFFragmentReadyListener` and override the `onReady()` method to indicate readiness which starts the biometric capture process.

    import com.veridiumid.sdk.fourf.FourFUIInterface;
    import com.veridiumid.sdk.fourf.FourFUIIntegrationWrapper;
    import com.veridiumid.sdk.fourf.onFourFFragmentReadyListener;

    public class FourFCaptureFragment extends Fragment implements FourFUIInterface {

        private onFourFFragmentReadyListener listener;

         @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
             // inflate your layout
            return inflater.inflate(R.layout.my_capture_layout , container, false);
        }

         @Override
        public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
            super.onViewCreated(view, savedInstanceState);
            // perform setup
            listener.onFourFFragmentReady();
        }

        @Override
        public void onReady(onFourFFragmentReadyListener listener) {
            this.listener = listener;
        }
    }

Specify your new fragment in the `fragmentToShow()` method of your 4FingerID activity.

To interact with the biometric you can call through via `FourFUIIntegrationWrapper`. This handles user interactions that may happen at any time, or to indicate the user wishes to progress or cancel. For example, requesting help via `FourFUIIntegrationWrapper.requestHelp()`. 4FingerID will receive such a request and call back to your UI fragment to request showing of help.

The UI fragment responds to events it receives via interface methods. For example, when an image is about to be captured your UI fragment receives a call to `onTakePictureStart()`:

    @Override
    public void onTakePictureStart() {
       // Indicate to the user that the system is capturing a photo.
    }

The UI is not required to perform an action in this case, and it can be safely ignored if desired. However, note that 4FingerID does not wait for an action to be taken in this case.

When an action is required that is *blocking* progress a call too `handleBlockingUIInstruction()` is received. This handles any case where the user is expected to provide confirmation and the process halts. Once the UI has determined the user is ready to continue, indicate this by calling `FourFUIIntegrationWrapper.handledBlockingUIInstruction()` with a `UserAction`. For example:

    @Override
    public void handleBlockingUIInstruction(blockingUIInstruction instruction){
        if (instruction == blockingUIInstruction.DISPLAY_HELP) {
            // show the user help

            FourFUIIntegrationWrapper.handledBlockingUIInstruction(UserAction.NEXT);
        }
    }

You can choose to advance the process immediately if you wish.

### Configuring For Print Capture

Because 4FingerID is able to capture a variety of fingers and thumbs, in any combination, an important interface method to implement carefully is `configureUI()`. This provides information about the *mode* 4FingerID is currently in, where the hand or digit should be placed within the camera view, and whether the user can select which hand they are capturing.

`configureUI()`is called whenever 4FingerID needs to capture a particular print, and this may occur several times. For example, when configured to capture both the left hand and the right hand, `configureUI()` is called twice; once at the start of left hand capture, and again after successful capture of the left hand to begin right hand capture. See the JavaDoc for details.

### Camera Preview

4FingerID controls the camera device internally so integrators need not worry about the camera api and the complexities that come with ensuring device compatibility.

However, preview frames generated by the camera can be shown in your UI by providing a `AspectRatioSafeFrameLayout` frame layout in the `getPreviewHolder()` method. Preview frames from the camera are posted to this frame layout.

       private AspectRatioSafeFrameLayout mPreviewHolder;

       @Override
       public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
           mPreviewHolder = view.findViewById(R.id.camera_preview_container);
       }

       @Override
       public AspectRatioSafeFrameLayout getPreviewHolder() {
           return mPreviewHolder;
       }

### Switching Hands During Capture

You can request to switch hands during the capture process if the user is either enroling or exporting, by calling `FourFIntegrationWrapper.requestSwitchHand()`.

Your logic for displaying UI components for switching hands should take notice of the `canSwitchHand` boolean provided by the `configureUI()` method.

For example:

    @Override
    public void configureUI(captureMode mode, printToCapture print, RectF regionOfInterest, boolean canSwitchHand) {

            usingRightHand = !print.isLeftHand();

             // if the user is allowed to switch hands, display a UI switch (left_right_switch)
            if(canSwitchHand) {
                left_right_switch.setChecked(print.isLeftHand());
                left_right_switch.setVisibility(View.VISIBLE);
            }else{
                left_right_switch.setVisibility(View.INVISIBLE);
            }
            
            // Request to switch hands on click
            left_right_switch.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    FourFUIIntegrationWrapper.requestSwitchHand();
                }
            });
            .....
    }

### Typical UI flow

An operation intent is created using the Veridium SDK from your application's activity. For example, VeridiumSDK.getSingleton().enrol(FourFInterface.UID) starts the activity. In `onCreate()` of `FourFBiometricsActivity` the following occurs:

1. `openStorage()`opens datastorage.

2. `fragmentToShow()`retrieves the UI fragment to show during capture (`UIFragment` in this example).

3. Transition to the UI fragment.

4. `UIFragment.onReady()` is called with an `onFourFFragmentReadyListener` object to indicate readiness.

5. The UI fragment is created, and the fragment's `onViewCreated()` method `onFourFFragmentReadyListener.onFourFFragmentReady()`starts the biometric capture.

6. `UIFragment.getPreviewHolder()` passes the preview holder to the camera.

7. `UIFragment.setPreviewResolution()` informs the UI of the camera preview resolution.

Once the above setup is complete 4 Finger ID calls UI interface methods to guide and inform during biometric capture. A typical flow is:

1. `UIFragment.configureUI()` informs the UI to display the appropriate interface and align UI components.

2. `UIFragment.handleBlockingUIInstruction(blockingUIInstruction.DISPLAY_HELP)` requests the UI show a user help screen prior to capture.

3. `UIFragment.handleUIInstruction(uiInstruction)` series of instructions received indicating the current state of capture.

4. `UIFragment.onTakePictureStart()` an image is being taken with the camera.

5. `UIFragment.onTakePictureStop()` image capture has completed.

6. `UIFragment.onImageAcceptance()` the image was accepted as being good quality, otherwise `UIFragment.onImageRejection()` is called and the system returns to step *3*.

7. `UIFragment.onProcessingStart()` begins extracting biometric data / matching.

8. `UIFragment.onProcessingStop()` processing completed.

9. `UIFragment.dismiss()` is the last call to the UI fragment, which (passes or relays?) the result to the user, and calls `finish()` on the activity.

Failing to capture a good quality image returns the system to step 3. This flow can be interrupted at any time if the user cancels, requests to change hands, or requests help via `handleBlockingUIInstruction()`.

Last updated: September 21, 2026

---
version: "v3.9.1"
language: "en"
---
# Android Platform UI Interface

UI abstract class with methods callable by the 4FingerID library. Allows the library to control the platform GUI from the library. Implement this abstract class to build a completely custom UI.

    /**
     *  UI abstract class that has abstract methods called by the FourF library. Allows the library
     *  to control the platform gui from the library. Must not change any method signatures without
     *  also making the same changes in the library.
     */

    public interface FourFUIInterface {

        /**
         * The distinct modes in which 4FingerID can capture fingerprint data.
         */
        enum captureMode{
            /** 4 fingers of one hand, presented from the side of the screen */
            Hand(0),
            /** thumb, presented from the bottom of the screen */
            Thumb(1),
            /** single finger, presented from the side of the screen */
            Finger(2),
            /** 4 fingers of one hand, presented from the top of the screen */
            AgentHand(3);

            private int code;
            captureMode(int code) {
                this.code = code;
            }
            public int getCode() {
                return code;
            }

            public static captureMode resolve(int what) {
                captureMode[] states = values();
                for (captureMode state : states) {
                    if (state.code == what) {
                        return state;
                    }
                }
                return null;
            }
        }

        /**
         * The current target for capture, either an individual finger, a thumb, or 4 fingers of a hand
         */
        enum printToCapture{
            INVALID(0),
            THUMB_RIGHT(1),
            INDEX_RIGHT(2),
            MIDDLE_RIGHT(3),
            RING_RIGHT(4),
            LITTLE_RIGHT(5),
            THUMB_LEFT(6),
            INDEX_LEFT(7),
            MIDDLE_LEFT(8),
            RING_LEFT(9),
            LITTLE_LEFT(10),
            HAND_RIGHT(11),
            HAND_LEFT(12);

            private int code;
            printToCapture(int code) {
                this.code = code;
            }
            public int getCode() {
                return code;
            }

            public static printToCapture resolve(int what) {
                printToCapture[] states = values();
                for (printToCapture state : states) {
                    if (state.code == what) {
                        return state;
                    }
                }
                return null;
            }

            public boolean isLeftHand(){
                switch (this) {
                    case INVALID:
                        return false;
                    case THUMB_RIGHT:
                    case INDEX_RIGHT:
                    case MIDDLE_RIGHT:
                    case RING_RIGHT:
                    case LITTLE_RIGHT:
                        return false;
                    case THUMB_LEFT:
                    case INDEX_LEFT:
                    case MIDDLE_LEFT:
                    case RING_LEFT:
                    case LITTLE_LEFT:
                        return true;
                    case HAND_RIGHT:
                        return false;
                    case HAND_LEFT:
                        return true;
                }
                return false;
            }
        }

        /**
         * Instructions to relay to the user as to the progress of a capture.
         */
        enum uiInstruction{  //FIXME improve instruction names
            /** correct position for capture, the user must be still */
            Wait(0),
            /** an image was out of focus */
            OutOfFocus(1),
            /** correct position, preparing to take an image */
            Yes(2),
            /** hand is too close to the camera */
            RoiTooBig(3),
            /** hand is too far from the camera */
            RoiTooSmall(4),
            /** the user is holding their fingers apart */
            FingersTooFarApart(5),
            /** fingers too high (towards the index finger) */
            FingersHigh(6),
            /** fingers too low (towards the little finger) */
            FingersLow(7),
            /** fingers too far left */
            FingersFarLeft(8),
            /** fingers too far right */
            FingersFarRight(9),
            /** the system is expecting an image to be taken */
            ImageRequestedWaiting(10),
            /** the fingers can not been seen or are unexpected */
            InvalidROIS(11),
            /** the camera feed is too dim */
            ImageTooDim(12),
            /** user showing the wrong hand */
            WrongHand(13);

            private int code;
            uiInstruction(int code) {
                this.code = code;
            }
            public int getCode() {
                return code;
            }

            public static uiInstruction resolve(int what) {
                uiInstruction[] states = values();
                for (uiInstruction state : states) {
                    if (state.code == what) {
                        return state;
                    }
                }
                return null;
            }

        }

        /**
         * Types of blocking event for indicating specific events to a user
         */
        enum blockingUIInstruction{
            /** NONE */
            NONE(0),
            /** switching to the next capture target */
            SWITCH_CAPTURE_TARGET(1),
            /** Enrolment step 2 of 2 will begin */
            ENROLLMENT_STEP2_OF_2(2),
            /** Enrolment step 2 of 3 will begin */
            ENROLLMENT_STEP2_OF_3(3),
            /** Enrolment step 3 of 3 will begin */
            ENROLLMENT_STEP3_OF_3(4),
            /** User failed in the biometric match */
            INTERNAL_MISMATCH(5),
            /** Display help to the user */
            DISPLAY_HELP(6);

            private int code;
            blockingUIInstruction(int code) {
                this.code = code;
            }
            public int getCode() {
                return code;
            }

            public static blockingUIInstruction resolve(int what) {
                blockingUIInstruction[] states = values();
                for (blockingUIInstruction state : states) {
                    if (state.code == what) {
                        return state;
                    }
                }
                return null;
            }

        }

        /**
         * Types of user actions.
         */
        enum UserAction{
            /** user wishes to continue */
            NEXT(0),
            /** user wishes to cancel */
            CANCEL(1);

            private int code;
            UserAction(int code) {
                this.code = code;
            }
            public int getCode() {
                return code;
            }

            public static UserAction resolve(int what) {
                UserAction[] states = values();
                for (UserAction state : states) {
                    if (state.code == what) {
                        return state;
                    }
                }
                return null;
            }

        }

        /**
         * Reasons for ending an operation
         */
        enum FourFFinishReason{
            SUCCESS_ENROLL(0),
            SUCCESS_AUTHENTICATE(1),
            SUCCESS_EXPORT(2),
            FAIL_ENROLL(3),
            FAIL_AUTHENTICATE(4),
            FAIL_LIVENESS(5),
            CANCEL(6),
            TIMEOUT(7),
            ERROR(8);

            private int code;
            FourFFinishReason(int code) {
                this.code = code;
            }
            public int getCode() {
                return code;
            }

            public static FourFFinishReason resolve(int what) {
                FourFFinishReason[] states = values();
                for (FourFFinishReason state : states) {
                    if (state.code == what) {
                        return state;
                    }
                }
                return null;
            }
        }

        /*
            Methods to be called by Library
            (To communicate from the UI to the FourF library call the methods available in the
             FourFIntegrationWrapper)
         */

        /**
         * Implement UI updates given an instruction. These events do not halt progress of the capture
         * so you should not expect user input. Newly received instructions should override previous
         * instructions.
         * @param instruction instruction
         */
        void handleUIInstruction(uiInstruction instruction);

        /**
         * Implement UI updates given an instruction. These events halt progress of the capture in order
         * to get user input if desired. Once handled, call
         * FourFUIIntegrationWrapper.handledBlockingUIInstruction() with a UserAction to continue.
         * @param instruction instruction
         */
        void handleBlockingUIInstruction(blockingUIInstruction instruction);

        /**
         * Indicates the biometric is processing for a result following successful acceptance
         * of a capture. No other feedback is given until onPocessingStop() is received. Use this, for
         * example, to show a spinning progress wheel.
         */
        void onProcessingStart();

        /**
         * Indicates the biometric has finished processing for a result following successful acceptance
         * of a capture. This is always paired with an onPocessingStart().
         */
        void onProcessingStop();

        /**
         * The system is about to begin taking a high resolution picture. This is always paired with
         * onTakePictureStop().
         */
        void onTakePictureStart();

        /**
         * The system has finished taking a high resolution picture. This is always paired with
         * onTakePictureStart().
         */
        void onTakePictureStop();

        /**
         * An image has been accepted as being of good quality. Processing will not begin until this
         * has occurred. Once received a user can safely remove their hand from view.
         */
        void onImageAcceptance();

        /**
         * An image has been rejected because of poor quality. Processing will not begin, and another
         * image may be requested.
         */
        void onImageRejection();

        /**
         * Provides information about the *mode* 4 FingerID is currently in, where the hand / digit
         * should be placed within the camera view, and if the user is able to decide to alter which
         * hand they are capturing.
         *
         * configureUI() will be called whenever 4 FingerID indicates it would like to capture a
         * particular print, and this may occur several times. For example, when configured to capture
         * both the left and right hand `configureUI()` will be called twice; once at the start
         * of left hand capture, and again after successful capture of the left hand to begin right hand
         * capture.
         *
         * @param mode The mode that the UI should prepare capture for. You should layout your UI
         *             accordingly.
         * @param print Which fingerprint, or prints, are about to be captured
         * @param regionOfInterest A rectangle indicating the region in the camera preview a user should
         *                         place their fingers within. You should use this region to position your
         *                         hand guide on screen. Values are normalised to the camera preview.
         *                         For example, an x value of 0.5 is the centre of the preview. A width
         *                         value of 0.25 is 25% the width of the preview. Note: this area will
         *                         differ between devices, so do not use a static positioning of UI
         *                         components.
         * @param canSwitchHand TRUE if the user is allowed to choose to switch hands during capture. If
         *                      TRUE you should provide a mechanism for the user to change hands (see
         *                      FourFUIIntegrationWrapper.requestSwitchHand()). If FALSE, disable any
         *                      UI for hand switching.
         */
        void configureUI(captureMode mode, printToCapture print, RectF regionOfInterest, boolean canSwitchHand);

        /**
         * Display realtime feedback. This includes "hand distance" relative to the
         * optimal, and position of each finger.
         *
         * @param rois RectF array indicating the position of fingers; index, middle, ring, and little.
         *             Values are normalised to the camera preview. For example, an x value of 0.5 is the
         *             centre of the preview. A width value of 0.25 is 25% the width of the preview.
         *             You must account for how your UI has cropped and positioned the camera preview in
         *             order to display them correctly.
         * @param distance the normalised distance of the hand from the optimal distance given in the
         *                 range [-2.5, 2.5], where values [-1.0, 1.0] are acceptable for capture.
         */
        void displayRealTimeInformation(RectF[] rois, float distance);

        /**
         * Informs your UI of camera preview width and height, for example, to set aspect ratios.
         *
         * @param width camera preview width (pixels)
         * @param height camera preview height (pixels)
         */
        void setPreviewResolution(int width, int height);

        /**
         * Control display of the instruction screen
         *
         * @param showInstructionScreen When TRUE the instruction screen is displayed
         */
        void setShowInstructionScreen(boolean showInstructionScreen);

        /*
            Methods that will be called by the platform
         */

        /**
         * Provide a frame layout for rendering the camera preview to.
         * @return an AspectRatioSafeFrameLayout frame layout
         */
        AspectRatioSafeFrameLayout getPreviewHolder();

        /**
         * Receive a listener object on which to call FourFFragmentReady() once the UI fragment is
         * inited.
         * @param onFourFFragmentReadyListener listener to allow the UI fragment to declare it is ready
         */
        void onReady(onFourFFragmentReadyListener onFourFFragmentReadyListener);

        /**
         * Called when an operation has completed, including a reason for the completion. Call
         * MyCustomUIFragment.this.getActivity().finish(); to finish.
         *
         * @param reason reason for completion.
         */
        void dismiss(FourFFinishReason reason);
    }

Last updated: September 21, 2026

---
version: "v3.9.1"
language: "en"
---
# Android Quickstart Sample App

Get started by running the 4FingerID Sample App and review its code alongside the [Android integration guide](https://productdocs.veridiumid.com/docs/veridiumid-sdks/4finger-id/android/4f-android-integration). Code can be repurposed for your own application.

## Sample App (*sample-ffid-export* )

The 4Fingers ID *sample-ffid-export* app demonstrates Veridium SDK integration and use of 4Fingers ID. It is intended as a minimal functional example and demonstrates:

* Licensing

* SDK initialisation

* Format selection

* Fingerprint export with various configurations

* Finger Selection

![:warning:](https://docs.veridiumid.com/__attachments/a_4d9fb399861f8c6af2f09cdc70ba2cf720e67d646cf78e4d7bc2c7f3cfbe6fd1/atlassian-warning?cb=14432459925d605e05cae2605cdfe666)  

### WARNING

If your license is only valid for 4Finger ID it will only function with the *sample-ffid-export* app, not any other Veridium sample app.

Please remove all previous versions of the sample apps before installing. These apps require a minimum of Android API 21 (Android 5.0, Lollipop).

This guide does not cover using the emulator due to use of hardware cameras.

### Build and Run

To build and run *sample-ffid-export*

1. Download and extract the *VeridiumSDK_Android_\[version\].zip* package as provided by your Veridium salesperson. The *sample-ffid-export* app is located at the root.

2. In Android Studio got to *File-\>Open* and open the root directory of the Veridium SDK package. If Android studio requests that you install the required Android SDK Platforms and Tools, do so.

3. In the *project* tab, in the left side navigation window, select *Android* from the dropdown view options. You will see all the available sample apps and gradle scripts, including *sample-ffid-export*.

4. In the *run configurations* dropdown in the toolbar, select *sample-ffid-export.app*.

5. Clean the project by menu selecting *Build-\>Clean* and then build the app via *Build-\>Rebuild*. This should successfully build the application.

6. A licence certificate is required to activate the SDK over the internet. This is provided by your Veridium representative inside a text file `certificate.base64` . Open `certificate.base64` with a text editor \[Note: the file is UTF-8 plain text encoded\] and copy the whole licence certificate string for pasting into the app.

7. In Android Studio, under *Gradle Scripts* in the left pane navigation, open *build.gradle (Module:sample-ffid-export:app)* and paste the licence string to replace *\<licence\>*:

       ```
       // TODO add here the VERIDIUM SDK licence
       manifestPlaceholders = [VERIDIUM_SDK_LICENSE: "<licence>"]
       ```

8. Your licence is tied to the app's *applicationId* . If required, change the *applicationId* in the *build.gradle* to that indicated by your Veridium salesperson. As supplied, the ID is set as `applicationId "com.veridiumid.sample.export"`.

9. Connect an Android device via USB. Ensure the device has *USB debugging* enabled within *Developer Options* . Select the device from the *available devices* dropdown on the toolbar. \[Note: the method of accessing *Developer Options* varies between devices. Please consult documentation from the manufacturer\]

10. Uninstall older versions of the app from the device.

11. Hit the *run* toolbar button to launch the app on the device. On first operation the app will ask for permissions. Press *Allow* or the app will not function.

### App Features

The app has a basic home screen layout (`res/layout/fragment_home.xml`) with buttons for running different configurations, a drop down for export format selection, and checkboxes for enabling liveness and dev output (useful for debugging).

`CustomFourFBiometricsActivity` extends `FourFBiometricsActivity` and is used to override core behaviour. This activity will be launched by the Veridium SDK during 4F operations.

`CustomFourFBiometricsActivity `uses the default storage where templates are stored locally on the device:

    @Override
    protected IKVStore openStorage() {
        return DataStorage.getDefaultStorage();
    }

Note the important entry in `AndroidManifest.xml` configuring `CustomFourFBiometricsActivity` as the 4F activity via *com.veridiumid.sdk.component.config* meta-data, and setting of portrait only mode:

    <activity
        android:name=".ui.main.CustomFourFBiometricsActivity"
        ....
    </activity>

`MainFragmentActvity` initialises the Veridium SDK in `initSDK()` and sets up the buttons for the various configurations. For example, `ExportConfig` static methods are used to set the capture configuration:

    ExportConfig.setFingersToCapture(ExportConfig.ExportMode.EIGHT_F);
    ExportConfig.optimiseForIndexLittle(false);
    ExportConfig.optimiseForIndex(false);

An intent is then created and started, e.g.:

    Intent captureIntent = mBiometricSDK.export(FourFInterface.UID);
    startActivityForResult(captureIntent, REQUEST_CAPTURE_8F);

**NOTE**: The Veridium SDK will itself ask for the appropriate permissions from the user if the enclosing app has not yet requested them.

A custom `IBiometricResultsHandler` is used to process the result by calling the `parse()` method of `BiometricResultsParser`:

    BiometricResultsParser.parse(resultCode, data, customCaptureHandler);

`handleSuccess()` is overridden and extracts the byte\[\] template data out of the `Map<String, byte[][]> results` map for the key `FourFInterface.UID`. Dimension of the byte array are as follows:

* byte\[0\]\[\] - Enrolment template data.

* byte\[1\]\[\] - Export template data in the configured format

* byte\[2\]\[\] - Development output contained in zip format

The app then writes the template data to disk with `writeTemplate()`.

`veridium-finger-selection` provides example UI for finger selection. ExportConfig are set directly within `FingerSelectionActivity` in response to the fingers chosen by the user.

    homeFragment.button_select_missing_fingers.setOnClickListener(v -> {
        Intent intent = new Intent(MainFragmentActivity.this, FingerSelectionActivity.class);
        startActivityForResult(intent, REQUEST_APP_MISSING_FINGERS);
    });

### Access Saved Templates

Templates are written to local storage within the app's data cache at `Android/data/com.veridiumid.sample.export`. This a secure area not accessible by other apps.

On macOS, we recommend installing [Android File Transfer](https://www.android.com/filetransfer/) for accessing the device's filesystem. Unlock your device, connect it via USB and, if prompted via notification, set the USB connection type as *File transfer* . Android File Transfer will open to show you the file system. Simply navigate to `Android/data/com.veridiumid.sample.export` and drag and rop template files to your Mac's filesystem. If template files fail to show, disconnect and reconnect the device to refresh the displayed file list.

On Windows, unlock your device, connect it via USB and, if prompted via notification, set the USB connection type as *File transfer* . Access the device's file system via Windows Explorer and navigate to `Android/data/com.veridiumid.sample.export`.

## Troubleshooting

### License Troubleshooting

* The provided licence is for specific features. Ensure you are running the correct app, *sample-ffid-export*.

* Ensure your licence copied correctly without introducing new lines. Your text editor should open the the licence file as UTF-8.

* Double check the *applicatonid* matches that indicated by your Veridium salesperson.

* Ensure the device has internet access.

* Uninstall the app, clean, build, and re-install.

* In Android Studio, open *Logcat* in the bottom pane. Ensure the correct device is selected and filter by *package:mine* . Copy the whole contents of *Logcat* following app start, and send it to your Veridium rep.

* Screenshot where you're entering the licence and send to your Veridium salesperson.

* **We are always happy to take a call to resolve sample app build issues.**

### Other Issues

* In Android Studio, if updating from a previous SDK version, you may need to clean the caches via *File-\>Invalidate caches...*

* If your device does not show, disconnect it, go to *developer options* and select *Revoke USB debugging authorisations* . Reconnect the device and it should prompt to *Allow USB debugging*.

* In case of the error *Error:Execution failed for task ':sample-ffid-export:mergeDebugResources* this is typically caused by the directory path to the project being too long. Reduce the length of the folder names.r

Last updated: September 21, 2026

---
version: "v3.9.1"
language: "en"
---
# Appendixes

* [SSL Certificates content and format](https://docs.veridiumid.com/docs/v3.9.1/ssl-certificates-content-and-format.md)
* [Appendixes non VID products](https://docs.veridiumid.com/docs/v3.9.1/appendixes-non-vid-products.md)
[Microsoft CA](https://docs.veridiumid.com/docs/v3.9.1/microsoft-ca.md) [Microsoft CA Certificate Templates](https://docs.veridiumid.com/docs/v3.9.1/microsoft-ca-certificate-templates.md)

Last updated: September 21, 2026

---
version: "v3.9.1"
language: "en"
---
# Appendixes non VID products

Last updated: September 21, 2026

---
version: "v3.9.1"
language: "en"
---
# Application CA Lifecycle Management from Veridium Admin

## Overview

A Certificate Authority is the trusted authority that signs the certificates devices use to prove their identity. CA certificates expire and occasionally must be replaced. If a CA expires or is replaced badly, devices can lose their ability to authenticate. This change makes replacing and renewing the CA a controlled operation instead of a delicate manual procedure and removes the ambiguities about which CA is behind a client certificate.

### What administrators can now do?

* **Back up the configuration** --- download a ZIP of the CA-related configuration before making changes, so a rotation or cleanup can be reviewed and recovered. The zip file contains *config.json* , *tenant-infra.yaml* and *trustore.json* files.

  * Always run this first, before any rotate, renew or cleanup, so you can review or restore the previous state.

![Screenshot 2026-07-16 at 13.55.48-20260716-105602.png](https://docs.veridiumid.com/__attachments/a_37a4b02f4a0e085fb972dc369891ca672d4d8cb5301ddad07584eee7f7e1b647/Screenshot%202026-07-16%20at%2013.55.48-20260716-105602.png?cb=0ee9a2a4aa06c152b9d41e02d573a591)

* **Update Internal Certificate Authority** --- introduce a new CA. The previous CA is kept trusted in the background so devices signed by it keep working during the transition.

![Screenshot 2026-07-16 at 15.00.17 copy-20260716-120121.png](https://docs.veridiumid.com/__attachments/a_92b3395911bd271d248412c54a708a4992887543d1e503b0c1bf2c19f936db98/Screenshot%202026-07-16%20at%2015.00.17%20copy-20260716-120121.png?cb=f82b8da71c9a61b64a081c65119efb14)

* **Renew the active CA in place** --- Re-issues the active CA keeping the same parameteres, only extending its validity. No transition window is needed because nothing about the CA's identity changes. It is not added to Previous CAs.

![image-20260716-120818.png](https://docs.veridiumid.com/__attachments/a_ce3b20f2a348c984f871b046708335d1582600479c1e2de214fc7963a7bc999c/image-20260716-120818.png?cb=22cc60bc7db136a02cab0db0f32cba0d)  
![Screenshot 2026-07-16 at 15.00.17 copy 2-20260716-120547.png](https://docs.veridiumid.com/__attachments/a_fb141a353888704603c7759268d35f17016fef3a7ebc169bdb4536f7285c6b0c/Screenshot%202026-07-16%20at%2015.00.17%20copy%202-20260716-120547.png?cb=10bd6d32043637b75832c893db6d91b1)

* After pressing the button a pop-up will be displayed for choosing the CA validity (years). The default value is 10 years and maximum value is 25.

![image-20260716-120818.png](https://docs.veridiumid.com/__attachments/a_ce3b20f2a348c984f871b046708335d1582600479c1e2de214fc7963a7bc999c/image-20260716-120818.png?cb=22cc60bc7db136a02cab0db0f32cba0d)

* Service Credentials --- Shows the existing Service Credentials

* **Review CAs**--- see the active CA and any previously-active CAs that are still trusted, in one overview screen

![Screenshot 2026-07-16 at 15.00.17 copy 3-20260716-121222.png](https://docs.veridiumid.com/__attachments/a_034f2556ddd9933d3fa7a53deb8df7b4b26c7e107c0368b545b74fee091c2983/Screenshot%202026-07-16%20at%2015.00.17%20copy%203-20260716-121222.png?cb=a72b9a745a28f491f95d578cf6242562)

* **Propagate the changes** to **HAProxy** nodes -- pushes the current CA trust configuration to the HAProxy nodes

![Screenshot 2026-07-16 at 15.00.17 copy-20260716-122326.png](https://docs.veridiumid.com/__attachments/a_b47cba70b9398a2cdfce432302d915fdbcd8721ad84e6a0444c13f7a1ec94bf9/Screenshot%202026-07-16%20at%2015.00.17%20copy-20260716-122326.png?cb=4b38dd7a41bf7f109c5e33674f576bd5)

* **Propagate the changes to** **Websecadmin** nodes - pushes the current CA configuration out to all WebSecAdmin nodes

![Screenshot 2026-07-16 at 15.00.17 copy 2-20260716-122348.png](https://docs.veridiumid.com/__attachments/a_99fd7670a58d0b4b8dc0af9d71ae869701a8ed34fcff5e648f08cd95ba88665a/Screenshot%202026-07-16%20at%2015.00.17%20copy%202-20260716-122348.png?cb=6f2a208fc3eb12db5a1559540a16b802)

### Previous Client Certificate Authorities

After a rotation, the screen shows the active CA alongside any previously active CAs. Previous CAs are kept for trust only, they can still validate devices they signed, but they no longer issue new certificates. Each previous CA can be removed with a cleanup action once it is no longer needed.  
![image-20260716-123024.png](https://docs.veridiumid.com/__attachments/a_faada2a1e1f8e816a62c9d6b8036c9b66e6050d24b36d582ae85c804bce8094f/image-20260716-123024.png?cb=3b0b5c9775cc669947d0b7654a0ffa9a)

### Why the old CAs need to be keept?

Devices that were issued under the old CA still present certificates signed by it. Keeping the old CA trusted during the overlap window means those devices keep authenticating while the fleet gradually moves to the new CA. Cleanup is always a deliberate, manual step, nothing is removed automatically.

### Device Issuer Thumbprint

Because a CA can now change, it becomes useful to know which CA issued each device's certificate. Every device now records the issuer thumbprint, the fingerprint of the CA certificate that signed its client certificate.

* Uses the same SHA-1 fingerprint format as the CA thumbprint displayed in the **Previous CAs** table, making it easy to identify which CA issued a device certificate.

* Populated only for newly issued or renewed certificates. Existing devices keep a `null` issuer thumbprint until their certificate is re-issued or renewed. No bulk backfill is performed.

* The `issuer_thumbprint` was added to the **device** tables in **Cassandra** (`device`, `device_by_cert_uuid`, `device_default`), in **Oracle** (`DEVICE`, `DEVICE_BY_CERT_UUID`), and to the **Elasticsearch** device index.

### Typical flow for rotating a CA

1. Backup Configuration -- download the current state first.

2. Update Internal Certificate Authority -- upload the new CA. It becomes active and the old one moves to Previous CAs and stays trusted.

3. Propagate to Websecadmin and Propagate to HAProxy -- roll the new CA set across the cluster and the edge layer.

4. Let the old + new CAs run -- existing devices keep working on the old CA and the new/re-issued devices use the new CA.

5. When no device relies on the old CA anymore, clean it up from the Previous CAs table.

### Which WEBSERVICE_\* variables change on upload, renew or remove CA

When you Upload, Renew or Remove a CA the server recomputes a set of WEBSERVICE_\* variables and stores them. Their values are then pushed to the HAProxy and WebSecAdmin nodes (via Propagate to HAProxy / Propagate to Websecadmin), so those nodes reload the CA, its trust bundle and the service keystore.  

|--------------------------------|--------------------------------------------|----------------------------------------------------------------------------------|--------------|-------------------|
| **Variable**                   | **Holds**                                  | **Upload new CA**                                                                | **Renew CA** | **Remove old CA** |
| WEBSERVICE_CA_CERT_BASE64      | Trusted-CA bundle, PEM (active + previous) | Changes                                                                          | **Changes**  | Changes           |
| WEBSERVICE_TRUSTORE_P12_BASE64 | Same bundle, PKCS12 form, certs only       | Changes                                                                          | Changes      | Changes           |
| WEBSERVICE_CA_PKCS12_BASE64    | Active CA cert + private key (PKCS12)      | Changes                                                                          | Changes      | Unchanged         |
| WEBSERVICE_KEYSTORE_P12_BASE64 | Webservice identity cert + key             | Changes                                                                          | Changes      | Unchanged         |
| WEBSERVICE_CA_CERT_KEY_BASE64  | Active CA private key - PEM                | Changes                                                                          | Unchanged    | Unchanged         |
| WEBSERVICE_CA_PASSWORD         | Password of the CA PKC12                   | Changes - only if the uploaded p12 uses a different password than the current CA | Unchanged    | Unchanged         |
| WEBSERVICE_TRUSTORE_PASSWORD   | Password protecting the trustore p12       | Unchanged unless first publish                                                   | Unchanged    | Unchanged         |
| WEBSERVICE_KEYSTORE_PASSWORD   | Password asserted for the keystore p12     | Unchanged unless first publish                                                   | Unchanged    | Unchanged         |

Last updated: September 21, 2026

---
version: "v3.9.1"
language: "en"
---
# Application logging

Webapp logs are in JSON format, so it will be easier to process them in external logging tools.

Persistance logs are in standard CSV format.  

|------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **WEBAPP:**                                                                              | **Description**                                                                                                                                               | **Log format**                                                                          | **Samples**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| /var/log/veridiumid/opa/opa.out                                                          | OPA logs                                                                                                                                                      | json                                                                                    | {"level":"error","msg":"Bundle load failed: request failed: Get \\"https://develop.dev.local/websec/rest/system/opa/export-archive\\": dial tcp 10.204.90.11:443: connect: connection refused","name":"veridium","plugin":"bundle","time":"2025-11-18T15:32:26+02:00"}                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| /var/log/veridiumid/tomcat/catalina.out                                                  | tomcat logs, where websec/shibboleth/adservice/dmz applications are deployed; this are general logs, to see that tomcat has started and applications deployed | json                                                                                    | {"@timestamp":"2025-11-18T14:44:45.619Z","log.level":"WARNING","message":"Failed to export spans. Server responded with gRPC status code 2. Error message: [opentelemetry-collector.ilpdevelop.veridium-dev.com](http://opentelemetry-collector.ilpdevelop.veridium-dev.com/): Name or service not known","ecs.version": "1.2.0","service.name":"catalina","event.dataset":"catalina","process.thread.name":"OkHttp <https://opentelemetry-collector.ilpdevelop.veridium-dev.com/...>","log.logger":"io.opentelemetry.exporter.internal.grpc.GrpcExporter"}                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| /var/log/veridiumid/tomcat/bops.log                                                      | These logs are the main application logs, containing the websec logs.                                                                                         | json                                                                                    | {"@timestamp":"2025-09-23T15:03:00.622Z","log.level": "WARN","message":"Zookeeper connection initialized, but not yet connected.", "ecs.version": "1.2.0","service.name":"bops","event.dataset":"bops","process.thread.name":"main","log.logger":"com.veridiumid.webconfig.ZookeeperConnectionFactory"}                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| /var/log/veridiumid/tomcat/ldap.log                                                      | These logs contains the interaction logs with LDAP service.                                                                                                   | sjon                                                                                    | {"@timestamp":"2025-09-23T15:03:05.360Z","log.level": "INFO","message":"Creating LDAP Connection 'default' url=ldap://127.0.0.1:389", "ecs.version": "1.2.0","service.name":"ldap","event.dataset":"ldap","process.thread.name":"pool-3-thread-1","log.logger":"com.veridiumid.ad.contract.LdapFactoryProvider"}                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| /var/log/veridiumid/fido/fido.log                                                        | The fido logs containing application logs related to fido usage.                                                                                              | json                                                                                    | {"@timestamp":"2025-11-04T08:28:53.581Z","log.level": "INFO","message":"The following 1 profile is active: \\"cassandra\\"", "ecs.version": "1.2.0","service.name":"fido","event.dataset":"fido","process.thread.name":"main","log.logger":"com.veridiumid.webauthn.Application"}                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| /var/log/veridiumid/selfservice/selfservice.log                                          | This is the self service application log.                                                                                                                     | json                                                                                    | {"@timestamp":"2025-11-17T17:27:08.690Z","log.level": "INFO","message":"HV000001: Hibernate Validator 8.0.3.Final", "ecs.version": "1.2.0","service.name":"selfservice","event.dataset":"selfservice","process.thread.name":"background-preinit","log.logger":"org.hibernate.validator.internal.util.Version"}                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| /var/log/veridiumid/websecadmin/websecadmin.log                                          | This is the websecadmin application log, where are kept the logs for user interaction with websec admin application.                                          | json                                                                                    | {"@timestamp":"2025-09-23T15:00:25.206Z","log.level": "INFO","message":"HV000001: Hibernate Validator 5.4.1.Final", "ecs.version": "1.2.0","service.name":"websecadmin","event.dataset":"websecadmin","process.thread.name":"background-preinit","log.logger":"org.hibernate.validator.internal.util.Version"}                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| /var/log/veridiumid/freeradius/freeradius.log                                            | Freeradius log contains the information about freeradius application.                                                                                         | %d{yyyy-MMM-dd HH:mm:ss a} %msg%n                                                       | Thu Oct 12 03:13:52 2023 : Debug: (1205) if (\&User-Name =\~ /\\.$/) -\> FALSE Thu Oct 12 03:13:52 2023 : Debug: (1205) if (\&User-Name =\~ /@\\./) { Thu Oct 12 03:13:52 2023 : Debug: (1205) if (\&User-Name =\~ /@\\./) -\> FALSE Thu Oct 12 03:13:52 2023 : Debug: (1205) } # if (\&User-Name) = notfound Thu Oct 12 03:13:52 2023 : Debug: (1205) } # policy filter_username = notfound Thu Oct 12 03:13:52 2023 : Debug: (1205) \[preprocess\] = ok Thu Oct 12 03:13:52 2023 : Debug: (1205) \[chap\] = noop Thu Oct 12 03:13:52 2023 : Debug: (1205) mschap: Found MS-CHAP attributes. Setting 'Auth-Type = mschap'                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| /var/log/veridiumid/shibboleth-idp/idp-warn.log                                          | This is the main log for shibboleth process.                                                                                                                  | json                                                                                    | {"@timestamp":"2025-11-18T06:51:40.666Z","log.level": "WARN","message":"Java class 'net.shibboleth.ext.spring.config.IdentifiableBeanPostProcessor': This will be removed in the next major version of this software; replacement is net.shibboleth.shared.spring.config.IdentifiableBeanPostProcessor","ecs.version": "1.2.0","service.name":"shibboleth","event.dataset":"shibboleth","process.thread.name":"http-nio-127.0.0.1-8943-exec-8","log.logger":"DEPRECATED","idp.server_hostname":"develop.dev.local","idp.server_port":"8945","idp.version":"5.1.6","clientIp":"10.201.0.10","idp.jsessionid":"0EFE1536A9914882DD5A0F811DFFF421","TraceID":"936ec2c9-e38e-4603-8486-234b8cbda48a","idp.remote_addr":"127.0.0.1"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| /var/log/veridiumid/websecadmin/deprovisioning.log                                       | This is the deprovisioning process log, where can be seen action taken by this process.                                                                       | json                                                                                    | {"@timestamp":"2025-09-24T09:48:54.790Z","log.level": "INFO","message":"Device deprovisioning configuration changed", "ecs.version": "1.2.0","service.name":"websecadmin","event.dataset":"websecadmin","process.thread.name":"main","log.logger":"com.veridiumid.deprovisioning.scheduler.ScheduledDormantDeviceNotificationService"}                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| /var/log/veridiumid/haproxy/haproxy.log                                                  | Haproxy application log contains the acces logs of all services.                                                                                              | json                                                                                    | {"service.name":"haproxy","timestamp":"23/Sep/2025:18:00:43 +0300","pid":36047,"frontend_type":"http","process_conn":6,"frontend_conn":3,"backend_conn":0,"server_conn":0,"backend_queue":0,"server_queue":0,"request_send_time":2021,"queue_wait_time":-1,"server_wait_time":-1,"server_response_send_time":"-1","response_time":"2021","request_termination_state":"SC--","server_retries":0,"remote_addr":"10.204.90.11","remote_port":29200,"frontend_addr":"10.204.90.11","frontend_port":443,"frontend_ssl_version":"TLSv1.3","frontend_ssl_ciphers":"TLS_AES_256_GCM_SHA384","request_method":"GET","request_uri":"\\/websec\\/schemas\\/shibboleth-attribute-resolver.xsd","request_http_version":"HTTP/1.1","host":"-","referer":"-","frontend_name":"frontend-bops-int","backend_name":"backend-bops-https","server_name":"\<NOSRV\>","status":"503","response_size":217,"request_size":"174","TraceID":"da22ce43-d39f-49d9-91ca-f964f8b7b4ee"}                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
|                                                                                          |                                                                                                                                                               |                                                                                         |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| **PERSISTENCE:**                                                                         |                                                                                                                                                               |                                                                                         |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| /var/log/veridiumid/cassandra/debug.log                                                  | This is the cassandra log, where can be seen the database logs.                                                                                               | %d{yyyy-MMM-dd HH:mm:ss a} \[%t\] %level %logger{36} %msg%n                             | 2023-10-27 15:10:03,621 DEBUG SSLFactory.java:384 - Initializing hot reloading SSLContext 2023-10-27 15:10:03,675 INFO JMXServerUtils.java:271 - Configured JMX server at: service:jmx:rmi://127.0.0.1/jndi/rmi://127.0.0.1:7199/jmxrmi 2023-10-27 15:10:03,682 INFO CassandraDaemon.java:625 - Hostname: ip-10-109-20-128.eu-central-1.compute.internal:7001:7001 2023-10-27 15:10:03,682 INFO CassandraDaemon.java:632 - JVM vendor/version: OpenJDK 64-Bit Server VM/1.8.0_382                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| /var/log/veridiumid/cassandra/backup.log                                                 | This log contains information about backup activities, that are running in crontab periodically.                                                              | %d{yyyy-MMM-dd HH:mm:ss a} %level %msg%n                                                | 30-Oct-2023 09:07:06 AM INFO Creating snapshot: dc1_10.109.20.128 30-Oct-2023 09:07:08 AM INFO Moving snapshot to /opt/veridiumid/backup/cassandra/2023-10-30_09-07/dc1_10.109.20.128 30-Oct-2023 09:07:10 AM DEBUG Moving the snapshot succeeded                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| *if elastic enabled, this log is not used anymore.* /var/log/veridiumid/kafka/server.log | This is the main kafka log.                                                                                                                                   | \[%d\] %p %m (%c)%n                                                                     | \[2023-06-22 09:00:11,106\] WARN Resetting first dirty offset of __consumer_offsets-38 to log start offset 73 since the checkpointed offset 62 is invalid. (kafka.log.LogCleanerManager$)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| /var/log/veridiumid/zookeeper/zookeeper.out                                              | This is the main zookeeper log.                                                                                                                               | %d{ISO8601} \[myid:%X{myid}\] - %-5p \[%t:%C{1}@%L\] - %m%n                             | 2023-10-30 08:53:08,036 \[myid:\] - INFO \[main:o.a.z.s.q.QuorumPeerConfig@444\] - secureClientPort is not set 2023-10-30 08:53:08,037 \[myid:\] - INFO \[main:o.a.z.s.q.QuorumPeerConfig@460\] - observerMasterPort is not set 2023-10-30 08:53:08,037 \[myid:\] - INFO \[main:o.a.z.s.q.QuorumPeerConfig@477\] - metricsProvider.className is org.apache.zookeeper.metrics.impl.DefaultMetricsProvider 2023-10-30 08:53:08,132 \[myid:\] - ERROR \[main:o.a.z.s.q.QuorumPeerConfig@702\] - Invalid configuration, only one server specified (ignoring)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| /var/log/veridiumid/elasticsearch/VeridiumID.log                                         | Elasticsearch log.                                                                                                                                            | \[%d{ISO8601}\]\[%-5p\]\[%-25c{1.}\] \[%node_name\]%marker %m%n                         | \[2023-10-30T09:24:47,218\]\[WARN \]\[o.e.c.c.Coordinator \] \[dc1-node-1\] This node is a fully-formed single-node cluster with cluster UUID \[VbhjRj4uS8ayHQiDjROKNg\], but it is configured as if to discover other nodes and form a multi-node cluster via the \[discovery.seed_hosts=\[10.109.20.128\]\] setting. Fully-formed clusters do not attempt to discover other nodes, and nodes with different cluster UUIDs cannot belong to the same cluster. The cluster UUID persists across restarts and can only be changed by deleting the contents of the node's data path(s). Remove the discovery configuration to suppress this message.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
|                                                                                          |                                                                                                                                                               |                                                                                         |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| **Access log:**                                                                          |                                                                                                                                                               |                                                                                         |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| /var/log/veridiumid/tomcat/shib_localhost_access_log.2023-10-27.log                      | Access log for shibboleth, including all called API, response and duration.                                                                                   | json                                                                                    | {"service.name":"shibboleth","host":"127.0.0.1","XFF":"10.201.0.10,10.204.0.110","timestamp":"2025-11-18T08:51:41.324+0200","request_uri":"/idp/profile/SAML2/POST/SSO","request_method":"POST","status":"302","request_size":"-","response_time":"1284390","server_response_send_time":"1284","TraceID":"936ec2c9-e38e-4603-8486-234b8cbda48a","ThreadID":"http-nio-127.0.0.1-8943-exec-8","Client-DN":"-"}                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| /var/log/veridiumid/tomcat/dmz_localhost_access_log.2023-10-27.log                       | Access log for dmz, including all called API, response and duration.                                                                                          | json                                                                                    | {"service.name":"dmz","host":"127.0.0.1","XFF":"86.126.146.250,10.204.0.110","timestamp":"2025-11-18T09:09:35.501+0200","request_uri":"/dmzwebsec/rest/api/GetPairingInfo","request_method":"POST","status":"200","request_size":"39360","response_time":"585275","server_response_send_time":"583","TraceID":"953ddb24-4cac-4931-b480-3ae3ff90c8d9","ThreadID":"http-nio-127.0.0.1-8543-exec-2","Client-DN":"-"}                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| /var/log/veridiumid/tomcat/localhost_access_log..2023-05-30.txt                          | Access log for websec and ADService including all called API, response and duration.                                                                          | json                                                                                    | {"service.name":"bops","host":"127.0.0.1","XFF":"10.204.90.11","timestamp":"2025-11-18T00:00:01.859+0200","request_uri":"/websec/rest/system/opa/export-archive","request_method":"GET","status":"304","request_size":"-","response_time":"6846","server_response_send_time":"6","TraceID":"9de60219-5c63-4273-b6bd-bd8fb572f6c3","ThreadID":"vid-exec-447","Client-DN":"/CN=Develop_friend_OPA_ACCOUNT_dc1/OU=VeridiumID/O=VeridiumClient/L=New York/ST=NY/C=US/emailAddress=/UID=cb553c0e-5e49-455c-97dd-6192200bc219"}                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| /var/log/veridiumid/websecadmin/access_log.2023-05-30.log                                | Access log for websecadmin including all called API, response and duration.                                                                                   | json                                                                                    | {"service.name":"websecadmin","host":"127.0.0.1","XFF":"10.204.0.110","timestamp":"2025-11-18T00:11:34.088+0200","request_uri":"/veridium-manager/","request_method":"GET","status":"302","request_size":"-","response_time":"14586","server_response_send_time":"14","TraceID":"6c58a314-9c16-43a2-b19a-405a7984d8d7","ThreadID":"https-jsse-nio-9443-exec-4","Client-DN":"/CN=lvartolomei@veridiumid.com/OU=VeridiumID/O=VeridiumClient/L=New York/ST=NY/C=US/emailAddress=/UID=d86af02b-de02-4792-9a3a-b009e71f3d5a"}                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| /var/log/veridiumid/selfservice/access_log.2023-05-30.log                                | Access log for selfservice including all called API, response and duration.                                                                                   | json                                                                                    | {"service.name":"selfservice","host":"127.0.0.1","XFF":"10.204.0.110","timestamp":"2025-11-18T08:49:48.987+0200","request_uri":"/ssp/polyfills.f6fa894b51ccdb26.js","request_method":"GET","status":"200","request_size":"35497","response_time":"73478","server_response_send_time":"72","TraceID":"af79c3ad-6979-4948-bbb3-9d2f3952bec1","ThreadID":"http-nio-127.0.0.1-9986-exec-1","Client-DN":"-"}                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| /var/log/veridiumid/fido/access_log.2023-05-30.log                                       | Access log for fido including all called API, response and duration.                                                                                          | json                                                                                    | {"service.name":"fido","host":"127.0.0.1","XFF":"-","timestamp":"2025-11-18T00:04:33.928+0200","request_uri":"/assertion/options","request_method":"POST","status":"200","request_size":"304","response_time":"33317","server_response_send_time":"30","TraceID":"-","ThreadID":"http-nio-127.0.0.1-11442-exec-4","Client-DN":"-"}                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
|                                                                                          |                                                                                                                                                               |                                                                                         |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| **Audit logs:**                                                                          |                                                                                                                                                               |                                                                                         |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| /opt/veridiumid/websecadmin/logs/events.log                                              | Events logs for accessing websecadmin                                                                                                                         | %d{yyyy-MMM-dd HH:mm:ss a} \[%t\] %level %logger{36} %msg%n Also can be in json format. | 2023-Oct-27 16:40:14 PM \[https-jsse-nio-9443-exec-5\] INFO com.veridiumid.identity.events.SystemEvents ActionLog(id=20316691-e8b5-46dc-9e46-4e58bcc38c31, actionName=Login, [accountExternalId=admin@veridiumid.com](mailto:accountExternalId=admin@veridiumid.com), accountEmail=null, accountId=47EAEF85-9D37-4366-AF8F-2F4777A6AD4E, deviceId=E27B2D93-291C-47F3-BF35-EA6DA590120A, ip=10.109.20.128, requestUri=/websecadmin/rest/opa/generate-certificate, requestMethod=GET, requestQueryParams=null, requestPath=null, requestBody=null, response=null, actionDate=Fri Oct 27 16:40:14 UTC 2023, location=Local Network)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| /opt/veridiumid/tomcat/logs/events.log                                                   | Events logs for user authentications                                                                                                                          | %d{yyyy-MMM-dd HH:mm:ss a} \[%t\] %level %logger{36} %msg%n Also can be in json format. | 2023-Oct-27 18:35:04 PM \[vid-exec-133\] INFO com.veridiumid.identity.events.SystemEvents EventLog(_caller=(accountId=9ae4ce0d-e3a1-447f-936e-dbdc03f26d10, accountExternalId=ADv2MultiStepEnrollment, accountEmailAddressInfo=null, accountStatus=NONE, deviceId=ssp, deviceOs=, deviceType=FRIEND, deviceName=ssp, deviceManufacturer=null, deviceDescription=Self Service Portal, deviceStatus=ACTIVATED), ipAddress='10.109.20.128', location='Local Network', requestURI='/websec/rest/enterprise/portal/InitiateEnrollment', requestMethod='POST', requestPath='/enterprise/portal/InitiateEnrollment', actionName='initiateEnrollment', actionDate=Fri Oct 27 18:35:04 UTC 2023, request=null, response=(currentStatus='null', profileId='null', enrollmentTrackerId='null')) 2023-Oct-27 18:35:09 PM \[vid-exec-134\] INFO com.veridiumid.identity.events.SystemEvents EventLog(_caller=(accountId=9ae4ce0d-e3a1-447f-936e-dbdc03f26d10, accountExternalId=ADv2MultiStepEnrollment, accountEmailAddressInfo=null, accountStatus=NONE, deviceId=ssp, deviceOs=, deviceType=FRIEND, deviceName=ssp, deviceManufacturer=null, deviceDescription=Self Service Portal, deviceStatus=ACTIVATED), ipAddress='10.109.20.128', location='Local Network', requestURI='/websec/rest/enterprise/portal/Enroll', requestMethod='POST', requestPath='/enterprise/portal/Enroll', actionName='enrollAccount', actionDate=Fri Oct 27 18:35:09 UTC 2023, request=(deviceId='null', profileId='null', enrollmentTrackerId='null', purpose=ENROLL), response=(currentStatus='ACTIVE', profileId='680395e0-b2cf-4f89-89eb-48e7d5d9cf82', enrollmentTrackerId='b4103206-e294-4266-9897-d9e0ea821862')) |

Here are some examples of what information can be found in events.log and what is the log format.

[Users_SIEM_3.8.1.xlsx](https://docs.veridiumid.com/__attachments/a_b4d2be8b0453aef73d42b40187530afecb077ebd421387690999b0da9be14d16/Users_SIEM_3.8.1.xlsx.md?cb=badbaa2b30238e31dfb142394bf06330)

Last updated: September 21, 2026

---
version: "v3.9.1"
language: "en"
---
# Application Types

Last updated: September 21, 2026

---
version: "v3.9.1"
language: "en"
---
# Applications

[Key concepts](https://docs.veridiumid.com/docs/v3.9.1/key-concepts.md) [Create/Edit/Delete application](https://docs.veridiumid.com/docs/v3.9.1/create-edit-delete-application.md)
* [Manage application groups](https://docs.veridiumid.com/docs/v3.9.1/manage-application-groups.md)

Last updated: September 21, 2026

---
version: "v3.9.1"
language: "en"
---
# Architecture

## Veridium Mobile SDK

The Mobile SDK is a set of libraries for Android and iOS that help to easily add biometric authentication capabilities to custom apps. The SDK exposes a high level API that intuitively describe the actions for managing identities, biometries and authentication workflows.

## Prequisites

In order to function properly, the following requirements are needed:

### iOS

* operating system: 10.0 and above

* programming language: Swift or Objective-C

* hardware sensors: depending on the capabilities of the phone the SDK will use local biometries like TouchID or FaceID. For the VeridiumID proprietary 4F biometry back camera permission is required.

### Android

* operating system: 5.0 (API 21) and above

* programming language: Java 8 or Kotlin

* hardware sensors: depending on the capabilities of the phone the SDK will use local biometries like Fingerprint. For the VeridiumID proprietary 4F biometry back camera permission is required.

## General Internal Structure

The internal structure of the SDK is for informative purposes detailed below as it is opaque to container application.

*Figure #1: MobileSDK internal structure*  
![https://productdocs.veridiumid.com/assets/images/image1-0e1a8268e1ae26b7dad0fd54b0a7dad1.png](https://productdocs.veridiumid.com/assets/images/image1-0e1a8268e1ae26b7dad0fd54b0a7dad1.png)

On both platforms the hardware capabilities are exploited if available. For instance all sensitive information (encryption keys, biometric information, user information) is stored in the hardware protected secure space; local biometry sensors are presented as authenticators when enrolling new accounts.

Authenticators are modules that can assert if the presented biometry during an authentication session is matching the enrolled one. During an authentication the list of authenticators that will challenge the user can be statically or dynamically composed by a negotiation with the VeridiumID Server. The authentication result is the list of authenticators, their result and signatures for each one that guaranty the authenticity of the result.

Any client that wants to communicate with the VeridiumID server needs to implement the Biometric Open Protocol Standard (BOPS). Request and response serialization, network security, error reporting is handled by the VeridiumID Server Communication module.

## Integrating MobileSDK into an existing application

For details integrating the FourF TouchlessID export format functionality and configuring export format settings, see [Biometric exports with Mobile SDK](file://wiki/spaces/IV/pages/811434083/Biometric+exports+with+Mobile+SDK).

### iOS

Before starting please check the [Prerequisites](file://wiki/pages/resumedraft.action%3fdraftId=793706497#VeridiumMobileSDK-prereq) section.

To export the logs from the SDK you need to:

1. Enable debug mode. After this option is enabled, the logs will be captured: `VIDMobileSDK.shared().getConfiguration().isDebugEnabled = true`

2. Call `VIDMobileSDK.shared().exportLogs()`

Add all the .xcframework dependencies by following these steps below. The Frameworks contain all necessary code that enable the workflows described in the next sections.

1. Contact the Veridium Sales team to get the SDK archive.

2. Extract the archive and locate the veridium-sdk folder.

3. Open your XCode project and navigate to the project navigator on the left-hand side.

4. Select your project at the top of the project navigator to open the project settings.

5. Select the target you want to add the VeridiumID framework to.

6. Select the "General" tab in the project editor.

7. Scroll down to the "Frameworks, Libraries, and Embedded Content" section.

8. Click the "+" button to add a new framework.

9. In the "Add" dialog that appears, select "Add Other...".

10. Navigate to the veridium-sdk folder that you extracted earlier and select the .xcframework file(s) you want to add.

* Veridium4FBiometrics and Veridium4FUI dependencies are optional. They can be excluded if the 4F biometric library is not desired to be used.

* VeridiumVFaceBiometrics and VeridiumDefaultVFaceUI dependencies are optional. They can be excluded if the VFace biometric library is not desired to be used.

11. Click "Open" to add the frameworks to your project.

12. In the "Embed" column next to each framework you just added, select "Embed \& Sign" from the dropdown menu.

13. Go to your app's settings and set 'Enable Bitcode' to No

14. If you did not tick the "Copy" checkbox when adding the frameworks, be sure to go to Project settings → Build Settings → Framework Search Path and add the directory to the framework files you just included.

![https://productdocs.veridiumid.com/assets/images/image2-63e8892a2f031581427ee44107cef3c2.png](https://productdocs.veridiumid.com/assets/images/image2-63e8892a2f031581427ee44107cef3c2.png)

To ensure that the VeridiumID SDK functions properly within your container app, you need to add these required permissions in your .plist file: *NSLocationWhenInUseUsageDescription* , *NSCameraUsageDescription* , *NSFaceIDUsageDescription*. If you cannot locate your .plist file, navigate to: Project -\> Targets -\> Info -\> Custom iOS Target Properties and add the permissions there.

The container app will only use the VIDMobileSDK singleton to access the code from the VeridiumOrchestrator framework. The other frameworks are subcomponents accessed and used internally. So add `import VeridiumOrchestrator` in the header of your `AppDelegate.swift` file and compile. You should get a successful compilation message.

The Mobile SDK needs registration and configuration for the biometric libraries (if used). The `VIDConfiguration` object has the `sdkConfigurationBlock` parameter used for providing the biometric library configurations as a closure. Import the biometric libraries you want to use and add the closure implementation with biometric library configurations. You can find how 4F and VFace biometric libraries are registered and configured in the code below:

**Init SDK with license and biometric library configurations**
> Note: This method is only for SDK implementations integrated with a VeridiumID server. For Biometrics only, export SDKs, please check [VFace iOS Integration](https://productdocs.veridiumid.com/docs/veridiumid-sdks/vface-id/ios/vface-ios-integration) or [4F iOS Integration](https://productdocs.veridiumid.com/docs/veridiumid-sdks/4finger-id/ios/4f-ios-integration)

    ...
    // Required
    import VeridiumOrchestrator
     
    // Optional imports for 4F biometric library
    import Veridium4FBiometrics
    import Veridium4FUI
     
    // Optional imports for VFace biometric library
    import VeridiumVFaceBiometrics
    import VeridiumDefaultVFaceUI
    ...
     
    @UIApplicationMain
    class AppDelegate: UIResponder, UIApplicationDelegate {
     
        // ...
     
        func application(_ application: UIApplication,
                didFinishLaunchingWithOptions launchOptions:
                    [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
             
            // ...
            
            let configBuilder = VIDConfigurationBuilder()
                .withSDKConfigurationBlock({ veridiumSDK in
                    // register biometric license loader for the 4F biometric library
                    veridiumSDK.registerLicenseLoader(VeridiumBiometricsFourFLicenseLoader())
                    
                    // register biometric license loader for the VFace biometric library
                    veridiumSDK.registerLicenseLoader(VeridiumBiometricsVFaceLicenseLoader())
                    
                    // register authenticator and enroller for the VFace biometric library
                    veridiumSDK.registerDefaultVFaceEnroller()
                    veridiumSDK.registerDefaultVFaceAuthenticator();
                    
                    // configurations for the 4F authenticator
                    let authenticatorConfig = VeridiumFourFCaptureConfig.init(forAuthWithHand: .eitherHandEnroll, andLiveness: false)
                    authenticatorConfig.do_debug = false
                    authenticatorConfig.configureTimeoutEnabled(true, andTimoutSeconds: 30, andAllowedRetries: .infinite, andAllowSkipping: false)
                    
                    // register authenticator for the 4F biometric library
                    veridiumSDK.register4FUIAuthenticator()
                    veridiumSDK.configureFourFAuthenticator(authenticatorConfig)
                    
                    // configurations for the 4F enroller
                    let enrollerConfig = VeridiumFourFCaptureConfig.init(forEnrollWithHand: .eitherHandEnroll, andLiveness: true)
                    enrollerConfig.do_debug = false
                    enrollerConfig.configureTimeoutEnabled(true, andTimoutSeconds: 30, andAllowedRetries: .infinite, andAllowSkipping: false)
                    enrollerConfig.showHandSelectorOnEnrolment = true
                    
                    // register enroller for the 4F biometric library
                    veridiumSDK.register4FUIEnroller()
                    veridiumSDK.configureFourFEnroler(enrollerConfig)
                })
            
            let initError = VIDMobileSDK.shared().initialize(configBuilder.build())
            
            if let error = initError {
                // handle initialization error
            }
            
            // ...
        }
    }

***Colour Theme customization***

To customize the colour palette of the SDK owned UI you can add this in the ***config*** object above:

    let appearanceBuilder = VIDAppearanceBuilder()
        .withPrimaryColor(UIColor.primaryColor)
        .withSecondaryColor(UIColor.secondaryColor)
        ...
            
    configBuilder
        .withAppearance(appearanceBuilder.build())
        ...

The assigned UIColor object may contain Light, Dark, Normal Contrast and High Contrast settings that will be used accordingly inside the SDK.

The complete list of colour attributes that can be configured is

* *primaryColor* : used for buttons, UI separators

* *secondaryColor* : not used; reserverd for future implementations

* *textPrimaryColor* : text main colour for content

* *textSecondaryColor* : text colour for alternate text and strong titles

* *textLightColor* : input fields watermark

* *backgroundColor* : main background colour

* *backgroundSecondaryColor* : secondary background colour

* *backgroundTernaryColor* : ternary background color

* *accentColor* : used for distructive buttons

> Note: This mechanism does not cover 4F and VFace modules. Their UI can be cusomized directly through the framework code included in the SDK.

**Enabling Push Notifications**

Push Notifications (APNS) handling is the responsibility of the container app. There are two operation modes: through APNS servers or with local polling. The container app must opt for one of them, otherwise normal operation is impossible.

#### Option #1

In the AppDelegate.swift file register for push notifications and once a push intended for the SDK arrives, the container app needs to forward it to the SDK. A sample on how to achieve this can be found below:

    @UIApplicationMain
    class AppDelegate: UIResponder, UIApplicationDelegate {
     
        var pushToken: Data?
     
        func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
            pushToken = deviceToken
             
            VIDMobileSDK.shared().setRemoteNotificationsToken(pushTokenData: deviceToken)
            print("registered for push notifications")
        }
         
        func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
            VIDMobileSDK.shared().setRemoteNotificationsToken(pushTokenData: nil)
            print("failed to registered for push notifications")
        }
         
        func application(_ application: UIApplication,  didReceiveRemoteNotification notification: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
            print("Did receive push: \(String(describing: notification["actionName"]))")
            VIDMobileSDK.shared().handlePush(notification)
        }
     
        
    }

#### Option #2

MobileSDK has alternative push notification mechanisms that can be enabled if APNS is not available / user opted out from receiving pushes. To enable this the container app needs to call `VIDMobileSDK.shared().setRemoteNotificationsToken(pushTokenData: nil)`. You can add this to `application(\_:didFinishLaunchingWithOptions:)` if you don't want to enable Apple pushes or you can have more complex decisions based on application settings and user preferences.

### Android

Before starting please check the [Prerequisites](file://wiki/pages/resumedraft.action%3fdraftId=793706497#VeridiumMobileSDK-prereq) section.

Include all the Veridium SDK dependencies in your project's library folder (e.g. *libs*)

**Include Veridium SDK in build.gradle**

    android {
        // Java compatibility is set to Java 1.8
        compileOptions {
            sourceCompatibility JavaVersion.VERSION_1_8
            targetCompatibility JavaVersion.VERSION_1_8
        }
    }
     
    repositories {
        // We include libs directory into repositories to make VeridiumSDK available for importing
        flatDir { dirs 'libs' }
        google()
        jcenter()
    }
     
    ...
     
    dependencies {
        ...
        // Veridium SDK Modules
        // ==================================
        implementation(name: 'veridium-sdk-release', ext: 'aar')
        implementation(name: 'veridium-core-release', ext: 'aar')
        implementation(name: 'veridium-support-release', ext: 'aar')
        implementation(name: 'veridium-secure-data-release', ext: 'aar')
        implementation(name: 'veridium-biometric-release', ext: 'aar')
        implementation(name: 'veridium-pin-release', ext: 'aar')
        implementation(name: 'veridium-piv-release', ext: 'aar')
        implementation(name: 'veridium-fourf-release', ext: 'aar')
        implementation(name: 'veridium-fourf-ui-release', ext: 'aar')
        implementation(name: 'veridium-analytics-release', ext: 'aar')
        // ==================================
     
        // Veridiumid SDK Modules
        // ==================================
        implementation(name: 'veridiumid-client-release', ext: 'aar')
        implementation(name: 'veridiumid-http-release', ext: 'aar')
        implementation(name: 'veridiumid-sdk-release', ext: 'aar')
        implementation(name: 'veridiumid-uba-release', ext: 'aar')
        implementation(name: 'veridiumid-otp-release', ext: 'aar')
        implementation(name: 'veridiumid-vc-release', ext: 'aar')
        implementation(name: 'veridiumid-dynamic-ui-release', ext: 'aar')
        implementation(name: 'veridiumid-mobile-sdk-release', ext: 'aar')
        implementation(name: 'veridiumid-fido-authenticator-release', ext: 'aar')
        // ==================================
     
     
        // Optional VFace Biometrics Dependencies
        // ==================================
        implementation(name: 'veridium-vface-release', ext: 'aar')
        implementation(name: 'veridium-vface-ui-release', ext: 'aar')
        implementation(name: 'veridium-vface-camera-release', ext: 'aar')
        implementation(name: 'veridiumid-vface-ui-release', ext: 'aar')    
        // ==================================
     
        // External Veridium SDK dependencies
        // ==================================
        implementation "androidx.appcompat:appcompat:1.5.1"
        implementation "com.google.android.material:material:1.7.0"
        implementation "androidx.constraintlayout:constraintlayout:2.1.4"
        implementation "androidx.annotation:annotation:1.1.0"
        implementation ("com.journeyapps:zxing-android-embedded:4.3.0"){
            transitive = false
        }
        implementation "com.google.zxing:core:3.3.0"
        implementation "com.google.android.gms:play-services-safetynet:18.0.1"
        implementation "com.google.android.gms:play-services-analytics:18.0.2"
        implementation "com.google.android.gms:play-services-location:20.0.0"
        implementation "com.google.android.play:core:1.10.3"
        implementation "com.google.android.play:integrity:1.1.0"
        implementation "com.google.code.gson:gson:2.9.1"
        // We only use this for deserialize JWS from SafetyNet attestation response
        implementation("com.google.http-client:google-http-client-gson:1.23.0") {
            // We use the default client based on OkHttp
            exclude group: 'org.apache.httpcomponents'
            // We already import gson, and the internal dependency is an older version 2.1 of gson
            exclude group: 'com.google.code.gson'
        }
        implementation 'com.squareup.okhttp3:okhttp:4.10.0'
        implementation 'com.squareup.okhttp3:logging-interceptor:4.10.0'
        implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.20'
        implementation 'de.hdodenhof:circleimageview:3.1.0'
        // ==================================
        ...
    }

If you are building for release, with **minifyEnabled** option set to **true**, make sure you configured your proguard file with:

[**proguard-rules.pro**](http://proguard-rules.pro/)

    ## Core Veridium SDK Modules
    -keep class com.veridiumid.sdk.** { *; }
    ## Orchestrator Veridium SDK module
    -keep class com.veridiumid.mobilesdk.** { *; }
     
    ## Samsung Pass SDK
    -keep class com.samsung.** { *; }
    -dontwarn com.samsung.**

The container app will only use the *VeridiumMobileSDK* singleton from *veridiumid-mobile-sdk-release.aar* to access the functionalities of the SDK. The other libraries are subcomponents accessed and used internally.

The Veridium Mobile SDK needs licenses to operate. Add the license provided by VeridiumID in your *AndroidManifest.xml*.

**Setup VeridiumId License in AndroidManifest.xml**

    <manifest xmlns:android="http://schemas.android.com/apk/res/android">
        
       <application>
           ...
     
           // Setup SDK license
           <meta-data
                   android:name="com.veridiumid.sdk.LICENSE"
                   android:value="<your_veridium_id_sdk_license>"/>
     
           // Optional activity handler for VFace biometrics opperations
           <activity
               android:name="com.veridiumid.sdk.vface.ui.VFaceMobileBiometricsActivity"
               android:label="VFACE"
               android:screenOrientation="portrait">
               <meta-data
                   android:name="com.veridiumid.sdk.component.config"
                   android:value="uid=VFACE, optional=false, validator=com.veridiumid.sdk.vface.VFaceValidator" />
           </activity>

           <activity
                android:name="com.veridiumid.mobilesdk.view.ui.screen.impl.MobileFourFBiometricsActivity"
                android:label="4 Fingers"
                android:screenOrientation="portrait"
                android:theme="@style/VeridiumId.Theme"
                android:windowSoftInputMode="stateHidden">
                <meta-data
                    android:name="com.veridiumid.sdk.component.config"
                    android:value="uid=4F, optional=false, validator=com.veridiumid.sdk.fourf.FourFValidator" />
            </activity>

            <activity
                android:name="com.veridiumid.sdk.authenticator.biometric.BiometricActivity"
                android:label="Fingerprint Scanner"
                android:theme="@style/VeridiumId.Theme.Transparent">
                <meta-data
                    android:name="com.veridiumid.sdk.component.config"
                    android:value="uid=TOUCHID, optional=true,validator=com.veridiumid.sdk.authenticator.biometric.BiometricModuleValidator" />
            </activity>
            <activity
                android:name="com.veridiumid.sdk.authenticator.pin.PinAuthenticatorActivity"
                android:label="PIN"
                android:screenOrientation="portrait"
                android:theme="@style/VeridiumId.Theme">
                <meta-data
                    android:name="com.veridiumid.sdk.component.config"
                    android:value="uid=PIN" />
            </activity>
            <activity

                android:name="com.veridiumid.sdk.authenticator.certificate.CertificateAuthenticatorActivity"
                android:label="Certificate Authenticator"
                android:theme="@style/VeridiumId.Theme.Transparent"
                android:windowSoftInputMode="stateVisible|adjustResize">
                <meta-data
                    android:name="com.veridiumid.sdk.component.config"
                    android:value="uid=CERTIFICATE, optional=true, validator=com.veridiumid.sdk.authenticator.certificate.CertificateAuthenticatorModuleValidator" />

            </activity>
            
           ...
       </application>
    </manifest>

Initialize the *VeridiumMobileSDK* when Application is created:

**Initialize VeridiumSDK**

    public class App extends Application {
        ...
     
        @Override
        public void onCreate() {
            super.onCreate();
            VeridiumConfiguration config = new VeridiumConfiguration.Builder(this)
                .with(new VeridiumSDKVFaceInitializer()) // Only if VFace dependencies are used
                .with(new CertificateAuthenticatorModuleInitializer())
                .with(new BiometricAuthenticatorModuleInitializer())
                .build();
            
            BiometricAuthenticatorModuleInitializer.initialize(this);
            VeridiumMobileSDK.init(this, config);
        }
         
        ...
    }

Push Notifications handling is the responsibility of the container app. In order to provide push notifications using internal polling system the SDK will notify via *NotificationsListener* and the container app needs to forward it to the SDK.

Some notifications requires user action (e.g. authentication) in order to get consumed. A sample on how to achieve this can be found below:

**UI customization**

You can define custom colors inside your own `colors.xml` file:

* `veridiumid_color_primary`: background color of the Toolbar

* `veridiumid_color_primary_dark`: color of the status bar

* `veridiumid_color_surface`: the color for windows background (activity and dialogs)

* `veridiumid_color_on_primary`: the color for texts displayed on - `veridiumid_color_primary` background

* `veridiumid_color_accent`: to color for controls (checkbox, switches, progress) in activated state

* `veridiumid_color_button`: the color of button background

* `veridiumid_color_text_button`: the color of button text

* `veridiumid_text_color_primary`: the color used for most of the texts

* `veridiumid_text_color_secondary`: the color used for secondary, disabled texts and not active controls

* `veridiumid_text_color_hint`: the color used for input text placeholder when the input is empty

* `veridiumid_color_divider`: the color for list dividers

* `veridiumid_color_warning`: the color used to illustrate warnings (input text error etc.)

* `veridiumid_color_map_overlay`: the color used to draw a transparent circle on context map

**Push notifications SDK forwarding**

    public class NotificationHandler implements NotificationsListener {
        private Queue<VeridiumIdPendingIntent> mPendingIntents;
     
        @Override
        public void onNotificationsReceived(List<VeridiumIdNotification> notifications) {
            for (VeridiumIdNotification notification : notifications) {
                VeridiumIdPendingIntent pendingIntent = VeridiumMobileSDK.getInstance().processNotification(notification);
                if (pendingIntent != null)
                    mPendingIntents.offer(pendingIntent);
            }
        }
     
        public VeridiumIdPendingIntent getPendingNotification() {
            return mPendingIntents.poll();
        }  
    }
     
     
    // Registering
    NotificationHandler notificationHandler = new NotificationHandler();
    VeridiumMobileSDK.getInstance().setNotificationListener(notificationHandler);
     
    // Consume notifications that requires user action (e.g. authentication)
    VeridiumIdPendingIntent pendingNotification = notificationHandler.getPendingNotification();
    if (pendingNotification != null && pendingNotification.hasPendingIntent()) {
        try {
            pendingNotification.launchPendingIntent(this, REQUEST_CODE_NOTIFICATION_HANDLE);
        } catch (IntentSender.SendIntentException e) {
            e.printStackTrace();
        }
    }

As alternative, a 3rd party push notifications service can be included. In the example blow we illustrate how to forward Push Notifications to SDK using Firebase.

This has a prerequisite to create a Firebase project and [setup in the Android application](https://firebase.google.com/docs/android/setup). The firebase token needs to be passed to the VeridiumMobile SDK after every intialization, otherwise the default implementation will use internal push notification mechanism described above.

**Push notifications SDK forwarding using Firebase**

    public class App extends Application {
         
        private static App sInstance;
        private SharedPreferences mSharedPreferences;
        private NotificationHandler mNotificationHandler;
        ...
         
        @Override
        public void onCreate() {
            super.onCreate();
            sInstance = this;
            mSharedPreferences = ... // Init Shared Preferences
             
            // We initialize Firebase App
            FirebaseApp.initializeApp(this);
                    VeridiumMobileSDK.init(this, configuration);
             
            // We get the pushRegistrationToken from persistence layer and pass it to the SDK
            String pushRegistrationToken = mSharedPreferences.getString("firebase_token");
            if(pushRegistrationToken != null)
                VeridiumMobileSDK.getInstance().setPushRegistrationId(pushRegistrationToken);
     
        }
         
        public static App getInstance() {
            return sInstance;
        }
        ...
    }

**Push notifications SDK forwarding using Firebase**

    public class FCMListeningService extends FirebaseMessagingService {
        private SharedPreferences mSharedPreferences
        private NotificationHandler mNotificationHanlder;
     
        public void FCMListeningService() {
        }
     
        @Override
        public void onCreate() {
            super.onCreate();
            mAppPreferences = App.getInstance().getPreferences();
             
        }
     
        @Override
        public void onNewToken(String token) {
            VeridiumMobileSDK.getInstance().setPushRegistrationId(token);
            mSharedPreferences.edit().putString("firebase_token", token).apply();
        }
     
        @Override
        public void onMessageReceived(RemoteMessage message) {
            App.getInstance().getNotificationHandler().onNotificationReceived(message);
        }
    }
     
    public class NotificationHanlder {
        private final Queue<VeridiumIdPendingIntent> mPendingIntents;
     
     
      public void onNotificationReceived(RemoteMessage remoteMessage) {
            processNotificationPendingIntent(VeridiumMobileSDK.getInstance().processNotification(remoteMessage.getData()));
      }
     
      private void processNotificationPendingIntent(VeridiumIdPendingIntent pendingIntent) {
            if (!pendingIntent.hasPendingIntent())
                return;
             
            mPendingIntents.offer(pendingIntent);
        }
    }
     
    // Consume notifications that requires user action (e.g. authentication)
    VeridiumIdPendingIntent pendingNotification = notificationHandler.getPendingNotification();
    if (pendingNotification != null && pendingNotification.hasPendingIntent()) {
        try {
            pendingNotification.launchPendingIntent(this, REQUEST_CODE_NOTIFICATION_HANDLE);
        } catch (IntentSender.SendIntentException e) {
            e.printStackTrace();
        }
    }

Note: Both push notification methods can be enabled and the Veridium SDK will multiplex between them at initialization time based on *VeridiumMobileSDK.getInstance().setPushRegistrationId(token)* was called with a non-null *token.*

## Unlock Server communication (deprecated with version 4.0.0)

After app start but before any server communication the client certificate used for device authentication needs to be unlocked. Starting with version 4.0.0 of the SDK this is done implicitly by the SDK before the first VeridiumID server call is made after an app restart. The unlock delegate was removed as well.

Still, to know in what state the SDK is you can call

**iOS unlock**

    class SplashViewController: UIViewController {
         
        ...
     
        func initializeApp() {    
            // removed in 4.0.0
            // VIDMobileSDK.shared().unlockDelegate = self
     
            let state = VIDMobileSDK.shared().getState()
     
            switch state {
                case .serverPairing:
                    // account not enrolled yet
                    break
                case .accountRegisteredAndBiometricsSet:
                    // removed in 4.0.0
                    //self.unlockCompletion = {
                        // SDK unlocked successfully 
                    }
                    //VIDMobileSDK.shared().unlockDelegate = self
                    //VIDMobileSDK.shared().unlock()
                    break
                case .initializeFailure:
                    // SDK initialization failed
                    break
            }
        }
    }
     
    // removed in 4.0.0
    //MARK: handlers for VIDUnlockDelegate
    extension SplashViewController: VIDUnlockDelegate {
        func didStartUnlock() {
             
        }
         
        func didFinishUnlock() {
            VIDMobileSDK.shared().unlockDelegate = nil
            self.unlockCompletion?()
        }
         
        func didFailUnlock(error: VIDError) {
        }
    }

**Android unlock**

class SplashViewController: UIViewController {

    // removed in 4.0.0
    public class UnlockHandler implements IInitDelegate {
         
        void unlock(){
            VeridiumDelegateManager.getInstance().setInitDelegate(this);
            VeridiumMobileSDK.getInstance().unlock();
        }
         
        @Override
        public void onInitResponse(InitResponse initResponse) {
            Log.d(TAG, "Received init response: deviceStatus" + initResponse.getDeviceStatus(), initResponse.getError());
            if (initResponse.getError() != null) {
                // We handle errors inside
            } else if (initResponse.getDeviceStatus() == DeviceStatus.ACTIVATED) {
                // Unlock finished successfully
            } else {
                // We handle different cases based on device state
            }
        });
    }
     
    // Added in 4.0.0
    VeridiumMobileSDK.getInstance().connect(new Callback<List<VeridiumIdAccount>>() {
        @Override
        public void onSuccess(List<VeridiumIdAccount> accounts) {
            if (accounts.isEmpty()) {
                // There are no accounts paired.
            } else {
                // The sdk connected with success and has enrolled profiles.
            }
        }
     
        @Override
        public void onFailure(Throwable throwable) {
            // We handle connect errors here. Only blocking errors will be received here (e.g. invalid/expired license retrieved from server) 
        }
    });

## Calling the MobileSDK and receiving responses

MobileSDK methods can be synchronous or asynchronous. The type is specified for each method in the code documentation.

**iOS Asynchronous method handling**

When calling asynchronous methods responses are sent back through delegates. In order to receive responses, implement the delegate interface in the container app and handle responses accordingly.

E.g. since *authentication* is an asynchronous method, in order to know when the execution finished and with what result the container app needs to implement VIDAuthenticationDelegate and subscribe itself as handler in the SDK

In order to subscribe to the delegate handler use:

VIDMobileSDK.shared().authenticationDelegate = self

**Android Asynchronous method handling**

On Android there are 2 different types of asynchronous methods:

1. Async methods that requires user action (e.g. enrollment, authentication). These methods can be identified when the retrun type is VeridiumIdPendingIntent. This allows the container application to perform the action on sdk at any desired time by calling VeridiumIdPendingIntent#launchPendingIntent(Activity actiivity, int requestCode). The result is received in onActivityResult(int requestCode, int resultCode, \\@Nullable Intent\* data). The data contains the result under data.getParcelableExtra(VeridiumMobileSDK.VERIDIUMID_KEY_ERROR_EXTRA) if the action completed with error or data.getParcelableExtra(VeridiumMobileSDK.VERIDIUMID_KEY_RESPONSE_EXTRA) if result completed with success.

2. Async methods that do not requires user action (e.g. getProfiles) are using Callback interface to send back successful or failed results back.

In the following sections there are code snippets for mobile platforms to integrate into the Veridium workflows.

The sections describe a complete integration with server and mobile coding. If your integration uses a standard VeridiumID server with a standard Integration Adaptor, you can ignore the server-side code snippets, but be sure you understand the diagrams and the interaction between all actors.

Last updated: September 21, 2026

---
version: "v3.9.1"
language: "en"
---
# Assigning selectors to application group

After creating a journey selector, an administrator can assign it to an application group. If there are no application groups defined, create one following these steps:

1. In Veridium Manager, click Applications.

   ![image-20230331-205808.png](https://docs.veridiumid.com/__attachments/a_e32e6a5d81b89090c5fef21ec8c73537046e73120fa88473c0af58d2b226fc01/image-20230331-205808.png?cb=2e3c82a146f50f3b12264c909b6ab408)

2. Select Group where you would like to assign the selector (or create new application group if necessary) and press Edit Group button.

   ![image-20230331-205822.png](https://docs.veridiumid.com/__attachments/a_329664851716f3d505a6aad7c4621bd08b44f7ed2203fd5804e17844af508d53/image-20230331-205822.png?cb=0611634228e1b0d193a68ba0f5ea0f3d)

3. Choose an existing Journey Selector that will be assigned to this new group.

   ![image-20230331-205836.png](https://docs.veridiumid.com/__attachments/a_f795f9b5f00d09b4da65265ac2f8548235ae6ea8e1af392c60d8aef918812eb1/image-20230331-205836.png?cb=b657159bb14a6c51cc8fda12824d8dbd)

4. Click OK to save the new Application Group.

This will link existing applications to a selector that will further determine which journey to run based on the contextual information present when user initiate an authentication session.

Last updated: September 21, 2026

---
version: "v3.9.1"
language: "en"
---
# Attribute name mapping

|         Name         |                    Basic Description                    |   Default Value    |                                                                    Advanced Description                                                                     |
|----------------------|---------------------------------------------------------|--------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------|
| ID                   | unique user entry ID                                    | objectSid          | Described default values shows typical mapping in Active Directory. for other LDAPs values will differ. All attributes here are mandatory (must be mapped). |
| Mobile               | mobile phone number (used for SMS)                      | telephoneNumber    | Described default values shows typical mapping in Active Directory. for other LDAPs values will differ. All attributes here are mandatory (must be mapped). |
| Groups               | list of group user is member of                         | memberOf           | Described default values shows typical mapping in Active Directory. for other LDAPs values will differ. All attributes here are mandatory (must be mapped). |
| User Account Control | to distinguish enabled/disabled account                 | userAccountControl | Described default values shows typical mapping in Active Directory. for other LDAPs values will differ. All attributes here are mandatory (must be mapped). |
| Email                | user's email address                                    | mail               | Described default values shows typical mapping in Active Directory. for other LDAPs values will differ. All attributes here are mandatory (must be mapped). |
| Username             | account name                                            | userPrincipalName  | Described default values shows typical mapping in Active Directory. for other LDAPs values will differ. All attributes here are mandatory (must be mapped). |
| Line Manager         | link to user's manager - may be used for authorization. | manager            | Described default values shows typical mapping in Active Directory. for other LDAPs values will differ. All attributes here are mandatory (must be mapped). |
| First Name           |                                                         | givenName          | Described default values shows typical mapping in Active Directory. for other LDAPs values will differ. All attributes here are mandatory (must be mapped). |
| Last Name            |                                                         | sn                 | Described default values shows typical mapping in Active Directory. for other LDAPs values will differ. All attributes here are mandatory (must be mapped). |
| Primary Group ID     |                                                         | primaryGroupID     | Described default values shows typical mapping in Active Directory. for other LDAPs values will differ. All attributes here are mandatory (must be mapped). |

Last updated: September 21, 2026

---
version: "v3.9.1"
language: "en"
---
# Audit

Audit section in dashboard includes Authentication Sessions, Action Logs and Reports. It can be accessed via **Veridium Manager/ Audit** tab.  
* [Enhanced Traceability and Device Log Reporting](https://docs.veridiumid.com/docs/v3.9.1/enhanced-traceability-and-device-log-reporting.md)
* [Auditing authentication sessions](https://docs.veridiumid.com/docs/v3.9.1/auditing-authentication-sessions.md)
* [Action logs](https://docs.veridiumid.com/docs/v3.9.1/action-logs.md)
* [Reports](https://docs.veridiumid.com/docs/v3.9.1/reports.md)
* [IDP Sessions in Audit](https://docs.veridiumid.com/docs/v3.9.1/idp-sessions-in-audit.md)

Last updated: September 21, 2026

---
version: "v3.9.1"
language: "en"
---
# Auditing authentication sessions

## Time Filtering

1. To filter time, click All Time.

   ![image-20230401-100101.png](https://docs.veridiumid.com/__attachments/a_1b45f8f40472f25883228b399b85f81f826ab037980765ce686dc412a3f5dd09/image-20230401-100101.png?cb=2115b51c1fa2fafec20bdefabc4c52a4)

2. Select time you are interested in and go back to main page.

![image-20230401-100118.png](https://docs.veridiumid.com/__attachments/a_b23a452d772cd9868571f0f21203f839e99420929c18cbb250b9a6b85cf97a18/image-20230401-100118.png?cb=7867f12c1dc68ee9a92c3c85cb474dc8)

### Search

1. To search, type in the selected area thing that you are looking for, click Search.

   ![image-20230401-100212.png](https://docs.veridiumid.com/__attachments/a_1e6518c0c2c429985db599fc0a2a8da76e8c8912c990a75322ffb98f87d45881/image-20230401-100212.png?cb=7f66d8a4181fc72cedf912dc1ef17446)

2. Using a arrow down the detailed search criteria might be used:

   ![image-20230401-100221.png](https://docs.veridiumid.com/__attachments/a_e7d12353f97e3a201b7e6f38a53704085f55dda8777b6e0c3c1656d916c6ddff/image-20230401-100221.png?cb=2b8e3ffccda5578ae7f7ef7f43c7e4b9)

#### Session Details

1. Click the Details button from the authentication session needed for inspection.

![1.png](https://docs.veridiumid.com/__attachments/a_8c51aa57769b7b1d6c7e67db2c0adf3801e2d674f272aaf8c6b2db18da8df4e9/1.png?cb=a1acbd22fb0af5e04a1ee941c3719f42)

2. The detailed information about the selected authentication session will appear.  
![image-20230401-100254.png](https://docs.veridiumid.com/__attachments/a_7189f973bf22d8cedbbaeea57177afb7599adc9ca2652cd04cc0719dcf617a29/image-20230401-100254.png?cb=f6c2bc962a94997645844e51326c0e94)

Note, each bullet on an authentication journey represents one step. For detailed information about each step, click on the time stamp on the authentication step.

Last updated: September 21, 2026

---
version: "v3.9.1"
language: "en"
---
# Auditing - SIEM events configuration

SIEM activities for **websecadmin** admin can be found here:

/var/log/veridiumid/websecadmin/events.log

SIEM activities fro **Application user activities** (login, etc) can be found here:

/var/log/veridiumid/tomcat/events.log

**Example of events - see excel file:**

[Users_SIEM_3.8.1.xlsx](https://docs.veridiumid.com/__attachments/a_0d418c16f4a4d57dee7805ac13ce739654e93bf5513cc7685692c7618498aa07/Users_SIEM_3.8.1.xlsx.md?cb=badbaa2b30238e31dfb142394bf06330)

**How rsyslog works:**

→ it monitors specific events/files on the system and send by default to /var/log/messages but it also can send them to a rsyslog server.

→ Veridium can have configured 2 files to be send to Rsyslog server (see below configuration examples)

(based on article <https://www.itzgeek.com/how-tos/linux/centos-how-tos/setup-syslog-server-on-centos-7-rhel-7.html> )

**How to configure rsyslog in order to deliver the events to a rsyslog:**

Due to the fact that logrotate with copytruncate is configured, the following configurations should be done in rsyslog file (this can be added in /etc/rsyslog.conf or in /etc/rsyslog.d/events.conf). Please fill in the proper IP of rsyslog server.

This should be configured on each webapp.

    module(load="imfile" PollingInterval="10")
    input(type="imfile" File="/var/log/veridiumid/websecadmin/events.log" Tag="ver-adminevents" reopenOnTruncate="on")
    input(type="imfile" File="/var/log/veridiumid/tomcat/events.log" Tag="ver-events" reopenOnTruncate="on")

    if $programname == 'ver-events' then @@10.10.10.10:514
    & stop
    if $programname == 'ver-adminevents' then @@10.10.10.10:514
    & stop

Last updated: September 21, 2026

[Next Page](https://docs.veridiumid.com/llms-full.txt/1)
