Cannot enable custom plugin with Kong Konnect

I have a setup with 1-node locally running kong proxy in minikube and Kong Konnect as the control plane. I am trying to enable there a custom plugin, which I developed with help of Pongo.

In Pongo’s version of Kong, the plugin works just fine. However, I a struggling to deploy it to the minikube:

deck konnect sync -s v1/konnect.yaml \
        --konnect-email "<redacted>" --konnect-password-file secrets/konnect_pwd.txt
creating plugin tls-cert-extract (global)
Summary:
  Created: 0
  Updated: 0
  Deleted: 0
Error: 1 errors occurred:
        while processing event: {Create} plugin tls-cert-extract (global) failed: HTTP status 400 (message: "schema violation (name: plugin 'tls-cert-extract' not enabled; add it to the 'plugins' configuration property)")

I’ve tried to do everything according to the doc, i.e. uploaded sources to the configMap, enabled plugin it in the plugins section of the Helm chart. However, I still see the same error. Tried to manually define volumes and volume mounts, tried to mount it directly under /usr/local/share/lua/5.1/kong/plugins/ - nothing works.

When I SSH to the proxy pod I can see that plugin files are mounted at the correct locations and all the needed vars are set:

kubectl exec --stdin --tty \
        $(kubectl get pod -l app.kubernetes.io/name=kong -n kong -o jsonpath="{.items[0].metadata.name}") \
        -c proxy -n kong \
        -- /bin/bash

bash-5.0$ echo $KONG_PLUGINS
bundled,tls-cert-extract
bash-5.0$ echo $KONG_LUA_PACKAGE_PATH
/opt/?.lua;/opt/?/init.lua;;
bash-5.0$ ls -al /usr/local/share/lua/5.1/kong/plugins/tls-cert-extract/
total 12
drwxrwxrwx    3 root     root          4096 Aug 11 08:46 .
drwxr-xr-x    1 root     root          4096 Aug 11 08:46 ..
drwxr-xr-x    2 root     root          4096 Aug 11 08:46 ..2021_08_11_08_46_14.342433247
lrwxrwxrwx    1 root     root            31 Aug 11 08:46 ..data -> ..2021_08_11_08_46_14.342433247
lrwxrwxrwx    1 root     root            18 Aug 11 08:46 handler.lua -> ..data/handler.lua
lrwxrwxrwx    1 root     root            17 Aug 11 08:46 schema.lua -> ..data/schema.lua
bash-5.0$ ls -al /opt/kong/plugins/tls-cert-extract/
total 12
drwxrwxrwx    3 root     root          4096 Aug 11 08:46 .
drwxr-xr-x    3 root     root          4096 Aug 11 08:46 ..
drwxr-xr-x    2 root     root          4096 Aug 11 08:46 ..2021_08_11_08_46_14.342433247
lrwxrwxrwx    1 root     root            31 Aug 11 08:46 ..data -> ..2021_08_11_08_46_14.342433247
lrwxrwxrwx    1 root     root            18 Aug 11 08:46 handler.lua -> ..data/handler.lua
lrwxrwxrwx    1 root     root            17 Aug 11 08:46 schema.lua -> ..data/schema.lua

Here is my plugin schema.lua:

local typedefs = require "kong.db.schema.typedefs"

local schema = {
  name = "tls-cert-extract",
  fields = {
    -- the 'fields' array is the top-level entry with fields defined by Kong
    { consumer = typedefs.no_consumer }, -- this plugin cannot be configured on a consumer (typical for auth plugins)
    { protocols = typedefs.protocols_http },
    { config = {
      -- The 'config' record is the custom part of the plugin schema
      type = "record",
      fields = {
        -- a standard defined field (typedef), with some customizations
        { host = typedefs.wildcard_host {
          required = true,
          default = "*" } },
        { request_client_cert = {
          type = "boolean",
          required = true,
          default = false } },
        { device_id = typedefs.header_name {
          required = false,
          default = "X-Lenovo-Device-ID" } },
      },
      entity_checks = {
        -- add some validation rules across fields
        -- the following is silly because it is always true, since they are both required
        { at_least_one_of = { "host" } }
      },
    },
    },
  },
}

