Self-hosted service
nabla-c0d3/sslyze avatar
nabla-c0d3/sslyze

SSLyze review: a Python TLS scanner built to run in CI/CD

Fast and powerful SSL/TLS scanning library.

3,782 stars493 forksPythonAGPL-3.0

At a glance

What is it?
SSLyze is an AGPL-licensed SSL/TLS scanning library and CLI that checks a server's certificate, cipher suites and protocol versions against Mozilla's recommended profiles. It is aimed at engineers who want TLS compliance as a build step or as a Python API call.
Who is it for?
Adopt SSLyze if you want a TLS configuration check that exits non-zero inside a pipeline, or if you need to call the scanner from Python rather than parse a report by hand. Do not adopt it if AGPL-3.0 is incompatible with how you distribute your own product, or if you need a hosted scanner with a web UI, since the project ships a CLI, a Python API and a Docker image and nothing else.
Can I use it commercially?
Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
Is it still maintained?
Yes. The repository last received commits 5 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What SSLyze checks, and who the check is for

SSLyze connects to a TLS endpoint and reports on its configuration: the certificate, the cipher suites the server accepts, the elliptic curves it offers, and the protocol versions it supports. It also probes for a defined set of known TLS attacks, with Heartbleed, ROBOT and OpenSSL CCS injection named in the README. The output is not a score. It is a set of observations, plus, when you ask for it, a pass or fail against a Mozilla TLS configuration.

The audience is narrower than the tagline suggests. This is a tool for people who already know what a cipher suite is and want that answer inside an automated process. The README describes two operational shapes: a command line you can drop into CI/CD, and a Python API you can call from an application, with AWS Lambda given as an example deployment target. If you want a hosted dashboard that emails you a grade, this is not that. If you want a library that returns structured results you can assert on, it is.

One detail worth noting is the non-HTTP support. The README lists SMTP, XMPP, LDAP, POP, IMAP, RDP, Postgres and FTP servers as scannable targets. Most TLS checkers assume port 443 and an HTTP handshake; SSLyze does not, which matters if your compliance surface includes a mail relay or a database endpoint.

How a scan is structured: plugins, trust stores and Mozilla profiles

The repository layout shows the scanner is organized as a set of plugins under sslyze/plugins/, with certificate_info holding its own trust store directory of PEM files. That is the mechanism behind certificate validation: SSLyze carries its own trust anchors rather than relying on whatever the host operating system happens to have installed. For a CI container this is the difference between a deterministic result and one that changes when the base image is rebuilt.

The Mozilla comparison is a separate component. setup.py packages sslyze/mozilla_tls_profile/5.7.json as a non-Python data file, so the profile is versioned with the code and travels with the install. The README shows the configurable values as old, intermediate and modern, with intermediate as the default. A scan result is checked against that profile, and non-compliance produces a non-zero exit code.

Results can be written to JSON, and json_output_schema.json sits at the top level of the repository, which tells you the output format is a contract the maintainers treat as stable enough to publish a schema for. That is the part that makes SSLyze usable as infrastructure rather than as an interactive tool: you can diff two JSON outputs, or feed them into whatever stores your compliance evidence.

The architecture also explains the speed claim. The README says SSLyze is used to scan hundreds of thousands of servers every day, and the design that makes that plausible is concurrency across targets combined with a fixed plugin set, rather than a sequential walk through every possible cipher. I have not run it, so I cannot tell you what the wall-clock cost per host is; the README does not publish a number either.

Installing SSLyze and running a first compliance scan

The README gives pip as the install path on Windows, Linux (x86 or x64) and macOS. It recommends upgrading the packaging tools first, which is the usual advice for a project that ships wheels and build dependencies.

bash
$ pip install --upgrade pip setuptools wheel
$ pip install --upgrade sslyze

