# Client certificates
Many enterprise web applications require the user to provide a client certificate, in order to verify that they are an authorized user. To test the functionality of these applications, the test must be able to provide the certificate.
Some applications also use certificates for access control; one certificate could allow for admin access, while another allows for viewer access. It's important to test that these different certificates result in different behaviour from the application.
Virtuoso empowers you to solve these testing scenarios, by allowing you to upload certificate profiles and use them in your executions!
# How to upload a certificate profile to Virtuoso
In order to use a certificate profile in Virtuoso executions, you will need to:
- Convert it to a format which the Virtuoso browser can read;
- Upload the converted certificate profile to Virtuoso.
This section explains two different methods for how you can do this:
Automatically with Podman (Recommended)
TIP
If you face difficulties in uploading your certificate, please contact customer support.
Containers are essentially small virtual machines that can be automatically configured to perform a task. We provide a configuration for such a container, which can be used to automatically convert your certificate profile to a format that can be understood by Virtuoso, upload it to Virtuoso, then finally verify that it was successfully uploaded. Podman is a program that you can use to easily setup and run this container on your machine.
# Installing Podman
Podman's installation process varies based on your operating system:
- Windows 10 & 11:
- Ensure that you have installed the latest available Windows update.
- Download the latest version's setup .exe from the Podman releases page and install it.
- Please note that earlier versions of Windows are not supported.
- macOS:
- If you have homebrew installed on your machine, open a terminal and run the command
brew install podman
. - Otherwise, download the latest macOS .pkg for the appropriate architecture from the Podman releases page and install it.
- If you have homebrew installed on your machine, open a terminal and run the command
- Linux:
- Use the appropriate command for your distribution, as Podman's documentation describes.
# Setting up Podman
Before using Podman, you must first set up and start its dedicated virtual machine. Fortunately, this is a simple process:
- In a terminal, run the command
podman machine init
. This will automatically download and set up the virtual machine; - Now run the command
podman machine set --rootful
. This allows the container to read your files (including the certificate file). - Next, run the command
podman machine start
. This will start the virtual machine. You might need to re-run this command if you want to use Podman again after restarting your computer.
# Running the container to convert, upload and verify the certificate profile
We supply a Dockerfile, which acts as a blueprint that Podman can use to set up the container. Before you can run the container to upload your certificate, you need to build it:
- Download the Dockerfile and its required shell script to the same directory on your machine;
- Open a terminal in this directory;
- On Windows 11, you can do this with the right-click context menu.
- On Windows 10, you can instead open the directory in your file browser, copy the path at the top of the window, then open Powershell and run the command
cd <the path that you copied>
- Run the command
podman build . -t virtuoso-certificate-uploader
.
Podman will automatically download the dependencies that it needs, and build the container. Once this is finished, you can use the container to convert and upload your certificate profile:
- Open a terminal in the directory where your .pfx / .p12 certificate profile is stored;
- Create an API access token for the organization owner account.
- Alternatively, on macOS or Linux, you can get a token with the following command:
export TOKEN=$(curl -s -X POST -H "Content-Type: application/json" -d '{ "email": "<email>", "password":"<password>"}' "https://api.virtuoso.qa/api/auth/login?envelope=false" | jq -r .token)
;
- Run the container with the following command, replacing the values as necessary:
podman run --env "CERTIFICATE_NAME=<The name that the certificate profile should have in Virtuoso>" --env "CERTIFICATE_DESCRIPTION=<A description of the certificate profile>" --env "CERTIFICATE_PASSWORD=<The password of the certificate profile>" --env "VIRTUOSO_ORGANIZATION=<The ID of your organization on Virtuoso>" --env "VIRTUOSO_TOKEN=<Your Virtuoso API token>" --env "CERTIFICATE_FILE=<The name of your certificate profile file, e.g. certificate.p12>" --mount type=bind,src=.,target=/data localhost/virtuoso-certificate-uploader:latest
If you are using an environment other than app.virtuoso.qa, you can target it with the VIRTUOSO_ENVIRONMENT_API option, e.g.
--env 'VIRTUOSO_ENVIRONMENT_API=api-app2'
If your certificate has been successfully uploaded to Virtuoso, the script will show you the resulting ID of the certificate.
If you have more certificate profiles that you want to upload, run the container again for each of them.
Manually
Manually uploading a certificate profile to Virtuoso involves:
- Converting the certificate profile to a Network Security Services Database (NSSDB);
- Creating the certificate entry on Virtuoso;
- Uploading the NSSDB files;
- Verifying that the NSSDB files were uploaded.
To add more certificate profiles, just repeat the same process with each of your certificate profiles that you wish to be available for your tests.
# Generating a Network Security Services Database (NSSDB)
For the Virtuoso browser to be able to read your certificate profile, it must be prepared as a Network Security Services Database (NSSDB). This section explains how to prepare the NSSDB.
- Install the
libnss3-tools
package on the Windows Subsystem for Linux (WSL), or a Linux computer or virtual machine;
- On Ubuntu operating systems, this can be performed using the command
sudo apt install libnss3-tools
.
- Download your certificate profile file. This should be in the
.p12
or.pfx
file format; - Create a directory to store the generated NSSDB within;
- Run the following command:
pk12util -d sql:<PATH-TO-TARGET-DIRECTORY> -i <PATH-TO-CERTIFICATE-FILE> -W "<CERTIFICATE-PASSWORD>"
; - The tool will ask you to
Enter a password which will be used to encrypt your keys
. Leave the password blank by only pressingENTER
, since Virtuoso will not be able to read the certificate files if a password is set; - The NSSDB will be generated in the target directory, consisting of the following files:
cert9.db
;key4.db
;pkcs11.txt
.
# Creating a certificate entry on Virtuoso
Before you can upload the NSSDB files, Virtuoso must generate secure, signed links for the files to be uploaded to. This also creates a record of the certificate profile in Virtuoso to use when accessing it later.
- Get a temporary access token for your Virtuoso organization owner account, with the following command:
export TOKEN=$(curl -s -X POST -H "Content-Type: application/json" -d '{ "email": "<email>", "password":"<password>"}' "https://api.virtuoso.qa/api/auth/login?envelope=false" | jq -r .token)
- Alternatively, create an API access token for the organization owner account.
- Make a
POST
call to/api/organizations/<ORGANIZATION-ID>/certificates
, where<ORGANIZATION-ID>
is your organization's ID, using the above token to authenticate the request:
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{ "name": "My certificate", "description": "Testing certificate" }' \
https://api.virtuoso.qa/api/organizations/<ORGANIZATION-ID>/certificates
If successful, this will return a response that looks like this:
{
"success": true,
"item": {
"id": <CERTIFICATE-ID>,
"uuid": <UUID>,
"s3PreSignedUrls": {
"key4.db": "https://.../key4.db?...",
"cert9.db": "https://.../cert9.db?...",
"pkcs11.txt": "https://.../pkcs11.txt?..."
}
}
}
# Uploading the NSSDB
The above certificate profile entry creation response includes upload URLs for each of the NSSDB files; the child items of s3PreSignedUrls
.
For each of your three NSSDB files, select the appropriate upload URL, then make a PUT
request to the URL. For example:
curl -X PUT \
-T path/to/key4.db \
https://.../key4.db?...
Please note that the maximum size for each file is 10 MB.
WARNING
Please note that these upload links will expire 1 hour after they are created. These links should not be shared.
# Verifying that the NSSDB was uploaded
After uploading your NSSDB files, the final step is to verify that your files were uploaded, allowing your certificate profile to be used in your executions.
To verify that a certificate profile's NSSDB was successfully uploaded, make a PUT
request to api/organizations/<ORGANIZATION-ID>/certificates/<CERTIFICATE-ID>/verify
, where <CERTIFICATE-ID>
refers to the numeric ID from the response of
Creating a certificate entry on Virtuoso.
curl -X PUT \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
https://api.virtuoso.qa/api/organizations/<ORGANIZATION-ID>/certificates/<CERTIFICATE-ID>/verify
If successful, this will provide a response similar to:
{
"success": true,
"item": {
"id": 2,
"uuid": "...", "name": "...",
"uploaded": true,
"createdBy": ..., "createdDate": ..., "modifiedDate": ...,
"archived":false
}
}
# Using an uploaded certificate profile in executions
After uploading and verifying the NSSDB files, you can use the certificate profile in executions on Virtuoso.
For the following sections, <CERTIFICATE-ID>
refers to the numeric ID from the response of
Creating a certificate entry on Virtuoso.
# Setting a default certificate profile for a goal
By setting a certificate profile for a goal, that certificate profile will be used for every execution of the goal's journeys, unless specifically overridden by a plan or advanced execution.
To set a goal's default certificate profile, first you need to retrieve the goal data, through a GET
request to /api/goals/<GOAL-ID>
.
curl -X GET \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
https://api.virtuoso.qa/api/goals/<GOAL-ID>
If successful, this will provide a response similar to:
{
"success": true,
"item": {
"id": 1234,
"projectId": 567,
"name": "Goal name",
"otherFields": "...",
"meta": {
"otherFields": "..."
}
}
}
Then, you need to make a PUT
request to /api/goals/<GOAL-ID>
with the JSON object of the Goal retrieved above, adding in the meta field the following:
{
"certificateId": <CERTIFICATE-ID>
}
So the request will be similar to the following:
curl -X PUT \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"id": 1234, "projectId": 567, "name": "Goal name", "otherFields": "...", "meta": {"otherFields": "...", "certificateId": <CERTIFICATE-ID>}' \
https://api.virtuoso.qa/api/goals/<GOAL-ID>
Note: you can un-set a goal's certificate by using
null
instead of the certificate's ID.
# Setting a certificate profile for a plan
Virtuoso also supports setting a certificate profile for a plan. Since multiple plans can target the same goals and journeys, this allows you to easily test shared functionality across different certificate profiles.
To set an existing plan's certificate profile, make a PUT
request to /api/plans/executions/<PLAN-ID>
:
curl -X PUT \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{ "certificateId": <CERTIFICATE-ID> }' \
https://api.virtuoso.qa/api/plans/executions/<PLAN-ID>
# Starting an advanced execution with a certificate profile
You can start a single execution of a journey, goal, or plan, by making a POST
request to the appropriate endpoint, with an application/json
request body that includes { "certificateId": <CERTIFICATE-ID> }
The endpoints to use for this are:
- Journey -
/api/testsuites/<JOURNEY-ID>/execute
- Goal -
/api/goals/<GOAL-ID>/execute
- Plan -
/api/plans/executions/<PLAN-ID>/execute
For example, to execute a journey with a certificate:
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{ "certificateId": <CERTIFICATE-ID> }' \
https://api.virtuoso.qa/api/testsuites/<JOURNEY-ID>/execute
# How to delete a certificate
Certificate deletion is available through the Virtuoso API.
To delete a certificate, make a DELETE
request to /api/organizations/<ORGANIZATION-ID>/certificates/<CERTIFICATE-ID>
, where <ORGANIZATION-ID>
is your organization's ID, and <CERTIFICATE-ID>
is the numeric ID of the certificate you wish to delete.
curl -X DELETE \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
https://api.virtuoso.qa/api/organizations/<ORGANIZATION-ID>/certificates/<CERTIFICATE-ID>
WARNING
Any goal or plan associations with the certificate will have to be manually updated, and, unless done so, will fail to execute with the "Archived certificates cannot be used" error.
# Limitations
Running Virtuoso making use of certificates has some unique limitations:
- Live authoring is not supported, if your goal uses a certificate, live authoring will not use it;
- Cross-browser executions are not supported, this feature requires the Virtuoso browser;
mouse move
step commands work but might sometimes behave unexpectedly, by moving the mouse a different distance when compared to conventional executions;- Screenshots will be shorter than the configured browser viewport size.
- API requests that are created from the API manager do not currently support certificate-based authentication.
TIP
You can use Virtuoso to make requests to API endpoints that require certificate-based authentication by creating a journey that uses the API request extensions, and running the journey with a certificate.
# Security
We strongly recommend that you consider the following practices when using your certificates to Virtuoso:
- Use certificates that can be revoked from your application;
- Use an additional factor of authentication alongside certificate-based authentication on your application;
- Avoid uploading certificates that would allow for access to sensitive data.