Problem
Lemur's certificate naming generates names that are incompatible with cloud providers that enforce strict naming rules. For example, GCP SSL certificate names must match [a-z][-a-z0-9]{0,61}[a-z0-9] (lowercase only, no dots, max 63 characters).
The current certificate_name() in lemur/common/defaults.py produces names like:
SAN-spotify.com-DigiCertInc-20260225-20260227
WILDCARD.spotify.com-DigiCertInc-20260225-20260227
These violate GCP's naming rules in three ways:
- Contains dots —
text_to_slug() preserves dots (regex [^A-Za-z0-9.]+)
- Mixed case — no
.lower() is applied
- No length cap — names can easily exceed 63 characters
Additionally, get_or_increase_name() in lemur/certificates/models.py uses .upper() on the hex serial suffix when handling name collisions, which also produces uppercase characters:
serial_name = f"{name}-{hex(int(serial))[2:].upper()}"
Current workaround
We deploy Lemur with GCP load balancer integration and currently monkey-patch both functions in our lemur.conf.py to produce GCP-compliant names. This works but is fragile and has caused several production issues during upgrades. Our patches:
- Replace
certificate_name() to generate short, lowercase, dot-free names (e.g. spotify-com-20260227)
- Replace
get_or_increase_name() to use .lower() on the hex serial and truncate to stay within 63 chars
Proposal
We'd like to contribute a fix upstream to eliminate the need for monkey-patching. We see two possible approaches and would like your input on which you'd prefer:
Option A: Configurable naming format
Add configuration options to control naming behavior:
- A
CERTIFICATE_NAME_FORMAT config (e.g. "default" vs "short") that selects between the current verbose format and a shorter cloud-friendly format
- A
CERTIFICATE_NAME_MAX_LENGTH config (default: unlimited) to cap generated names
- Make
text_to_slug() respect a lowercase option and optionally strip dots
- Fix
get_or_increase_name() to respect the same casing/length settings
This preserves full backwards compatibility while giving operators control.
Option B: Minimal fix to text_to_slug() + get_or_increase_name()
A smaller change:
- Change
text_to_slug() to replace dots with the joiner character (change regex from [^A-Za-z0-9.]+ to [^A-Za-z0-9]+) and add .lower()
- Add a
CERTIFICATE_NAME_MAX_LENGTH config to truncate generated names
- Change
.upper() to .lower() in get_or_increase_name()
This is simpler but changes the default naming behavior (existing certificates in the DB would keep their old names, only newly generated names would differ).
We're happy to submit a PR for whichever approach you prefer, or a different approach entirely. We've been running Lemur in production with GCP for a while now and would like to get this fixed properly upstream.
Problem
Lemur's certificate naming generates names that are incompatible with cloud providers that enforce strict naming rules. For example, GCP SSL certificate names must match
[a-z][-a-z0-9]{0,61}[a-z0-9](lowercase only, no dots, max 63 characters).The current
certificate_name()inlemur/common/defaults.pyproduces names like:These violate GCP's naming rules in three ways:
text_to_slug()preserves dots (regex[^A-Za-z0-9.]+).lower()is appliedAdditionally,
get_or_increase_name()inlemur/certificates/models.pyuses.upper()on the hex serial suffix when handling name collisions, which also produces uppercase characters:Current workaround
We deploy Lemur with GCP load balancer integration and currently monkey-patch both functions in our
lemur.conf.pyto produce GCP-compliant names. This works but is fragile and has caused several production issues during upgrades. Our patches:certificate_name()to generate short, lowercase, dot-free names (e.g.spotify-com-20260227)get_or_increase_name()to use.lower()on the hex serial and truncate to stay within 63 charsProposal
We'd like to contribute a fix upstream to eliminate the need for monkey-patching. We see two possible approaches and would like your input on which you'd prefer:
Option A: Configurable naming format
Add configuration options to control naming behavior:
CERTIFICATE_NAME_FORMATconfig (e.g."default"vs"short") that selects between the current verbose format and a shorter cloud-friendly formatCERTIFICATE_NAME_MAX_LENGTHconfig (default: unlimited) to cap generated namestext_to_slug()respect alowercaseoption and optionally strip dotsget_or_increase_name()to respect the same casing/length settingsThis preserves full backwards compatibility while giving operators control.
Option B: Minimal fix to
text_to_slug()+get_or_increase_name()A smaller change:
text_to_slug()to replace dots with the joiner character (change regex from[^A-Za-z0-9.]+to[^A-Za-z0-9]+) and add.lower()CERTIFICATE_NAME_MAX_LENGTHconfig to truncate generated names.upper()to.lower()inget_or_increase_name()This is simpler but changes the default naming behavior (existing certificates in the DB would keep their old names, only newly generated names would differ).
We're happy to submit a PR for whichever approach you prefer, or a different approach entirely. We've been running Lemur in production with GCP for a while now and would like to get this fixed properly upstream.