Skip to content

Issuance policies

Issuance policies are rules evaluated on every certificate request, across all profiles, that can require approval or block a request according to its context: names, wildcard, environment, key algorithm, profile, organization. They complement the rules of each certificate profile.

Manage them in the Administration workspace, Governance > Issuance policies. The page and its API are reserved to administrators.

Issuance policies

Principles

  • The first matching rule wins. Enabled rules are evaluated by ascending Priority (then by creation order). If no rule matches, the request is allowed.
  • A rule can only harden. Effects are Require approval, Block and Allow (exempt). None of them removes an approval that the profile already requires. Allow only stops the evaluation, so that later rules do not apply to the requests it matches.
  • Block applies everywhere: web interface, API, and requests arriving through ACME, EST, SCEP and CMP, at issuance and at renewal.
  • Require approval applies to interactive requests only. A request counts as a protocol request when it actually arrives through the ACME, EST, SCEP or CMP gateway (not merely because the profile accepts one of these protocols). On a protocol request there is nobody to approve: the request goes through and the audit trail records POLICY_AUTO_ALLOWED with the outcome failure, so that a skipped human check stands out in the SIEM.
  • Renewal. Blocking rules always apply at renewal, so a name that has become forbidden stops renewing. Require approval rules apply at renewal only when the renewal changes the identity of the certificate (a different CN, or a SAN that the previous certificate did not have): such a renewal is treated like a new request for those names. A renewal with the same names stays automatic.
  • Fail-closed at issuance. If the rules cannot be evaluated (database error, for example), POLICY_EVAL_ERROR is recorded; an interactive request is sent to approval, and a protocol request (ACME, EST, SCEP, CMP) is refused, since nobody could approve it. The client can retry later.
  • Bounded tolerance at renewal. If the rules cannot be evaluated during a renewal, the renewal goes through only when the certificate is close to its expiry (7 days by default, set by the POLICY_RENEW_FAILOPEN_DAYS environment variable of the backend; an already expired certificate counts as close). Other renewals are refused and retried later. The error is recorded in both cases.

Rule conditions

All the conditions you fill in must match (logical AND); an empty condition matches everything.

Field Matches when Example
CN pattern (glob) — empty = all The CN or any SAN matches the pattern (case-insensitive). The names are those of the request and those of the CSR *.prod.example.com
Wildcard Yes (wildcard only): a name starts with *.. No (non-wildcard only): none does. Any Yes
Environment (comma list or 'any') The environment deduced from the names is in the list prod,preprod
Algorithm (prefix) — empty = all The key algorithm starts with the value (case-insensitive). ECC, ECDSA and EC all match any elliptic-curve key. When the request carries a CSR, the algorithm of the actual key in the CSR is evaluated, not the algorithm declared in the request RSA matches RSA-2048; ML-DSA matches ML-DSA-65
Profile ID (optional) The request uses that profile (numeric identifier; the list shows the profile name) 4
Organization ID (optional) The certificate belongs to that organization (numeric identifier; the list shows the organization name) 2

Each rule also has a Name (required), a Priority (100 by default; lower numbers are evaluated first), an Effect and an Enabled check box.

The Message (shown in audit / to the approver) explains the decision: it is shown to the requester when the rule blocks, and to the approver when it requires approval.

How the environment is deduced

The environment comes from markers in the names (CN, SANs), with the same classifier as the crypto posture. A name with no marker is not assumed to be production.

Environment value Markers in the name (examples)
dev dev-, -dev, dev., .dev, develop, feature-
test test, -qa, qa-, .qa, recette, .rec, integration, -int, e2e
lab .lab., .lab, lab., -lab, lab-
preprod preprod, pre-prod, staging, -stage, stage-, uat
prod prod, -prd, prd-, .prd

