feat(security): replace the leaked CA, and add tooling to issue certs - #34
Merged
Conversation
The previous CA and leaf keys were committed to a public repository and removed by rewriting every commit. This replaces them and makes issuing a certificate a command rather than a research project. scripts/gen-certs.sh creates the CA once, issues leaves signed by it, and lists what exists with expiry. It refuses to clobber an existing CA — regenerating one invalidates every leaf it has signed and every trust store holding it — and verifies each issued certificate against the CA before reporting success, so a chain that does not build fails at issue time rather than at deploy time. Two limits are enforced rather than left to be discovered. A certificate with no subjectAltName is rejected by every current browser and by Go's crypto/tls, which is what Prometheus, Alertmanager and Grafana are built on; the error names the Common Name field and reads like a trust problem. And leaf lifetimes over 825 days are rejected by browsers, so a ten-year leaf looks like less future work and produces something nothing will trust. Naming follows the lab as it exists now — matrix.elysium, matching pfSense's own hostname — rather than the Gandalf.Gondor.Lab of the leaked set. Nothing terminates TLS yet, so this issues no promises: Grafana is the first candidate and that roadmap item now says wiring rather than PKI. Also closes two gaps the leak should have already taught us: certificates/ is added to the never-tracked assertion in CI and validate.sh. It is the one directory whose contents forced a history rewrite and it was not on that list. certificates/ and .rendered/ are allowlisted for the gitleaks filesystem scan. Both hold real secrets on purpose and are gitignored, so on any host that has actually deployed the scan reported eight findings that were all working as designed. CI scans a fresh checkout and never saw them. gitleaks was never the control there — never becoming a tracked file is, and that is asserted directly. Refs docs/runbooks/generate-certificates.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Replaces the CA and leaf keys that were purged from history, and adds the tooling to issue more.
What changed
scripts/gen-certs.sh— create the CA, issue leaves, list what existsmake certs ARGS=...docs/runbooks/generate-certificates.mdcertificates/added to the never-tracked assertions in CI andvalidate.shcertificates/and.rendered/allowlisted for the gitleaks filesystem scanWhy
The old CA and leaf keys were committed to a public repository and removed by
rewriting every commit. They have to be treated as compromised, so they needed
replacing — and there was no tooling at all, which is how a lab ends up
improvising a CA on the day something needs one.
Nothing terminates TLS yet. Prometheus, Alertmanager, Loki and Grafana all
publish plain HTTP. So this deliberately promises nothing: it creates the CA
deliberately and once, and the Grafana-TLS roadmap item now reads as wiring
rather than PKI.
Naming follows the lab as it is today —
matrix.elysium, matching pfSense’s ownhostname — rather than the
Gandalf.Gondor.Labof the leaked set.Two failure modes the script enforces rather than lets you discover
subjectAltName→ rejected outright by every current browser and byGo’s
crypto/tls, which is what this stack is built on. The error names theCommon Name field and reads like a trust problem rather than a missing one.
like less future work and produces something nothing will trust.
Every issued certificate is verified against the CA before success is reported.
Two gaps the original leak should have taught us
certificates/was not on the never-tracked list — the one directory whosecontents forced a history rewrite. Now asserted by CI and
make validate.make validatewas permanently red on any host that had actually deployed.The gitleaks filesystem scan reported 8 findings — the new CA and leaf keys, and
the decrypted SNMP communities in
.rendered/. All gitignored, all working asdesigned, none visible to CI because it scans a fresh checkout. Allowlisting
them is not a weakening: gitleaks was never the control there, never becoming a
tracked file is, and that is asserted directly. A check that is permanently red
for a known reason is a check nobody reads — the same argument that retired
.gitleaksignore.Blast radius
Nothing deployed changes. No service, no config, no port, no credential in
secrets/. The generated keys are gitignored and local to the monitoring host.secrets/*.sops.yamlVerification
Certificate checked by hand, not just by exit status: SAN carries both
DNS:grafana.matrix.elysiumandIP:10.0.99.20;basicConstraints CA:FALSEcritical;
keyUsagedigitalSignature + keyEncipherment; EKU serverAuth; chainverifies against the CA; public key matches the private key. CA is
CA:TRUE, pathlen:0with keyCertSign/cRLSign.Guard rails exercised: leaf-before-CA refused, CA clobber refused, leaf clobber
refused,
--days 3650refused../scripts/validate.shpasses. gitleaks clean on both the working tree (withthe keys present on disk) and full history.
shellcheckandmarkdownlint-cli2clean. Nothing undercertificates/appears ingit status.make validatepasses