return schema

My values.yaml:

image:
  repository: kong/kong-gateway
  tag: "2.4.1.1-alpine"

deployment:
  userDefinedVolumes:
    - name: kong-plugin-tls-cert-extract
      configMap:
        name: kong-plugin-tls-cert-extract
  userDefinedVolumeMounts:
    - name: kong-plugin-tls-cert-extract
      mountPath: "/usr/local/share/lua/5.1/kong/plugins/tls-cert-extract"

secretVolumes:
  - kong-cluster-cert
  - kong-cluster-ca

env:
  role: data_plane
  database: "off"
  anonymous_reports: off
  vitals_ttl_days: 732
  cluster_mtls: pki
  cluster_control_plane: <redacted>
  cluster_server_name: <redacted>
  cluster_telemetry_endpoint: <redacted>
  cluster_telemetry_server_name: <redacted>
  cluster_ca_cert: /etc/secrets/kong-cluster-ca/ca.crt
  cluster_cert: /etc/secrets/kong-cluster-cert/tls.crt
  cluster_cert_key: /etc/secrets/kong-cluster-cert/tls.key
  lua_ssl_trusted_certificate: /etc/secrets/kong-cluster-ca/ca.crt
  kong_plugins: bundled,tls-cert-extract
  kong_lua_package_path: /opt/?.lua;/opt/?/init.lua;;

plugins:
  configMaps:
    - name: kong-plugin-tls-cert-extract
      pluginName: tls-cert-extract

ingressController:
  enabled: false
  installCRDs: false

And konnect.yaml:

_format_version: "0.1"

service_packages:
  - name: Echo
    versions:
      - implementation:
          kong:
            service:
              connect_timeout: 60000
              host: echo.mtls-poc
              id: b939ce96-94e7-4337-82a9-3bbe8119ce90
              path: /
              port: 80
              protocol: http
              read_timeout: 60000
              retries: 5
              routes:
                - hosts:
                    - mtls.auth.local
                  https_redirect_status_code: 426
                  id: 5a290e5f-4bf1-4023-b6c1-bde5679af14a
                  methods:
                    - GET
                  path_handling: v0
                  paths:
                    - /echo
                  preserve_host: false
                  protocols:
                    - https
                  regex_priority: 0
                  request_buffering: true
                  response_buffering: true
                  strip_path: true
              write_timeout: 60000
          type: kong-gateway
        version: v1

certificates:
  - cert: |
      -----BEGIN CERTIFICATE-----
      ...
      -----END CERTIFICATE-----
      -----BEGIN CERTIFICATE-----
      ...
      -----END CERTIFICATE-----
      -----BEGIN CERTIFICATE-----
      ...
      -----END CERTIFICATE-----
    key: |
      -----BEGIN PRIVATE KEY-----
      ...
      -----END PRIVATE KEY-----
    id: 18cee516-6268-11eb-ae93-0242ac130012
    snis:
      - name: mtls.auth.local
    tags: [ "mtls.key" ]

plugins:
  - id: 0e5aa468-fa7a-11eb-adf8-975743bfa9fc
    name: tls-cert-extract
    config:
      host: mtls.auth.local
      request_client_cert: true
    protocols: [ "https" ]
    enabled: true
    tags: [ "tls-cert-extract" ]

I have a strong suspicion it has something to do with the Konnect control plane not knowing about my custom plugin and refusing to sync the decK’s YAML.

What should I do?

FYI: I managed to make it work with Kong OSS with Kong Ingress Controller via CRDs and same Helm configuration.

Still I am curious what’s the deal with Konnect. It seems like it is limiting plugin choice to only those available at Kong Plugin Hub?