Names marked as ephemeral (sandbox, tmp-, temp-, and similar) get their own class, éphémère. The markers are matched as substrings: product.example.com is classified prod, latest.example.com is classified test. Check the class of your naming conventions before writing environment rules. When several markers are present, the first class in the order above wins (an ephemeral marker first, then dev, test, lab, preprod, prod): app.test.prod.example.com is classified test.

Safeguards

  • A Block rule must have at least one condition: a block rule without conditions would stop every issuance, and is refused when saved.
  • The list flags a rule that can never match because an earlier enabled rule covers all its requests: shadowed by "rule name".
  • A rule that cannot be read during evaluation is fail-closed: requests reaching it are refused with a message naming the rule ("…illisible : émission refusée jusqu'à sa correction.") until an administrator fixes it.
  • A Block rule that depends only on the algorithm (optionally restricted to a profile), with no name, wildcard, environment or organization condition, also removes that algorithm from the choices offered when PKIFactor generates the key, so the interface never proposes an algorithm that the policy would then refuse.
  • Every creation, change and deletion of a rule is recorded in the audit trail (POLICY_RULE_CREATED, POLICY_RULE_UPDATED, POLICY_RULE_DELETED), and so is every decision (POLICY_BLOCK, POLICY_REQUIRE_APPROVAL, POLICY_AUTO_ALLOWED), with the rule name and all the names evaluated.

The default rule

A new installation has one rule: Wildcard en production (priority 100, wildcard = yes, environment = prod, effect = require approval), with the message "Un certificat wildcard en production exige une approbation manuelle (SecOps)." Change it, disable it or delete it as needed.

Examples

Goal Conditions Effect
No wildcard in production at all Wildcard = yes, environment = prod Block
Review every RSA request on a profile meant for EC keys Algorithm = RSA, profile = that profile Require approval
Forbid a sensitive host name (for example the PKIFactor console itself) CN pattern = clm.example.com Block
Exempt a laboratory domain from later rules CN pattern = *.lab.example.com, low priority number Allow (exempt)
Via the API

curl -s -b jar https://clm.example.com/api/issuance-policies
curl -s -b jar -X POST https://clm.example.com/api/issuance-policies \
  -H "Content-Type: application/json" \
  -d '{"name":"No wildcard in production","priority":10,"is_wildcard":true,
       "environment":"prod","effect":"block",
       "message":"Wildcard certificates are not allowed in production."}'
curl -s -b jar -X PUT https://clm.example.com/api/issuance-policies/3 \
  -H "Content-Type: application/json" -d '{"name":"No wildcard in production","enabled":false,"effect":"block","is_wildcard":true,"environment":"prod"}'
curl -s -b jar -X DELETE https://clm.example.com/api/issuance-policies/3
effect is allow, require_approval or block. PUT replaces the whole rule: send every field. The listing returns shadowed_by for unreachable rules.

Other controls on a request

Issuance policies are one of several checks. In order of scope:

Control Where Effect
Allowed algorithms of the profile Certificate profile Refuses a key algorithm not listed, on every channel
Allowed names of the profile (CN Domain Filter) Certificate profile Refuses a CN or SAN outside the list
Subject fields of the profile Certificate profile Imposes or forbids subject values
Issuance policies This page Cross-profile rules: approval or block by context
CA template The CA (Vault role, AD CS template, EJBCA profile) The CA's own limits, applied last

Troubleshooting

Symptom Cause and fix
Request refused with "Demande refusée par une politique d'émission." A block rule without a message matched; the audit trail (POLICY_BLOCK) names the rule and the names evaluated
Every request reaching a rule is refused with "Règle de politique d'émission « … » illisible" That rule cannot be evaluated; edit or delete it
A rule never applies It is shadowed by an earlier rule (see the list), disabled, or its environment does not match the names (an unmarked name is not prod)
An ACME or EST request went through despite an approval rule Expected: approval cannot apply to protocol requests. Use a block rule, or recorded POLICY_AUTO_ALLOWED events, to control them
Saving a block rule is refused It has no condition