Skip to content

Certificate names are incompatible with cloud providers that require lowercase/short names (e.g. GCP) #5345

@gijzelaerr

Description

@gijzelaerr

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:

  1. Contains dotstext_to_slug() preserves dots (regex [^A-Za-z0-9.]+)
  2. Mixed case — no .lower() is applied
  3. 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:

  1. Replace certificate_name() to generate short, lowercase, dot-free names (e.g. spotify-com-20260227)
  2. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions