POST /v1/license-keys/validate compares the submitted key with a plain case-sensitive equality (LicenseKey.key == key) against a plain String column, no normalization or ilike.
Auto-generated keys are always uppercase (generate_key uppercases the UUID and prefix), so this doesn't affect the default flow. But a customer-supplied key with different casing, or a client that re-types/pastes a key with different casing, will 404 (ResourceNotFound) even though it's logically the same key.
Reported externally: an uppercase key returns granted, the identical key lowercased returns 404.
Proposal: normalize the key to canonical casing before lookup (or use a case-insensitive comparison), so validation isn't sensitive to casing. If case-sensitive matching is intentional, document it explicitly in the API reference and return a more descriptive error to make the behavior easier to diagnose.
Relevant code:
server/polar/license_key/endpoints.py (validate route)
server/polar/license_key/repository.py (get_readable_by_key, get_by_organization_and_key)
server/polar/models/license_key.py (key column, plain String)
server/polar/license_key/schemas.py (LicenseKeyCreate.generate_key)
Sent by @allison-polar from License key case sensitivity validation.
Plain Thread
POST /v1/license-keys/validatecompares the submitted key with a plain case-sensitive equality (LicenseKey.key == key) against a plainStringcolumn, no normalization orilike.Auto-generated keys are always uppercase (
generate_keyuppercases the UUID and prefix), so this doesn't affect the default flow. But a customer-supplied key with different casing, or a client that re-types/pastes a key with different casing, will 404 (ResourceNotFound) even though it's logically the same key.Reported externally: an uppercase key returns
granted, the identical key lowercased returns 404.Proposal: normalize the key to canonical casing before lookup (or use a case-insensitive comparison), so validation isn't sensitive to casing. If case-sensitive matching is intentional, document it explicitly in the API reference and return a more descriptive error to make the behavior easier to diagnose.
Relevant code:
server/polar/license_key/endpoints.py(validateroute)server/polar/license_key/repository.py(get_readable_by_key,get_by_organization_and_key)server/polar/models/license_key.py(keycolumn, plainString)server/polar/license_key/schemas.py(LicenseKeyCreate.generate_key)Sent by @allison-polar from License key case sensitivity validation.
Plain Thread