# Hakky54 mutual-tls-ssl is a TLS lab where the client library is the variable

> This Java tutorial repository turns two-way TLS into a repeatable local exercise: one Spring Boot server, a root CA, and dozens of HTTP clients wired up for mutual authentication. Its value is the breadth of client configurations, and its cost is a client module that pulls in a large dependency set.

**Hakky54/mutual-tls-ssl** — 🔐 Tutorial of setting up Security for your API with one way authentication with TLS/SSL and mutual authentication for a java based web server and a client with both Spring Boot. Different clients are provided such as Apache HttpClient, OkHttp, Spring RestTemplate, Spring WebFlux WebClient Jetty and Netty, the old and the new JDK HttpClient, the old and the new Jersey Client, Google HttpClient, Unirest, Retrofit, Feign, Methanol, vertx, Scala client Finagle, Featherbed, Dispatch Reboot, AsyncHttpClient, Sttp, Akka, Requests Scala, Http4s Blaze, Kotlin client Fuel, http4k, Kohttp and ktor. Also other server examples are available such as jersey with grizzly. Also gRPC, WebSocket and ElasticSearch examples are included

- Repository: https://github.com/Hakky54/mutual-tls-ssl
- Stars: 637 · Forks: 127
- Language: Java
- License: Apache-2.0
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/hakky54-mutual-tls-ssl

## A pet project that became a repeatable two way TLS walkthrough

The origin story is worth hearing because it explains the shape of the repository. This started as a pet project by the author, who wanted to learn how mutual authentication based on TLS works, including which commands are needed to set it up locally. It was not written as a tutorial from the start. Once it worked, the author refactored it so the steps could be repeated and published as a walkthrough.

That origin leaves a distinctive fingerprint. The project is not a TLS library that you add to your application. It is a lab environment: a server module, a client module, a root-ca directory, and a script directory, laid out so you can start a server, break it deliberately, and fix it again. The stated goal is protecting an application with TLS authentication, only allowing access for certain users based on their certificates, so you can choose which users are allowed to call the application.

The scope of the sample project is a basic setup of a server and a client. The communication between the server and client happens through HTTP at first, with no encryption at all yet, and the goal is to ensure that all communication will be encrypted. The tutorial walks the reader from plain HTTP through one-way TLS to two-way TLS, and finally to a variant where the client trusts the certificate authority directly.

## KeyStore and TrustStore are the only two concepts you need to learn

The project defines its terms carefully, and the definitions are the actual teaching content.

Identity is a KeyStore which holds the key pair, also known as private and public key. TrustStore is a KeyStore containing one or more certificates, also known as public key, and it holds a list of trusted certificates.

Everything else follows from those two. One way authentication, also called one way TLS or one way SSL, is an HTTPS connection where the client validates the certificate of the counter party. Two way authentication, also called two way TLS, two way SSL, or mutual authentication, is an HTTPS connection where the client as well as the counter party validates the certificate.

The tutorial then adds a third mode: two way TLS based on trusting the Certificate Authority. In that setup the client does not need a trust store of individual certificates, it needs the CA itself, which is a different configuration from pinning a leaf certificate. A reader who cannot articulate the difference between the identity KeyStore, the trust store of leaf certificates, and the CA anchor will struggle with every later step, which is why the definitions come first and every later section builds on them.

The repository also links cheat sheets for keytool, for openssl, and for curl with a Java KeyStore, which is where the concrete commands live.

## Java 21 and Maven 3.9.10 are the floor, with tags for older runtimes

The minimum requirements are Java 21, Maven 3.9.10, an editor such as Eclipse or Intellij IDEA or any other text editor like VIM, and a terminal. A badge in the project description also states JDK compatibility 21.

If your runtime is older, the repository keeps compatibility branches as git tags rather than as separate maintenance effort in the main tree:

one tag for Java 8 and one for Java 11, checked out in place of the default branch.

The project includes a Maven wrapper, so it can be run without installing Maven locally. The project text gives, next to the default mvn command, the equivalent commands for the Maven wrapper. That detail matters more than it sounds: on a locked down workstation where installing a build tool is a request to another team, the wrapper removes one blocker.

The client module is where the build gets heavy. It has grown over time and contains a-lot dependencies, because it has to test many HTTP clients for Java, Scala, and Kotlin. The author warns that for this specific reason it will download a-lot of dependencies during the initial build. That is the single most important practical expectation to set before cloning: the first build is slow, and it stays slow if you keep rebuilding everything rather than the module you are working on.

## Forty plus HTTP clients, because every client configures TLS differently

The client list is the reason this project is worth a look, and the reason it was built in the first place. The author mostly worked with Apache Http Client, so the project started with a single Apache client. Later it became clear there were many more Java clients, plus clients based on Kotlin and Scala.

The problem being solved is stated plainly: configuring SSL and TLS can be hard, and every client requires a different setup. A developer who ships on one client library cannot assume the configuration knowledge transfers. So the project provides a cheatsheet with example client configuration and example http request, covering a list of 40+ HTTP clients.

The clients named in the project description span a wide range of ecosystems: Apache HttpClient, OkHttp, Spring RestTemplate, Spring WebFlux WebClient, Jetty, Netty, the old and the new JDK HttpClient, the old and the new Jersey Client, Google HttpClient, Unirest, Retrofit, Feign, Methanol, vertx, Scala client Finagle, Featherbed, Dispatch Reboot, AsyncHttpClient, Sttp, Akka, Requests Scala, Http4s Blaze, the Kotlin client Fuel, http4k, Kohttp, and ktor. Server examples beyond the Spring Boot one are also present, including jersey with grizzly, and there are gRPC, WebSocket, and ElasticSearch examples.

