quarkusio/quarkus · critical · SpiffeConnectionException
Leaf certificate must not have 'keyCertSign' as key usage
Error message
Leaf certificate must not have 'keyCertSign' as key usage
What it means
A leaf workload certificate must not be able to sign other certificates. If KeyUsage includes the keyCertSign bit, the certificate could act as a CA and the validator rejects it to enforce the SPIFFE X.509-SVID profile. This protects against privilege escalation if the workload's key is compromised.
Source
Thrown at extensions/spiffe-client/runtime/src/main/java/io/quarkus/spiffe/client/runtime/internal/SpiffeValidator.java:33
private static final int MAX_TRUST_DOMAIN_LENGTH = 255;
private SpiffeValidator() {
}
static String validateLeaf(X509Certificate leaf) throws SpiffeConnectionException {
if (leaf.getBasicConstraints() != -1) {
throw new SpiffeConnectionException("Leaf certificate must not have CA flag set to true");
}
boolean[] keyUsage = leaf.getKeyUsage();
if (keyUsage == null) {
throw new SpiffeConnectionException("Leaf certificate is missing the key usage extension");
}
if (keyUsage.length < 1 || !keyUsage[0]) {
throw new SpiffeConnectionException("Leaf certificate must have 'digitalSignature' as key usage");
}
if (keyUsage.length > 5 && keyUsage[5]) {
throw new SpiffeConnectionException("Leaf certificate must not have 'keyCertSign' as key usage");
}
if (keyUsage.length > 6 && keyUsage[6]) {
throw new SpiffeConnectionException("Leaf certificate must not have 'cRLSign' as key usage");
}
return extractAndValidateUriSan(leaf);
}
// X.509-SVID 3.2 SHOULD: signing cert SHOULD itself be an SVID (not enforced — upstream CA may not be SPIFFE-aware)
// X.509-SVID 3.2 SHOULD: signing cert SHOULD reside in the trust domain of leaf SVIDs it issues (not enforced — cross-domain signing is allowed)
static void validateIntermediate(X509Certificate cert) throws SpiffeConnectionException {
if (cert.getBasicConstraints() < 0) {
throw new SpiffeConnectionException(
"Signing certificate must have CA flag set to true: " + cert.getSubjectX500Principal());
}
boolean[] keyUsage = cert.getKeyUsage();
if (keyUsage == null || keyUsage.length <= 5 || !keyUsage[5]) {
throw new SpiffeConnectionException(View on GitHub (pinned to e1c734241f)
Solutions
- Serve a proper end-entity SVID without CA flags or CA usages from the SPIRE agent.
- Check the leaf: openssl x509 -noout -ext keyUsage — remove keyCertSign from workload cert templates.
- Separate your CA chain (trust bundle) from the leaf chain in custom code paths.
- Verify SPIRE server registration entries map to workload profiles, not CA profiles.
Example fix
// before -addext "keyUsage=digitalSignature,keyCertSign" // after -addext "keyUsage=digitalSignature,keyEncipherment"
Defensive patterns
Strategy: validation
Validate before calling
static boolean lacksKeyCertSign(X509Certificate leaf) {
boolean[] ku = leaf.getKeyUsage();
return ku == null || ku.length <= 5 || !ku[5];
} Type guard
static boolean isNotCaCapable(X509Certificate cert) {
boolean[] ku = cert.getKeyUsage();
return cert.getBasicConstraints() == -1 && (ku == null || ku.length <= 5 || !ku[5]);
} Try / catch
try {
SpiffeValidator.validateLeaf(leaf);
} catch (SpiffeConnectionException e) {
throw new SecurityException("Leaf must not have keyCertSign usage: " + e.getMessage(), e);
} Prevention
- Never feed CA/intermediate certificates into leaf validation
- Strip CA usages from workload certificate templates
- Separate trust-bundle handling from SVID-chain handling in custom code
- Confirm SPIRE registration entries issue end-entity profiles
When it happens
Trigger: Validation encountering a leaf whose KeyUsage asserts keyCertSign (bit 5), e.g. a self-signed CA certificate or an intermediate passed in as the leaf.
Common situations: Testing with self-signed CA certs as if they were SVIDs; upstream CA templates leaking CA usages into workload certs; accidentally passing a bundle/intermediate where a leaf is expected.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- Leaf certificate is missing the key usage extension
- Leaf certificate must not have CA flag set to true
- Leaf certificate must have 'digitalSignature' as key usage
- Leaf certificate must not have 'cRLSign' as key usage
- Signing certificate must have 'keyCertSign' as key usage: ${
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/e4f301fcfaafe832.
Report an issue: GitHub.