Skip to main content

Getting started with Domino AppDev Pack Java API - Part 2

In my previous post I've shown how to quickly start coding with Domino AppDev Pack Java API. I used an insecure connection to avoid dealing with certificates, now it's time to fix this. If you are testing the new Java API, which is marked as a preview, you probably enjoy living on the edge and may also have a V12 EAP Domino server somewhere. This may help us see how the future may look.

Domino AppDev Pack series:
2. Certificates (this)

The AppDev Pack distribution contains sample files that generate ca, certificates and kyr file using openssl, but this is a one-time operation that is pretty hard to repeat or even use in production. If you want to use this in production, you should use a proper certificate authority. Last week Daniel Nashed posted info about nice enhancements coming to V12 that can help us here Domino V12 ACME for company CAs using smallstep and Easy kyr file creation with Early Access V12 in production.

smallstep ca

step-ca is an open source online certificate authority that can be easily hosted in Docker and supports ACME protocol (know primarily from Let'sEncrypt). It makes it very easy to run your own PKI and automate the certificate management. 

Domino V12 now has support for ACME and it works with step-ca too. Now we just need to connect the pieces. 


The primary goal of this part is to secure the communication between the Java client and the Proton server and authenticating the app using a certificate.

I'll be mixing V12 and V11.0.1 environments here as V12 is currently available only in Docker and I have my Proton task running on different Windows VM. I think once V12 is out, all this will work together nicely.

  1. Setup the CA
  2. Get a Domino kyr using ACME
  3. Configure the kyr in Proton
  4. Create a user certificate
  5. Import the certificate to Domino Directory
  6. Use the certificate from Java API
Sounds pretty easy, but there are few issues when doing this with current versions.

Setup the CA

I won't cover the full setup of the smallstep ca here as the project has nice tutorials, including docker installation. Basically, it's about running 

step ca init 

and answering few questions.

Once you have the default setup in place, you need to do 2 configuration adjustments:

1. Add support for ACME
Done simply by executing

step ca provisioner add my-acme-provisioner --type ACME

2. Extend the default certificate duration
The default expiration is set to 1 day and we don't want to change the certs every day now. Add the claims to config/ca.json, - e.g.

 "claims": {
                        "maxTLSCertDuration": "17520h0m0s",
                        "defaultTLSCertDuration": "17520h0m0s"
See documentation for details. 

Don't forget to restart the ca, e.g. kill -1 1 if running in Docker.

Get the kyr file for Domino

Now it's getting more interesting.  Daniel explained that it's possible to generate the kyr file for Domino servers probably starting with version 9.0.1, but to do it properly, you'd have to install the DSAPI filter on that server too. 

For now, I just temporarily changed my DNS record to point to my V12 server using my Proton server address, this way I was able to get the certificate/kyr, which I could just copy to the server manually. Once everything is running on V12, this all will be fully automated, including renewals (and maybe we can go back to the 1 day certificates).

You need to do follow the standard setup procedure for Let's Encrypt integration -

Then copy the PEM from the root certificate of the CA - it's in certs/root_ca.crt and then create the ACME Account configuration document in the Certificate Store.

Enter the following information:
  • Account Name - some meaningful name
  • ACME Directory URL - based on the information you used to create the ca
  • Key Algorithm - set to RSA
  • On Security/Keys tab - paste the root_ca.crt content

Now you should be ready to request the certificate. Create new Key File document and select the account that you've just configured.

Leave the Domino Server Names empty, the CertMgr then should not try to copy the kyr file to the server and restart the HTTP, which you normally want to happen if you would use it on the current server. 

If everything works well .....

you get the kyr file at the bottom of the form.

Few comments ...

The key must but RSA, not ECDSA as ECDSA support was added in V12 and is probably still being improved. 

If you are running the test Domino server behind some reverse proxy, e.g. like me on a Synology NAS, you may have a problem with /.well-known/acme-challenge being used by the proxy to handle its certificate requests. It's easy to test as it's returning "Challenge NOT found" for unknown ids

Configure the kyr in Proton

Now just copy the kyr and sth file to Data directory of your Proton server. Then open the Proton settings and insert the name of the kyr file.

Last step, enable the Client Certificate authentication. When saving the configuration, the Proton will ask for a restart. If all is good you should see

PROTON: Server initialized

Create a user certificate

The easiest way to create a user certificate is go directly to the ca and use step ca certificate command.
Just make sure the common name matches the name of the user you want to use. E.g.

Then select the JWK provisioner and you should get a certificate and a key.

This should work fine for the Node.js domino-db module, but with the Java API I had a problem that the key file was not consumed correctly. I had to create a pkcs#8 version of the key file, which allowed the Java API to use it just fine.

You can use the step crypt key command to do the conversion, e.g. if you don't want to use a password.

step crypto key format protonapp1.key --pem --pkcs8 --no-password --insecure --out protonapp1-pkcs8.key

Then copy the files to your workstation, where the Notes client and your Java program can access them.

Import the certificate to Domino Directory

Register a user for the connection as usual (no mailfile is needed). Once it's registered, open the person document, and from the Actions menu choose Import Internet Certificates.

Select All Files, pick the .crt file and confirm the import.

Re-open the person document and you should see the certificate.

Use the certificate from the Java API

Now is time for the last step. Using the certificates from the Java API. 

Currently, there seems to be an issue with handling of the trust chain in Java, so we need to make few adjustments. Node.js domino-db module seems to work just fine with these files. I've already mentioned the different key file format. 

The second issue requires combining the root_ca.crt and intermediate_ca.crt to a trust.crt file. You can also grab the intermediate certificate from the user.crt. I'll need to check this with HCL. For now just open the root_ca.crt, prepend it with the certificate for intermediate ca. Save the file as trust.crt.

Now you should be ready to use everything from your code.

If you run my sample, you should see that the document is now created by the new user.


It was a bit painful process to get this to work, but I know that Java API is in preview and V12 is in the Early access program. Daniel Nashed tried to help me and I've learned many things about smallstep ca, cryptography and Domino along the way. This setup should be good for use in production when you e.g. want to do system-to-system data integration, e.g. batch processing of Domino data from external Java-based system.

I hope that future versions will remove those manual workarounds, namely:
  • problem with the trust chain 
  • problem with the key file handling
  • ECDSA support for kyr - should be in V12 already where it works for HTTP task just fine.

Code is available in github -, certs are loaded from the resources folder. I've also removed the dependencies from the pom.xml, so if you want to use it directly, you need to add the artifact manually to your maven repository.


Popular posts from this blog

Microsoft Word black box in numbering issue

This is awkward post, primarily to save the solution for future me. I have seen many people mentioning this problem over years and as I've struggled with it several times, I needed to find final and permanent solution. All editions of Microsoft Word from time to time suffer from bug in numbering. Instead of a number, black box is displayed. Sometimes it happens right after document is opened, sometimes during editing. Probably some internal structure of document gets corrupted, so based on level of corruption, different fixes could help. Many of them are listed at I took different approach. Since docx is just standard zip package with xml files, I decided to try if I can fix it manually. And it worked. When I extracted the docx, there was file called numbering.xml in word folder. When I examined that file, I found strange se

HCL Domino SSO with Microsoft Teams

 Microsoft Teams is probably one of the most used tools this year, it was already quite popular before the pandemic started to spread across the world this spring, but now most of the businesses I work with use it. After using it just like a chat/conferencing tool, many start to explore further capabilities of the platform. When working with Domino data in apps that are web-enabled, it can be quite easy - just add a web tab anywhere you want. The problem is, that you need to deal with user authentication. 

Domino CI build with Jenkins and Docker

 I wanted to make this work for a very long time, but there were always some parts missing, so I could not get the full process running. Finally, the wait is over. The following paragraphs describe a way to build Notes/Domino apps automatically on a Jenkins server, allowing parallel builds and all "normal" continuous-integration behavior, without having to think too much about Domino specifics. The Problem Until now, I was running my automated builds of Domino apps using Jenkins in two ways: The official headless-designer way, where you need to pass special commands to Domino Designer and hope for the best as the Designer sometimes gets stuck. I have this wrapped inside a Jenkins pipeline, so I have some control and can e.g. avoid parallel builds by using locks on Jenkins, but still, sometimes it just dies. Some of my headless builds run for more than 30 minutes, so it's really hard to quickly spot an issue without actually connecting to the machi