DEV Community

Cover image for Why Your Company Should Use a Self-Signed Internal CA for TLS Certificates
Guilherme Diniz
Guilherme Diniz

Posted on

Why Your Company Should Use a Self-Signed Internal CA for TLS Certificates

“Wait — why do we need our own certificate authority inside the company?”

If you’re a new developer or DevOps engineer, this is a common and important question when working in secure internal environments.

Let’s break it down.


The Challenge: Securing Internal Applications

In most organizations, internal web applications — such as:

  • my-system.company.local
  • intranet.company.local
  • grafana.company.local

— need to communicate securely via HTTPS.

Even though these apps are not publicly accessible, modern browsers, frameworks, and APIs expect encrypted traffic. So, TLS is mandatory.

But using public CAs (like Let’s Encrypt or DigiCert) comes with problems:

  • Internal domains like .local or .company.local aren’t valid on the public internet.
  • You can’t prove ownership of them to a public CA.
  • Renewing and managing multiple certificates manually is painful and risky.
  • You’d be spending money for no external benefit.

The Solution: Set Up an Internal Certificate Authority (CA)

Instead of relying on external providers, you can create a self-signed internal CA— a trusted root certificate that lives only inside your organization.

This internal CA will be the foundation to:

  • Sign TLS certificates for internal systems
  • Manage lifecycle and trust
  • Avoid browser warnings and TLS errors across your network

How it Works

  1. Create a root CA certificate (self-signed)
  2. Install the CA certificate into trusted stores on all internal machines
  3. Use the CA to issue individual TLS certs for your services

Step-by-Step: Creating a Self-Signed CA and Issuing Certificates

Here’s a minimal example using OpenSSL.

1. Generate the Root CA Key and Certificate

openssl genrsa -out internal-rootCA.key 4096
openssl req -x509 -new -nodes -key internal-rootCA.key \
 -sha256 -days 1825 -out internal-rootCA.crt \
 -subj "/C=BR/ST=SP/O=Company/CN=Internal CA"
Enter fullscreen mode Exit fullscreen mode

2. Generate a Private Key and CSR for Your App

openssl genrsa -out my-system.company.local.key 2048
openssl req -new -key my-system.company.local.key -out my-system.company.local.csr \
 -subj "/C=BR/ST=SP/O=Company/CN=my-system.company.local"
Enter fullscreen mode Exit fullscreen mode

3. Create a SAN Config (Subject Alternative Name)

Create a file san.cnf:

[req]
distinguished_name=req
[ext]
subjectAltName=DNS:my-system.company.local
Enter fullscreen mode Exit fullscreen mode
  1. Sign the CSR with Your Internal CA
openssl x509 -req -in my-system.company.local.csr \
 -CA internal-rootCA.crt -CAkey internal-rootCA.key -CAcreateserial \
 -out my-system.company.local.crt -days 825 -sha256 \
 -extfile san.cnf -extensions ext

Enter fullscreen mode Exit fullscreen mode

That’s it. You now have a valid TLS certificate signed by your own internal CA.


Distribute and Trust Your CA

To make this work:

  • Install the internal-rootCA.crt on all developer machines, servers, and containers.
  • For browsers and operating systems, import the CA into the Trusted Root Certificates Store.
  • In enterprise environments, automate this using GPO (Windows), Ansible, or MDMs (mobile device management).

Summary

An internal CA gives you:

  • Complete control over your TLS infrastructure
  • No cost or dependency on external providers
  • A scalable way to secure internal services

It’s a foundational DevOps skill that pays off in reliability, compliance, and developer experience.


Final Thoughts

Setting up an internal CA is one of those “small infrastructure wins” that unlocks big benefits later. If you’re in DevOps, SRE, or backend engineering — it’s worth mastering.

Bonus: Automate Everything

Manually managing certs gets old fast. Consider using:

  • cfssl: Cloudflare’s PKI toolkit
  • step-ca: Easy, production-ready CA server
  • Vault PKI: Secret management with certificate issuing

Via Guilherme Diniz

Top comments (0)