TL;DR — Résumé Rapide

step-ca transforme n'importe quel serveur en AC privée pour TLS interne, mTLS et certificats SSH. Guide complet installation, provisioners, ACME et production.

step-ca est une autorité de certification privée open source de Smallstep qui vous permet d’exploiter votre propre PKI pour le TLS interne, le mTLS entre microservices et les certificats SSH, sans envoyer de trafic vers une AC publique. Si vous avez déjà eu des difficultés avec Let’s Encrypt sur des domaines privés, des avertissements de certificats auto-signés ou la distribution de la confiance sur des dizaines de services, step-ca résout chacun de ces problèmes avec une conception moderne orientée automatisation. Ce guide couvre le cycle complet : pourquoi vous avez besoin d’une AC privée, l’architecture, l’installation, les provisioners, ACME pour le renouvellement automatique, les certificats SSH et un déploiement HA en production.

Pourquoi une AC Privée ?

Les AC publiques comme Let’s Encrypt exigent la validation du domaine sur l’internet public. Cela exclut immédiatement :

  • Noms d’hôtes internespostgres.internal, api.corp ou tout domaine .local / .corp
  • mTLS pour les microservices — le mTLS exige que chaque service présente un certificat client ; émettre des milliers de certificats de service de courte durée depuis une AC publique est impraticable et coûteux
  • Réseaux à confiance zéro — chaque connexion authentifiée par certificat, pas par position réseau
  • Environnements air-gapped — aucun accès à l’internet public
  • Service mesh sans sidecars — TLS natif entre services utilisant des certificats step-ca, évitant la surcharge d’un déploiement Istio ou Linkerd complet

step-ca comble ce vide avec un serveur compatible ACME, des durées de vie courtes (24 heures par défaut), des daemons de renouvellement automatique et une intégration de premier plan avec Kubernetes via le webhook autocert et le step-issuer de cert-manager.

Architecture

