mirror of
https://github.com/enix/x509-certificate-exporter.git
synced 2026-08-19 03:56:21 +00:00
docs(README, metrics): announce JKS/JCEKS support and x509_jks_passphrase_failures_total
This commit is contained in:
committed by
Thibault VINCENT
parent
17bf1dca2c
commit
a163963eeb
@@ -41,6 +41,7 @@ cluster it observes, but equally happy as a standalone binary.
|
||||
- **Memory-safe Kubernetes watch** — RAM stays flat instead of spiking; on Secret-heavy clusters, memory limits drop ~10×.
|
||||
- **Richer PKCS#12 wiring** — full keystore + truststore coverage, flexible passphrase sourcing.
|
||||
- **DER consumption** — raw cert / CRL blobs as served by HTTP CRL Distribution Points are now first-class inputs.
|
||||
- **JKS / JCEKS support** — Java KeyStore and JCEKS stores.
|
||||
- **CRL freshness monitoring** — Certificate Revocation Lists are tracked alongside certs, with alerts before they go stale.
|
||||
- **Surface workload metadata** — lift watched resource labels onto emitted certificate series.
|
||||
- **Supply-chain hardened** — SLSA Build L3 provenance, cosign-signed binaries, images and chart, SBOM attestations.
|
||||
@@ -55,6 +56,9 @@ cluster it observes, but equally happy as a standalone binary.
|
||||
- **PKCS#12** keystores and truststores, with passphrase pulled from a
|
||||
sibling key in the same Secret, an external file, a cross-namespace
|
||||
Secret reference, or none (`tryEmptyPassphrase`).
|
||||
- **JKS / JCEKS** keystores and truststores — magic-byte auto-detection
|
||||
between JKS and JCEKS; passphrase from a sibling key, external file,
|
||||
or `tryEmptyPassphrase`.
|
||||
- **Certificate Revocation Lists** — `X509 CRL` PEM blocks (intermixed
|
||||
freely with `CERTIFICATE` blocks) and raw DER `*.crl` files
|
||||
(`format: der`) are parsed into the dedicated `x509_crl_*` family so
|
||||
|
||||
+8
-5
@@ -50,6 +50,7 @@ cluster it observes, but equally happy as a standalone binary.
|
||||
- **Memory-safe Kubernetes watch** — RAM stays flat instead of spiking; on Secret-heavy clusters, memory limits drop ~10×.
|
||||
- **Richer PKCS#12 wiring** — full keystore + truststore coverage, flexible passphrase sourcing.
|
||||
- **DER consumption** — raw cert / CRL blobs as served by HTTP CRL Distribution Points are now first-class inputs.
|
||||
- **JKS / JCEKS support** — Java KeyStore and JCEKS stores.
|
||||
- **CRL freshness monitoring** — Certificate Revocation Lists are tracked alongside certs, with alerts before they go stale.
|
||||
- **Surface workload metadata** — lift watched resource labels onto emitted certificate series.
|
||||
- **Supply-chain hardened** — SLSA Build L3 provenance, cosign-signed binaries, images and chart, SBOM attestations.
|
||||
@@ -64,6 +65,9 @@ cluster it observes, but equally happy as a standalone binary.
|
||||
- **PKCS#12** keystores and truststores, with passphrase pulled from a
|
||||
sibling key in the same Secret, an external file, a cross-namespace
|
||||
Secret reference, or none (`tryEmptyPassphrase`).
|
||||
- **JKS / JCEKS** keystores and truststores — magic-byte auto-detection
|
||||
between JKS and JCEKS; passphrase from a sibling key, external file,
|
||||
or `tryEmptyPassphrase`.
|
||||
- **Certificate Revocation Lists** — `X509 CRL` PEM blocks (intermixed
|
||||
freely with `CERTIFICATE` blocks) and raw DER `*.crl` files
|
||||
(`format: der`) are parsed into the dedicated `x509_crl_*` family so
|
||||
@@ -165,15 +169,14 @@ The default install runs a single Deployment watching
|
||||
`kubernetes.io/tls` Secrets across all namespaces — disable with
|
||||
`secretsExporter.enabled: false`.
|
||||
|
||||
### Multiple Secret types, PKCS#12, and JKS
|
||||
### Multiple Secret types and PKCS#12
|
||||
|
||||
`secretsExporter.secretTypes` accepts any mix of types and keys: a
|
||||
literal `key` (regex `^<key>$` is built for you) or a `keyPatterns`
|
||||
list for full regex control, with optional `format: pkcs12` plus a
|
||||
`pkcs12:` block, or `format: jks` plus a `jks:` block. Passphrases
|
||||
are pulled from a sibling Secret key (`pkcs12.passphraseKey` /
|
||||
`jks.passphraseKey`), an external file, a cross-namespace Secret ref
|
||||
(pkcs12 only), or skipped entirely with `tryEmptyPassphrase: true` for
|
||||
`pkcs12:` block. Passphrases are pulled from a sibling Secret key
|
||||
(`pkcs12.passphraseKey`), an external file, a cross-namespace Secret
|
||||
ref, or skipped entirely with `tryEmptyPassphrase: true` for
|
||||
passwordless keystores.
|
||||
|
||||
### Watching ConfigMaps
|
||||
|
||||
@@ -50,6 +50,7 @@ cluster it observes, but equally happy as a standalone binary.
|
||||
- **Memory-safe Kubernetes watch** — RAM stays flat instead of spiking; on Secret-heavy clusters, memory limits drop ~10×.
|
||||
- **Richer PKCS#12 wiring** — full keystore + truststore coverage, flexible passphrase sourcing.
|
||||
- **DER consumption** — raw cert / CRL blobs as served by HTTP CRL Distribution Points are now first-class inputs.
|
||||
- **JKS / JCEKS support** — Java KeyStore and JCEKS stores.
|
||||
- **CRL freshness monitoring** — Certificate Revocation Lists are tracked alongside certs, with alerts before they go stale.
|
||||
- **Surface workload metadata** — lift watched resource labels onto emitted certificate series.
|
||||
- **Supply-chain hardened** — SLSA Build L3 provenance, cosign-signed binaries, images and chart, SBOM attestations.
|
||||
@@ -64,6 +65,9 @@ cluster it observes, but equally happy as a standalone binary.
|
||||
- **PKCS#12** keystores and truststores, with passphrase pulled from a
|
||||
sibling key in the same Secret, an external file, a cross-namespace
|
||||
Secret reference, or none (`tryEmptyPassphrase`).
|
||||
- **JKS / JCEKS** keystores and truststores — magic-byte auto-detection
|
||||
between JKS and JCEKS; passphrase from a sibling key, external file,
|
||||
or `tryEmptyPassphrase`.
|
||||
- **Certificate Revocation Lists** — `X509 CRL` PEM blocks (intermixed
|
||||
freely with `CERTIFICATE` blocks) and raw DER `*.crl` files
|
||||
(`format: der`) are parsed into the dedicated `x509_crl_*` family so
|
||||
|
||||
+19
-19
@@ -1188,6 +1188,25 @@
|
||||
],
|
||||
"required": []
|
||||
},
|
||||
"jks": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"passphrase": {
|
||||
"type": "string"
|
||||
},
|
||||
"passphraseFile": {
|
||||
"type": "string"
|
||||
},
|
||||
"passphraseKey": {
|
||||
"type": "string"
|
||||
},
|
||||
"tryEmptyPassphrase": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"required": [],
|
||||
"type": "object"
|
||||
},
|
||||
"key": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -1235,25 +1254,6 @@
|
||||
"required": [],
|
||||
"type": "object"
|
||||
},
|
||||
"jks": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"passphrase": {
|
||||
"type": "string"
|
||||
},
|
||||
"passphraseFile": {
|
||||
"type": "string"
|
||||
},
|
||||
"passphraseKey": {
|
||||
"type": "string"
|
||||
},
|
||||
"tryEmptyPassphrase": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"required": [],
|
||||
"type": "object"
|
||||
},
|
||||
"type": {
|
||||
"minLength": 1,
|
||||
"type": "string"
|
||||
|
||||
+21
-4
@@ -37,6 +37,7 @@ The exporter splits its output into four families:
|
||||
| Per-source | `x509_source_errors_total` | counter | always |
|
||||
| Per-source | `x509_kube_watch_resyncs_total` | counter | Kubernetes sources only |
|
||||
| Per-source | `x509_pkcs12_passphrase_failures_total` | counter | auto: when any source declares `format: pkcs12` |
|
||||
| Per-source | `x509_jks_passphrase_failures_total` | counter | auto: when any source declares `format: jks` |
|
||||
| Per-source | `x509_cert_collision_total` | counter | always |
|
||||
| Diagnostic | `x509_parse_duration_seconds` | histogram | `metrics.exposeDiagnostics: true` |
|
||||
| Diagnostic | `x509_kube_request_duration_seconds` | histogram | `metrics.exposeDiagnostics: true`, Kubernetes sources only |
|
||||
@@ -410,6 +411,21 @@ was wrong.
|
||||
A spike usually means a Secret was rotated but the sibling passphrase
|
||||
key wasn't, or a `passphraseFile` was stale.
|
||||
|
||||
### `x509_jks_passphrase_failures_total`
|
||||
|
||||
JKS / JCEKS keystore decoding attempts that failed because the passphrase
|
||||
was wrong.
|
||||
|
||||
- **Type**: counter
|
||||
- **Labels**: `source_name`
|
||||
- **Auto-gated**: registered only when at least one source declares
|
||||
`format: jks` (file source `formats:`, kubernetes source
|
||||
`secrets.types[].format`, or `configMaps.format`). Deployments
|
||||
without JKS don't see the metric in `/metrics` at all.
|
||||
|
||||
A spike usually means a Secret was rotated but the sibling passphrase
|
||||
key wasn't, or a `passphraseFile` was stale.
|
||||
|
||||
### `x509_cert_collision_total`
|
||||
|
||||
Number of times the registry detected two distinct certificates that
|
||||
@@ -512,9 +528,9 @@ etc.) into the internal certificate representation.
|
||||
- **Buckets**: `0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 5` seconds
|
||||
- **Emitted only when `metrics.exposeDiagnostics` is `true`.**
|
||||
|
||||
`format` takes one of `pem` or `pkcs12`. PKCS#12 is meaningfully slower
|
||||
because of the KDF — expect millisecond-range parse times on PEM and
|
||||
double-digit-millisecond on PKCS#12.
|
||||
`format` takes one of `pem`, `pkcs12`, `der`, or `jks`. PKCS#12 and JKS are
|
||||
meaningfully slower because of their KDF — expect millisecond-range parse
|
||||
times on PEM/DER and double-digit-millisecond on PKCS#12/JKS.
|
||||
|
||||
### `x509_kube_request_duration_seconds`
|
||||
|
||||
@@ -604,7 +620,8 @@ metrics provider with the synthetic `source_kind="kubernetes"`,
|
||||
| `bad_pem` | any source running the PEM parser (file, kubeconfig, kube-secret with `format: pem`, kube-configmap) | PEM block present but malformed |
|
||||
| `no_certificate_found` | same | The bundle decoded successfully but contained no `CERTIFICATE` block |
|
||||
| `bad_pkcs12` | any source running the PKCS#12 parser (file with `formats: [pkcs12]`, kube-secret / kube-configmap with `format: pkcs12`) | PKCS#12 archive malformed or uses an unsupported algorithm |
|
||||
| `bad_passphrase` | same | PKCS#12 archive structurally valid but the configured passphrase was wrong |
|
||||
| `bad_jks` | any source running the JKS parser (file with `formats: [jks]`, kube-secret / kube-configmap with `format: jks`) | JKS / JCEKS archive malformed or magic bytes not recognised |
|
||||
| `bad_passphrase` | PKCS#12 or JKS parser | Archive structurally valid but the configured passphrase was wrong |
|
||||
| `read_failed` | `file`, `kubeconfig` | Generic I/O error opening or reading a file |
|
||||
| `permission_denied` | `file` | EACCES on a watched path |
|
||||
| `not_found` | `file` | Path disappeared between announcement and read |
|
||||
|
||||
Reference in New Issue
Block a user