Skip to content

pg_ssl_cert / pg_ssl_cert_key are documented but silently ignored in Kong Gateway OSS #14956

Description

@Coder-in-a-shell

Is there an existing issue for this?

  • I have searched the existing issues

Kong version ($ kong version)

3.9.3 (and master as of today)

Current Behavior

pg_ssl_cert and pg_ssl_cert_key are documented as standard, non-Enterprise Kong Gateway configuration options:

pg_ssl_cert — The absolute path to the PEM encoded client TLS certificate for the PostgreSQL connection. Mutual TLS authentication against PostgreSQL is only enabled if this value is set.

pg_ssl_cert_key — If pg_ssl_cert is set, the absolute path to the PEM encoded client TLS private key for the PostgreSQL connection.

— https://developer.konghq.com/gateway/configuration/

In Kong Gateway OSS these properties do not exist and are silently ignored:

  1. They are not declared in kong/conf_loader/constants.lua — only pg_ssl, pg_ssl_verify, pg_ro_ssl and pg_ro_ssl_verify are.
  2. They are not documented in kong.conf.default.
  3. kong/db/strategies/postgres/connector.lua never passes a client certificate to pgmoon. Both the read-write config in _M.new() and the ro_override table set only ssl, ssl_verify and cafile.

Because unknown KONG_* / kong.conf keys are dropped rather than rejected, an operator who follows the documentation gets no warning at all — the connection is simply made without a client certificate, and PostgreSQL rejects it:

[PostgreSQL error] failed to retrieve PostgreSQL server_version_num:
receive_message: failed to get type: tlsv13 alert certificate required

This was reported in #11768. That issue was closed with the pending author feedback label seven days after it was filed, so I don't believe the underlying gap was ever addressed — it's still reproducible on master. A maintainer noted there that mTLS to PostgreSQL is expected to require Kong Gateway Enterprise, which is what I'd like to clarify (see below).

Expected Behavior

Either:

(a) pg_ssl_cert / pg_ssl_cert_key work in OSS as documented, or

(b) if mTLS to PostgreSQL is intentionally Enterprise-only, the OSS configuration reference is updated to say so, and Kong fails to start (or logs a warning) when these keys are set but unsupported — rather than silently ignoring a security-relevant setting.

Steps To Reproduce

  1. Configure PostgreSQL with ssl = on and clientcert = verify-full in pg_hba.conf.
  2. Configure Kong OSS:
    database        = postgres
    pg_ssl          = on
    pg_ssl_verify   = on
    pg_ssl_cert     = /path/to/client.pem
    pg_ssl_cert_key = /path/to/client.key
    lua_ssl_trusted_certificate = /path/to/ca.pem
    
  3. Run kong migrations bootstrap -vv.
  4. Observe the tlsv13 alert certificate required failure, and note that pg_ssl_cert / pg_ssl_cert_key never appear in the -vv config dump.

Anything else?

The driver already supports this. Kong depends on kong-pgmoon == 1.16.2 (kong-latest.rockspec), and the Kong/pgmoon fork already implements client certificates for the OpenResty cosocket path. send_ssl_message does:

local luasec_opts = self.config.luasec_opts or self:create_luasec_opts()
if self.sock.setclientcert then
  local ok, err_internal = self.sock:setclientcert(luasec_opts.certificate, luasec_opts.key)
  ...
  return self.sock:sslhandshake(false, nil, self.config.ssl_verify)
else
  if self.sock.tlshandshake then
    return self.sock:tlshandshake({
      verify          = self.config.ssl_verify,
      client_cert     = luasec_opts.certificate,
      client_priv_key = luasec_opts.key,
    })
  ...

and create_luasec_opts reads and parses the PEM files directly from config.cert / config.key:

if self.sock_type == "nginx" and key and cert then
  key  = assert(ssl.parse_pem_priv_key(pl_file.read(key, true)))
  cert = assert(ssl.parse_pem_cert(pl_file.read(cert, true)))
end

So enabling this in OSS looks like plumbing two values through, with no driver, OpenSSL, or protocol work required:

  1. Declare pg_ssl_cert, pg_ssl_cert_key, pg_ro_ssl_cert, pg_ro_ssl_cert_key in kong/conf_loader/constants.lua and document them in kong.conf.default.
  2. Validate in kong/conf_loader/init.lua that the pair is set together and that both files are readable.
  3. Pass cert / key into the pgmoon config in connector.lua, in both _M.new() and ro_override.
  4. Unit tests in spec/01-unit/03-conf_loader_spec.lua plus a changelog/unreleased/kong/ entry.

My question before I open a PR: would a patch along these lines be accepted into Kong Gateway OSS? I'm happy to write it, including tests and changelog, and to mirror it for the read-only connection for consistency with the existing pg_ssl / pg_ro_ssl pairs. But given the earlier comment on #11768 that this is an Enterprise capability, I'd rather confirm the direction than send a PR that conflicts with product intent. If the answer is that it stays Enterprise-only, I'd be glad to file the documentation correction instead.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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