That breadth is the actual contribution, and it is also the maintenance cost, since every one of those clients can change its TLS API between major versions.

## The ayza library grew out of the client module

Along the way a separate project came out of this one. The description says that GitHub - Ayza came into life during the lifecycle of this project to easily configure all those clients.

The reason is mechanical. Every HTTP client can require a different ssl object to enable ssl, and each library expects a different concrete type: one wants an SSLContext, another wants a connection socket factory, another wants a client configuration object with its own fields. Assembling those by hand per client is repetitive and error prone, and the tutorial ended up doing that assembly a few dozen times. The library's stated purpose is to ensure it can deliver all the types to configure these clients while having a basic ssl configuration.

So the architecture is: the tutorial repository demonstrates the raw configuration for each client so you can see what is going on, and Ayza packages the same idea as a reusable library for your own application. For a reader who is going to write production code, the library is the more interesting artifact, and the tutorial is the guide for it.

The repository also carries an EXERCISES.MD file, which suggests the content is intended to be worked through rather than only read, and a .gitpod.yml, which is the configuration for a cloud development environment where a browser terminal is enough to follow along.

## Where the tutorial stops and real TLS work begins

Two limitations are visible without running anything.

The first is scope. The sample project demonstrates a basic setup of a server and a client, and the deliverable is a teaching environment. There is no production TLS stack here, no session ticket management, no cipher suite selection, no certificate rotation story, and no integration with a secrets manager. The root-ca directory and the script directory are the fixtures of a local exercise, not a deployment pipeline. Treat everything in the repository as a working reference for the mechanics of mutual TLS, not as configuration you would copy into a service.

The second is the client module dependency weight, which the author calls out directly. A repository that must compile forty plus clients across Java, Scala, and Kotlin will carry the union of their dependencies, including test frameworks, and the initial build downloads them all. If you are only using the server example, you are paying for that.

The security model itself is worth stating plainly, because the trust decision is entirely yours. One way TLS means the client checks who the server is and the server checks nothing about the client. Two way TLS adds the client certificate, and the server then decides which certificate holders are allowed in. The tutorial does not describe an authorisation layer on top of that, so the allow list is wherever your application code puts it, and the certificate is the only claim of identity the server has.

## Active commits, no releases, and an Apache 2.0 licence

The maintenance picture is clear enough to plan around. The last push to the repository was on 2026-10-15, so the work is current, and the project carries continuous integration through a GitHub Actions workflow, along with SonarCloud badges for quality gate status, maintainability rating, and coverage. The project description does not claim any GitHub releases, and the repository has no tagged releases, which is normal for a tutorial repository whose versioning lives in git tags such as java-8-compatible and java-11-compatible rather than in release artefacts.

The licence is Apache-2.0, which is the permissive choice with an explicit patent grant, and suits both the tutorial and the Ayza library derived from it. Read the LICENSE file for the actual terms rather than relying on the badge.

The upgrade cost for a team that adopts this is not in the build. It is in the client matrix. When a client library changes its TLS configuration API, this repository has to change with it, and your copy of the tutorial is a snapshot. The practical version of this advice is concrete: copy the pattern for your client, not the whole module. If your application uses one HTTP client, take that one section, confirm it against the current version of that client, and drop the other thirty-nine.

## Conclusion

Hakky54 mutual-tls-ssl fits Java developers who need mutual TLS configured against a specific HTTP client rather than against a generic diagram, and who want to rehearse the certificate steps locally first. It does not fit a team looking for a production TLS library, since the deliverable is a tutorial repository with a large client module, not a maintained component. Before using it, decide which client you actually need, because the client module carries a-lot dependencies and the initial build downloads them all, and check the script/ directory to see whether the automated certificate setup matches the keytool and openssl commands your organisation standardises on.

## FAQ

### What are the minimum requirements to run the Hakky54 mutual-tls-ssl tutorial?

Java 21, Maven 3.9.10, an editor such as Eclipse or Intellij IDEA, and a terminal. The project also includes a Maven wrapper, so you can run it without installing Maven.

### How do I use an older Java version with the mutual-tls-ssl tutorial?

Check out one of the compatibility tags in the repository, either tags/java-8-compatible or tags/java-11-compatible, and build from that tag.

### What is the difference between the KeyStore and the TrustStore in this tutorial?

Identity is a KeyStore holding the key pair, private and public key. TrustStore is a KeyStore containing one or more trusted certificates, also known as public key.

### Which HTTP clients are covered by the mutual-tls-ssl client cheatsheet?

A list of 40+ clients for Java, Scala, and Kotlin, including Apache HttpClient, OkHttp, Spring RestTemplate, Spring WebFlux WebClient, Netty, Retrofit, Feign, vertx, Akka, Fuel, http4k, and ktor, each with example client configuration and example http request.

### Can I build the mutual-tls-ssl project without installing Maven?

Yes. The project contains a Maven wrapper, and the documentation gives both the default mvn command and the equivalent Maven wrapper commands.

## Sources

- [Hakky54/mutual-tls-ssl on GitHub](https://github.com/Hakky54/mutual-tls-ssl)
- [Issues](https://github.com/Hakky54/mutual-tls-ssl/issues)
- [License: Apache-2.0](https://github.com/Hakky54/mutual-tls-ssl/blob/master/LICENSE)
- [README](https://github.com/Hakky54/mutual-tls-ssl/blob/master/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/hakky54-mutual-tls-ssl