After that, the module is runnable directly. The README's example passes three targets at once: two hostnames and one IPv6 address with an explicit port, written as "[2607:f8b0:400a:807::2004]:443". The bracketed form is how you give SSLyze a non-default port on an address that already contains colons.

bash
$ python -m sslyze www.yahoo.com www.google.com "[2607:f8b0:400a:807::2004]:443"

The first real use is the compliance check. Running the module against a single host prints a line stating which Mozilla configuration was used, then a per-target verdict. The README's example output for mozilla.com against the default profile is "mozilla.com:443: OK - Compliant." The exit code is the point: a non-zero return means the server failed the check, which is what a pipeline step consumes.

bash
$ python -m sslyze mozilla.com

Switching profiles is a flag. The README shows --mozilla_config=modern and the failure output it produces, which lists certificate_types, certificate_signatures, tls_versions and ciphers as the categories that can fail. If your organisation has its own rules rather than Mozilla's, the README shows --custom_tls_config pointing at a JSON file in Mozilla's TLS configuration format, and custom_tls_config_example.json in the repository is the example to copy.

bash
$ python -m sslyze --custom_tls_config custom_tls_config_example.json mozilla.com

Docker is the other documented route. The README gives an image tag and a target, and the repository's Dockerfile builds from python:3.12-slim, creates a virtualenv, installs the package, and runs the container as a non-root user with uid 1001. The entrypoint is sslyze with -h as the default command, so an invocation without arguments prints help rather than scanning anything.

bash
$ docker run --rm -it nablac0d3/sslyze:6.1.0 www.google.com

Finally, a pre-compiled Windows executable is available from the Releases page, which is the answer for anyone who cannot or will not install Python. The README does not describe how that executable is built beyond the cx_Freeze branch visible in setup.py.

Where SSLyze is the wrong tool

The most concrete limitation is the licence. SSLyze is AGPL-3.0, and the README points to LICENSE.txt for details and exceptions. The AGPL's network clause is the part that catches people: if you embed this library in a service users interact with over a network, the licence's obligations attach in a way that a permissive library would not trigger. Whether that matters to you depends on your distribution model, and it is a question for your own counsel, not for a review. The practical consequence is that a team that would happily vendor an MIT-licensed scanner may not be able to vendor this one.

The second limitation is scope. SSLyze evaluates the TLS handshake and the certificate as presented. It does not crawl your application, does not test HTTP headers, and does not tell you whether the endpoint behind the TLS layer is authenticated. A server can be fully compliant with the modern Mozilla profile and still be trivially exploitable at the application layer. Treating a green SSLyze run as a security sign-off is a misreading of what it measures.

Third, the compliance verdict is only as good as the profile you selected. The default is intermediate, and the README's own modern-profile example shows a server being marked non-compliant for supporting TLS 1.2 and RSA certificates. If your team assumes the default is strict, you will get a pass where a stricter reading of your policy would produce a failure. The profile choice is a policy decision that SSLyze cannot make for you.

Finally, the README does not document a rollback or remediation workflow, and it does not describe how to handle a target that is intermittently unreachable. Anyone wiring this into a pipeline needs to decide for themselves what a connection failure should mean for the build.

SSLyze versus testssl.sh and sslscan

The obvious alternatives are testssl.sh and sslscan, and the difference is not in what they measure but in how you consume the result. testssl.sh is a shell script that produces a human-readable report with severity ratings and colour output; its natural habitat is a terminal and a person reading it. SSLyze's natural habitat is a process that reads an exit code and a JSON file. Both will tell you a server supports a weak cipher. Only one of them is designed to be a library call.

sslscan is closer in spirit to a fast enumeration tool: it reports accepted ciphers and certificate details. SSLyze goes further by bundling the Mozilla profile comparison and the attack probes, and by exposing the whole thing behind a documented Python API. The repository ships api_sample.py at the top level, and the README links to full API documentation, so the intended second use case beyond the CLI is clear.

