Skip to content

OpenLI Tutorial 20: REST API Authentication

Richard edited this page May 16, 2024 · 2 revisions

OpenLI Tutorial 20: REST API Authentication

OpenLI Tutorial 20

You may either watch the tutorial lesson on YouTube by clicking on the image above, or you can download the slides and read them alongside the transcript provided below.


Hello once again and welcome to the twentieth chapter in the OpenLI training series. In this lesson, I’m going to show you how you can further secure the REST API by requiring requestors to authenticate themselves.


As you may have already noticed, the default behaviour of the OpenLI REST API is to accept and act upon requests from anyone who manages to send a correctly formatted JSON object to the appropriate URL.

This clashes with the requirement that access to our LI infrastructure be limited to only absolutely essential personnel.

There are some obvious ways in which you can protect the REST API from unwanted access: you can isolate the provisioner by having the REST API socket reachable on a separate network, or use firewalling rules to only allow inbound connections to the listening socket from pre-approved hosts. A somewhat more radical option would be to have the provisioner only listen for REST API requests on localhost, and therefore only people who can log in to the provisioner host would be able to send requests.

Some, if not all, of these approaches will likely form part of your security strategy to protect your OpenLI infrastructure, but we can add an extra layer of protection by also insisting that requests are authenticated before they are accepted by the provisioner.


At this stage, OpenLI supports two different types of HTTP Authentication for the REST API. The first is to accept any request that has a valid pre-generated API key, and the second is conventional Digest Authentication as per RFC 2617.

I very strongly recommend that you employ at least one of these authentication methods with the REST API when you deploy OpenLI on your network.


Authentication in OpenLI is managed by a simple SQLite3 database backend, which stores the usernames, digest hashes and API keys for the users who will be allowed access to the REST API. The database is a file on the provisioner host and will be created automatically for you when you install the provisioner package.

The database itself is encrypted using sqlcipher, and cannot be read from or written to without a valid keyphrase.


The database file on the provisioner can be found at /var/lib/openli/provauth.db.

The initial keyphrase for the database that was set when you installed the provisioner package can be found in the file /etc/openli/provauthdb.phrase on the provisioner.

You should note down the phrase in that file, put it somewhere safe (such as a password store) and then delete the file so nobody else can read it later. You will need this phrase if you want to add or remove authenticated users later on.


To enable authentication checking for the REST API, you will need to edit the provisioner configuration file once more. Go ahead and open this file on your provisioner container.


There are two configuration options that you will need to enable -- these should already be present in the file, but commented out.

The first is the “restauthdb” option, which needs to be set to contain the path to the database file. Unless you decide to move the database for some reason, this should be /var/lib/openli/provauth.db.

The second is the “restauthkey” option, which needs to be set to the passphrase that you noted down earlier. The passphrase is randomly generated on package install, so I can’t tell you what to put in here.


Make sure both options have correct values and are no longer commented out, then go ahead and restart the provisioner using the same process we’ve used a few times already.


If you poke around in the provisioner log file, you should now see a recent entry stating that Authentication has been enabled for the REST API.


So let’s try it out -- on the provisioner container, try using curl to fetch the list of active intercepts using a command much like the one on the slide (adjusting the URL to match your provisioner IP and port, of course).

Because our request doesn’t include any authentication credentials, our request gets denied and the provisioner returns an “Authentication Failed” message.


OK, so let’s give ourselves some valid credentials.

To make life a bit easier, OpenLI automatically installs a script for adding new authenticated users onto your provisioner. The script can be found in /usr/sbin and is called openli-prov-adduser.sh.

The script takes four arguments -- the first one is the passphrase for the database file, the second is the username for the new user, the third is the password for the new user and the fourth is the location of the database file itself.

Please note that the password that you supply is NOT stored in the database -- we instead store a derived hash that is sufficient for validating a digest authentication. This also means, of course, that passwords cannot be recovered if forgotten.


When you successfully add a user with the script, a randomized API key will be generated and assigned to that user as well.

You will want to note this down somewhere, in case the user wants to authenticate using their API key.


An API key can be used to authenticate a REST API request by including an additional header in your HTTP request. The header type is “X-API-KEY” and the header value should of course be the REST API key that has been assigned to you.


In curl, you can use the “-H” option to add the “X-API-KEY” header to your request, just like we have done earlier to set the content type to JSON for requests where we send a JSON object.

You can see an example curl command on the slide, with the resulting output being as expected for that particular request.

Note that the API key will be visible in the HTTP header of your request, so you should only give out API keys to users if your REST API service is using HTTPS. Otherwise, a man in the middle could harvest your API keys by sniffing any request traffic that is sent to your REST API service.


The use of digest authentication will vary depending on the tool that you are using to send your REST API requests. I’ll show you how it works with curl, but figuring out how to do digest auth with any other software will be left as an exercise for you to do on your own.

In curl, applying digest authentication is fairly straightforward. You’ll need to add two extra options to your command line: the first is to enable digest mode by adding “--digest” with no additional arguments. The second is to use the “-u” argument to specify your username and password, separated by a colon.


An example curl command is shown on the slide, where you can see I’ve added both the “--digest” flag, followed by a “-u” with my username and password as an argument.


On occasion, you may find yourself needing to revoke authentication credentials for a particular user.

Unfortunately, OpenLI doesn’t provide a script to do that but this is actually a simple task that can be completed using a single command.

I’ve put the command here on the slide for you -- you can copy it directly and just substitute in your database passphrase and the username of the person you want to remove.

Obviously, if your database is in a different location than /var/lib/openli, then you’ll also need to update that argument.


And that is all you really need to know about authentication support in the REST API. I hope that what you’ve seen today will encourage you to make use of this feature when you deploy OpenLI for real.

Next time, we’re going to look at another optional but recommended feature in the OpenLI collector, where you can use RabbitMQ to buffer unsent intercept records and improve OpenLI’s robustness in the event of a communication failure between the collector and the mediator.

Thanks for joining me today, and I’ll see you again soon.

Clone this wiki locally