┌─────────────────────────────────────────────┐
│             serveur step-ca                 │
│  ┌──────────┐  ┌─────────────┐              │
│  │  AC Racine│→ │AC Intermédiaire            │
│  │(hors ligne│  │             │              │
│  └──────────┘  └──────┬──────┘              │
│                       │ signe               │
│  ┌────────────────────▼──────────────────┐  │
│  │            Provisioners               │  │
│  │  JWK │ ACME │ OIDC │ AWS │ K8sSA │…  │  │
│  └───────────────────────────────────────┘  │
└─────────────────────────────────────────────┘
         ↑ API HTTPS (port 9000)
    ┌────┴────┐
    │step CLI │  certbot  Caddy  Traefik  cert-manager
    └─────────┘

L’AC racine signe uniquement le certificat de l’AC intermédiaire. En production, conservez la clé racine hors ligne. L’AC intermédiaire est celle avec laquelle step-ca fonctionne au quotidien. Les provisioners sont les mécanismes d’authentification qui contrôlent l’émission des certificats.

Installation

Binaire (Linux/macOS)

# step CLI
wget https://github.com/smallstep/cli/releases/latest/download/step_linux_amd64.tar.gz
tar xzf step_linux_amd64.tar.gz && sudo mv step /usr/local/bin/

# step-ca serveur
wget https://github.com/smallstep/certificates/releases/latest/download/step-ca_linux_amd64.tar.gz
tar xzf step-ca_linux_amd64.tar.gz && sudo mv step-ca /usr/local/bin/

macOS (Homebrew)

brew install step
brew install step-ca

Docker

docker run -v step:/home/step \
  -p 9000:9000 \
  -e "DOCKER_STEPCA_INIT_NAME=AC Interne" \
  -e "DOCKER_STEPCA_INIT_DNS_NAMES=ca.internal,localhost" \
  -e "DOCKER_STEPCA_INIT_REMOTE_MANAGEMENT=true" \
  smallstep/step-ca

Kubernetes (Helm + autocert)

helm repo add smallstep https://smallstep.github.io/helm-charts
helm install step-certificates smallstep/step-certificates \
  --set ca.name="AC Interne" \
  --set ca.dns="step-certificates.default.svc.cluster.local"

Configuration Initiale : step ca init

step ca init \
  --name "AC Corporative" \
  --dns ca.corp.internal \
  --address :9000 \
  --provisioner admin@corp.internal

Cela crée sous $(step path)/ :

  • certs/root_ca.crt — certificat AC racine (à distribuer à tous les clients)
  • certs/intermediate_ca.crt — certificat intermédiaire
  • secrets/root_ca_key — clé privée AC racine (à conserver hors ligne)
  • secrets/intermediate_ca_key — clé intermédiaire (utilisée par le serveur)
  • config/ca.json — configuration du serveur

Démarrez le serveur :

step-ca $(step path)/config/ca.json

Pour la production, créez une unité systemd :

[Unit]
Description=Smallstep CA
After=network.target

[Service]
User=step
ExecStart=/usr/local/bin/step-ca /etc/step-ca/config/ca.json
Restart=always
RestartSec=5
Environment=STEPPATH=/etc/step-ca

[Install]
WantedBy=multi-user.target

Provisioners

Les provisioners sont des plugins d’authentification. Ajoutez-en avec :

step ca provisioner add <nom> --type <TYPE>

JWK — Interactif / Basé sur des Scripts

Le provisioner par défaut. Les clients s’authentifient avec un JSON Web Token :

step ca certificate api.internal api.crt api.key

ACME — Automatisé (Caddy, Nginx, certbot)

step ca provisioner add acme --type ACME

Exemple avec certbot :

certbot certonly \
  --server https://ca.internal:9000/acme/acme/directory \
  --standalone \
  -d api.internal \
  --agree-tos -m admin@corp.internal

Caddy dans le Caddyfile :

api.internal {
  tls {
    ca https://ca.internal:9000/acme/acme/directory
  }
  reverse_proxy localhost:8080
}

OIDC — Basé sur le SSO

step ca provisioner add google --type OIDC \
  --client-id <GOOGLE_CLIENT_ID> \
  --client-secret <SECRET> \
  --configuration-endpoint https://accounts.google.com/.well-known/openid-configuration

Identité d’Instance Cloud (AWS / GCP / Azure)

step ca provisioner add aws --type AWS --aws-account 123456789012
step ca provisioner add gcp --type GCP --gcp-project mon-projet
step ca provisioner add azure --type Azure --azure-tenant <TENANT_ID>

Comptes de Service Kubernetes (K8sSA)

step ca provisioner add k8s --type K8sSA \
  --public-key /var/run/secrets/kubernetes.io/serviceaccount/public-key.pub

Émission de Certificats

# ECDSA P-256 (par défaut) avec SANs
step ca certificate api.internal api.crt api.key \
  --san api.corp --san 10.0.1.50

# Ed25519
step ca certificate api.internal api.crt api.key --kty OKP --crv Ed25519

# RSA 4096 (compatibilité legacy)
step ca certificate api.internal api.crt api.key --kty RSA --size 4096

# Certificat de courte durée (1 heure)
step ca certificate api.internal api.crt api.key --not-after 1h

Certificats SSH

# Certificat utilisateur SSH
step ssh certificate utilisateur@corp.internal id_ecdsa --provisioner google

# Certificat hôte SSH
step ssh certificate --host api.internal ssh_host_ecdsa_key --provisioner aws

Configurez sshd :

TrustedUserCAKeys /etc/ssh/step_user_ca.pub
HostCertificate /etc/ssh/ssh_host_ecdsa_key-cert.pub
HostKey /etc/ssh/ssh_host_ecdsa_key

Renouvellement et Révocation

Renouvellement Automatique (—daemon)

step ca renew --daemon api.crt api.key

Dans un service systemd :

ExecStartPost=/usr/local/bin/step ca renew --daemon \
  /etc/tls/service.crt /etc/tls/service.key \
  --exec "systemctl reload mon-service"

Révocation

Révocation passive — la courte durée de vie des certificats rend la révocation implicite.

Révocation active :

step ca revoke --serial 1234567890abcdef

Backends de Base de Données et Haute Disponibilité

BackendPar défautHACas d’usage
BadgerOuiNonInstance unique, dev/petites équipes
PostgreSQLNonOuiProduction multi-répliques
MySQLNonOuiProduction multi-répliques
"db": {
  "type": "postgresql",
  "dataSource": "postgresql://stepca:password@pg.internal:5432/stepca?sslmode=require"
}

Comparaison : Options d’AC Privée

OutilServeur ACMECerts SSHProvisionersHAFacilitéLicence
step-caOui (intégré)Oui8 typesOui (BD ext.)HauteApache 2
CFSSLNonNonAucunOuiMoyenneBSD
Vault PKIVia pluginVia Vault SSHVia Vault authOui (Raft)FaibleBSL
EJBCAOuiNonNombreuxOuiTrès faibleLGPL / EE
Let’s EncryptOui (public)NonACME seulementN/ATrès hauteN/A
mkcertNonNonAucunNonTrès hauteMIT

Pièges et Cas Particuliers

Décalage d’horloge — step-ca rejette les CSR si l’horloge du client diffère de plus de quelques minutes. Assurez-vous que NTP est actif sur tous les nœuds.

Protection de la clé AC racine — après step ca init, déplacez root_ca_key hors ligne. La clé intermédiaire est tout ce dont step-ca a besoin pour fonctionner.

ACME et SANs d’adresse IP — les challenges ACME HTTP-01 et DNS-01 fonctionnent pour les noms de domaine. Pour les SANs d’adresse IP, utilisez directement le step CLI.

Transparence des certificats — contrairement aux AC publiques, step-ca ne soumet pas les certificats aux journaux CT. C’est souhaitable pour l’infrastructure interne.

Gestion des mots de passe de provisioner — stockez les mots de passe dans un gestionnaire de secrets. Ne les codez jamais en dur dans les scripts.

Résumé

  • step-ca exécute une PKI privée complète : AC racine, AC intermédiaire et API REST pour l’émission de certificats
  • Utilisez des certificats de courte durée (24h par défaut) et le renouvellement avec --daemon plutôt que CRL/OCSP
  • Le provisioner ACME fait de step-ca une AC interne compatible avec Caddy, Nginx, Traefik et certbot
  • Les provisioners cloud (AWS, GCP, Azure) permettent le bootstrap d’identité workload sans secrets partagés
  • K8sSA et l’intégration cert-manager automatisent le TLS par pod dans Kubernetes sans sidecars
  • Les certificats SSH de step-ca éliminent la gestion individuelle de known_hosts par serveur
  • Pour la HA, passez le backend à PostgreSQL et exécutez plusieurs répliques derrière un répartiteur de charge
  • Conservez la clé AC racine hors ligne ; faites pivoter la clé intermédiaire indépendamment si compromise

Articles Connexes