The trade-off runs the other way too. A shell script has no dependency resolution problem, no virtualenv, and no Python version to pin. SSLyze's install instructions start with upgrading pip, setuptools and wheel, which is a signal that packaging matters here. If your environment is a locked-down jump host with no Python, the pre-compiled Windows executable is the only documented escape hatch, and it is Windows-only.

On licence, the comparison is stark. A permissive or public-domain scanner imposes no distribution obligations. SSLyze's AGPL is the price of the library API and the maintained Mozilla profile data.

Maintenance, releases and what upgrading costs

The last push to the repository was on 2026-08-30, which is recent. The release cadence visible in the release list is roughly two to three releases a year: 6.2.0 in August 2025, 6.3.0 in December 2025, and 6.3.1 in March 2026. That is a steady but not fast-moving project, and the version numbers suggest the maintainers are not afraid to break things across minor versions.

The upgrade cost concentrates in two places. The Mozilla profile is a versioned data file (5.7.json) shipped inside the package, so a new SSLyze release can change what counts as compliant without any change on your side. A pipeline that was green can go red after a dependency bump. That is arguably correct behaviour, but it needs to be a known property rather than a surprise at 2am.

The second place is the JSON output. A published schema at json_output_schema.json is a good sign, but schema files get revised. If you persist scan results and query them later, pin the SSLyze version in your CI image and upgrade deliberately, reading the release notes for output changes before you move.

On licence implications, the AGPL-3.0 applies to SSLyze itself, and the README directs readers to LICENSE.txt for details and exceptions. If you are only running the CLI as a separate process in CI, your exposure is different from embedding the library in a shipped or network-served product. That distinction is worth confirming with your legal team before you build on the API rather than the command line.

Editorial conclusion

Adopt SSLyze if you want a TLS configuration check that exits non-zero inside a pipeline, or if you need to call the scanner from Python rather than parse a report by hand. Do not adopt it if AGPL-3.0 is incompatible with how you distribute your own product, or if you need a hosted scanner with a web UI, since the project ships a CLI, a Python API and a Docker image and nothing else. Before rolling it out, verify the exact Mozilla profile your hosts must satisfy by running --mozilla_config=modern against one staging host and reading the failure list, because the intermediate default is more permissive and will pass servers that the modern profile rejects.

Frequently asked questions

How do I install SSLyze?

The README recommends upgrading pip, setuptools and wheel first, then installing the package with pip install --upgrade sslyze. It can also be run from the published Docker image, and a pre-compiled Windows executable is available from the Releases page.

How do I install SSLyze on Windows?

The README lists Windows alongside Linux (x86 or x64) and macOS as supported for the pip install path, so the same pip commands apply. If you cannot install Python, the README points to a pre-compiled Windows executable on the Releases page.

How do I use SSLyze?

Run it as a module against one or more targets, for example python -m sslyze mozilla.com. By default it checks the results against Mozilla's intermediate TLS configuration and returns a non-zero exit code when the server is not compliant.

How do I use SSLyze on Windows?

The README's quick start covers Windows through pip, and the same python -m sslyze invocation is used across platforms. The alternative for Windows is the pre-compiled executable from the Releases page.

What is SSLyze used for?

It analyzes a server's SSL/TLS configuration by connecting to it, checking the certificate, cipher suites and elliptic curves, and probing for known TLS attacks such as Heartbleed, ROBOT and OpenSSL CCS injection. The README also presents it as a CI/CD step that checks a server against Mozilla's recommended TLS configuration.

What does SSLyze do?

It scans a TLS endpoint and reports its configuration, and it can compare that configuration against Mozilla's old, intermediate or modern profiles, or against a custom JSON TLS configuration you supply. Scan results can be saved to a JSON file for later processing.

Official sources

  1. Issues
  2. License: AGPL-3.0
  3. nabla-c0d3/sslyze on GitHub
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/nabla-c0d3-sslyze.svg)](https://hysenlabs.com/projects/nabla-c0d3-sslyze)