<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mo</title>
    <description>The latest articles on DEV Community by Mo (@ingeniumcode).</description>
    <link>https://dev.to/ingeniumcode</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2602835%2Fbee076af-c9d8-49b1-9d3c-da908d59c31e.jpeg</url>
      <title>DEV Community: Mo</title>
      <link>https://dev.to/ingeniumcode</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ingeniumcode"/>
    <language>en</language>
    <item>
      <title>Secure HTTP Traffic with HashiCorp Vault as your PKI + Cert Manager in Kubernetes - Deep Dive: Part 1!</title>
      <dc:creator>Mo</dc:creator>
      <pubDate>Tue, 29 Apr 2025 13:10:32 +0000</pubDate>
      <link>https://dev.to/ingeniumcode/secure-http-traffic-with-hashicorp-vault-as-your-pki-cert-manager-in-kubernetes-deep-dive-part-585a</link>
      <guid>https://dev.to/ingeniumcode/secure-http-traffic-with-hashicorp-vault-as-your-pki-cert-manager-in-kubernetes-deep-dive-part-585a</guid>
      <description>&lt;h1&gt;
  
  
  HashiCorp Vault as a Private Certificate Authority (PKI) with Kubernetes Integration
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;This technical guide walks through the first part of configuring HashiCorp Vault as a Private Certificate Authority (PKI) and integrating it with cert-manager in Kubernetes to automate certificate management. This setup enables internal applications to have HTTPS encryption in transit within a private network environment. The next article will cover the kubernetes part.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxpak3nt32lf259yaeslv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxpak3nt32lf259yaeslv.png" alt="Minio With Local HTTPS Certificate" width="800" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Main Benefits
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Centralized PKI Infrastructure
&lt;/h3&gt;

&lt;p&gt;Vault provides a centralized solution for managing your entire certificate lifecycle. Instead of managing certificates across different applications and services, Vault acts as a single source of truth for all your PKI needs. This centralization simplifies management, improves security posture, and ensures consistent certificate policies across your organization.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dynamic Certificate Issuance and Rotation
&lt;/h3&gt;

&lt;p&gt;Vault can automatically issue short-lived certificates and rotate them before expiration. When integrated with cert-manager in Kubernetes, this automation eliminates the manual certificate renewal process that often leads to outages from expired certificates. The system can continuously issue, renew, and rotate certificates without human intervention.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fine-grained Access Control
&lt;/h3&gt;

&lt;p&gt;Vault's advanced policy system allows you to implement precise access controls around who can issue what types of certificates. You can limit which teams or services can request certificates for specific domains, restrict certificate lifetimes based on risk profiles, and implement comprehensive audit logging. This helps enforce the principle of least privilege across your certificate infrastructure.&lt;/p&gt;

