shimkit tls — container-first TLS certificate lifecycle via
upstream certbot. Third of the deferred v0.5+ candidates. For the
full machine-readable changelog, see
CHANGELOG.md.
shimkit tls request -d D --email E --webroot PATH # MODERATE
shimkit tls list # enumerate
shimkit tls status DOMAIN # one cert's paths + expiry
shimkit tls renew # MODERATE — all due
shimkit tls revoke -d D --confirm REVOKE-TLS # SEVERE
shimkit tls cron-install # MODERATE — daily renewal
Every certbot invocation is a one-shot through
certbot/certbot:v3.0.1. The /etc/letsencrypt directory is
bind-mounted from ~/.shimkit/data/tls/etc-letsencrypt/ so account
keys + cert state survive container exits and host reboots.
ACME issuance via webroot challenge:
docker run --rm \
-v ~/.shimkit/data/tls/etc-letsencrypt:/etc/letsencrypt \
-v ~/.shimkit/data/tls/var-lib-letsencrypt:/var/lib/letsencrypt \
-v <webroot>:/webroot:ro \
certbot/certbot:v3.0.1 \
certonly --non-interactive --agree-tos \
--email <you> --webroot -w /webroot \
-d <domain> [-d <san>] [--staging]
# Recommended first run — Let's Encrypt rate-limits production
# aggressively; staging is forgiving.
shimkit tls request --yes --staging \
--email ops@example.com \
--webroot /var/www/example \
-d example.com -d www.example.com
# Once staging works, the real cert.
shimkit tls request --yes \
--email ops@example.com \
--webroot /var/www/example \
-d example.com -d www.example.comReads ~/.shimkit/data/tls/etc-letsencrypt/live/<domain>/fullchain.pem
and parses the notAfter via host openssl x509 -enddate. Flags
certs within 30 days of expiry.
shimkit tls list
shimkit tls list --json
shimkit tls status example.comDefaults to all certs within Let's Encrypt's 30-day renewal window.
Pass --domain D for a single cert, or --force-renewal for a
test rotation.
shimkit tls renew --yes
shimkit tls renew --yes --force-renewal -d example.comInstalls a shimkit-managed cron entry that runs shimkit tls renew --yes --json daily at the configured schedule (default
03:17 — well off any on-the-hour cron herd).
shimkit tls cron-install --yes # default schedule
shimkit tls cron-install --yes --schedule "0 4 * * *"SEVERE — requires --confirm REVOKE-TLS. Revocation tells the
ACME CA the cert is no longer trusted; a separate operation from
deleting local files.
core/docker.DockerEnv.run_oneshot(image, command, ...)— new detached-then-waited container run that captures exit code + stdout + stderr and auto-removes on exit. Available to any future tool that needs one-shot container semantics.core/version.pyregisters anopenssldetector. The regex handles bothOpenSSLandLibreSSLstrings — macOS ships LibreSSL by default; brew can install OpenSSL alongside.tools.versions.opensslfloor at1.1.
- Webroot only. DNS-01 (required for wildcard certs) is opt-in
extras in a future release — each provider needs its own
credential surface (
cloudflare,route53, etc). - Staging recommended for first runs. Let's Encrypt production rate limits are punishing (5 failed validations / hour / hostname). The resulting staging cert isn't trusted but proves the webroot setup works.
- Tests: 561 → 609 (+48)
- Gates: pytest, ruff, mypy strict — all green
- New optional extras: 0 (reuses
[docker-clean]'sdocker)
uv tool upgrade shimkit
pipx upgrade shimkitOptional: set tools.tls.default_email in your user config to
drop --email from every shimkit tls request invocation.