How to Add SSL/TLS Encryption to APIs Posted in Security J Simpson February 13, 2025 Treblle’s Anatomy of an API 2024 report revealed a disturbing trend. Despite existing for over 30 years, only 45% of API developers use HTTPS to send or receive data. To make matters worse, that’s down from 74% in 2023. That’s nearly a 30% decline in a single year! Failing to properly secure your data puts your customers, company, and reputation at risk. Sending unencrypted information can expose all manner of sensitive data, ranging from usernames and passwords to financial data. Not encrypting APIs runs the risk of giving cyber attackers the keys to the kingdom with live and active usernames and passwords. When they use such login info, this unauthorized access is challenging to detect or prevent. To help you ensure this doesn’t happen and that your API is as secure as possible, we’ll walk through how to add SSL/TLS encryption to APIs. We’ll explain what SSL/TLS is and showcase how it can be set up from scratch as well as easily enabled using modern API gateways. What Is SSL/TLS Encryption? Before we explore how to add SSL/TLS encryption to APIs in earnest, let’s take a moment to explore our terminology. What is SSL/TLS encryption? SSL/TLS encryption stands for Secure Socket Layer and Transport Layer Security, respectively. Both work by establishing a secure connection known as a handshake. Handshakes can be executed by exchanging certificates, keys, or ciphers to establish a connection and an agreement about how the data will be encrypted and decoded. How To Add SSL/TLS Encryption To An API Getting Started With SSL/TLS Encryption The first step in adding SSL/TLS encryption is to obtain a valid SSL/TLS certificate on your server from a trusted Certificate Authority (CA) like Let’s Encrypt or Global Sign. These certificates are digital documents containing all the data necessary to validate a digital entity’s authenticity, including the domain name, public key, and who issued the certificate. API developers can also generate self-signed certificates if they like. However, many internet browsers and clients don’t recognize self-signed certificates and sometimes even trigger security warnings or errors. Therefore, best practices recommend using an official CA like Let’s Encrypt. Once you have the SSL/TLS certificate, you must install it on your API server. Every server has its unique way of manually installing an SSL/TLS certificate, so you may have to research the details of your particular infrastructure when setting up SSL/TLS encryption on your API server. To give you a rough idea, we’ll show you how to add an SSL/TLS certificate to an AWS server. Start by generating a certificate using an official CA. We recommend Let’s Encrypt due to their non-profit status and the service being free to use. To install an SSL certificate on AWS, generate an SSL certificate and then download it. Next, sign into the Amazon EC2 console. Find the Load Balancers section on the navigation menu on the left side of the screen and open it. You’ll need a Load Balancer to attach the SSL/TLS certificate, so you’ll need to create one if you don’t have one already. Open your Listener and find the section called Listeners. If you’re modifying an existing Listener, scroll down and find the HTTPS (Secure HTTP) Load Balancer Protocol and locate the SSL Certificate column. Select Change, where you can Upload a new SSL certificate to AWS Identity and Access Management (IAM). When creating your certificate, make sure to give it a name that you can remember later. In the Private Key field, copy and paste the text from the .key component of the certificate you downloaded. Do the same with the .crt file for the Public Key. Once you’ve done this, scroll down and Save your Listener. If you created your Listener from scratch, you have the opportunity to make an SSL/TLS certificate as the default. Simply find the Default SSL/TLS Certification section beneath the Secure Listener Settings section of the console. Select the Certificate Source and then copy the steps above, copying the Private and Public Keys from the SSL certificate. This is just one example, but you should already be getting an idea of the general pattern for adding SSL/TLS encryption to a server. First, get a secured certificate, then install that certificate on your server. This pattern holds true for API developers, as well. Simply add the SSL/TLS certificate to your API server. Using SSL/TLS encryption for APIs has unique rules and requirements, however, as we’ll detail below. Adding SSL/TLS Encryption To An API Now, let’s add SSL/TLS Encryption to an API to demonstrate how this works. Let’s start with an API server. For this example, we’re going to make barebones API server using Flask, creating an app called pythonserver with three endpoints: \users, \resources, and \tests. from flask import Flask, jsonify, request from werkzeug.middleware.proxy_fix import ProxyFix # Initialize Flask app app = Flask(__name__) # Middleware to handle proxy headers when behind a reverse proxy app.wsgi_app = ProxyFix(app.wsgi_app, x_proto=1, x_host=1) # Sample data for demonstration purposes users = [ {"id": 1, "name": "Alice"}, {"id": 2, "name": "Bob"} ] resources = [ {"id": 1, "type": "ResourceA"}, {"id": 2, "type": "ResourceB"} ] tests = [ {"id": 1, "status": "Passed"}, {"id": 2, "status": "Failed"} ] # Define API endpoints @app.route('/users', methods=['GET']) def get_users(): return jsonify(users) @app.route('/resources', methods=['GET']) def get_resources(): return jsonify(resources) @app.route('/tests', methods=['GET']) def get_tests(): return jsonify(tests) # Run the Flask app on localhost:8080 if __name__ == '__main__': app.run(debug=True, host='127.0.0.1', port=8080) Now, let’s configure that server to require SSL encryption. Run the following command to generate your own SSL certificate for the sake of this tutorial: openssl req -newkey rsa:2048 -nodes -keyout server.key -x509 -out server.crt You’ll be given a variety of prompts to fill out to generate your certificate. Once you’re done, you’ll be left with two files in your programming directory: server.crt and server.key. Now let’s modify our Flask server so it expects SSL encryption: from flask import Flask, jsonify, request from werkzeug.middleware.proxy_fix import ProxyFix # Initialize Flask app app = Flask(__name__) # Middleware to handle proxy headers when behind a reverse proxy app.wsgi_app = ProxyFix(app.wsgi_app, x_proto=1, x_host=1) # Sample data for demonstration purposes users = [ {"id": 1, "name": "Alice"}, {"id": 2, "name": "Bob"} ] resources = [ {"id": 1, "type": "ResourceA"}, {"id": 2, "type": "ResourceB"} ] tests = [ {"id": 1, "status": "Passed"}, {"id": 2, "status": "Failed"} ] # Define API endpoints @app.route('/users', methods=['GET']) def get_users(): return jsonify(users) @app.route('/resources', methods=['GET']) def get_resources(): return jsonify(resources) @app.route('/tests', methods=['GET']) def get_tests(): return jsonify(tests) # Run the Flask app with SSL encryption if __name__ == '__main__': app.run(debug=True, host='127.0.0.1', port=8080, ssl_context=('server.crt', 'server.key')) If you run this script just as it is, you should see a Privacy Error in your browser. That’s just because you’re using a self-signed certificate, which the browser mistrusts by default. That shouldn’t be the case when using an SSL certificate issued by an official CA. Since you’re just testing this on a production server, go ahead and allow your browser to trust the site. Open up one of your endpoints, and you should see the test data from the Python script. If the certificate and key files aren’t present, though, you won’t see anything, as the script won’t even run. The same thing happens if the .crt or .key files generated using SSL are modified in any way. Enforce SSL/TLS Encryption Once your API server is configured to send and receive SSL/TLS encryption, you must also ensure your users use it. This requires HTTPS for all your transactions, the secure form of HTTP that uses SSL/TLS encryption. This can be accomplished in a variety of ways. Redirecting basic HTTP requests to HTTPS using HTTP Strict Transport Security (HSTS) headers is a popular technique. So are various SSL/TSL libraries and frameworks, such as the https module for Node.js. As you can see, SSL/TLS encryption works like most other authorization flows, pairing a public key and a private key. Of course, the localized method we’ve used to create a private SSL certificate has limited practical applications, but it’s useful for illustrating the principles we’re talking about. Now let’s take a look at how to create an API server using an API gateway, as many API management tools offer native solutions for enforcing SSL/TSL encryption. Adding SSL/TLS Encryption To Your API Server Let’s finish by quickly creating a brand new API server using an API gateway so you can see how SSL/TSL encryption isn’t dependent on a particular platform. To start, we’re going to use Certbot to generate an authorized certificate from Let’s Encrypt. Start out by installing Certbot if you haven’t already. Once it’s up and running, navigate to your development folder for this project. Run the following command in a Terminal as an Administrator: certbot certonly --manual --preferred-challenges dns You’ll be guided through a series of prompts, at the end of which you’ll be given a name and a value to add to your server’s DNS settings. Create a new record with the name provided, using the TXT type, and then enter the provided value as data. Once you’ve created this record, you’ll have to configure your Web Server to enforce HTTPS. To accomplish this, you’ll need to redirect HTTP traffic to HTTPS. You’ll also need it to only listen on the 403 port, which manages HTTPS. If you’re running an NGINX server, that would look something like this: server { listen 80; server_name api.example.com; return 301 https://$host$request_uri; # Redirect HTTP to HTTPS } server { listen 443 ssl; server_name api.example.com; ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; location / { proxy_pass http://127.0.0.1:5000; # Example API backend proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } } Once that’s modified, you can test the configuration by running the following command: sudo nginx -t After this is all complete, restart your server. sudo systemctl reload nginx Once your Web Server is updated, you’ll need to modify your API so it enforces HTTPS, as well. For a Flask server, start by installing Flask-Talisman. Then modify your existing API server script by adding the following: from flask import Flask from flask_talisman import Talisman app = Flask(__name__) Talisman(app) @app.route("/") def home(): return "Secure API Server" if __name__ == "__main__": app.run(ssl_context=("fullchain.pem", "privkey.pem")) You’ll also need to remove any listen 80 blocks on NGINX or HTTP virtual hosts on Apache. Once that’s all modified, you can test your API to ensure it only accepts HTTPS requests. curl -k -X GET https://api.thisexample.com/resource Final Thoughts on SSL/TLS Encryption As more and more of our sensitive data ends up on the internet, developers and users alike must understand the latest protocols around both sending and receiving encryption. We’ve shown you how to add SSL/TLS Encryption to your APIs the hard way so you can better understand the principles, making it possible to add SSL/TSL encryption to your API server no matter what tech you’re using. All that said, adding SSL/TSL encryption to APIs using a tool like an API gateway is usually as easy as clicking a button, as most modern API management platforms and gateways offer native support for both sending and receiving encrypted data. Just keep an eye out for an option like Enable SSL/TSL Encryption or Require HTTPs or something like that. The latest API insights straight to your inbox