Issuance policy & pre-issuance gates¶
What is checked before the HSM is ever asked to sign.
Every issuance path — REST, gRPC, CLI, ACME, SCEP/EST, CMP, BRSKI — funnels
through the same ordered stack of fail-closed gates. A gate that cannot
reach its dependency refuses the issuance rather than waving it through. Each
page documents one gate: what it enforces, how to set it to
off/permissive/enforce per profile, and the audit event and metric it
emits.
| Guide | Covers |
|---|---|
| CEL issuance restrictions | The operator-written half of the gate stack (Task 223): fail-closed CEL rules evaluated before every signature on every issuance path, over the certificate request (names, lifetime, subject, key), the verified claims of the caller's token, the request URL (as an object and as the full path) and its body parameters, and the caller's identity. A rule reports the reason the requester is shown — "requested 400 days; this profile allows at most 90" rather than "forbidden" — and is editable at runtime through the console's Signing Policy view, secsy-ca issuance-policy, or /api/issuance-policies, with a compile check, a dry-run against a real CSR, monitor mode, and an extensive function library (strings, regex, arrays/sets, math, IP/CIDR, encoding, time). The same engine gates the signatures that are not certificates — see CEL signing restrictions |
| Issuance preview (dry-run) | Validating a would-be issuance through the full fail-closed pre-issuance gate stack (lint/CAA/name-constraints/policy/S-MIME/key-checks/UPN/QC/validity + the four-eyes "would-park" and attestation-posture verdicts) without signing, allocating a serial, persisting a record, auditing, or taking a rate-limit/quota reservation — for operators and CI: secsy-ca issue -dry-run (exits non-zero if rejected), POST /api/ca/{id}/certificates:preview, gRPC PreviewCertificate, and the console Issue-page preview button; the gate evaluators are shared with real issuance so the verdict cannot drift |
| Pre-issuance certificate linting | The fail-closed pre-issuance lint gate: the dependency-free hand-rolled CA/Browser-Forum Baseline Requirements checks (always on) plus the optional industry-standard github.com/zmap/zlint backend compiled in only under -tags zlint (default/FIPS/supply-chain builds stay dependency-free), the per-profile lint.zlint level→enforce/warn/ignore mapping + source/name filters, the pre-issuance "linting certificate" synthesis, secsy-ca lint -zlint (PEM/DER) + /api/lint + console, the zlint/-namespaced findings in cert.lint audit + metrics, and the dependency / govulncheck -tags zlint implications |
| CAA record checking (RFC 8659) | DNS Certification Authority Authorization as a fail-closed pre-issuance gate on every issuance path: the tree-climbing + CNAME/DNAME algorithm, issue/issuewild/iodef evaluation against the CA identifier, per-profile off/permissive/enforce mode, the DNS-answer TTL cache, and the cert.caa audit event + Prometheus metrics |
| Name Constraints & Certificate Policies (RFC 5280) | First-class Name Constraints (2.5.29.30) and the certificate-policy family (2.5.29.32/.33/.36) on CAs: configuring permitted/excluded DNS/IP/email/URI/dirName subtrees and policy OIDs on roots/intermediates, per-profile leaf policy assignment, the fail-closed pre-issuance name-constraint gate (cert.nameconstraint audit + metrics), rotation preservation, and openssl verify interop |
| Weak-key & compromised-key gate | The fail-closed pre-issuance key-quality gate (CA/Browser Forum BR §6.1.1.3) on every issuance surface and the dry-run preview: ROCA/CVE-2017-15361 fingerprint detection, RSA exponent (e≥65537, odd) and modulus (odd, ≥2048-bit) policy, the optional operator-supplied Debian OpenSSL weak-key blocklist, an operator-managed compromised-key blocklist (secsy-ca blocked-keys, keyed by the SPKI SHA-256 fingerprint), and opt-in duplicate/reused-subject-key detection; per-profile enforce/warn, cert.keycheck audit + metrics, and doctor keychecks.* |
| Certificate Transparency (RFC 6962) | Optional precertificate submission and SCT embedding on the issuance path: registering CT logs, per-profile CT policy (min-SCTs, fail-open/closed, retries/timeouts), SCT signature verification, CT status in the console/API/audit log, and the leader-elected SCT inclusion-proof monitor (get-sth / get-proof-by-hash Merkle verification, log-misbehavior alerting, secsy-ca ct + doctor ct.inclusion) |
↩ Back to the documentation map · project README