areas/devops/networking/skills/tls-termination/SKILL.md
Configure TLS termination with cert-manager — Let's Encrypt, internal CA via Vault PKI, wildcard certs, mTLS between services.
npx skillsauth add sawrus/agent-guides tls-terminationInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Expertise: cert-manager ClusterIssuer, Let's Encrypt ACME (HTTP-01 + DNS-01), Vault PKI, cert rotation, mTLS.
When setting up TLS for a new service, debugging certificate issuance, rotating certificates, or implementing mTLS.
# ClusterIssuer — Let's Encrypt production
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: [email protected]
privateKeySecretRef:
name: letsencrypt-prod-key
solvers:
- http01:
ingress:
class: nginx # must match ingressClassName in Ingress
---
# Staging issuer (for testing — no rate limits)
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
spec:
acme:
server: https://acme-staging-v02.api.letsencrypt.org/directory
email: [email protected]
privateKeySecretRef:
name: letsencrypt-staging-key
solvers:
- http01:
ingress:
class: nginx
# Requires DNS provider API credentials
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-dns
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: [email protected]
privateKeySecretRef:
name: letsencrypt-dns-key
solvers:
- dns01:
cloudflare:
email: [email protected]
apiTokenSecretRef:
name: cloudflare-api-token
key: api-token
---
# Wildcard certificate
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: wildcard-example-com
namespace: production
spec:
secretName: wildcard-example-com-tls
issuerRef:
name: letsencrypt-dns
kind: ClusterIssuer
dnsNames:
- "*.example.com"
- "example.com"
# ClusterIssuer backed by HashiCorp Vault
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: vault-pki
spec:
vault:
server: https://vault.infra.svc.cluster.local:8200
path: pki/sign/internal-services
auth:
kubernetes:
mountPath: /v1/auth/kubernetes
role: cert-manager
secretRef:
name: cert-manager-vault-token
key: token
---
# Internal service certificate (short-lived, auto-rotated)
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: payment-service-tls
namespace: production
spec:
secretName: payment-service-tls
issuerRef:
name: vault-pki
kind: ClusterIssuer
duration: 24h # short-lived internal certs
renewBefore: 8h # renew 8h before expiry
dnsNames:
- payment-service.production.svc.cluster.local
- payment-service.production
# Check certificate status
kubectl get certificate -A
kubectl describe certificate <name> -n <ns>
# Look for: Conditions: Ready=True / reason for failure in Events
# Check CertificateRequest and Order (debugging ACME)
kubectl get certificaterequest -n <ns>
kubectl describe certificaterequest <n> -n <ns>
kubectl get order -n <ns>
kubectl describe order <n> -n <ns>
# Test ACME challenge reachability
curl -v http://<domain>/.well-known/acme-challenge/test
# Check TLS certificate details
echo | openssl s_client -connect api.example.com:443 -servername api.example.com 2>/dev/null \
| openssl x509 -noout -text | grep -E "Subject:|DNS:|Not After"
# Check cert expiry for all ingresses
kubectl get secret -A -o json | jq -r '
.items[] | select(.type == "kubernetes.io/tls") |
"\(.metadata.namespace)/\(.metadata.name)"' | while read secret; do
ns=$(echo $secret | cut -d/ -f1)
name=$(echo $secret | cut -d/ -f2)
kubectl get secret $name -n $ns -o jsonpath='{.data.tls\.crt}' | \
base64 -d | openssl x509 -noout -enddate -subject 2>/dev/null | \
awk -v s="$secret" '{print s": "$0}'
done
# Each service gets a client cert for mTLS
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: order-service-client-cert
namespace: production
spec:
secretName: order-service-client-tls
issuerRef:
name: vault-pki
kind: ClusterIssuer
duration: 24h
usages:
- client auth # mTLS client usage
- digital signature
subject:
organizations: [mycompany]
commonName: order-service.production
# Python: use client cert for mTLS call to upstream
import httpx
client = httpx.Client(
cert=("/var/run/secrets/tls/tls.crt", "/var/run/secrets/tls/tls.key"),
verify="/var/run/secrets/ca/ca.crt", # internal CA bundle
)
response = client.get("https://payment-service.production.svc.cluster.local:8443/charge")
testing
QA Expert for writing E2E tests, test scenarios, test plans, and ensuring test coverage quality.
development
Expert UI/UX design intelligence for creating distinctive, high-craft, and mobile-first interfaces. Focuses on premium aesthetics, touch-first ergonomics, and Flutter performance.
development
Code Review Expert for static analysis, security auditing, architecture review, and ensuring code quality standards.
development
Babysit a GitHub pull request after creation by continuously polling review comments, CI checks/workflow runs, and mergeability state until the PR is merged/closed or user help is required. Diagnose failures, retry likely flaky failures up to 3 times, auto-fix/push branch-related issues when appropriate, and keep watching open PRs so fresh review feedback is surfaced promptly. Use when the user asks Codex to monitor a PR, watch CI, handle review comments, or keep an eye on failures and feedback on an open PR.