&lt;p&gt;An additional benefit is Vault's broader secret management capabilities – the same tool managing your certificates can also handle database credentials, API keys, and other sensitive information, giving you a unified approach to secrets management.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A DNS Server (I use my firewall)&lt;/li&gt;
&lt;li&gt;A running Kubernetes cluster (I am using microk8s)&lt;/li&gt;
&lt;li&gt;Vault server installed and initialized (vault 0.30.0 · hashicorp/hashicorp)&lt;/li&gt;
&lt;li&gt;cert-manager installed in your Kubernetes cluster (microk8s addon)&lt;/li&gt;
&lt;li&gt;Administrative access to both Vault and Kubernetes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;See my homelab diagram in GitHub: &lt;a href="https://github.com/mdf-ido/mdf-ido" rel="noopener noreferrer"&gt;mdf-ido/mdf-ido: Config files for my GitHub profile&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Configure Vault as a PKI
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1.1. Enable the PKI Secrets Engine
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Enable the PKI secrets engine&lt;/span&gt;
vault secrets &lt;span class="nb"&gt;enable &lt;/span&gt;pki
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frtqb0eaujy75sj3z0h20.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frtqb0eaujy75sj3z0h20.png" alt="Image description" width="800" height="399"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;PKI in Hashicorp Vault&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Configure the PKI secrets engine with a longer max lease time (e.g., 1 year)&lt;/span&gt;
vault secrets tune &lt;span class="nt"&gt;-max-lease-ttl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;8760h pki
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3vft7iwar7w0vsgiz3a1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3vft7iwar7w0vsgiz3a1.png" alt="Image description" width="800" height="558"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;PKI 1 year Expiration&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  1.2. Generate or Import Root CA
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Generate a new root CA&lt;/span&gt;
vault write &lt;span class="nt"&gt;-field&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;certificate pki/root/generate/internal &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;common_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Root CA"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;ttl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;87600h &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; root_ca.crt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;em&gt;Hashicorp Vault Root CA&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  1.3. Configure PKI URLs
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Configure the CA and CRL URLs&lt;/span&gt;
vault write pki/config/urls &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;issuing_certificates&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"http://vault.example.com:8200/v1/pki/ca"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;crl_distribution_points&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"http://vault.example.com:8200/v1/pki/crl"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8e19mtqidfar3kgqbl5s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8e19mtqidfar3kgqbl5s.png" alt="Image description" width="800" height="439"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Issuing and Certificate Request Links&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  1.4. Create an Intermediate CA
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fypmfduyhnpzi71n1az5j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fypmfduyhnpzi71n1az5j.png" alt="Image description" width="800" height="412"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Hashicorp Intermediate Certificate Authority&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Enable the intermediate PKI secrets engine&lt;/span&gt;
vault secrets &lt;span class="nb"&gt;enable&lt;/span&gt; &lt;span class="nt"&gt;-path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;pki_int pki

&lt;span class="c"&gt;# Set the maximum TTL for the intermediate CA&lt;/span&gt;
vault secrets tune &lt;span class="nt"&gt;-max-lease-ttl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;43800h pki_int

&lt;span class="c"&gt;# Generate a CSR for the intermediate CA&lt;/span&gt;
vault write &lt;span class="nt"&gt;-format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;json pki_int/intermediate/generate/internal &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;common_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Intermediate CA"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;ttl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;43800h &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; pki_intermediate.json

&lt;span class="c"&gt;# Extract the CSR&lt;/span&gt;
&lt;span class="nb"&gt;cat &lt;/span&gt;pki_intermediate.json | jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.data.csr'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; pki_intermediate.csr

&lt;span class="c"&gt;# Sign the intermediate CSR with the root CA&lt;/span&gt;
vault write &lt;span class="nt"&gt;-format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;json pki/root/sign-intermediate &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;csr&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;@pki_intermediate.csr &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;pem_bundle &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;ttl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;43800h &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; intermediate_cert.json

&lt;span class="c"&gt;# Extract the signed certificate&lt;/span&gt;
&lt;span class="nb"&gt;cat &lt;/span&gt;intermediate_cert.json | jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.data.certificate'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; intermediate.cert.pem

&lt;span class="c"&gt;# Import the signed certificate back into Vault&lt;/span&gt;
vault write pki_int/intermediate/set-signed &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;certificate&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;@intermediate.cert.pem
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  1.5. Create a Role for Certificate Issuance
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create a role for issuing certificates&lt;/span&gt;
vault write pki_int/roles/your-domain-role &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;allowed_domains&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"yourdomain.com"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;allow_subdomains&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;allow_bare_domains&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;allow_wildcard_certificates&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;max_ttl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;720h
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb7tlg6stchi6stywrtlh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb7tlg6stchi6stywrtlh.png" alt="Image description" width="598" height="703"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the next article I'll cover the kubernetes configs. &lt;/p&gt;

</description>
      <category>devops</category>
      <category>kubernetes</category>
      <category>platformengineering</category>
      <category>security</category>
    </item>
  </channel>
</rss>
