{"record":{"id":"87afed0529ba8a2f","repo":"quarkusio/quarkus","slug":"leaf-certificate-must-not-have-crlsign-as-key-us","errorCode":null,"errorMessage":"Leaf certificate must not have 'cRLSign' as key usage","messagePattern":"Leaf certificate must not have 'cRLSign' as key usage","errorType":"exception","errorClass":"SpiffeConnectionException","httpStatus":null,"severity":"error","filePath":"extensions/spiffe-client/runtime/src/main/java/io/quarkus/spiffe/client/runtime/internal/SpiffeValidator.java","lineNumber":36,"sourceCode":"    }\n\n    static String validateLeaf(X509Certificate leaf) throws SpiffeConnectionException {\n        if (leaf.getBasicConstraints() != -1) {\n            throw new SpiffeConnectionException(\"Leaf certificate must not have CA flag set to true\");\n        }\n\n        boolean[] keyUsage = leaf.getKeyUsage();\n        if (keyUsage == null) {\n            throw new SpiffeConnectionException(\"Leaf certificate is missing the key usage extension\");\n        }\n        if (keyUsage.length < 1 || !keyUsage[0]) {\n            throw new SpiffeConnectionException(\"Leaf certificate must have 'digitalSignature' as key usage\");\n        }\n        if (keyUsage.length > 5 && keyUsage[5]) {\n            throw new SpiffeConnectionException(\"Leaf certificate must not have 'keyCertSign' as key usage\");\n        }\n        if (keyUsage.length > 6 && keyUsage[6]) {\n            throw new SpiffeConnectionException(\"Leaf certificate must not have 'cRLSign' as key usage\");\n        }\n\n        return extractAndValidateUriSan(leaf);\n    }\n\n    // X.509-SVID 3.2 SHOULD: signing cert SHOULD itself be an SVID (not enforced — upstream CA may not be SPIFFE-aware)\n    // 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)\n    static void validateIntermediate(X509Certificate cert) throws SpiffeConnectionException {\n        if (cert.getBasicConstraints() < 0) {\n            throw new SpiffeConnectionException(\n                    \"Signing certificate must have CA flag set to true: \" + cert.getSubjectX500Principal());\n        }\n        boolean[] keyUsage = cert.getKeyUsage();\n        if (keyUsage == null || keyUsage.length <= 5 || !keyUsage[5]) {\n            throw new SpiffeConnectionException(\n                    \"Signing certificate must have 'keyCertSign' as key usage: \" + cert.getSubjectX500Principal());\n        }\n        // X.509-SVID 3.2 MUST: if signing cert has a SPIFFE ID, it must not have a path component","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/spiffe-client/runtime/src/main/java/io/quarkus/spiffe/client/runtime/internal/SpiffeValidator.java#L18-L54","documentation":"When validating an X.509 SVID chain, Quarkus SPIFFE client requires that a leaf (end-entity) SVID certificate not have the cRLSign key usage bit set. cRLSign is reserved for certificates that sign certificate revocation lists; a leaf carrying it violates the X.509-SVID profile and could enable revocation-list forgery, so the validator rejects the chain with a SpiffeConnectionException.","triggerScenarios":"Calling the workload API / SPIFFE connection validation where the first certificate of the presented chain has keyUsage[6] (cRLSign) = true, e.g. a workload cert whose KeyUsage extension includes digitalSignature plus cRLSign.","commonSituations":"The certificate authority that issued the workload cert used an over-broad KeyUsage template (copying CA defaults), a misconfigured internal PKI that issues leaf certs with full key usage bits, or a non-SPIFFE-compliant CA minting SVIDs.","solutions":["Reissue the leaf SVID with a KeyUsage extension limited to digitalSignature (no cRLSign, no keyCertSign).","Fix the issuing CA / cert template so leaf certificates omit cRLSign and keyCertSign.","If you cannot fix the CA, use a SPIFFE-compliant workload API source (e.g. spire-agent) to obtain compliant SVIDs."],"exampleFix":"// before (openssl config for leaf)\nkeyUsage = digitalSignature, keyCertSign, cRLSign\n// after\nkeyUsage = digitalSignature","handlingStrategy":"validation","validationCode":"boolean[] ku = cert.getKeyUsage();\nif (ku != null && ku.length > 6 && ku[6]) {\n    throw new IllegalArgumentException(\"Leaf cert must not have cRLSign key usage\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    connection.establish();\n} catch (SpiffeConnectionException e) {\n    if (e.getMessage().contains(\"cRLSign\")) {\n        log.error(\"Leaf SVID has invalid key usage; reissue certificate\", e);\n    }\n    throw e;\n}","preventionTips":["Issue leaf SVIDs from a SPIFFE-compliant CA (e.g. SPIRE) with keyUsage=digitalSignature only","Audit cert templates so leaf certs never copy CA key usage bits","Inspect certificates with openssl x509 -noout -ext keyUsage before deploying"],"tags":["x509","certificate-validation","spiffe","tls"],"backgroundTag":"certificate-key-usage-violation","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}