fix(litellm): percent-encode DB password in DATABASE_URL
LiteLLM crash-looped on macOS with Prisma `P1013: invalid port number in
database URL`. The shared auth token is generated by `openssl rand -base64`
and can contain '/', '+' or '='; injected raw into the DATABASE_URL
userinfo, a '/' truncates the authority so the port parses as invalid and
proxy startup fails (port 4000 never binds).
Percent-encode the password for the DATABASE_URL only, via an explicit
reserved-set replace chain ('%' first to avoid double-encoding) since
Jinja's urlencode leaves '/' unescaped. The DB user password stays raw in
provision-database and LITELLM_DB_PASSWORD, and the URL form decodes back
to the identical secret (verified round-trip), so authentication is
unchanged. No effect when no DB host is configured.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
ef67c61cf7
commit
9926a46f76
@ -107,8 +107,22 @@ litellm_database_password: "{{ lookup('ansible.builtin.env', 'LITELLM_DATABASE_P
|
||||
litellm_database_admin_user: "{{ lookup('ansible.builtin.env', 'LITELLM_DATABASE_ADMIN_USER') | default('postgres', true) }}"
|
||||
litellm_database_admin_password: "{{ lookup('ansible.builtin.env', 'LITELLM_DATABASE_ADMIN_PASSWORD') | default('', true) }}"
|
||||
|
||||
# Percent-encode the password for use inside the DATABASE_URL userinfo. The
|
||||
# shared auth token is `openssl rand -base64`, which can contain '/', '+' and
|
||||
# '=' — a raw '/' truncates the URL authority and Prisma aborts with
|
||||
# "P1013: invalid port number in database URL". Jinja's `urlencode` leaves '/'
|
||||
# safe, so encode the reserved set explicitly ('%' first to avoid double
|
||||
# encoding). The actual DB user password stays raw (provision-database and
|
||||
# LITELLM_DB_PASSWORD use it verbatim); only the URL form is encoded so the
|
||||
# client decodes back to the same raw secret.
|
||||
litellm_database_password_urlencoded: >-
|
||||
{{ litellm_database_password
|
||||
| replace('%', '%25') | replace('/', '%2F') | replace('+', '%2B')
|
||||
| replace('=', '%3D') | replace('@', '%40') | replace(':', '%3A')
|
||||
| replace('?', '%3F') | replace('#', '%23') | replace(' ', '%20') }}
|
||||
|
||||
# Build DATABASE_URL from components (used in litellm.env)
|
||||
litellm_database_url: "{% if litellm_database_host | trim | length > 0 %}postgresql://{{ litellm_database_user }}:{{ litellm_database_password }}@{{ litellm_database_host }}:{{ litellm_database_port }}/{{ litellm_database_name }}?sslmode={{ litellm_database_sslmode }}{% else %}{% endif %}"
|
||||
litellm_database_url: "{% if litellm_database_host | trim | length > 0 %}postgresql://{{ litellm_database_user }}:{{ litellm_database_password_urlencoded | trim }}@{{ litellm_database_host }}:{{ litellm_database_port }}/{{ litellm_database_name }}?sslmode={{ litellm_database_sslmode }}{% else %}{% endif %}"
|
||||
|
||||
# Models are now dynamically managed via DB/UI or user-provided config
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user