diff --git a/.github/styles/kong/dictionary.txt b/.github/styles/kong/dictionary.txt index 630a0deb384f..f1eed8386797 100644 --- a/.github/styles/kong/dictionary.txt +++ b/.github/styles/kong/dictionary.txt @@ -2,29 +2,41 @@ Alertmanager allowlist anonymized api +apis +arg autogenerate autogenerated autogenerates aws +backtrace Bintray Bitnami blockquote blockquotes +body_filter boolean +cleartext +client_payload +client_status CloudFormation +cncf +cncf's Cognito config configs conntrack cors +crds Curity DAO DAOs +datadog Datadog datagram datagrams dataplane dataplanes +db-ip dbless declaratively degraphql @@ -33,16 +45,24 @@ deployer deserialize deserialized dev +digitalocean +dockerfile +Equinix etcd Fargate favicon +flamegraph +gevent +gibibytes Github +gojira Goroutine Grafana grpc grpcs hardcoded hashicorp +header_filter hostname hostnames http @@ -53,20 +73,32 @@ inbounds ini invalidation invalidations +init_worker +inso +instrumentations io +ip +ips iptables Istio +jetstack jq json JsonPath jwk jwks jwt +kafka +keepalive Keycloak +keyspace kiali +kibibytes Knative kong Kong/kong +kong-ip +kong_name Konnect kubectl kubeconfig @@ -75,27 +107,34 @@ Kuma kumactl kustomization Kustomize +loggly Loggly lookup lookups loopback lua +Lua's Luarocks ngrok npm md +mebibytes middleware minifier minikube Mockbin Moesif MongoDB +nameserver +nameservers namespace namespaces namespaced navtabs +Netcat Netlify Nginx +nginx observability oc Okta @@ -103,6 +142,7 @@ onboard onboarding onwards opa +openresty outbounds passthrough PayPal @@ -110,22 +150,36 @@ performant plaintext Postgres PostgreSQL +perf +petstore +pgdump +plaintext +Pongo PowerShell prepend prepends prepended +preread profiler +prometheus Prometheus +proto Protobuf proxied proxying querystring +rbac +reachability redis reentrant referenceable +regexes repo requery +Resty +rockspec routable +ruleset runtime runtimes deduplication @@ -135,10 +189,16 @@ sandboxing schema's serializer serverless +slas +sni snis Splunk ssl +ssl_certificate sso +Stap +stapxx +statsd stderr stdin stdout @@ -146,27 +206,44 @@ Styra subtree Bagdi subcommand +submodule +submodule's substring sudo +syslog Syslog tbl +tcp tcpdump +teardown +tfvars +transcoded transcoder +transpile +transpiled ttl txt +unary uncheck uncomment uncommenting +unencrypted Unicode unix +unnormalized +unprocessable unpublish unregister unregistering upsert upstream +upstream_payload +upstream_status upstreams +upstream's upvalue upvalues +use_daily_image usr uri uris @@ -177,12 +254,16 @@ Valero validator validators vararg +vms websocket websockets wireframe wireframes +worker-ip workspace +xenial yaml yml +zipkin Zipkin zsh diff --git a/.github/workflows/check-links.yml b/.github/workflows/check-links.yml index 76dda639676f..96c7b93b1f0d 100644 --- a/.github/workflows/check-links.yml +++ b/.github/workflows/check-links.yml @@ -38,6 +38,7 @@ jobs: id: waitForNetlify with: site_name: "kongdocs" + max_timeout: 120 - name: Run link checker run: | cd broken-link-checker diff --git a/Gemfile b/Gemfile index 2d62bfe830d8..c7ed022295b6 100644 --- a/Gemfile +++ b/Gemfile @@ -7,6 +7,7 @@ gem 'jekyll-redirect-from' gem 'kramdown-parser-gfm' gem 'liquid-c' gem 'rouge', '3.30.0' +gem 'activesupport' group :development do gem 'pry' diff --git a/Gemfile.lock b/Gemfile.lock index bbef6675e0f2..a3cb9643678a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,11 @@ GEM remote: https://rubygems.org/ specs: + activesupport (7.0.3.1) + concurrent-ruby (~> 1.0, >= 1.0.2) + i18n (>= 1.6, < 2) + minitest (>= 5.1) + tzinfo (~> 2.0) addressable (2.8.0) public_suffix (>= 2.0.2, < 5.0) ast (2.4.2) @@ -52,6 +57,7 @@ GEM rb-inotify (~> 0.9, >= 0.9.10) mercenary (0.4.0) method_source (1.0.0) + minitest (5.16.3) nio4r (2.5.8) parallel (1.22.1) parser (3.1.2.0) @@ -92,12 +98,15 @@ GEM ffi (~> 1.9) terminal-table (2.0.0) unicode-display_width (~> 1.1, >= 1.1.1) + tzinfo (2.0.5) + concurrent-ruby (~> 1.0) unicode-display_width (1.8.0) PLATFORMS ruby DEPENDENCIES + activesupport jekyll (= 4.2.0) jekyll-include-cache jekyll-redirect-from diff --git a/algolia/config-full-docs.json b/algolia/config-full-docs.json index 811a10f24850..f4222172a0f2 100644 --- a/algolia/config-full-docs.json +++ b/algolia/config-full-docs.json @@ -24,9 +24,6 @@ "url": "https://docs.konghq.com/mesh/changelog/", "selectors_key": "changelog" }, - { - "url": "https://docs.konghq.com/konnect-platform/" - }, { "url": "https://docs.konghq.com/hub/", "selectors_key": "hub" diff --git a/app/_assets/images/docs/gateway/km_workspace.png b/app/_assets/images/docs/gateway/km_workspace.png new file mode 100644 index 000000000000..b6d7a12ffb37 Binary files /dev/null and b/app/_assets/images/docs/gateway/km_workspace.png differ diff --git a/app/_assets/images/icons/documentation/icn-flag.svg b/app/_assets/images/icons/documentation/icn-flag.svg index 812bf2d9993e..b49a2e950a06 100644 --- a/app/_assets/images/icons/documentation/icn-flag.svg +++ b/app/_assets/images/icons/documentation/icn-flag.svg @@ -1,3 +1,3 @@ - + diff --git a/app/_assets/images/icons/documentation/icn-learning.svg b/app/_assets/images/icons/documentation/icn-learning.svg index f9e40490e864..c1ec32bcf771 100644 --- a/app/_assets/images/icons/documentation/icn-learning.svg +++ b/app/_assets/images/icons/documentation/icn-learning.svg @@ -1,9 +1,13 @@ - - - - - - - - + + + + + + + + + + + + diff --git a/app/_assets/images/icons/hub/kong-inc_opentelemetry.png b/app/_assets/images/icons/hub/kong-inc_opentelemetry.png new file mode 100644 index 000000000000..4fb337a5ca7c Binary files /dev/null and b/app/_assets/images/icons/hub/kong-inc_opentelemetry.png differ diff --git a/app/_assets/images/icons/hub/kong-inc_tls-handshake-modifier.png b/app/_assets/images/icons/hub/kong-inc_tls-handshake-modifier.png new file mode 100644 index 000000000000..2440615c725a Binary files /dev/null and b/app/_assets/images/icons/hub/kong-inc_tls-handshake-modifier.png differ diff --git a/app/_assets/images/icons/hub/kong-inc_tls-metadata-headers.png b/app/_assets/images/icons/hub/kong-inc_tls-metadata-headers.png new file mode 100644 index 000000000000..2440615c725a Binary files /dev/null and b/app/_assets/images/icons/hub/kong-inc_tls-metadata-headers.png differ diff --git a/app/_assets/images/icons/hub/kong-inc_upstream-timeout.png b/app/_assets/images/icons/hub/kong-inc_upstream-timeout.png new file mode 100644 index 000000000000..884f8fcae773 Binary files /dev/null and b/app/_assets/images/icons/hub/kong-inc_upstream-timeout.png differ diff --git a/app/_assets/images/icons/hub/kong-inc_websocket-size-limit.png b/app/_assets/images/icons/hub/kong-inc_websocket-size-limit.png new file mode 100644 index 000000000000..9281ad1c4701 Binary files /dev/null and b/app/_assets/images/icons/hub/kong-inc_websocket-size-limit.png differ diff --git a/app/_assets/images/icons/hub/kong-inc_websocket-validator.png b/app/_assets/images/icons/hub/kong-inc_websocket-validator.png new file mode 100644 index 000000000000..b0b876295598 Binary files /dev/null and b/app/_assets/images/icons/hub/kong-inc_websocket-validator.png differ diff --git a/app/_assets/javascripts/app.js b/app/_assets/javascripts/app.js index 39bdae8e2b10..753c72ff560d 100644 --- a/app/_assets/javascripts/app.js +++ b/app/_assets/javascripts/app.js @@ -145,21 +145,21 @@ jQuery(function () { }); }); - // COMPAT DROPDOWN: dropdown menu functionality (handles /konnect-platform/compatibility dropdown) - $("#compat-dropdown").on("click", function(e) { - e.preventDefault(); - e.stopPropagation(); - - $("#compat-list").toggleClass("open"); - - $(document).one('click', function closeMenu (e){ - if($('#compat-list').has(e.target).length === 0){ - $('#compat-list').removeClass('open'); - } else { - $(document).one('click', closeMenu); - } - }); - }); + // COMPAT DROPDOWN: dropdown menu functionality (handles /archive/konnect-platform/compatibility dropdown. Currently not in use.) + // $("#compat-dropdown").on("click", function(e) { + // e.preventDefault(); + // e.stopPropagation(); + // + // $("#compat-list").toggleClass("open"); + // + // $(document).one('click', function closeMenu (e){ + // if($('#compat-list').has(e.target).length === 0){ + // $('#compat-list').removeClass('open'); + // } else { + // $(document).one('click', closeMenu); + // } + // }); + // }); // Cookie functions @@ -574,7 +574,7 @@ function pluginFilter(target){ // Toggle all nav tabs that match this title const text = navtabTitle.text(); const search = $(".navtab-title").filter(function () { - return $(this).text().toLowerCase().indexOf(text.toLowerCase()) >= 0; + return $(this).text().trim().toLowerCase() == text.trim().toLowerCase() }).each(function(k,v){ activateSingleNavTab($(v)); }); diff --git a/app/_assets/stylesheets/compat-form.less b/app/_assets/stylesheets/compat-form.less index d14b920de515..815db91cce56 100644 --- a/app/_assets/stylesheets/compat-form.less +++ b/app/_assets/stylesheets/compat-form.less @@ -1,5 +1,5 @@ // Styling for the compatibility form and table located under -// /app/konnect-platform/compatibility +// /archive/konnect-platform/compatibility. Not currently in use. .compat-form { border: 1px solid @grey-200; diff --git a/app/_assets/stylesheets/features-table.less b/app/_assets/stylesheets/features-table.less index bbd9d9e30e52..cc70c54a4657 100644 --- a/app/_assets/stylesheets/features-table.less +++ b/app/_assets/stylesheets/features-table.less @@ -2,6 +2,11 @@ width: fit-content; overflow-x: visible !important; + .product-title { + font-size: 1.6em; + text-transform: none !important; + } + .mobile-label { display: none; } diff --git a/app/_assets/stylesheets/navtabs.less b/app/_assets/stylesheets/navtabs.less index dcd84c1e2aa9..ac4beaa26e86 100644 --- a/app/_assets/stylesheets/navtabs.less +++ b/app/_assets/stylesheets/navtabs.less @@ -41,6 +41,25 @@ } } + + .external-trigger { + .navtab-titles { + display: none !important; + } + + .navtab-contents { + margin-top: -22px !important; + } + + .copy-action { + margin-top: 0 !important; + } + + pre.highlight { + padding: 20px 12px !important; + } + } + &.codeblock { background-color: @grey-300; border: 1px solid @grey-200; @@ -56,24 +75,6 @@ } } - &.external-trigger { - .navtab-titles { - display: none; - } - - .navtab-contents { - margin-top: -22px; - } - - .copy-action { - margin-top: 0 !important; - } - - pre.highlight { - padding: 20px 12px; - } - } - .navtab-titles { background-color: @grey-300; color: rgba(black, 0.6); diff --git a/app/_assets/stylesheets/pages/docs.less b/app/_assets/stylesheets/pages/docs.less index 3e0fa43d6b6c..656e20c5cfce 100644 --- a/app/_assets/stylesheets/pages/docs.less +++ b/app/_assets/stylesheets/pages/docs.less @@ -792,3 +792,27 @@ font-size: 11px; } } + +.book-nav-container { + hr { + margin: 1em 0; + } +} + +.book-nav { + width: 48%; + + + .direction { + display: block; + font-weight: bold; + } + margin-bottom: 1em; +} +.book-nav.previous { + float: left; +} +.book-nav.next { + float: right; + text-align: right; +} \ No newline at end of file diff --git a/app/_data/docs_nav_deck_1.12.x.yml b/app/_data/docs_nav_deck_1.12.x.yml index 81b915b7645d..6e5b5d913b1d 100644 --- a/app/_data/docs_nav_deck_1.12.x.yml +++ b/app/_data/docs_nav_deck_1.12.x.yml @@ -13,6 +13,8 @@ items: url: /design-architecture - text: Compatibility Promise url: /compatibility-promise + - text: Stages of Software Availability + url: /availability-stages - title: Changelog icon: /assets/images/icons/documentation/icn-references-color.svg diff --git a/app/_data/docs_nav_gateway_2.6.x.yml b/app/_data/docs_nav_gateway_2.6.x.yml index 32c4816353ed..59753610b60f 100644 --- a/app/_data/docs_nav_gateway_2.6.x.yml +++ b/app/_data/docs_nav_gateway_2.6.x.yml @@ -4,7 +4,7 @@ absolute_url: true items: - text: Version Support Policy - url: /konnect-platform/support-policy + url: /gateway/latest/support-policy absolute_url: true - text: Compatibility url: /compatibility/ diff --git a/app/_data/docs_nav_gateway_2.7.x.yml b/app/_data/docs_nav_gateway_2.7.x.yml index 81b054894117..08bfb13f6527 100644 --- a/app/_data/docs_nav_gateway_2.7.x.yml +++ b/app/_data/docs_nav_gateway_2.7.x.yml @@ -4,7 +4,7 @@ absolute_url: true items: - text: Version Support Policy - url: /konnect-platform/support-policy + url: /gateway/latest/support-policy absolute_url: true - text: Compatibility url: /compatibility/ diff --git a/app/_data/docs_nav_gateway_2.8.x.yml b/app/_data/docs_nav_gateway_2.8.x.yml index 31163e3a73f3..a4aad9212012 100644 --- a/app/_data/docs_nav_gateway_2.8.x.yml +++ b/app/_data/docs_nav_gateway_2.8.x.yml @@ -2,13 +2,12 @@ icon: /assets/images/icons/documentation/icn-flag.svg items: - text: Overview of Kong Gateway - url: /gateway/ + url: /gateway/2.8.x/ absolute_url: true - text: Version Support Policy - url: /konnect-platform/support-policy - absolute_url: true - - text: Compatibility - url: /compatibility/ + url: /support-policy + - text: Stages of Software Availability + url: /availability-stages - text: Changelog url: /gateway/changelog absolute_url: true diff --git a/app/_data/docs_nav_gateway_3.0.x.yml b/app/_data/docs_nav_gateway_3.0.x.yml new file mode 100644 index 000000000000..019c40acf83e --- /dev/null +++ b/app/_data/docs_nav_gateway_3.0.x.yml @@ -0,0 +1,585 @@ +product: gateway +release: 3.0.x +generate: true +assume_generated: true +items: + - title: Introduction + icon: /assets/images/icons/documentation/icn-flag.svg + items: + - text: Overview of Kong Gateway + url: /gateway/3.0.x/ + absolute_url: true + - text: Version Support Policy + url: /support-policy + - text: Stability + url: /stability + - text: Release Notes + url: /gateway/changelog + absolute_url: true + - text: Key Concepts + items: + - text: Services + url: /key-concepts/services + - text: Routes + items: + - text: Overview + url: /key-concepts/routes + - text: Configure Routes with Expressions + url: /key-concepts/routes/expressions + - text: Upstreams + url: /key-concepts/upstreams + - text: Plugins + url: /key-concepts/plugins + # - text: Manage Kong Gateway with decK + # url: /key-concepts/manage-kong-with-deck + - text: How Kong Works + items: + - text: Routing Traffic + url: /how-kong-works/routing-traffic + - text: Load Balancing + url: /how-kong-works/load-balancing + - text: Health Checks and Circuit Breakers + url: /how-kong-works/health-checks + - text: Kong Performance Testing + url: /how-kong-works/performance-testing + - text: Glossary + url: /glossary + + - title: Get Started with Kong + icon: /assets/images/icons/documentation/icn-learning.svg + items: + - text: Get Kong + url: /get-started/ + - text: Services and Routes + url: /get-started/services-and-routes + - text: Rate Limiting + url: /get-started/rate-limiting + - text: Proxy Caching + url: /get-started/proxy-caching + - text: Key Authentication + url: /get-started/key-authentication + - text: Load-Balancing + url: /get-started/load-balancing + - title: Kong in Production + icon: /assets/images/icons/documentation/icn-deployment-color.svg + items: + - text: Deployment Topologies + items: + - text: Overview + url: /production/deployment-topologies/ + - text: Hybrid Mode + items: + - text: Overview + url: /production/deployment-topologies/hybrid-mode/ + - text: Deploy Kong Gateway in Hybrid mode + url: /production/deployment-topologies/hybrid-mode/setup + - text: DB-less Deployment + url: /production/deployment-topologies/db-less-and-declarative-config + - text: Traditional + url: /production/deployment-topologies/traditional + - text: Installation Options + items: + - text: Overview + url: /install/ + - text: Kubernetes + items: + - text: kubectl apply + url: /install/kubernetes/kubectl + - text: Helm + url: /install/kubernetes/helm-quickstart + - text: OpenShift with Helm + url: /install/kubernetes/openshift + - text: Kubernetes Deployment Options + url: /install/kubernetes/deployment-options + - text: Docker + items: + - text: Using docker run + url: /install/docker + - text: Build your own Docker images + url: /install/docker/build-custom-images/ + - text: Linux + items: + - text: Supported Distributions + url: /install/linux/os-support + - text: Amazon Linux + url: /install/linux/amazon-linux + - text: Debian + url: /install/linux/debian + - text: Red Hat + url: /install/linux/rhel + - text: Ubuntu + url: /install/linux/ubuntu + - text: macOS + url: /install/macos + - text: Running Kong + items: + - text: Running Kong as a non-root user + url: /production/running-kong/kong-user + - text: Securing the Admin API + url: /production/running-kong/secure-admin-api + - text: Using systemd + url: /production/running-kong/systemd + - text: Access Control + items: + - text: Start Kong Gateway Securely + url: /production/access-control/start-securely + - text: Programatically Creating Admins + url: /production/access-control/register-admin-api + - text: Enabling RBAC + url: /production/access-control/enable-rbac + - text: Licenses + items: + - text: Overview + url: /licenses/ + - text: Download your License + url: /licenses/download + - text: Deploy Enterprise License + url: /licenses/deploy + - text: Using the License API + url: /licenses/examples + - text: Monitor Licenses Usage + url: /licenses/report + - text: Networking + items: + - text: Default Ports + url: /production/networking/default-ports + - text: DNS Considerations + url: /production/networking/dns-considerations + - text: Network and Firewall + url: /production/networking/firewall + - text: Kong Configuration File + url: /production/kong-conf + - text: Environment Variables + url: /production/environment-variables + - text: Embedding Kong in Open Resty + url: /production/kong-openresty + - text: Serving a Website and APIs from Kong + url: /production/website-api-serving + - text: Monitoring + items: + - text: Overview + url: /production/monitoring/ + - text: Prometheus + url: /production/monitoring/prometheus + - text: StatsD + url: /production/monitoring/statsd + - text: Datadog + url: /production/monitoring/datadog + - text: Tracing + items: + - text: Overview + url: /production/tracing/ + - text: Writing a Custom Trace Exporter + url: /production/tracing/write-custom-trace-exporter + - text: Tracing API Reference + url: /production/tracing/api + - text: Resource Sizing Guidelines + url: /production/sizing-guidelines + - text: Security Update Process + url: /production/security-update-process + - text: Blue-Green Deployments + url: /production/blue-green + - text: Canary Deployments + url: /production/canary + - text: Clustering Reference + url: /production/clustering + - text: Logging Reference + url: /production/logging + - text: Upgrade and Migration + items: + - text: Upgrade Kong Gateway + url: /upgrade/ + - text: Migrate from OSS to Enterprise + url: /migrate-ce-to-ke/ + - title: Kong Enterprise + icon: /assets/images/icons/documentation/icn-enterprise-blue.svg + items: + - text: Overview + url: /kong-enterprise/ + - text: Kong Vitals + items: + - text: Overview + url: /kong-enterprise/analytics/ + - text: Metrics + url: /kong-enterprise/analytics/metrics + - text: Reports + url: /kong-enterprise/analytics/reports + - text: Analytics with InfluxDB + url: /kong-enterprise/analytics/influx-strategy + - text: Analytics with Prometheus + url: /kong-enterprise/analytics/prometheus-strategy + - text: Estimate Analytics Storage in PostgreSQL + url: /kong-enterprise/analytics/estimates + - text: Secrets Management + items: + - text: Overview + url: /kong-enterprise/secrets-management/ + - text: Getting Started + url: /kong-enterprise/secrets-management/getting-started + - text: Advanced Usage + url: /kong-enterprise/secrets-management/advanced-usage + - text: Backends + items: + - text: Overview + url: /kong-enterprise/secrets-management/backends + - text: Environment Variables + url: /kong-enterprise/secrets-management/backends/env + - text: AWS Secrets Manager + url: /kong-enterprise/secrets-management/backends/aws-sm + - text: Google Secrets Manager + url: /kong-enterprise/secrets-management/backends/gcp-sm + - text: Hashicorp Vault + url: /kong-enterprise/secrets-management/backends/hashicorp-vault + - text: How-To + items: + - text: Securing the Database with AWS Secrets Manager + url: /kong-enterprise/secrets-management/how-to/aws-secrets-manager + - text: Reference Format + url: /kong-enterprise/secrets-management/reference-format + - text: Dynamic Plugin Ordering + items: + - text: Overview + url: /kong-enterprise/plugin-ordering/ + - text: Get Started with Dynamic Plugin Ordering + url: /kong-enterprise/plugin-ordering/get-started + - text: Dev Portal + items: + - text: Overview + url: /kong-enterprise/dev-portal/ + - text: Enable the Dev Portal + url: /kong-enterprise/dev-portal/enable + - text: Publish an OpenAPI Spec + url: /kong-enterprise/dev-portal/publish-spec + - text: Structure and File Types + url: /kong-enterprise/dev-portal/structure-and-file-types + - text: Themes Files + url: /kong-enterprise/dev-portal/themes + - text: Working with Templates + url: /kong-enterprise/dev-portal/working-with-templates + - text: Using the Editor + url: /kong-enterprise/dev-portal/using-the-editor + - text: Authentication and Authorization + items: + - text: Basic Auth + url: /kong-enterprise/dev-portal/authentication/basic-auth + - text: Key Auth + url: /kong-enterprise/dev-portal/authentication/key-auth + - text: OIDC + url: /kong-enterprise/dev-portal/authentication/oidc + - text: Sessions + url: /kong-enterprise/dev-portal/authentication/sessions + - text: Adding Custom Registration Fields + url: /kong-enterprise/dev-portal/authentication/adding-registration-fields + - text: Manage Developers + url: /kong-enterprise/dev-portal/authentication/managing-developers + - text: Developer Roles and Content Permissions + url: /kong-enterprise/dev-portal/authentication/developer-permissions + - text: Application Registration + items: + - text: Authorization Provider Strategy + url: /kong-enterprise/dev-portal/applications/auth-provider-strategy + - text: Enable Application Registration + url: /kong-enterprise/dev-portal/applications/enable-application-registration + - text: Enable Key Authentication for Application Registration + url: /kong-enterprise/dev-portal/applications/enable-key-auth-plugin + - text: Enable External Authentication + items: + - text: External OAuth2 Support + url: /kong-enterprise/dev-portal/authentication/3rd-party-oauth + - text: Set up Okta and Kong for External Oauth + url: /kong-enterprise/dev-portal/authentication/okta-config + - text: Set up Azure AD and Kong for External Authentication + url: /kong-enterprise/dev-portal/authentication/azure-oidc-config + - text: Manage Applications + url: /kong-enterprise/dev-portal/applications/managing-applications + - text: Customize Dev Portal + items: + - text: Theme Editing + url: /kong-enterprise/dev-portal/customize/theme-editing + - text: Migrating Templates Between Workspaces + url: /kong-enterprise/dev-portal/customize/migrating-templates + - text: Markdown Rendering Module + url: /kong-enterprise/dev-portal/customize/markdown-extended + - text: Customizing Portal Emails + url: /kong-enterprise/dev-portal/customize/emails + - text: Adding and Using JavaScript Assets + url: /kong-enterprise/dev-portal/customize/adding-javascript-assets + - text: Single Page App in Dev Portal + url: /kong-enterprise/dev-portal/customize/single-page-app + - text: Alternate OpenAPI Renderer + url: /kong-enterprise/dev-portal/customize/alternate-openapi-renderer + - text: SMTP + url: /kong-enterprise/dev-portal/smtp + - text: Workspaces + url: /kong-enterprise/dev-portal/workspaces + - text: Helpers CLI + url: /kong-enterprise/dev-portal/cli + - text: Portal API + url: /kong-enterprise/dev-portal/portal-api + - text: Audit Logging + url: /kong-enterprise/audit-log + - text: Keyring and Data Encryption + url: /kong-enterprise/db-encryption + - text: Workspaces + url: /kong-enterprise/workspaces + - text: Consumer Groups + url: /kong-enterprise/consumer-groups + - text: Event Hooks + url: /kong-enterprise/event-hooks + - title: Kong Manager + icon: /assets/images/icons/documentation/icn-manager-color.svg + items: + - text: Overview + url: /kong-manager/ + - text: Enable Kong Manager + url: /kong-manager/enable + - text: Get Started with Kong Manager + items: + - text: Services and Routes + url: /kong-manager/get-started/services-and-routes + - text: Rate Limiting + url: /kong-manager/get-started/rate-limiting + - text: Proxy Caching + url: /kong-manager/get-started/proxy-caching + - text: Authentication with Consumers + url: /kong-manager/get-started/consumers + - text: Load Balancing + url: /kong-manager/get-started/load-balancing + - text: Authentication and Authorization + items: + - text: Overview + url: /kong-manager/auth/ + - text: Create a Super Admin + url: /kong-manager/auth/super-admin + - text: Workspaces and Teams + url: /kong-manager/auth/workspaces-and-teams + - text: Reset Passwords and RBAC Tokens + url: /kong-manager/auth/reset-password + - text: Basic Auth + url: /kong-manager/auth/basic + - text: LDAP + items: + - text: Configure LDAP + url: /kong-manager/auth/ldap/configure + - text: LDAP Service Directory Mapping + url: /kong-manager/auth/ldap/service-directory-mapping + - text: OIDC + items: + - text: Configure OIDC + url: /kong-manager/auth/oidc/configure + - text: OIDC Authenticated Group Mapping + url: /kong-manager/auth/oidc/mapping + - text: Sessions + url: /kong-manager/auth/sessions + - text: RBAC + items: + - text: Overview + url: /kong-manager/auth/rbac + - text: Enable RBAC + url: /kong-manager/auth/rbac/enable + - text: Add a Role and Permissions + url: /kong-manager/auth/rbac/add-role + - text: Create a User + url: /kong-manager/auth/rbac/add-user + - text: Create an Admin + url: /kong-manager/auth/rbac/add-admin + - text: Networking Configuration + url: /kong-manager/networking + - text: Workspaces + url: /kong-manager/workspaces + - text: Sending Email + url: /kong-manager/configuring-to-send-email + + - title: Develop Custom Plugins + icon: /assets/images/icons/documentation/icn-dev-portal-color.svg + items: + - text: Overview + url: /plugin-development/ + - text: File Structure + url: /plugin-development/file-structure + - text: Implementing Custom Logic + url: /plugin-development/custom-logic + - text: Plugin Configuration + url: /plugin-development/configuration + - text: Accessing the Data Store + url: /plugin-development/access-the-datastore + - text: Storing Custom Entities + url: /plugin-development/custom-entities + - text: Caching Custom Entities + url: /plugin-development/entities-cache + - text: Extending the Admin API + url: /plugin-development/admin-api + - text: Writing Tests + url: /plugin-development/tests + - text: (un)Installing your Plugin + url: /plugin-development/distribution + - text: Plugin Development Kit + items: + - text: Overview + url: /plugin-development/pdk/ + - text: kong.client + url: /plugin-development/pdk/kong.client + - text: kong.client.tls + url: /plugin-development/pdk/kong.client.tls + - text: kong.cluster + url: /plugin-development/pdk/kong.cluster + - text: kong.ctx + url: /plugin-development/pdk/kong.ctx + - text: kong.ip + url: /plugin-development/pdk/kong.ip + - text: kong.log + url: /plugin-development/pdk/kong.log + - text: kong.nginx + url: /plugin-development/pdk/kong.nginx + - text: kong.node + url: /plugin-development/pdk/kong.node + - text: kong.request + url: /plugin-development/pdk/kong.request + - text: kong.response + url: /plugin-development/pdk/kong.response + - text: kong.router + url: /plugin-development/pdk/kong.router + - text: kong.service + url: /plugin-development/pdk/kong.service + - text: kong.service.request + url: /plugin-development/pdk/kong.service.request + - text: kong.service.response + url: /plugin-development/pdk/kong.service.response + - text: kong.table + url: /plugin-development/pdk/kong.table + - text: kong.tracing + url: /plugin-development/pdk/kong.tracing + - text: kong.vault + url: /plugin-development/pdk/kong.vault + + - text: kong.websocket.client + url: /plugin-development/pdk/kong.websocket.client + + - text: kong.websocket.upstream + url: /plugin-development/pdk/kong.websocket.upstream + + - text: Plugins in Other Languages + items: + - text: Go + url: /plugin-development/pluginserver/go + - text: Javascript + url: /plugin-development/pluginserver/javascript + - text: Python + url: /plugin-development/pluginserver/python + - text: Running Plugins in Containers + url: /plugin-development/pluginserver/plugins-kubernetes + - title: Kong Plugins + icon: /assets/images/icons/documentation/icn-api-plugins-color.svg + items: + - text: Overview + url: /kong-plugins/ + - text: Authentication + items: + - text: Open ID Connect Plugin + items: + - text: Overview + url: /kong-plugins/authentication/oidc/ + - text: OpenID Connect with Curity + url: /kong-plugins/authentication/oidc/curity + - text: OpenID Connect with Azure AD + url: /kong-plugins/authentication/oidc/azure-ad + - text: OpenID Connect with Google + url: /kong-plugins/authentication/oidc/google + - text: OpenID Connect with Okta + url: /kong-plugins/authentication/oidc/okta + - text: OpenID Connect with Auth0 + url: /kong-plugins/authentication/oidc/auth0 + - text: OpenID Connect with Cognito + url: /kong-plugins/authentication/oidc/cognito + - text: Authentication Reference + url: /kong-plugins/authentication/reference + - text: Allow Multiple Authentication Plugins + url: /kong-plugins/authentication/allowing-multiple-authentication-methods/ + - text: Rate Limiting Plugin + url: /kong-plugins/rate-limiting/algorithms/rate-limiting + #items: + #- text: Overview + #url: /kong-plugins/rate-limiting/ commenting these lines out for 3.0 + #url: /kong-plugins/rate-limiting/algorithms/rate-limiting + #- text: Algorithms + # items: + # - text: Configuring sliding-window + # url: /kong-plugins/rate-limiting/algorithms/rate-limiting + #- text: Configuring Fixed bucket + # url: /kong-plugins/rate-limiting/algorithms/fixed-bucket + - text: Request Transformer + items: + - text: Add a Body Value + url: /kong-plugins/request-transformer/add-body-value + + - text: GraphQL + url: /kong-plugins/graphql + - text: gRPC + items: + - text: gRPC Plugins + url: /kong-plugins/grpc + - text: Configure a gRPC service + url: /kong-plugins/configuring-a-grpc-service + + - title: Admin API + icon: /assets/images/icons/documentation/icn-admin-api-color.svg + items: + - text: Overview + url: /admin-api/ + - text: Information Routes + url: /admin-api/#information-routes + - text: Health Routes + url: /admin-api/#health-routes + - text: Tags + url: /admin-api/#tags + - text: Services + url: /admin-api/#service-object + - text: Routes + url: /admin-api/#route-object + - text: Consumers + url: /admin-api/#consumer-object + - text: Plugins + url: /admin-api/#plugin-object + - text: Certificates + url: /admin-api/#certificate-object + - text: CA Certificates + url: /admin-api/#ca-certificate-object + - text: SNIs + url: /admin-api/#sni-object + - text: Upstreams + url: /admin-api/#upstream-object + - text: Targets + url: /admin-api/#target-object + - text: Vaults + url: /admin-api/#vaults-entity + - text: Licenses + url: /admin-api/licenses/reference + - text: Workspaces + url: /admin-api/workspaces/reference + - text: RBAC + url: /admin-api/rbac/reference + - text: Admins + url: /admin-api/admins/reference + - text: Developers + url: /admin-api/developers/reference + - text: Consumer Groups + url: /admin-api/consumer-groups/reference + - text: Event Hooks + url: /admin-api/event-hooks/reference + - text: Keyring and Data Encryption + url: /admin-api/db-encryption + - title: Reference + icon: /assets/images/icons/documentation/icn-references-color.svg + items: + - text: kong.conf + url: /reference/configuration + - text: Injecting Nginx Directives + url: /reference/nginx-directives + - text: CLI + url: /reference/cli + - text: Performance Testing Framework + url: /reference/performance-testing-framework + - text: Router Operators + url: /reference/router-operators + - text: FAQ + url: /reference/faq diff --git a/app/_data/docs_nav_kic_2.5.x.yml b/app/_data/docs_nav_kic_2.5.x.yml index ed76b970522e..c1f1fd5b6f43 100644 --- a/app/_data/docs_nav_kic_2.5.x.yml +++ b/app/_data/docs_nav_kic_2.5.x.yml @@ -9,6 +9,10 @@ items: items: - text: FAQ url: /faq + - text: Version Support Policy + url: /support-policy + - text: Stages of Software Availability + url: /availability-stages - text: Changelog url: https://github.com/Kong/kubernetes-ingress-controller/blob/main/CHANGELOG.md absolute_url: true diff --git a/app/_data/docs_nav_konnect.yml b/app/_data/docs_nav_konnect.yml index b6c3d871960a..bddcf8eaec9e 100644 --- a/app/_data/docs_nav_konnect.yml +++ b/app/_data/docs_nav_konnect.yml @@ -11,6 +11,8 @@ url: /network - text: Compatibility url: /compatibility + - text: Stages of Software Availability + url: /availability-stages - text: Release Notes url: /updates diff --git a/app/_data/docs_nav_konnect_platform.yml b/app/_data/docs_nav_konnect_platform.yml deleted file mode 100644 index 1c66f4e7798f..000000000000 --- a/app/_data/docs_nav_konnect_platform.yml +++ /dev/null @@ -1,20 +0,0 @@ -- title: Konnect Platform Overview - icon: /assets/images/icons/documentation/icn-flag.svg - url: /konnect-platform - items: - - text: Key Concepts - url: /konnect-platform/key-concepts - -- title: Version Support Policy - icon: /assets/images/icons/documentation/icn-support.svg - url: /konnect-platform/support-policy - -- title: Getting Started Guides - icon: /assets/images/icons/documentation/icn-quickstart-color.svg - url: /konnect-platform/guides - -- title: Compatibility - icon: /assets/images/icons/documentation/icn-references-color.svg - items: - - text: Plugin Compatibility - url: /konnect-platform/compatibility/plugins diff --git a/app/_data/docs_nav_mesh_1.5.x.yml b/app/_data/docs_nav_mesh_1.5.x.yml index ad87bb69673e..e18fdfd75408 100644 --- a/app/_data/docs_nav_mesh_1.5.x.yml +++ b/app/_data/docs_nav_mesh_1.5.x.yml @@ -10,7 +10,7 @@ - title: Version Support Policy icon: /assets/images/icons/documentation/icn-support.svg - url: /konnect-platform/support-policy + url: /mesh/latest/support-policy absolute_url: true - title: Getting Started diff --git a/app/_data/docs_nav_mesh_1.6.x.yml b/app/_data/docs_nav_mesh_1.6.x.yml index 49c4acfeff2f..c1481cafc4db 100644 --- a/app/_data/docs_nav_mesh_1.6.x.yml +++ b/app/_data/docs_nav_mesh_1.6.x.yml @@ -10,7 +10,7 @@ - title: Version Support Policy icon: /assets/images/icons/documentation/icn-support.svg - url: /konnect-platform/support-policy + url: /mesh/latest/support-policy absolute_url: true - title: Getting Started diff --git a/app/_data/docs_nav_mesh_1.8.x.yml b/app/_data/docs_nav_mesh_1.8.x.yml index 6e58f1bfe7d0..4028d0abb8df 100644 --- a/app/_data/docs_nav_mesh_1.8.x.yml +++ b/app/_data/docs_nav_mesh_1.8.x.yml @@ -6,12 +6,15 @@ items: icon: /assets/images/icons/documentation/icn-flag.svg url: /mesh/1.8.x/ absolute_url: true - - - title: Release notes - icon: /assets/images/icons/documentation/icn-references-color.svg - url: /mesh/changelog - generate: false - absolute_url: true + items: + - text: Version Support Policy + url: /support-policy + - text: Stages of Software Availability + url: /availability-stages + - text: Release notes + url: /mesh/changelog + generate: false + absolute_url: true - title: Getting Started icon: /assets/images/icons/documentation/icn-quickstart-color.svg diff --git a/app/_data/docs_nav_mesh_1.9.x.yml b/app/_data/docs_nav_mesh_1.9.x.yml index 94e9841bede4..208a08f2272d 100644 --- a/app/_data/docs_nav_mesh_1.9.x.yml +++ b/app/_data/docs_nav_mesh_1.9.x.yml @@ -6,12 +6,15 @@ items: icon: /assets/images/icons/documentation/icn-flag.svg url: /mesh/1.9.x/ absolute_url: true - - - title: Release notes - icon: /assets/images/icons/documentation/icn-references-color.svg - url: /mesh/changelog - generate: false - absolute_url: true + items: + - text: Version Support Policy + url: /support-policy + - text: Stages of Software Availability + url: /availability-stages + - text: Release Notes + url: /mesh/changelog + generate: false + absolute_url: true - title: Getting Started icon: /assets/images/icons/documentation/icn-quickstart-color.svg diff --git a/app/_data/kong_versions.yml b/app/_data/kong_versions.yml index 4988ff8a1e91..f1f68a89e1cb 100644 --- a/app/_data/kong_versions.yml +++ b/app/_data/kong_versions.yml @@ -1,94 +1,5 @@ - # Old OSS Gateway docs - release: "0.13.x" - version: "0.13.1" - edition: "gateway-oss" - luarocks_version: "0.13.1-0" - dependencies: - luajit: "2.1.0-beta2" - luarocks: "2.4.3" - cassandra: "3.x.x" - postgres: "9.5+" - openresty: "1.11.2.5" - lua_doc: true -- - release: "0.14.x" - version: "0.14.1" - edition: "gateway-oss" - luarocks_version: "0.14.1-0" - dependencies: - luajit: "2.1.0-beta3" - luarocks: "2.4.3" - cassandra: "3.x.x" - postgres: "9.5+" - openresty: "1.13.6.2" -- - release: "1.0.x" - version: "1.0.3" - edition: "gateway-oss" - luarocks_version: "1.0.3-0" - dependencies: - luajit: "2.1.0-beta3" - luarocks: "2.4.3" - cassandra: "3.x.x" - postgres: "9.5+" - openresty: "1.13.6.2" -- - release: "1.1.x" - version: "1.1.3" - edition: "gateway-oss" - luarocks_version: "1.1.3-0" - dependencies: - luajit: "2.1.0-beta3" - luarocks: "2.4.3" - cassandra: "3.x.x" - postgres: "9.5+" - openresty: "1.13.6.2" -- - release: "1.2.x" - version: "1.2.3" - edition: "gateway-oss" - luarocks_version: "1.2.3-0" - dependencies: - luajit: "2.1.0-beta3" - luarocks: "2.4.3" - cassandra: "3.x.x" - postgres: "9.5+" - openresty: "1.13.6.2" -- - release: "1.3.x" - version: "1.3.1" - edition: "gateway-oss" - luarocks_version: "1.3.1-0" - dependencies: - luajit: "2.1.0-beta3" - luarocks: "3.1.3" - cassandra: "3.x.x" - postgres: "9.5+" - openresty: "1.15.8.1" -- - release: "1.4.x" - version: "1.4.3" - edition: "gateway-oss" - luarocks_version: "1.4.3-0" - dependencies: - luajit: "2.1.0-beta3" - luarocks: "3.1.3" - cassandra: "3.x.x" - postgres: "9.5+" - openresty: "1.15.8.1" -- - release: "1.5.x" - version: "1.5.1" - edition: "gateway-oss" - luarocks_version: "1.5.1-0" - dependencies: - luajit: "2.1.0-beta3" - luarocks: "3.2.1" - cassandra: "3.x.x" - postgres: "9.5+" - openresty: "1.15.8.2" -- release: "2.0.x" version: "2.0.5" edition: "gateway-oss" @@ -171,102 +82,6 @@ pcre: "8.44" - # Old Enterprise Gateway docs - release: "0.31-x" - version: "0.31" - edition: "enterprise" - luarocks_version: "0.31.x" - dependencies: - luajit: "2.1.0-beta2" - luarocks: "2.4.3" - cassandra: "3.x.x" - postgres: "9.5+" - openresty: "1.11.2.5" - lua_doc: true -- - release: "0.32-x" - version: "0.32" - edition: "enterprise" - luarocks_version: "0.32.x" - dependencies: - luajit: "2.1.0-beta2" - luarocks: "2.4.3" - cassandra: "3.x.x" - postgres: "9.5+" - openresty: "1.11.2.5" - lua_doc: true -- - release: "0.33-x" - version: "0.33" - edition: "enterprise" - luarocks_version: "0.33.x" - dependencies: - luajit: "2.1.0-beta2" - luarocks: "2.4.3" - cassandra: "3.x.x" - postgres: "9.5+" - openresty: "1.11.2.5" - lua_doc: true -- - release: "0.34-x" - version: "0.34" - edition: "enterprise" - luarocks_version: "0.34.x" - dependencies: - luajit: "2.1.0-beta2" - luarocks: "2.4.3" - cassandra: "3.x.x" - postgres: "9.5+" - openresty: "1.13.6.2" - lua_doc: true -- - release: "0.35-x" - version: "0.35" - edition: "enterprise" - luarocks_version: "0.34.x" - dependencies: - luajit: "2.1.0-beta2" - luarocks: "2.4.3" - cassandra: "3.x.x" - postgres: "9.5+" - openresty: "1.13.6.2" - lua_doc: true -- - release: "0.36-x" - version: "0.36" - edition: "enterprise" - luarocks_version: "0.34.x" - dependencies: - luajit: "2.1.0-beta2" - luarocks: "2.4.3" - cassandra: "3.x.x" - postgres: "9.5+" - openresty: "1.13.6.2" - lua_doc: true -- - release: "1.3-x" - version: "1.3" - edition: "enterprise" - luarocks_version: "0.34.x" - dependencies: - luajit: "2.1.0-beta2" - luarocks: "2.4.3" - cassandra: "3.x.x" - postgres: "9.5+" - openresty: "1.13.6.2" - lua_doc: true -- - release: "1.5.x" - version: "1.5.0.11" - edition: "enterprise" - luarocks_version: "0.34.x" - dependencies: - luajit: "2.1.0-beta2" - luarocks: "2.4.3" - cassandra: "3.x.x" - postgres: "9.5+" - openresty: "1.13.6.2" - lua_doc: true -- release: "2.1.x" version: "2.1.4.6" edition: "enterprise" @@ -376,6 +191,21 @@ libyaml: "0.2.5" pcre: "8.45" lua_doc: true +- + release: "3.0.x" + ee-version: "3.0.0.0" + ce-version: "3.0.0" + edition: "gateway" + luarocks_version: "3.0.0-0" + dependencies: + luajit: "2.1-20220411" + luarocks: "3.9.1" + postgres: "9.5+" + openresty: "1.21.4.1" + openssl: "1.1.1.q" + libyaml: "0.2.5" + pcre: 8.45 + lua_doc: true - release: "CE-2.0.x_KE-1.5.x" version: "CE-2.0.x/KE-1.5.x" @@ -442,8 +272,6 @@ edition: "mesh" - edition: "konnect" -- - edition: "konnect-platform" - edition: "contributing" - diff --git a/app/_data/tables/features/gateway.yml b/app/_data/tables/features/gateway.yml new file mode 100644 index 000000000000..c6f63f41fce2 --- /dev/null +++ b/app/_data/tables/features/gateway.yml @@ -0,0 +1,124 @@ +columns: + - name: Open Source + cta: Get Started + cta_link: /gateway/latest/install/ + key: oss + - name: Kong Enterprise + cta: Contact Sales + cta_link: http://konghq.com/contact-sales + key: enterprise +features: + - name: API Infrastructure Modernization + items: + - name: Fast, Lightweight, Cloud-Native API Gateway + oss: true + enterprise: true + - name: End-to-End Automation + tooltip: Drive a GitOps flow of API design and execution + oss: true + enterprise: true + - name: Kubernetes Ingress Controller + tooltip: Deploy APIs to Kubernetes in a native fashion + oss: true + enterprise: true + - name: Gateway Mocking + tooltip: Mock API responses directly on the API gateway + oss: false + enterprise: true + - name: "Kong Manager: Admin GUI" + tooltip: Visually manage Kong cluster, plugins, APIs, and consumers + oss: false + enterprise: true + - name: + oss: true + enterprise: true + - name: Traffic Management and Transformations + items: + - name: Basic Traffic Control Plugins + tooltip: Manage ACME certificates, basic rate limiting, and lightweight caching + oss: true + enterprise: true + - name: Simple Data Transformations + tooltip: Add or remove headers, JSON data, or query strings + oss: true + enterprise: true + - name: gRPC Transformations + tooltip: Translate requests from gRPC-Web and REST to backend gRPC services + oss: true + enterprise: true + - name: GraphQL + tooltip: Convert GraphQL queries to REST requests. Rate limit and cache GraphQL queries. + oss: false + enterprise: true + - name: Request Validation + tooltip: Validate requests using either Kong’s own schema validator or a JSON Schema Draft 4-compliant validator + oss: false + enterprise: true + - name: jq Transformations + tooltip: Advanced JSON transformations of requests or responses with the ability to chain transformations + oss: false + enterprise: true + - name: Advanced Caching + tooltip: Cache responses and optimize for high scale by integrating distributed backends + oss: false + enterprise: true + - name: Advanced Rate Limiting + tooltip: Enterprise-grade rate limiting with sliding window controls + oss: false + enterprise: true + - name: Security and Governance + items: + - name: Authentication + tooltip: Common methods of API authentication - Basic Auth, HMAC, JWT Key Auth, limited OAuth 2.0, limited LDAP + oss: true + enterprise: true + - name: Advanced Authentication + tooltip: Enterprise-grade API authentication - Full OAuth 2.0, OpenID Connect, Vault, mutual TLS, JWT signing/resigning, full LDAP + oss: false + enterprise: true + - name: Role-Based Access Control (RBAC) + tooltip: Control gateway configurations based on a user's role in the organization + oss: false + enterprise: true + - name: Basic Authorization (Bot Detection, CORS controls, ACLs) + tooltip: Control access to APIs by rules of user behavior and control lists + oss: true + enterprise: true + - name: Advanced Authorization (OPA) + tooltip: Control access to APIs with complex, programmable, enterprise-wide rules + oss: false + enterprise: true + - name: Secret Management + tooltip: Encrypt sensitive keys, certificates, and passwords + oss: false + enterprise: true + - name: Observability + items: + - name: Simple logging + tooltip: Send basic API gateway logs - File logging, HTTP logging, basic StatsD, TCP/UDP logging + oss: true + enterprise: true + - name: API Analytics + tooltip: Natively analyze requests and responses flowing through the API gateway + oss: false + enterprise: true + - name: Gateway Event Hooks + tooltip: Automatically log out or send web hooks on changes to the gateway, such as administrators added or rate limits exceeded + oss: false + enterprise: true + - name: Enterprise Support and Services + items: + - name: Enterprise support + tooltip: 24/7 x 365 technical support SLAs + oss: false + enterprise: true + - name: Security CVE and Bug Fix Backports + oss: false + enterprise: true + - name: Performance Tuning Guidance + oss: false + enterprise: true + - name: Customer Success Packages - Add-on + tooltip: Accelerate time to value with dedicated Technical Account Managers and Field Engineers + oss: false + enterprise: true diff --git a/app/_data/tables/features/mesh.yml b/app/_data/tables/features/mesh.yml new file mode 100644 index 000000000000..15d8ecad9a25 --- /dev/null +++ b/app/_data/tables/features/mesh.yml @@ -0,0 +1,147 @@ +columns: + - name: Kuma + image: /assets/images/logos/kuma.png + cta: Start Free + cta_link: https://kuma.io/ + key: kuma + - name: Kong Mesh + image: /assets/images/logos/kong-mesh.png + cta: Contact Sales + cta_link: http://konghq.com/contact-sales + key: mesh +features: + - name: Core Service Mesh Capabilities + items: + - name: All Kuma Policies + kuma: true + mesh: true + - name: All Traffic Management Policies + kuma: true + mesh: true + - name: All Observability Policies + kuma: true + mesh: true + - name: Multi-Zone & Multi-Cluster + kuma: true + mesh: true + - name: Multi-Zone Security + tooltip: | + Allows you to secure multi-zone deployments with a JWT-based authentication that ensures only approved zones can join the cluster. + kuma: false + mesh: true + - name: Multi-Mesh support + kuma: true + mesh: true + - name: Zero-Trust and mTLS + items: + - name: Built-in CA + kuma: true + mesh: true + - name: Provided CA + kuma: true + mesh: true + - name: HashiCorp Vault CA + tooltip: | + Allows you to enable HashiCorp Vault as an additional third-party backend for mTLS CAs that are used to setup zero-trust security, without storing the CAs in Kong Mesh proper. + kuma: false + mesh: true + - name: AWS Certificate Manager CA + tooltip: | + Allows you to enable AWS Certificate Manager as an additional third-party backend for the mTLS CAs that are used to setup zero-trust security, without storing the CAs in Kong Mesh proper. + kuma: false + mesh: true + - name: Kubernetes cert-manager CA + tooltip: | + Allows you to enable Kubernetes cert-manager as an additional third-party backend for the mTLS CAs that are used to setup zero-trust security, without storing the CAs in Kong Mesh proper. + kuma: false + mesh: true + - name: GUI Dashboard for TLS and CA + tooltip: | + Provides you with additional visual reports that display the rotation status of the data plane proxy certificates and the rotation of the CAs themselves, in a zero-trust service mesh. + kuma: false + mesh: true + - name: Data Plane Certificate Rotation + kuma: true + mesh: true + - name: CA Automatic Rotation + tooltip: | + Provides automatic rotation across different CAs with no downtime in addition to providing automatic rotation and certificate lifecycle management to the data plane proxy mTLS certificates. This feature combined with the GUI Dashboard for TLS and CA provides a complete solution for managing the entire lifecycle of zero-trust service meshes. + kuma: false + mesh: true + - name: Enterprise Application Security + items: + - name: FIPS-140 Encryption + tooltip: | + By default, FIPS-140 compliant encryption is automatically enabled in Kong Mesh on the Envoy-based data plane proxies. This doesn't require any additional steps other than running Kong Mesh itself. + kuma: false + mesh: true + - name: Embedded OPA Agent + tooltip: | + Kong Mesh ships with an embedded OPA agent in the data plane proxy sidecars, without requiring the user to run an additional dedicated sidecar for the OPA agent. This simplifies the roll out of OPA across the entire organization and lowers operational costs. + kuma: false + mesh: true + - name: Native OPA Policy + tooltip: | + This exposes a native OPA policy resource that can be used to store and automatically propagate OPA policies across a multi-zone deployment natively with Kong Mesh. We also support the ability to connect to a third-party OPA store like Styra. + kuma: false + mesh: true + - name: Enterprise Security and Governance + items: + - name: Roles and permissions (RBAC) + tooltip: | + Allows you to manage complex RBAC rules to allow or deny access to Kong Mesh policies and functions in a sophisticated and fine grained way. This works across multi-zone and multi-mesh natively. + kuma: false + mesh: true + - name: Audit Logs + tooltip: | + Allows you to store and fetch auditing logs for operations that were performed on the cluster. When used with RBAC, it allows us to have full visibility into how the system is being governed and configured by the users. + kuma: false + mesh: true + - name: Universal Platform Distributions + items: + - name: Containers, Kubernetes & OpenShift + kuma: true + mesh: true + - name: Kubernetes Operator + tooltip: | + Allows you to simplify the operational cost of running Kong Mesh on Kubernetes by providing a native Kubernetes operator to fully manage the deployment, upgrades, and roll outs of a cluster on Kubernetes. + kuma: false + mesh: true + - name: Virtual Machine Support + kuma: true + mesh: true + - name: Virtual Machine Transparent Proxying + kuma: true + mesh: true + - name: Native AWS ECS Controller + tooltip: | + Allows you to natively support AWS ECS workloads with a built-in controller that automatically integrates ECS workloads within one or more service meshes powered by Kong Mesh. This simplifies the expansion of service mesh in the cloud. + kuma: false + mesh: true + - name: Windows Distributions + tooltip: | + Allows you to natively support Microsoft Windows workloads in service meshes, allowing you to further expand the reach of Kong Mesh across every workload in your organization. + kuma: false + mesh: true + - name: UBI Federal Distributions + tooltip: | + Provides officially supported distributions based on the Red Hat Universal Base Images (UBI). + kuma: false + mesh: true + - name: Support and Customer Success + items: + - name: Enterprise Support and SLA + tooltip: | + With Kong Mesh, we provide 24/7/365 enterprise support with different SLAs, powered by Kong's global customer success and technical support team across all world regions. This also provides access to a vast network of partners for local language support as well. This is recommended for enterprise mission-critical deployments. + kuma: false + mesh: true + - name: Customer Success Packages + tooltip: | + With Kong Mesh, we provide access to our implementation and training programs to accelerate the roll out of a service mesh across every team, and to properly train and educate the organization on how to effectively drive business outcomes with the product. + kuma: false + mesh: true + - name: Envoy Support + tooltip: | + With Kong Mesh, we provide access to the Envoy contributors at Kong to further expand the capabilities of the underlying data plane proxy technology (Envoy) with features that are not currently available in upstream Envoy. This can be used to remove road blocks and cater to unique enterprise requirements and use-cases. + kuma: false + mesh: true \ No newline at end of file diff --git a/app/_data/tables/install_options.yml b/app/_data/tables/install_options.yml new file mode 100644 index 000000000000..2a11f5647c37 --- /dev/null +++ b/app/_data/tables/install_options.yml @@ -0,0 +1,76 @@ +columns: + - name: Kong OSS + key: oss + - name: Kong Enterprise + key: enterprise + - name: Production Ready + key: support +features: + - name: 'Packages' + items: + - name: 'Alpine' + url: /gateway/VERSION/install/docker/build-custom-images/ + oss: true + enterprise: true + support: true + - name: 'Debian' + url: /gateway/VERSION/install/linux/debian/ + oss: true + enterprise: true + support: true + - name: 'Ubuntu' + url: /gateway/VERSION/install/linux/ubuntu/ + oss: true + enterprise: true + support: true + - name: 'RedHat' + url: /gateway/VERSION/install/linux/rhel/ + oss: true + enterprise: true + support: true + - name: 'Amazon Linux 2' + url: /gateway/VERSION/install/linux/amazon-linux/ + oss: true + enterprise: true + support: true + - name: 'Kubernetes' + items: + - name: 'Kubernetes (YAML Manifests)' + url: /gateway/VERSION/install/kubernetes/kubectl/ + oss: true + enterprise: true + support: false + - name: 'Kubernetes (Helm)' + url: /gateway/VERSION/install/kubernetes/helm-quickstart/ + oss: true + enterprise: true + support: true + - name: 'OpenShift' + url: /gateway/VERSION/install/kubernetes/openshift/ + oss: true + enterprise: true + support: false + + - name: 'Docker' + items: + - name: 'Debian (bullseye-slim)' + oss: true + enterprise: true + support: true + - name: 'RHEL (8-ubi)' + oss: true + enterprise: true + support: true + - name: 'Alpine' + oss: true + enterprise: true + support: false + + - name: 'Other' + items: + - name: 'MacOS (Homebrew)' + url: /gateway/VERSION/install/macos/ + oss: true + enterprise_text: N/A + support: false + \ No newline at end of file diff --git a/app/_data/tables/os_support.yml b/app/_data/tables/os_support.yml new file mode 100644 index 000000000000..10f0bd990675 --- /dev/null +++ b/app/_data/tables/os_support.yml @@ -0,0 +1,196 @@ +- + name: Amazon Linux 1 + enterprise: true + enterprise_versions: + first_version: 1.5.x + last_version: 2.8.x + oss: true + oss_versions: + first_version: 0.10.x + last_version: 2.8.x + status: deprecated + deprecation_date: December 31, 2020 + eol_link: https://aws.amazon.com/blogs/aws/update-on-amazon-linux-ami-end-of-life +- + name: Amazon Linux 2 + enterprise: true + enterprise_versions: + first_version: 1.5.x + last_version: null + oss: true + oss_versions: + first_version: 2.0.x + last_version: null + status: active + deprecation_date: null + eol_link: null +- + name: CentOS 6 + enterprise: true + enterprise_versions: + first_version: null + last_version: 2.3.x + oss: true + oss_versions: + first_version: 0.10.x + last_version: 2.3.x + status: deprecated + deprecation_date: November 30, 2020 + eol_link: https://endoflife.software/operating-systems/linux/centos +- + name: CentOS 7 + enterprise: true + enterprise_versions: + first_version: 2.1.x + last_version: 2.8.x + oss: true + oss_versions: + first_version: 0.10.x + last_version: 2.7.x + status: deprecated + deprecation_date: December 31, 2021 + eol_link: https://www.centos.org/centos-linux-eol/ + +- + name: CentOS 8 + enterprise: true + enterprise_versions: + first_version: 1.5.x + last_version: 2.8.x + oss: true + oss_versions: + first_version: 1.4.x + last_version: 2.7.x + status: deprecated + deprecation_date: December 31, 2021 + eol_link: https://www.centos.org/centos-linux-eol/ +- + name: Debian 8 (Jessie) + enterprise: true + enterprise_versions: + first_version: 1.5.x + last_version: 2.8.x + oss: true + oss_versions: + first_version: 0.2.x + last_version: 2.8.x + status: deprecated + deprecation_date: June 30th, 2020 + eol_link: https://www.debian.org/News/2020/20200709 +- + name: Debian 9 (Stretch) + enterprise: true + enterprise_versions: + first_version: 2.1.x + last_version: null + oss: true + oss_versions: + first_version: 0.11.x + last_version: null + status: active + deprecation_date: null + eol_link: null +- + name: Debian 10 (Buster) + enterprise: true + enterprise_versions: + first_version: 2.7.x + last_version: null + oss: true + oss_versions: + first_version: 1.4.x + last_version: null + status: active + deprecation_date: null + eol_link: null +- + name: Debian 11 (Bullseye) + enterprise: true + enterprise_versions: + first_version: 2.7.x + last_version: null + oss: true + oss_versions: + first_version: 1.4.x + last_version: null + status: active + deprecation_date: null + eol_link: null +- + name: RHEL 6 + enterprise: false + enterprise_versions: + first_version: null + last_version: null + oss: true + oss_versions: + first_version: 0.14.x + last_version: 1.5.x + status: deprecated + deprecation_date: November 30, 2020 + eol_link: https://access.redhat.com/support/policy/updates/errata +- + name: RHEL 7 + enterprise: true + enterprise_versions: + first_version: 1.5.x + last_version: null + oss: true + oss_versions: + first_version: 0.14.x + last_version: null + status: active + deprecation_date: null + eol_link: null +- + name: RHEL 8 + enterprise: true + enterprise_versions: + first_version: 1.5.x + last_version: null + oss: true + oss_versions: + first_version: 1.4.x + last_version: null + status: active + deprecation_date: null + eol_link: null +- + name: Ubuntu 16.04 (Xenial) + enterprise: true + enterprise_versions: + first_version: 1.5.x + last_version: 2.8.x + oss: true + oss_versions: + first_version: 0.10.x + last_version: 2.8.x + status: deprecated + deprecation_date: April 2021 + eol_link: https://wiki.ubuntu.com/Releases +- + name: Ubuntu 18.04 (Bionic) + enterprise: true + enterprise_versions: + first_version: 1.5.x + last_version: null + oss: true + oss_versions: + first_version: 0.14.x + last_version: null + status: active + deprecation_date: null + eol_link: null +- + name: Ubuntu 20.04 (Focal) + enterprise: true + enterprise_versions: + first_version: 2.1.x + last_version: null + oss: true + oss_versions: + first_version: 2.1.x + last_version: null + status: active + deprecation_date: null + eol_link: null diff --git a/app/_data/tables/plugin_index.yml b/app/_data/tables/plugin_index.yml index 5ee83b6c651a..e7c6f283ff69 100644 --- a/app/_data/tables/plugin_index.yml +++ b/app/_data/tables/plugin_index.yml @@ -169,6 +169,22 @@ notes: -- url: /hub/kong-inc/opa + - name: TLS Handshake Modifier + free: No + plus: No + enterprise: Yes + network_config_opts: Self-managed classic, DB-less, and hybrid + notes: -- + url: /hub/kong-inc/tls-handshake-modifier + + - name: TLS Metadata Headers + free: No + plus: No + enterprise: Yes + network_config_opts: Self-managed classic, DB-less, and hybrid + notes: -- + url: /hub/kong-inc/tls-metadata-headers + - category: name: Traffic Control plugins: @@ -300,6 +316,30 @@ notes: -- url: /hub/kong-inc/route-by-header + - name: Upstream Timeout + free: No + plus: No + Enterprise: Yes + network_config_opts: All + notes: -- + url: /hub/kong-inc/upstream-timeout + + - name: WebSocket Size Limit + free: No + plus: Yes + enterprise: Yes + network_config_opts: All + notes: -- + url: /hub/kong-inc/websocket-size-limit + + - name: WebSocket Validator + free: No + plus: Yes + enterprise: Yes + network_config_opts: All + notes: -- + url: /hub/kong-inc/websocket-validator + - name: Mocking free: No plus: Yes @@ -357,6 +397,14 @@ notes: -- url: /hub/kong-inc/datadog + - name: OpenTelemetry + free: Yes + plus: Yes + enterprise: Yes + network_config_opts: All + notes: -- + url: /hub/kong-inc/opentelemetry + - name: Prometheus free: Yes plus: Yes diff --git a/app/_hub/SmartParkingTechnology/google-logging/_index.md b/app/_hub/SmartParkingTechnology/google-logging/_index.md index 1d2419f138a2..912334dcfa2c 100644 --- a/app/_hub/SmartParkingTechnology/google-logging/_index.md +++ b/app/_hub/SmartParkingTechnology/google-logging/_index.md @@ -14,7 +14,7 @@ description: | support_url: https://github.com/SmartParkingTechnology/kong-google-logging-plugin/issues -source_url: https://github.com/SmartParkingTechnology/kong-google-logging-plugin +source_code: https://github.com/SmartParkingTechnology/kong-google-logging-plugin license_type: Apache-2.0 diff --git a/app/_hub/_init/my-extension/_index.md b/app/_hub/_init/my-extension/_index.md index 4dbdd12ba9d4..f2466ffd1fd1 100644 --- a/app/_hub/_init/my-extension/_index.md +++ b/app/_hub/_init/my-extension/_index.md @@ -67,7 +67,7 @@ description: #| # (Optional) A specific URL of your own for this extension. # Defaults to the url setting in your publisher profile. -#source_url: +#source_code: # (Optional) If your extension is open source, provide a link to your code. #license_type: diff --git a/app/_hub/arecabay/ab-microsensor/_index.md b/app/_hub/arecabay/ab-microsensor/_index.md index dca531cbede9..77c07093b646 100644 --- a/app/_hub/arecabay/ab-microsensor/_index.md +++ b/app/_hub/arecabay/ab-microsensor/_index.md @@ -20,7 +20,7 @@ description: | support_url: https://www.arecabay.com/partners/kong#support -source_url: +source_code: https://luarocks.org/modules/sekhar-arecabay/ab-microsensor #license_type: diff --git a/app/_hub/bitnami/microsoft_azure/_index.md b/app/_hub/bitnami/microsoft_azure/_index.md index d0fafbb48e61..e75ba44d6677 100644 --- a/app/_hub/bitnami/microsoft_azure/_index.md +++ b/app/_hub/bitnami/microsoft_azure/_index.md @@ -21,8 +21,6 @@ description: | support_url: https://bitnami.com/support/azure -source_url: # (Optional) If your extension is open source, provide a link to your code. - # license_type: Apache-2.0 # (Optional) For open source, use the abbreviations in parentheses at: # https://opensource.org/licenses/alphabetical diff --git a/app/_hub/critical-blue/approov/_index.md b/app/_hub/critical-blue/approov/_index.md index 9a6456ac8f56..db9d3811895d 100644 --- a/app/_hub/critical-blue/approov/_index.md +++ b/app/_hub/critical-blue/approov/_index.md @@ -16,7 +16,7 @@ description: | support_url: https://approov.zendesk.com/hc/en-gb/requests/new -source_url: https://github.com/approov/kong_approov-plugin +source_code: https://github.com/approov/kong_approov-plugin kong_version_compatibility: community_edition: diff --git a/app/_hub/flash/set-dynamic-upstream-host/_index.md b/app/_hub/flash/set-dynamic-upstream-host/_index.md index fe255c5ebfb2..ed2a796a9413 100644 --- a/app/_hub/flash/set-dynamic-upstream-host/_index.md +++ b/app/_hub/flash/set-dynamic-upstream-host/_index.md @@ -14,7 +14,7 @@ description: | support_url: https://github.com/anup-krai/kong-plugin-set-dynamic-target-host/issues -source_url: https://github.com/anup-krai/kong-plugin-set-dynamic-target-host +source_code: https://github.com/anup-krai/kong-plugin-set-dynamic-target-host license_type: Apache-2.0 type: plugin diff --git a/app/_hub/index.html b/app/_hub/index.html index a00a20bcc650..f018d95cda8d 100644 --- a/app/_hub/index.html +++ b/app/_hub/index.html @@ -31,7 +31,7 @@

Introduction

diff --git a/app/_hub/inspur/apig-request-transformer/_index.md b/app/_hub/inspur/apig-request-transformer/_index.md index a68e3b37efce..b857e1e49a3b 100644 --- a/app/_hub/inspur/apig-request-transformer/_index.md +++ b/app/_hub/inspur/apig-request-transformer/_index.md @@ -18,7 +18,7 @@ description: | support_url: https://github.com/cheriL/apig-request-transformer/issues -source_url: https://github.com/cheriL/apig-request-transformer +source_code: https://github.com/cheriL/apig-request-transformer license_type: Apache-2.0 diff --git a/app/_hub/inspur/apig-response-transform/_index.md b/app/_hub/inspur/apig-response-transform/_index.md index ed375a6ecf5b..d2f0eb96625b 100644 --- a/app/_hub/inspur/apig-response-transform/_index.md +++ b/app/_hub/inspur/apig-response-transform/_index.md @@ -8,7 +8,7 @@ desc: kong plugin to transform http response from json to xml description: | This plugin transform the response sent by the upstream server on the fly on Kong from json to xml,before returning the response to the client.Because of Nginx's internals, the `Content-Length` header will not be set when transforming a response body. support_url: https://github.com/kakascx/apig-response-transform/issues -source_url: https://github.com/kakascx/apig-response-transform +source_code: https://github.com/kakascx/apig-response-transform license_type: Apache-2.0 license_url: https://github.com/kakascx/apig-response-transform/blob/master/LICENSE diff --git a/app/_hub/justeat/kongverge/_index.md b/app/_hub/justeat/kongverge/_index.md index 5eb71e8b37c5..64e12eeb2076 100644 --- a/app/_hub/justeat/kongverge/_index.md +++ b/app/_hub/justeat/kongverge/_index.md @@ -28,7 +28,7 @@ description: | support_url: https://github.com/justeat/kongverge/issues -source_url: https://github.com/justeat/kongverge +source_code: https://github.com/justeat/kongverge license_type: Apache-2.0 diff --git a/app/_hub/kong-inc/acl/0.1-x.md b/app/_hub/kong-inc/acl/0.1-x.md deleted file mode 100644 index d8f24a310396..000000000000 --- a/app/_hub/kong-inc/acl/0.1-x.md +++ /dev/null @@ -1,174 +0,0 @@ ---- -name: ACL -publisher: Kong Inc. -version: 0.1-x - -desc: Control which consumers can access APIs -description: | - Restrict access to a Service or a Route (or the deprecated API entity) by whitelisting or blacklisting consumers using arbitrary ACL group names. This plugin requires an [authentication plugin](/hub/#authentication) to have been already enabled on the Service or the Route (or API). - -
- Note: The functionality of this plugin as bundled - with versions of Kong Gateway (OSS) prior to 0.14.1 and Kong Gateway prior to 0.34 - differs from what is documented herein. Refer to the - CHANGELOG - for details. -
- -type: plugin -categories: - - traffic-control - -kong_version_compatibility: - community_edition: - compatible: - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x -# incompatible: -# - 0.4.x -# - 0.3.x -# - 0.2.x - enterprise_edition: - compatible: - - 0.34-x - - 0.33-x - - 0.32-x - - 0.31-x -# incompatible: - -params: - name: acl - api_id: true - service_id: true - route_id: true - consumer_id: false - config: - - name: whitelist - required: semi - default: - value_in_examples: group1, group2 - description: | - Comma separated list of arbitrary group names that are allowed to consume the Service or the Route (or API). One of `config.whitelist` or `config.blacklist` must be specified. - - name: blacklist - required: semi - default: - description: | - Comma separated list of arbitrary group names that are not allowed to consume the Service or the Route (or API). One of `config.whitelist` or `config.blacklist` must be specified. - - name: hide_groups_header - required: false - default: false - value_in_examples: true - description: | - Flag which if enabled (`true`), prevents the `X-Consumer-Groups` header to be sent in the request to the upstream service. - extra: | - Note that the `whitelist` and `blacklist` models are mutually exclusive in their usage, as they provide complimentary approaches. That is, you cannot configure an ACL with both `whitelist` and `blacklist` configurations. An ACL with a `whitelist` provides a positive security model, in which the configured groups are allowed access to the resources, and all others are inherently rejected. By contrast, a `blacklist` configuration provides a negative security model, in which certain groups are explicitly denied access to the resource (and all others are inherently allowed). ---- - -### Usage - -In order to use this plugin, you need to properly have configured your Service or Route (or API) with an [authentication plugin](/hub/#authentication) so that the plugin can identify who is the client [Consumer][consumer-object] making the request. - -#### Associating Consumers - -Once you have added an authentication plugin to a Service or a Route (or API) and you have created your [Consumers][consumer-object], you can now associate a group to a [Consumer][consumer-object] using the following request: - -```bash -$ curl -X POST http://kong:8001/consumers/{consumer}/acls \ - --data "group=group1" -``` - -`consumer`: The `id` or `username` property of the [Consumer][consumer-object] entity to associate the credentials to. - -form parameter | default| description ---- | --- | --- -`group` | | The arbitrary group name to associate to the consumer. - -You can have more than one group associated to a consumer. - -#### Upstream Headers - -When a consumer has been validated, the plugin will append a `X-Consumer-Groups` header to the request before proxying it to the upstream service, so that you can identify the groups associated with the consumer. The value of the header is a comma separated list of groups that belong to the consumer, like `admin, pro_user`. - -This header will not be injected in the request to the upstream service if the `hide_groups_header` config flag is set to `true`. - -#### Paginate through the ACLs - -
- Note: This endpoint was introduced in Kong 0.11.2. -
- -You can retrieve all the ACLs for all Consumers using the following -request: - -```bash -$ curl -X GET http://kong:8001/acls - -{ - "total": 3, - "data": [ - { - "group": "foo-group", - "created_at": 1511391159000, - "id": "724d1be7-c39e-443d-bf36-41db17452c75", - "consumer_id": "89a41fef-3b40-4bb0-b5af-33da57a7ffcf" - }, - { - "group": "bar-group", - "created_at": 1511391162000, - "id": "0905f68e-fee3-4ecb-965c-fcf6912bf29e", - "consumer_id": "c0d92ba9-8306-482a-b60d-0cfdd2f0e880" - }, - { - "group": "baz-group", - "created_at": 1509814006000, - "id": "ff883d4b-aee7-45a8-a17b-8c074ba173bd", - "consumer_id": "c0d92ba9-8306-482a-b60d-0cfdd2f0e880" - } - ] -} -``` - -You can filter the list using the following query parameters: - -Attributes | Description ----:| --- -`id`
*optional* | A filter on the list based on the ACL `id` field. -`group`
*optional* | A filter on the list based on the ACL `group` field. -`consumer_id`
*optional* | A filter on the list based on the ACL `consumer_id` field. -`size`
*optional, default is __100__* | A limit on the number of objects to be returned. -`offset`
*optional* | A cursor used for pagination. `offset` is an object identifier that defines a place in the list. - -#### Retrieve the Consumer associated with an ACL - -
- Note: This endpoint was introduced in Kong 0.11.2. -
- -It is possible to retrieve a [Consumer][consumer-object] associated with an ACL -using the following request: - -```bash -curl -X GET http://kong:8001/acls/{id}/consumer - -{ - "created_at":1507936639000, - "username":"foo", - "id":"c0d92ba9-8306-482a-b60d-0cfdd2f0e880" -} -``` - -`id`: The `id` property of the ACL for which to get the associated -[Consumer][consumer-object]. - -[cidr]: https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing#CIDR_notation -[api-object]: /gateway/latest/admin-api/#api-object -[configuration]: /gateway/latest/reference/configuration -[consumer-object]: /gateway/latest/admin-api/#consumer-object diff --git a/app/_hub/kong-inc/acl/_index.md b/app/_hub/kong-inc/acl/_index.md index cc8a972a00b9..b7c5006e2bc2 100644 --- a/app/_hub/kong-inc/acl/_index.md +++ b/app/_hub/kong-inc/acl/_index.md @@ -1,7 +1,6 @@ --- name: ACL publisher: Kong Inc. -version: 1.0.0 desc: Control which Consumers can access Services description: | Restrict access to a Service or a Route by adding Consumers to allowed or @@ -16,45 +15,10 @@ categories: - traffic-control kong_version_compatibility: community_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x + compatible: true enterprise_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x + compatible: true + params: name: acl service_id: true @@ -69,6 +33,22 @@ params: Admin API endpoints that POST, PUT, PATCH, or DELETE ACLs do not work in DB-less mode. config: + # deprecated parameters + - name: whitelist + required: semi + default: + value_in_examples: group1, group2 + description: | + Comma separated list of arbitrary group names that are allowed to consume the Service or the Route (or API). One of `config.whitelist` or `config.blacklist` must be specified. + maximum_version: "2.0.x" + - name: blacklist + required: semi + default: + description: | + Comma separated list of arbitrary group names that are not allowed to consume the Service or the Route (or API). One of `config.whitelist` or `config.blacklist` must be specified. + maximum_version: "2.0.x" + + # current parameters - name: allow required: semi default: null @@ -78,12 +58,14 @@ params: datatype: array of string elements description: | Arbitrary group names that are allowed to consume the Service or Route. One of `config.allow` or `config.deny` must be specified. + minimum_version: "2.1.x" - name: deny required: semi default: null datatype: array of string elements description: | Arbitrary group names that are not allowed to consume the Service or Route. One of `config.allow` or `config.deny` must be specified. + minimum_version: "2.1.x" - name: hide_groups_header required: true default: false @@ -91,11 +73,28 @@ params: datatype: boolean description: | Flag that if enabled (`true`), prevents the `X-Consumer-Groups` header to be sent in the request to the Upstream service. - extra: | - Note that you cannot configure an ACL with both `allow` and `deny` configurations. An ACL with an `allow` provides a positive security model, in which the configured groups are allowed access to the resources, and all others are inherently rejected. By contrast, a `deny` configuration provides a negative security model, in which certain groups are explicitly denied access to the resource (and all others are allowed). --- -### Usage +{% if_plugin_version eq:2.0.x %} + +The `whitelist` and `blacklist` models are mutually exclusive in their usage, as they provide complimentary approaches. That is, you cannot configure an ACL with both `whitelist` and `blacklist` configurations. An ACL with a `whitelist` provides a positive security model, in which the configured groups are allowed access to the resources, and all others are inherently rejected. By contrast, a `blacklist` configuration provides a negative security model, in which certain groups are explicitly denied access to the resource (and all others are inherently allowed). + +{% endif_plugin_version %} + +{% if_plugin_version gte:2.1.x %} + +You can't configure an ACL with both `allow` and `deny` configurations. An ACL with an `allow` provides a positive security model, in which the configured groups are allowed access to the resources, and all others are inherently rejected. By contrast, a `deny` configuration provides a negative security model, in which certain groups are explicitly denied access to the resource (and all others are allowed). + +{% endif_plugin_version %} + +## Usage + +{% if_plugin_version gte:2.1.x and lte:2.8.x %} + +{:.note} +> **Note**: We have deprecated the usage of `whitelist` and `blacklist` in favor of `allow` and `deny`. This change may require Admin API requests to be updated. + +{% endif_plugin_version %} Before you use the ACL plugin, configure your Service or Route with an [authentication plugin](/hub/#authentication) @@ -122,7 +121,7 @@ curl -X POST http://{HOST}:8001/consumers/{CONSUMER}/acls \ form parameter | default| description --- | --- | --- `group` | | The arbitrary group name to associate with the consumer. -`tags` | | Optional descriptor tags for the group. +`tags` | | Optional descriptor tags for the group. {% endnavtab %} {% navtab Without a database %} @@ -137,13 +136,13 @@ acls: * `CONSUMER`: The `id` or `username` property of the Consumer entity to associate the credentials to. * `group`: The arbitrary group name to associate to the Consumer. -* `tags`: Optional descriptor tags for the group. +* `tags`: Optional descriptor tags for the group. {% endnavtab %} {% endnavtabs %} You can have more than one group associated to a consumer. -#### Upstream Headers +### Upstream Headers When a consumer has been validated, the plugin appends a `X-Consumer-Groups` header to the request before proxying it to the Upstream service, so that you can @@ -153,13 +152,16 @@ comma-separated list of groups that belong to the consumer, like `admin, pro_use This header will not be injected in the request to the upstream service if the `hide_groups_header` config flag is set to `true`. -#### Return ACLs +### Return ACLs -Retrieves paginated ACLs. +Retrieves paginated ACLs. ```bash curl -X GET http://{HOST}:8001/acls +``` +Result: +``` { "total": 3, "data": [ @@ -187,11 +189,14 @@ curl -X GET http://{HOST}:8001/acls #### Retrieve ACLs by consumer -Retrieves ACLs by consumer. +Retrieves ACLs by consumer. ```bash curl -X GET http://{HOST}:8001/consumers/{CONSUMER}/acls +``` +Result: +``` { "total": 1, "data": [ @@ -207,13 +212,16 @@ curl -X GET http://{HOST}:8001/consumers/{CONSUMER}/acls `CONSUMER`: The `username` or `id` of the consumer. -#### Retrieve ACL by ID +### Retrieve ACL by ID -Retrieves ACL by ID if the ACL belongs to the specified consumer. +Retrieves ACL by ID if the ACL belongs to the specified consumer. ```bash curl -X GET http://{HOST}:8001/consumers/{CONSUMER}/acls/{ID} +``` +Result: +``` { "group": "foo-group", "created_at": 1511391159000, @@ -233,7 +241,10 @@ using the following request: ```bash curl -X GET http://{HOST}:8001/acls/{ID}/consumer +``` +Result: +``` { "created_at":1507936639000, "username":"foo", @@ -245,7 +256,7 @@ curl -X GET http://{HOST}:8001/acls/{ID}/consumer #### Update and insert an ACL group name -Update and insert the group name of the ACL by passing a new group name. +Update and insert the group name of the ACL by passing a new group name. ```bash curl -X PUT http://{HOST}:8001/consumers/{CONSUMER}/acls/{ID} @@ -256,9 +267,9 @@ curl -X PUT http://{HOST}:8001/consumers/{CONSUMER}/acls/{ID} `ID`: The `id` property of the ACL. -#### Update an ACL group by ID +### Update an ACL group by ID -Updates an ACL group name by passing a new group name. +Updates an ACL group name by passing a new group name. ```bash curl -X POST http://{HOST}:8001/consumers/{CONSUMER}/acls \ @@ -286,7 +297,18 @@ curl -X DELETE http://{HOST}:8001/consumers/{CONSUMER}/acls/{GROUP} `GROUP`: The `group` property of the ACL. -A successful DELETE request returns a `204` status. +A successful DELETE request returns a `204` status. -#### See also +### See also - [configuration](/gateway/latest/reference/configuration) + +--- + +## Changelog + +**{{site.base_gateway}} 3.0.x** +- Removed the deprecated `whitelist` and `blacklist` parameters. +They are no longer supported. + +**{{site.base_gateway}} 2.1.x** +- Use `allow` and `deny` instead of `whitelist` and `blacklist` diff --git a/app/_hub/kong-inc/acl/versions.yml b/app/_hub/kong-inc/acl/versions.yml index f56356207baf..59d55d91e74a 100644 --- a/app/_hub/kong-inc/acl/versions.yml +++ b/app/_hub/kong-inc/acl/versions.yml @@ -1,2 +1,12 @@ -- release: 1.0-x -- release: 0.1-x +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 3.0.1 + 2.7.x: 3.0.1 + 2.6.x: 3.0.1 + 2.5.x: 3.0.1 + 2.4.x: 3.0.1 + 2.3.x: 3.0.1 + 2.2.x: 3.0.1 + 2.1.x: 3.0.1 diff --git a/app/_hub/kong-inc/acme/0.2.11.md b/app/_hub/kong-inc/acme/0.2.11.md deleted file mode 100644 index 8990c74c705e..000000000000 --- a/app/_hub/kong-inc/acme/0.2.11.md +++ /dev/null @@ -1,353 +0,0 @@ ---- -name: ACME -publisher: Kong Inc. -version: 0.2.11 - -source_url: https://github.com/Kong/kong-plugin-acme - -desc: Let's Encrypt and ACMEv2 integration with Kong -description: | - This plugin allows Kong to apply certificates from Let's Encrypt or any other ACMEv2 service and serve dynamically. Renewal is handled with a configurable threshold time. - -type: plugin -categories: - - security - -kong_version_compatibility: - community_edition: - compatible: - - 2.2.x - - 2.1.x - - 2.0.x - enterprise_edition: - compatible: - - 2.2.x - - 2.1.x - -params: - name: acme - api_id: false - service_id: false - route_id: false - consumer_id: false - protocols: ['http', 'https', 'tcp', 'tls', 'grpc', 'grpcs'] - dbless_compatible: yes - config: - - name: account_email - required: yes - default: - value_in_examples: example@example.com - description: | - The account identifier, can be reused in different plugin instance. - - name: api_uri - required: false - default: "`https://acme-v02.api.letsencrypt.org`" - description: | - The ACMEv2 API endpoint to use. Users can specify the [Let's Encrypt staging environment](https://letsencrypt.org/docs/staging-environment/) (`https://acme-staging-v02.api.letsencrypt.org/directory`) for testing. Note that Kong doesn't automatically delete staging certificates: if you use same domain to test and use in production, you will need to delete those certificates manually after testing. - - name: cert_type - required: false - default: "`rsa`" - description: | - The certificate type to create. The possible values are `"rsa"` for RSA certificate or `"ecc"` for EC certificate. - - name: domains - required: false - default: "`[]`" - description: | - The list of domains to create certificate for. To match subdomains under `example.com`, use `*.example.com`. Regex pattern is not supported. Note this config is only used to match domains, not to specify the Common Name or Subject Alternative Name to create certifcates; each domain will have its own certificate. ACME plugin checks this configuration before the presense of certificate in `storage` when serving certificate of a request. - - name: fail_backoff_minutes - required: false - default: 5 - description: | - Minutes to wait for each domain that fails to create a certificate. This applies to both new certificate and renewal. - - name: renew_threshold_days - required: false - default: "`14`" - description: | - Days before expire to renew the certificate. - - name: storage - required: false - default: "`shm`" - description: | - The backend storage type to use. The possible values are `"kong"`, `"shm"`, `"redis"`, `"consul"`, or `"vault"`. In DB-less mode, `"kong"` storage is unavailable. Note that `"shm"` storage does not persist during Kong restarts and does not work for Kong running on different machines, so consider using one of `"kong"`, `"redis"`, `"consul"`, or `"vault"` in production. - - name: storage_config - required: false - default: - description: | - Storage configs for each backend storage. See below for its default value. - - name: tos_accepted - required: false - default: "`false`" - description: | - If you are using Let's Encrypt, you must set this to true to agree the [Terms of Service](https://letsencrypt.org/repository/). - extra: | - `config.storage_config` is a table for all possible storage types, by default it is: - ```json - "storage_config": { - "kong": {}, - "shm": { - "shm_name": "kong" - }, - "redis": { - "auth": null, - "port": 6379, - "database": 0, - "host": "127.0.0.1" - }, - "consul": { - "host": "127.0.0.1", - "port": 8500, - "token": null, - "kv_path": "acme", - "timeout": 2000, - "https": false - }, - "vault": { - "host": "127.0.0.1", - "port": 8200, - "token": null, - "kv_path": "acme", - "timeout": 2000, - "https": false, - "tls_verify": true, - "tls_server_name": null - }, - } - ``` - - To configure storage type other than `kong`, please refer to [lua-resty-acme](https://github.com/fffonion/lua-resty-acme#storage-adapters). - ---- - -### Workflow - -A `http-01` challenge workflow between the {{site.base_gateway}} and the ACME server is described below: - -1. The client sends a proxy or Admin API request that triggers certificate generation for `mydomain.com`. -2. The {{site.base_gateway}} sends a request to the ACME server to start the validation process. -3. The ACME server returns a challenge response detail to the {{site.base_gateway}}. -4. `mydomain.com` is publicly resolvable to the {{site.base_gateway}} that serves the challenge response. -5. The ACME server checks if the previous challenge has a response at `mydomain.com`. -6. The {{site.base_gateway}} checks the challenge status and if passed, downloads the certificate from the ACME server. -7. The {{site.base_gateway}} uses the new certificate to serve TLS requests. - -### Using the Plugin - -#### Configure Kong - -- Kong needs to listen on port 80 or proxy a load balancer that listens for port 80. -- `lua_ssl_trusted_certificate` needs to be set in `kong.conf` to ensure the plugin can properly -verify the Let's Encrypt API. The CA-bundle file is usually `/etc/ssl/certs/ca-certificates.crt` for -Ubuntu/Debian and `/etc/ssl/certs/ca-bundle.crt` for CentOS/Fedora/RHEL. Starting with Kong v2.2, -users can set this config to `system` to auto pick CA-bundle from OS. - -#### Configure Plugin - -Here's a sample declarative configuration with `redis` as storage: - -```yaml -_format_version: "1.1" -# this section is not necessary if there's already a route that matches -# /.well-known/acme-challenge path with http protocol -services: - - name: acme-dummy - url: http://127.0.0.1:65535 - routes: - - name: acme-dummy - protocols: - - http - paths: - - /.well-known/acme-challenge -plugins: - - name: acme - config: - account_email: example@myexample.com - domains: - - "*.example.com" - - "example.com" - tos_accepted: true - storage: redis - storage_config: - redis: - host: redis.service - port: 6379 -``` - -#### Enable the Plugin - -For each the domain that needs a certificate, make sure `DOMAIN/.well-known/acme-challenge` -is mapped to a Route in Kong. You can check this by sending -`curl KONG_IP/.well-known/acme-challenge/x -H "host:DOMAIN"` and getting the response `Not found`. -You can also [use the Admin API](#create-certificates) to verify the setup. -If not, add a Route and a dummy Service to catch this route. -```bash -# add a dummy service if needed -$ curl http://localhost:8001/services \ - -d name=acme-dummy \ - -d url=http://127.0.0.1:65535 - -# add a dummy route if needed -$ curl http://localhost:8001/routes \ - -d name=acme-dummy \ - -d paths[]=/.well-known/acme-challenge \ - -d service.name=acme-dummy - -# add the plugin -$ curl http://localhost:8001/plugins \ - -d name=acme \ - -d config.account_email=yourname@yourdomain.com \ - -d config.tos_accepted=true \ - -d config.domains[]=my.secret.domains.com -``` - -Note by setting `tos_accepted` to *true* implies that you have read and accepted -[terms of service](https://letsencrypt.org/repository/). - -**This plugin can only be configured as a global plugin.** The plugin terminates -`/.well-known/acme-challenge/` path for matching domains. To create certificates -and terminate challenges only for certain domains, please refer to the -[Parameters](#parameters) section. - -#### Trigger creation of certificate - -Assume Kong proxy is accessible via http://mydomain.com and https://mydomain.com. - -```bash -# Trigger asynchronous creation from proxy requests -# The following request returns immediately with Kong's default certificate -# Wait up to 1 minute for the background process to finish -$ curl https://mydomain.com -k - -# OR create from Admin API synchronously -# User can also use this endpoint to force "renew" a certificate -$ curl http://localhost:8001/acme -d host=mydomain.com - -# Furthermore, it's possible to run a sanity test on your Kong setup -# before creating any certificate -$ curl http://localhost:8001/acme -d host=mydomain.com -d test_http_challenge_flow=true - -$ curl https://mydomain.com -# Now gives you a valid Let's Encrypt certicate -``` - -#### Renew certificates - -The plugin runs daily checks and automatically renews all certificates that -will expire in less than the configured `renew_threshold_days` value. If the renewal -of an individual certificate throws an error, the plugin will continue renewing the -other certificates. It will try renewing all certificates, including those that previously -failed, once per day. Note the renewal configuration is stored in the configured storage backend. -If the storage is cleared or modified outside of Kong, renewal might not complete properly. - -It's also possible to actively trigger the renewal. The following request -schedules a renewal in the background and returns immediately. - -```bash -$ curl http://localhost:8001/acme -XPATCH -``` - -### Monitoring and debugging - -The ACME plugin exposes several endpoints through Admin API that can be used for -debugging and monitoring certificate creation and renewal. - -- **POST /acme**: start applying or renewing certificate and return the result; available parameter: - - **host**: the domain to create certificate - - **test_http_challenge_flow**: when set, only check for configuration sanity. -- **PATCH /acme**: same as POST, but runs the process at background. -- **GET /acme/certificates**: list the certificate being created by ACME plugin; one can use this endpoint to monitor certificate existence and expiry. -- **GET /acme/certificates/:host**: list the certificate with specific host. - -Following is an example of the certificate listing API: - -``` -{ - "data": [ - { - "not_after": "2022-09-21 23:59:59", - "pubkey_type": "id-ecPublicKey", - "digest": "A9:49:55:06:A7:B6:1D:2B:13:47:C5:58:5B:AC:DA:43:B5:25:E0:86", - "issuer_cn": "ZeroSSL ECC Domain Secure Site CA", - "valid": true, - "host": "subdomain1.domain.com", - "not_before": "2022-06-23 00:00:00", - "serial_number": "93:B8:E9:D5:C6:36:ED:B4:A8:B3:FD:C5:9E:A8:08:88" - }, - { - "not_after": "2022-09-21 23:59:59", - "pubkey_type": "id-ecPublicKey", - "digest": "26:12:A2:C4:6A:F5:A5:90:9D:03:15:CB:FE:A7:BF:32:1C:42:49:CE", - "issuer_cn": "ZeroSSL ECC Domain Secure Site CA", - "valid": true, - "host": "subdomain2.domain.com", - "not_before": "2022-06-23 00:00:00", - "serial_number": "F1:15:74:E3:E1:DD:21:72:48:C0:4F:06:25:1B:71:F7" - } - ] -} -``` - - -### Local testing and development - -#### Run ngrok - -[ngrok](https://ngrok.com) exposes a local URL to the internet. [Download ngrok](https://ngrok.com/download) and install. - -*`ngrok` is only needed for local testing or development, it's **not** a requirement for the plugin itself.* - -Run ngrok with - -```bash -$ ./ngrok http localhost:8000 -# Shows something like -# ... -# Forwarding http://e2e034a5.ngrok.io -> http://localhost:8000 -# Forwarding https://e2e034a5.ngrok.io -> http://localhost:8000 -# ... -# Substitute "e2e034a5.ngrok.io" with the host shows in your ngrok output -$ export NGROK_HOST=e2e034a5.ngrok.io -``` - -Leave the process running. - -#### Configure Route and Service - -```bash -$ curl http://localhost:8001/services -d name=acme-test -d url=http://mockbin.org -$ curl http://localhost:8001/routes -d service.name=acme-test -d hosts=$NGROK_HOST -``` - -#### Enable Plugin - -```bash -$ curl localhost:8001/plugins -d name=acme \ - -d config.account_email=test@test.com \ - -d config.tos_accepted=true \ - -d config.domains[]=$NGROK_HOST -``` - -#### Trigger creation of certificate - -```bash -$ curl https://$NGROK_HOST:8443 --resolve $NGROK_HOST:8443:127.0.0.1 -vk -# Wait for several seconds -``` - -#### Check new certificate - -```bash -$ echo q |openssl s_client -connect localhost -port 8443 -servername $NGROK_HOST 2>/dev/null |openssl x509 -text -noout -``` - -### Notes - -- In database mode, the plugin creates SNI and Certificate entity in Kong to -serve certificate. If SNI or Certificate for current request is already set -in database, they will be overwritten. -- In DB-less mode, the plugin takes over certificate handling. If the SNI or -Certificate entity is already defined in Kong, they will be overridden by the -response. -- The plugin only supports http-01 challenge, meaning user will need a public -IP and setup resolvable DNS. Kong also needs to accept proxy traffic from port `80`. -Also, note that wildcard or star certificate is not supported, each domain will have its -own certificate. diff --git a/app/_hub/kong-inc/acme/0.2.13.md b/app/_hub/kong-inc/acme/0.2.13.md deleted file mode 100644 index 3806680c4cb5..000000000000 --- a/app/_hub/kong-inc/acme/0.2.13.md +++ /dev/null @@ -1,372 +0,0 @@ ---- -name: ACME -publisher: Kong Inc. -version: 0.2.13 - -source_url: https://github.com/Kong/kong-plugin-acme - -desc: Let's Encrypt and ACMEv2 integration with Kong -description: | - This plugin allows Kong to apply certificates from Let's Encrypt or any other ACMEv2 service and serve dynamically. Renewal is handled with a configurable threshold time. - -type: plugin -categories: - - security - -kong_version_compatibility: - community_edition: - compatible: - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 2.0.x - enterprise_edition: - compatible: - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - -params: - name: acme - api_id: false - service_id: false - route_id: false - consumer_id: false - protocols: ['http', 'https', 'tcp', 'tls', 'grpc', 'grpcs'] - dbless_compatible: yes - config: - - name: account_email - required: yes - default: - value_in_examples: example@example.com - description: | - The account identifier, can be reused in different plugin instance. - - name: api_uri - required: false - default: "`https://acme-v02.api.letsencrypt.org`" - description: | - The ACMEv2 API endpoint to use. Users can specify the [Let's Encrypt staging environment](https://letsencrypt.org/docs/staging-environment/) (`https://acme-staging-v02.api.letsencrypt.org/directory`) for testing. Note that Kong doesn't automatically delete staging certificates: if you use same domain to test and use in production, you will need to delete those certificates manually after testing. - - name: cert_type - required: false - default: "`rsa`" - description: | - The certificate type to create. The possible values are `"rsa"` for RSA certificate or `"ecc"` for EC certificate. - - name: domains - required: false - default: "`[]`" - description: | - The list of domains to create certificate for. To match subdomains under `example.com`, use `*.example.com`. Regex pattern is not supported. Note this config is only used to match domains, not to specify the Common Name or Subject Alternative Name to create certifcates; each domain will have its own certificate. ACME plugin checks this configuration before the presense of certificate in `storage` when serving certificate of a request. - - name: fail_backoff_minutes - required: false - default: 5 - description: | - Minutes to wait for each domain that fails to create a certificate. This applies to both new certificate and renewal. - - name: renew_threshold_days - required: false - default: "`14`" - description: | - Days before expire to renew the certificate. - - name: storage - required: false - default: "`shm`" - description: | - The backend storage type to use. The possible values are `"kong"`, `"shm"`, `"redis"`, `"consul"`, or `"vault"`. In DB-less mode, `"kong"` storage is unavailable. Note that `"shm"` storage does not persist during Kong restarts and does not work for Kong running on different machines, so consider using one of `"kong"`, `"redis"`, `"consul"`, or `"vault"` in production. - - name: storage_config - required: false - default: - description: | - Storage configs for each backend storage. See below for its default value. - - name: tos_accepted - required: false - default: "`false`" - description: | - If you are using Let's Encrypt, you must set this to true to agree the [Terms of Service](https://letsencrypt.org/repository/). - - name: eab_kid - required: false - description: | - External account binding (EAB) key id. You usually don't need to set this unless it is explicitly required by the CA. - - name: eab_hmac_key - required: false - description: | - External account binding (EAB) base64-encoded URL string of the HMAC key. You usually don't need to set this unless it is explicitly required by the CA. - extra: | - `config.storage_config` is a table for all possible storage types. By default, it is: - ```json - "storage_config": { - "kong": {}, - "shm": { - "shm_name": "kong" - }, - "redis": { - "auth": null, - "port": 6379, - "database": 0, - "host": "127.0.0.1" - }, - "consul": { - "host": "127.0.0.1", - "port": 8500, - "token": null, - "kv_path": "acme", - "timeout": 2000, - "https": false - }, - "vault": { - "host": "127.0.0.1", - "port": 8200, - "token": null, - "kv_path": "acme", - "timeout": 2000, - "https": false, - "tls_verify": true, - "tls_server_name": null - }, - } - ``` - - To configure a storage type other than `kong`, refer to [lua-resty-acme](https://github.com/fffonion/lua-resty-acme#storage-adapters). - - External account binding (EAB) is supported as long as `eab_kid` and `eab_hmac_key` are provided. - - The following CA provider's external account can be registered automatically, without specifying - the `eab_kid` or `eab_hmac_key`: - - - [ZeroSSL](https://zerossl.com/) - ---- - -### Workflow - -A `http-01` challenge workflow between the {{site.base_gateway}} and the ACME server is described below: - -1. The client sends a proxy or Admin API request that triggers certificate generation for `mydomain.com`. -2. The {{site.base_gateway}} sends a request to the ACME server to start the validation process. -3. The ACME server returns a challenge response detail to the {{site.base_gateway}}. -4. `mydomain.com` is publicly resolvable to the {{site.base_gateway}} that serves the challenge response. -5. The ACME server checks if the previous challenge has a response at `mydomain.com`. -6. The {{site.base_gateway}} checks the challenge status and if passed, downloads the certificate from the ACME server. -7. The {{site.base_gateway}} uses the new certificate to serve TLS requests. - -### Using the Plugin - -#### Configure Kong - -- Kong needs to listen on port 80 or proxy a load balancer that listens for port 80. -- `lua_ssl_trusted_certificate` needs to be set in `kong.conf` to ensure the plugin can properly -verify the Let's Encrypt API. The CA-bundle file is usually `/etc/ssl/certs/ca-certificates.crt` for -Ubuntu/Debian and `/etc/ssl/certs/ca-bundle.crt` for CentOS/Fedora/RHEL. Starting with Kong v2.2, -users can set this config to `system` to auto pick CA-bundle from OS. - -#### Configure Plugin - -Here's a sample declarative configuration with `redis` as storage: - -```yaml -_format_version: "1.1" -# this section is not necessary if there's already a route that matches -# /.well-known/acme-challenge path with http protocol -services: - - name: acme-dummy - url: http://127.0.0.1:65535 - routes: - - name: acme-dummy - protocols: - - http - paths: - - /.well-known/acme-challenge -plugins: - - name: acme - config: - account_email: example@myexample.com - domains: - - "*.example.com" - - "example.com" - tos_accepted: true - storage: redis - storage_config: - redis: - host: redis.service - port: 6379 -``` - -#### Enable the Plugin - -For each the domain that needs a certificate, make sure `DOMAIN/.well-known/acme-challenge` -is mapped to a Route in Kong. You can check this by sending -`curl KONG_IP/.well-known/acme-challenge/x -H "host:DOMAIN"` and getting the response `Not found`. -You can also [use the Admin API](#create-certificates) to verify the setup. -If not, add a Route and a dummy Service to catch this route. - -```bash -# add a dummy service if needed -$ curl http://localhost:8001/services \ - -d name=acme-dummy \ - -d url=http://127.0.0.1:65535 - -# add a dummy route if needed -$ curl http://localhost:8001/routes \ - -d name=acme-dummy \ - -d paths[]=/.well-known/acme-challenge \ - -d service.name=acme-dummy - -# add the plugin -$ curl http://localhost:8001/plugins \ - -d name=acme \ - -d config.account_email=yourname@yourdomain.com \ - -d config.tos_accepted=true \ - -d config.domains[]=my.secret.domains.com -``` - -Note by setting `tos_accepted` to *true* implies that you have read and accepted -[terms of service](https://letsencrypt.org/repository/). - -**This plugin can only be configured as a global plugin.** The plugin terminates -`/.well-known/acme-challenge/` path for matching domains. To create certificates -and terminate challenges only for certain domains, refer to the -[Parameters](#parameters) section. - -#### Trigger creation of certificate - -Assume Kong proxy is accessible via http://mydomain.com and https://mydomain.com. - -```bash -# Trigger asynchronous creation from proxy requests -# The following request returns immediately with Kong's default certificate -# Wait up to 1 minute for the background process to finish -$ curl https://mydomain.com -k - -# OR create from Admin API synchronously -# User can also use this endpoint to force "renew" a certificate -$ curl http://localhost:8001/acme -d host=mydomain.com - -# Furthermore, it's possible to run a sanity test on your Kong setup -# before creating any certificate -$ curl http://localhost:8001/acme -d host=mydomain.com -d test_http_challenge_flow=true - -$ curl https://mydomain.com -# Now gives you a valid Let's Encrypt certicate -``` - -#### Renew certificates - -The plugin runs daily checks and automatically renews all certificates that -will expire in less than the configured `renew_threshold_days` value. If the renewal -of an individual certificate throws an error, the plugin will continue renewing the -other certificates. It will try renewing all certificates, including those that previously -failed, once per day. Note the renewal configuration is stored in the configured storage backend. -If the storage is cleared or modified outside of Kong, renewal might not complete properly. - -It's also possible to actively trigger the renewal. The following request -schedules a renewal in the background and returns immediately. - -```bash -$ curl http://localhost:8001/acme -XPATCH -``` - -### Monitoring and debugging - -The ACME plugin exposes several endpoints through Admin API that can be used for -debugging and monitoring certificate creation and renewal. - -- **POST /acme**: start applying or renewing certificate and return the result; available parameter: - - **host**: the domain to create certificate - - **test_http_challenge_flow**: when set, only check for configuration sanity. -- **PATCH /acme**: same as POST, but runs the process at background. -- **GET /acme/certificates**: list the certificate being created by ACME plugin; one can use this endpoint to monitor certificate existence and expiry. -- **GET /acme/certificates/:host**: list the certificate with specific host. - -Following is an example of the certificate listing API: - -``` -{ - "data": [ - { - "not_after": "2022-09-21 23:59:59", - "pubkey_type": "id-ecPublicKey", - "digest": "A9:49:55:06:A7:B6:1D:2B:13:47:C5:58:5B:AC:DA:43:B5:25:E0:86", - "issuer_cn": "ZeroSSL ECC Domain Secure Site CA", - "valid": true, - "host": "subdomain1.domain.com", - "not_before": "2022-06-23 00:00:00", - "serial_number": "93:B8:E9:D5:C6:36:ED:B4:A8:B3:FD:C5:9E:A8:08:88" - }, - { - "not_after": "2022-09-21 23:59:59", - "pubkey_type": "id-ecPublicKey", - "digest": "26:12:A2:C4:6A:F5:A5:90:9D:03:15:CB:FE:A7:BF:32:1C:42:49:CE", - "issuer_cn": "ZeroSSL ECC Domain Secure Site CA", - "valid": true, - "host": "subdomain2.domain.com", - "not_before": "2022-06-23 00:00:00", - "serial_number": "F1:15:74:E3:E1:DD:21:72:48:C0:4F:06:25:1B:71:F7" - } - ] -} -``` - -### Local testing and development - -#### Run ngrok - -[ngrok](https://ngrok.com) exposes a local URL to the internet. [Download ngrok](https://ngrok.com/download) and install. - -*`ngrok` is only needed for local testing or development, it's **not** a requirement for the plugin itself.* - -Run ngrok with - -```bash -$ ./ngrok http localhost:8000 -# Shows something like -# ... -# Forwarding http://e2e034a5.ngrok.io -> http://localhost:8000 -# Forwarding https://e2e034a5.ngrok.io -> http://localhost:8000 -# ... -# Substitute "e2e034a5.ngrok.io" with the host shows in your ngrok output -$ export NGROK_HOST=e2e034a5.ngrok.io -``` - -Leave the process running. - -#### Configure Route and Service - -```bash -$ curl http://localhost:8001/services -d name=acme-test -d url=http://mockbin.org -$ curl http://localhost:8001/routes -d service.name=acme-test -d hosts=$NGROK_HOST -``` - -#### Enable Plugin - -```bash -$ curl localhost:8001/plugins -d name=acme \ - -d config.account_email=test@test.com \ - -d config.tos_accepted=true \ - -d config.domains[]=$NGROK_HOST -``` - -#### Trigger creation of certificate - -```bash -$ curl https://$NGROK_HOST:8443 --resolve $NGROK_HOST:8443:127.0.0.1 -vk -# Wait for several seconds -``` - -#### Check new certificate - -```bash -$ echo q |openssl s_client -connect localhost -port 8443 -servername $NGROK_HOST 2>/dev/null |openssl x509 -text -noout -``` - -### Notes - -- In database mode, the plugin creates an SNI and Certificate entity in Kong to -serve the certificate. If SNI or Certificate for the current request is already set -in the database, they will be overwritten. -- In DB-less mode, the plugin takes over certificate handling. If the SNI or -Certificate entity is already defined in Kong, they will be overridden by the -response. -- The plugin only supports http-01 challenge, meaning a user will need a public -IP and set up a resolvable DNS. Kong also needs to accept proxy traffic from port `80`. -Also, note that a wildcard or star (*) certificate is not supported. Each domain will have its -own certificate. diff --git a/app/_hub/kong-inc/acme/0.2.14.md b/app/_hub/kong-inc/acme/0.2.14.md deleted file mode 100644 index b4a4e7bca493..000000000000 --- a/app/_hub/kong-inc/acme/0.2.14.md +++ /dev/null @@ -1,434 +0,0 @@ ---- -name: ACME -publisher: Kong Inc. -version: 0.2.14 -source_url: 'https://github.com/Kong/kong-plugin-acme' -desc: Let's Encrypt and ACMEv2 integration with Kong -description: | - This plugin allows Kong to apply certificates from Let's Encrypt or any other ACMEv2 service and serve them dynamically. - Renewal is handled with a configurable threshold time. -type: plugin -categories: - - security -kong_version_compatibility: - community_edition: - compatible: - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 2.0.x - enterprise_edition: - compatible: - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x -params: - name: acme - api_id: false - service_id: false - route_id: false - consumer_id: false - protocols: - - http - - https - - tcp - - tls - - grpc - - grpcs - dbless_compatible: 'yes' - config: - - name: account_email - required: 'yes' - default: null - value_in_examples: example@example.com - datatype: string - description: | - The account identifier. Can be reused in a different plugin instance. - - name: api_uri - required: false - default: '` https://acme-v02.api.letsencrypt.org/directory`' - datatype: string - description: | - The ACMEv2 API endpoint to use. You can specify the - [Let's Encrypt staging environment](https://letsencrypt.org/docs/staging-environment/) for testing. Kong doesn't automatically delete staging certificates. If you use the same domain in test and production environments, you need to manually delete those certificates after testing. - - name: cert_type - required: false - default: '`rsa`' - datatype: string - description: | - The certificate type to create. The possible values are `"rsa"` for RSA certificate or `"ecc"` for EC certificate. - - name: domains - required: false - default: '`[]`' - datatype: array of string elements - description: | - The list of domains to create certificate for. To match subdomains under `example.com`, use `*.example.com`. - Regex pattern is not supported. Note this config is only used to match domains, not to specify the Common Name - or Subject Alternative Name to create certificates; each domain must have its own certificate. - ACME plugin checks this configuration before the presense of certificate in `storage` when serving certificate of a request. - - name: fail_backoff_minutes - required: false - default: 5 - datatype: number - description: | - Minutes to wait for each domain that fails to create a certificate. This applies to both a - new certificate and a renewal certificate. - - name: renew_threshold_days - required: false - default: '`14`' - datatype: number - description: | - Days remaining to renew the certificate before it expires. - - name: storage - required: false - default: '`shm`' - datatype: string - description: | - The backend storage type to use. The possible values are `"kong"`, `"shm"`, `"redis"`, `"consul"`, or `"vault"`. In DB-less mode, `"kong"` storage is unavailable. Note that `"shm"` storage does not persist during Kong restarts and does not work for Kong running on different machines, so consider using one of `"kong"`, `"redis"`, `"consul"`, or `"vault"` in production. Please refer to the Hybrid Mode sections below as well. - - name: storage_config - required: false - default: null - datatype: record - description: | - Storage configs for each backend storage. See [Storage configuration considerations](#storage-config) - for information on its default values. - - name: tos_accepted - required: false - default: '`false`' - datatype: boolean - description: | - If you are using Let's Encrypt, you must set this to `true` to agree the [Terms of Service](https://letsencrypt.org/repository/). - - name: eab_kid - required: false - datatype: string - description: | - External account binding (EAB) key id. You usually don't need to set this unless it is explicitly required by the CA. - - name: eab_hmac_key - required: false - datatype: string - description: | - External account binding (EAB) base64-encoded URL string of the HMAC key. You usually don't need to set this unless it is explicitly required by the CA. - extra: | - - External account binding (EAB) is supported as long as `eab_kid` and `eab_hmac_key` are provided. - - The following CA provider's external account can be registered automatically, without specifying - the `eab_kid` or `eab_hmac_key`: - - - [ZeroSSL](https://zerossl.com/) ---- - -## Storage configuration considerations {#storage-config} - -`config.storage_config` is a table for all possible storage types. By default, it is: - -```json - "storage_config": { - "kong": {}, - "shm": { - "shm_name": "kong" - }, - "redis": { - "auth": null, - "port": 6379, - "database": 0, - "host": "127.0.0.1" - }, - "consul": { - "host": "127.0.0.1", - "port": 8500, - "token": null, - "kv_path": "acme", - "timeout": 2000, - "https": false - }, - "vault": { - "host": "127.0.0.1", - "port": 8200, - "token": null, - "kv_path": "acme", - "timeout": 2000, - "https": false, - "tls_verify": true, - "tls_server_name": null - }, - } -``` - -To configure a storage type other than `kong`, refer to [lua-resty-acme](https://github.com/fffonion/lua-resty-acme#storage-adapters). - -## Workflow - -A `http-01` challenge workflow between the {{site.base_gateway}} and the ACME server is described below: - -1. The client sends a proxy or Admin API request that triggers certificate generation for `mydomain.com`. -2. The {{site.base_gateway}} sends a request to the ACME server to start the validation process. -3. The ACME server returns a challenge response detail to the {{site.base_gateway}}. -4. `mydomain.com` is publicly resolvable to the {{site.base_gateway}} that serves the challenge response. -5. The ACME server checks if the previous challenge has a response at `mydomain.com`. -6. The {{site.base_gateway}} checks the challenge status and if passed, downloads the certificate from the ACME server. -7. The {{site.base_gateway}} uses the new certificate to serve TLS requests. - - -## Using the plugin - -### Configure Kong - -- Kong needs to listen on port 80 or proxy a load balancer that listens for port 80. -- `lua_ssl_trusted_certificate` needs to be set in `kong.conf` to ensure the plugin can properly -verify the Let's Encrypt API. The CA-bundle file is usually `/etc/ssl/certs/ca-certificates.crt` for -Ubuntu/Debian and `/etc/ssl/certs/ca-bundle.crt` for CentOS/Fedora/RHEL. Starting with Kong v2.2, -users can set this config to `system` to auto pick CA-bundle from OS. - -### Configure plugin - -Here's a sample declarative configuration with `redis` as storage: - -```yaml -_format_version: "1.1" -# this section is not necessary if there's already a route that matches -# /.well-known/acme-challenge path with http protocol -services: - - name: acme-dummy - url: http://127.0.0.1:65535 - routes: - - name: acme-dummy - protocols: - - http - paths: - - /.well-known/acme-challenge -plugins: - - name: acme - config: - account_email: example@myexample.com - domains: - - "*.example.com" - - "example.com" - tos_accepted: true - storage: redis - storage_config: - redis: - host: redis.service - port: 6379 -``` - -### Enable the plugin - -For each the domain that needs a certificate, make sure `DOMAIN/.well-known/acme-challenge` -is mapped to a route in Kong. You can check this by sending -`curl KONG_IP/.well-known/acme-challenge/x -H "host:DOMAIN"` and getting the response `Not found`. -You can also [use the Admin API](#create-certificates) to verify the setup. -If not, add a route and a dummy service to catch this route. - -```bash -# add a dummy service if needed -$ curl http://localhost:8001/services \ - -d name=acme-dummy \ - -d url=http://127.0.0.1:65535 - -# add a dummy route if needed -$ curl http://localhost:8001/routes \ - -d name=acme-dummy \ - -d paths[]=/.well-known/acme-challenge \ - -d service.name=acme-dummy - -# add the plugin -$ curl http://localhost:8001/plugins \ - -d name=acme \ - -d config.account_email=yourname@yourdomain.com \ - -d config.tos_accepted=true \ - -d config.domains[]=my.secret.domains.com -``` - -Note by setting `tos_accepted` to *true* implies that you have read and accepted -[terms of service](https://letsencrypt.org/repository/). - -**This plugin can only be configured as a global plugin.** The plugin terminates -`/.well-known/acme-challenge/` path for matching domains. To create certificates -and terminate challenges only for certain domains, refer to the -[Parameters](#parameters) section. - -### Trigger certificate creation - -Assume Kong proxy is accessible via http://mydomain.com and https://mydomain.com. - -```bash -# Trigger asynchronous creation from proxy requests -# The following request returns immediately with Kong's default certificate -# Wait up to 1 minute for the background process to finish -$ curl https://mydomain.com -k - -# OR create from Admin API synchronously -# User can also use this endpoint to force "renew" a certificate -$ curl http://localhost:8001/acme -d host=mydomain.com - -# Furthermore, it's possible to run a sanity test on your Kong setup -# before creating any certificate -$ curl http://localhost:8001/acme -d host=mydomain.com -d test_http_challenge_flow=true - -$ curl https://mydomain.com -# Now gives you a valid Let's Encrypt certicate -``` - -### Renew certificates - -The plugin runs daily checks and automatically renews all certificates that -will expire in less than the configured `renew_threshold_days` value. If the renewal -of an individual certificate throws an error, the plugin will continue renewing the -other certificates. It will try renewing all certificates, including those that previously -failed, once per day. Note the renewal configuration is stored in the configured storage backend. -If the storage is cleared or modified outside of Kong, renewal might not complete properly. - -It's also possible to actively trigger the renewal. The following request -schedules a renewal in the background and returns immediately. - -```bash -$ curl http://localhost:8001/acme -XPATCH -``` - -## Monitoring and debugging - -The ACME plugin exposes several endpoints through Admin API that can be used for -debugging and monitoring certificate creation and renewal. - -- **POST /acme**: start applying or renewing certificate and return the result; available parameter: - - **host**: the domain to create certificate - - **test_http_challenge_flow**: when set, only check for configuration sanity. -- **PATCH /acme**: same as POST, but runs the process at background. -- **GET /acme/certificates**: list the certificate being created by ACME plugin; one can use this endpoint to monitor certificate existence and expiry. -- **GET /acme/certificates/:host**: list the certificate with specific host. - -Following is an example of the certificate listing API: - -``` -{ - "data": [ - { - "not_after": "2022-09-21 23:59:59", - "pubkey_type": "id-ecPublicKey", - "digest": "A9:49:55:06:A7:B6:1D:2B:13:47:C5:58:5B:AC:DA:43:B5:25:E0:86", - "issuer_cn": "ZeroSSL ECC Domain Secure Site CA", - "valid": true, - "host": "subdomain1.domain.com", - "not_before": "2022-06-23 00:00:00", - "serial_number": "93:B8:E9:D5:C6:36:ED:B4:A8:B3:FD:C5:9E:A8:08:88" - }, - { - "not_after": "2022-09-21 23:59:59", - "pubkey_type": "id-ecPublicKey", - "digest": "26:12:A2:C4:6A:F5:A5:90:9D:03:15:CB:FE:A7:BF:32:1C:42:49:CE", - "issuer_cn": "ZeroSSL ECC Domain Secure Site CA", - "valid": true, - "host": "subdomain2.domain.com", - "not_before": "2022-06-23 00:00:00", - "serial_number": "F1:15:74:E3:E1:DD:21:72:48:C0:4F:06:25:1B:71:F7" - } - ] -} -``` - -## Hybrid mode - -`"shm"` storage type is not available in Hybrid Mode. - -Due to current the limitations of Hybrid Mode, `"kong"` storage only supports certificate generation from -the Admin API but not the proxy side. - -`"kong"` storage in Hybrid Mode works in following flow: - -1. The client sends an Admin API request that triggers certificate generation for `mydomain.com`. -2. The Kong Control Plane requests the ACME server to start the validation process. -3. The ACME server returns a challenge response detail to the Kong Control Plane. -4. The Kong Control Plane propagates the challenge response detail to the Kong Data Plane. -5. `mydomain.com` is publicly resolvable to the Kong Data Plane that serves the challenge response. -6. The ACME server checks if the previous challenge has a response at `mydomain.com`. -7. The Kong Control Plane checks the challenge status and if passed, downloads the certificate from the ACME server. -8. The Kong Control Plane propagates the new certificates to the Kong Data Plane. -9. The Kong Data Plane uses the new certificate to serve TLS requests. - -All external storage types work as usual in Hybrid Mode. Note both the Control Plane and Data Planes -need to connect to the same external storage cluster. It's also a good idea to setup replicas to avoid -connecting to same node directly for external storage. - -External storage in Hybrid Mode works in following flow: - -1. The client send a proxy or Admin API request that triggers certificate generation for `mydomain.com`. -2. The Kong Control Plane or Data Plane requests the ACME server to start the validation process. -3. The ACME server returns a challenge response detail to the {{site.base_gateway}}. -4. The Kong Control Plane or Data Plane stores the challenge response detail in external storage. -5. `mydomain.com` is publicly resolvable to the Kong Data Plane that reads and serves the challenge response from external storage. -6. The ACME server checks if the previous challenge has a response at `mydomain.com`. -7. The Kong Control Plane or Data Plane checks the challenge status and if passed, downloads the certificate from the ACME server. -8. The Kong Control Plane or Data Plane stores the new certificates in external storage. -9. The Kong Data Plane reads from external storage and uses the new certificate to serve TLS requests. - -## Local testing and development - -### Run ngrok - -[ngrok](https://ngrok.com) exposes a local URL to the internet. [Download ngrok](https://ngrok.com/download) and install. - -*`ngrok` is only needed for local testing or development, it's **not** a requirement for the plugin itself.* - -Run ngrok with: - -```bash -$ ./ngrok http localhost:8000 -# Shows something like -# ... -# Forwarding http://e2e034a5.ngrok.io -> http://localhost:8000 -# Forwarding https://e2e034a5.ngrok.io -> http://localhost:8000 -# ... -# Substitute "e2e034a5.ngrok.io" with the host shows in your ngrok output -$ export NGROK_HOST=e2e034a5.ngrok.io -``` - -Leave the process running. - -### Configure route and service - -```bash -$ curl http://localhost:8001/services -d name=acme-test -d url=http://mockbin.org -$ curl http://localhost:8001/routes -d service.name=acme-test -d hosts=$NGROK_HOST -``` - -### Enable plugin - -```bash -$ curl localhost:8001/plugins -d name=acme \ - -d config.account_email=test@test.com \ - -d config.tos_accepted=true \ - -d config.domains[]=$NGROK_HOST -``` - -### Trigger certificate creation - -```bash -$ curl https://$NGROK_HOST:8443 --resolve $NGROK_HOST:8443:127.0.0.1 -vk -# Wait for several seconds -``` - -### Check new certificate - -```bash -$ echo q |openssl s_client -connect localhost -port 8443 -servername $NGROK_HOST 2>/dev/null |openssl x509 -text -noout -``` - -## Notes - -- In database mode, the plugin creates an SNI and Certificate entity in Kong to -serve the certificate. If SNI or Certificate for the current request is already set -in the database, they will be overwritten. -- In DB-less mode, the plugin takes over certificate handling. If the SNI or -Certificate entity is already defined in Kong, they will be overridden by the -response. -- The plugin only supports http-01 challenge, meaning a user will need a public -IP and set up a resolvable DNS. Kong also needs to accept proxy traffic from port `80`. -Also, note that a wildcard or star (*) certificate is not supported. Each domain must have its -own certificate. diff --git a/app/_hub/kong-inc/acme/0.2.2.md b/app/_hub/kong-inc/acme/0.2.2.md deleted file mode 100644 index 23b3351d2484..000000000000 --- a/app/_hub/kong-inc/acme/0.2.2.md +++ /dev/null @@ -1,238 +0,0 @@ ---- -name: ACME -publisher: Kong Inc. -version: 0.2.2 - -source_url: https://github.com/Kong/kong-plugin-acme - -desc: Let's Encrypt and ACMEv2 integration with Kong -description: | - This plugin allows Kong to apply certificates from Let's Encrypt or any other ACMEv2 service and serve dynamically. Renewal is handled with a configurable threshold time. - -type: plugin -categories: - - security - -kong_version_compatibility: - community_edition: - compatible: - - 2.0.x - enterprise_edition: - compatible: - -params: - name: acme - api_id: false - service_id: false - route_id: false - consumer_id: false - protocols: ['http', 'https', 'tcp', 'tls', 'grpc', 'grpcs'] - dbless_compatible: yes - config: - - name: account_email - required: yes - default: - description: | - The account identifier, can be reused in different plugin instance. - - name: api_uri - required: false - default: "`https://acme-v02.api.letsencrypt.org`" - description: | - The ACMEv2 API endpoint to use. You can use the [Let's Encrypt staging environment](https://letsencrypt.org/docs/staging-environment/) during testing. Note that Kong doesn't automatically delete staging certificates: if you use same domain to test and use in production, you will need to delete those certificates manually after testing. - - name: cert_type - required: false - default: "`rsa`" - description: | - The certificate type to create, choice of `"rsa"` for RSA certificate or `"ecc"` for EC certificate. - - name: domains - required: false - default: "`[]`" - description: | - The list of domains to create certificate for. To match subdomains under `example.com`, use `*.example.com`. Regex pattern is not supported. Note this config is only used to match domains, not to specify the Common Name or Subject Alternative Name to create certifcates; each domain will have its own certificate. - - name: renew_threshold_days - required: false - default: "`14`" - description: | - Days before expire to renew the certificate. - - name: storage - required: false - default: "`shm`" - description: | - The backend storage type to use, choice of `"kong"`, `"shm"`, `"redis"`, `"consul"` or `"vault"`. In dbless mode, `"kong"` storage is unavailable. - - name: storage_config - required: false - default: - description: | - Storage configs for each backend storage. See below for its default value. - - name: tos_accepted - required: false - default: "`false`" - description: | - If you are using Let's Encrypt, you must set this to true to agree the [Terms of Service](https://letsencrypt.org/repository/). - extra: | - `config.storage_config` is a table for all possible storage types, by default it is: - ```json - "storage_config": { - "kong": {}, - "shm": { - "shm_name": "kong" - }, - "redis": { - "auth": null, - "port": 6379, - "database": 0, - "host": "127.0.0.1" - }, - "consul": { - "host": "127.0.0.1", - "port": 8500, - "token": null, - "kv_path": "acme" - }, - "vault": { - "host": "127.0.0.1", - "port": 8200, - "token": null, - "kv_path": "acme" - }, - } - ``` - - If you are using a cluster of Kong (multiple Kong instances running on different machines), - consider using one of `"kong"`, `"redis"`, `"consul"` or `"vault"` to support inter-cluster communication. - - To configure a storage type other than `kong`, refer to [lua-resty-acme](https://github.com/fffonion/lua-resty-acme#storage-adapters). - ---- - -### Workflow - -A `http-01` challenge workflow between Kong and the ACME server is described below: - -1. The client sends a proxy or Admin API request that triggers a certificate generation for `mydomain.com`. -2. Kong sends a request to the ACME server to start the validation process. -3. The ACME server returns a challenge response detail to Kong. -4. `mydomain.com` is publicly resolvable to Kong that serves the challenge response. -5. ACME server checks if the previous challenge is responded at `mydomain.com`. -6. Kong checks challenge status and if passed, downloads the certificate from the ACME server. -7. Kong uses the new certificate to serve TLS requests. - -### Using the Plugin - -#### Configure Kong - -- Kong needs to listen 80 port or proxied by a load balancer that listens for 80 port. -- `nginx_proxy_lua_ssl_trusted_certificate` needs to be set in `kong.conf` to ensure the plugin can properly -verify Let's Encrypt API. The CA-bundle file is usually `/etc/ssl/certs/ca-certificates.crt` for -Ubuntu/Debian and `/etc/ssl/certs/ca-bundle.crt` for CentOS/Fedora/RHEL. - -#### Enable the Plugin - -For each the domain that needs a certificate, make sure `DOMAIN/.well-known/acme-challenge` -is mapped to a Route in Kong. You can check this by sending -`curl KONG_IP/.well-known/acme-challenge/x -H "host:DOMAIN"` and getting the response `Not found`. -If not, add a Route and a dummy Service to catch this route. -```bash -# add a dummy service if needed -$ curl http://localhost:8001/services \ - -d name=acme-dummy \ - -d url=http://127.0.0.1:65535 - -# add a dummy route if needed -$ curl http://localhost:8001/routes \ - -d name=acme-dummy \ - -d paths[]=/.well-known/acme-challenge \ - -d service.name=acme-dummy - -# add the plugin -$ curl http://localhost:8001/plugins \ - -d name=acme \ - -d config.account_email=yourname@yourdomain.com \ - -d config.tos_accepted=true \ - -d config.domains[]=my.secret.domains.com -``` - -Note by setting `tos_accepted` to *true* implies that you have read and accepted -[terms of service](https://letsencrypt.org/repository/). - -**This plugin can only be configured as a global plugin.** The plugin terminates -`/.well-known/acme-challenge/` path for matching domains. To create certificates -and terminate challenges only for certain domains, please refer to the -[Parameters](#parameters) section. - -#### Trigger creation of certificate - -Assume Kong proxy is accessible via http://mydomain.com and https://mydomain.com. - -```bash -$ curl https://mydomain.com -k -# Returns Kong's default certificate -# Wait up to 1 minute -$ curl https://mydomain.com -# Now gives you a valid Let's Encrypt certicate -``` - -### Local testing and development - -#### Run ngrok - -[ngrok](https://ngrok.com) exposes a local URL to the internet. [Download ngrok](https://ngrok.com/download) and install. - -*`ngrok` is only needed for local testing or development, it's **not** a requirement for the plugin itself.* - -Run ngrok with - -```bash -$ ./ngrok http localhost:8000 -# Shows something like -# ... -# Forwarding http://e2e034a5.ngrok.io -> http://localhost:8000 -# Forwarding https://e2e034a5.ngrok.io -> http://localhost:8000 -# ... -# Substitute "e2e034a5.ngrok.io" with the host shows in your ngrok output -$ export NGROK_HOST=e2e034a5.ngrok.io -``` - -Leave the process running. - -#### Configure Route and Service - -```bash -$ curl http://localhost:8001/services -d name=acme-test -d url=http://mockbin.org -$ curl http://localhost:8001/routes -d service.name=acme-test -d hosts=$NGROK_HOST -``` - -#### Enable Plugin - -```bash -$ curl localhost:8001/plugins -d name=acme \ - -d config.account_email=test@test.com \ - -d config.tos_accepted=true \ - -d config.domains[]=$NGROK_HOST -``` - -#### Trigger creation of certificate - -```bash -$ curl https://$NGROK_HOST:8443 --resolve $NGROK_HOST:8443:127.0.0.1 -vk -# Wait for several seconds -``` - -#### Check new certificate - -```bash -$ echo q |openssl s_client -connect localhost -port 8443 -servername $NGROK_HOST 2>/dev/null |openssl x509 -text -noout -``` - -### Notes - -- In database mode, the plugin creates SNI and Certificate entity in Kong to -serve certificate. If SNI or Certificate for current request is already set -in database, they will be overwritten. -- In DB-less mode, the plugin takes over certificate handling. If the SNI or -Certificate entity is already defined in Kong, they will be overridden from -response. -- The plugin only supports http-01 challenge, meaning a user will need a public -IP and setup resolvable DNS. Kong also needs to accept proxy traffic from port `80`. -Also, note that wildcard or star (*) certificate is not supported. Each domain will have its -own certificate. diff --git a/app/_hub/kong-inc/acme/0.2.7.md b/app/_hub/kong-inc/acme/0.2.7.md deleted file mode 100644 index b2ef0093acf2..000000000000 --- a/app/_hub/kong-inc/acme/0.2.7.md +++ /dev/null @@ -1,303 +0,0 @@ ---- -name: ACME -publisher: Kong Inc. -version: 0.2.7 - -source_url: https://github.com/Kong/kong-plugin-acme - -desc: Let's Encrypt and ACMEv2 integration with Kong -description: | - This plugin allows Kong to apply certificates from Let's Encrypt or any other ACMEv2 service and serve dynamically. Renewal is handled with a configurable threshold time. - -type: plugin -categories: - - security - -kong_version_compatibility: - community_edition: - compatible: - - 2.1.x - - 2.0.x - enterprise_edition: - compatible: - - 2.1.x - -params: - name: acme - api_id: false - service_id: false - route_id: false - consumer_id: false - protocols: ['http', 'https', 'tcp', 'tls', 'grpc', 'grpcs'] - dbless_compatible: yes - config: - - name: account_email - required: yes - default: - value_in_examples: example@example.com - description: | - The account identifier, can be reused in different plugin instance. - - name: api_uri - required: false - default: "`https://acme-v02.api.letsencrypt.org`" - description: | - The ACMEv2 API endpoint to use. Users can specify the [Let's Encrypt staging environment](https://letsencrypt.org/docs/staging-environment/) (`https://acme-staging-v02.api.letsencrypt.org/directory`) for testing. Note that Kong doesn't automatically delete staging certificates: if you use same domain to test and use in production, you will need to delete those certificates manually after testing. - - name: cert_type - required: false - default: "`rsa`" - description: | - The certificate type to create. The possible values are `"rsa"` for RSA certificate or `"ecc"` for EC certificate. - - name: domains - required: false - default: "`[]`" - description: | - The list of domains to create certificate for. To match subdomains under `example.com`, use `*.example.com`. Regex pattern is not supported. Note this config is only used to match domains, not to specify the Common Name or Subject Alternative Name to create certifcates; each domain will have its own certificate. - - name: renew_threshold_days - required: false - default: "`14`" - description: | - Days before expire to renew the certificate. - - name: storage - required: false - default: "`shm`" - description: | - The backend storage type to use. The possible values are `"kong"`, `"shm"`, `"redis"`, `"consul"`, or `"vault"`. In DB-less mode, `"kong"` storage is unavailable. Note that `"shm"` storage does not persist during Kong restarts and does not work for Kong running on different machines, so consider using one of `"kong"`, `"redis"`, `"consul"`, or `"vault"` in production. - - name: storage_config - required: false - default: - description: | - Storage configs for each backend storage. See below for its default value. - - name: tos_accepted - required: false - default: "`false`" - description: | - If you are using Let's Encrypt, you must set this to true to agree the [Terms of Service](https://letsencrypt.org/repository/). - extra: | - `config.storage_config` is a table for all posisble storage types, by default it is: - ```json - "storage_config": { - "kong": {}, - "shm": { - "shm_name": "kong" - }, - "redis": { - "auth": null, - "port": 6379, - "database": 0, - "host": "127.0.0.1" - }, - "consul": { - "host": "127.0.0.1", - "port": 8500, - "token": null, - "kv_path": "acme", - "timeout": 2000, - "https": false - }, - "vault": { - "host": "127.0.0.1", - "port": 8200, - "token": null, - "kv_path": "acme", - "timeout": 2000, - "https": false, - "tls_verify": true, - "tls_server_name": null - }, - } - ``` - - To configure storage type other than `kong`, please refer to [lua-resty-acme](https://github.com/fffonion/lua-resty-acme#storage-adapters). - ---- - -### Workflow - -A `http-01` challenge workflow between the Kong Gateway and the ACME server is described below: - -1. The client sends a proxy or Admin API request that triggers certificate generation for `mydomain.com`. -2. The Kong Gateway sends a request to the ACME server to start the validation process. -3. The ACME server returns a challenge response detail to the Kong Gateway. -4. `mydomain.com` is publicly resolvable to the Kong Gateway that serves the challenge response. -5. The ACME server checks if the previous challenge has a response at `mydomain.com`. -6. The Kong Gateway checks the challenge status and if passed, downloads the certificate from the ACME server. -7. The Kong Gateway uses the new certificate to serve TLS requests. - -### Using the Plugin - -#### Configure Kong - -- Kong needs to listen 80 port or proxied by a load balancer that listens for 80 port. -- `lua_ssl_trusted_certificate` needs to be set in `kong.conf` to ensure the plugin can properly -verify Let's Encrypt API. The CA-bundle file is usually `/etc/ssl/certs/ca-certificates.crt` for -Ubuntu/Debian and `/etc/ssl/certs/ca-bundle.crt` for CentOS/Fedora/RHEL. - -#### Configure Plugin - -Here's a sample declarative configuration with `redis` as storage: - -```yaml -_format_version: "1.1" -# this section is not necessary if there's already a route that matches -# /.well-known/acme-challenge path with http protocol -services: - - name: acme-dummy - url: http://127.0.0.1:65535 - routes: - - name: acme-dummy - protocols: - - http - paths: - - /.well-known/acme-challenge -plugins: - - name: acme - config: - account_email: example@myexample.com - domains: - - "*.example.com" - - "example.com" - tos_accepted: true - storage: redis - storage_config: - redis: - host: redis.service - port: 6379 -``` - -#### Enable the Plugin - -For each the domain that needs a certificate, make sure `DOMAIN/.well-known/acme-challenge` -is mapped to a Route in Kong. You can check this by sending -`curl KONG_IP/.well-known/acme-challenge/x -H "host:DOMAIN"` and getting the response `Not found`. -You can also [use the Admin API](#create-certificates) to verify the setup. -If not, add a Route and a dummy Service to catch this route. -```bash -# add a dummy service if needed -$ curl http://localhost:8001/services \ - -d name=acme-dummy \ - -d url=http://127.0.0.1:65535 - -# add a dummy route if needed -$ curl http://localhost:8001/routes \ - -d name=acme-dummy \ - -d paths[]=/.well-known/acme-challenge \ - -d service.name=acme-dummy - -# add the plugin -$ curl http://localhost:8001/plugins \ - -d name=acme \ - -d config.account_email=yourname@yourdomain.com \ - -d config.tos_accepted=true \ - -d config.domains[]=my.secret.domains.com -``` - -Note by setting `tos_accepted` to *true* implies that you have read and accepted -[terms of service](https://letsencrypt.org/repository/). - -**This plugin can only be configured as a global plugin.** The plugin terminates -`/.well-known/acme-challenge/` path for matching domains. To create certificates -and terminate challenges only for certain domains, please refer to the -[Parameters](#parameters) section. - -#### Trigger creation of certificate - -Assume Kong proxy is accessible via http://mydomain.com and https://mydomain.com. - -```bash -# Trigger asynchronous creation from proxy requests -# The following request returns immediately with Kong's default certificate -# Wait up to 1 minute for the background process to finish -$ curl https://mydomain.com -k - -# OR create from Admin API synchronously -# User can also use this endpoint to force "renew" a certificate -$ curl http://localhost:8001/acme -d host=mydomain.com - -# Furthermore, it's possible to run a sanity test on your Kong setup -# before creating any certificate -$ curl http://localhost:8001/acme -d host=mydomain.com -d test_http_challenge_flow=true - -$ curl https://mydomain.com -# Now gives you a valid Let's Encrypt certicate -``` - -#### Renew certificates - -The plugin runs daily checks and automatically renews all certificates that -will expire in less than the configured `renew_threshold_days` value. If the renewal -of an individual certificate throws an error, the plugin will continue renewing the -other certificates. It will try renewing all certificates, including those that previously -failed, once per day. Note the renewal configuration is stored in the configured storage backend. -If the storage is cleared or modified outside of Kong, renewal might not complete properly. - -It's also possible to actively trigger the renewal. The following request -schedules a renewal in the background and returns immediately. - -```bash -$ curl http://localhost:8001/acme -XPATCH -``` - -### Local testing and development - -#### Run ngrok - -[ngrok](https://ngrok.com) exposes a local URL to the internet. [Download ngrok](https://ngrok.com/download) and install. - -*`ngrok` is only needed for local testing or development, it's **not** a requirement for the plugin itself.* - -Run ngrok with - -```bash -$ ./ngrok http localhost:8000 -# Shows something like -# ... -# Forwarding http://e2e034a5.ngrok.io -> http://localhost:8000 -# Forwarding https://e2e034a5.ngrok.io -> http://localhost:8000 -# ... -# Substitute "e2e034a5.ngrok.io" with the host shows in your ngrok output -$ export NGROK_HOST=e2e034a5.ngrok.io -``` - -Leave the process running. - -#### Configure Route and Service - -```bash -$ curl http://localhost:8001/services -d name=acme-test -d url=http://mockbin.org -$ curl http://localhost:8001/routes -d service.name=acme-test -d hosts=$NGROK_HOST -``` - -#### Enable Plugin - -```bash -$ curl localhost:8001/plugins -d name=acme \ - -d config.account_email=test@test.com \ - -d config.tos_accepted=true \ - -d config.domains[]=$NGROK_HOST -``` - -#### Trigger creation of certificate - -```bash -$ curl https://$NGROK_HOST:8443 --resolve $NGROK_HOST:8443:127.0.0.1 -vk -# Wait for several seconds -``` - -#### Check new certificate - -```bash -$ echo q |openssl s_client -connect localhost -port 8443 -servername $NGROK_HOST 2>/dev/null |openssl x509 -text -noout -``` - -### Notes - -- In database mode, the plugin creates SNI and Certificate entity in Kong to -serve certificate. If SNI or Certificate for current request is already set -in database, they will be overwritten. -- In DB-less mode, the plugin takes over certificate handling, if the SNI or -Certificate entity is already defined in Kong, they will be overrided from -response. -- The plugin only supports http-01 challenge, meaning user will need a public -IP and setup resolvable DNS. Kong also needs to accept proxy traffic from port `80`. -Also, note that wildcard or star certificate is not supported, each domain will have its -own certificate. diff --git a/app/_hub/kong-inc/acme/0.3.x.md b/app/_hub/kong-inc/acme/0.3.x.md deleted file mode 100644 index 722d959c2a2d..000000000000 --- a/app/_hub/kong-inc/acme/0.3.x.md +++ /dev/null @@ -1,442 +0,0 @@ ---- -name: ACME -publisher: Kong Inc. -version: 0.3.x -source_url: 'https://github.com/Kong/kong-plugin-acme' -desc: Let's Encrypt and ACMEv2 integration with Kong -description: | - This plugin allows Kong to apply certificates from Let's Encrypt or any other ACMEv2 service and serve them dynamically. - Renewal is handled with a configurable threshold time. -type: plugin -categories: - - security -kong_version_compatibility: - community_edition: - compatible: - - 2.7.x - enterprise_edition: - compatible: - - 2.7.x -params: - name: acme - service_id: false - route_id: false - consumer_id: false - protocols: - - http - - https - - tcp - - tls - - grpc - - grpcs - dbless_compatible: 'yes' - config: - - name: account_email - required: 'yes' - default: null - value_in_examples: example@example.com - encrypted: true - datatype: string - description: | - The account identifier. Can be reused in a different plugin instance. - - name: api_uri - required: false - default: '` https://acme-v02.api.letsencrypt.org/directory`' - datatype: string - description: | - The ACMEv2 API endpoint to use. You can specify the - [Let's Encrypt staging environment](https://letsencrypt.org/docs/staging-environment/) for testing. Kong doesn't automatically delete staging certificates. If you use the same domain in test and production environments, you need to manually delete those certificates after testing. - - name: cert_type - required: false - default: '`rsa`' - datatype: string - description: | - The certificate type to create. The possible values are `"rsa"` for RSA certificate or `"ecc"` for EC certificate. - - name: domains - required: false - default: '`[]`' - datatype: array of string elements - description: | - The list of domains to create certificate for. To match subdomains under `example.com`, use `*.example.com`. - Regex pattern is not supported. Note this config is only used to match domains, not to specify the Common Name - or Subject Alternative Name to create certificates; each domain must have its own certificate. - ACME plugin checks this configuration before the presense of certificate in `storage` when serving certificate of a request. - - name: fail_backoff_minutes - required: false - default: 5 - datatype: number - description: | - Minutes to wait for each domain that fails to create a certificate. This applies to both a - new certificate and a renewal certificate. - - name: renew_threshold_days - required: false - default: '`14`' - datatype: number - description: | - Days remaining to renew the certificate before it expires. - - name: storage - required: false - default: '`shm`' - datatype: string - description: | - The backend storage type to use. The possible values are `"kong"`, `"shm"`, `"redis"`, `"consul"`, or `"vault"`. In DB-less mode, `"kong"` storage is unavailable. Note that `"shm"` storage does not persist during Kong restarts and does not work for Kong running on different machines, so consider using one of `"kong"`, `"redis"`, `"consul"`, or `"vault"` in production. Please refer to the Hybrid Mode sections below as well. - - name: storage_config - required: false - default: null - datatype: record - description: | - Storage configs for each backend storage. See [Storage configuration considerations](#storage-config) - for information on its default values. - - name: tos_accepted - required: false - default: '`false`' - datatype: boolean - description: | - If you are using Let's Encrypt, you must set this to `true` to agree the [Terms of Service](https://letsencrypt.org/repository/). - - name: eab_kid - required: false - datatype: string - encrypted: true - description: | - External account binding (EAB) key id. You usually don't need to set this unless it is explicitly required by the CA. - - name: eab_hmac_key - required: false - datatype: string - encrypted: true - description: | - External account binding (EAB) base64-encoded URL string of the HMAC key. You usually don't need to set this unless it is explicitly required by the CA. - extra: | - - External account binding (EAB) is supported as long as `eab_kid` and `eab_hmac_key` are provided. - - The following CA provider's external account can be registered automatically, without specifying - the `eab_kid` or `eab_hmac_key`: - - - [ZeroSSL](https://zerossl.com/) ---- - -## Storage configuration considerations {#storage-config} - -`config.storage_config` is a table for all possible storage types. By default, it is: - -```json - "storage_config": { - "kong": {}, - "shm": { - "shm_name": "kong" - }, - "redis": { - "auth": null, - "port": 6379, - "database": 0, - "host": "127.0.0.1" - }, - "consul": { - "host": "127.0.0.1", - "port": 8500, - "token": null, - "kv_path": "acme", - "timeout": 2000, - "https": false - }, - "vault": { - "host": "127.0.0.1", - "port": 8200, - "token": null, - "kv_path": "acme", - "timeout": 2000, - "https": false, - "tls_verify": true, - "tls_server_name": null - }, - } -``` - -To configure a storage type other than `kong`, refer to [lua-resty-acme](https://github.com/fffonion/lua-resty-acme#storage-adapters). - -## Workflow - -A `http-01` challenge workflow between the {{site.base_gateway}} and the ACME server is described below: - -1. The client sends a proxy or Admin API request that triggers certificate generation for `mydomain.com`. -2. The {{site.base_gateway}} sends a request to the ACME server to start the validation process. -3. The ACME server returns a challenge response detail to the {{site.base_gateway}}. -4. `mydomain.com` is publicly resolvable to the {{site.base_gateway}} that serves the challenge response. -5. The ACME server checks if the previous challenge has a response at `mydomain.com`. -6. The {{site.base_gateway}} checks the challenge status and if passed, downloads the certificate from the ACME server. -7. The {{site.base_gateway}} uses the new certificate to serve TLS requests. - - -## Using the plugin - -### Configure Kong - -- Kong needs to listen on port 80 or proxy a load balancer that listens for port 80. -- `lua_ssl_trusted_certificate` needs to be set in `kong.conf` to ensure the plugin can properly -verify the Let's Encrypt API. The CA-bundle file is usually `/etc/ssl/certs/ca-certificates.crt` for -Ubuntu/Debian and `/etc/ssl/certs/ca-bundle.crt` for CentOS/Fedora/RHEL. Starting with Kong v2.2, -users can set this config to `system` to auto pick CA-bundle from OS. - -### Configure plugin - -Here's a sample declarative configuration with `redis` as storage: - -```yaml -_format_version: "1.1" -# this section is not necessary if there's already a route that matches -# /.well-known/acme-challenge path with http protocol -services: - - name: acme-dummy - url: http://127.0.0.1:65535 - routes: - - name: acme-dummy - protocols: - - http - paths: - - /.well-known/acme-challenge -plugins: - - name: acme - config: - account_email: example@myexample.com - domains: - - "*.example.com" - - "example.com" - tos_accepted: true - storage: redis - storage_config: - redis: - host: redis.service - port: 6379 -``` - -### Enable the plugin - -For each the domain that needs a certificate, make sure `DOMAIN/.well-known/acme-challenge` -is mapped to a route in Kong. You can check this by sending -`curl KONG_IP/.well-known/acme-challenge/x -H "host:DOMAIN"` and getting the response `Not found`. -You can also [use the Admin API](#create-certificates) to verify the setup. -If not, add a route and a dummy service to catch this route. - -```bash -# add a dummy service if needed -curl http://localhost:8001/services \ - -d name=acme-dummy \ - -d url=http://127.0.0.1:65535 - -# add a dummy route if needed -curl http://localhost:8001/routes \ - -d name=acme-dummy \ - -d paths[]=/.well-known/acme-challenge \ - -d service.name=acme-dummy - -# add the plugin -curl http://localhost:8001/plugins \ - -d name=acme \ - -d config.account_email=yourname@yourdomain.com \ - -d config.tos_accepted=true \ - -d config.domains[]=my.secret.domains.com -``` - -Note by setting `tos_accepted` to *true* implies that you have read and accepted -[terms of service](https://letsencrypt.org/repository/). - -**This plugin can only be configured as a global plugin.** The plugin terminates -`/.well-known/acme-challenge/` path for matching domains. To create certificates -and terminate challenges only for certain domains, refer to the -[Parameters](#parameters) section. - -### Trigger certificate creation - -Assume Kong proxy is accessible via http://mydomain.com and https://mydomain.com. - -```bash -# Trigger asynchronous creation from proxy requests -# The following request returns immediately with Kong's default certificate -# Wait up to 1 minute for the background process to finish -curl https://mydomain.com -k - -# OR create from Admin API synchronously -# User can also use this endpoint to force "renew" a certificate -curl http://localhost:8001/acme -d host=mydomain.com - -# Furthermore, it's possible to run a sanity test on your Kong setup -# before creating any certificate -curl http://localhost:8001/acme -d host=mydomain.com -d test_http_challenge_flow=true - -curl https://mydomain.com -# Now gives you a valid Let's Encrypt certicate -``` - -### Renew certificates - -The plugin runs daily checks and automatically renews all certificates that -will expire in less than the configured `renew_threshold_days` value. If the renewal -of an individual certificate throws an error, the plugin will continue renewing the -other certificates. It will try renewing all certificates, including those that previously -failed, once per day. Note the renewal configuration is stored in the configured storage backend. -If the storage is cleared or modified outside of Kong, renewal might not complete properly. - -It's also possible to actively trigger the renewal. The following request -schedules a renewal in the background and returns immediately. - -```bash -curl http://localhost:8001/acme -XPATCH -``` - -## Monitoring and debugging - -The ACME plugin exposes several endpoints through Admin API that can be used for -debugging and monitoring certificate creation and renewal. - -- **POST /acme**: start applying or renewing certificate and return the result; available parameter: - - **host**: the domain to create certificate - - **test_http_challenge_flow**: when set, only check for configuration sanity. -- **PATCH /acme**: same as POST, but runs the process at background. -- **GET /acme/certificates**: list the certificate being created by ACME plugin; one can use this endpoint to monitor certificate existence and expiry. -- **GET /acme/certificates/:host**: list the certificate with specific host. - -Following is an example of the certificate listing API: - -``` -{ - "data": [ - { - "not_after": "2022-09-21 23:59:59", - "pubkey_type": "id-ecPublicKey", - "digest": "A9:49:55:06:A7:B6:1D:2B:13:47:C5:58:5B:AC:DA:43:B5:25:E0:86", - "issuer_cn": "ZeroSSL ECC Domain Secure Site CA", - "valid": true, - "host": "subdomain1.domain.com", - "not_before": "2022-06-23 00:00:00", - "serial_number": "93:B8:E9:D5:C6:36:ED:B4:A8:B3:FD:C5:9E:A8:08:88" - }, - { - "not_after": "2022-09-21 23:59:59", - "pubkey_type": "id-ecPublicKey", - "digest": "26:12:A2:C4:6A:F5:A5:90:9D:03:15:CB:FE:A7:BF:32:1C:42:49:CE", - "issuer_cn": "ZeroSSL ECC Domain Secure Site CA", - "valid": true, - "host": "subdomain2.domain.com", - "not_before": "2022-06-23 00:00:00", - "serial_number": "F1:15:74:E3:E1:DD:21:72:48:C0:4F:06:25:1B:71:F7" - } - ] -} -``` - -## Hybrid mode - -`"shm"` storage type is not available in Hybrid Mode. - -Due to current the limitations of Hybrid Mode, `"kong"` storage only supports certificate generation from -the Admin API but not the proxy side. - -`"kong"` storage in Hybrid Mode works in following flow: - -1. The client sends an Admin API request that triggers certificate generation for `mydomain.com`. -2. The Kong Control Plane requests the ACME server to start the validation process. -3. The ACME server returns a challenge response detail to the Kong Control Plane. -4. The Kong Control Plane propagates the challenge response detail to the Kong Data Plane. -5. `mydomain.com` is publicly resolvable to the Kong Data Plane that serves the challenge response. -6. The ACME server checks if the previous challenge has a response at `mydomain.com`. -7. The Kong Control Plane checks the challenge status and if passed, downloads the certificate from the ACME server. -8. The Kong Control Plane propagates the new certificates to the Kong Data Plane. -9. The Kong Data Plane uses the new certificate to serve TLS requests. - -All external storage types work as usual in Hybrid Mode. Note both the Control Plane and Data Planes -need to connect to the same external storage cluster. It's also a good idea to setup replicas to avoid -connecting to same node directly for external storage. - -External storage in Hybrid Mode works in following flow: - -1. The client send a proxy or Admin API request that triggers certificate generation for `mydomain.com`. -2. The Kong Control Plane or Data Plane requests the ACME server to start the validation process. -3. The ACME server returns a challenge response detail to the {{site.base_gateway}}. -4. The Kong Control Plane or Data Plane stores the challenge response detail in external storage. -5. `mydomain.com` is publicly resolvable to the Kong Data Plane that reads and serves the challenge response from external storage. -6. The ACME server checks if the previous challenge has a response at `mydomain.com`. -7. The Kong Control Plane or Data Plane checks the challenge status and if passed, downloads the certificate from the ACME server. -8. The Kong Control Plane or Data Plane stores the new certificates in external storage. -9. The Kong Data Plane reads from external storage and uses the new certificate to serve TLS requests. - -## Local testing and development - -### Run ngrok - -[ngrok](https://ngrok.com) exposes a local URL to the internet. [Download ngrok](https://ngrok.com/download) and install. - -*`ngrok` is only needed for local testing or development, it's **not** a requirement for the plugin itself.* - -Run ngrok with: - -```bash -./ngrok http localhost:8000 -# Shows something like -# ... -# Forwarding http://e2e034a5.ngrok.io -> http://localhost:8000 -# Forwarding https://e2e034a5.ngrok.io -> http://localhost:8000 -# ... -# Substitute "e2e034a5.ngrok.io" with the host shows in your ngrok output -export NGROK_HOST=e2e034a5.ngrok.io -``` - -Leave the process running. - -### Configure route and service - -```bash -curl http://localhost:8001/services \ - -d name=acme-test \ - -d url=http://mockbin.org - -curl http://localhost:8001/routes \ - -d service.name=acme-test \ - -d hosts=$NGROK_HOST \ - -d paths=/mock -``` - -### Enable plugin - -```bash -curl localhost:8001/plugins \ - -d name=acme \ - -d config.account_email=test@test.com \ - -d config.tos_accepted=true \ - -d config.domains[]=$NGROK_HOST -``` - -### Trigger certificate creation - -```bash -curl https://$NGROK_HOST:8443 --resolve $NGROK_HOST:8443:127.0.0.1 -vk -# Wait for several seconds -``` - -### Check new certificate - -```bash -echo q |openssl s_client -connect localhost -port 8443 -servername $NGROK_HOST 2>/dev/null |openssl x509 -text -noout -``` - -## Notes - -- In database mode, the plugin creates an SNI and Certificate entity in Kong to -serve the certificate. If SNI or Certificate for the current request is already set -in the database, they will be overwritten. -- In DB-less mode, the plugin takes over certificate handling. If the SNI or -Certificate entity is already defined in Kong, they will be overridden by the -response. -- The plugin only supports http-01 challenge, meaning a user will need a public -IP and set up a resolvable DNS. Kong also needs to accept proxy traffic from port `80`. -Also, note that a wildcard or star (`*`) certificate is not supported. Each domain must have its -own certificate. - ---- - -## Changelog - -### 0.3.0 - -* Starting with {{site.base_gateway}} 2.7.0.0, if keyring encryption is enabled, - the `account_email`, `eab_kid`, and `eab_hmac_kid` parameter values will be - encrypted. diff --git a/app/_hub/kong-inc/acme/_index.md b/app/_hub/kong-inc/acme/_index.md index 0a3c1ee46e8b..724045cbf6aa 100644 --- a/app/_hub/kong-inc/acme/_index.md +++ b/app/_hub/kong-inc/acme/_index.md @@ -1,7 +1,6 @@ --- name: ACME publisher: Kong Inc. -version: 0.4.x desc: Let's Encrypt and ACMEv2 integration with Kong description: | This plugin allows Kong to apply certificates from Let's Encrypt or any other ACMEv2 service and serve them dynamically. @@ -11,11 +10,9 @@ categories: - security kong_version_compatibility: community_edition: - compatible: - - 2.8.x + compatible: true enterprise_edition: - compatible: - - 2.8.x + compatible: true params: name: acme service_id: false @@ -38,6 +35,10 @@ params: datatype: string description: | The account identifier. Can be reused in a different plugin instance. + + This field is _referenceable_, which means it can be securely stored as a + [secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). - name: api_uri required: false default: '` https://acme-v02.api.letsencrypt.org/directory`' @@ -56,7 +57,7 @@ params: default: '`[]`' datatype: array of string elements description: | - The list of domains to create certificate for. To match subdomains under `example.com`, use `*.example.com`. + The list of domains to create certificates for. To match subdomains under `example.com`, use `*.example.com`. Regex pattern is not supported. This parameter is only used to match domains, not to specify the Common Name @@ -64,7 +65,15 @@ params: The ACME plugin checks this configuration before checking any certificate in `storage` when serving the certificate of a request. If this field is left empty, all top-level domains (TLDs) are allowed. + - name: allow_any_domain + minimum_version: "3.0.x" + required: false + default: false + datatype: boolean + description: | + If set to `true`, the plugin allows all domains and ignores any values in the `domains` list. - name: fail_backoff_minutes + minimum_version: "2.1.x" required: false default: 5 datatype: number @@ -97,32 +106,48 @@ params: description: | If you are using Let's Encrypt, you must set this to `true` to agree the [Terms of Service](https://letsencrypt.org/repository/). - name: eab_kid + minimum_version: "2.4.x" required: false datatype: string encrypted: true description: | External account binding (EAB) key id. You usually don't need to set this unless it is explicitly required by the CA. + + This field is _referenceable_, which means it can be securely stored as a + [secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). - name: eab_hmac_key + minimum_version: "2.4.x" required: false datatype: string encrypted: true description: | External account binding (EAB) base64-encoded URL string of the HMAC key. You usually don't need to set this unless it is explicitly required by the CA. + + This field is _referenceable_, which means it can be securely stored as a + [secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). - name: rsa_key_size + minimum_version: "2.8.x" required: false datatype: number default: 4096 description: | RSA private key size for the certificate. The possible values are 2048, 3072, or 4096. - extra: | +--- - External account binding (EAB) is supported as long as `eab_kid` and `eab_hmac_key` are provided. +{% if_plugin_version gte:2.4.x %} - The following CA provider's external account can be registered automatically, without specifying - the `eab_kid` or `eab_hmac_key`: +## EAB support - - [ZeroSSL](https://zerossl.com/) ---- +External account binding (EAB) is supported as long as `eab_kid` and `eab_hmac_key` are provided. + +The following CA provider's external account can be registered automatically, without specifying +the `eab_kid` or `eab_hmac_key`: + +- [ZeroSSL](https://zerossl.com/) + +{% endif_plugin_version %} ## Storage configuration considerations {#storage-config} @@ -156,11 +181,18 @@ params: "timeout": 2000, "https": false, "tls_verify": true, - "tls_server_name": null + "tls_server_name": null, + "auth_method": "token", + "auth_path": null, + "auth_role": null, + "jwt_path": null, }, } ``` +The `consul.token`, `redis.auth`, and `vault.token` fields are _referenceable_, which means they can be securely stored as [secrets](/gateway/latest/kong-enterprise/secrets-management/getting-started) +in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/secrets-management/reference-format). + To configure a storage type other than `kong`, refer to [lua-resty-acme](https://github.com/fffonion/lua-resty-acme#storage-adapters). ## Workflow @@ -191,7 +223,7 @@ users can set this config to `system` to auto pick CA-bundle from OS. Here's a sample declarative configuration with `redis` as storage: ```yaml -_format_version: "1.1" +_format_version: "3.0" # this section is not necessary if there's already a route that matches # /.well-known/acme-challenge path with http protocol services: @@ -484,12 +516,38 @@ own certificate. ## Changelog -### {{site.base_gateway}} 2.8.x (plugin version 0.4.0) +{% if_plugin_version gte:3.0.x %} + +**{{site.base_gateway}} 3.0.x** +* The `storage_config.vault.auth_method` configuration parameter now defaults to `token`. +* Added the `allow_any_domain` configuration parameter. If enabled, it lets {{site.base_gateway}} + ignore the `domains` field. + +{% endif_plugin_version %} + +{% if_plugin_version gte:2.8.x %} +**{{site.base_gateway}} 2.8.x** * Added the `rsa_key_size` configuration parameter. +* The `consul.token`, `redis.auth`, and `vault.token` are now marked as now marked as +referenceable, which means they can be securely stored as [secrets](/gateway/latest/kong-enterprise/secrets-management/getting-started) in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/secrets-management/reference-format). -### {{site.base_gateway}} 2.7.x (plugin version 0.3.0) +{% endif_plugin_version %} + +{% if_plugin_version gte:2.7.x %} +**{{site.base_gateway}} 2.7.x** * Starting with {{site.base_gateway}} 2.7.0.0, if keyring encryption is enabled, the `account_email`, `eab_kid`, and `eab_hmac_kid` parameter values will be encrypted. + +{% endif_plugin_version %} + +{% if_plugin_version gte:2.4.x %} +**{{site.base_gateway}} 2.4.x** +* Added external account binding (EAB) support with the `eab_kid` and `eab_hmac_key` configuration parameters. + +{% endif_plugin_version %} + +**{{site.base_gateway}} 2.1.x** +* Added the `fail_backoff_minutes` configuration parameter. diff --git a/app/_hub/kong-inc/acme/versions.yml b/app/_hub/kong-inc/acme/versions.yml index fd9d8990ddff..cd80f26be224 100644 --- a/app/_hub/kong-inc/acme/versions.yml +++ b/app/_hub/kong-inc/acme/versions.yml @@ -1,7 +1,12 @@ -- release: 0.4.x -- release: 0.3.x -- release: 0.2.14 -- release: 0.2.13 -- release: 0.2.11 -- release: 0.2.7 -- release: 0.2.2 +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 0.4.0 + 2.7.x: 0.3.0 + 2.6.x: 0.3.0 + 2.5.x: 0.2.15 + 2.4.x: 0.2.15 + 2.3.x: 0.2.15 + 2.2.x: 0.2.15 + 2.1.x: 0.2.14 diff --git a/app/_hub/kong-inc/application-registration/1.0.x.md b/app/_hub/kong-inc/application-registration/1.0.x.md deleted file mode 100644 index 21d7f0530129..000000000000 --- a/app/_hub/kong-inc/application-registration/1.0.x.md +++ /dev/null @@ -1,276 +0,0 @@ ---- -name: Portal Application Registration -publisher: Kong Inc. -version: 1.0.x - -desc: Allow portal developers to register applications against services -description: | - Applications allow registered developers on Kong Developer Portal to - authenticate with OAuth against a Service on Kong. Admins can selectively - admit access to Services using this - [Application Registration](/enterprise/1.5.x/developer-portal/administration/application-registration) plugin. - - At least one OAuth2 grant flow (typical use case) must be enabled for the - plugin on a Service: - - Authorization Code - - Client Credentials - - Implicit Grant - - Password Grant - -enterprise: true -type: plugin -categories: - - authentication - -kong_version_compatibility: - enterprise_edition: - compatible: - - 1.5.x - -params: - name: application-registration - service_id: true - consumer_id: false - route_id: false - konnect_examples: false - protocols: ["http", "https", "grpc", "grpcs"] - dbless_compatible: no - config: - - name: auth_header_name - required: false - default: "`authorization`" - value_in_examples: authorization - description: | - The name of the header that is supposed to carry the access token ([RFC 6750 Section 2.1](https://tools.ietf.org/html/rfc6750#section-2.1)). - - name: auto_approve - required: true - default: "`false`" - value_in_examples: false - description: | - If enabled, all new Service Contracts requests are automatically - approved. See [Enable automatic registration approval](#enable-automatic-registration-approval). Otherwise, Dev Portal admins must manually approve requests. - - name: description - required: false - default: - value_in_examples: - description: | - Unique description displayed in information about a Service in the Developer Portal. - - name: display_name - required: true - default: - value_in_examples: - description: | - Unique display name used for a Service in the Developer Portal. - - name: enable_authorization_code - required: true - default: "`false`" - value_in_examples: true - description: | - An optional boolean value to enable the three-legged Authorization - Code flow ([RFC 6742 Section 4.1](https://tools.ietf.org/html/rfc6749#section-4.1)). At least one flow must be enabled for the plugin. - - name: enable_client_credentials - required: true - default: "`false`" - value_in_examples: true - description: | - An optional boolean value to enable the Client Credentials Grant - flow ([RFC 6742 Section 4.4](https://tools.ietf.org/html/rfc6749#section-4.4)). At least one flow must be enabled for the plugin. - - name: enable_implicit_grant - required: true - default: "`false`" - value_in_examples: true - description: | - An optional boolean value to enable the Implicit Grant flow, which - allows to provision a token as a result of the authorization - process ([RFC 6742 Section 4.2](https://tools.ietf.org/html/rfc6749#section-4.2)). At least one flow must be enabled for the plugin. - - name: enable_password_grant - required: true - default: "`false`" - value_in_examples: true - description: | - An optional boolean value to enable the Resource Owner Password - Credentials Grant flow ([RFC 6742 Section 4.3](https://tools.ietf.org/html/rfc6749#section-4.3)). At least one flow must be enabled for the plugin. - - name: mandatory_scope - required: true - default: "`false`" - value_in_examples: false - description: | - An optional boolean value telling the plugin to require at least - one scope to be authorized by the end user. See [Set mandatory scopes](#set-mandatory-scopes). - - name: provision_key - required: false - default: - value_in_examples: - description: | - The Provision Key is automatically generated on creation. No input - is required. Used by the Resource Owner Password Credentials Grant - (Password Grant) flow. - - name: refresh_token_ttl - required: true - default: 1209600 - value_in_examples: 1209600 - description: | - An integer value that indicates the Time To Live (TTL) in seconds for a - [refresh token](https://tools.ietf.org/html/rfc6749#section-1.5). - Default value is 1209600 seconds (two weeks). The refresh token is used - to acquire a new access token. Set to `0` to disable expiring the - refresh token, which keeps the refresh token valid. To keep the access - and refresh tokens valid indefinitely, see - [Set tokens to never expire](#set-tokens-to-never-expire). Refresh - tokens are typically issued with the Authorization Code Grant flow, - and are not applicable to the Implicit Grant flow. - - name: scopes - required: semi - default: - value_in_examples: - description: | - A string array of scope names that will be available to the - end user. See [Set mandatory scopes](#set-mandatory-scopes). - - name: token_expiration - required: true - default: 7200 - value_in_examples: 7200 - description: | - An integer value that indicates when an - [access token](https://tools.ietf.org/html/rfc6749#section-1.4) - expires, after which the client will need to refresh the token. Default - value is 7200 seconds (two hours). Set to `0` to disable the token - expiration. To keep the access and refresh tokens valid indefinitely, - see [Set tokens to never expire](#set-tokens-to-never-expire). - extra: | - **Important:** When configuring the plugin, at least one of the following - OAuth2 auth flows must be enabled: - - Authorization Code - - Client Credentials - - Implicit Grant - - Password Grant - ---- - -## Examples - -Replace `` with your host name or IP address, `{service}` with -your Service name, and `` with the -`display_name` of your Service for all examples in this section. - -### Enable the plugin with Client Credentials - -Command: - -``` -curl -X POST http://:8001/services/{service} \ - --data "name=application-registration" \ - --data "config.display_name=" \ - --data "config.enable_client_credentials=true" -``` - -Result: - -``` -{ - "created_at":1589485602, - "config":{ - "refresh_token_ttl":1209600, - "auto_approve":false, - "provision_key":"D7gc8R1vGD5lkod2wUrSRdpBPpte73kF", - "mandatory_scope":false, - "scopes":null, - "enable_implicit_grant":false, - "display_name":"my_service_display_name", - "enable_client_credentials":true, - "description":null, - "enable_password_grant":false, - "enable_authorization_code":false, - "token_expiration":7200, - "auth_header_name":"authorization" - }, - "id":"7696f657-00f9-462e-9d63-96d27140d2f8", - "service":{ - "id":"c2a45fd2-e753-46a0-955d-2ac7b4a18ce0" - }, - "name":"application-registration", - "protocols":[ - "grpc", - "grpcs", - "http", - "https" - ], - "enabled":true, - "run_on":null, - "consumer":null, - "route":null, - "tags":null -} -``` - -Note that the `provision_key` was autogenerated. - -### Enable the plugin with Authorization Code - -``` -curl -X POST http://:8001/services/{service} \ - --data "name=application-registration" \ - --data "config.display_name=" \ - --data "config.enable_authorization_code=true" -``` - -### Enable the plugin with Password Grant - -``` -curl -X POST http://:8001/services/{service} \ - --data "name=application-registration" \ - --data "config.display_name=" \ - --data "config.enable_password_grant=true" -``` - -### Enable the plugin with Implicit Grant - -``` -curl -X POST http://:8001/services/{service} \ - --data "name=application-registration" \ - --data "config.display_name=" \ - --data "config.enable_implicit_grant=true" -``` - -### Set tokens to never expire - -Set the `config.refresh_token_ttl` and `config.token_expiration` values to `0`. - -``` -curl -X POST http://:8001/services/{service} \ - --data "name=application-registration" \ - --data "config.display_name=" \ - --data "config.enable_authorization_code=true" - --data "config.refresh_token_ttl=0" \ - --data "config.token_expiration=0" -``` - -### Set mandatory scopes - -Replace `` and `` with the name of your scopes. - -``` -curl -X POST http://:8001/services/{service} \ - --data "name=application-registration" \ - --data "config.display_name=" \ - --data "config.enable_authorization_code=true" \ - --data "config.mandatory_scope=true" \ - --data "config.scopes[]=" -``` - -Multiple scopes: - -``` - ... - --data "config.scopes[]= " -``` -The scopes string array is space delimited. - -### Enable automatic registration approval - -Enable `auto_approve` so that application registration requests are automatically approved. Update your current configuration by running a PATCH command. Replace `{plugin_id}` with the `id` of your plugin. - -``` -curl -X PATCH http://:8001/plugins/{plugin_id} \ - --data "config.auto_approve=true" -``` diff --git a/app/_hub/kong-inc/application-registration/_index.md b/app/_hub/kong-inc/application-registration/_index.md index 8e5f5e0f1a2f..3bfa835b30f8 100644 --- a/app/_hub/kong-inc/application-registration/_index.md +++ b/app/_hub/kong-inc/application-registration/_index.md @@ -1,14 +1,13 @@ --- name: Portal Application Registration publisher: Kong Inc. -version: 2.0.x desc: Allow portal developers to register applications against Services description: | Applications allow registered developers on Kong Developer Portal to authenticate against a Gateway Service. Dev Portal admins can selectively admit access to Services using the - [Application Registration](/gateway/latest/developer-portal/administration/application-registration/enable-application-registration) plugin. + Application Registration plugin. {:.note} > **Note**: This plugin is for application registration in _self-managed_ Kong @@ -24,9 +23,9 @@ description: | Portal authorization provider. Either Kong Gateway (`kong-oauth2`) or a third-party OAuth provider (`external-oauth2`) can be the system of record (SoR) for application credentials. For more information, see - [Configure an Authorization Provider Strategy](/gateway/latest/developer-portal/administration/application-registration/auth-provider-strategy). + [Configure an Authorization Provider Strategy](/gateway/latest/kong-enterprise/developer-portal/applications/auth-provider-strategy/). - To learn how to set up key authentication, see [Enable Key Authentication for Application Registration](/gateway/latest/developer-portal/administration/application-registration/enable-key-auth-plugin/). + To learn how to set up key authentication, see [Enable Key Authentication for Application Registration](/gateway/latest/kong-enterprise/developer-portal/applications/enable-key-auth-plugin/). Supported authorization plugins for use with application registration: @@ -37,7 +36,7 @@ description: | | [OIDC](/hub/kong-inc/openid-connect)| `external-oauth2` | If you plan to use the external OAuth option with OIDC, review the - [supported OAuth workflows](/gateway/latest/developer-portal/administration/application-registration/3rd-party-oauth). + [supported OAuth workflows](/gateway/latest/kong-enterprise/developer-portal/applications/3rd-party-oauth). enterprise: true cloud: false type: plugin @@ -45,15 +44,7 @@ categories: - authentication kong_version_compatibility: enterprise_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x + compatible: true params: name: application-registration global: false @@ -127,9 +118,9 @@ curl -X PATCH http://:8001/plugins/{plugin_id} \ Enable `show_issuer` to expose the **Issuer URL** in the **Service Details** dialog. -**Note:** Exposing the [Issuer URL](/gateway/latest/developer-portal/administration/application-registration/enable-application-registration#show-url-issuer) is essential +**Note:** Exposing the [Issuer URL](/gateway/latest/kong-enterprise/developer-portal/applications/enable-application-registration#show-url-issuer) is essential for the -[Authorization Code Flow](/gateway/latest/developer-portal/administration/application-registration/3rd-party-oauth/#ac-flow) configured for third-party identity providers. +[Authorization Code Flow](/gateway/latest/kong-enterprise/developer-portal/applications/3rd-party-oauth/#ac-flow) configured for third-party identity providers. Update your current configuration by running a PATCH command. Replace `{plugin_id}` with the `id` of your plugin. diff --git a/app/_hub/kong-inc/application-registration/versions.yml b/app/_hub/kong-inc/application-registration/versions.yml index feac59c09064..499736e2925a 100644 --- a/app/_hub/kong-inc/application-registration/versions.yml +++ b/app/_hub/kong-inc/application-registration/versions.yml @@ -1,2 +1,12 @@ -- release: 2.0.x -- release: 1.0.x +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 2.0.0 + 2.7.x: 2.0.0 + 2.6.x: 2.0.0 + 2.5.x: 2.0.0 + 2.4.x: 2.0.0 + 2.3.x: 2.0.0 + 2.2.x: 2.0.0 + 2.1.x: 2.0.0 diff --git a/app/_hub/kong-inc/aws-lambda/0.1-x.md b/app/_hub/kong-inc/aws-lambda/0.1-x.md deleted file mode 100644 index 6f29bd1f2e63..000000000000 --- a/app/_hub/kong-inc/aws-lambda/0.1-x.md +++ /dev/null @@ -1,237 +0,0 @@ ---- -name: AWS Lambda -publisher: Kong Inc. -version: 0.1-x - -desc: Invoke and manage AWS Lambda functions from Kong -description: | - Invoke an [AWS Lambda](https://aws.amazon.com/lambda/) function from Kong. It - can be used in combination with other request plugins to secure, manage or extend - the function. - -
- Note: The functionality of this plugin as bundled - with versions of Kong prior to 0.14.0 and Kong Gateway prior to 0.34 - differs from what is documented herein. Refer to the - CHANGELOG - for details. -
- -type: plugin -categories: - - serverless - -kong_version_compatibility: - community_edition: - compatible: - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - enterprise_edition: - compatible: - - 0.34-x - - 0.33-x - - 0.32-x - - 0.31-x - -params: - - name: aws-lambda - api_id: true - service_id: true - route_id: true - consumer_id: true - protocols: ["http", "https"] - config: - - name: aws_key - required: true - value_in_examples: AWS_KEY - urlencode_in_examples: true - default: - description: The AWS key credential to be used when invoking the function - - name: aws_secret - required: true - value_in_examples: AWS_SECRET - urlencode_in_examples: true - default: - description: The AWS secret credential to be used when invoking the function - - name: aws_region - required: true - default: - value_in_examples: AWS_REGION - description: | - The AWS region where the Lambda function is located. Regions supported are: `us-east-1`, `us-east-2`, `ap-northeast-1`, `ap-northeast-2`, `ap-southeast-1`, `ap-southeast-2`, `eu-central-1`, `eu-west-1` - - name: function_name - required: true - default: - value_in_examples: LAMBDA_FUNCTION_NAME - description: The AWS Lambda function name to invoke - - name: qualifier - required: false - default: - description: | - The [`Qualifier`](http://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html#API_Invoke_RequestSyntax) to use when invoking the function. - - name: invocation_type - required: false - default: "`RequestResponse`" - description: | - The [`InvocationType`](http://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html#API_Invoke_RequestSyntax) to use when invoking the function. Available types are `RequestResponse`, `Event`, `DryRun` - - name: log_type - required: false - default: "`Tail`" - description: | - The [`LogType`](http://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html#API_Invoke_RequestSyntax) to use when invoking the function. By default `None` and `Tail` are supported - - name: timeout - required: false - default: "`60000`" - description: An optional timeout in milliseconds when invoking the function - - name: keepalive - required: false - default: "`60000`" - description: | - An optional value in milliseconds that defines how long an idle connection will live before being closed - - name: unhandled_status - required: false - default: "`200`, `202` or `204`" - description: | - The response status code to use (instead of the default `200`, `202`, or `204`) in the case of an [`Unhandled` Function Error](https://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html#API_Invoke_ResponseSyntax) - - name: forward_request_body - required: false - default: "`false`" - description: | - An optional value that defines whether the request body is to be sent in the `request_body` field of the JSON-encoded request. If the body arguments can be parsed, they will be sent in the separate `request_body_args` field of the request. The body arguments can be parsed for `application/json`, `application/x-www-form-urlencoded`, and `multipart/form-data` content types. - - name: forward_request_headers - required: false - default: "`false`" - description: | - An optional value that defines whether the original HTTP request headers are to be sent as a map in the `request_headers` field of the JSON-encoded request. - - name: forward_request_method - required: false - default: "`false`" - description: | - An optional value that defines whether the original HTTP request method verb is to be sent in the `request_method` field of the JSON-encoded request. - - name: forward_request_uri - required: false - default: "`false`" - description: | - An optional value that defines whether the original HTTP request URI is to be sent in the `request_uri` field of the JSON-encoded request. Request URI arguments (if any) will be sent in the separate `request_uri_args` field of the JSON body. - - extra: | - **Reminder**: curl by default sends payloads with an - `application/x-www-form-urlencoded` MIME type, which will naturally be URL- - decoded by Kong. To ensure special characters that are likely to appear in your - AWS key or secret (like `+`) are correctly decoded, you must URL-encode them, - hence use `--data-urlencode` if you are using curl. Alternatives to this - approach would be to send your payload with a different MIME type (like - `application/json`), or to use a different HTTP client. - ---- - -### Sending parameters - -Any form parameter sent along with the request, will be also sent as an -argument to the AWS Lambda function. - -### Known Issues - -#### Use a fake upstream service - -When using the AWS Lambda plugin, the response will be returned by the plugin -itself without proxying the request to any upstream service. This means that -a Service's `host`, `port`, `path` properties will be ignored, but must still -be specified for the entity to be validated by Kong. The `host` property in -particular must either be an IP address, or a hostname that gets resolved by -your nameserver. - -When the plugin is added to an API entity (which is deprecated as of 0.13.0), -it is the `upsream_url` property which must be specified and resolvable as well -(but ignored). - -#### Response plugins - -There is a known limitation in the system that prevents some response plugins -from being executed. We are planning to remove this limitation in the future. - -[api-object]: /gateway/latest/admin-api/#api-object -[configuration]: /gateway/latest/reference/configuration -[consumer-object]: /gateway/latest/admin-api/#consumer-object -[acl-associating]: /plugins/acl/#associating-consumers - - ---- -### Step By Step Guide - -#### The Steps -1. Access to AWS Console as user allowed to operate with lambda functions and create user and roles. -2. Create an Execution role in AWS -3. Create an user which will be invoke the function via Kong, test it. -4. Create an API in Kong, add the aws-lambda plugin linked to our aws function and execute it. - -#### Configure - -1. First, let's create an execution role called `LambdaExecutor` for our lambda function. - - In IAM Console create a new Role choosing the AWS Lambda service, there will be no policies as our function in this example will simply execute itself giving us back an hardcoded JSON as response without accessing other AWS resources. - -2. Now let's create a user named KongInvoker, used by our Kong API gateway to invoke the function. - - In IAM Console create a new user, must be provided to it programmatic access via Access and Secret keys; then will attach existing policies directly particularly the AWSLambdaRole predefined. Once the user creation is confirmed, store Access Key and Secret Key in a safe place. - -3. Now we need to create the lambda function itself, will do so in N.Virginia Region (code us-east-1). - - In Lambda Management, create a new function Mylambda, there will be no blueprint as we are going to paste the code below; for the execution role let's choose an existing role specifically LambdaExecutor created previously - - Use the inline code below to have a simple JSON response in return, note this is code for Python 3.6 interpreter. - - ```python - import json - def lambda_handler(event, context): - jsonbody='''{"response": "yes"}''' - return json.loads(jsonbody) - ``` - - Test the lambda function from the AWS console and make sure the execution succeeds. - -4. Finally we setup the api in Kong and link it to the function just created. - - The api that we are going to create doesn't really need a real `upstream_url` since we are not going to have an HTTP call to upstream but rather a response generated by our function. - - ```bash - curl -i -X POST http://{kong_hostname}:8001/apis \ - --data 'name=lambda1' \ - --data 'upstream_url=http://localhost:8000' \ - --data 'uris=/lambda1' - ``` - - Add the plugin: - - ```bash - curl -i -X POST http://{kong_hostname}:8001/apis/lambda1/plugins \ - --data 'name=aws-lambda' \ - --data-urlencode 'config.aws_key={KongInvoker user key}' \ - --data-urlencode 'config.aws_secret={KongInvoker user secret}' \ - --data 'config.aws_region=us-east-1' \ - --data 'config.function_name=MyLambda' - ``` - - Call the Api and verify the correct invocation, execution and response: - - ```bash - curl http://{kong_hostname}:8000/lambda1 - ``` - - Additional headers: - - ``` - x-amzn-Remapped-Content-Length, X-Amzn-Trace-Id, x-amzn-RequestId - ``` - - JSON response: - - ```json - {"response": "yes"} - ``` - -Have fun leveraging the power of AWS Lambda in Kong! diff --git a/app/_hub/kong-inc/aws-lambda/1.0-x.md b/app/_hub/kong-inc/aws-lambda/1.0-x.md deleted file mode 100644 index 2a50cdae683b..000000000000 --- a/app/_hub/kong-inc/aws-lambda/1.0-x.md +++ /dev/null @@ -1,309 +0,0 @@ ---- -name: AWS Lambda -publisher: Kong Inc. -version: 1.0-x - -desc: Invoke and manage AWS Lambda functions from Kong -description: | - Invoke an [AWS Lambda](https://aws.amazon.com/lambda/) function from Kong. It - can be used in combination with other request plugins to secure, manage, or - extend the function. - -
- Note: The functionality of this plugin as bundled - with versions of Kong prior to 0.14.0 and Kong Gateway prior to 0.34 - differs from what is documented herein. Refer to the - CHANGELOG - for details. -
- -type: plugin -categories: - - serverless - -kong_version_compatibility: - community_edition: - compatible: - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - enterprise_edition: - compatible: - - 1.5.x - - 1.3-x - - 0.36-x - - 0.35-x - - 0.34-x - - 0.33-x - - 0.32-x - - 0.31-x - -params: - - name: aws-lambda - service_id: true - route_id: true - consumer_id: true - protocols: ["http", "https"] - dbless_compatible: yes - config: - - name: aws_key - required: semi - value_in_examples: AWS_KEY - urlencode_in_examples: true - default: - description: The AWS key credential to be used when invoking the function. This value is required if `aws_secret` is defined. - - name: aws_secret - required: semi - value_in_examples: AWS_SECRET - urlencode_in_examples: true - default: - description: The AWS secret credential to be used when invoking the function. This value is required if `aws_key` is defined. - - name: aws_region - required: true - default: - value_in_examples: AWS_REGION - description: | - The AWS region where the Lambda function is located. Regions supported are: `ap-northeast-1`, `ap-northeast-2`, `ap-south-1`, `ap-southeast-1`, `ap-southeast-2`, `ca-central-1`, `cn-north-1`, `cn-northwest-1`, `eu-central-1`, `eu-west-1`, `eu-west-2`, `sa-east-1`, `us-east-1`, `us-east-2`, `us-gov-west-1`, `us-west-1`, `us-west-2`. - - name: function_name - required: true - default: - value_in_examples: LAMBDA_FUNCTION_NAME - description: The AWS Lambda function name to invoke. - - name: qualifier - required: false - default: - description: | - The [`Qualifier`](http://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html#API_Invoke_RequestSyntax) to use when invoking the function. - - name: invocation_type - required: false - default: "`RequestResponse`" - description: | - The [`InvocationType`](http://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html#API_Invoke_RequestSyntax) to use when invoking the function. Available types are `RequestResponse`, `Event`, `DryRun`. - - name: log_type - required: false - default: "`Tail`" - description: | - The [`LogType`](http://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html#API_Invoke_RequestSyntax) to use when invoking the function. By default, `None` and `Tail` are supported. - - name: timeout - required: false - default: "`60000`" - description: An optional timeout in milliseconds when invoking the function. - - name: port - required: false - default: "`443`" - description: | - The TCP port that this plugin will use to connect to the server. - - name: keepalive - required: false - default: "`60000`" - description: | - An optional value in milliseconds that defines how long an idle connection will live before being closed. - - name: unhandled_status - required: false - default: "`200`, `202` or `204`" - description: | - The response status code to use (instead of the default `200`, `202`, or `204`) in the case of an [`Unhandled` Function Error](https://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html#API_Invoke_ResponseSyntax). - - name: forward_request_body - required: false - default: "`false`" - description: | - An optional value that defines whether the request body is to be sent in the `request_body` field of the JSON-encoded request. If the body arguments can be parsed, they will be sent in the separate `request_body_args` field of the request. The body arguments can be parsed for `application/json`, `application/x-www-form-urlencoded`, and `multipart/form-data` content types. - - name: forward_request_headers - required: false - default: "`false`" - description: | - An optional value that defines whether the original HTTP request headers are to be sent as a map in the `request_headers` field of the JSON-encoded request. - - name: forward_request_method - required: false - default: "`false`" - description: | - An optional value that defines whether the original HTTP request method verb is to be sent in the `request_method` field of the JSON-encoded request. - - name: forward_request_uri - required: false - default: "`false`" - description: | - An optional value that defines whether the original HTTP request URI is to be sent in the `request_uri` field of the JSON-encoded request. Request URI arguments (if any) will be sent in the separate `request_uri_args` field of the JSON body. - - name: is_proxy_integration - required: false - default: "`false`" - description: | - An optional value that defines whether the response format to receive from the Lambda to [this format](https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-output-format). Note that the parameter `isBase64Encoded` is not implemented. - - extra: | - **Reminder**: cURL by default sends payloads with an - `application/x-www-form-urlencoded` MIME type, which will naturally be URL- - decoded by Kong. To ensure special characters that are likely to appear in - your AWS key or secret (like `+`) are correctly decoded, you must - URL-encode them, hence use `--data-urlencode` if you are using cURL. - Alternatives to this approach would be to send your payload with a - different MIME type (like `application/json`), or to use a different HTTP client. - ---- - -### Sending parameters - -Any form parameter sent along with the request will be also sent as an -argument to the AWS Lambda function. - -### Notes - -If you do not provide an `aws.key` and `aws.secret`, the plugin attempts to use an IAM role inherited from the instance running Kong. - -The plugin will first try ECS metadata to fetch the role; if no ECS metadata is available, the plugin will fall back on EC2 metadata. - -### Known Issues - -#### Use a fake upstream service - -When using the AWS Lambda plugin, the response will be returned by the plugin -itself without proxying the request to any upstream service. This means that -a Service's `host`, `port`, and `path` properties will be ignored, but must -still be specified for the entity to be validated by Kong. The `host` property -in particular must either be an IP address, or a hostname that gets resolved by -your nameserver. - -#### Response plugins - -There is a known limitation in the system that prevents some response plugins -from being executed. We are planning to remove this limitation in the future. - -[configuration]: /gateway/latest/reference/configuration -[consumer-object]: /gateway/latest/admin-api/#consumer-object -[acl-associating]: /plugins/acl/#associating-consumers - - ---- -### Step-By-Step Guide - -#### Steps - -You must have access to the AWS Console as a user who is allowed to operate -with lambda functions, and create users and roles. - -1. Create an Execution role in AWS. -2. Create a user that will invoke the function via Kong and test it. -3. Create a Service and Route in Kong, add the aws-lambda plugin linked to -our AWS function, and execute it. - -#### Configure - -1. First, let's create an execution role called `LambdaExecutor` for our -lambda function. - - In the IAM Console, create a new Role choosing the AWS Lambda service. There - will be no policies as our function in this example will simply execute - itself, giving us back a hardcoded JSON response without accessing other - AWS resources. - -2. Now let's create a user named `KongInvoker`, used by our Kong API gateway -to invoke the function. - - In the IAM Console, create a new user. Programmatic access must be provided to the user via Access and Secret keys. Then attach existing policies directly, particularly the predefined `AWSLambdaRole`. After the user creation is confirmed, store the Access Key and Secret Key in a safe place. - -3. Now we need to create the lambda function itself; we will do so in -N. Virginia Region (code `us-east-1`). - - In Lambda Management, create a new function `Mylambda`. There will be no blueprint because we are going to paste the code below (which is an example code snippet). Let's choose an existing role for the execution role, specifically `LambdaExecutor` created previously. - - **Note**: The following code snippet is only an example. The Kong AWS Lambda plugin supports all runtimes provided by AWS. See the list of runtimes in the **AWS Lambda** > **Functions** > **Create function** dialog. - - ```python - import json - def lambda_handler(event, context): - """ - If is_proxy_integration is set to true : - jsonbody='''{"statusCode": 200, "body": {"response": "yes"}}''' - """ - jsonbody='''{"response": "yes"}''' - return json.loads(jsonbody) - ``` - - Test the lambda function from the AWS console and make sure the execution succeeds. - -4. Finally, we set up a Service and Route in Kong and link it to the -`Mylambda` function we just created. - -{% navtabs %} -{% navtab With a database %} - -```bash -curl -i -X POST http://{kong_hostname}:8001/services \ ---data 'name=lambda1' \ ---data 'url=http://localhost:8000' \ -``` - -The Service doesn't really need a real `url` because we're not going to have an HTTP call to an Upstream but rather a response generated by our function. - -Also create a Route for the Service: - -``` -curl -i -X POST http://{kong_hostname}:8001/services/lambda1/routes \ ---data 'paths[1]=/lambda1' -``` - -Add the plugin: - -```bash -curl -i -X POST http://{kong_hostname}:8001/services/lambda1/plugins \ ---data 'name=aws-lambda' \ ---data-urlencode 'config.aws_key={KongInvoker user key}' \ ---data-urlencode 'config.aws_secret={KongInvoker user secret}' \ ---data 'config.aws_region=us-east-1' \ ---data 'config.function_name=MyLambda' -``` -{% endnavtab %} -{% navtab Without a database %} - -Add a Service, Route, and Plugin to the declarative config file: - -``` yaml -services: -- name: lambda1 - url: http://localhost:8000 - -routes: -- service: lambda1 - paths: [ "/lambda1" ] - -plugins: -- service: lambda1 - name: aws-lambda - config: - aws_key: {KongInvoker user key} - aws_secret: {KongInvoker user secret} - aws_region: us-east-1 - function_name: MyLambda -``` -{% endnavtab %} -{% endnavtabs %} - -After everything is created, call the Service and verify the correct -invocation, execution, and response: - -```bash -curl http://{kong_hostname}:8000/lambda1 -``` - -Additional headers: - -``` -x-amzn-Remapped-Content-Length, X-Amzn-Trace-Id, x-amzn-RequestId -``` - -JSON response: - -```json -{"response": "yes"} -``` - -Have fun leveraging the power of AWS Lambda in Kong! diff --git a/app/_hub/kong-inc/aws-lambda/3.0.x.md b/app/_hub/kong-inc/aws-lambda/3.0.x.md deleted file mode 100644 index 2b1e6e994a56..000000000000 --- a/app/_hub/kong-inc/aws-lambda/3.0.x.md +++ /dev/null @@ -1,334 +0,0 @@ ---- -name: AWS Lambda -publisher: Kong Inc. -version: 3.0.x - -desc: Invoke and manage AWS Lambda functions from Kong -description: | - Invoke an [AWS Lambda](https://aws.amazon.com/lambda/) function from Kong. It - can be used in combination with other request plugins to secure, manage, or - extend the function. - -
- Note: The functionality of this plugin as bundled - with versions of Kong prior to 0.14.0 and Kong Gateway prior to 0.34 - differs from what is documented herein. Refer to the - CHANGELOG - for details. -
- -type: plugin -categories: - - serverless - -kong_version_compatibility: - community_edition: - compatible: - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - enterprise_edition: - compatible: - - 1.5.x - - 1.3-x - - 0.36-x - - 0.35-x - - 0.34-x - - 0.33-x - - 0.32-x - - 0.31-x - -params: - - name: aws-lambda - service_id: true - route_id: true - consumer_id: true - protocols: ["http", "https"] - dbless_compatible: yes - config: - - name: aws_key - required: semi - value_in_examples: AWS_KEY - urlencode_in_examples: true - default: - description: The AWS key credential to be used when invoking the function. This value is required if `aws_secret` is defined. - - name: aws_secret - required: semi - value_in_examples: AWS_SECRET - urlencode_in_examples: true - default: - description: The AWS secret credential to be used when invoking the function. This value is required if `aws_key` is defined. - - name: aws_region - required: true - default: - value_in_examples: AWS_REGION - description: | - The AWS region where the Lambda function is located. Regions supported - are: `ap-northeast-1`, `ap-northeast-2`, `ap-south-1`, - `ap-southeast-1`, `ap-southeast-2`, `ca-central-1`, `cn-north-1`, - `cn-northwest-1`, `eu-central-1`, `eu-north-1`, `eu-west-1`, - `eu-west-2`, `eu-west-3`, `me-south-1`, `sa-east-1`, - `us-east-1`, `us-east-2`, `us-gov-west-1`, `us-west-1`, `us-west-2`. - - name: function_name - required: true - default: - value_in_examples: LAMBDA_FUNCTION_NAME - description: The AWS Lambda function name to invoke. - - name: qualifier - required: false - default: - description: | - The [`Qualifier`](http://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html#API_Invoke_RequestSyntax) to use when invoking the function. - - name: invocation_type - required: false - default: "`RequestResponse`" - description: | - The [`InvocationType`](http://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html#API_Invoke_RequestSyntax) to use when invoking the function. Available types are `RequestResponse`, `Event`, `DryRun`. - - name: log_type - required: false - default: "`Tail`" - description: | - The [`LogType`](http://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html#API_Invoke_RequestSyntax) to use when invoking the function. By default, `None` and `Tail` are supported. - - name: timeout - required: true - default: "`60000`" - description: An optional timeout in milliseconds when invoking the function. - - name: port - required: false - default: "`443`" - description: | - The TCP port that this plugin will use to connect to the server. - - name: keepalive - required: true - default: "`60000`" - description: | - An optional value in milliseconds that defines how long an idle connection will live before being closed. - - name: unhandled_status - required: false - default: "`200`, `202`, or `204`" - description: | - The response status code to use (instead of the default `200`, `202`, or `204`) in the case of an [`Unhandled` Function Error](https://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html#API_Invoke_ResponseSyntax). - - name: forward_request_body - required: false - default: "`false`" - description: | - An optional value that defines whether the request body is to be sent in the `request_body` field of the JSON-encoded request. If the body arguments can be parsed, they will be sent in the separate `request_body_args` field of the request. The body arguments can be parsed for `application/json`, `application/x-www-form-urlencoded`, and `multipart/form-data` content types. - - name: forward_request_headers - required: false - default: "`false`" - description: | - An optional value that defines whether the original HTTP request headers are to be sent as a map in the `request_headers` field of the JSON-encoded request. - - name: forward_request_method - required: false - default: "`false`" - description: | - An optional value that defines whether the original HTTP request method verb is to be sent in the `request_method` field of the JSON-encoded request. - - name: forward_request_uri - required: false - default: "`false`" - description: | - An optional value that defines whether the original HTTP request URI is to be sent in the `request_uri` field of the JSON-encoded request. Request URI arguments (if any) will be sent in the separate `request_uri_args` field of the JSON body. - - name: is_proxy_integration - required: false - default: "`false`" - description: | - An optional value that defines whether the response format to receive from the Lambda to [this format](https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-output-format). Note that the parameter `isBase64Encoded` is not implemented. - - name: awsgateway_compatible - required: false - default: "`false`" - description: | - An optional value that defines whether the plugin should wrap requests into the Amazon API gateway. - - name: proxy_url - required: semi - default: - description: | - An optional value that defines whether the plugin should connect through the given proxy server URL. This value is required if `proxy_scheme` is defined. - - name: proxy_scheme - required: semi - default: - description: | - An optional value that defines which HTTP scheme to use for connecting through the proxy server. The schemes supported are: `http` and `https`. This value is required if `proxy_url` is defined. - - name: skip_large_bodies - required: false - default: "`true`" - description: | - An optional value that defines whether Kong should send large bodies that are buffered to disk. To define the threshold for the body size, use the [client_body_buffer_size](https://docs.konghq.com/latest/configuration/#client_body_buffer_size) property. Note that sending large bodies will have an impact on system memory. - - extra: | - **Reminder**: By default, cURL sends payloads with an - `application/x-www-form-urlencoded` MIME type, which will naturally be URL- - decoded by Kong. To ensure special characters that are likely to appear in - your AWS key or secret (like `+`) are correctly decoded, you must - URL-encode them with `--data-urlencode`. - Alternatives to this approach would be to send your payload with a - different MIME type (like `application/json`), or to use a different HTTP client. - ---- - -### Sending parameters - -Any form parameter sent along with the request will be also sent as an -argument to the AWS Lambda function. - -### Notes - -If you do not provide an `aws.key` and `aws.secret`, the plugin uses an IAM role inherited from the instance running Kong. - -First, the plugin will try ECS metadata to get the role. If no ECS metadata is available, the plugin will fall back on EC2 metadata. - -### Known Issues - -#### Use a fake upstream service - -When using the AWS Lambda plugin, the response will be returned by the plugin -itself without proxying the request to any upstream service. This means that -a Service's `host`, `port`, and `path` properties will be ignored, but must -still be specified for the entity to be validated by Kong. The `host` property -in particular must either be an IP address, or a hostname that gets resolved by -your nameserver. - -#### Response plugins - -There is a known limitation in the system that prevents some response plugins -from being executed. We are planning to remove this limitation in the future. - -[configuration]: /gateway/latest/reference/configuration -[consumer-object]: /gateway/latest/admin-api/#consumer-object -[acl-associating]: /plugins/acl/#associating-consumers - - ---- -### Step-By-Step Guide - -#### Steps - -Prerequisite: You must have access to the AWS Console as a user who is -allowed to operate with lambda functions, and create users and roles. - -1. Create an Execution role in AWS. -2. Create a user that will invoke the function via Kong and test it. -3. Create a Service and Route in Kong, add the aws-lambda plugin linked to -our AWS function, and execute it. - -#### Configure - -1. First, create an execution role called `LambdaExecutor` for your -lambda function. - - In the IAM Console, create a new Role choosing the AWS Lambda service. There - will be no policies because the function in this example will simply execute - itself, returning a hardcoded JSON response without accessing other - AWS resources. - -2. Create a user named `KongInvoker`, used by the Kong API gateway -to invoke the function. - - In the IAM Console, create a new user. Programmatic access must be provided to the user via Access and Secret keys. Then, attach existing policies directly, particularly the predefined `AWSLambdaRole`. After the user creation is confirmed, store the Access Key and Secret Key in a safe place. - -3. Next, create the lambda function itself in the N. Virginia Region -(code `us-east-1`). - - In Lambda Management, create a new function `MyLambda`. There will be no blueprint because you are going to paste the code below (which is an example code snippet). For the execution role, choose the `LambdaExecutor` created previously. - - **Note**: The following code snippet is only an example. The Kong AWS Lambda plugin supports all runtimes provided by AWS. See the list of runtimes in the **AWS Lambda** > **Functions** > **Create function** dialog. - - ```python - import json - def lambda_handler(event, context): - """ - If is_proxy_integration is set to true : - jsonbody='''{"statusCode": 200, "body": {"response": "yes"}}''' - """ - jsonbody='''{"response": "yes"}''' - return json.loads(jsonbody) - ``` - - Test the lambda function from the AWS console and make sure the execution succeeds. - -4. Set up a Service and Route in Kong and link it to the -`MyLambda` function you just created. - -{% navtabs %} -{% navtab With a database %} - -```bash -curl -i -X POST http://{kong_hostname}:8001/services \ ---data 'name=lambda1' \ ---data 'url=http://localhost:8000' \ -``` - -The Service doesn't really need a real `url` because this example won't have an HTTP call to an Upstream but rather a response generated by the lambda function. - -Also create a Route for the Service: - -``` -curl -i -X POST http://{kong_hostname}:8001/services/lambda1/routes \ ---data 'paths[1]=/lambda1' -``` - -Add the plugin: - -```bash -curl -i -X POST http://{kong_hostname}:8001/services/lambda1/plugins \ ---data 'name=aws-lambda' \ ---data-urlencode 'config.aws_key={KongInvoker user key}' \ ---data-urlencode 'config.aws_secret={KongInvoker user secret}' \ ---data 'config.aws_region=us-east-1' \ ---data 'config.function_name=MyLambda' -``` -{% endnavtab %} -{% navtab Without a database %} - -Add a Service, Route, and Plugin to the declarative config file: - -``` yaml -services: -- name: lambda1 - url: http://localhost:8000 - -routes: -- service: lambda1 - paths: [ "/lambda1" ] - -plugins: -- service: lambda1 - name: aws-lambda - config: - aws_key: {KongInvoker user key} - aws_secret: {KongInvoker user secret} - aws_region: us-east-1 - function_name: MyLambda -``` -{% endnavtab %} -{% endnavtabs %} - -After everything is created, call the Service and verify the correct -invocation, execution, and response: - -```bash -curl http://{kong_hostname}:8000/lambda1 -``` - -Additional headers: - -``` -x-amzn-Remapped-Content-Length, X-Amzn-Trace-Id, x-amzn-RequestId -``` - -JSON response: - -```json -{"response": "yes"} -``` - -Have fun leveraging the power of AWS Lambda in Kong! diff --git a/app/_hub/kong-inc/aws-lambda/3.4.x.md b/app/_hub/kong-inc/aws-lambda/3.4.x.md deleted file mode 100644 index 6d5f2d2f3956..000000000000 --- a/app/_hub/kong-inc/aws-lambda/3.4.x.md +++ /dev/null @@ -1,343 +0,0 @@ ---- -name: AWS Lambda -publisher: Kong Inc. -version: 3.4.x - -desc: Invoke and manage AWS Lambda functions from Kong -description: | - Invoke an [AWS Lambda](https://aws.amazon.com/lambda/) function from Kong. It - can be used in combination with other request plugins to secure, manage, or - extend the function. - -
- Note: The functionality of this plugin as bundled - with versions of Kong prior to 0.14.0 and Kong Gateway prior to 0.34 - differs from what is documented herein. Refer to the - CHANGELOG - for details. -
- -type: plugin -categories: - - serverless - -kong_version_compatibility: - community_edition: - compatible: - - 2.1.x - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - enterprise_edition: - compatible: - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x - - 0.35-x - - 0.34-x - - 0.33-x - - 0.32-x - - 0.31-x - -params: - - name: aws-lambda - service_id: true - route_id: true - consumer_id: true - protocols: ["http", "https"] - dbless_compatible: yes - config: - - name: aws_key - required: semi - value_in_examples: AWS_KEY - urlencode_in_examples: true - default: - description: The AWS key credential to be used when invoking the function. This value is required if `aws_secret` is defined. If `aws_key` and `aws_secret` are not set, the plugin uses an IAM role inherited from the instance running Kong to authenticate. - - name: aws_secret - required: semi - value_in_examples: AWS_SECRET - urlencode_in_examples: true - default: - description: The AWS secret credential to be used when invoking the function. This value is required if `aws_key` is defined. If `aws_key` and `aws_secret` are not set, the plugin uses an IAM role inherited from the instance running Kong to authenticate. - - name: aws_region - required: semi - default: - value_in_examples: AWS_REGION - description: | - The AWS region where the Lambda function is located. The plugin does not - attempt to validate the supplied region name; if an invalid region name - is provided, the plugin will respond with an HTTP `500 Internal Server Error` - at run-time and log a DNS resolution failure. Either `aws_region` or `host` - must be provided. - - name: host - required: semi - default: - value_in_examples: - description: | - The host where the Lambda function is located. This value can point to a - local Lambda server, allowing for easier debugging. Either `host` or - `aws_region` must be provided. - - name: function_name - required: true - default: - value_in_examples: LAMBDA_FUNCTION_NAME - description: The AWS Lambda function name to invoke. - - name: qualifier - required: false - default: - description: | - The [`Qualifier`](http://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html#API_Invoke_RequestSyntax) to use when invoking the function. - - name: invocation_type - required: false - default: "`RequestResponse`" - description: | - The [`InvocationType`](http://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html#API_Invoke_RequestSyntax) to use when invoking the function. Available types are `RequestResponse`, `Event`, `DryRun`. - - name: log_type - required: false - default: "`Tail`" - description: | - The [`LogType`](http://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html#API_Invoke_RequestSyntax) to use when invoking the function. By default, `None` and `Tail` are supported. - - name: timeout - required: true - default: "`60000`" - description: An optional timeout in milliseconds when invoking the function. - - name: port - required: false - default: "`443`" - description: | - The TCP port that this plugin will use to connect to the server. - - name: keepalive - required: true - default: "`60000`" - description: | - An optional value in milliseconds that defines how long an idle connection will live before being closed. - - name: unhandled_status - required: false - default: "`200`, `202`, or `204`" - description: | - The response status code to use (instead of the default `200`, `202`, or `204`) in the case of an [`Unhandled` Function Error](https://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html#API_Invoke_ResponseSyntax). - - name: forward_request_body - required: false - default: "`false`" - description: | - An optional value that defines whether the request body is to be sent in the `request_body` field of the JSON-encoded request. If the body arguments can be parsed, they will be sent in the separate `request_body_args` field of the request. The body arguments can be parsed for `application/json`, `application/x-www-form-urlencoded`, and `multipart/form-data` content types. - - name: forward_request_headers - required: false - default: "`false`" - description: | - An optional value that defines whether the original HTTP request headers are to be sent as a map in the `request_headers` field of the JSON-encoded request. - - name: forward_request_method - required: false - default: "`false`" - description: | - An optional value that defines whether the original HTTP request method verb is to be sent in the `request_method` field of the JSON-encoded request. - - name: forward_request_uri - required: false - default: "`false`" - description: | - An optional value that defines whether the original HTTP request URI is to be sent in the `request_uri` field of the JSON-encoded request. Request URI arguments (if any) will be sent in the separate `request_uri_args` field of the JSON body. - - name: is_proxy_integration - required: false - default: "`false`" - description: | - An optional value that defines whether the response format to receive from the Lambda to [this format](https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-output-format). Note that the parameter `isBase64Encoded` is not implemented. - - name: awsgateway_compatible - required: false - default: "`false`" - description: | - An optional value that defines whether the plugin should wrap requests into the Amazon API gateway. - - name: proxy_url - required: semi - default: - description: | - An optional value that defines whether the plugin should connect through the given proxy server URL. This value is required if `proxy_scheme` is defined. - - name: proxy_scheme - required: semi - default: - description: | - An optional value that defines which HTTP scheme to use for connecting through the proxy server. The schemes supported are: `http` and `https`. This value is required if `proxy_url` is defined. - - name: skip_large_bodies - required: false - default: "`true`" - description: | - An optional value that defines whether Kong should send large bodies that are buffered to disk. To define the threshold for the body size, use the [client_body_buffer_size](https://docs.konghq.com/latest/configuration/#client_body_buffer_size) property. Note that sending large bodies will have an impact on system memory. - - extra: | - **Reminder**: By default, cURL sends payloads with an - `application/x-www-form-urlencoded` MIME type, which will naturally be URL- - decoded by Kong. To ensure special characters that are likely to appear in - your AWS key or secret (like `+`) are correctly decoded, you must - URL-encode them with `--data-urlencode`. - Alternatives to this approach would be to send your payload with a - different MIME type (like `application/json`), or to use a different HTTP client. - ---- - -### Sending parameters - -Any form parameter sent along with the request will be also sent as an -argument to the AWS Lambda function. - -### Notes - -If you do not provide an `aws_key` and `aws_secret`, the plugin uses an IAM role inherited from the instance running Kong. - -First, the plugin will try ECS metadata to get the role. If no ECS metadata is available, the plugin will fall back on EC2 metadata. - -### Known Issues - -#### Use a fake upstream service - -When using the AWS Lambda plugin, the response will be returned by the plugin -itself without proxying the request to any upstream service. This means that -a Service's `host`, `port`, and `path` properties will be ignored, but must -still be specified for the entity to be validated by Kong. The `host` property -in particular must either be an IP address, or a hostname that gets resolved by -your nameserver. - -#### Response plugins - -There is a known limitation in the system that prevents some response plugins -from being executed. We are planning to remove this limitation in the future. - -[configuration]: /gateway/latest/reference/configuration -[consumer-object]: /gateway/latest/admin-api/#consumer-object -[acl-associating]: /plugins/acl/#associating-consumers - - ---- -### Step-By-Step Guide - -#### Steps - -Prerequisite: You must have access to the AWS Console as a user who is -allowed to operate with lambda functions, and create users and roles. - -1. Create an Execution role in AWS. -2. Create a user that will invoke the function via Kong and test it. -3. Create a Service and Route in Kong, add the aws-lambda plugin linked to -our AWS function, and execute it. - -#### Configure - -1. First, create an execution role called `LambdaExecutor` for your -lambda function. - - In the IAM Console, create a new Role choosing the AWS Lambda service. There - will be no policies because the function in this example will simply execute - itself, returning a hardcoded JSON response without accessing other - AWS resources. - -2. Create a user named `KongInvoker`, used by the Kong API gateway -to invoke the function. - - In the IAM Console, create a new user. Programmatic access must be provided to the user via Access and Secret keys. Then, attach existing policies directly, particularly the predefined `AWSLambdaRole`. After the user creation is confirmed, store the Access Key and Secret Key in a safe place. - -3. Next, create the lambda function itself in the N. Virginia Region -(code `us-east-1`). - - In Lambda Management, create a new function `MyLambda`. There will be no blueprint because you are going to paste the code below (which is an example code snippet). For the execution role, choose the `LambdaExecutor` created previously. - - **Note**: The following code snippet is only an example. The Kong AWS Lambda plugin supports all runtimes provided by AWS. See the list of runtimes in the **AWS Lambda** > **Functions** > **Create function** dialog. - - ```python - import json - def lambda_handler(event, context): - """ - If is_proxy_integration is set to true : - jsonbody='''{"statusCode": 200, "body": {"response": "yes"}}''' - """ - jsonbody='''{"response": "yes"}''' - return json.loads(jsonbody) - ``` - - Test the lambda function from the AWS console and make sure the execution succeeds. - -4. Set up a Service and Route in Kong and link it to the -`MyLambda` function you just created. - -{% navtabs %} -{% navtab With a database %} - -```bash -curl -i -X POST http://{kong_hostname}:8001/services \ ---data 'name=lambda1' \ ---data 'url=http://localhost:8000' \ -``` - -The Service doesn't really need a real `url` because this example won't have an HTTP call to an Upstream but rather a response generated by the lambda function. - -Also create a Route for the Service: - -``` -curl -i -X POST http://{kong_hostname}:8001/services/lambda1/routes \ ---data 'paths[1]=/lambda1' -``` - -Add the plugin: - -```bash -curl -i -X POST http://{kong_hostname}:8001/services/lambda1/plugins \ ---data 'name=aws-lambda' \ ---data-urlencode 'config.aws_key={KongInvoker user key}' \ ---data-urlencode 'config.aws_secret={KongInvoker user secret}' \ ---data 'config.aws_region=us-east-1' \ ---data 'config.function_name=MyLambda' -``` -{% endnavtab %} -{% navtab Without a database %} - -Add a Service, Route, and Plugin to the declarative config file: - -``` yaml -services: -- name: lambda1 - url: http://localhost:8000 - -routes: -- service: lambda1 - paths: [ "/lambda1" ] - -plugins: -- service: lambda1 - name: aws-lambda - config: - aws_key: {KongInvoker user key} - aws_secret: {KongInvoker user secret} - aws_region: us-east-1 - function_name: MyLambda -``` -{% endnavtab %} -{% endnavtabs %} - -After everything is created, call the Service and verify the correct -invocation, execution, and response: - -```bash -curl http://{kong_hostname}:8000/lambda1 -``` - -Additional headers: - -``` -x-amzn-Remapped-Content-Length, X-Amzn-Trace-Id, x-amzn-RequestId -``` - -JSON response: - -```json -{"response": "yes"} -``` - -Have fun leveraging the power of AWS Lambda in Kong! diff --git a/app/_hub/kong-inc/aws-lambda/3.5.x.md b/app/_hub/kong-inc/aws-lambda/3.5.x.md deleted file mode 100644 index a0d3e0e79944..000000000000 --- a/app/_hub/kong-inc/aws-lambda/3.5.x.md +++ /dev/null @@ -1,360 +0,0 @@ ---- -name: AWS Lambda -publisher: Kong Inc. -version: 3.5.x - -desc: Invoke and manage AWS Lambda functions from Kong -description: | - Invoke an [AWS Lambda](https://aws.amazon.com/lambda/) function from Kong. The - AWS Lambda plugin can be used in combination with other request plugins to secure, manage, or - extend the function. - -type: plugin -categories: - - serverless - -kong_version_compatibility: - community_edition: - compatible: - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - enterprise_edition: - compatible: - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x - - -params: - - name: aws-lambda - service_id: true - route_id: true - consumer_id: true - protocols: ["http", "https"] - dbless_compatible: yes - config: - - name: aws_key - required: semi - value_in_examples: - urlencode_in_examples: true - default: - datatype: string - description: | - The AWS key credential to be used when invoking the function. The `aws_key` value is required - if `aws_secret` is defined. If `aws_key` and `aws_secret` are not set, the plugin uses an - IAM role inherited from the instance running Kong to authenticate. Can be symmetrically encrypted - if using Kong Gateway and [data encryption](https://docs.konghq.com/gateway/latest/plan-and-deploy/security/db-encryption/) - is configured. - - name: aws_secret - required: semi - value_in_examples: - urlencode_in_examples: true - default: - datatype: string - description: | - The AWS secret credential to be used when invoking the function. The `aws_secret` value is required - if `aws_key` is defined. If `aws_key` and `aws_secret` are not set, the plugin uses an - IAM role inherited from the instance running Kong to authenticate. Can be symmetrically encrypted - if using Kong Gateway and [data encryption](https://docs.konghq.com/gateway/latest/plan-and-deploy/security/db-encryption/) - is configured. - - name: aws_region - required: true - default: - value_in_examples: - datatype: string - description: | - The AWS region where the Lambda function is located. The plugin does not - attempt to validate the supplied region name. If an invalid region name - is provided, the plugin responds with an HTTP `500 Internal Server Error` - at run-time and logs a DNS resolution failure. Either `aws_region` or `host` - must be provided. - - name: host - required: semi - default: - value_in_examples: - datatype: string - description: | - The host where the Lambda function is located. This value can point to a - local Lambda server, allowing for easier debugging. Either `host` or - `aws_region` must be provided. - - name: function_name - required: true - default: - value_in_examples: - datatype: string - description: The AWS Lambda function name to invoke. - - name: qualifier - required: false - default: - datatype: string - description: | - The [`Qualifier`](http://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html#API_Invoke_RequestSyntax) to use when invoking the function. - - name: invocation_type - required: true - default: "`RequestResponse`" - datatype: string - description: | - The [`InvocationType`](http://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html#API_Invoke_RequestSyntax) to use when invoking the function. Available types are `RequestResponse`, `Event`, `DryRun`. - - name: log_type - required: true - default: "`Tail`" - datatype: string - description: | - The [`LogType`](http://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html#API_Invoke_RequestSyntax) to use when invoking the function. By default, `None` and `Tail` are supported. - - name: timeout - required: true - default: "`60000`" - datatype: number - description: An optional timeout in milliseconds when invoking the function. - - name: port - required: false - default: "`443`" - datatype: integer - description: | - The TCP port that the plugin uses to connect to the server. - - name: keepalive - required: true - default: "`60000`" - datatype: number - description: | - An optional value in milliseconds that defines how long an idle connection lives before being closed. - - name: unhandled_status - required: false - default: "`200`, `202`, or `204`" - datatype: integer - description: | - The response status code to use (instead of the default `200`, `202`, or `204`) in the case of an - [`Unhandled` Function Error](https://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html#API_Invoke_ResponseSyntax). - - name: forward_request_body - required: false - default: "`false`" - datatype: boolean - description: | - An optional value that defines whether the request body is sent in the `request_body` field of the JSON-encoded request. - If the body arguments can be parsed, they are sent in the separate `request_body_args` field of the request. - The body arguments can be parsed for `application/json`, `application/x-www-form-urlencoded`, and `multipart/form-data` content types. - - name: forward_request_headers - required: false - default: "`false`" - datatype: boolean - description: | - An optional value that defines whether the original HTTP request headers are - sent as a map in the `request_headers` field of the JSON-encoded request. - - name: forward_request_method - required: false - default: "`false`" - datatype: boolean - description: | - An optional value that defines whether the original HTTP request method verb is - sent in the `request_method` field of the JSON-encoded request. - - name: forward_request_uri - required: false - default: "`false`" - datatype: boolean - description: | - An optional value that defines whether the original HTTP request URI is sent in - the `request_uri` field of the JSON-encoded request. Request URI arguments (if any) are sent in - the separate `request_uri_args` field of the JSON body. - - name: is_proxy_integration - required: false - default: "`false`" - datatype: boolean - description: | - An optional value that defines whether the response format to receive from the Lambda to - [this format](https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-output-format). - - name: awsgateway_compatible - required: false - default: "`false`" - datatype: boolean - description: | - An optional value that defines whether the plugin should wrap requests into the Amazon API gateway. - - name: proxy_url - required: semi - default: - datatype: string - description: | - An optional value that defines whether the plugin should connect through the given proxy server URL. - The `proxy_url` value is required if `proxy_scheme` is defined. - - name: proxy_scheme - required: semi - default: - datatype: string - description: | - An optional value that defines which HTTP scheme to use for connecting through the proxy server. The - supported schemes are `http` and `https`. The `proxy_scheme` value is required if `proxy_url` is defined. - - name: skip_large_bodies - required: false - default: "`true`" - datatype: boolean - description: | - An optional value that defines whether Kong should send large - bodies that are buffered to disk. Note that enabling this option will have an impact - on system memory depending on the number of requests simultaneously in flight at any given point in time - and on the maximum size of each request. Also this option blocks all requests being handled by the - nginx workers. That could be tens of thousands of other transactions that are not being processed. For small I/O - operations, such a delay would generally not be problematic. In cases where the body size is in the order of MB, - such a delay would cause notable interruptions in request processing. Given all of the potential - downsides resulting from enabling this option, consider increasing the - [client_body_buffer_size](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_buffer_size) - value instead. - - name: base64_encode_body - required: false - default: "`true`" - datatype: boolean - description: | - An optional value that Base64-encodes the request body. - - extra: | - **Reminder**: By default, cURL sends payloads with an - `application/x-www-form-urlencoded` MIME type, which will naturally be URL- - decoded by Kong. To ensure special characters that are likely to appear in - your AWS key or secret (like `+`) are correctly decoded, you must - URL-encode them with `--data-urlencode`. - Alternatives to this approach would be to send your payload with a - different MIME type (like `application/json`), or to use a different HTTP client. - ---- - -### Sending parameters - -Any form parameter sent along with the request is also sent as an -argument to the AWS Lambda function. - ---- -### Notes - -If you do not provide an `aws_key` and `aws_secret`, the plugin uses an IAM role inherited -from the instance running Kong. - -First, the plugin tries ECS metadata to get the role. If no ECS metadata is available, -the plugin falls back on EC2 metadata. - ---- -### Step-By-Step Guide - -Prerequisite: You must have access to the AWS Console as a user who is -allowed to operate with lambda functions, and create users and roles. - -1. First, create an execution role called `LambdaExecutor` for your -lambda function. - - In the IAM Console, create a new Role choosing the AWS Lambda service. There - will be no policies because the function in this example will simply execute - itself, returning a hardcoded JSON response without accessing other - AWS resources. - -2. Create a user named `KongInvoker`, used by the Kong API gateway -to invoke the function. - - In the IAM Console, create a new user. Programmatic access must be provided to the user via Access and Secret keys. Then, attach existing policies directly, particularly the predefined `AWSLambdaRole`. After the user creation is confirmed, store the Access Key and Secret Key in a safe place. - -3. Next, create the lambda function itself in the N. Virginia Region -(code `us-east-1`). - - In Lambda Management, create a new function `MyLambda`. There will be no blueprint because you are going to paste the code below (which is an example code snippet). For the execution role, choose the `LambdaExecutor` created previously. - - **Note**: The following code snippet is only an example. The Kong AWS Lambda plugin supports all runtimes provided by AWS. See the list of runtimes in the **AWS Lambda** > **Functions** > **Create function** dialog. - - ```python - import json - def lambda_handler(event, context): - """ - If is_proxy_integration is set to true : - jsonbody='''{"statusCode": 200, "body": {"response": "yes"}}''' - """ - jsonbody='''{"response": "yes"}''' - return json.loads(jsonbody) - ``` - - Test the lambda function from the AWS console and make sure the execution succeeds. - -4. Set up a route in Kong and link it to the `MyLambda` function you just created. - -{% navtabs %} -{% navtab With a database %} - -Create the route: - -```bash -curl -i -X POST http://:8001/routes \ ---data 'name=lambda1' \ ---data 'paths[1]=/lambda1' -``` - -Add the plugin: - -```bash -curl -i -X POST http://:8001/routes/lambda1/plugins \ ---data 'name=aws-lambda' \ ---data-urlencode 'config.aws_key={KongInvoker user key}' \ ---data-urlencode 'config.aws_secret={KongInvoker user secret}' \ ---data 'config.aws_region=us-east-1' \ ---data 'config.function_name=MyLambda' -``` - -{% endnavtab %} -{% navtab Without a database %} - -Add a route and plugin to the declarative config file: - -``` yaml -routes: -- name: lambda1 - paths: [ "/lambda1" ] - -plugins: -- route: lambda1 - name: aws-lambda - config: - aws_key: {KongInvoker user key} - aws_secret: {KongInvoker user secret} - aws_region: us-east-1 - function_name: MyLambda -``` - -{% endnavtab %} -{% endnavtabs %} - -#### Test your Lambda with Kong - -After everything is created, make the http request and verify the correct -invocation, execution, and response: - -```bash -curl http://:8000/lambda1 -``` - -Additional headers: - -``` -x-amzn-Remapped-Content-Length, X-Amzn-Trace-Id, x-amzn-RequestId -``` - -JSON response: - -```json -{"response": "yes"} -``` - -Have fun leveraging the power of AWS Lambda in Kong! diff --git a/app/_hub/kong-inc/aws-lambda/_index.md b/app/_hub/kong-inc/aws-lambda/_index.md index 569e49b5b7f6..09ec32157edf 100644 --- a/app/_hub/kong-inc/aws-lambda/_index.md +++ b/app/_hub/kong-inc/aws-lambda/_index.md @@ -1,7 +1,6 @@ --- name: AWS Lambda publisher: Kong Inc. -version: 3.6.x desc: Invoke and manage AWS Lambda functions from Kong description: | Invoke an [AWS Lambda](https://aws.amazon.com/lambda/) function from Kong. The @@ -12,13 +11,9 @@ categories: - serverless kong_version_compatibility: community_edition: - compatible: - - 2.8.x - - 2.7.x + compatible: true enterprise_edition: - compatible: - - 2.8.x - - 2.7.x + compatible: true params: name: aws-lambda service_id: true @@ -40,8 +35,12 @@ params: The AWS key credential to be used when invoking the function. The `aws_key` value is required if `aws_secret` is defined. If `aws_key` and `aws_secret` are not set, the plugin uses an IAM role inherited from the instance running Kong to authenticate. Can be symmetrically encrypted - if using Kong Gateway and [data encryption](https://docs.konghq.com/gateway/latest/plan-and-deploy/security/db-encryption/) + if using Kong Gateway and [data encryption](/gateway/latest/kong-production/db-encryption/) is configured. + + This field is _referenceable_, which means it can be securely stored as a + [secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). - name: aws_secret required: semi value_in_examples: @@ -53,9 +52,28 @@ params: The AWS secret credential to be used when invoking the function. The `aws_secret` value is required if `aws_key` is defined. If `aws_key` and `aws_secret` are not set, the plugin uses an IAM role inherited from the instance running Kong to authenticate. Can be symmetrically encrypted - if using Kong Gateway and [data encryption](https://docs.konghq.com/gateway/latest/plan-and-deploy/security/db-encryption/) + if using Kong Gateway and [data encryption](/gateway/latest/kong-production/db-encryption/) is configured. - - name: aws_region + + This field is _referenceable_, which means it can be securely stored as a + [secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). + - name: aws_region # old version, do not update + maximum_version: "2.5.x" + required: true + default: + value_in_examples: + datatype: string + description: | + The AWS region where the Lambda function is located. The plugin does not + attempt to validate the supplied region name. If an invalid region name + is provided, the plugin responds with an HTTP `500 Internal Server Error` + at runtime and logs a DNS resolution failure. Either `aws_region` or `host` + must be provided. + + - name: aws_region # old version, do not update + minimum_version: "2.6.x" + maximum_version: "2.8.x" required: false default: null value_in_examples: @@ -64,14 +82,43 @@ params: The AWS region where the Lambda function is located. The plugin does not attempt to validate the supplied region name. If an invalid region name is provided, the plugin responds with an HTTP `500 Internal Server Error` - at run-time and logs a DNS resolution failure. The plugin will automatically - detect AWS region on runtime via `AWS_REGION` or `AWS_DEFAULT_REGION` environment - variables when neither `region` nor `host` is specified in plugin configuration. + at runtime and logs a DNS resolution failure. + + The plugin will automatically + detect the AWS region on runtime via `AWS_REGION` or `AWS_DEFAULT_REGION` environment + variables when neither `aws_region` nor `host` is specified in plugin configuration. Using environment variables enables regionally distributed Kong cluster nodes - to connect to the closest AWS region. If `region`, `host` and environment + to connect to the closest AWS region. If `aws_region`, `host` and environment variables have not been specified, the plugin responds with an HTTP `500 Internal Server Error` at run-time. + + - name: aws_region # current version of parameter + minimum_version: "3.0.x" + required: semi + default: null + value_in_examples: + datatype: string + description: | + The AWS region where the Lambda function is located. The plugin does not + attempt to validate the supplied region name. + + The plugin has two methods of detecting the AWS region: the `aws_region` + parameter, or one of the `AWS_REGION` or `AWS_DEFAULT_REGION` environment + variables. One of these must be set. + + If `region` is not specified in plugin configuration, the plugin + automatically detects the AWS region on runtime via one of the environment + variables. + Using environment variables enables regionally distributed Kong cluster nodes + to connect to the closest AWS region. + + The AWS region is required for AWS SigV4. + If `aws_region` or the `AWS_REGION` or `AWS_DEFAULT_REGION` environment + variables have not been specified, or an invalid region name has been provided, + the plugin responds with an HTTP `500 Internal Server Error` at runtime. + - name: aws_assume_role_arn + minimum_version: "2.8.x" required: false default: null value_in_examples: @@ -79,7 +126,12 @@ params: description: | The target AWS IAM role ARN used to invoke the Lambda function. Typically this is used for a cross-account Lambda function invocation. + + This field is _referenceable_, which means it can be securely stored as a + [secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). - name: aws_role_session_name + minimum_version: "2.8.x" required: false default: '`kong`' value_in_examples: @@ -88,7 +140,22 @@ params: The identifier of the assumed role session. It is used for uniquely identifying a session when the same target role is assumed by different principals or for different reasons. The role session name is also used in the ARN of the assumed role principle. + + - name: host + minimum_version: "2.1.x" + maximum_version: "2.5.x" + required: semi + default: null + value_in_examples: null + datatype: string + description: | + The host where the Lambda function is located. This value can point to a + local Lambda server, allowing for easier debugging. + + Either `aws_region` or `host` must be provided. + - name: host + minimum_version: "3.0.x" required: false default: null value_in_examples: null @@ -96,6 +163,9 @@ params: description: | The host where the Lambda function is located. This value can point to a local Lambda server, allowing for easier debugging. + + To set a region, use the `aws_region` parameter. + - name: function_name required: true default: null @@ -103,7 +173,7 @@ params: datatype: string description: | The AWS Lambda function name to invoke. This may contain - the function name only (`my-function`), the full ARN + the function name only (`my-function`), the full ARN (arn:aws:lambda:us-west-2:123456789012:function:my-function) or a partial ARN (123456789012:function:my-function). You can also append a version number or alias to any of the formats. @@ -205,15 +275,15 @@ params: Kong Gateway uses HTTP tunneling via the [CONNECT HTTP](https://httpwg.org/specs/rfc7231.html#CONNECT) method so that no details of the AWS Lambda request are leaked to the proxy server. - - name: proxy_scheme + - name: proxy_scheme # deprecated and removed + maximum_version: "2.8.x" required: semi default: null datatype: string description: | {:.important} - > As of Kong Gateway 2.8.0.0, this parameter is deprecated and will be - removed in 3.x.x. + > As of Kong Gateway 2.8.0.0, this parameter is deprecated. >

> If running Kong Gateway 2.7.x or earlier, the `proxy_scheme` value is required if `proxy_url` is defined. In 2.8.x or @@ -221,6 +291,7 @@ params: An optional value that defines which HTTP scheme to use for connecting through the proxy server. The supported schemes are `http` and `https`. + - name: skip_large_bodies required: false default: '`true`' @@ -237,6 +308,7 @@ params: [client_body_buffer_size](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_buffer_size) value instead. - name: base64_encode_body + minimum_version: "2.2.x" required: false default: '`true`' datatype: boolean @@ -252,13 +324,13 @@ params: different MIME type (like `application/json`), or to use a different HTTP client. --- -### Sending parameters +## Sending parameters Any form parameter sent along with the request is also sent as an argument to the AWS Lambda function. --- -### Notes +## Notes If you provide `aws_key` and `aws_secret`, they will be used in the highest priority to invoke the Lambda function. @@ -266,6 +338,15 @@ invoke the Lambda function. If you do not provide an `aws_key` and `aws_secret`, the plugin uses an IAM role inherited from the instance running Kong. +{% if_plugin_version lte:2.7.x %} + +First, the plugin tries ECS metadata to get the role. If no ECS metadata is available, +the plugin falls back on EC2 metadata. + +{% endif_plugin_version %} + +{% if_plugin_version gte:2.8.x %} + For example, if you're running Kong on an EC2 instance, the IAM role that attached to the EC2 will be used, and Kong will fetch the credential from the [EC2 Instance Metadata service(IMDSv1)](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html). @@ -281,7 +362,10 @@ configuring AWS access key/secret or fetching credentials automatically from EC2 If it succeeds, the plugin will fetch a temporary security credentials that represents that the plugin now has the access permission configured in the target assumed role. -### AWS Region as Environment Variable +{% endif_plugin_version %} + +{% if_plugin_version gte:2.6.x %} +## AWS region as environment variable If the plugin configuration `aws_region` is unset, the plugin attempts to obtain the AWS region through environment variables `AWS_REGION` and `AWS_DEFAULT_REGION`, @@ -291,8 +375,30 @@ with the former taking higher precedence. For example, if both `AWS_REGION` and nor environment variables are set, a run-time error "no region or host specified" will be thrown. +{% endif_plugin_version %} + +{% if_plugin_version lte:2.1.x %} + +### Known issues + +#### Use a fake upstream service + +When using the AWS Lambda plugin, the response will be returned by the plugin +itself without proxying the request to any upstream service. This means that +a service's `host`, `port`, and `path` properties will be ignored, but must +still be specified for the entity to be validated by Kong. The `host` property +in particular must either be an IP address, or a hostname that gets resolved by +your nameserver. + +#### Response plugins + +There is a known limitation in the system that prevents some response plugins +from being executed. We are planning to remove this limitation in the future. + +{% endif_plugin_version %} + --- -### Step-By-Step Guide +## Usage Prerequisite: You must have access to the AWS Console as a user who is allowed to operate with lambda functions, and create users and roles. @@ -377,7 +483,7 @@ plugins: {% endnavtab %} {% endnavtabs %} -#### Test your Lambda with Kong +### Test your Lambda with Kong After everything is created, make the http request and verify the correct invocation, execution, and response: @@ -404,15 +510,45 @@ Have fun leveraging the power of AWS Lambda in Kong! ## Changelog -> See the Kong GitHub repository for the -[full plugin changelog](https://github.com/Kong/kong/blob/master/kong/plugins/aws-lambda/CHANGELOG.md). +{% if_plugin_version gte:3.0.x %} -### {{site.base_gateway}} 2.8.x (plugin version 3.6.3) +**{{site.base_gateway}} 3.0.x** +* The `proxy_scheme` configuration parameter has been removed from the plugin. +* The plugin now allows both `aws_region` and `host` to be set at the same time. +{% endif_plugin_version %} + +{% if_plugin_version gte:2.8.x %} + +**{{site.base_gateway}} 2.8.x** * The `proxy_scheme` configuration parameter is deprecated and planned to be removed in 3.x.x. +* {{site.base_gateway}} 2.8.1.3: Added support for cross account invocation +through configuration properties `aws_assume_role_arn` and `aws_role_session_name`. -### {{site.base_gateway}} 2.7.x (plugin version 3.6.0) +{% endif_plugin_version %} +{% if_plugin_version gte:2.7.x %} + +**{{site.base_gateway}} 2.7.x** * Starting with {{site.base_gateway}} 2.7.0.0, if keyring encryption is enabled, the `config.aws_key` and `config.aws_secret` parameter values will be encrypted. + +{% endif_plugin_version %} + +{% if_plugin_version gte:2.6.x %} + +**{{site.base_gateway}} 2.6.x** +* The AWS region can now be set with the environment variables: `AWS_REGION` or `AWS_DEFAULT_REGION`. + +{% endif_plugin_version %} + +{% if_plugin_version gte:2.2.x %} + +**{{site.base_gateway}} 2.2.x** +* Added support for `isBase64Encoded` flag in Lambda function responses. + +{% endif_plugin_version %} + +**{{site.base_gateway}} 2.1.x** +* Added `host` configuration to allow for custom Lambda endpoints. diff --git a/app/_hub/kong-inc/aws-lambda/versions.yml b/app/_hub/kong-inc/aws-lambda/versions.yml index 60683f2fc151..e162a3df59c5 100644 --- a/app/_hub/kong-inc/aws-lambda/versions.yml +++ b/app/_hub/kong-inc/aws-lambda/versions.yml @@ -1,6 +1,12 @@ -- release: 3.6.x -- release: 3.5.x -- release: 3.4.x -- release: 3.0.x -- release: 1.0-x -- release: 0.1-x +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 3.6.3 + 2.7.x: 3.6.2 + 2.6.x: 3.6.2 + 2.5.x: 3.5.4 + 2.4.x: 3.5.4 + 2.3.x: 3.5.4 + 2.2.x: 3.5.4 + 2.1.x: 3.4.0 diff --git a/app/_hub/kong-inc/azure-functions/0.1-x.md b/app/_hub/kong-inc/azure-functions/0.1-x.md deleted file mode 100644 index 50a20ee17244..000000000000 --- a/app/_hub/kong-inc/azure-functions/0.1-x.md +++ /dev/null @@ -1,180 +0,0 @@ ---- -name: Azure Functions -publisher: Kong Inc. -version: 0.1-x - -source_url: https://github.com/Kong/kong-plugin-azure-functions - -desc: Invoke and manage Azure functions from Kong -description: | - This plugin invokes - [Azure Functions](https://azure.microsoft.com/en-us/services/functions/). - It can be used in combination with other request plugins to secure, manage - or extend the function. - -type: plugin -categories: - - serverless - -kong_version_compatibility: - community_edition: - compatible: - - 0.14.x - enterprise_edition: - compatible: - -params: - name: azure-functions - api_id: true - service_id: true - route_id: true - consumer_id: true - config: - - name: functionname - required: true - default: - value_in_examples: AZURE_FUNCTIONNAME - description: Name of the Azure function to invoke. - - name: appname - required: true - default: - value_in_examples: AZURE_APPNAME - description: The Azure app name. - - name: hostdomain - required: false - default: azurewebsites.net - value_in_examples: - description: The domain where the function resides. - - name: routeprefix - required: false - default: /api - value_in_examples: - description: Route prefix to use. - - name: apikey - required: false - default: - value_in_examples: AZURE_APIKEY - description: The apikey to access the Azure resources. If provided, it will be injected as the `x-functions-key` header. - - name: clientid - required: false - default: - value_in_examples: - description: The clientid to access the Azure resources. If provided, it will be injected as the `x-functions-clientid` header. - - name: https_verify - required: false - default: false - value_in_examples: - description: Set it to true to authenticate the Azure Functions server. - - name: https - required: false - default: true - value_in_examples: - description: Use of HTTPS to connect with the Azure Functions server. - - name: timeout - required: false - default: 600000 - value_in_examples: - description: Timeout in milliseconds before aborting a connection to Azure Functions server. - - name: keepalive - required: false - default: 60000 - value_in_examples: - description: Time in milliseconds for which an idle connection to the Azure Functions server will live before being closed. - - extra: | - Note: If `config.https_verify` is set as `true`, then the server certificate - will be verified according to the CA certificates specified by the - `lua_ssl_trusted_certificate` directive in your Kong configuration. - ---- - -## Demonstration - -To demonstrate the plugin, set up the [Azure Functions "hello world" function](https://docs.microsoft.com/en-us/azure/azure-functions/functions-create-first-azure-function). - -1. In this example we'll consider the following settings/placeholders, insert your own values here: - - ``` - - `` for the Functions appname - - `` for the function name - - `` for the api key - ``` - -2. Test your function to make sure it works before adding it to Kong - - ```bash - curl -i -X GET https://.azurewebsites.net/api/?name=Kong \ - -H "x-functions-key:" - - HTTP/1.1 200 OK - ... - "Hello Kong!" - ``` - -3. Create a Service on Kong - - ```bash - $ curl -i -X POST http://localhost:8001/services/ \ - --data "name=plugin-testing" \ - --data "url=http://dead.end.com" - - HTTP/1.1 201 Created - ... - ``` - -4. Add a Route to the Service on Kong - - ```bash - $ curl -i -X POST http://localhost:8001/services/plugin-testing/routes \ - --data "paths[]=/mytest" - - HTTP/1.1 201 Created - ... - ``` - -5. Apply the Azure-functions plugin - - ```bash - $ curl -i -X POST http://localhost:8001/services/plugin-testing/plugins \ - --data "name=azure-functions" \ - --data "config.appname=" \ - --data "config.functionname=" \ - --data "config.apikey=" - - HTTP/1.1 201 Created - ... - - ``` - -6. Test the Azure Function through Kong (same result as step 2) - - ```bash - curl -i -X GET http://localhost:8000/mytest?name=Kong - - HTTP/1.1 200 OK - ... - "Hello Kong!" - ``` - -In this example we're only passing a query parameter `name` to the Azure -Function. Besides query parameters, also the HTTP method, path parameters, -headers, and body will be passed to the Azure Function if provided. - ----- - -### Limitations - -#### Use a fake upstream_url - -When using the this plugin, the response will be returned by the plugin itself -without proxying the request to any upstream service. This means that whatever -`url` has been set on the [Service](https://docs.konghq.com/latest/admin-api/#service-object) -it will never be used. Although `url` will never be used, it's -currently a mandatory field in Kong's data model, so feel free to set a fake -value (ie, `http://dead.end.com` as per the example above) if you are planning to use this plugin. -In the future, we will provide a more intuitive way to deal with similar use cases. - -#### Response plugins - -There is a known limitation in the system that prevents some response plugins -from being executed. We are planning to remove this limitation in the future. diff --git a/app/_hub/kong-inc/azure-functions/_index.md b/app/_hub/kong-inc/azure-functions/_index.md index c4b2f35d8d92..a0933c31a82c 100644 --- a/app/_hub/kong-inc/azure-functions/_index.md +++ b/app/_hub/kong-inc/azure-functions/_index.md @@ -1,8 +1,6 @@ --- name: Azure Functions publisher: Kong Inc. -version: 1.0.0 -source_url: 'https://github.com/Kong/kong-plugin-azure-functions' desc: Invoke and manage Azure functions from Kong description: | This plugin invokes @@ -14,36 +12,9 @@ categories: - serverless kong_version_compatibility: community_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x + compatible: true enterprise_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x + compatible: true params: name: azure-functions service_id: true @@ -84,14 +55,24 @@ params: value_in_examples: datatype: string encrypted: true - description: 'The apikey to access the Azure resources. If provided, it is injected as the `x-functions-key` header.' + description: | + The apikey to access the Azure resources. If provided, it is injected as the `x-functions-key` header. + + This field is _referenceable_, which means it can be securely stored as a + [secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). - name: clientid required: false default: null value_in_examples: null datatype: string encrypted: true - description: 'The `clientid` to access the Azure resources. If provided, it is injected as the `x-functions-clientid` header.' + description: | + The `clientid` to access the Azure resources. If provided, it is injected as the `x-functions-clientid` header. + + This field is _referenceable_, which means it can be securely stored as a + [secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). - name: https_verify required: false default: false @@ -129,7 +110,7 @@ To demonstrate the plugin, set up the [Azure Functions "hello world" function](h 1. In this example, we'll consider the following placeholder settings. Insert your own values for the placeholders in the code examples: - - `` for the functions appname + - `` for the function's app name - `` for the function name - `` for the api key @@ -213,7 +194,7 @@ HTTP/1.1 200 OK ## Changelog -### 1.0.1 +**{{site.base_gateway}} 2.7.x** * Starting with {{site.base_gateway}} 2.7.0.0, if keyring encryption is enabled, the `config.apikey` and `config.clientid` parameter values will be encrypted. diff --git a/app/_hub/kong-inc/azure-functions/versions.yml b/app/_hub/kong-inc/azure-functions/versions.yml index f56356207baf..da1a90217685 100644 --- a/app/_hub/kong-inc/azure-functions/versions.yml +++ b/app/_hub/kong-inc/azure-functions/versions.yml @@ -1,2 +1,12 @@ -- release: 1.0-x -- release: 0.1-x +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 1.0.1 + 2.7.x: 1.0.1 + 2.6.x: 1.0.1 + 2.5.x: 1.0.1 + 2.4.x: 1.0.0 + 2.3.x: 1.0.0 + 2.2.x: 1.0.0 + 2.1.x: 0.4.2 diff --git a/app/_hub/kong-inc/basic-auth/0.1-x.md b/app/_hub/kong-inc/basic-auth/0.1-x.md deleted file mode 100644 index 51db0b5c8ab6..000000000000 --- a/app/_hub/kong-inc/basic-auth/0.1-x.md +++ /dev/null @@ -1,220 +0,0 @@ ---- -name: Basic Authentication -publisher: Kong Inc. -version: 0.1-x - -desc: Add Basic Authentication to your APIs -description: | - Add Basic Authentication to a Service or a Route (or the deprecated API entity) with username and password protection. The plugin will check for valid credentials in the `Proxy-Authorization` and `Authorization` header (in this order). - -
- Note: The functionality of this plugin as bundled - with versions of Kong prior to 0.14.0 and Kong Gateway prior to 0.34 - differs from what is documented herein. Refer to the - CHANGELOG - for details. -
- -type: plugin -categories: - - authentication - -kong_version_compatibility: - community_edition: - compatible: - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x - - 0.4.x - - 0.3.x - - 0.2.x - enterprise_edition: - compatible: - - 0.34-x - - 0.33-x - - 0.32-x - - 0.31-x - -params: - name: basic-auth - api_id: true - service_id: true - route_id: true - consumer_id: false - config: - - name: hide_credentials - required: false - value_in_examples: true - default: "`false`" - description: | - An optional boolean value telling the plugin to show or hide the credential from the upstream service. If `true`, the plugin will strip the credential from the request (i.e. the `Authorization` header) before proxying it. - - - name: anonymous - required: false - default: - description: | - An optional string (consumer uuid) value to use as an "anonymous" consumer if authentication fails. If empty (default), the request will fail with an authentication failure `4xx`. Please note that this value must refer to the Consumer `id` attribute which is internal to Kong, and **not** its `custom_id`. - extra: | - Once applied, any user with a valid credential can access the Service/API. - To restrict usage to only some of the authenticated users, also add the - [ACL](/plugins/acl/) plugin (not covered here) and create whitelist or - blacklist groups of users. - ---- - -## Usage - -In order to use the plugin, you first need to create a Consumer to associate one or more credentials to. The Consumer represents a developer or an application consuming the upstream service. - -### Create a Consumer - -You need to associate a credential to an existing [Consumer][consumer-object] object. To create a Consumer, you can execute the following request: - -```bash -curl -d "username=user123&custom_id=SOME_CUSTOM_ID" http://kong:8001/consumers/ -``` - -parameter | default | description ---- | --- | --- -`username`
*semi-optional* | | The username of the consumer. Either this field or `custom_id` must be specified. -`custom_id`
*semi-optional* | | A custom identifier used to map the consumer to another database. Either this field or `username` must be specified. - -A [Consumer][consumer-object] can have many credentials. - -If you are also using the [ACL](/plugins/acl/) plugin and whitelists with this -service, you must add the new consumer to a whitelisted group. See -[ACL: Associating Consumers][acl-associating] for details. - -### Create a Credential - -You can provision new username/password credentials by making the following HTTP request: - -```bash -$ curl -X POST http://kong:8001/consumers/{consumer}/basic-auth \ - --data "username=Aladdin" \ - --data "password=OpenSesame" -``` - -`consumer`: The `id` or `username` property of the [Consumer][consumer-object] entity to associate the credentials to. - -form parameter | default | description ---- | --- | --- -`username` | | The username to use in the Basic Authentication -`password` | | The password to use in the Basic Authentication - -### Using the Credential - -The authorization header must be base64 encoded. For example, if the credential -uses `Aladdin` as the username and `OpenSesame` as the password, then the field's -value is the base64-encoding of `Aladdin:OpenSesame`, or `QWxhZGRpbjpPcGVuU2VzYW1l`. - -Then the `Authorization` (or `Proxy-Authorization`) header must appear as: - -``` -Authorization: Basic QWxhZGRpbjpPcGVuU2VzYW1l -``` - -Simply make a request with the header: - -```bash -$ curl http://kong:8000/{path matching a configured Route} \ - -H 'Authorization: Basic QWxhZGRpbjpPcGVuU2VzYW1l' -``` - -### Upstream Headers - -When a client has been authenticated, the plugin will append some headers to the request before proxying it to the upstream service, so that you can identify the Consumer in your code: - -* `X-Consumer-ID`, the ID of the Consumer on Kong -* `X-Consumer-Custom-ID`, the `custom_id` of the Consumer (if set) -* `X-Consumer-Username`, the `username` of the Consumer (if set) -* `X-Credential-Username`, the `username` of the Credential (only if the consumer is not the 'anonymous' consumer) -* `X-Anonymous-Consumer`, will be set to `true` when authentication failed, and the 'anonymous' consumer was set instead. - -You can use this information on your side to implement additional logic. You can use the `X-Consumer-ID` value to query the Kong Admin API and retrieve more information about the Consumer. - -### Paginate through the basic-auth Credentials - -
- Note: This endpoint was introduced in Kong 0.11.2. -
- -You can paginate through the basic-auth Credentials for all Consumers using the -following request: - -```bash -$ curl -X GET http://kong:8001/basic-auths - -{ - "total": 3, - "data": [ - { - "created_at": 1511379926000, - "id": "805520f6-842b-419f-8a12-d1de8a30b29f", - "password": "37b1af03d3860acf40bd9c681aa3ef3f543e49fe", - "username": "baz", - "consumer_id": "5e52251c-54b9-4c10-9605-b9b499aedb47" - }, - { - "created_at": 1511379863000, - "id": "8edfe5c7-3151-4d92-971f-3faa5e6c5d7e", - "password": "451b06c564a06ce60874d0ea2f542fa8ed26317e", - "username": "foo", - "consumer_id": "89a41fef-3b40-4bb0-b5af-33da57a7ffcf" - }, - { - "created_at": 1511379877000, - "id": "f11cb0ea-eacf-4a6b-baea-a0e0b519a990", - "password": "451b06c564a06ce60874d0ea2f542fa8ed26317e", - "username": "foobar", - "consumer_id": "89a41fef-3b40-4bb0-b5af-33da57a7ffcf" - } - ] -} -``` - -You can filter the list using the following query parameters: - -Attributes | Description ----:| --- -`id`
*optional* | A filter on the list based on the basic-auth credential `id` field. -`username`
*optional* | A filter on the list based on the basic-auth credential `username` field. -`consumer_id`
*optional* | A filter on the list based on the basic-auth credential `consumer_id` field. -`size`
*optional, default is __100__* | A limit on the number of objects to be returned. -`offset`
*optional* | A cursor used for pagination. `offset` is an object identifier that defines a place in the list. - -### Retrieve the Consumer associated with a Credential - -
- Note: This endpoint was introduced in Kong 0.11.2. -
- -It is possible to retrieve a [Consumer][consumer-object] associated with a -basic-auth Credential using the following request: - -```bash -curl -X GET http://kong:8001/basic-auths/{username or id}/consumer - -{ - "created_at":1507936639000, - "username":"foo", - "id":"c0d92ba9-8306-482a-b60d-0cfdd2f0e880" -} -``` - -`username or id`: The `id` or `username` property of the basic-auth -Credential for which to get the associated [Consumer][consumer-object]. -Note that the `username` accepted here is **not** the `username` property of a -Consumer. - -[api-object]: /gateway/latest/admin-api/#api-object -[configuration]: /gateway/latest/reference/configuration -[consumer-object]: /gateway/latest/admin-api/#consumer-object -[acl-associating]: /plugins/acl/#associating-consumers diff --git a/app/_hub/kong-inc/basic-auth/2.1-x.md b/app/_hub/kong-inc/basic-auth/2.1-x.md deleted file mode 100644 index 17c56fe3e28d..000000000000 --- a/app/_hub/kong-inc/basic-auth/2.1-x.md +++ /dev/null @@ -1,280 +0,0 @@ ---- -name: Basic Authentication -publisher: Kong Inc. -version: 1.0.0 - -desc: Add Basic Authentication to your Services -description: | - Add Basic Authentication to a Service or a Route with username and password protection. The plugin will check for valid credentials in the `Proxy-Authorization` and `Authorization` header (in this order). - -
- Note: The functionality of this plugin as bundled - with versions of Kong prior to 0.14.0 and Kong Gateway prior to 0.34 - differs from what is documented herein. Refer to the - CHANGELOG - for details. -
- -type: plugin -categories: - - authentication - -kong_version_compatibility: - community_edition: - compatible: - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x - - 0.4.x - - 0.3.x - - 0.2.x - enterprise_edition: - compatible: - - 1.5.x - - 1.3-x - - 0.36-x - - 0.35-x - - 0.34-x - - 0.33-x - - 0.32-x - - 0.31-x - -params: - name: basic-auth - service_id: true - route_id: true - consumer_id: false - protocols: ["http", "https"] - dbless_compatible: partially - dbless_explanation: | - Consumers and Credentials can be created with declarative configuration. - - Admin API endpoints which do POST, PUT, PATCH or DELETE on Credentials are not available on DB-less mode. - config: - - name: hide_credentials - required: false - value_in_examples: true - default: "`false`" - description: | - An optional boolean value telling the plugin to show or hide the credential from the upstream service. If `true`, the plugin will strip the credential from the request (i.e. the `Authorization` header) before proxying it. - - - name: anonymous - required: false - default: - description: | - An optional string (consumer uuid) value to use as an "anonymous" consumer if authentication fails. If empty (default), the request will fail with an authentication failure `4xx`. Please note that this value must refer to the Consumer `id` attribute which is internal to Kong, and **not** its `custom_id`. - extra: | - Once applied, any user with a valid credential can access the Service. - To restrict usage to only some of the authenticated users, also add the - [ACL](/plugins/acl/) plugin (not covered here) and create whitelist or - blacklist groups of users. - ---- - -## Usage - -In order to use the plugin, you first need to create a Consumer to associate one or more credentials to. The Consumer represents a developer or an application consuming the upstream service. - -### Create a Consumer - -You need to associate a credential to an existing [Consumer][consumer-object] object. -A Consumer can have many credentials. - -{% navtabs %} -{% navtab With a Database %} -To create a Consumer, you can execute the following request: - -```bash -curl -d "username=user123&custom_id=SOME_CUSTOM_ID" http://kong:8001/consumers/ -``` -{% endnavtab %} -{% navtab Without a Database %} -Your declarative configuration file will need to have one or more Consumers. You can create them -on the `consumers:` yaml section: - -``` yaml -consumers: -- username: user123 - custom_id: SOME_CUSTOM_ID -``` -{% endnavtab %} -{% endnavtabs %} - -In both cases, the parameters are as described below: - -parameter | description ---- | --- -`username`
*semi-optional* | The username of the consumer. Either this field or `custom_id` must be specified. -`custom_id`
*semi-optional* | A custom identifier used to map the consumer to another database. Either this field or `username` must be specified. - -If you are also using the [ACL](/plugins/acl/) plugin and whitelists with this -service, you must add the new consumer to a whitelisted group. See -[ACL: Associating Consumers][acl-associating] for details. - -### Create a Credential - -{% navtabs %} -{% navtab With a Database %} -You can provision new username/password credentials by making the following HTTP request: - -```bash -$ curl -X POST http://kong:8001/consumers/{consumer}/basic-auth \ - --data "username=Aladdin" \ - --data "password=OpenSesame" -``` -{% endnavtab %} -{% navtab Without a Database %} - -You can add credentials on your declarative config file on the `basicauth_credentials` yaml entry: - -``` yaml -basicauth_credentials: -- consumer: {consumer} - username: Aladdin - password: OpenSesame -``` -{% endnavtab %} -{% endnavtabs %} - -In both cases, the fields / parameters work as described below: - -field/parameter | description ---- | --- -`{consumer}` | The `id` or `username` property of the [Consumer][consumer-object] entity to associate the credentials to. -`username` | The username to use in the Basic Authentication -`password` | The password to use in the Basic Authentication - - -### Using the Credential - -The authorization header must be base64 encoded. For example, if the credential -uses `Aladdin` as the username and `OpenSesame` as the password, then the field's -value is the base64-encoding of `Aladdin:OpenSesame`, or `QWxhZGRpbjpPcGVuU2VzYW1l`. - -Then the `Authorization` (or `Proxy-Authorization`) header must appear as: - -``` -Authorization: Basic QWxhZGRpbjpPcGVuU2VzYW1l -``` - -Simply make a request with the header: - -```bash -$ curl http://kong:8000/{path matching a configured Route} \ - -H 'Authorization: Basic QWxhZGRpbjpPcGVuU2VzYW1l' -``` - -### Upstream Headers - -When a client has been authenticated, the plugin will append some headers to the request before proxying it to the upstream service, so that you can identify the Consumer in your code: - -* `X-Consumer-ID`, the ID of the Consumer on Kong -* `X-Consumer-Custom-ID`, the `custom_id` of the Consumer (if set) -* `X-Consumer-Username`, the `username` of the Consumer (if set) -* `X-Credential-Username`, the `username` of the Credential (only if the consumer is not the 'anonymous' consumer) -* `X-Anonymous-Consumer`, will be set to `true` when authentication failed, and the 'anonymous' consumer was set instead. - -You can use this information on your side to implement additional logic. You can use the `X-Consumer-ID` value to query the Kong Admin API and retrieve more information about the Consumer. - -### Paginate through the basic-auth Credentials - -
- Note: This endpoint was introduced in Kong 0.11.2. -
- -You can paginate through the basic-auth Credentials for all Consumers using the -following request: - -```bash -$ curl -X GET http://kong:8001/basic-auths - -{ - "total": 3, - "data": [ - { - "created_at": 1511379926000, - "id": "805520f6-842b-419f-8a12-d1de8a30b29f", - "password": "37b1af03d3860acf40bd9c681aa3ef3f543e49fe", - "username": "baz", - "consumer": { "id": "5e52251c-54b9-4c10-9605-b9b499aedb47" } - }, - { - "created_at": 1511379863000, - "id": "8edfe5c7-3151-4d92-971f-3faa5e6c5d7e", - "password": "451b06c564a06ce60874d0ea2f542fa8ed26317e", - "username": "foo", - "consumer": { "id": "89a41fef-3b40-4bb0-b5af-33da57a7ffcf" } - }, - { - "created_at": 1511379877000, - "id": "f11cb0ea-eacf-4a6b-baea-a0e0b519a990", - "password": "451b06c564a06ce60874d0ea2f542fa8ed26317e", - "username": "foobar", - "consumer": { "id": "89a41fef-3b40-4bb0-b5af-33da57a7ffcf" } - } - ] -} -``` - -You can filter the list by consumer by using this other path: - -```bash -$ curl -X GET http://kong:8001/consumers/{username or id}/basic-auth - -{ - "total": 1, - "data": [ - { - "created_at": 1511379863000, - "id": "8edfe5c7-3151-4d92-971f-3faa5e6c5d7e", - "password": "451b06c564a06ce60874d0ea2f542fa8ed26317e", - "username": "foo", - "consumer": { "id": "89a41fef-3b40-4bb0-b5af-33da57a7ffcf" } - } - ] -} -``` - -`username or id`: The username or id of the consumer whose credentials need to be listed - -### Retrieve the Consumer associated with a Credential - -
- Note: This endpoint was introduced in Kong 0.11.2. -
- -It is possible to retrieve a [Consumer][consumer-object] associated with a -basic-auth Credential using the following request: - -```bash -curl -X GET http://kong:8001/basic-auths/{username or id}/consumer - -{ - "created_at":1507936639000, - "username":"foo", - "id":"c0d92ba9-8306-482a-b60d-0cfdd2f0e880" -} -``` - -`username or id`: The `id` or `username` property of the basic-auth -Credential for which to get the associated [Consumer][consumer-object]. -Note that the `username` accepted here is **not** the `username` property of a -Consumer. - -[configuration]: /gateway/latest/reference/configuration -[consumer-object]: /gateway/latest/admin-api/#consumer-object -[acl-associating]: /plugins/acl/#associating-consumers diff --git a/app/_hub/kong-inc/basic-auth/_index.md b/app/_hub/kong-inc/basic-auth/_index.md index e9c12d7c7b54..e8b6cab10a8c 100644 --- a/app/_hub/kong-inc/basic-auth/_index.md +++ b/app/_hub/kong-inc/basic-auth/_index.md @@ -1,7 +1,6 @@ --- name: Basic Authentication publisher: Kong Inc. -version: 2.2.0 desc: Add Basic Authentication to your Services description: | Add Basic Authentication to a Service or a Route with username and password protection. The plugin @@ -11,25 +10,9 @@ categories: - authentication kong_version_compatibility: community_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x + compatible: true enterprise_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x + compatible: true params: name: basic-auth service_id: true @@ -168,18 +151,7 @@ grpcurl -H 'Authorization: Basic QWxhZGRpbjpPcGVuU2VzYW1l' ... ### Upstream Headers -When a client has been authenticated, the plugin appends some headers to the request before proxying it to the upstream service, so that you can identify the Consumer in your code: - -* `X-Consumer-ID`: the ID of the Consumer in Kong Gateway -* `X-Consumer-Custom-ID`: the `custom_id` of the Consumer (if set) -* `X-Consumer-Username`: the `username` of the Consumer (if set) -* `X-Credential-Identifier`: the identifier of the Credential (only if the consumer is not the 'anonymous' consumer) -* `X-Anonymous-Consumer`: set to `true` if authentication fails, and the 'anonymous' consumer is set instead - -You can use this information on your side to implement additional logic. Use the `X-Consumer-ID` value to query the Kong Admin API and retrieve more information about the Consumer. - -{:.important} -> **Important:** `X-Credential-Username` was deprecated in favor of `X-Credential-Identifier` in Kong 2.1. +{% include_cached /md/plugins-hub/upstream-headers.md %} ### Paginate through the basic-auth Credentials @@ -280,16 +252,17 @@ Credential for which to get the associated [Consumer][consumer-object]. Note that the `username` accepted here is **not** the `username` property of a Consumer. +[configuration]: /gateway/latest/reference/configuration +[consumer-object]: /gateway/latest/admin-api/#consumer-object +[acl-associating]: /plugins/acl/#associating-consumers + --- ## Changelog -### 2.2.0 +**{{site.base_gateway}} 3.0.x** +* The deprecated `X-Credential-Username` header has been removed. +**{{site.base_gateway}} 2.7.x** * Starting with {{site.base_gateway}} 2.7.0.0, if keyring encryption is enabled and you are using basic authentication, the `basicauth_credentials.password` field will be encrypted. - - -[configuration]: /gateway/latest/reference/configuration -[consumer-object]: /gateway/latest/admin-api/#consumer-object -[acl-associating]: /plugins/acl/#associating-consumers diff --git a/app/_hub/kong-inc/basic-auth/versions.yml b/app/_hub/kong-inc/basic-auth/versions.yml index 14405d124ae7..66a1be48947c 100644 --- a/app/_hub/kong-inc/basic-auth/versions.yml +++ b/app/_hub/kong-inc/basic-auth/versions.yml @@ -1,3 +1,12 @@ -- release: 2.2-x -- release: 2.1-x -- release: 0.1-x +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 2.2.0 + 2.7.x: 2.2.0 + 2.6.x: 2.2.0 + 2.5.x: 2.2.0 + 2.4.x: 2.2.0 + 2.3.x: 2.2.0 + 2.2.x: 2.2.0 + 2.1.x: 2.2.0 diff --git a/app/_hub/kong-inc/bot-detection/0.1-x.md b/app/_hub/kong-inc/bot-detection/0.1-x.md deleted file mode 100644 index 5d5ff2257ff1..000000000000 --- a/app/_hub/kong-inc/bot-detection/0.1-x.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -name: Bot Detection -publisher: Kong Inc. -version: 0.1-x - -desc: Detect and block bots or custom clients -description: | - Protects a Service or a Route (or the deprecated API entity) from most common bots and has the capability of whitelisting and blacklisting custom clients. - -type: plugin -categories: - - security - -kong_version_compatibility: - community_edition: - compatible: - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - enterprise_edition: - compatible: - - 0.34-x - - 0.33-x - - 0.32-x - - 0.31-x - -params: - name: bot-detection - api_id: true - service_id: true - route_id: true - consumer_id: false - config: - - name: whitelist - required: false - default: - description: | - A comma separated array of regular expressions that should be whitelisted. The regular expressions will be checked against the `User-Agent` header. - - name: blacklist - required: false - default: - description: | - A comma separated array of regular expressions that should be blacklisted. The regular expressions will be checked against the `User-Agent` header. - ---- - -## Default rules - -The plugin already includes a basic list of rules that will be checked on every request. You can find this list on GitHub at [https://github.com/Kong/kong/blob/master/kong/plugins/bot-detection/rules.lua](https://github.com/Kong/kong/blob/master/kong/plugins/bot-detection/rules.lua). - -[api-object]: /gateway/latest/admin-api/#api-object -[configuration]: /gateway/latest/reference/configuration -[consumer-object]: /gateway/latest/admin-api/#consumer-object - diff --git a/app/_hub/kong-inc/bot-detection/_index.md b/app/_hub/kong-inc/bot-detection/_index.md index 6cff28ae8485..24fa47bdd619 100644 --- a/app/_hub/kong-inc/bot-detection/_index.md +++ b/app/_hub/kong-inc/bot-detection/_index.md @@ -1,7 +1,6 @@ --- name: Bot Detection publisher: Kong Inc. -version: 1.0.0 desc: Detect and block bots or custom clients description: | Protects a Service or a Route from most common bots and has the capability of allowing and denying custom clients. @@ -10,41 +9,11 @@ categories: - security kong_version_compatibility: community_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x + compatible: true + enterprise_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x + compatible: true + params: name: bot-detection service_id: true @@ -55,25 +24,62 @@ params: - https dbless_compatible: 'yes' config: + + # deprecated parameters + - name: whitelist + required: false + default: + description: | + A comma separated array of regular expressions that should be whitelisted. The regular expressions will be checked against the `User-Agent` header. + maximum_version: "2.0.x" + - name: blacklist + required: false + default: + description: | + A comma separated array of regular expressions that should be blacklisted. The regular expressions will be checked against the `User-Agent` header. + maximum_version: "2.0.x" + +# current parameters - name: allow required: false default: null datatype: array of string elements description: | An array of regular expressions that should be allowed. The regular expressions will be checked against the `User-Agent` header. + minimum_version: "2.1.x" - name: deny required: false default: null datatype: array of string elements description: | An array of regular expressions that should be denied. The regular expressions will be checked against the `User-Agent` header. + minimum_version: "2.1.x" + --- ## Default rules +{% if_plugin_version gte:2.1.x and lte:2.8.x %} + +{:.note} +> **Note**: We have deprecated the usage of `whitelist` and `blacklist` in favor of `allow` and `deny`. This change may require Admin API requests to be updated. + +{% endif_plugin_version %} + The plugin already includes a basic list of rules that will be checked on every request. You can find this list on GitHub at [https://github.com/Kong/kong/blob/master/kong/plugins/bot-detection/rules.lua](https://github.com/Kong/kong/blob/master/kong/plugins/bot-detection/rules.lua). [api-object]: /gateway/latest/admin-api/#api-object [configuration]: /gateway/latest/reference/configuration [consumer-object]: /gateway/latest/admin-api/#consumer-object +--- + +## Changelog + +**{{site.base_gateway}} 3.0.x** +- Removed the deprecated `whitelist` and `blacklist` parameters. +They are no longer supported. + +**{{site.base_gateway}} 2.1.x** + +- Use `allow` and `deny` instead of `whitelist` and `blacklist` diff --git a/app/_hub/kong-inc/bot-detection/versions.yml b/app/_hub/kong-inc/bot-detection/versions.yml index f56356207baf..499736e2925a 100644 --- a/app/_hub/kong-inc/bot-detection/versions.yml +++ b/app/_hub/kong-inc/bot-detection/versions.yml @@ -1,2 +1,12 @@ -- release: 1.0-x -- release: 0.1-x +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 2.0.0 + 2.7.x: 2.0.0 + 2.6.x: 2.0.0 + 2.5.x: 2.0.0 + 2.4.x: 2.0.0 + 2.3.x: 2.0.0 + 2.2.x: 2.0.0 + 2.1.x: 2.0.0 diff --git a/app/_hub/kong-inc/canary/0.3.x.md b/app/_hub/kong-inc/canary/_0.3.x.md similarity index 100% rename from app/_hub/kong-inc/canary/0.3.x.md rename to app/_hub/kong-inc/canary/_0.3.x.md diff --git a/app/_hub/kong-inc/canary/0.4.x.md b/app/_hub/kong-inc/canary/_0.4.x.md similarity index 100% rename from app/_hub/kong-inc/canary/0.4.x.md rename to app/_hub/kong-inc/canary/_0.4.x.md diff --git a/app/_hub/kong-inc/canary/0.5.x.md b/app/_hub/kong-inc/canary/_0.5.x.md similarity index 100% rename from app/_hub/kong-inc/canary/0.5.x.md rename to app/_hub/kong-inc/canary/_0.5.x.md diff --git a/app/_hub/kong-inc/canary/versions.yml b/app/_hub/kong-inc/canary/versions.yml index c67b66aeaf48..fa0827722a8d 100644 --- a/app/_hub/kong-inc/canary/versions.yml +++ b/app/_hub/kong-inc/canary/versions.yml @@ -1,6 +1,20 @@ -- release: 0.6.x -- release: 0.5.x -- release: 0.4.x -- release: 0.3.x -- release: 0.2.x -- release: 0.1.x +strategy: gateway +delegate_releases: true +sources: + 2.7.x: _0.5.x + 2.6.x: _0.4.x + 2.5.x: _0.4.x + 2.4.x: _0.4.x + 2.3.x: _0.3.x + 2.2.x: _0.3.x + 2.1.x: _0.3.x + +overrides: + 2.8.x: 0.6.0 + 2.7.x: 0.5.0 + 2.6.x: 0.5.0 + 2.5.x: 0.4.4 + 2.4.x: 0.4.4 + 2.3.x: 0.3.0 + 2.2.x: 0.3.0 + 2.1.x: 0.3.0 diff --git a/app/_hub/kong-inc/correlation-id/1.0.x.md b/app/_hub/kong-inc/correlation-id/_1.0.x.md similarity index 100% rename from app/_hub/kong-inc/correlation-id/1.0.x.md rename to app/_hub/kong-inc/correlation-id/_1.0.x.md diff --git a/app/_hub/kong-inc/correlation-id/versions.yml b/app/_hub/kong-inc/correlation-id/versions.yml index 8b8c4b784126..f10acb0de02f 100644 --- a/app/_hub/kong-inc/correlation-id/versions.yml +++ b/app/_hub/kong-inc/correlation-id/versions.yml @@ -1,3 +1,14 @@ -- release: 2.0.x -- release: 1.0.x -- release: 0.1.x +strategy: gateway +delegate_releases: true +sources: + 2.1.x: _1.0.x + +overrides: + 2.8.x: 2.0.2 + 2.7.x: 2.0.2 + 2.6.x: 2.0.2 + 2.5.x: 0.4.4 + 2.4.x: 2.0.2 + 2.3.x: 2.0.2 + 2.2.x: 2.0.1 + 2.1.x: 2.0.1 diff --git a/app/_hub/kong-inc/cors/0.1-x.md b/app/_hub/kong-inc/cors/0.1-x.md deleted file mode 100644 index 8a91536df7a6..000000000000 --- a/app/_hub/kong-inc/cors/0.1-x.md +++ /dev/null @@ -1,115 +0,0 @@ ---- -name: CORS -publisher: Kong Inc. -version: 0.1-x - -desc: Allow developers to make requests from the browser -description: | - Easily add __Cross-origin resource sharing *(CORS)*__ to a Service, a Route (or the deprecated API entity) by enabling - this plugin. - -
- Note: The functionality of this plugin as bundled - with versions of Kong prior to 0.10.3 differs from what is documented herein. - Refer to the - CHANGELOG - for details. -
- -type: plugin -categories: - - security - -kong_version_compatibility: - community_edition: - compatible: - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x - - 0.4.x - - 0.3.x - - 0.2.x - enterprise_edition: - compatible: - - 0.34-x - - 0.33-x - - 0.32-x - - 0.31-x - -params: - name: cors - api_id: true - service_id: true - route_id: true - consumer_id: false - config: - - name: origins - required: false - default: - value_in_examples: http://mockbin.com - description: | - A comma-separated list of allowed domains for the `Access-Control-Allow-Origin` header. If you wish to allow all origins, add `*` as a single value to this configuration field. The accepted values can either be flat strings or PCRE regexes. **NOTE**: Prior to Kong 0.10.x, this parameter was `config.origin` (note the change in trailing `s`), and only accepted a single value, or the `*` special value. - - name: methods - required: false - default: "`GET, HEAD, PUT, PATCH, POST`" - value_in_examples: GET, POST - description: - Value for the `Access-Control-Allow-Methods` header, expects a comma delimited string (e.g. `GET,POST`). - - name: headers - required: false - default: "Value of the `Access-Control-Request-Headers` request header" - value_in_examples: Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Auth-Token - description: | - Value for the `Access-Control-Allow-Headers` header, expects a comma delimited string (e.g. `Origin, Authorization`). - - name: exposed_headers - required: false - default: - value_in_examples: X-Auth-Token - description: | - Value for the `Access-Control-Expose-Headers` header, expects a comma delimited string (e.g. `Origin, Authorization`). If not specified, no custom headers are exposed. - - name: credentials - required: false - default: "`false`" - value_in_examples: true - description: | - Flag to determine whether the `Access-Control-Allow-Credentials` header should be sent with `true` as the value. - - name: max_age - required: false - default: - value_in_examples: 3600 - description: | - Indicated how long the results of the preflight request can be cached, in `seconds`. - - name: preflight_continue - required: false - default: "`false`" - description: A boolean value that instructs the plugin to proxy the `OPTIONS` preflight request to the upstream service. - ---- - -## Known issues - -Below is a list of known issues or limitations for this plugin. - -### CORS Limitations - -If the client is a browser, there is a known issue with this plugin caused by a -limitation of the CORS specification that doesn't allow to specify a custom -`Host` header in a preflight `OPTIONS` request. - -Because of this limitation, this plugin will only work for APIs that have been -configured with a `uris` setting, and it will not work for APIs that -are being resolved using a custom DNS (the `hosts` property). - -To learn how to configure `uris` for an API, please read the [Proxy -Reference][proxy-reference]. - -[api-object]: /gateway/latest/admin-api/#api-object -[configuration]: /gateway/latest/reference/configuration -[proxy-reference]: /gateway/latest/reference/proxy#request-uri diff --git a/app/_hub/kong-inc/cors/_index.md b/app/_hub/kong-inc/cors/_index.md index 6c651d3d8ea4..acead88736f8 100644 --- a/app/_hub/kong-inc/cors/_index.md +++ b/app/_hub/kong-inc/cors/_index.md @@ -1,7 +1,6 @@ --- name: CORS publisher: Kong Inc. -version: 1.0.0 desc: Allow developers to make requests from the browser description: | Easily add __cross-origin resource sharing *(CORS)*__ to a Service and a Route @@ -11,48 +10,9 @@ categories: - security kong_version_compatibility: community_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x - - 0.4.x - - 0.3.x - - 0.2.x + compatible: true enterprise_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x + compatible: true params: name: cors service_id: true diff --git a/app/_hub/kong-inc/cors/versions.yml b/app/_hub/kong-inc/cors/versions.yml index f56356207baf..03ec3c17cc75 100644 --- a/app/_hub/kong-inc/cors/versions.yml +++ b/app/_hub/kong-inc/cors/versions.yml @@ -1,2 +1,12 @@ -- release: 1.0-x -- release: 0.1-x +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 2.1.1 + 2.7.x: 2.0.0 + 2.6.x: 2.0.0 + 2.5.x: 2.0.0 + 2.4.x: 2.0.0 + 2.3.x: 2.0.0 + 2.2.x: 2.0.0 + 2.1.x: 2.0.0 diff --git a/app/_hub/kong-inc/datadog/3.0.x.md b/app/_hub/kong-inc/datadog/_3.0.x.md similarity index 100% rename from app/_hub/kong-inc/datadog/3.0.x.md rename to app/_hub/kong-inc/datadog/_3.0.x.md diff --git a/app/_hub/kong-inc/datadog/3.1.x.md b/app/_hub/kong-inc/datadog/_3.1.x.md similarity index 100% rename from app/_hub/kong-inc/datadog/3.1.x.md rename to app/_hub/kong-inc/datadog/_3.1.x.md diff --git a/app/_hub/kong-inc/datadog/versions.yml b/app/_hub/kong-inc/datadog/versions.yml index 5a08650ca4b6..b4a4731fc5f1 100644 --- a/app/_hub/kong-inc/datadog/versions.yml +++ b/app/_hub/kong-inc/datadog/versions.yml @@ -1,4 +1,19 @@ -- release: 3.1.x -- release: 3.0.x -- release: 1.0-x -- release: 0.1-x +strategy: gateway +delegate_releases: true +sources: + 2.6.x: _3.1.x + 2.5.x: _3.1.x + 2.4.x: _3.0.x + 2.3.x: _3.0.x + 2.2.x: _3.0.x + 2.1.x: _3.0.x + +overrides: + 2.8.x: 3.1.1 + 2.7.x: 3.1.0 + 2.6.x: 3.0.1 + 2.5.x: 3.0.1 + 2.4.x: 3.0.1 + 2.3.x: 3.0.1 + 2.2.x: 3.0.1 + 2.1.x: 3.0.1 diff --git a/app/_hub/kong-inc/degraphql/_index.md b/app/_hub/kong-inc/degraphql/_index.md index 6d41f81d9cea..c2f212ffe902 100644 --- a/app/_hub/kong-inc/degraphql/_index.md +++ b/app/_hub/kong-inc/degraphql/_index.md @@ -1,7 +1,6 @@ --- name: DeGraphQL publisher: Kong Inc. -version: 0.1.0 desc: Transform a GraphQL upstream into a REST API description: | This plugin transforms a GraphQL upstream into a traditional endpoint by mapping URIs into GraphQL queries. @@ -12,128 +11,136 @@ categories: - transformations kong_version_compatibility: enterprise_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x + compatible: true params: name: degraphql service_id: true dbless_compatible: 'yes' - config: null + config: + - name: graphql_server_path + required: true + default: "/graphql" + datatype: string + description: The path to the GraphQL server. + minimum_version: "3.0.x" --- ## Usage -DeGraphQL needs a graphql endpoint to query. As an example, we are going to -build a REST API around https://api.github.com GraphQL service. For that reason -examples are going to include the header `Authorization: Bearer some-token`. +DeGraphQL needs a GraphQL endpoint to query. As an example, we are going to +build a REST API around the `https://api.github.com` GraphQL service. For that +reason, the following examples include the header `Authorization: Bearer some-token`. -Note this plugin differs from other plugins as far as configuration goes. It -needs to be activated on a service that points to a GraphQL endpoint -(sans `/graphql`). +This plugin must be activated on a service that points to a GraphQL endpoint. -### 1. Create a Service and a Route in Kong: +### Create a Service and a Route - ```bash - $ curl -X POST http://localhost:8001/services \ - --data name="github" \ - --data url="https://api.github.com" - $ curl -X POST http://localhost:8001/services/github/routes \ - --data paths="/api" - ``` +Create a Service and Route in {{site.base_gateway}}: -### 2. Configure the Plugin on the Service +```bash +curl -X POST http://localhost:8001/services \ + --data name="github" \ + --data url="https://api.github.com" -The plugin takes over the service. From this point on, the service represents -our REST api and not the graphql endpoint itself. It will return a 404 Not Found -if no DeGraphQL routes have been configured. +curl -X POST http://localhost:8001/services/github/routes \ + --data paths="/api" +``` - ```bash - $ curl -X POST http://localhost:8001/services/github/plugins \ - --data name="degraphql" - ``` +### Configure the plugin on the Service -### 3. Configure DeGraphQL Routes on the Service +Set up the DeGraphQL plugin: -Once the Plugin is activated on a Service, we can add our own routes to build -our service, by defining URIs and associating them to GraphQL queries. +```bash +curl -X POST http://localhost:8001/services/github/plugins \ + --data name="degraphql" +``` - ```bash - $ curl -X POST http://localhost:8001/services/github/degraphql/routes \ - --data uri="/me" \ - --data query="query { viewer { login } }" +Enabling the plugin disables regular service function. Instead, the +plugin now builds the path and GraphQL query to hit the GraphQL service +with. - $ curl http://localhost:8000/api/me \ - --header "Authorization: Bearer some-token" - { - "data": { - "viewer": { - "login": "you" - } - } - } - ``` - -GraphQL Query Variables can be defined on URIs: - - ```bash - $ curl -X POST http://localhost:8001/services/github/degraphql/routes \ - --data uri='/:owner/:name' \ - --data query='query ($owner:String! $name:String!){ - repository(owner:$owner, name:$name) { - name - forkCount - description - } - }' - - $ curl http://localhost:8000/api/kong/kong \ - --header "Authorization: Bearer some-token" - { +From this point on, the Service represents +your REST API and not the GraphQL endpoint itself. It will return a `404 Not Found` +status code if no DeGraphQL routes have been configured. + +### Configure DeGraphQL Routes on the Service + +Once the plugin is activated on a Service, you can add your own routes +by defining URIs and associating them to GraphQL queries. + +{:.note} +> Don't include the GraphQL server path prefix in the URI parameter +(`/graphql` by default). + +```bash +curl -X POST http://localhost:8001/services/github/degraphql/routes \ + --data uri="/me" \ + --data query="query { viewer { login } }" + +curl http://localhost:8000/api/me \ + --header "Authorization: Bearer some-token" +{ "data": { - "repository": { - "description": "🦍 The Cloud-Native API Gateway ", - "forkCount": 2997, - "name": "kong" + "viewer": { + "login": "you" } } +} +``` + + +GraphQL query variables can be defined on URIs: + +```bash +curl -X POST http://localhost:8001/services/github/degraphql/routes \ + --data uri='/:owner/:name' \ + --data query='query ($owner:String! $name:String!){ + repository(owner:$owner, name:$name) { + name + forkCount + description + } + }' + +curl http://localhost:8000/api/kong/kong \ + --header "Authorization: Bearer some-token" +{ + "data": { + "repository": { + "description": "🦍 The Cloud-Native API Gateway ", + "forkCount": 2997, + "name": "kong" + } } - ``` - -The same Variables can also be provided as GET arguments: - - ```bash - $ curl -X POST http://localhost:8001/services/github/degraphql/routes \ - --data uri='/repo' \ - --data query='query ($owner:String! $name:String!){ - repository(owner:$owner, name:$name) { - name - forkCount - description - } - }' - - $ curl "http://localhost:8000/api/repo?owner=kong&name=kuma" \ - --header "Authorization: Bearer some-token" - { - "data": { - "repository": { - "description": "🐻 The Universal Service Mesh", - "forkCount": 48, - "name": "kuma" - } - } +} +``` + +The same variables can also be provided as `GET` arguments: + +```bash +curl -X POST http://localhost:8001/services/github/degraphql/routes \ + --data uri='/repo' \ + --data query='query ($owner:String! $name:String!){ + repository(owner:$owner, name:$name) { + name + forkCount + description + } + }' + +curl "http://localhost:8000/api/repo?owner=kong&name=kuma" \ + --header "Authorization: Bearer some-token" +{ + "data": { + "repository": { + "description": "🐻 The Universal Service Mesh", + "forkCount": 48, + "name": "kuma" + } } - ``` +} +``` -### Available endpoints +## Available endpoints **List defined DeGraphQL Routes for a service** @@ -143,21 +150,28 @@ The same Variables can also be provided as GET arguments:
/services/:service_name/degraphql/routes
-| Attributes | Description +| Attribute | Description | -------------- | ------- -|`uri` | path to map to a GraphQL query -|`query` | GraphQL query to map to uri +|`uri` | Path to map to a GraphQL query. +|`query` | GraphQL query to map to the URI. **Edit a DeGraphQL Route for a Service**
/services/:service_name/degraphql/routes/:id
-| Attributes | Description +| Attribute | Description | -------------- | ------- -|`uri` | path to map to a GraphQL query -|`query` | GraphQL query to map to uri +|`uri` | Path to map to a GraphQL query. +|`query` | GraphQL query to map to the URI. **Delete a DeGraphQL Route for a Service**
/services/:service_name/degraphql/routes/:id
+ +--- +## Changelog + +**{{site.base_gateway}} 3.0.x** + +* Added the `graphql_server_path` configuration parameter. diff --git a/app/_hub/kong-inc/degraphql/versions.yml b/app/_hub/kong-inc/degraphql/versions.yml index 57f7f5264e38..6f1e991008f1 100644 --- a/app/_hub/kong-inc/degraphql/versions.yml +++ b/app/_hub/kong-inc/degraphql/versions.yml @@ -1 +1,13 @@ -- release: 1.3-x +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 0.1.2 + 2.7.x: 0.1.2 + 2.6.x: 0.1.2 + 2.5.x: 0.1.2 + 2.4.x: 0.1.2 + 2.3.x: 0.1.1 + 2.2.x: 0.1.1 + 2.1.x: 0.1.1 + 2.0.x: 0.1.1 diff --git a/app/_hub/kong-inc/ee-openid-connect-rp/_index.md b/app/_hub/kong-inc/ee-openid-connect-rp/_index.md deleted file mode 100644 index d5b9572889f2..000000000000 --- a/app/_hub/kong-inc/ee-openid-connect-rp/_index.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -name: OpenID Connect -publisher: Kong Inc. - -redirect_to: /plugins/ee-openid-connect ---- diff --git a/app/_hub/kong-inc/exit-transformer/1.3-x.md b/app/_hub/kong-inc/exit-transformer/1.3-x.md deleted file mode 100644 index 73a8e2ea6b5d..000000000000 --- a/app/_hub/kong-inc/exit-transformer/1.3-x.md +++ /dev/null @@ -1,183 +0,0 @@ ---- -name: Exit Transformer -publisher: Kong Inc. -version: 1.3-x - -desc: Customize Kong exit responses sent downstream -description: | - Transform and customize Kong response exit messages using Lua functions. - The capabilities range from changing messages, status codes, and headers, to completely transforming - the structure of Kong responses. - -type: plugin -enterprise: true -categories: - - transformations - -kong_version_compatibility: - enterprise_edition: - compatible: - - 1.3-x - -params: - name: exit-transformer - service_id: true - route_id: true - consumer_id: false - yaml_examples: false - konnect_examples: false - protocols: ["http", "https"] - config: - - name: functions - required: true - value_in_examples: "[]" - description: Array of functions used to transform any Kong proxy exit response. - ---- - -## Function syntax - -The exit transformer expects a configuration function to be Lua code that returns -a function accepting three arguments: status, body, and headers. - -Any Kong exit call exposed on the proxy side gets reduced through these -functions. - -``` -Kong -> f(status, body, headers) -> ... -> exit(status, body, headers) -``` - - -### Examples - -* Identity function: does not transform the exit responses - -```lua -return function(status, body, headers) - return status, body, headers -end -``` - -* Always return a 200 status code, bundling the status within the message - -```lua -return function(status, body, headers) - -- identity - if not body or not body.message then - return status, body, headers - end - - body.status = status - - return 200, body, headers -end -``` - -* Customize particular Kong messages - -```lua -local responses = { - ["No API key found in request"] = { - message = "Please provide an API key", - status = 418, - headers = { ["x-some-header"] = "some value" }, - }, - ["Invalid authentication credentials"] = { - message = "Invalid API key", - }, - -- ... -} - -return function(status, body, headers) - if not body or not body.message then - return status, body, headers - end - - local response = responses[body.message] - - body.message = response.message or body.message - status = response.status or status - headers = response.headers or headers - - return status, body, headers -end -``` - -## Demonstration - -1. Create a Service and a Route in Kong: - - ```bash - $ http :8001/services name=example.com host=mockbin.org - $ http -f :8001/services/example.com/routes hosts=example.com - ``` - -2. Create a file named `transform.lua` with the transformation code. The - following example adds a header, appends "arr!" to any message, and adds - an `error` and `status` field on the response. - - ```lua - -- transform.lua - return function(status, body, headers) - if not body or not body.message then - return status, body, headers - end - - headers = { ["x-some-header"] = "some value" } - local new_body = { - error = true, - status = status, - message = body.message .. ", arr!", - } - - return status, body, headers - end - ``` - -3. Configure the `exit-transformer` plugin with `transform.lua` - - ```bash - $ http -f :8001/services/example.com/plugins \ - name=exit-transformer \ - config.functions=@transform.lua - ``` - -4. (example) Add key-auth plugin to force generation of an exit response - - ```bash - $ http :8001/services/example.com/plugins name=key-auth - ``` - -5. Attempt a request to the Service to get the custom error - - ```bash - $ http :8000 Host:example.com - HTTP/1.1 200 OK - ... - X-Some-Header: some value - - { - "error": true, - "status": 401, - "kong_message": "No API key found in request, arr!" - } - ``` - -6. Note the plugin can also be applied globally - - ```bash - $ http :8001/plugins \ - name=exit-transformer \ - config.functions=@transform.lua - - $ http :8000 Host:non-existent.com - HTTP/1.1 200 OK - ... - X-Some-Header: some value - - { - "error": true, - "status": 404, - "kong_message": "no Route matched with those values, arr!" - } - ``` diff --git a/app/_hub/kong-inc/exit-transformer/_index.md b/app/_hub/kong-inc/exit-transformer/_index.md index 395f867a10b0..05a5d8b832e5 100644 --- a/app/_hub/kong-inc/exit-transformer/_index.md +++ b/app/_hub/kong-inc/exit-transformer/_index.md @@ -1,7 +1,6 @@ --- name: Exit Transformer publisher: Kong Inc. -version: 1.5.x desc: Customize Kong exit responses sent downstream description: | Transform and customize Kong response exit messages using Lua functions. @@ -14,17 +13,7 @@ categories: - transformations kong_version_compatibility: enterprise_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x + compatible: true params: name: exit-transformer service_id: true @@ -230,7 +219,7 @@ end {% navtab Using cURL %} ```bash - $ curl -i -X POST http://:8001/services \ + curl -i -X POST http://:8001/services \ --data name=example.com \ --data url='http://mockbin.org' ``` @@ -239,7 +228,7 @@ end {% navtab Using HTTPie %} ```bash - $ http :8001/services name=example.com host=mockbin.org + http :8001/services name=example.com host=mockbin.org ``` {% endnavtab %} @@ -251,7 +240,7 @@ end {% navtab Using cURL %} ```bash -$ curl -i -X POST http://:8001/services/example.com/routes \ +curl -i -X POST http://:8001/services/example.com/routes \ --data 'hosts[]=example.com' ``` @@ -259,7 +248,7 @@ $ curl -i -X POST http://:8001/services/example.com/routes \ {% navtab Using HTTPie %} ```bash -$ http -f :8001/services/example.com/routes hosts=example.com +http -f :8001/services/example.com/routes hosts=example.com ``` {% endnavtab %} @@ -297,7 +286,7 @@ Configure the `exit-transformer` plugin with `transform.lua`. {% navtab Using cURL %} ```bash - $ curl -X POST http://:8001/services/example.com/plugins \ + curl -X POST http://:8001/services/example.com/plugins \ -F "name=exit-transformer" \ -F "config.functions=@transform.lua" ``` @@ -305,7 +294,7 @@ Configure the `exit-transformer` plugin with `transform.lua`. {% navtab Using HTTPie %} ```bash - $ http -f :8001/services/example.com/plugins \ + http -f :8001/services/example.com/plugins \ name=exit-transformer \ config.functions=@transform.lua ``` @@ -322,7 +311,7 @@ response in [step 6](#testy-exit): {% navtab Using cURL %} ```bash - $ curl -X POST http://:8001/services/example.com/plugins \ + curl -X POST http://:8001/services/example.com/plugins \ --data "name=key-auth" ``` @@ -330,7 +319,7 @@ response in [step 6](#testy-exit): {% navtab Using HTTPie %} ```bash - $ http :8001/services/example.com/plugins name=key-auth + http :8001/services/example.com/plugins name=key-auth ``` {% endnavtab %} @@ -346,14 +335,14 @@ in the message body. {% navtab Using cURL %} ```bash -$ curl --header 'Host: example.com' 'localhost:8000' +curl --header 'Host: example.com' 'localhost:8000' ``` {% endnavtab %} {% navtab Using HTTPie %} ```bash -$ http :8000 Host:example.com +http :8000 Host:example.com ``` {% endnavtab %} @@ -383,24 +372,24 @@ The plugin can also be applied globally: {% navtab Using cURL %} ```bash -$ curl -X POST http://:8001/plugins/ \ +curl -X POST http://:8001/plugins/ \ -F "name=exit-transformer" \ -F "config.handle_unknown=true" \ -F "config.functions=@transform.lua" ... -$ curl --header 'Host: non-existent.com' 'localhost:8000' +curl --header 'Host: non-existent.com' 'localhost:8000' ``` {% endnavtab %} {% navtab Using HTTPie %} ```bash -$ http :8001/plugins \ +http :8001/plugins \ name=exit-transformer \ config.handle_unknown=true \ config.functions=@transform.lua -$ http :8000 Host:non-existent.com +http :8000 Host:non-existent.com ``` {% endnavtab %} @@ -500,7 +489,7 @@ Configure the `exit-transformer` plugin with `custom-errors-by-mimetype.lua`. {% navtab Using cURL %} ```bash -$ curl -X POST http://:8001/services/example.com/plugins \ +curl -X POST http://:8001/services/example.com/plugins \ -F "name=exit-transformer" \ -F "config.handle_unknown=true" \ -F "config.handle_unexpected=true" \ @@ -511,7 +500,7 @@ $ curl -X POST http://:8001/services/example.com/plugins \ {% navtab Using HTTPie %} ```bash -$ http -f :8001/plugins name=exit-transformer \ +http -f :8001/plugins name=exit-transformer \ config.handle_unknown=true \ config.handle_unexpected=true \ config.functions=@examples/custom-errors-by-mimetype.lua diff --git a/app/_hub/kong-inc/exit-transformer/versions.yml b/app/_hub/kong-inc/exit-transformer/versions.yml index 333ef2ba3073..55ba51040d69 100644 --- a/app/_hub/kong-inc/exit-transformer/versions.yml +++ b/app/_hub/kong-inc/exit-transformer/versions.yml @@ -1,2 +1,12 @@ -- release: 1.5.x -- release: 1.3-x +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 0.3.3 + 2.7.x: 0.3.3 + 2.6.x: 0.3.2 + 2.5.x: 0.3.2 + 2.4.x: 0.3.2 + 2.3.x: 0.3.2 + 2.2.x: 0.3.0 + 2.1.x: 0.3.0 diff --git a/app/_hub/kong-inc/file-log/0.1-x.md b/app/_hub/kong-inc/file-log/0.1-x.md deleted file mode 100644 index e88821c0c156..000000000000 --- a/app/_hub/kong-inc/file-log/0.1-x.md +++ /dev/null @@ -1,194 +0,0 @@ ---- -name: File Log -publisher: Kong Inc. -version: 0.1-x - -desc: Append request and response data to a log file -description: | - Append request and response data in JSON format to a log file. You can also specify - streams (for example, `/dev/stdout` and `/dev/stderr`), which is especially useful - when running Kong in Kubernetes. - - This plugin uses blocking I/O, which could affect performance when writing - to physical files on slow (spinning) disks. - -
- Note: The functionality of this plugin as bundled - with versions of Kong prior to 0.10.2 differs from what is documented herein. - Refer to the - CHANGELOG - for details. -
- - -type: plugin -categories: - - logging - -kong_version_compatibility: - community_edition: - compatible: - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x - - 0.4.x - - 0.3.x - enterprise_edition: - compatible: - - 0.34-x - - 0.33-x - - 0.32-x - - 0.31-x - -params: - name: file-log - api_id: true - service_id: true - route_id: true - consumer_id: true - config: - - name: path - required: true - default: - value_in_examples: "/tmp/file.log" - description: | - The file path of the output log file. The plugin will create the file if it doesn't exist yet. Make sure Kong has write permissions to this file. - - name: reopen - required: false - default: "`false`" - description: | - Introduced in Kong `0.10.2`. Determines whether the log file is closed and reopened on every request. If the file is not reopened, and has been removed/rotated, the plugin will keep writing to the stale file descriptor, and hence lose information. - ---- - -## Log Format - -Every request will be logged separately in a JSON object separated by a new line `\n`, with the following format: - -```json -{ - "request": { - "method": "GET", - "uri": "/get", - "url": "http://httpbin.org:8000/get", - "size": "75", - "querystring": {}, - "headers": { - "accept": "*/*", - "host": "httpbin.org", - "user-agent": "curl/7.37.1" - }, - "tls": { - "version": "TLSv1.2", - "cipher": "ECDHE-RSA-AES256-GCM-SHA384", - "supported_client_ciphers": "ECDHE-RSA-AES256-GCM-SHA384", - "client_verify": "NONE" - } - }, - "upstream_uri": "/", - "response": { - "status": 200, - "size": "434", - "headers": { - "Content-Length": "197", - "via": "kong/0.3.0", - "Connection": "close", - "access-control-allow-credentials": "true", - "Content-Type": "application/json", - "server": "nginx", - "access-control-allow-origin": "*" - } - }, - "tries": [ - { - "state": "next", - "code": 502, - "ip": "127.0.0.1", - "port": 8000 - }, - { - "ip": "127.0.0.1", - "port": 8000 - } - ], - "authenticated_entity": { - "consumer_id": "80f74eef-31b8-45d5-c525-ae532297ea8e", - "id": "eaa330c0-4cff-47f5-c79e-b2e4f355207e" - }, - "route": { - "created_at": 1521555129, - "hosts": null, - "id": "75818c5f-202d-4b82-a553-6a46e7c9a19e", - "methods": null, - "paths": [ - "/example-path" - ], - "preserve_host": false, - "protocols": [ - "http", - "https" - ], - "regex_priority": 0, - "service": { - "id": "0590139e-7481-466c-bcdf-929adcaaf804" - }, - "strip_path": true, - "updated_at": 1521555129 - }, - "service": { - "connect_timeout": 60000, - "created_at": 1521554518, - "host": "example.com", - "id": "0590139e-7481-466c-bcdf-929adcaaf804", - "name": "myservice", - "path": "/", - "port": 80, - "protocol": "http", - "read_timeout": 60000, - "retries": 5, - "updated_at": 1521554518, - "write_timeout": 60000 - }, - "consumer": { - "username": "demo", - "created_at": 1491847011000, - "id": "35b03bfc-7a5b-4a23-a594-aa350c585fa8" - }, - "latencies": { - "proxy": 1430, - "kong": 9, - "request": 1921 - }, - "client_ip": "127.0.0.1", - "started_at": 1433209822425 -} -``` - -A few considerations on the above JSON object: - -* `request` contains properties about the request sent by the client -* `response` contains properties about the response sent to the client -* `tries` contains the list of (re)tries (successes and failures) made by the load balancer for this request -* `route` contains Kong properties about the specific Route requested -* `service` contains Kong properties about the Service associated with the requested Route -* `authenticated_entity` contains Kong properties about the authenticated credential (if an authentication plugin has been enabled) -* `consumer` contains the authenticated Consumer (if an authentication plugin has been enabled) -* `latencies` contains some data about the latencies involved: - * `proxy` is the time it took for the final service to process the request - * `kong` is the internal Kong latency that it took to run all the plugins - * `request` is the time elapsed between the first bytes were read from the client and after the last bytes were sent to the client. Useful for detecting slow clients. -* `client_ip` contains the original client IP address -* `started_at` contains the UTC timestamp of when the request has started to be processed. - ----- - -## Kong Process Errors - -This logging plugin will only log HTTP request and response data. If you are looking for the Kong process error file (which is the nginx error file), then you can find it at the following path: {[prefix](/gateway/latest/reference/configuration/#prefix)}/logs/error.log diff --git a/app/_hub/kong-inc/file-log/1.0.x.md b/app/_hub/kong-inc/file-log/1.0.x.md deleted file mode 100644 index d8698e139e0e..000000000000 --- a/app/_hub/kong-inc/file-log/1.0.x.md +++ /dev/null @@ -1,211 +0,0 @@ ---- -name: File Log -publisher: Kong Inc. -version: 1.0.x - -desc: Append request and response data to a log file -description: | - Append request and response data in JSON format to a log file. You can also specify - streams (for example, `/dev/stdout` and `/dev/stderr`), which is especially useful - when running Kong in Kubernetes. - - This plugin uses blocking I/O, which could affect performance when writing - to physical files on slow (spinning) disks. - - -type: plugin -categories: - - logging - -kong_version_compatibility: - community_edition: - compatible: - - 2.3.x - - 2.2.x - - 2.1.x - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x - - 0.4.x - - 0.3.x - enterprise_edition: - compatible: - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x - - -params: - name: file-log - service_id: true - route_id: true - consumer_id: true - protocols: ["http", "https", "grpc", "grpcs", "tcp", "tls", "udp"] - dbless_compatible: yes - config: - - name: path - required: true - default: - value_in_examples: "/tmp/file.log" - datatype: string - description: | - The file path of the output log file. The plugin creates the log file if it doesn't exist yet. Make sure Kong has write permissions to this file. - - name: reopen - required: true - default: "`false`" - datatype: boolean - description: | - Determines whether the log file is closed and reopened on every request. If the file - is not reopened, and has been removed/rotated, the plugin keeps writing to the - stale file descriptor, and hence loses information. - ---- - -## Log Format - -Every request will be logged separately in a JSON object separated by a new line `\n`, with the following format: - -```json -{ - "request": { - "method": "GET", - "uri": "/get", - "url": "http://httpbin.org:8000/get", - "size": "75", - "querystring": {}, - "headers": { - "accept": "*/*", - "host": "httpbin.org", - "user-agent": "curl/7.37.1" - }, - "tls": { - "version": "TLSv1.2", - "cipher": "ECDHE-RSA-AES256-GCM-SHA384", - "supported_client_ciphers": "ECDHE-RSA-AES256-GCM-SHA384", - "client_verify": "NONE" - } - }, - "upstream_uri": "/", - "response": { - "status": 200, - "size": "434", - "headers": { - "Content-Length": "197", - "via": "kong/0.3.0", - "Connection": "close", - "access-control-allow-credentials": "true", - "Content-Type": "application/json", - "server": "nginx", - "access-control-allow-origin": "*" - } - }, - "tries": [ - { - "state": "next", - "code": 502, - "ip": "127.0.0.1", - "port": 8000 - }, - { - "ip": "127.0.0.1", - "port": 8000 - } - ], - "authenticated_entity": { - "consumer_id": "80f74eef-31b8-45d5-c525-ae532297ea8e", - "id": "eaa330c0-4cff-47f5-c79e-b2e4f355207e" - }, - "route": { - "created_at": 1521555129, - "hosts": null, - "id": "75818c5f-202d-4b82-a553-6a46e7c9a19e", - "methods": null, - "paths": [ - "/example-path" - ], - "preserve_host": false, - "protocols": [ - "http", - "https" - ], - "regex_priority": 0, - "service": { - "id": "0590139e-7481-466c-bcdf-929adcaaf804" - }, - "strip_path": true, - "updated_at": 1521555129 - }, - "service": { - "connect_timeout": 60000, - "created_at": 1521554518, - "host": "example.com", - "id": "0590139e-7481-466c-bcdf-929adcaaf804", - "name": "myservice", - "path": "/", - "port": 80, - "protocol": "http", - "read_timeout": 60000, - "retries": 5, - "updated_at": 1521554518, - "write_timeout": 60000 - }, - "workspaces": [ - { - "id":"b7cac81a-05dc-41f5-b6dc-b87e29b6c3a3", - "name": "default" - } - ], - "consumer": { - "username": "demo", - "created_at": 1491847011000, - "id": "35b03bfc-7a5b-4a23-a594-aa350c585fa8" - }, - "latencies": { - "proxy": 1430, - "kong": 9, - "request": 1921 - }, - "client_ip": "127.0.0.1", - "started_at": 1433209822425 -} -``` - -A few considerations on the above JSON object: - -* `request` contains properties about the request sent by the client -* `response` contains properties about the response sent to the client -* `tries` contains the list of (re)tries (successes and failures) made by the load balancer for this request -* `route` contains Kong properties about the specific Route requested -* `service` contains Kong properties about the Service associated with the requested Route -* `authenticated_entity` contains Kong properties about the authenticated credential (if an authentication plugin has been enabled) -* `workspaces` contains Kong properties of the Workspaces associated with the requested Route. **Only in Kong Gateway version >= 0.34**. -* `consumer` contains the authenticated Consumer (if an authentication plugin has been enabled) -* `latencies` contains some data about the latencies involved: - * `proxy` is the time it took for the final service to process the request - * `kong` is the internal Kong latency that it took to run all the plugins - * `request` is the time elapsed between the first bytes were read from the client and after the last bytes were sent to the client. Useful for detecting slow clients. -* `client_ip` contains the original client IP address -* `started_at` contains the UTC timestamp of when the request has started to be processed. - ----- - -## Kong Process Errors - -{% include /md/plugins-hub/kong-process-errors.md %} diff --git a/app/_hub/kong-inc/file-log/2.0.x.md b/app/_hub/kong-inc/file-log/2.0.x.md deleted file mode 100644 index 10b1876a4bf4..000000000000 --- a/app/_hub/kong-inc/file-log/2.0.x.md +++ /dev/null @@ -1,92 +0,0 @@ ---- -name: File Log -publisher: Kong Inc. -version: 2.0.x -# internal handler version 2.0.2 - -desc: Append request and response data to a log file -description: | - Append request and response data in JSON format to a log file. You can also specify - streams (for example, `/dev/stdout` and `/dev/stderr`), which is especially useful - when running Kong in Kubernetes. - - This plugin uses blocking I/O, which could affect performance when writing - to physical files on slow (spinning) disks. - - -type: plugin -categories: - - logging - -kong_version_compatibility: - community_edition: - compatible: - - 2.3.x - - 2.2.x - - 2.1.x - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x - - 0.4.x - - 0.3.x - enterprise_edition: - compatible: - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x - - -params: - name: file-log - service_id: true - route_id: true - consumer_id: true - protocols: ["http", "https", "grpc", "grpcs", "tcp", "tls", "udp"] - dbless_compatible: yes - config: - - name: path - required: true - default: - value_in_examples: "/tmp/file.log" - datatype: string - description: | - The file path of the output log file. The plugin creates the log file if it doesn't exist yet. Make sure Kong has write permissions to this file. - - name: reopen - required: true - default: "`false`" - datatype: boolean - description: | - Determines whether the log file is closed and reopened on every request. If the file - is not reopened, and has been removed/rotated, the plugin keeps writing to the - stale file descriptor, and hence loses information. - ---- - -## Log format - -{% include /md/plugins-hub/log-format.md %} - -### JSON object considerations - -{% include /md/plugins-hub/json-object-log.md %} - -## Kong process errors - -{% include /md/plugins-hub/kong-process-errors.md %} diff --git a/app/_hub/kong-inc/file-log/_index.md b/app/_hub/kong-inc/file-log/_index.md index deebae55c2ff..6063e9397fc0 100644 --- a/app/_hub/kong-inc/file-log/_index.md +++ b/app/_hub/kong-inc/file-log/_index.md @@ -1,7 +1,6 @@ --- name: File Log publisher: Kong Inc. -version: 2.1.x desc: Append request and response data to a log file description: | Append request and response data in JSON format to a log file. You can also specify @@ -15,48 +14,9 @@ categories: - logging kong_version_compatibility: community_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x - - 0.4.x - - 0.3.x + compatible: true enterprise_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x -params: + compatible: true name: file-log service_id: true route_id: true @@ -87,6 +47,7 @@ params: is not reopened, and has been removed/rotated, the plugin keeps writing to the stale file descriptor, and hence loses information. - name: custom_fields_by_lua + minimum_version: "2.4.x" required: false default: null datatype: map @@ -108,6 +69,15 @@ params: {% include /md/plugins-hub/kong-process-errors.md %} +{% if_plugin_version gte:2.4.x %} ## Custom Fields by Lua {% include /md/plugins-hub/log_custom_fields_by_lua.md %} +{% endif_plugin_version %} + +--- +## Changelog + +**{{site.base_gateway}} 2.4.x** + +* Added `custom_fields_by_lua` configuration option. diff --git a/app/_hub/kong-inc/file-log/versions.yml b/app/_hub/kong-inc/file-log/versions.yml index bc466d57ec2e..ea575532347c 100644 --- a/app/_hub/kong-inc/file-log/versions.yml +++ b/app/_hub/kong-inc/file-log/versions.yml @@ -1,3 +1,12 @@ -- release: 2.0.x -- release: 1.0.x -- release: 0.1-x +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 2.1.0 + 2.7.x: 2.1.0 + 2.6.x: 2.1.0 + 2.5.x: 2.1.0 + 2.4.x: 2.1.0 + 2.3.x: 2.0.2 + 2.2.x: 2.0.2 + 2.1.x: 2.0.2 diff --git a/app/_hub/kong-inc/forward-proxy/1.0.5.md b/app/_hub/kong-inc/forward-proxy/_1.0.5.md similarity index 100% rename from app/_hub/kong-inc/forward-proxy/1.0.5.md rename to app/_hub/kong-inc/forward-proxy/_1.0.5.md diff --git a/app/_hub/kong-inc/forward-proxy/1.1.x.md b/app/_hub/kong-inc/forward-proxy/_1.1.x.md similarity index 100% rename from app/_hub/kong-inc/forward-proxy/1.1.x.md rename to app/_hub/kong-inc/forward-proxy/_1.1.x.md diff --git a/app/_hub/kong-inc/forward-proxy/_index.md b/app/_hub/kong-inc/forward-proxy/_index.md index d4c4c16caaa3..63a0abb69115 100644 --- a/app/_hub/kong-inc/forward-proxy/_index.md +++ b/app/_hub/kong-inc/forward-proxy/_index.md @@ -94,7 +94,7 @@ params: {:.important} > This parameter is deprecated as of Kong Gateway 2.8.0.0 and - is planned to be removed in 3.x.x. + is planned to be removed in a future release. >
> Use `http_proxy_host` or `https_proxy_host` instead. @@ -109,7 +109,7 @@ params: {:.important} > This parameter is deprecated as of Kong Gateway 2.8.0.0 and - is planned to be removed in 3.x.x. + is planned to be removed in a future release. >
> Use `http_proxy_host` or `https_proxy_host` instead. @@ -132,8 +132,8 @@ params: by basic authentication. This field is _referenceable_, which means it can be securely stored as a - [secret](/gateway/latest/plan-and-deploy/security/secrets-management/getting-started) - in a vault. References must follow a [specific format](/gateway/latest/plan-and-deploy/security/secrets-management/reference-format). + [secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). - name: auth_password required: false default: null @@ -144,8 +144,8 @@ params: by basic authentication. This field is _referenceable_, which means it can be securely stored as a - [secret](/gateway/latest/plan-and-deploy/security/secrets-management/getting-started) - in a vault. References must follow a [specific format](/gateway/latest/plan-and-deploy/security/secrets-management/reference-format). + [secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). - name: https_verify required: true default: false @@ -173,12 +173,12 @@ params: {:.important} > These parameters replace the `proxy_port` and `proxy_host` fields, which - are now **deprecated** and planned to be removed in 3.x.x. + are now **deprecated** and planned to be removed in a future release. * The `auth_password` and `auth_username` configuration fields are now marked as referenceable, which means they can be securely stored as [secrets](/gateway/latest/plan-and-deploy/security/secrets-management/getting-started) -in a vault. References must follow a [specific format](/gateway/latest/plan-and-deploy/security/secrets-management/reference-format). +in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). * Fixed a plugin version in the documentation. Previously, there was a plugin version labelled as `1.0.x`. It is now updated to align with the diff --git a/app/_hub/kong-inc/forward-proxy/versions.yml b/app/_hub/kong-inc/forward-proxy/versions.yml index 973e1e6a0dd0..0a2339bf8c9b 100644 --- a/app/_hub/kong-inc/forward-proxy/versions.yml +++ b/app/_hub/kong-inc/forward-proxy/versions.yml @@ -1,9 +1,20 @@ -- release: 1.2.x -- release: 1.1.x -- release: 1.0.5 -- release: 0.36-x -- release: 0.35-x -- release: 0.34-x -- release: 0.33-x -- release: 0.32-x -- release: 0.31-x +strategy: gateway +delegate_releases: true +sources: + 2.7.x: _1.1.x + 2.6.x: _1.0.5 + 2.5.x: _1.0.5 + 2.4.x: _1.0.5 + 2.3.x: _1.0.5 + 2.2.x: _1.0.5 + 2.1.x: _1.0.5 + +overrides: + 2.8.x: 1.2.0 + 2.7.x: 1.1.0 + 2.6.x: 1.0.5 + 2.5.x: 1.0.5 + 2.4.x: 1.0.5 + 2.3.x: 1.0.4 + 2.2.x: 1.0.4 + 2.1.x: 1.0.4 diff --git a/app/_hub/kong-inc/graphql-proxy-cache-advanced/_index.md b/app/_hub/kong-inc/graphql-proxy-cache-advanced/_index.md index 0b48d28572bf..9052c55451ff 100644 --- a/app/_hub/kong-inc/graphql-proxy-cache-advanced/_index.md +++ b/app/_hub/kong-inc/graphql-proxy-cache-advanced/_index.md @@ -1,7 +1,6 @@ --- name: GraphQL Proxy Caching Advanced publisher: Kong Inc. -version: 1.3-x desc: Cache and serve commonly requested responses in Kong description: | This plugin provides a reverse GraphQL proxy cache implementation for Kong. It caches response entities based on @@ -15,17 +14,7 @@ categories: - traffic-control kong_version_compatibility: enterprise_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x + compatible: true params: name: graphql-proxy-cache-advanced service_id: true diff --git a/app/_hub/kong-inc/graphql-proxy-cache-advanced/versions.yml b/app/_hub/kong-inc/graphql-proxy-cache-advanced/versions.yml index 57f7f5264e38..ca5fc6bec4c9 100644 --- a/app/_hub/kong-inc/graphql-proxy-cache-advanced/versions.yml +++ b/app/_hub/kong-inc/graphql-proxy-cache-advanced/versions.yml @@ -1 +1,12 @@ -- release: 1.3-x +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 0.2.3 + 2.7.x: 0.2.2 + 2.6.x: 0.2.2 + 2.5.x: 0.2.2 + 2.4.x: 0.2.2 + 2.3.x: 0.2.2 + 2.2.x: 0.2.2 + 2.1.x: 0.2.1 diff --git a/app/_hub/kong-inc/graphql-rate-limiting-advanced/0.1.x.md b/app/_hub/kong-inc/graphql-rate-limiting-advanced/0.1.x.md deleted file mode 100644 index e28339fb2b53..000000000000 --- a/app/_hub/kong-inc/graphql-rate-limiting-advanced/0.1.x.md +++ /dev/null @@ -1,571 +0,0 @@ ---- - -name: GraphQL Rate Limiting Advanced -publisher: Kong Inc. -version: 0.1.x - -desc: Provide rate limiting for GraphQL queries -description: | - The GraphQL Rate Limiting Advanced plugin provides rate limiting for GraphQL queries. The - GraphQL Rate Limiting plugin extends the - [Rate Limiting Advanced](/hub/kong-inc/rate-limiting-advanced/) plugin. - -type: plugin -enterprise: true -categories: - - traffic-control - -kong_version_compatibility: - enterprise_edition: - compatible: - - 1.3-x - -params: - name: graphql-rate-limiting-advanced - service_id: true - route_id: true - config: - - name: cost_strategy - required: true - default: "default" - value_in_examples: - datatype: string - description: | - Strategy to use to evaluate query costs. Either `default` or - `node_quantifier`. See [default](/hub/kong-inc/graphql-rate-limiting-advanced/#default) and - [node_quantifier](/hub/kong-inc/graphql-rate-limiting-advanced/#node_quantifier) respectively. - - name: max_cost - required: false - default: 0 - value_in_examples: - datatype: number - description: | - A defined maximum cost per query. 0 means unlimited. - - name: score_factor - required: false - default: 1.0 - value_in_examples: - datatype: number - description: | - A scoring factor to multiply (or divide) the cost. The `score_factor` must always be greater than 0. - - name: limit - required: true - default: - value_in_examples: [ "5" ] - datatype: array of number elements - description: | - One or more requests-per-window limits to apply. - - name: window_size - required: true - default: - value_in_examples: [ "30" ] - datatype: array of number elements - description: | - One or more window sizes to apply a limit to (defined in seconds). - - name: identifier - required: true - default: consumer - value_in_examples: - datatype: string - description: | - How to define the rate limit key. Can be `ip`, `credential`, `consumer`. - - name: header_name - required: semi - datatype: string - description: | - Header name to use as the rate limit key when the `header` identifier is defined. - - name: dictionary_name - required: true - default: kong_rate_limiting_counters - value_in_examples: - datatype: string - description: | - The shared dictionary where counters will be stored until the next sync cycle. - - name: sync_rate - required: true - default: - value_in_examples: -1 - datatype: number - description: | - How often to sync counter data to the central data store. A value of 0 - results in synchronous behavior; a value of -1 ignores sync behavior - entirely and only stores counters in node memory. A value greater than - 0 syncs the counters in that many number of seconds. - - name: namespace - required: false - default: random string - value_in_examples: - datatype: string - description: | - The rate limiting library namespace to use for this plugin instance. Counter data and sync configuration is shared in a namespace. - - name: strategy - required: - default: cluster - value_in_examples: - datatype: string - description: | - The sync strategy to use; `cluster` and `redis` are supported. - - name: redis.host - required: semi - default: - value_in_examples: - datatype: string - description: | - Host to use for Redis connection when the `redis` strategy is defined. - - name: redis.port - required: semi - default: - value_in_examples: - datatype: integer - description: | - Port to use for Redis connection when the `redis` strategy is defined. - - name: redis.timeout - required: semi - default: 2000 - value_in_examples: - datatype: number - description: | - Connection timeout (in milliseconds) to use for Redis connection when the `redis` strategy is defined. - - name: redis.password - required: semi - default: - value_in_examples: - datatype: string - description: | - Password to use for Redis connection when the `redis` strategy is defined. If undefined, no AUTH commands are sent to Redis. - - name: redis.database - required: semi - default: 0 - value_in_examples: - datatype: integer - description: | - Database to use for Redis connection when the `redis` strategy is defined. - - name: redis.sentinel_master - required: semi - default: - value_in_examples: - datatype: string - description: | - Sentinel master to use for Redis connection when the `redis` strategy is defined. Defining this value implies using Redis Sentinel. - - name: redis.sentinel_password - required: semi - default: - value_in_examples: - datatype: string - description: | - Sentinel password to authenticate with a Redis Sentinel instance. - **Note:** This parameter is only available for Kong Gateway versions - 1.3.0.2 and later. - - name: redis.sentinel_role - required: semi - default: - value_in_examples: - datatype: string - description: | - Sentinel role to use for Redis connection when the `redis` strategy is defined. Defining this value implies using Redis Sentinel. - - name: redis.sentinel_addresses - required: semi - default: - value_in_examples: - datatype: array of string elements - description: | - Sentinel addresses to use for Redis connection when the `redis` strategy is defined. Defining this value implies using Redis Sentinel. - - name: redis.cluster_addresses - required: semi - default: - value_in_examples: - datatype: array of string elements - description: | - Cluster addresses to use for Redis connection when the `redis` strategy is defined. Defining this value implies using Redis cluster. - - name: window_type - required: true - default: sliding - value_in_examples: - datatype: string - description: | - Sets the time window to either `sliding` or `fixed`. - - name: hide_client_headers - required: false - default: false - value_in_examples: - datatype: boolean - description: | - Optionally hide informative response headers. Available options: `true` or `false`. - - extra: | - > Note: Redis configuration values are ignored if the `cluster` strategy is used. - - **Notes:** - - * PostgreSQL 9.5+ is required when using the `cluster` strategy with `postgres` as the backing Kong cluster data store. This requirement varies from the PostgreSQL 9.4+ requirement as described in the Kong Community Edition documentation. - - * The `dictionary_name` directive was added to prevent the usage of the `kong` shared dictionary, which could lead to `no memory` errors. - ---- - -The **GraphQL Rate Limiting Advanced** plugin is an extension of the -**Rate Limiting Advanced** plugin and provides rate limiting for -GraphQL queries. - -Due to the nature of client-specified GraphQL queries, the same HTTP request -to the same URL with the same method can vary greatly in cost depending on the -semantics of the GraphQL operation in the body. - -A common pattern to protect your GraphQL API is then to analyze and -assign costs to incoming GraphQL queries and rate limit the consumer's -cost for a given time window. - -## Costs in GraphQL queries - -GraphQL query costs are evaluated by introspecting the endpoint's GraphQL schema -and applying cost decoration to parts of the schema tree. - -Initially all nodes start with zero cost, with any operation at cost 1. -Add rate-limiting constraints on any subtree. If subtree omitted, then -rate-limit window applies on the whole tree (any operation). - -Since there are many ways of approximating the cost of a GraphQL query, the -plugin exposes two strategies: `default` and `node_quantifier`. - -The following example queries can be run on this [SWAPI playground]. - -[SWAPI playground]: https://swapi-graphql.eskerda.now.sh - -### `default` - -The default strategy is meant as a good middle ground for general GraphQL -queries, where it's difficult to assert a clear cost strategy, so every operation -has a cost of 1. - -``` -query { # + 1 - allPeople { # + 1 - people { # + 1 - name # + 1 - } - } -} - -# total cost: 4 -``` - -Default node costs can be defined by decorating the schema: - -| `type_path` | `mul_arguments` | `mul_constant` | `add_arguments` | `add_constant` -|---------------------------|-------------------|-------------------|-------------------|--------------- -| Query.allPeople | ["first"] | 1 | [] | 1 -| Person.vehicleConnection | ["first"] | 1 | [] | 1 - - -``` -query { # + 1 - allPeople(first:20) { # * 20 + 1 - people { # + 1 - name # + 1 - vehicleConnection(first:10) { # * 10 + 1 - vehicles { # + 1 - id # + 1 - name # + 1 - cargoCapacity # + 1 - } - } - } - } -} - -# total cost: ((((4 * 10 + 1) + 1) + 1) * 20 + 1) + 1 = 862 -``` - -Generally speaking, vehicleConnection weight (4) is applied 10 times, and the -total weight of it (40) 20 times, which gives us a rough 800. - -Cost constants can be atomically defined as: - -| `type_path` | `mul_arguments` | `mul_constant` | `add_arguments` | `add_constant` -|---------------------------|-------------------|-------------------|-------------------|--------------- -| Query.allPeople | ["first"] | 2 | [] | 2 -| Person.vehicleConnection | ["first"] | 1 | [] | 5 -| Vehicle.name | [] | 1 | [] | 8 - -On this example, `Vehicle.name` and `Person.vehicleConnection` have specific -weights of 8 and 5 respectively. `allPeople` weights 2, and also has double -its weight when multiplied by arguments. - -``` -query { # + 1 - allPeople(first:20) { # 2 * 20 + 2 - people { # + 1 - name # + 1 - vehicleConnection(first:10) { # * 10 + 5 - vehicles { # + 1 - id # + 1 - name # + 8 - cargoCapacity # + 1 - } - } - } - } -} - -# total cost: ((((11 * 10 + 5) + 1) + 1) * 2 * 20 + 2) + 1 = 4683 -``` - -### `node_quantifier` - -This strategy is fit for GraphQL schemas that enforce quantifier arguments on -any connection, providing a good approximation on the number of nodes visited -for satisfying a query. Any query without decorated quantifiers has a cost of 1. -It is roughly based on [github's GraphQL resource limits]. - -[github's GraphQL resource limits]: https://developer.github.com/v4/guides/resource-limitations/ - -``` -query { - allPeople(first:100) { # 1 - people { - name - vehicleConnection(first:10) { # 100 - vehicles { - name - filmConnection(first:5) { # 10 * 100 - films{ - title - characterConnection(first:50) { # 5 * 10 * 100 - characters { - name - } - } - } - } - } - } - } - } -} -# total cost: 1 + 100 + 10 * 100 + 5 * 10 * 100 = 6101 -``` - -| `type_path` | `mul_arguments` | `mul_constant` | `add_arguments` | `add_constant` -|---------------------------|-------------------|-------------------|-------------------|--------------- -| Query.allPeople | ["first"] | 1 | [] | 1 -| Person.vehicleConnection | ["first"] | 1 | [] | 1 -| Vehicle.filmConnection | ["first"] | 1 | [] | 1 -| Film.characterConnection | ["first"] | 1 | [] | 1 - -Roughly speaking: - -* `allPeople` returns 100 nodes, and has been called once -* `vehicleConnection` returns 10 nodes, and has been called 100 times -* `filmConnection` returns 5 nodes, and has been called 10 * 100 times -* `characterConnection` returns 50 nodes, and has been called 5 * 10 * 100 times - - -Specific costs per node can be specified by adding a constant: - -| `type_path` | `mul_arguments` | `mul_constant` | `add_arguments` | `add_constant` -|---------------------------|-------------------|-------------------|-------------------|--------------- -| Query.allPeople | ["first"] | 1 | [] | 1 -| Person.vehicleConnection | ["first"] | 1 | [] | 42 -| Vehicle.filmConnection | ["first"] | 1 | [] | 1 -| Film.characterConnection | ["first"] | 1 | [] | 1 - - -``` -query { - allPeople(first:100) { # 1 - people { - name - vehicleConnection(first:10) { # 100 * 42 - vehicles { - name - filmConnection(first:5) { # 10 * 100 - films{ - title - characterConnection(first:50) { # 5 * 10 * 100 - characters { - name - } - } - } - } - } - } - } - } -} -# total cost: 1 + 100 * 42 + 10 * 100 + 5 * 10 * 100 = 10201 -``` - -## Usage - -The following configuration example targets a GraphQL endpoint at our [SWAPI playground]. - -### Add a GraphQL service and route - -``` -$ curl -X POST http://kong:8001/services \ - --data "name=example" \ - --data "host=swapi-graphql.eskerda.now.sh" \ - --data "port=443" \ - --data "protocol=https" - -$ curl -X POST http://kong:8001/services/example/routes \ - --data "hosts=example.com" -``` - -### Enable the plugin on the service - -Example using a single time window: - -``` -$ curl -i -X POST http://kong:8001/services/{service}/plugins \ - --data name=graphql-rate-limiting-advanced \ - --data config.limit=100 \ - --data config.window_size=60 \ - --data config.sync_rate=10 -``` - -Example using multiple time windows: - -``` -$ curl -i -X POST --url http://kong:8001/services/{service}/plugins \ - --data 'name=graphql-rate-limiting-advanced' \ - --data 'config.window_size[]=60' \ - --data 'config.window_size[]=3600' \ - --data 'config.limit[]=10' \ - --data 'config.limit[]=100' \ - --data 'config.sync_rate=10' -``` - -### Decorate gql schema for costs - -Cost decoration schema looks like: - -| Form Parameter | default | description -|-------------------|-----------|------------- -| `type_path` | | Path to node to decorate -| `add_constant` | `1` | Node weight when added -| `add_arguments` | `[]` | List of arguments to add to add_constant -| `mul_constant` | `1` | Node weight multiplier value -| `mul_arguments` | `[]` | List of arguments that multiply weight - - -Cost decoration is available on the following routes: - -#### `/services/{service}/graphql-rate-limiting-advanced/costs` - -* **GET**: list of costs associated to a service schema -* **PUT**, **POST**: add a cost to a service schema - - -For example: - -``` -$ curl -X POST http://kong:8001/services/{service}/graphql-rate-limiting-advanced/costs \ - --data type_path="Query.allPeople" \ - --data mul_arguments="first" - - -$ curl -X POST http://kong:8001/services/{service}/graphql-rate-limiting-advanced/costs \ - --data type_path="Person.vehicleConnection" \ - --data mul_arguments="first" - --data add_constant=42 - -$ curl -X POST http://kong:8001/services/{service}/graphql-rate-limiting-advanced/costs \ - --data type_path="Vehicle.filmConnection" \ - --data mul_arguments="first" - - -$ curl -X POST http://kong:8001/services/{service}/graphql-rate-limiting-advanced/costs \ - --data type_path="Film.characterConnection" \ - --data mul_arguments="first" -``` - - -#### `/graphql-rate-limiting-advanced/costs` - -* **GET**: list of all costs on any service -* **PUT**, **POST**: add a cost to a service schema - - -#### `/graphql-rate-limiting-advanced/costs/{cost_id}` - -* **GET**: get cost associated by id -* **PATCH**: modify cost associated by id -* **DELETE**: delete cost associated by id - - -### Changing the default strategy - -``` -$ curl -X POST http://kong:8001/services/{service}/plugins \ - --data name=graphql-rate-limiting-advanced \ - --data config.limit=100 \ - --data config.limit=10000 \ - --data config.window_size=60 \ - --data config.window_size=3600 \ - --data config.sync_rate=10 \ - --data config.cost_strategy=default -``` - -``` -$ curl -i -X PATCH http://kong:8001/plugins/{plugin_id} \ - --data config.cost_strategy=node_quantifier -``` - -### Limit query cost by using `config.max_cost` - -It's usually a good idea to define a maximum cost applied to any query, -regardless if the call is within the rate limits for a consumer. - -By defining a `max_cost` on our service, we are ensuring no query will run with -a cost higher than our set `max_cost`. By default it's set to 0, which means -no limit. - -``` -$ curl -X POST http://kong:8001/services/{service}/plugins \ - --data name=graphql-rate-limiting-advanced \ - --data config.limit=100 \ - --data config.limit=10000 \ - --data config.window_size=60 \ - --data config.window_size=3600 \ - --data config.sync_rate=0 \ - --data config.max_cost=5000 -``` - -To update `max_cost`: - -``` -$ curl -X PATCH http://kong:8001/plugins/{plugin_id} \ - --data config.max_cost=10000 -``` - -### Using `config.score_factor` to modify costs - -GraphQL query cost depends on multiple factors based on our resolvers -and the implementation of the schema. Cost on queries, depending on the cost -strategy might turn very high when using quantifiers, or very low with no -quantifiers at all. By using `config.score_factor` the cost can be divided -or multiplied to a certain order of magnitude. - -For example, a `score_factor` of `0.01` will divide the costs by 100, meaning -every cost unit represents 100 nodes. - -``` -$ curl -X POST http://kong:8001/services/{service}/plugins \ - --data name=graphql-rate-limiting-advanced \ - --data config.limit=100 \ - --data config.limit=10000 \ - --data config.window_size=60 \ - --data config.window_size=3600 \ - --data config.sync_rate=0 \ - --data config.max_cost=5000 \ - --data config.score_factor=0.01 -``` - -To update `score_factor`: - -``` -$ curl -i -X PATCH http://kong:8001/plugins/{plugin_id} \ - --data config.score_factor=1 -``` diff --git a/app/_hub/kong-inc/graphql-rate-limiting-advanced/_index.md b/app/_hub/kong-inc/graphql-rate-limiting-advanced/_index.md index 6d640e560dc2..f0293c25196f 100644 --- a/app/_hub/kong-inc/graphql-rate-limiting-advanced/_index.md +++ b/app/_hub/kong-inc/graphql-rate-limiting-advanced/_index.md @@ -1,7 +1,6 @@ --- name: GraphQL Rate Limiting Advanced publisher: Kong Inc. -version: 0.2.x desc: Provide rate limiting for GraphQL queries description: | The GraphQL Rate Limiting Advanced plugin provides rate limiting for GraphQL queries. The @@ -14,16 +13,7 @@ categories: - traffic-control kong_version_compatibility: enterprise_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x + compatible: true params: name: graphql-rate-limiting-advanced service_id: true @@ -152,9 +142,7 @@ params: datatype: boolean description: | If set to true, then uses SSL to connect to Redis. - - **Note:** This parameter is only available for Kong Gateway versions - 2.2.x and later. + minimum_version: "2.2.x" - name: redis.ssl_verify required: false default: false @@ -165,9 +153,7 @@ params: [lua_ssl_trusted_certificate](/gateway/latest/reference/configuration/#lua_ssl_trusted_certificate) to specify the CA (or server) certificate used by your redis server. You may also need to configure [lua_ssl_verify_depth](/gateway/latest/reference/configuration/#lua_ssl_verify_depth) accordingly. - - **Note:** This parameter is only available for Kong Gateway versions - 2.2.x and later. + minimum_version: "2.2.x" - name: redis.server_name required: false default: null @@ -175,9 +161,7 @@ params: datatype: string description: | Specifies the server name for the new TLS extension Server Name Indication (SNI) when connecting over SSL. - - **Note:** This parameter is only available for Kong Gateway versions - 2.2.x and later. + minimum_version: "2.2.x" - name: redis.timeout required: semi default: 2000 @@ -195,8 +179,9 @@ params: If undefined, ACL authentication will not be performed. This requires Redis v6.0.0+. This field is _referenceable_, which means it can be securely stored as a - [secret](/gateway/latest/plan-and-deploy/security/secrets-management/getting-started) - in a vault. References must follow a [specific format](/gateway/latest/plan-and-deploy/security/secrets-management/reference-format). + [secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). + minimum_version: "2.8.x" - name: redis.password required: semi default: null @@ -207,8 +192,8 @@ params: If undefined, no AUTH commands are sent to Redis. This field is _referenceable_, which means it can be securely stored as a - [secret](/gateway/latest/plan-and-deploy/security/secrets-management/getting-started) - in a vault. References must follow a [specific format](/gateway/latest/plan-and-deploy/security/secrets-management/reference-format). + [secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). - name: redis.database required: semi default: 0 @@ -233,8 +218,9 @@ params: If undefined, ACL authentication will not be performed. This requires Redis v6.2.0+. This field is _referenceable_, which means it can be securely stored as a - [secret](/gateway/latest/plan-and-deploy/security/secrets-management/getting-started) - in a vault. References must follow a [specific format](/gateway/latest/plan-and-deploy/security/secrets-management/reference-format). + [secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). + minimum_version: "2.8.x" - name: redis.sentinel_password required: semi default: null @@ -245,8 +231,8 @@ params: If undefined, no AUTH commands are sent to Redis Sentinels. This field is _referenceable_, which means it can be securely stored as a - [secret](/gateway/latest/plan-and-deploy/security/secrets-management/getting-started) - in a vault. References must follow a [specific format](/gateway/latest/plan-and-deploy/security/secrets-management/reference-format). + [secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). - name: redis.sentinel_role required: semi default: null @@ -280,6 +266,7 @@ params: will fail and return `nil`. Queued connect operations resume once the number of connections in the pool is less than `keepalive_pool_size`. Note that queued connect operations are subject to set timeouts. + minimum_version: "2.5.x" - name: redis.keepalive_pool required: false default: generated from string template @@ -288,6 +275,7 @@ params: description: | The custom name of the connection pool. If not specified, the connection pool name is generated from the string template `":"` or `""`. + minimum_version: "2.5.x" - name: redis.keepalive_pool_size required: false default: 30 @@ -298,6 +286,7 @@ params: server, per worker process. If no `keepalive_pool_size` is specified and no `keepalive_backlog` is specified, no pool is created. If no `keepalive_pool_size` is specified and `keepalive_backlog` is specified, then the pool uses the default value `30`. + minimum_version: "2.5.x" - name: window_type required: true default: sliding @@ -693,15 +682,24 @@ curl -i -X PATCH http://kong:8001/plugins/{plugin_id} \ ## Changelog -### {{site.base_gateway}} 2.8.x (plugin version 0.2.5) +**{{site.base_gateway}} 2.8.x** * Added the `redis.username` and `redis.sentinel_username` configuration parameters. * The `redis.username`, `redis.password`, `redis.sentinel_username`, and `redis.sentinel_password` configuration fields are now marked as referenceable, which means they can be securely stored as [secrets](/gateway/latest/plan-and-deploy/security/secrets-management/getting-started) -in a vault. References must follow a [specific format](/gateway/latest/plan-and-deploy/security/secrets-management/reference-format). +in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). * Fixed plugin versions in the documentation. Previously, the plugin versions were labelled as `1.3-x` and `2.3.x`. They are now updated to align with the plugin's actual versions, `0.1.x` and `0.2.x`. + +**{{site.base_gateway}} 2.5.x** + +* Added the `redis.keepalive_pool`, `redis.keepalive_pool_size`, and `redis.keepalive_backlog` configuration parameters. + These options relate to [Openresty’s Lua INGINX module’s](https://github.com/openresty/lua-nginx-module/#tcpsockconnect) `tcp:connect` options. + +**{{site.base_gateway}} 2.2.x** + +* Added Redis TLS support with the `redis.ssl`, `redis.ssl_verify`, and `redis.server_name` configuration parameters. diff --git a/app/_hub/kong-inc/graphql-rate-limiting-advanced/versions.yml b/app/_hub/kong-inc/graphql-rate-limiting-advanced/versions.yml index 8f68dd8fa36b..7010a13c6ca7 100644 --- a/app/_hub/kong-inc/graphql-rate-limiting-advanced/versions.yml +++ b/app/_hub/kong-inc/graphql-rate-limiting-advanced/versions.yml @@ -1,2 +1,12 @@ -- release: 0.2.x -- release: 0.1.x +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 0.2.5 + 2.7.x: 0.2.5 + 2.6.x: 0.2.4 + 2.5.x: 0.2.4 + 2.4.x: 0.2.4 + 2.3.x: 0.2.3 + 2.2.x: 0.2.3 + 2.1.x: 0.2.2 diff --git a/app/_hub/kong-inc/grpc-gateway/0.1.x.md b/app/_hub/kong-inc/grpc-gateway/0.1.x.md deleted file mode 100644 index 20de12c5bd22..000000000000 --- a/app/_hub/kong-inc/grpc-gateway/0.1.x.md +++ /dev/null @@ -1,167 +0,0 @@ ---- -name: gRPC-gateway -publisher: Kong Inc. -version: 0.1.x - -categories: - - transformations -type: plugin - -desc: Access gRPC services through HTTP REST -description: | - A Kong plugin to allow access to a gRPC service via HTTP REST requests - and translate requests and responses in a JSON format. Similar to - [gRPC-gateway](https://grpc-ecosystem.github.io/grpc-gateway/). - -source_url: https://github.com/Kong/kong-plugin-grpc-gateway - -license_type: MIT - -kong_version_compatibility: - community_edition: - compatible: - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - enterprise_edition: - compatible: - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - -params: - name: grpc-gateway - route_id: true - protocols: ["http", "https"] - dbless_compatible: 'yes' - - config: - - name: proto - required: false - default: - value_in_examples: path/to/hello.proto - datatype: string - description: | - Describes the gRPC types and methods. - [HTTP configuration](https://github.com/googleapis/googleapis/blob/fc37c47e70b83c1cc5cc1616c9a307c4303fe789/google/api/http.proto) - must be defined in the file. - ---- - -## Purpose - -This plugin translates requests and responses between gRPC and HTTP REST. - -![grpc-gateway](https://grpc-ecosystem.github.io/grpc-gateway/assets/images/architecture_introduction_diagram.svg) - -Image credit: [grpc-gateway](https://grpc-ecosystem.github.io/grpc-gateway/) - -## Usage - -This plugin should be enabled on a Kong `Route` that serves the `http(s)` protocol -but proxies to a `Service` with the `grpc(s)` protocol. - -Sample configuration via declarative (YAML): - -```yaml -_format_version: "1.1" -services: -- protocol: grpc - host: localhost - port: 9000 - routes: - - protocols: - - http - paths: - - / - plugins: - - name: grpc-gateway - config: - proto: path/to/hello.proto -``` - -Sample configuration via the Admin API: - -```bash -$ # add the gRPC service -$ curl -X POST localhost:8001/services \ - --data name=grpc \ - --data protocol=grpc \ - --data host=localhost \ - --data port=9000 - -$ # add an http route -$ curl -X POST localhost:8001/services/grpc/routes \ - --data protocols=http \ - --data name=web-service \ - --data paths[]=/ - -$ # add the plugin to the route -$ curl -X POST localhost:8001/routes/web-service/plugins \ - --data name=grpc-gateway -``` - -The proto file must contain the -[HTTP REST to gRPC mapping rule](https://github.com/googleapis/googleapis/blob/fc37c47e70b83c1cc5cc1616c9a307c4303fe789/google/api/http.proto). - -The example uses the following mapping: - -```protobuf -syntax = "proto2"; - -package hello; - -service HelloService { - rpc SayHello(HelloRequest) returns (HelloResponse) { - option (google.api.http) = { - get: "/v1/messages/{name}" - additional_bindings { - get: "/v1/messages/legacy/{name=**}" - } - post: "/v1/messages/" - body: "*" - } - } -} - - -// The request message containing the user's name. -message HelloRequest { - string name = 1; -} - -// The response message containing the greetings -message HelloReply { - string message = 1; -} -``` - -Note the `option (google.api.http) = {}` section is required. - -You can send the following requests to Kong that translate to the corresponding -gRPC requests: - -```bash -curl -XGET localhost:8000/v1/messages/Kong2.0 -{"message":"Hello Kong2.0"} - -curl -XGET localhost:8000/v1/messages/legacy/Kong2.0 -{"message":"Hello Kong2.0"} - -curl -XGET localhost:8000/v1/messages/legacy/Kong2.0/more/paths -{"message":"Hello Kong2.0\/more\/paths"} - -curl -XPOST localhost:8000/v1/messages/Kong2.0 -d '{"name":"kong2.0"}' -{"message":"Hello kong2.0"} -``` - -All syntax defined in [Path template syntax](https://github.com/googleapis/googleapis/blob/fc37c47e70b83c1cc5cc1616c9a307c4303fe789/google/api/http.proto#L225) is supported. - -Currently only unary requests are supported; streaming requests are not supported. - -## See also - -[Introduction to Kong gRPC plugins](/gateway/latest/configure/grpc) diff --git a/app/_hub/kong-inc/grpc-gateway/_index.md b/app/_hub/kong-inc/grpc-gateway/_index.md index 6b90e4123ea0..f4bd2ab502c0 100644 --- a/app/_hub/kong-inc/grpc-gateway/_index.md +++ b/app/_hub/kong-inc/grpc-gateway/_index.md @@ -1,7 +1,6 @@ --- name: gRPC-gateway publisher: Kong Inc. -version: 0.2.x categories: - transformations type: plugin @@ -10,29 +9,12 @@ description: | A Kong plugin to allow access to a gRPC service via HTTP REST requests and translate requests and responses in a JSON format. Similar to [gRPC-gateway](https://grpc-ecosystem.github.io/grpc-gateway/). -source_url: 'https://github.com/Kong/kong-plugin-grpc-gateway' license_type: MIT kong_version_compatibility: community_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x + compatible: true enterprise_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x + compatible: true params: name: grpc-gateway route_id: true @@ -68,7 +50,7 @@ but proxies to a `Service` with the `grpc(s)` protocol. Sample configuration via declarative (YAML): ```yaml -_format_version: "1.1" +_format_version: "3.0" services: - protocol: grpc host: localhost @@ -86,24 +68,28 @@ services: Sample configuration via the Admin API: -```bash -$ # add the gRPC service -$ curl -X POST localhost:8001/services \ - --data name=grpc \ - --data protocol=grpc \ - --data host=localhost \ - --data port=9000 - -$ # add an http route -$ curl -X POST localhost:8001/services/grpc/routes \ - --data protocols=http \ - --data name=web-service \ - --data paths[]=/ - -$ # add the plugin to the route -$ curl -X POST localhost:8001/routes/web-service/plugins \ - --data name=grpc-gateway -``` +1. Add the gRPC service: + ```sh + curl -X POST localhost:8001/services \ + --data name=grpc \ + --data protocol=grpc \ + --data host=localhost \ + --data port=9000 + ``` + +2. Add an `http` route: + ```sh + curl -X POST localhost:8001/services/grpc/routes \ + --data protocols=http \ + --data name=web-service \ + --data paths[]=/ + ``` + +3. Add the plugin to the route: + ```sh + curl -X POST localhost:8001/routes/web-service/plugins \ + --data name=grpc-gateway + ``` The proto file must contain the [HTTP REST to gRPC mapping rule](https://github.com/googleapis/googleapis/blob/fc37c47e70b83c1cc5cc1616c9a307c4303fe789/google/api/http.proto). @@ -161,6 +147,7 @@ curl -XPOST localhost:8000/v1/messages/Kong2.0 -d '{"name":"kong2.0"}' All syntax defined in [Path template syntax](https://github.com/googleapis/googleapis/blob/fc37c47e70b83c1cc5cc1616c9a307c4303fe789/google/api/http.proto#L225) is supported. +{% if_plugin_version gte:2.6.x %} Object fields not mentioned in the endpoint paths as in `/messages/{name}` can be passed as URL arguments, for example `/v1/messages?name=Kong`. Structured arguments are supported. For example, a request like the following: @@ -181,8 +168,17 @@ is interpreted like the following JSON object: Similarly, fields of the type `google.protobuf.Timestamp` are converted to and from strings in ISO8601 format. +{% endif_plugin_version %} + Currently only unary requests are supported; streaming requests are not supported. ## See also [Introduction to Kong gRPC plugins](/gateway/latest/configure/grpc) + +--- +## Changelog + +**{{site.base_gateway}} 2.6.x** +* Fields of type `.google.protobuf.Timestamp` on the gRPC side are now transcoded to and from ISO8601 strings on the REST side. +* URI arguments like `..?foo.bar=x&foo.baz=y` are interpreted as structured fields, equivalent to `{"foo": {"bar": "x", "baz": "y"}}`. diff --git a/app/_hub/kong-inc/grpc-gateway/versions.yml b/app/_hub/kong-inc/grpc-gateway/versions.yml index 6e09fadd023d..26e783019a0d 100644 --- a/app/_hub/kong-inc/grpc-gateway/versions.yml +++ b/app/_hub/kong-inc/grpc-gateway/versions.yml @@ -1 +1,12 @@ -- release: 0.1.x +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 0.2.0 + 2.7.x: 0.2.0 + 2.6.x: 0.2.0 + 2.5.x: 0.1.3 + 2.4.x: 0.1.3 + 2.3.x: 0.1.3 + 2.2.x: 0.1.3 + 2.1.x: 0.1.3 diff --git a/app/_hub/kong-inc/grpc-web/0.1.x.md b/app/_hub/kong-inc/grpc-web/0.1.x.md deleted file mode 100644 index a12abcd1446a..000000000000 --- a/app/_hub/kong-inc/grpc-web/0.1.x.md +++ /dev/null @@ -1,187 +0,0 @@ ---- -name: gRPC-Web -publisher: Kong Inc. -version: 0.1.x - -categories: - - transformations - -type: plugin - -desc: Allow browser clients to call gRPC services -description: | - A Kong plugin to allow access to a gRPC service via the [gRPC-Web protocol](https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-WEB.md#protocol-differences-vs-grpc-over-http2). - Primarily, this means JavaScript browser applications using the [gRPC-Web](https://github.com/grpc/grpc-web) library. - -source_url: https://github.com/Kong/kong-plugin-grpc-web - -license_type: MIT - -kong_version_compatibility: - community_edition: - compatible: - - 2.1.x - - enterprise_edition: - compatible: - - 2.1.x - - -params: - name: grpc-web - route_id: true - protocols: ["http", "https"] - dbless_compatible: 'yes' - - config: - - name: proto - required: false - default: - value_in_examples: path/to/hello.proto - description: | - If present, describes the gRPC types and methods. - Required to support payload transcoding. When absent, the - web client must use application/grpw-web+proto content. - ---- - -## Purpose - -A service that presents a gRPC API can be used by clients written in many languages, -but the network specifications are oriented primarily to connections within a -datacenter. [gRPC-Web] lets you expose the gRPC API to the Internet so -that it can be consumed by browser-based JavaScript applications. - -This plugin translates requests and responses between [gRPC-Web] and -[gRPC](https://github.com/grpc/grpc). The plugin supports both HTTP/1.1 -and HTTP/2, over plaintext (HTTP) and TLS (HTTPS) connections. - -## Usage - -This plugin should be enabled on a Kong Route that serves the `http(s)` protocol -but proxies to a Service with the `grpc(s)` protocol. - -Sample configuration via declarative (YAML): - -```yaml -_format_version: "1.1" -services: -- protocol: grpc - host: localhost - port: 9000 - routes: - - protocols: - - http - paths: - - / - plugins: - - name: grpc-web -``` - -Same thing via the Admin API: - -```bash -$ # add the gRPC service -$ curl -XPOST localhost:8001/services \ - --data name=grpc \ - --data protocol=grpc \ - --data host=localhost \ - --data port=9000 - -$ # add an http route -$ curl -XPOST localhost:8001/services/grpc/routes \ - --data protocols=http \ - --data name=web-service \ - --data paths=/ - -$ # add the plugin to the route -$ curl -XPOST localhost:8001/routes/web-service/plugins \ - --data name=grpc-web -``` - -In these examples, we don't set any configuration for the plugin. -This minimal setup works for the default varieties of the [gRPC-Web protocol], -which use ProtocolBuffer messages either directly in binary or with base64-encoding. -The related `Content-Type` headers are `application/grpc-web` or `application/grpc-web+proto` -for binary, and `application/grpc-web-text` or `application/grpc-web-text+proto` for text. - -If you want to use JSON encoding, you have to provide the gRPC specification in -a `.proto` file, which needs to be installed in the Kong node running the plugin. -A path starting with a `/` is considered absolute; otherwise, it will be interpreted -relative to the Kong node's prefix (`/usr/local/kong/` by default). For example: - -```protobuf -syntax = "proto2"; - -package hello; - -service HelloService { - rpc SayHello(HelloRequest) returns (HelloResponse); - rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse); - rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse); - rpc BidiHello(stream HelloRequest) returns (stream HelloResponse); -} - -message HelloRequest { - optional string greeting = 1; -} - -message HelloResponse { - required string reply = 1; -} -``` - -The declarative configuration becomes: - -```yaml -_format_version: "1.1" -services: -- protocol: grpc - host: localhost - port: 9000 - routes: - - protocols: - - http - paths: - - / - plugins: - - name: grpc-web - proto: path/to/hello.proto -``` - -or via the Admin API: - -```bash -$ # add the plugin to the route -$ curl -XPOST localhost:8001/routes/web-service/plugins \ - --data name=grpc-web \ - --data proto=path/to/hello.proto -``` - -With this setup, we can support gRPC-Web/JSON clients using `Content-Type` headers -like `application/grpc-web+json` or `application/grpc-web-text+json`. - -Note that even when using JSON encoding, the [gRPC-Web protocol] specifies that -both request and response data consist of a series of frames, in a similar way -to the full [gRPC protocol]. The [gRPC-Web] library performs this framing as expected. - -As an extension, this plugin also allows naked JSON requests with the POST method and -`Content-Type: application/json` header. These requests are encoded to ProtocolBuffer, -framed, and forwarded to the gRPC service. Likewise, the responses are transformed -on the way back, allowing any HTTP client to use a gRPC service without special -libraries. This feature is limited to unary (non-streaming) requests. Streaming -responses are encoded into multiple JSON objects; it's up to the client to split into -separate records if it has to support multiple response messages. - -## Related information -[Kong]: https://konghq.com -[gRPC protocol]: https://github.com/grpc/grpc -[gRPC-Web]: https://github.com/grpc/grpc-web -[gRPC-Web protocol]: https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-WEB.md#protocol-differences-vs-grpc-over-http2 -[lua-protobuf]: https://github.com/starwing/lua-protobuf -[lua-cjson]: https://github.com/openresty/lua-cjson -[lua-pack]: https://github.com/Kong/lua-pack - -## See also - -[Introduction to Kong gRPC plugins](/enterprise/2.1.x/plugins/grpc) diff --git a/app/_hub/kong-inc/grpc-web/0.2.x.md b/app/_hub/kong-inc/grpc-web/0.2.x.md deleted file mode 100644 index 28d949338370..000000000000 --- a/app/_hub/kong-inc/grpc-web/0.2.x.md +++ /dev/null @@ -1,202 +0,0 @@ ---- -name: gRPC-Web -publisher: Kong Inc. -version: 0.2.x - -categories: - - transformations - -type: plugin - -desc: Allow browser clients to call gRPC services -description: | - A Kong plugin to allow access to a gRPC service via the [gRPC-Web protocol](https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-WEB.md#protocol-differences-vs-grpc-over-http2). - Primarily, this means JavaScript browser applications using the [gRPC-Web](https://github.com/grpc/grpc-web) library. - -source_url: https://github.com/Kong/kong-plugin-grpc-web - -license_type: MIT - -kong_version_compatibility: - community_edition: - compatible: - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - enterprise_edition: - compatible: - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - -params: - name: grpc-web - route_id: true - protocols: ["http", "https"] - dbless_compatible: 'yes' - - config: - - name: proto - required: false - default: - value_in_examples: path/to/hello.proto - datatype: string - description: | - If present, describes the gRPC types and methods. - Required to support payload transcoding. When absent, the - web client must use application/grpw-web+proto content. - - name: pass_stripped_path - required: false - default: - value_in_examples: - datatype: boolean - description: - If set to `true` causes the plugin to pass the stripped request path to - the upstream gRPC service (see the `strip_path` Route attribute). - ---- - -## Purpose - -A service that presents a gRPC API can be used by clients written in many languages, -but the network specifications are oriented primarily to connections within a -datacenter. [gRPC-Web] lets you expose the gRPC API to the Internet so -that it can be consumed by browser-based JavaScript applications. - -This plugin translates requests and responses between [gRPC-Web] and -[gRPC](https://github.com/grpc/grpc). The plugin supports both HTTP/1.1 -and HTTP/2, over plaintext (HTTP) and TLS (HTTPS) connections. - -## Usage - -This plugin should be enabled on a Kong Route that serves the `http(s)` protocol -but proxies to a Service with the `grpc(s)` protocol. - -Sample configuration via declarative (YAML): - -```yaml -_format_version: "1.1" -services: -- protocol: grpc - host: localhost - port: 9000 - routes: - - protocols: - - http - paths: - - / - plugins: - - name: grpc-web -``` - -Same thing via the Admin API: - -```bash -$ # add the gRPC service -$ curl -X POST localhost:8001/services \ - --data name=grpc \ - --data protocol=grpc \ - --data host=localhost \ - --data port=9000 - -$ # add an http route -$ curl -X POST localhost:8001/services/grpc/routes \ - --data protocols=http \ - --data name=web-service \ - --data paths=/ - -$ # add the plugin to the route -$ curl -X POST localhost:8001/routes/web-service/plugins \ - --data name=grpc-web -``` - -In these examples, we don't set any configuration for the plugin. -This minimal setup works for the default varieties of the [gRPC-Web protocol], -which use ProtocolBuffer messages either directly in binary or with base64-encoding. -The related `Content-Type` headers are `application/grpc-web` or `application/grpc-web+proto` -for binary, and `application/grpc-web-text` or `application/grpc-web-text+proto` for text. - -If you want to use JSON encoding, you have to provide the gRPC specification in -a `.proto` file, which needs to be installed in the Kong node running the plugin. -A path starting with a `/` is considered absolute; otherwise, it will be interpreted -relative to the Kong node's prefix (`/usr/local/kong/` by default). For example: - -```protobuf -syntax = "proto2"; - -package hello; - -service HelloService { - rpc SayHello(HelloRequest) returns (HelloResponse); - rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse); - rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse); - rpc BidiHello(stream HelloRequest) returns (stream HelloResponse); -} - -message HelloRequest { - optional string greeting = 1; -} - -message HelloResponse { - required string reply = 1; -} -``` - -The declarative configuration becomes: - -```yaml -_format_version: "1.1" -services: -- protocol: grpc - host: localhost - port: 9000 - routes: - - protocols: - - http - paths: - - / - plugins: - - name: grpc-web - proto: path/to/hello.proto -``` - -or via the Admin API: - -```bash -$ # add the plugin to the route -$ curl -X POST localhost:8001/routes/web-service/plugins \ - --data name=grpc-web \ - --data proto=path/to/hello.proto -``` - -With this setup, we can support gRPC-Web/JSON clients using `Content-Type` headers -like `application/grpc-web+json` or `application/grpc-web-text+json`. - -Note that even when using JSON encoding, the [gRPC-Web protocol] specifies that -both request and response data consist of a series of frames, in a similar way -to the full [gRPC protocol]. The [gRPC-Web] library performs this framing as expected. - -As an extension, this plugin also allows naked JSON requests with the POST method and -`Content-Type: application/json` header. These requests are encoded to ProtocolBuffer, -framed, and forwarded to the gRPC service. Likewise, the responses are transformed -on the way back, allowing any HTTP client to use a gRPC service without special -libraries. This feature is limited to unary (non-streaming) requests. Streaming -responses are encoded into multiple JSON objects; it's up to the client to split into -separate records if it has to support multiple response messages. - -## Related information -[Kong]: https://konghq.com -[gRPC protocol]: https://github.com/grpc/grpc -[gRPC-Web]: https://github.com/grpc/grpc-web -[gRPC-Web protocol]: https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-WEB.md#protocol-differences-vs-grpc-over-http2 -[lua-protobuf]: https://github.com/starwing/lua-protobuf -[lua-cjson]: https://github.com/openresty/lua-cjson -[lua-pack]: https://github.com/Kong/lua-pack - -## See also - -[Introduction to Kong gRPC plugins](/gateway/latest/configure/grpc) diff --git a/app/_hub/kong-inc/grpc-web/_index.md b/app/_hub/kong-inc/grpc-web/_index.md index 2a8ea815ce61..9790b58b7464 100644 --- a/app/_hub/kong-inc/grpc-web/_index.md +++ b/app/_hub/kong-inc/grpc-web/_index.md @@ -1,7 +1,6 @@ --- name: gRPC-Web publisher: Kong Inc. -version: 0.3.x categories: - transformations type: plugin @@ -9,29 +8,12 @@ desc: Allow browser clients to call gRPC services description: | A Kong plugin to allow access to a gRPC service via the [gRPC-Web protocol](https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-WEB.md#protocol-differences-vs-grpc-over-http2). Primarily, this means JavaScript browser applications using the [gRPC-Web](https://github.com/grpc/grpc-web) library. -source_url: 'https://github.com/Kong/kong-plugin-grpc-web' license_type: MIT kong_version_compatibility: community_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x + compatible: true enterprise_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x + compatible: true params: name: grpc-web route_id: true @@ -50,12 +32,14 @@ params: Required to support payload transcoding. When absent, the web client must use application/grpw-web+proto content. - name: pass_stripped_path + minimum_version: "2.2.x" required: false default: null value_in_examples: null datatype: boolean description: If set to `true` causes the plugin to pass the stripped request path to the upstream gRPC service (see the `strip_path` Route attribute). - name: allow_origin_header + minimum_version: "2.5.x" required: false datatype: string default: '*' @@ -71,7 +55,7 @@ params: A service that presents a gRPC API can be used by clients written in many languages, but the network specifications are oriented primarily to connections within a -datacenter. [gRPC-Web] lets you expose the gRPC API to the Internet so +data center. [gRPC-Web] lets you expose the gRPC API to the Internet so that it can be consumed by browser-based JavaScript applications. This plugin translates requests and responses between [gRPC-Web] and @@ -86,7 +70,7 @@ but proxies to a Service with the `grpc(s)` protocol. Sample configuration via declarative (YAML): ```yaml -_format_version: "1.1" +_format_version: "3.0" services: - protocol: grpc host: localhost @@ -102,24 +86,28 @@ services: Same thing via the Admin API: -```bash -$ # add the gRPC service -$ curl -X POST localhost:8001/services \ - --data name=grpc \ - --data protocol=grpc \ - --data host=localhost \ - --data port=9000 - -$ # add an http route -$ curl -X POST localhost:8001/services/grpc/routes \ - --data protocols=http \ - --data name=web-service \ - --data paths=/ - -$ # add the plugin to the route -$ curl -X POST localhost:8001/routes/web-service/plugins \ - --data name=grpc-web -``` +1. Add the gRPC service: + ```sh + curl -X POST localhost:8001/services \ + --data name=grpc \ + --data protocol=grpc \ + --data host=localhost \ + --data port=9000 + ``` + +2. Add an `http` route: + ```sh + curl -X POST localhost:8001/services/grpc/routes \ + --data protocols=http \ + --data name=web-service \ + --data paths[]=/ + ``` + +3. Add the plugin to the route: + ```sh + curl -X POST localhost:8001/routes/web-service/plugins \ + --data name=grpc-web + ``` In these examples, we don't set any plugin configurations. This minimal setup works for the default varieties of the [gRPC-Web protocol](https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-WEB.md#protocol-differences-vs-grpc-over-http2), @@ -129,7 +117,7 @@ for binary, and `application/grpc-web-text` or `application/grpc-web-text+proto` If you want to use JSON encoding, you have to provide the gRPC specification in a `.proto` file, which needs to be installed in the Kong node running the plugin. -A path starting with a `/` is considered absolute; otherwise, it interprets +A path starting with a `/` is considered absolute; otherwise, it interprets relative to the Kong node's prefix (`/usr/local/kong/` by default). For example: ```protobuf @@ -156,7 +144,7 @@ message HelloResponse { The declarative configuration becomes: ```yaml -_format_version: "1.1" +_format_version: "3.0" services: - protocol: grpc host: localhost @@ -174,8 +162,7 @@ services: or via the Admin API: ```bash -$ # add the plugin to the route -$ curl -X POST localhost:8001/routes/web-service/plugins \ +curl -X POST localhost:8001/routes/web-service/plugins \ --data name=grpc-web \ --data proto=path/to/hello.proto ``` @@ -207,3 +194,12 @@ separate records if it has to support multiple response messages. ## See also [Introduction to Kong gRPC plugins](/gateway/latest/configure/grpc) + +--- +## Changelog + +**{{site.base_gateway}} 2.5.x** +* Added support for setting the `Access-Control-Allow-Origin` header. + +**{{site.base_gateway}} 2.2.x** +* Added the `pass_stripped_path` configuration parameter, which, if set to true, causes the plugin to pass the stripped request path to the upstream gRPC service. diff --git a/app/_hub/kong-inc/grpc-web/versions.yml b/app/_hub/kong-inc/grpc-web/versions.yml index f14b54143820..0eedacc724f3 100644 --- a/app/_hub/kong-inc/grpc-web/versions.yml +++ b/app/_hub/kong-inc/grpc-web/versions.yml @@ -1,3 +1,12 @@ -- release: 0.3.x -- release: 0.2.x -- release: 0.1.x +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 0.3.0 + 2.7.x: 0.3.0 + 2.6.x: 0.3.0 + 2.5.x: 0.2.0 + 2.4.x: 0.2.0 + 2.3.x: 0.2.0 + 2.2.x: 0.2.0 + 2.1.x: 0.1.0 diff --git a/app/_hub/kong-inc/hmac-auth/0.1-x.md b/app/_hub/kong-inc/hmac-auth/0.1-x.md deleted file mode 100644 index 0c33746bddcd..000000000000 --- a/app/_hub/kong-inc/hmac-auth/0.1-x.md +++ /dev/null @@ -1,469 +0,0 @@ ---- -name: HMAC Authentication -publisher: Kong Inc. -version: 0.1-x - -desc: Add HMAC Authentication to your APIs -description: | - Add HMAC Signature authentication to a Service or a Route (or the deprecated API entity) - to establish the integrity of incoming requests. The plugin will validate the - digital signature sent in the `Proxy-Authorization` or `Authorization` header - (in this order). This plugin implementation is based off the - [draft-cavage-http-signatures](https://tools.ietf.org/html/draft-cavage-http-signatures) - draft with a slightly different signature scheme. - -
- Note: The functionality of this plugin as bundled - with versions of Kong prior to 0.14.0 and Kong Gateway prior to 0.34 - differs from what is documented herein. Refer to the - CHANGELOG - for details. -
- - -type: plugin -categories: - - authentication - -kong_version_compatibility: - community_edition: - compatible: - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x - enterprise_edition: - compatible: - - 0.34-x - - 0.33-x - - 0.32-x - - 0.31-x - -params: - name: hmac-auth - api_id: true - service_id: true - route_id: true - consumer_id: false - config: - - name: hide_credentials - required: false - default: "`false`" - description: | - An optional boolean value telling the plugin to show or hide the credential from the upstream service. If `true`, the plugin will strip the credential from the request (i.e. the `Authorization` header) before proxying it. - - name: clock_skew - required: false - default: "`300`" - description: | - [Clock Skew](https://tools.ietf.org/html/draft-cavage-http-signatures-00#section-3.4) in seconds to prevent replay attacks. - - name: anonymous - required: false - default: - description: | - An optional string (consumer uuid) value to use as an "anonymous" consumer if authentication fails. If empty (default), the request will fail with an authentication failure `4xx`. Please note that this value must refer to the Consumer `id` attribute which is internal to Kong, and **not** its `custom_id`. - - name: validate_request_body - required: false - default: "`false`" - description: A boolean value telling the plugin to enable body validation - - name: enforce_headers - required: false - default: - description: A list of headers which the client should at least use for HTTP signature creation - - name: algorithms - required: false - default: "`hmac-sha1`,
`hmac-sha256`,
`hmac-sha384`,
`hmac-sha512`" - description: | - A list of HMAC digest algorithms which the user wants to support. Allowed values are `hmac-sha1`, `hmac-sha256`, `hmac-sha384`, and `hmac-sha512` - extra: | - Once applied, any user with a valid credential can access the Service/API. - To restrict usage to only some of the authenticated users, also add the - [ACL](/plugins/acl/) plugin (not covered here) and create whitelist or - blacklist groups of users. - ---- - -## Usage - -In order to use the plugin, you first need to create a Consumer to associate -one or more credentials to. - -Note: Because the HMAC signature is generated by the client, you should make sure that Kong does not -update or remove any request parameter used in HMAC signature before this plugin runs. - -### Create a Consumer - -You need to associate a credential to an existing [Consumer][consumer-object] -object. To create a Consumer, you can execute the following request: - -```bash -$ curl -d "username=user123&custom_id=SOME_CUSTOM_ID" http://kong:8001/consumers/ -``` - -parameter | description ---- | --- -`username`
*semi-optional* | The username of the consumer. Either this field or `custom_id` must be specified. -`custom_id`
*semi-optional* | A custom identifier used to map the consumer to another database. Either this field or `username` must be specified. - -A [Consumer][consumer-object] can have many credentials. - -### Create a Credential - -You can provision new username/password credentials by making the following -HTTP request: - -```bash -$ curl -X POST http://kong:8001/consumers/{consumer}/hmac-auth \ - --data "username=bob" \ - --data "secret=secret456" -``` - -`consumer`: The `id` or `username` property of the [Consumer][consumer-object] -entity to associate the credentials to. - -form parameter | description ---- | --- -`username` | The username to use in the HMAC Signature verification. -`secret`
*optional* | The secret to use in the HMAC Signature verification. Note that if this parameter isn't provided, Kong will generate a value for you and send it as part of the response body. - -### Signature Authentication Scheme - -The client is expected to send an `Authorization` or `Proxy-Authorization` header -with the following parameterization: - -``` -credentials := "hmac" params -params := keyId "," algorithm ", " headers ", " signature -keyId := "username" "=" plain-string -algorithm := "algorithm" "=" DQUOTE (hmac-sha1|hmac-sha256|hmac-sha384|hmac-sha512) DQUOTE -headers := "headers" "=" plain-string -signature := "signature" "=" plain-string -plain-string = DQUOTE *( %x20-21 / %x23-5B / %x5D-7E ) DQUOTE -``` - -### Signature Parameters - -parameter| description ---- | --- -username | The `username` of the credential -algorithm | Digital signature algorithm used to create the signature -headers | List of HTTP header names, separated by a single space character, used to sign the request -signature | `Base64` encoded digital signature generated by the client - -### Signature String Construction - -In order to generate the string that is signed with a key, the client -MUST take the values of each HTTP header specified by `headers` in -the order they appear. - -1. If the header name is not `request-line` then append the - lowercased header name followed with an ASCII colon `:` and an - ASCII space ` `. - -2. If the header name is `request-line` then append the HTTP - request line (in ASCII format), otherwise append the header value. - -3. If value is not the last value then append an ASCII newline `\n`. - The string MUST NOT include a trailing ASCII newline. - -### Clock Skew - -The HMAC Authentication plugin also implements a clock skew check as described -in the [specification][clock-skew] to prevent replay attacks. By default, -a minimum lag of 300s in either direction (past/future) is allowed. Any request -with a higher or lower date value will be rejected. The length of the clock -skew can be edited through the plugin's configuration by setting the -`clock_skew` property (`config.clock_skew` POST parameters). - -The server and requesting client should be synchronized with NTP and a valid -date (using GMT format) should be sent with either the `X-Date` or `Date` -header. - -### Body Validation - -User can set `config.validate_request_body` as `true` to validate the request -body. If it's enabled the plugin will calculate the `SHA-256` HMAC digest of -the request body and match it against the value of the `Digest` header. The -Digest header needs to be in following format: - -``` -Digest: SHA-256=base64(sha256()) -``` - -If there is no request body, the `Digest` should be set to the digest of a -body of 0 length. - -Note: In order to create the digest of a request body, the plugin needs to -retain it in memory, which might cause pressure on the worker's Lua VM when -dealing with large bodies (several MBs) or during high request concurrency. - -### Enforcing Headers - -`config.enforce_headers` can be used to enforce any of the headers to be part -of the signature creation. By default, the plugin doesn't enforce which header -needs to be used for the signature creation. The minimum recommended data to -sign is the `request-line`, `host`, and `date`. A strong signature would -include all of the headers and a `digest` of the body. - -### HMAC Example - -The HMAC plugin can be enabled on a Service or a Route (or the deprecated API entity). - - **Create a Service** - - ```bash - $ curl -i -X POST http://localhost:8001/services \ - -d "name=example-service" \ - -d "url=http://example.com" - HTTP/1.1 201 Created - ... - - ``` - - **Then create a Route** - - ```bash - $ curl -i -f -X POST http://localhost:8001/services/example-service/routes \ - -d "name=hmac-test" \ - -d "paths[]=/" - HTTP/1.1 201 Created - ... - - ``` - - - **Add an API** - -For versions below 0.13.0, you would use now-deprecated API entity: - - ```bash - $ curl -i -X POST http://localhost:8001/apis \ - -d "name=hmac-test" \ - -d "hosts=hmac.com" \ - -d "upstream_url=http://example.com" - HTTP/1.1 201 Created - ... - - ``` - - **Enabling the plugin on a Service** - - Plugins can be enabled on a Service or a Route. This example uses a Service. - - ```bash - $ curl -i -X POST http://localhost:8001/services/example-service/plugins \ - -d "name=hmac-auth" \ - -d "config.enforce_headers=date, request-line" \ - -d "config.algorithms=hmac-sha1, hmac-sha256" - HTTP/1.1 201 Created - ... - - ``` - - **Enabling the plugin on an API** - - ```bash - $ curl -i -X POST http://localhost:8001/apis/hmac-test/plugins \ - -d "name=hmac-auth" \ - -d "config.enforce_headers=date, request-line" \ - -d "config.algorithms=hmac-sha1, hmac-sha256" - HTTP/1.1 201 Created - ... - - ``` - - Here we are enabling the `hmac-auth` plugin on API the `hmac-test`. - `config.enforce_headers` is set to force the client to at least use `date` - and `request-line` in the HTTP signature creation. Also we are setting the - `config.algorithms` to force the client to only use `hmac-sha1` or - `hmac-sha256` for hashing the signing string. - - **Add a Consumer** - - ```bash - $ curl -i -X POST http://localhost:8001/consumers/ \ - -d "username=alice" - HTTP/1.1 201 Created - ... - - ``` - - **Add credential for Alice** - - ```bash - $ curl -i -X POST http://localhost:8001/consumers/alice/hmac-auth \ - -d "username=alice123" \ - -d "secret=secret" - HTTP/1.1 201 Created - ... - - ``` - - **Request to the API** - - ```bash - $ curl -i -X GET http://localhost:8000/requests \ - -H "Host: hmac.com" \ - -H "Date: Thu, 22 Jun 2017 17:15:21 GMT" \ - -H 'Authorization: hmac username="alice123", algorithm="hmac-sha256", headers="date request-line", signature="ujWCGHeec9Xd6UD2zlyxiNMCiXnDOWeVFMu5VeRUxtw="' - HTTP/1.1 200 OK - ... - - ``` - - In the above request, we are composing the signing string using the `date` and - `request-line` headers and creating the digest using the `hmac-sha256` to - hash the digest: - - ``` - signing_string="date: Thu, 22 Jun 2017 17:15:21 GMT\nGET /requests HTTP/1.1" - digest=HMAC-SHA256(, "secret") - base64_digest=base64() - ``` - - So the final value of the `Authorization` header would look like: - - - ``` - Authorization: hmac username="alice123", algorithm="hmac-sha256", headers="date request-line", signature=" - ``` - - **Validating request body** - - To enable body validation we would need to set `config.validate_request_body` - to `true`: - - The following example works the same way, whether the plugin was added to - a Service or a Route (or an API). - - ```bash - $ curl -i -X PATCH http://localhost:8001/plugins/{plugin-id} \ - -d "config.validate_request_body=true" - HTTP/1.1 200 OK - ... - - ``` - - Now if the client includes the body digest in the request as the value of the - `Digest` header, the plugin will validate the request body by calculating the - `SHA-256` of the body and matching it against the `Digest` header's value. - - ```bash - $ curl -i -X GET http://localhost:8000/requests \ - -H "Host: hmac.com" \ - -H "Date: Thu, 22 Jun 2017 21:12:36 GMT" \ - -H "Digest: SHA-256=SBH7QEtqnYUpEcIhDbmStNd1MxtHg2+feBfWc1105MA=" \ - -H 'Authorization: hmac username="alice123", algorithm="hmac-sha256", headers="date request-line digest", signature="gaweQbATuaGmLrUr3HE0DzU1keWGCt3H96M28sSHTG8="' \ - -d "A small body" - HTTP/1.1 200 OK - ... - - ``` - - In the above request we calculated the `SHA-256` digest of the body and set - the `Digest` header with the following format: - - ``` - body="A small body" - digest=SHA-256(body) - base64_digest=base64(digest) - Digest: SHA-256= - ``` - -### Upstream Headers - -When a client has been authenticated, the plugin will append some headers to -the request before proxying it to the upstream service, so that you -can identify the Consumer in your code: - -* `X-Consumer-ID`, the ID of the Consumer on Kong -* `X-Consumer-Custom-ID`, the `custom_id` of the Consumer (if set) -* `X-Consumer-Username`, the `username` of the Consumer (if set) -* `X-Credential-Username`, the `username` of the Credential (only if the consumer is not the 'anonymous' consumer) -* `X-Anonymous-Consumer`, will be set to `true` when authentication failed, and the 'anonymous' consumer was set instead. - -You can use this information on your side to implement additional logic. -You can use the `X-Consumer-ID` value to query the Kong Admin API and retrieve -more information about the Consumer. - -### Paginate through the HMAC Credentials - -
- Note: This endpoint was introduced in Kong 0.11.2. -
- -You can paginate through the hmac-auth Credentials for all Consumers using the -following request: - -```bash -$ curl -X GET http://kong:8001/hmac-auths - -{ - "total": 3, - "data": [ - { - "created_at": 1509681246000, - "id": "75695322-e8a0-4109-aed4-5416b0308d85", - "secret": "wQazJ304DW5huJklHgUfjfiSyCyTAEDZ", - "username": "foo", - "consumer_id": "c0d92ba9-8306-482a-b60d-0cfdd2f0e880" - }, - { - "created_at": 1509419793000, - "id": "11d5cbfb-31b9-4a6d-8496-2f4a76500643", - "secret": "zi6YHyvLaUCe21XMXKesTYiHSWy6m6CW", - "username": "bar", - "consumer_id": "3c2c8fc1-7245-4fbb-b48b-e5947e1ce941" - }, - { - "created_at": 1509681215000, - "id": "eb0365bc-88ae-4568-be7c-db1eb7c16e5e", - "secret": "NvHDTg5mp0ySFVJsITurtgyhEq1Cxbnv", - "username": "baz", - "consumer_id": "c0d92ba9-8306-482a-b60d-0cfdd2f0e880" - } - ] -} -``` - -You can filter the list using the following query parameters: - -Attributes | Description ----:| --- -`id`
*optional* | A filter on the list based on the hmac-auth credential `id` field. -`username`
*optional* | A filter on the list based on the hmac-auth credential `username` field. -`consumer_id`
*optional* | A filter on the list based on the hmac-auth credential `consumer_id` field. -`size`
*optional, default is __100__* | A limit on the number of objects to be returned. -`offset`
*optional* | A cursor used for pagination. `offset` is an object identifier that defines a place in the list. - -### Retrieve the Consumer associated with a Credential - -
- Note: This endpoint was introduced in Kong 0.11.2. -
- -It is possible to retrieve a [Consumer][consumer-object] associated with an -HMAC Credential using the following request: - -```bash -curl -X GET http://kong:8001/hmac-auths/{hmac username or id}/consumer - -{ - "created_at":1507936639000, - "username":"foo", - "id":"c0d92ba9-8306-482a-b60d-0cfdd2f0e880" -} -``` - -`hmac username or id`: The `id` or `username` property of the HMAC Credential -for which to get the associated [Consumer][consumer-object]. -Note that `username` accepted here is **not** the `username` property of a -Consumer. - -[consumer-object]: /gateway/latest/admin-api/#consumer-object -[clock-skew]: https://tools.ietf.org/html/draft-cavage-http-signatures-00#section-3.4 diff --git a/app/_hub/kong-inc/hmac-auth/2.1-x.md b/app/_hub/kong-inc/hmac-auth/2.1-x.md deleted file mode 100644 index 494645a419b2..000000000000 --- a/app/_hub/kong-inc/hmac-auth/2.1-x.md +++ /dev/null @@ -1,492 +0,0 @@ ---- -name: HMAC Authentication -publisher: Kong Inc. -version: 1.0.0 - -desc: Add HMAC Authentication to your Services -description: | - Add HMAC Signature authentication to a Service or a Route - to establish the integrity of incoming requests. The plugin will validate the - digital signature sent in the `Proxy-Authorization` or `Authorization` header - (in this order). This plugin implementation is based off the - [draft-cavage-http-signatures](https://tools.ietf.org/html/draft-cavage-http-signatures) - draft with a slightly different signature scheme. - -
- Note: The functionality of this plugin as bundled - with versions of Kong prior to 0.14.0 and Kong Gateway prior to 0.34 - differs from what is documented herein. Refer to the - CHANGELOG - for details. -
- - -type: plugin -categories: - - authentication - -kong_version_compatibility: - community_edition: - compatible: - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x - enterprise_edition: - compatible: - - 1.5.x - - 1.3-x - - 0.36-x - - 0.35-x - - 0.34-x - - 0.33-x - - 0.32-x - - 0.31-x - -params: - name: hmac-auth - service_id: true - route_id: true - consumer_id: false - protocols: ["http", "https"] - dbless_compatible: partially - dbless_explanation: | - Consumers and Credentials can be created with declarative configuration. - - Admin API endpoints which do POST, PUT, PATCH or DELETE on Credentials will not work on DB-less mode. - config: - - name: hide_credentials - required: false - default: "`false`" - description: | - An optional boolean value telling the plugin to show or hide the credential from the upstream service. If `true`, the plugin will strip the credential from the request (i.e. the `Authorization` header) before proxying it. - - name: clock_skew - required: false - default: "`300`" - description: | - [Clock Skew](https://tools.ietf.org/html/draft-cavage-http-signatures-00#section-3.4) in seconds to prevent replay attacks. - - name: anonymous - required: false - default: - description: | - An optional string (consumer uuid) value to use as an "anonymous" consumer if authentication fails. If empty (default), the request will fail with an authentication failure `4xx`. Please note that this value must refer to the Consumer `id` attribute which is internal to Kong, and **not** its `custom_id`. - - name: validate_request_body - required: false - default: "`false`" - description: A boolean value telling the plugin to enable body validation - - name: enforce_headers - required: false - default: - description: A list of headers which the client should at least use for HTTP signature creation - - name: algorithms - required: false - default: "`hmac-sha1`,
`hmac-sha256`,
`hmac-sha384`,
`hmac-sha512`" - description: | - A list of HMAC digest algorithms which the user wants to support. Allowed values are `hmac-sha1`, `hmac-sha256`, `hmac-sha384`, and `hmac-sha512` - extra: | - Once applied, any user with a valid credential can access the Service/Route. - To restrict usage to only some of the authenticated users, also add the - [ACL](/plugins/acl/) plugin (not covered here) and create whitelist or - blacklist groups of users. - ---- - -## Usage - -In order to use the plugin, you first need to create a Consumer to associate -one or more credentials to. - -Note: Because the HMAC signature is generated by the client, you should make sure that Kong does not -update or remove any request parameter used in HMAC signature before this plugin runs. - -### Create a Consumer - -You need to associate a credential to an existing [Consumer][consumer-object] object. -A Consumer can have many credentials. - -{% navtabs %} -{% navtab With a Database %} -To create a Consumer, you can execute the following request: - -```bash -curl -d "username=user123&custom_id=SOME_CUSTOM_ID" http://kong:8001/consumers/ -``` -{% endnavtab %} -{% navtab Without a Database %} -Your declarative configuration file will need to have one or more Consumers. You can create them -on the `consumers:` yaml section: - -``` yaml -consumers: -- username: user123 - custom_id: SOME_CUSTOM_ID -``` -{% endnavtab %} -{% endnavtabs %} - -In both cases, the parameters are as described below: - -parameter | description ---- | --- -`username`
*semi-optional* | The username of the consumer. Either this field or `custom_id` must be specified. -`custom_id`
*semi-optional* | A custom identifier used to map the consumer to another database. Either this field or `username` must be specified. - -### Create a Credential - -{% navtabs %} -{% navtab With a database %} -You can provision new username/password credentials by making the following -HTTP request: - -```bash -$ curl -X POST http://kong:8001/consumers/{consumer}/hmac-auth \ - --data "username=bob" \ - --data "secret=secret456" -``` -{% endnavtab %} -{% navtab Without a database %} -You can add credentials on your declarative config file on the `hmacauth_credentials` yaml entry: - -``` yaml -hmacauth_credentials: -- consumer: {consumer} - username: bob - secret: secret456 -``` -{% endnavtab %} -{% endnavtabs %} - -In both cases the fields/parameters work as follows: - -field/parameter | description ---- | --- -`{consumer}` | The `id` or `username` property of the [Consumer][consumer-object] entity to associate the credentials to. -`username` | The username to use in the HMAC Signature verification. -`secret`
*optional* | The secret to use in the HMAC Signature verification. Note that if this parameter isn't provided, Kong will generate a value for you and send it as part of the response body. - -### Signature Authentication Scheme - -The client is expected to send an `Authorization` or `Proxy-Authorization` header -with the following parameterization: - -``` -credentials := "hmac" params -params := keyId "," algorithm ", " headers ", " signature -keyId := "username" "=" plain-string -algorithm := "algorithm" "=" DQUOTE (hmac-sha1|hmac-sha256|hmac-sha384|hmac-sha512) DQUOTE -headers := "headers" "=" plain-string -signature := "signature" "=" plain-string -plain-string = DQUOTE *( %x20-21 / %x23-5B / %x5D-7E ) DQUOTE -``` - -### Signature Parameters - -parameter| description ---- | --- -username | The `username` of the credential -algorithm | Digital signature algorithm used to create the signature -headers | List of HTTP header names, separated by a single space character, used to sign the request -signature | `Base64` encoded digital signature generated by the client - -### Signature String Construction - -In order to generate the string that is signed with a key, the client -MUST take the values of each HTTP header specified by `headers` in -the order they appear. - -1. If the header name is not `request-line` then append the - lowercased header name followed with an ASCII colon `:` and an - ASCII space ` `. - -2. If the header name is `request-line` then append the HTTP - request line (in ASCII format), otherwise append the header value. - -3. If value is not the last value then append an ASCII newline `\n`. - The string MUST NOT include a trailing ASCII newline. - -### Clock Skew - -The HMAC Authentication plugin also implements a clock skew check as described -in the [specification][clock-skew] to prevent replay attacks. By default, -a minimum lag of 300s in either direction (past/future) is allowed. Any request -with a higher or lower date value will be rejected. The length of the clock -skew can be edited through the plugin's configuration by setting the -`clock_skew` property (`config.clock_skew` POST parameters). - -The server and requesting client should be synchronized with NTP and a valid -date (using GMT format) should be sent with either the `X-Date` or `Date` -header. - -### Body Validation - -User can set `config.validate_request_body` as `true` to validate the request -body. If it's enabled the plugin will calculate the `SHA-256` HMAC digest of -the request body and match it against the value of the `Digest` header. The -Digest header needs to be in following format: - -``` -Digest: SHA-256=base64(sha256()) -``` - -If there is no request body, the `Digest` should be set to the digest of a -body of 0 length. - -Note: In order to create the digest of a request body, the plugin needs to -retain it in memory, which might cause pressure on the worker's Lua VM when -dealing with large bodies (several MBs) or during high request concurrency. - -### Enforcing Headers - -`config.enforce_headers` can be used to enforce any of the headers to be part -of the signature creation. By default, the plugin doesn't enforce which header -needs to be used for the signature creation. The minimum recommended data to -sign is the `request-line`, `host`, and `date`. A strong signature would -include all of the headers and a `digest` of the body. - -### HMAC Example - -The HMAC plugin can be enabled on a Service or a Route. - - **Create a Service** - - ```bash - $ curl -i -X POST http://localhost:8001/services \ - -d "name=example-service" \ - -d "url=http://example.com" - HTTP/1.1 201 Created - ... - - ``` - - **Then create a Route** - - ```bash - $ curl -i -f -X POST http://localhost:8001/services/example-service/routes \ - -d "paths[]=/" - HTTP/1.1 201 Created - ... - - ``` - - **Enabling the plugin on a Service** - - Plugins can be enabled on a Service or a Route. This example uses a Service. - - ```bash - $ curl -i -X POST http://localhost:8001/services/example-service/plugins \ - -d "name=hmac-auth" \ - -d "config.enforce_headers=date, request-line" \ - -d "config.algorithms=hmac-sha1, hmac-sha256" - HTTP/1.1 201 Created - ... - - ``` - - **Add a Consumer** - - ```bash - $ curl -i -X POST http://localhost:8001/consumers/ \ - -d "username=alice" - HTTP/1.1 201 Created - ... - - ``` - - **Add credential for Alice** - - ```bash - $ curl -i -X POST http://localhost:8001/consumers/alice/hmac-auth \ - -d "username=alice123" \ - -d "secret=secret" - HTTP/1.1 201 Created - ... - - ``` - - **Making an authorized request** - - ```bash - $ curl -i -X GET http://localhost:8000/requests \ - -H "Host: hmac.com" \ - -H "Date: Thu, 22 Jun 2017 17:15:21 GMT" \ - -H 'Authorization: hmac username="alice123", algorithm="hmac-sha256", headers="date request-line", signature="ujWCGHeec9Xd6UD2zlyxiNMCiXnDOWeVFMu5VeRUxtw="' - HTTP/1.1 200 OK - ... - - ``` - - In the above request, we are composing the signing string using the `date` and - `request-line` headers and creating the digest using the `hmac-sha256` to - hash the digest: - - ``` - signing_string="date: Thu, 22 Jun 2017 17:15:21 GMT\nGET /requests HTTP/1.1" - digest=HMAC-SHA256(, "secret") - base64_digest=base64() - ``` - - So the final value of the `Authorization` header would look like: - - - ``` - Authorization: hmac username="alice123", algorithm="hmac-sha256", headers="date request-line", signature=" - ``` - - **Validating request body** - - To enable body validation we would need to set `config.validate_request_body` - to `true`: - - The following example works the same way, whether the plugin was added to - a Service or a Route. - - ```bash - $ curl -i -X PATCH http://localhost:8001/plugins/{plugin-id} \ - -d "config.validate_request_body=true" - HTTP/1.1 200 OK - ... - - ``` - - Now if the client includes the body digest in the request as the value of the - `Digest` header, the plugin will validate the request body by calculating the - `SHA-256` of the body and matching it against the `Digest` header's value. - - ```bash - $ curl -i -X GET http://localhost:8000/requests \ - -H "Host: hmac.com" \ - -H "Date: Thu, 22 Jun 2017 21:12:36 GMT" \ - -H "Digest: SHA-256=SBH7QEtqnYUpEcIhDbmStNd1MxtHg2+feBfWc1105MA=" \ - -H 'Authorization: hmac username="alice123", algorithm="hmac-sha256", headers="date request-line digest", signature="gaweQbATuaGmLrUr3HE0DzU1keWGCt3H96M28sSHTG8="' \ - -d "A small body" - HTTP/1.1 200 OK - ... - - ``` - - In the above request we calculated the `SHA-256` digest of the body and set - the `Digest` header with the following format: - - ``` - body="A small body" - digest=SHA-256(body) - base64_digest=base64(digest) - Digest: SHA-256= - ``` - -### Upstream Headers - -When a client has been authenticated, the plugin will append some headers to -the request before proxying it to the upstream service, so that you -can identify the Consumer in your code: - -* `X-Consumer-ID`, the ID of the Consumer on Kong -* `X-Consumer-Custom-ID`, the `custom_id` of the Consumer (if set) -* `X-Consumer-Username`, the `username` of the Consumer (if set) -* `X-Credential-Username`, the `username` of the Credential (only if the consumer is not the 'anonymous' consumer) -* `X-Anonymous-Consumer`, will be set to `true` when authentication failed, and the 'anonymous' consumer was set instead. - -You can use this information on your side to implement additional logic. -You can use the `X-Consumer-ID` value to query the Kong Admin API and retrieve -more information about the Consumer. - -### Paginate through the HMAC Credentials - -
- Note: This endpoint was introduced in Kong 0.11.2. -
- -You can paginate through the hmac-auth Credentials for all Consumers using the -following request: - -```bash -$ curl -X GET http://kong:8001/hmac-auths - -{ - "total": 3, - "data": [ - { - "created_at": 1509681246000, - "id": "75695322-e8a0-4109-aed4-5416b0308d85", - "secret": "wQazJ304DW5huJklHgUfjfiSyCyTAEDZ", - "username": "foo", - "consumer": { "id": "c0d92ba9-8306-482a-b60d-0cfdd2f0e880" } - }, - { - "created_at": 1509419793000, - "id": "11d5cbfb-31b9-4a6d-8496-2f4a76500643", - "secret": "zi6YHyvLaUCe21XMXKesTYiHSWy6m6CW", - "username": "bar", - "consumer": { "id": "3c2c8fc1-7245-4fbb-b48b-e5947e1ce941" } - }, - { - "created_at": 1509681215000, - "id": "eb0365bc-88ae-4568-be7c-db1eb7c16e5e", - "secret": "NvHDTg5mp0ySFVJsITurtgyhEq1Cxbnv", - "username": "baz", - "consumer": { "id": "c0d92ba9-8306-482a-b60d-0cfdd2f0e880" } - } - ] -} -``` - -You can filter the list by consumer by using this other path: - -```bash -$ curl -X GET http://kong:8001/consumers/{username or id}/hmac-auth - -{ - "total": 1, - "data": [ - { - "created_at": 1509419793000, - "id": "11d5cbfb-31b9-4a6d-8496-2f4a76500643", - "secret": "zi6YHyvLaUCe21XMXKesTYiHSWy6m6CW", - "username": "bar", - "consumer": { "id": "3c2c8fc1-7245-4fbb-b48b-e5947e1ce941" } - } - ] -} -``` - -`username or id`: The username or id of the consumer whose credentials need to be listed - -### Retrieve the Consumer associated with a Credential - -
- Note: This endpoint was introduced in Kong 0.11.2. -
- -It is possible to retrieve a [Consumer][consumer-object] associated with an -HMAC Credential using the following request: - -```bash -curl -X GET http://kong:8001/hmac-auths/{hmac username or id}/consumer - -{ - "created_at":1507936639000, - "username":"foo", - "id":"c0d92ba9-8306-482a-b60d-0cfdd2f0e880" -} -``` - -`hmac username or id`: The `id` or `username` property of the HMAC Credential -for which to get the associated [Consumer][consumer-object]. -Note that `username` accepted here is **not** the `username` property of a -Consumer. - -[consumer-object]: /gateway/latest/admin-api/#consumer-object -[clock-skew]: https://tools.ietf.org/html/draft-cavage-http-signatures-00#section-3.4 diff --git a/app/_hub/kong-inc/hmac-auth/2.4-x.md b/app/_hub/kong-inc/hmac-auth/2.4-x.md deleted file mode 100644 index 224b393fb17e..000000000000 --- a/app/_hub/kong-inc/hmac-auth/2.4-x.md +++ /dev/null @@ -1,505 +0,0 @@ ---- -name: HMAC Authentication -publisher: Kong Inc. -version: 1.0.0 - -desc: Add HMAC Authentication to your Services -description: | - Add HMAC Signature authentication to a Service or a Route - to establish the integrity of incoming requests. The plugin will validate the - digital signature sent in the `Proxy-Authorization` or `Authorization` header - (in this order). This plugin implementation is based off the - [draft-cavage-http-signatures](https://tools.ietf.org/html/draft-cavage-http-signatures) - draft with a slightly different signature scheme. - -
- Note: The functionality of this plugin as bundled - with versions of Kong prior to 0.14.0 and Kong Gateway prior to 0.34 - differs from what is documented herein. Refer to the - CHANGELOG - for details. -
- - -type: plugin -categories: - - authentication - -kong_version_compatibility: - community_edition: - compatible: - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x - enterprise_edition: - compatible: - - 1.5.x - - 1.3-x - - 0.36-x - - 0.35-x - - 0.34-x - - 0.33-x - - 0.32-x - - 0.31-x - -params: - name: hmac-auth - service_id: true - route_id: true - consumer_id: false - protocols: ["http", "https"] - dbless_compatible: partially - dbless_explanation: | - Consumers and Credentials can be created with declarative configuration. - - Admin API endpoints which do POST, PUT, PATCH or DELETE on Credentials will not work on DB-less mode. - config: - - name: hide_credentials - required: false - default: "`false`" - description: | - An optional boolean value telling the plugin to show or hide the credential from the upstream service. If `true`, the plugin will strip the credential from the request (i.e. the `Authorization` header) before proxying it. - - name: clock_skew - required: false - default: "`300`" - description: | - [Clock Skew](https://tools.ietf.org/html/draft-cavage-http-signatures-00#section-3.4) in seconds to prevent replay attacks. - - name: anonymous - required: false - default: - description: | - An optional string (consumer uuid) value to use as an "anonymous" consumer if authentication fails. If empty (default), the request will fail with an authentication failure `4xx`. Please note that this value must refer to the Consumer `id` attribute which is internal to Kong, and **not** its `custom_id`. - - name: validate_request_body - required: false - default: "`false`" - description: A boolean value telling the plugin to enable body validation - - name: enforce_headers - required: false - default: - description: A list of headers which the client should at least use for HTTP signature creation - - name: algorithms - required: false - default: "`hmac-sha1`,
`hmac-sha256`,
`hmac-sha384`,
`hmac-sha512`" - description: | - A list of HMAC digest algorithms which the user wants to support. Allowed values are `hmac-sha1`, `hmac-sha256`, `hmac-sha384`, and `hmac-sha512` - extra: | - Once applied, any user with a valid credential can access the Service/Route. - To restrict usage to only some of the authenticated users, also add the - [ACL](/plugins/acl/) plugin (not covered here) and create whitelist or - blacklist groups of users. - ---- - -## Usage - -In order to use the plugin, you first need to create a Consumer to associate -one or more credentials to. - -Note: Because the HMAC signature is generated by the client, you should make sure that Kong does not -update or remove any request parameter used in HMAC signature before this plugin runs. - -### Create a Consumer - -You need to associate a credential to an existing [Consumer][consumer-object] object. -A Consumer can have many credentials. - -{% navtabs %} -{% navtab With a database %} - -To create a Consumer, you can execute the following request: - -```bash -curl -d "username=user123&custom_id=SOME_CUSTOM_ID" http://kong:8001/consumers/ -``` -{% endnavtab %} -{% navtab Without a database %} -Your declarative configuration file will need to have one or more Consumers. You can create them -on the `consumers:` yaml section: - -``` yaml -consumers: -- username: user123 - custom_id: SOME_CUSTOM_ID -``` -{% endnavtab %} -{% endnavtabs %} - -In both cases, the parameters are as described below: - -parameter | description ---- | --- -`username`
*semi-optional* | The username of the consumer. Either this field or `custom_id` must be specified. -`custom_id`
*semi-optional* | A custom identifier used to map the consumer to another database. Either this field or `username` must be specified. - -### Create a Credential - -{% navtabs %} -{% navtab With a database %} -You can provision new username/password credentials by making the following -HTTP request: - -```bash -$ curl -X POST http://kong:8001/consumers/{consumer}/hmac-auth \ - --data "username=bob" \ - --data "secret=secret456" -``` - -{% endnavtab %} -{% navtab Without a database %} -You can add credentials on your declarative config file on the `hmacauth_credentials` yaml entry: - -``` yaml -hmacauth_credentials: -- consumer: {consumer} - username: bob - secret: secret456 -``` -{% endnavtab %} -{% endnavtabs %} - -In both cases the fields/parameters work as follows: - -field/parameter | description ---- | --- -`{consumer}` | The `id` or `username` property of the [Consumer][consumer-object] entity to associate the credentials to. -`username` | The username to use in the HMAC Signature verification. -`secret`
*optional* | The secret to use in the HMAC Signature verification. Note that if this parameter isn't provided, Kong will generate a value for you and send it as part of the response body. - -### Signature Authentication Scheme - -The client is expected to send an `Authorization` or `Proxy-Authorization` header -with the following parameterization: - -``` -credentials := "hmac" params -params := keyId "," algorithm ", " headers ", " signature -keyId := "username" "=" plain-string -algorithm := "algorithm" "=" DQUOTE (hmac-sha1|hmac-sha256|hmac-sha384|hmac-sha512) DQUOTE -headers := "headers" "=" plain-string -signature := "signature" "=" plain-string -plain-string = DQUOTE *( %x20-21 / %x23-5B / %x5D-7E ) DQUOTE -``` - -### Signature Parameters - -parameter| description ---- | --- -username | The `username` of the credential -algorithm | Digital signature algorithm used to create the signature -headers | List of HTTP header names, separated by a single space character, used to sign the request -signature | `Base64` encoded digital signature generated by the client - -### Signature String Construction - -To generate the string that is signed with a key, the client -MUST take the values of each HTTP header specified by `headers` in -the order they appear. - -1. If the header name is not `request-line` and not `@request-target` - then append the lowercased header name followed with an ASCII colon `:` and an - ASCII space ` `. - -2. If the header name is `request-line` then append the HTTP - request line (in ASCII format). - -3. If the header name is `@request-target`, - then append the lowercase request method, followed by a ASCII space ` ` - and the request URI including any query strings; otherwise append the header value. - -3. If value is not the last value then append an ASCII newline `\n`. - The string MUST NOT include a trailing ASCII newline. - - {:.warning} - > **Note:** The `@request-target` pseudo header was added in the 2.4.0 - version of the plugin release. It is similiar to the `request-line` pseudo header - except that the HTTP version was removed from the signature calculation. Otherwise, - semantically equivlent requests that uses HTTP/1.x and HTTP/2 will generate different - signature value. It is strongly recommended to use `@request-target` - instead of `request-line` with releases of this plugin after 2.4.0. - - -### Clock Skew - -The HMAC Authentication plugin also implements a clock skew check as described -in the [specification][clock-skew] to prevent replay attacks. By default, -a minimum lag of 300s in either direction (past/future) is allowed. Any request -with a higher or lower date value will be rejected. The length of the clock -skew can be edited through the plugin's configuration by setting the -`clock_skew` property (`config.clock_skew` POST parameters). - -The server and requesting client should be synchronized with NTP and a valid -date (using GMT format) should be sent with either the `X-Date` or `Date` -header. - -### Body Validation - -User can set `config.validate_request_body` as `true` to validate the request -body. If it's enabled the plugin will calculate the `SHA-256` HMAC digest of -the request body and match it against the value of the `Digest` header. The -Digest header needs to be in following format: - -``` -Digest: SHA-256=base64(sha256()) -``` - -If there is no request body, the `Digest` should be set to the digest of a -body of 0 length. - -Note: In order to create the digest of a request body, the plugin needs to -retain it in memory, which might cause pressure on the worker's Lua VM when -dealing with large bodies (several MBs) or during high request concurrency. - -### Enforcing Headers - -`config.enforce_headers` can be used to enforce any of the headers to be part -of the signature creation. By default, the plugin doesn't enforce which header -needs to be used for the signature creation. The minimum recommended data to -sign is the `@request-target`, `host`, and `date`. A strong signature would -include all of the headers and a `digest` of the body. - -### HMAC Example - -The HMAC plugin can be enabled on a Service or a Route. - - **Create a Service** - - ```bash - $ curl -i -X POST http://localhost:8001/services \ - -d "name=example-service" \ - -d "url=http://example.com" - HTTP/1.1 201 Created - ... - - ``` - - **Then create a Route** - - ```bash - $ curl -i -f -X POST http://localhost:8001/services/example-service/routes \ - -d "paths[]=/" - HTTP/1.1 201 Created - ... - - ``` - - **Enabling the plugin on a Service** - - Plugins can be enabled on a Service or a Route. This example uses a Service. - - ```bash - $ curl -i -X POST http://localhost:8001/services/example-service/plugins \ - -d "name=hmac-auth" \ - -d "config.enforce_headers=date, @request-target \ - -d "config.algorithms=hmac-sha1, hmac-sha256" - HTTP/1.1 201 Created - ... - - ``` - - **Add a Consumer** - - ```bash - $ curl -i -X POST http://localhost:8001/consumers/ \ - -d "username=alice" - HTTP/1.1 201 Created - ... - - ``` - - **Add credential for Alice** - - ```bash - $ curl -i -X POST http://localhost:8001/consumers/alice/hmac-auth \ - -d "username=alice123" \ - -d "secret=secret" - HTTP/1.1 201 Created - ... - - ``` - - **Making an authorized request** - - ```bash - $ curl -i -X GET http://localhost:8000/requests \ - -H "Host: hmac.com" \ - -H "Date: Thu, 22 Jun 2017 17:15:21 GMT" \ - -H 'Authorization: hmac username="alice123", algorithm="hmac-sha256", headers="date @request-target", signature="ujWCGHeec9Xd6UD2zlyxiNMCiXnDOWeVFMu5VeRUxtw="' - HTTP/1.1 200 OK - ... - - ``` - - In the above request, we are composing the signing string using the `date` and - `@request-target-line` headers and creating the digest using the `hmac-sha256` to - hash the digest: - - ``` - signing_string="date: Thu, 22 Jun 2017 17:15:21 GMT\nGET /requests HTTP/1.1" - digest=HMAC-SHA256(, "secret") - base64_digest=base64() - ``` - - So the final value of the `Authorization` header would look like: - - - ``` - Authorization: hmac username="alice123", algorithm="hmac-sha256", headers="date @request-target", signature=" - ``` - - **Validating request body** - - To enable body validation we would need to set `config.validate_request_body` - to `true`: - - The following example works the same way, whether the plugin was added to - a Service or a Route. - - ```bash - $ curl -i -X PATCH http://localhost:8001/plugins/{plugin-id} \ - -d "config.validate_request_body=true" - HTTP/1.1 200 OK - ... - - ``` - - Now if the client includes the body digest in the request as the value of the - `Digest` header, the plugin will validate the request body by calculating the - `SHA-256` of the body and matching it against the `Digest` header's value. - - ```bash - $ curl -i -X GET http://localhost:8000/requests \ - -H "Host: hmac.com" \ - -H "Date: Thu, 22 Jun 2017 21:12:36 GMT" \ - -H "Digest: SHA-256=SBH7QEtqnYUpEcIhDbmStNd1MxtHg2+feBfWc1105MA=" \ - -H 'Authorization: hmac username="alice123", algorithm="hmac-sha256", headers="date @request-target digest", signature="gaweQbATuaGmLrUr3HE0DzU1keWGCt3H96M28sSHTG8="' \ - -d "A small body" - HTTP/1.1 200 OK - ... - - ``` - - In the above request we calculated the `SHA-256` digest of the body and set - the `Digest` header with the following format: - - ``` - body="A small body" - digest=SHA-256(body) - base64_digest=base64(digest) - Digest: SHA-256= - ``` - -### Upstream Headers - -When a client has been authenticated, the plugin will append some headers to -the request before proxying it to the upstream service, so that you -can identify the Consumer in your code: - -* `X-Consumer-ID`, the ID of the Consumer on Kong -* `X-Consumer-Custom-ID`, the `custom_id` of the Consumer (if set) -* `X-Consumer-Username`, the `username` of the Consumer (if set) -* `X-Credential-Username`, the `username` of the Credential (only if the consumer is not the 'anonymous' consumer) -* `X-Anonymous-Consumer`, will be set to `true` when authentication failed, and the 'anonymous' consumer was set instead. - -You can use this information on your side to implement additional logic. -You can use the `X-Consumer-ID` value to query the Kong Admin API and retrieve -more information about the Consumer. - -### Paginate through the HMAC Credentials - -
- Note: This endpoint was introduced in Kong 0.11.2. - -You can paginate through the hmac-auth Credentials for all Consumers using the -following request: - -```bash -$ curl -X GET http://kong:8001/hmac-auths - -{ - "total": 3, - "data": [ - { - "created_at": 1509681246000, - "id": "75695322-e8a0-4109-aed4-5416b0308d85", - "secret": "wQazJ304DW5huJklHgUfjfiSyCyTAEDZ", - "username": "foo", - "consumer": { "id": "c0d92ba9-8306-482a-b60d-0cfdd2f0e880" } - }, - { - "created_at": 1509419793000, - "id": "11d5cbfb-31b9-4a6d-8496-2f4a76500643", - "secret": "zi6YHyvLaUCe21XMXKesTYiHSWy6m6CW", - "username": "bar", - "consumer": { "id": "3c2c8fc1-7245-4fbb-b48b-e5947e1ce941" } - }, - { - "created_at": 1509681215000, - "id": "eb0365bc-88ae-4568-be7c-db1eb7c16e5e", - "secret": "NvHDTg5mp0ySFVJsITurtgyhEq1Cxbnv", - "username": "baz", - "consumer": { "id": "c0d92ba9-8306-482a-b60d-0cfdd2f0e880" } - } - ] -} -``` - -You can filter the list by consumer by using this other path: - -```bash -$ curl -X GET http://kong:8001/consumers/{username or id}/hmac-auth - -{ - "total": 1, - "data": [ - { - "created_at": 1509419793000, - "id": "11d5cbfb-31b9-4a6d-8496-2f4a76500643", - "secret": "zi6YHyvLaUCe21XMXKesTYiHSWy6m6CW", - "username": "bar", - "consumer": { "id": "3c2c8fc1-7245-4fbb-b48b-e5947e1ce941" } - } - ] -} -``` - -`username or id`: The username or id of the consumer whose credentials need to be listed. - -### Retrieve the Consumer associated with a Credential - -{:.warning} - > **Note:** This endpoint was introduced in Kong 0.11.2. - -It is possible to retrieve a [Consumer][consumer-object] associated with an -HMAC Credential using the following request: - -```bash -curl -X GET http://kong:8001/hmac-auths/{hmac username or id}/consumer - -{ - "created_at":1507936639000, - "username":"foo", - "id":"c0d92ba9-8306-482a-b60d-0cfdd2f0e880" -} -``` - -`hmac username or id`: The `id` or `username` property of the HMAC Credential -for which to get the associated [Consumer][consumer-object]. -Note that `username` accepted here is **not** the `username` property of a -Consumer. - -[consumer-object]: /gateway/latest/admin-api/#consumer-object -[clock-skew]: https://tools.ietf.org/html/draft-cavage-http-signatures-00#section-3.4 diff --git a/app/_hub/kong-inc/hmac-auth/_index.md b/app/_hub/kong-inc/hmac-auth/_index.md index f6d83789e5c3..3be1fb054cd8 100644 --- a/app/_hub/kong-inc/hmac-auth/_index.md +++ b/app/_hub/kong-inc/hmac-auth/_index.md @@ -1,7 +1,6 @@ --- name: HMAC Authentication publisher: Kong Inc. -version: 2.2.0 desc: Add HMAC Authentication to your Services description: | Add HMAC Signature authentication to a Service or a Route @@ -15,45 +14,9 @@ categories: - authentication kong_version_compatibility: community_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x + compatible: true enterprise_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x + compatible: true params: name: hmac-auth service_id: true @@ -160,9 +123,9 @@ You can provision new username/password credentials by making the following HTTP request: ```bash -$ curl -X POST http://kong:8001/consumers/{consumer}/hmac-auth \ - --data "username=bob" \ - --data "secret=secret456" +curl -X POST http://kong:8001/consumers/{consumer}/hmac-auth \ + --data "username=bob" \ + --data "secret=secret456" ``` {% endnavtab %} @@ -190,7 +153,7 @@ field/parameter | description ### Signature Authentication Scheme The client is expected to send an `Authorization` or `Proxy-Authorization` header -with the following parameterization: +with the following: ``` credentials := "hmac" params @@ -211,6 +174,8 @@ algorithm | Digital signature algorithm used to create the signature headers | List of HTTP header names, separated by a single space character, used to sign the request signature | `Base64` encoded digital signature generated by the client +{% if_plugin_version lte:2.4.x %} + ### Signature String Construction In order to generate the string that is signed with a key, the client @@ -218,7 +183,7 @@ MUST take the values of each HTTP header specified by `headers` in the order they appear. 1. If the header name is not `request-line` then append the - lowercased header name followed with an ASCII colon `:` and an + lowercase header name followed with an ASCII colon `:` and an ASCII space ` `. 2. If the header name is `request-line` then append the HTTP @@ -227,6 +192,39 @@ the order they appear. 3. If value is not the last value then append an ASCII newline `\n`. The string MUST NOT include a trailing ASCII newline. +{% endif_plugin_version %} + +{% if_plugin_version gte:2.5.x %} +### Signature String Construction + +To generate the string that is signed with a key, the client +MUST take the values of each HTTP header specified by `headers` in +the order they appear. + +1. If the header name is not `request-line` or `@request-target`, + append the lowercase header name followed with an ASCII colon `:` and an + ASCII space ` `. + +2. If the header name is `request-line`, append the HTTP + request line (in ASCII format). + +3. If the header name is `@request-target`, append the lowercase request method, + followed by a ASCII space ` ` and the request URI including any query strings; + otherwise append the header value. + +3. If value is not the last value then append an ASCII newline `\n`. + The string MUST NOT include a trailing ASCII newline. + +{:.note} + > **Note:** The `@request-target` pseudo header was added in the 2.5.0 + version of the plugin release. It is similar to the `request-line` pseudo header + except that the HTTP version was removed from the signature calculation. Otherwise, + semantically equivalent requests that uses HTTP/1.x and HTTP/2 will generate different + signature value. It is strongly recommended to use `@request-target` + instead of `request-line` with releases of this plugin after 2.5.0. + +{% endif_plugin_version %} + ### Clock Skew The HMAC Authentication plugin also implements a clock skew check as described @@ -263,159 +261,137 @@ dealing with large bodies (several MBs) or during high request concurrency. `config.enforce_headers` can be used to enforce any of the headers to be part of the signature creation. By default, the plugin doesn't enforce which header needs to be used for the signature creation. The minimum recommended data to -sign is the `request-line`, `host`, and `date`. A strong signature would +sign is the `@request-target`, `host`, and `date`. A strong signature would include all of the headers and a `digest` of the body. ### HMAC Example -The HMAC plugin can be enabled on a Service or a Route. - - **Create a Service** - - ```bash - $ curl -i -X POST http://localhost:8001/services \ - -d "name=example-service" \ - -d "url=http://example.com" - HTTP/1.1 201 Created - ... - - ``` - - **Then create a Route** +The HMAC plugin can be enabled on a service or a route. This example uses a service. - ```bash - $ curl -i -f -X POST http://localhost:8001/services/example-service/routes \ - -d "paths[]=/" - HTTP/1.1 201 Created - ... +1. Enable the plugin on a service: - ``` + ```bash + curl -i -X POST http://localhost:8001/services/example-service/plugins \ + -d "name=hmac-auth" \ + -d "config.enforce_headers=date, @request-target" \ + -d "config.algorithms=hmac-sha1, hmac-sha256" + ``` - **Enabling the plugin on a Service** + Response: + ``` + HTTP/1.1 201 Created + ... + ``` - Plugins can be enabled on a Service or a Route. This example uses a Service. +2. Add a consumer: - ```bash - $ curl -i -X POST http://localhost:8001/services/example-service/plugins \ - -d "name=hmac-auth" \ - -d "config.enforce_headers=date, request-line" \ - -d "config.algorithms=hmac-sha1, hmac-sha256" - HTTP/1.1 201 Created - ... + ```bash + curl -i -X POST http://localhost:8001/consumers/ \ + -d "username=alice" + ``` - ``` + Response: + ``` + HTTP/1.1 201 Created + ... + ``` - **Add a Consumer** +3. Add credential for the consumer: - ```bash - $ curl -i -X POST http://localhost:8001/consumers/ \ - -d "username=alice" - HTTP/1.1 201 Created - ... + ```bash + curl -i -X POST http://localhost:8001/consumers/alice/hmac-auth \ + -d "username=alice123" \ + -d "secret=secret" + ``` - ``` + Response: + ``` + HTTP/1.1 201 Created + ... + ``` - **Add credential for Alice** +4. Make an authorized request: - ```bash - $ curl -i -X POST http://localhost:8001/consumers/alice/hmac-auth \ - -d "username=alice123" \ - -d "secret=secret" - HTTP/1.1 201 Created - ... + ```bash + curl -i -X GET http://localhost:8000/requests \ + -H "Host: hmac.com" \ + -H "Date: Thu, 22 Jun 2017 17:15:21 GMT" \ + -H 'Authorization: hmac username="alice123", algorithm="hmac-sha256", headers="date @request-target", signature="ujWCGHeec9Xd6UD2zlyxiNMCiXnDOWeVFMu5VeRUxtw="' + ``` - ``` + Response: + ``` + HTTP/1.1 200 OK + ... + ``` - **Making an authorized request** + In the above request, we are composing the signing string using the `date` and + `@request-target` headers and creating the digest using the `hmac-sha256` to + hash the digest: - ```bash - $ curl -i -X GET http://localhost:8000/requests \ - -H "Host: hmac.com" \ - -H "Date: Thu, 22 Jun 2017 17:15:21 GMT" \ - -H 'Authorization: hmac username="alice123", algorithm="hmac-sha256", headers="date request-line", signature="ujWCGHeec9Xd6UD2zlyxiNMCiXnDOWeVFMu5VeRUxtw="' - HTTP/1.1 200 OK - ... + ``` + signing_string="date: Thu, 22 Jun 2017 17:15:21 GMT\nGET /requests HTTP/1.1" + digest=HMAC-SHA256(, "secret") + base64_digest=base64() + ``` - ``` + So the final value of the `Authorization` header would look like: - In the above request, we are composing the signing string using the `date` and - `request-line` headers and creating the digest using the `hmac-sha256` to - hash the digest: - ``` - signing_string="date: Thu, 22 Jun 2017 17:15:21 GMT\nGET /requests HTTP/1.1" - digest=HMAC-SHA256(, "secret") - base64_digest=base64() - ``` + ``` + Authorization: hmac username="alice123", algorithm="hmac-sha256", headers="date @request-target", signature=" + ``` - So the final value of the `Authorization` header would look like: +5. Validate the request body. + To enable body validation we would need to set `config.validate_request_body` + to `true`. - ``` - Authorization: hmac username="alice123", algorithm="hmac-sha256", headers="date request-line", signature=" - ``` + The following example works the same way, whether the plugin was added to + a service or a route. - **Validating request body** - - To enable body validation we would need to set `config.validate_request_body` - to `true`: - - The following example works the same way, whether the plugin was added to - a Service or a Route. - - ```bash - $ curl -i -X PATCH http://localhost:8001/plugins/{plugin-id} \ + ```bash + curl -i -X PATCH http://localhost:8001/plugins/{plugin-id} \ -d "config.validate_request_body=true" - HTTP/1.1 200 OK - ... - - ``` - - Now if the client includes the body digest in the request as the value of the - `Digest` header, the plugin will validate the request body by calculating the - `SHA-256` of the body and matching it against the `Digest` header's value. - - ```bash - $ curl -i -X GET http://localhost:8000/requests \ - -H "Host: hmac.com" \ - -H "Date: Thu, 22 Jun 2017 21:12:36 GMT" \ - -H "Digest: SHA-256=SBH7QEtqnYUpEcIhDbmStNd1MxtHg2+feBfWc1105MA=" \ - -H 'Authorization: hmac username="alice123", algorithm="hmac-sha256", headers="date request-line digest", signature="gaweQbATuaGmLrUr3HE0DzU1keWGCt3H96M28sSHTG8="' \ - -d "A small body" - HTTP/1.1 200 OK - ... - - ``` - - In the above request we calculated the `SHA-256` digest of the body and set - the `Digest` header with the following format: - - ``` - body="A small body" - digest=SHA-256(body) - base64_digest=base64(digest) - Digest: SHA-256= - ``` + ``` + Response: + ``` + HTTP/1.1 200 OK + ... + ``` + +6. Now if the client includes the body digest in the request as the value of the +`Digest` header, the plugin will validate the request body by calculating the +`SHA-256` of the body and matching it against the `Digest` header's value. + + ```bash + curl -i -X GET http://localhost:8000/requests \ + -H "Host: hmac.com" \ + -H "Date: Thu, 22 Jun 2017 21:12:36 GMT" \ + -H "Digest: SHA-256=SBH7QEtqnYUpEcIhDbmStNd1MxtHg2+feBfWc1105MA=" \ + -H 'Authorization: hmac username="alice123", algorithm="hmac-sha256", headers="date @request-target digest", signature="gaweQbATuaGmLrUr3HE0DzU1keWGCt3H96M28sSHTG8="' \ + -d "A small body" + ``` + + Response: + ``` + HTTP/1.1 200 OK + ... + ``` + + In the above request we calculated the `SHA-256` digest of the body and set + the `Digest` header with the following format: + + ``` + body="A small body" + digest=SHA-256(body) + base64_digest=base64(digest) + Digest: SHA-256= + ``` ### Upstream Headers -When a client has been authenticated, the plugin will append some headers to -the request before proxying it to the upstream service, so that you -can identify the Consumer in your code: - -* `X-Consumer-ID`, the ID of the Consumer on Kong -* `X-Consumer-Custom-ID`, the `custom_id` of the Consumer (if set) -* `X-Consumer-Username`, the `username` of the Consumer (if set) -* `X-Credential-Identifier`, the identifier of the Credential (only if the consumer is not the 'anonymous' consumer) -* `X-Anonymous-Consumer`, will be set to `true` when authentication failed, and the 'anonymous' consumer was set instead. - -You can use this information on your side to implement additional logic. -You can use the `X-Consumer-ID` value to query the Kong Admin API and retrieve -more information about the Consumer. - -
- Note:`X-Credential-Username` was deprecated in favor of `X-Credential-Identifier` in Kong 2.1. -
+{% include_cached /md/plugins-hub/upstream-headers.md %} ### Paginate through the HMAC credentials @@ -423,8 +399,11 @@ Paginate through the `hmac-auth` Credentials for all Consumers using the following request: ```bash -$ curl -X GET http://kong:8001/hmac-auths +curl -X GET http://kong:8001/hmac-auths +``` +Example output: +```json { "total": 3, "data": [ @@ -456,8 +435,11 @@ $ curl -X GET http://kong:8001/hmac-auths You can filter the list by consumer by using this other path: ```bash -$ curl -X GET http://kong:8001/consumers/{username or id}/hmac-auth +curl -X GET http://kong:8001/consumers/{username or id}/hmac-auth +``` +Example output: +```json { "total": 1, "data": [ @@ -481,7 +463,10 @@ HMAC Credential using the following request: ```bash curl -X GET http://kong:8001/hmac-auths/{hmac username or id}/consumer +``` +Example output: +```json { "created_at":1507936639000, "username":"foo", @@ -496,3 +481,12 @@ Consumer. [consumer-object]: /gateway/latest/admin-api/#consumer-object [clock-skew]: https://tools.ietf.org/html/draft-cavage-http-signatures-00#section-3.4 + +--- +## Changelog + +**{{site.base_gateway}} 3.0.x** +* The deprecated `X-Credential-Username` header has been removed. + +**{{site.base_gateway}} 2.5.x** +* The plugin now includes support for the `@request-target` field in the signature string. diff --git a/app/_hub/kong-inc/hmac-auth/versions.yml b/app/_hub/kong-inc/hmac-auth/versions.yml index 14405d124ae7..d4657d53485f 100644 --- a/app/_hub/kong-inc/hmac-auth/versions.yml +++ b/app/_hub/kong-inc/hmac-auth/versions.yml @@ -1,3 +1,12 @@ -- release: 2.2-x -- release: 2.1-x -- release: 0.1-x +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 2.4.0 + 2.7.x: 2.4.0 + 2.6.x: 2.4.0 + 2.5.x: 2.4.0 + 2.4.x: 2.2.1 + 2.3.x: 2.2.1 + 2.2.x: 2.2.0 + 2.1.x: 2.2.0 diff --git a/app/_hub/kong-inc/http-log/0.1-x.md b/app/_hub/kong-inc/http-log/0.1-x.md deleted file mode 100644 index 46d2e9ce13f4..000000000000 --- a/app/_hub/kong-inc/http-log/0.1-x.md +++ /dev/null @@ -1,207 +0,0 @@ ---- -name: HTTP Log -publisher: Kong Inc. -version: 0.1-x - -desc: Send request and response logs to an HTTP server -description: | - Send request and response logs to an HTTP server. - -
- Note: The functionality of this plugin as bundled - with versions of Kong prior to 0.10.2 differs from - what is documented herein. Refer to the - CHANGELOG - for details. -
- -type: plugin -categories: - - logging - -kong_version_compatibility: - community_edition: - compatible: - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x - - 0.4.x - - 0.3.x - enterprise_edition: - compatible: - - 0.34-x - - 0.33-x - - 0.32-x - - 0.31-x - -params: - name: http-log - api_id: true - service_id: true - route_id: true - consumer_id: true - config: - - name: http_endpoint - required: true - default: - value_in_examples: http://mockbin.org/bin/:id - description: The HTTP endpoint (including the protocol to use) to which the data will be sent. - - name: method - required: false - default: "`POST`" - value_in_examples: POST - description: | - An optional method used to send data to the http server, other supported values are `PUT`, `PATCH` - - name: timeout - required: false - default: "`10000`" - value_in_examples: 1000 - description: An optional timeout in milliseconds when sending data to the upstream server - - name: keepalive - required: false - default: "`60000`" - value_in_examples: 1000 - description: An optional value in milliseconds that defines for how long an idle connection will live before being closed - extra: | - **NOTE:** If the `config.http_endpoint` contains a username and password (ex. - `http://bob:password@example.com/logs`), then Kong will automatically include - a basic-auth `Authorization` header in the log requests. - ---- - -## Log Format - -Every request will be logged separately in a JSON object, with the following format: - -```json -{ - "request": { - "method": "GET", - "uri": "/get", - "url": "http://httpbin.org:8000/get", - "size": "75", - "querystring": {}, - "headers": { - "accept": "*/*", - "host": "httpbin.org", - "user-agent": "curl/7.37.1" - }, - "tls": { - "version": "TLSv1.2", - "cipher": "ECDHE-RSA-AES256-GCM-SHA384", - "supported_client_ciphers": "ECDHE-RSA-AES256-GCM-SHA384", - "client_verify": "NONE" - } - }, - "upstream_uri": "/", - "response": { - "status": 200, - "size": "434", - "headers": { - "Content-Length": "197", - "via": "kong/0.3.0", - "Connection": "close", - "access-control-allow-credentials": "true", - "Content-Type": "application/json", - "server": "nginx", - "access-control-allow-origin": "*" - } - }, - "tries": [ - { - "state": "next", - "code": 502, - "ip": "127.0.0.1", - "port": 8000 - }, - { - "ip": "127.0.0.1", - "port": 8000 - } - ], - "authenticated_entity": { - "consumer_id": "80f74eef-31b8-45d5-c525-ae532297ea8e", - "id": "eaa330c0-4cff-47f5-c79e-b2e4f355207e" - }, - "route": { - "created_at": 1521555129, - "hosts": null, - "id": "75818c5f-202d-4b82-a553-6a46e7c9a19e", - "methods": null, - "paths": [ - "/example-path" - ], - "preserve_host": false, - "protocols": [ - "http", - "https" - ], - "regex_priority": 0, - "service": { - "id": "0590139e-7481-466c-bcdf-929adcaaf804" - }, - "strip_path": true, - "updated_at": 1521555129 - }, - "service": { - "connect_timeout": 60000, - "created_at": 1521554518, - "host": "example.com", - "id": "0590139e-7481-466c-bcdf-929adcaaf804", - "name": "myservice", - "path": "/", - "port": 80, - "protocol": "http", - "read_timeout": 60000, - "retries": 5, - "updated_at": 1521554518, - "write_timeout": 60000 - }, - "consumer": { - "username": "demo", - "created_at": 1491847011000, - "id": "35b03bfc-7a5b-4a23-a594-aa350c585fa8" - }, - "latencies": { - "proxy": 1430, - "kong": 9, - "request": 1921 - }, - "client_ip": "127.0.0.1", - "started_at": 1433209822425 -} -``` - -A few considerations on the above JSON object: - -* `request` contains properties about the request sent by the client -* `response` contains properties about the response sent to the client -* `tries` contains the list of (re)tries (successes and failures) made by the load balancer for this request -* `route` contains Kong properties about the specific Route requested -* `service` contains Kong properties about the Service associated with the requested Route -* `authenticated_entity` contains Kong properties about the authenticated credential (if an authentication plugin has been enabled) -* `consumer` contains the authenticated Consumer (if an authentication plugin has been enabled) -* `latencies` contains some data about the latencies involved: - * `proxy` is the time it took for the final service to process the request - * `kong` is the internal Kong latency that it took to run all the plugins - * `request` is the time elapsed between the first bytes were read from the client and after the last bytes were sent to the client. Useful for detecting slow clients. -* `client_ip` contains the original client IP address -* `started_at` contains the UTC timestamp of when the request has started to be processed. - ----- - -## Kong Process Errors - -This logging plugin will only log HTTP request and response data. If you are -looking for the Kong process error file (which is the nginx error file), then -you can find it at the following path: -`$KONG_PREFIX/logs/error.log`, -where `$KONG_PREFIX` means -[prefix in the configuration](/gateway/latest/reference/configuration/#prefix). diff --git a/app/_hub/kong-inc/http-log/1.0.x.md b/app/_hub/kong-inc/http-log/1.0.x.md deleted file mode 100644 index ef719ba1552a..000000000000 --- a/app/_hub/kong-inc/http-log/1.0.x.md +++ /dev/null @@ -1,227 +0,0 @@ ---- -name: HTTP Log -publisher: Kong Inc. -version: 1.0.x - -desc: Send request and response logs to an HTTP server -description: | - Send request and response logs to an HTTP server. - -
- Note: The functionality of this plugin as bundled - with versions of Kong prior to 0.10.2 differs from - what is documented herein. Refer to the - CHANGELOG - for details. -
- -type: plugin -categories: - - logging - -kong_version_compatibility: - community_edition: - compatible: - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x - - 0.4.x - - 0.3.x - enterprise_edition: - compatible: - - 1.5.x - - 1.3-x - - 0.36-x - - 0.35-x - - 0.34-x - - 0.33-x - - 0.32-x - - 0.31-x - -params: - name: http-log - service_id: true - route_id: true - consumer_id: true - protocols: ["http", "https", "grpc", "grpcs"] - dbless_compatible: yes - config: - - name: http_endpoint - required: true - default: - value_in_examples: http://mockbin.org/bin/:id - description: The HTTP endpoint (including the protocol to use) to which the data is sent. - - name: method - required: false - default: "`POST`" - value_in_examples: POST - description: | - An optional method used to send data to the HTTP server. Supported values are `POST` (default), `PUT`, and `PATCH`. - - name: timeout - required: false - default: "`10000`" - value_in_examples: 1000 - description: An optional timeout in milliseconds when sending data to the upstream server. - - name: keepalive - required: false - default: "`60000`" - value_in_examples: 1000 - description: An optional value in milliseconds that defines how long an idle connection will live before being closed. - extra: | - **NOTE:** If the `config.http_endpoint` contains a username and password (for example, - `http://bob:password@example.com/logs`), then Kong automatically includes - a basic-auth `Authorization` header in the log requests. - ---- - -## Log Format - -Every request is logged separately in a JSON object in the following format: - -```json -{ - "request": { - "method": "GET", - "uri": "/get", - "url": "http://httpbin.org:8000/get", - "size": "75", - "querystring": {}, - "headers": { - "accept": "*/*", - "host": "httpbin.org", - "user-agent": "curl/7.37.1" - }, - "tls": { - "version": "TLSv1.2", - "cipher": "ECDHE-RSA-AES256-GCM-SHA384", - "supported_client_ciphers": "ECDHE-RSA-AES256-GCM-SHA384", - "client_verify": "NONE" - } - }, - "upstream_uri": "/", - "response": { - "status": 200, - "size": "434", - "headers": { - "Content-Length": "197", - "via": "kong/0.3.0", - "Connection": "close", - "access-control-allow-credentials": "true", - "Content-Type": "application/json", - "server": "nginx", - "access-control-allow-origin": "*" - } - }, - "tries": [ - { - "state": "next", - "code": 502, - "ip": "127.0.0.1", - "port": 8000 - }, - { - "ip": "127.0.0.1", - "port": 8000 - } - ], - "authenticated_entity": { - "consumer_id": "80f74eef-31b8-45d5-c525-ae532297ea8e", - "id": "eaa330c0-4cff-47f5-c79e-b2e4f355207e" - }, - "route": { - "created_at": 1521555129, - "hosts": null, - "id": "75818c5f-202d-4b82-a553-6a46e7c9a19e", - "methods": null, - "paths": [ - "/example-path" - ], - "preserve_host": false, - "protocols": [ - "http", - "https" - ], - "regex_priority": 0, - "service": { - "id": "0590139e-7481-466c-bcdf-929adcaaf804" - }, - "strip_path": true, - "updated_at": 1521555129 - }, - "service": { - "connect_timeout": 60000, - "created_at": 1521554518, - "host": "example.com", - "id": "0590139e-7481-466c-bcdf-929adcaaf804", - "name": "myservice", - "path": "/", - "port": 80, - "protocol": "http", - "read_timeout": 60000, - "retries": 5, - "updated_at": 1521554518, - "write_timeout": 60000 - }, - "workspaces": [ - { - "id":"b7cac81a-05dc-41f5-b6dc-b87e29b6c3a3", - "name": "default" - } - ], - "consumer": { - "username": "demo", - "created_at": 1491847011000, - "id": "35b03bfc-7a5b-4a23-a594-aa350c585fa8" - }, - "latencies": { - "proxy": 1430, - "kong": 9, - "request": 1921 - }, - "client_ip": "127.0.0.1", - "started_at": 1433209822425 -} -``` - -A few considerations on the above JSON object: - -* `request` contains properties about the request sent by the client. -* `response` contains properties about the response sent to the client. -* `tries` contains the list of tries and retries (successes and failures) made by the load balancer for the request. -* `route` contains Kong properties about the specific Route requested. -* `service` contains Kong properties about the Service associated with the requested Route. -* `authenticated_entity` contains Kong properties about the authenticated credential if an authentication plugin has been enabled. -* `workspaces` contains Kong properties of the Workspaces associated with the requested Route. **Only in Kong Gateway version >= 0.34**. -* `consumer` contains the authenticated Consumer if an authentication plugin has been enabled. -* `latencies` contains some data about the latencies involved: - * `proxy` is the time it took for the final service to process the request. - * `kong` is the internal Kong latency that it took to run all the plugins. - * `request` is the time elapsed between the first bytes were read from the client and after the last bytes were sent to the client. Useful for detecting slow clients. -* `client_ip` contains the original client IP address. -* `started_at` contains the UTC timestamp of when the request started to be processed. - ----- - -## Kong Process Errors - -This logging plugin only logs HTTP request and response data. If you are -looking for the Kong process error file (which is the nginx error file), then -you can find it at the following path: - -`$KONG_PREFIX/logs/error.log` - -where `$KONG_PREFIX` means -[prefix in the configuration](/gateway/latest/reference/configuration/#prefix). diff --git a/app/_hub/kong-inc/http-log/2.0.x.md b/app/_hub/kong-inc/http-log/2.0.x.md deleted file mode 100644 index a128704d4aa4..000000000000 --- a/app/_hub/kong-inc/http-log/2.0.x.md +++ /dev/null @@ -1,137 +0,0 @@ ---- -name: HTTP Log -publisher: Kong Inc. -version: 2.0.x -# internal handler version 2.0.1 - -desc: Send request and response logs to an HTTP server -description: | - Send request and response logs to an HTTP server. - -type: plugin -categories: - - logging - -kong_version_compatibility: - community_edition: - compatible: - - 2.3.x - - 2.2.x - - 2.1.x - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x - - 0.4.x - - 0.3.x - enterprise_edition: - compatible: - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x - -params: - name: http-log - service_id: true - route_id: true - consumer_id: true - protocols: ["http", "https", "grpc", "grpcs", "tcp", "tls", "udp"] - dbless_compatible: yes - config: - - name: http_endpoint - required: true - default: - value_in_examples: http://mockbin.org/bin/:id - datatype: string - description: The HTTP URL endpoint (including the protocol to use) to which the data is sent. - - name: method - required: false - default: "`POST`" - value_in_examples: POST - datatype: string - description: | - An optional method used to send data to the HTTP server. Supported values are - `POST` (default), `PUT`, and `PATCH`. - - name: content_type - required: false - default: "`application/json`" - value_in_examples: - datatype: string - description: | - Indicates the type of data sent. The only available option is `application/json`. - - name: timeout - required: false - default: "`10000`" - value_in_examples: 1000 - datatype: number - description: An optional timeout in milliseconds when sending data to the upstream server. - - name: keepalive - required: false - default: "`60000`" - value_in_examples: 1000 - datatype: number - description: An optional value in milliseconds that defines how long an idle connection will live before being closed. - - name: flush_timeout - required: false - default: "`2`" - value_in_examples: 2 - datatype: number - description: | - Optional time in seconds. If `queue_size` > 1, this is the max idle time before sending a log with less than `queue_size` records. - - name: retry_count - required: false - default: 10 - value_in_examples: 15 - datatype: integer - description: Number of times to retry when sending data to the upstream server. - - name: queue_size - required: false - default: 1 - datatype: integer - description: Maximum number of log entries to be sent on each message to the upstream server. - - name: headers - required: false - default: empty table - datatype: array of string elements - description: | - An optional table of headers added to the HTTP message to the upstream server. The following - headers are not allowed: `Host`, `Content-Length`, `Content-Type`. - - **Note:** This parameter is only available for versions - 2.3.x and later. - extra: | - **NOTE:** If the `config.http_endpoint` contains a username and password (for example, - `http://bob:password@example.com/logs`), then Kong Gateway automatically includes - a basic-auth `Authorization` header in the log requests. - ---- - -## Log format - -**Note:** If the `queue_size` argument > 1, a request is logged as an array of JSON objects. - -{% include /md/plugins-hub/log-format.md %} - -### JSON object considerations - -{% include /md/plugins-hub/json-object-log.md %} - -## Kong process errors - -{% include /md/plugins-hub/kong-process-errors.md %} diff --git a/app/_hub/kong-inc/http-log/_index.md b/app/_hub/kong-inc/http-log/_index.md index 239bef86941d..70ff241c7a9b 100644 --- a/app/_hub/kong-inc/http-log/_index.md +++ b/app/_hub/kong-inc/http-log/_index.md @@ -1,7 +1,6 @@ --- name: HTTP Log publisher: Kong Inc. -version: 2.1.x desc: Send request and response logs to an HTTP server description: | Send request and response logs to an HTTP server. @@ -10,19 +9,9 @@ categories: - logging kong_version_compatibility: community_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x + compatible: true enterprise_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x + compatible: true params: name: http-log service_id: true @@ -45,7 +34,12 @@ params: value_in_examples: 'http://mockbin.org/bin/:id' datatype: string encrypted: true - description: The HTTP URL endpoint (including the protocol to use) to which the data is sent. + description: | + The HTTP URL endpoint (including the protocol to use) to which the data is sent. + + If the `http_endpoint` contains a username and password (for example, + `http://bob:password@example.com/logs`), then Kong Gateway automatically includes + a basic-auth `Authorization` header in the log requests. - name: method required: false default: '`POST`' @@ -91,20 +85,37 @@ params: default: 1 datatype: integer description: Maximum number of log entries to be sent on each message to the upstream server. + + # ----- Old version of the 'headers' parameter ----- - name: headers required: false default: empty table - datatype: array of string elements + datatype: table description: | - An optional table of headers added to the HTTP message to the upstream server. The following - headers are not allowed: `Host`, `Content-Length`, `Content-Type`. - - **Note:** This parameter is only available for versions - 2.3.x and later. - extra: | - **NOTE:** If the `config.http_endpoint` contains a username and password (for example, - `http://bob:password@example.com/logs`), then Kong Gateway automatically includes - a basic-auth `Authorization` header in the log requests. + + An optional table of headers added to the HTTP message to the upstream server. + The table contains arrays of values, indexed by the header name (multiple values per header). + + The following headers are not allowed: `Host`, `Content-Length`, `Content-Type`. + + minimum_version: "2.3.x" + maximum_version: "2.8.x" + # --------------------------------------------------- + + - name: headers + required: false + default: empty table + datatype: table + description: | + An optional table of headers included in the HTTP message to the + upstream server. Values are indexed by header name, and each header name + accepts a single string. + + The following headers are not allowed: `Host`, `Content-Length`, `Content-Type`. + + > **Note:** Before version 3.0.0, the values were arrays of strings (multiple values per header name). + + minimum_version: "3.0.x" - name: custom_fields_by_lua required: false default: @@ -113,11 +124,13 @@ params: A list of key-value pairs, where the key is the name of a log field and the value is a chunk of Lua code, whose return value sets or replaces the log field value. + minimum_version: "2.4.x" --- ## Log format -**Note:** If the `queue_size` argument > 1, a request is logged as an array of JSON objects. +{:.note} +> **Note:** If the `queue_size` argument > 1, a request is logged as an array of JSON objects. {% include /md/plugins-hub/log-format.md %} @@ -126,6 +139,8 @@ params: {% include /md/plugins-hub/json-object-log.md %} +{% if_plugin_version gte:2.3.x %} + ## Custom Headers The log server that receives these messages might require extra headers, such as for authorization purposes. @@ -139,19 +154,39 @@ The log server that receives these messages might require extra headers, such as ... ``` +{% endif_plugin_version %} + ## Kong process errors {% include /md/plugins-hub/kong-process-errors.md %} + +{% if_plugin_version gte:2.4.x %} + ## Custom Fields by Lua {% include /md/plugins-hub/log_custom_fields_by_lua.md %} +{% endif_plugin_version %} + --- ## Changelog -### 2.2.1 +**{{site.base_gateway}} 3.0.x** + +* The `headers` parameter now takes a single string per header name, where it +previously took an array of values. + +**{{site.base_gateway}} 2.7.x** + +* If keyring encryption is enabled, the `config.http_endpoint` parameter value +will be encrypted. + +**{{site.base_gateway}} 2.4.x** + +* Added the `custom_fields_by_lua` parameter. + +**{{site.base_gateway}} 2.3.x** -* Starting with {{site.base_gateway}} 2.7.0.0, if keyring encryption is enabled, - the `config.http_endpoint` parameter value will be encrypted. +* Custom headers can now be specified for the log request using the `headers` parameter. diff --git a/app/_hub/kong-inc/http-log/versions.yml b/app/_hub/kong-inc/http-log/versions.yml index 28b8d91826b3..fb3cf4d1e543 100644 --- a/app/_hub/kong-inc/http-log/versions.yml +++ b/app/_hub/kong-inc/http-log/versions.yml @@ -1,4 +1,12 @@ -- release: 2.1.x -- release: 2.0.x -- release: 1.0.x -- release: 0.1-x +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 2.1.1 + 2.7.x: 2.1.1 + 2.6.x: 2.1.1 + 2.5.x: 2.1.0 + 2.4.x: 2.1.0 + 2.3.x: 2.0.1 + 2.2.x: 2.0.1 + 2.1.x: 2.0.1 diff --git a/app/_hub/kong-inc/ip-restriction/0.1-x.md b/app/_hub/kong-inc/ip-restriction/0.1-x.md deleted file mode 100644 index 8e39e5d0dfb5..000000000000 --- a/app/_hub/kong-inc/ip-restriction/0.1-x.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -name: IP Restriction -publisher: Kong Inc. -version: 0.1-x - -desc: Whitelist or blacklist IPs that can make API requests -description: | - Restrict access to a Service or a Route (or the deprecated API entity) by either whitelisting or blacklisting IP addresses. Single IPs, multiple IPs or ranges in [CIDR notation](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing#CIDR_notation) like `10.10.10.0/24` can be used. - -type: plugin -categories: - - security - -kong_version_compatibility: - community_edition: - compatible: - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x - - 0.4.x - enterprise_edition: - compatible: - - 0.34-x - - 0.33-x - - 0.32-x - - 0.31-x - -params: - name: ip-restriction - api_id: true - service_id: true - route_id: true - consumer_id: true - config: - - name: whitelist - required: semi - default: - value_in_examples: 54.13.21.1, 143.1.0.0/24 - description: | - Comma-separated list of IPs or CIDR ranges to whitelist. One of `config.whitelist` or `config.blacklist` must be specified. - - name: blacklist - required: semi - default: - description: | - Comma-separated list of IPs or CIDR ranges to blacklist. One of `config.whitelist` or `config.blacklist` must be specified. - - extra: | - - Note that the `whitelist` and `blacklist` models are mutually exclusive in their usage, as they provide complimentary approaches. That is, you cannot configure the plugin with both `whitelist` and `blacklist` configurations. A `whitelist` provides a positive security model, in which the configured CIDR ranges are allowed access to the resource, and all others are inherently rejected. In contrast, a `blacklist` configuration provides a negative security model, in which certain CIDRS are explicitly denied access to the resource (and all others are inherently allowed). - ---- diff --git a/app/_hub/kong-inc/ip-restriction/1.0-x.md b/app/_hub/kong-inc/ip-restriction/1.0-x.md deleted file mode 100644 index fbb59cb16e78..000000000000 --- a/app/_hub/kong-inc/ip-restriction/1.0-x.md +++ /dev/null @@ -1,69 +0,0 @@ ---- -name: IP Restriction -publisher: Kong Inc. -version: 1.0-x - -desc: Whitelist or blacklist IPs that can make API requests -description: | - Restrict access to a Service or a Route (or the deprecated API entity) by either whitelisting or blacklisting IP addresses. Single IPs, multiple IPs or ranges in [CIDR notation](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing#CIDR_notation) like `10.10.10.0/24` can be used. The plugin supports IPv4 and IPv6 addresses. - -type: plugin -categories: - - security - -kong_version_compatibility: - community_edition: - compatible: - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x - - 0.4.x - enterprise_edition: - compatible: - - 1.5.x - - 1.3-x - - 0.36-x - - 0.35-x - - 0.34-x - - 0.33-x - - 0.32-x - - 0.31-x - -params: - name: ip-restriction - service_id: true - route_id: true - consumer_id: true - protocols: ["http", "https"] - dbless_compatible: yes - config: - - name: whitelist - required: semi - default: - value_in_examples: [ "54.13.21.1", "143.1.0.0/24" ] - description: | - Comma-separated list of IPs or CIDR ranges to whitelist. One of `config.whitelist` or `config.blacklist` must be specified. - - name: blacklist - required: semi - default: - description: | - Comma-separated list of IPs or CIDR ranges to blacklist. One of `config.whitelist` or `config.blacklist` must be specified. - - extra: | - - Note that the `whitelist` and `blacklist` models are mutually exclusive in their usage, as they provide complimentary approaches. That is, you cannot configure the plugin with both `whitelist` and `blacklist` configurations. A `whitelist` provides a positive security model, in which the configured CIDR ranges are allowed access to the resource, and all others are inherently rejected. In contrast, a `blacklist` configuration provides a negative security model, in which certain CIDRS are explicitly denied access to the resource (and all others are inherently allowed). - ---- diff --git a/app/_hub/kong-inc/ip-restriction/2.0.x.md b/app/_hub/kong-inc/ip-restriction/2.0.x.md deleted file mode 100644 index 78b10516925b..000000000000 --- a/app/_hub/kong-inc/ip-restriction/2.0.x.md +++ /dev/null @@ -1,86 +0,0 @@ ---- -name: IP Restriction -publisher: Kong Inc. -version: 2.0.x - -desc: Allow or deny IPs that can make requests to your Services -description: | - Restrict access to a Service or a Route by either allowing or denying IP addresses. Single IPs, multiple IPs or ranges in [CIDR notation](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing#CIDR_notation) like `10.10.10.0/24` can be used. The plugin supports IPv4 and IPv6 addresses. - -type: plugin -categories: - - security - -kong_version_compatibility: - community_edition: - compatible: - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x - - 0.4.x - enterprise_edition: - compatible: - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x - -params: - name: ip-restriction - service_id: true - route_id: true - consumer_id: true - protocols: ["http", "https"] - dbless_compatible: yes - config: - - name: allow - required: semi - default: - value_in_examples: [ "54.13.21.1", "143.1.0.0/24" ] - datatype: array of string elements - description: | - List of IPs or CIDR ranges to allow. One of `config.allow` or `config.deny` must be specified. - - name: deny - required: semi - default: - datatype: array of string elements - description: | - List of IPs or CIDR ranges to deny. One of `config.allow` or `config.deny` must be specified. - - extra: | - - An `allow` list provides a positive security model, in which the configured CIDR ranges are allowed access to the resource, and all others are inherently rejected. By contrast, a `deny` list configuration provides a negative security model, in which certain CIDRS are explicitly denied access to the resource (and all others are inherently allowed). - - You can configure the plugin with both `allow` and `deny` configurations. An interesting use case of this flexibility is to allow a CIDR range, but deny an IP address on that CIDR range: - - ```bash - $ curl -X POST http://kong:8001/services/{service}/plugins \ - --data "name=ip-restriction" \ - --data "config.allow=127.0.0.0/24" \ - --data "config.deny=127.0.0.1" - ``` - ---- diff --git a/app/_hub/kong-inc/ip-restriction/_index.md b/app/_hub/kong-inc/ip-restriction/_index.md index 2ed367c5d2e8..ea10ccbf514b 100644 --- a/app/_hub/kong-inc/ip-restriction/_index.md +++ b/app/_hub/kong-inc/ip-restriction/_index.md @@ -1,58 +1,18 @@ --- name: IP Restriction publisher: Kong Inc. -version: 2.1.x desc: Allow or deny IPs that can make requests to your Services description: | - Restrict access to a Service or a Route by either allowing or denying IP addresses. Single IPs, multiple IPs or ranges in [CIDR notation](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing#CIDR_notation) like `10.10.10.0/24` can be used. The plugin supports IPv4 and IPv6 addresses. + Restrict access to a Service or a Route by either allowing or denying IP addresses. Single IPs, multiple IPs, or ranges in [CIDR notation](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing#CIDR_notation) like `10.10.10.0/24` can be used. The plugin supports IPv4 and IPv6 addresses. - {:.note} - > **Note**: We have deprecated the usage of `whitelist` and `blacklist` in favor of `allow` and `deny`. This change may require Admin API requests to be updated. type: plugin categories: - security kong_version_compatibility: community_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x - - 0.4.x + compatible: true enterprise_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x + compatible: true params: name: ip-restriction service_id: true @@ -63,6 +23,21 @@ params: - https dbless_compatible: 'yes' config: + +# deprecated parameters and previous versions + - name: whitelist + required: semi + default: + value_in_examples: 54.13.21.1, 143.1.0.0/24 + description: | + Comma-separated list of IPs or CIDR ranges to whitelist. One of `config.whitelist` or `config.blacklist` must be specified. + maximum_version: "2.0.x" + - name: blacklist + required: semi + default: + description: | + Comma-separated list of IPs or CIDR ranges to blacklist. One of `config.whitelist` or `config.blacklist` must be specified. + maximum_version: "2.0.0" - name: allow required: semi default: null @@ -71,42 +46,94 @@ params: - 143.1.0.0/24 datatype: array of string elements description: | - List of IPs or CIDR ranges to allow. One of `config.allow` or `config.deny` must be specified. Note that we have deprecated the usage of `whitelist` and `blacklist` in favor of `allow` and `deny`. + List of IPs or CIDR ranges to allow. One of `config.allow` or `config.deny` must be specified. + + Note: We have deprecated the usage of `whitelist` and `blacklist` in favor of `allow` and `deny`. + minimum_version: "2.1.x" + maximum_version: "2.8.x" - name: deny required: semi default: null datatype: array of string elements description: | - List of IPs or CIDR ranges to deny. One of `config.allow` or `config.deny` must be specified. Note that we have deprecated the usage of `whitelist` and `blacklist` in favor of `allow` and `deny`. + List of IPs or CIDR ranges to deny. One of `config.allow` or `config.deny` must be specified. + + Note: We have deprecated the usage of `whitelist` and `blacklist` in favor of `allow` and `deny`. + minimum_version: "2.1.x" + maximum_version: "2.8.x" + +# current parameters + - name: allow + required: semi + default: null + value_in_examples: + - 54.13.21.1 + - 143.1.0.0/24 + datatype: array of string elements + description: | + List of IPs or CIDR ranges to allow. One of `config.allow` or `config.deny` must be specified. + minimum_version: "3.0.x" + - name: deny + required: semi + default: null + datatype: array of string elements + description: | + List of IPs or CIDR ranges to deny. One of `config.allow` or `config.deny` must be specified. + minimum_version: "3.0.x" - name: status required: false default: 403 datatype: integer description: | The HTTP status of the requests that will be rejected by the plugin. + minimum_version: "2.7.x" - name: message required: false default: Your IP address is not allowed datatype: string description: | The message to send as a response body to rejected requests. - extra: | + minimum_version: "2.7.x" +--- +## Usage + +{% if_plugin_version gte:2.1.x %} + +{% if_plugin_version lte:2.8.x %} - An `allow` list provides a positive security model, in which the configured CIDR ranges are allowed access to the resource, and all others are inherently rejected. By contrast, a `deny` list configuration provides a negative security model, in which certain CIDRS are explicitly denied access to the resource (and all others are inherently allowed). +{:.note} +> **Note**: We have deprecated the usage of `whitelist` and `blacklist` in favor of `allow` and `deny`. This change may require Admin API requests to be updated. - You can configure the plugin with both `allow` and `deny` configurations. An interesting use case of this flexibility is to allow a CIDR range, but deny an IP address on that CIDR range: +{% endif_plugin_version %} + +An `allow` list provides a positive security model, in which the configured CIDR ranges are allowed access to the resource, and all others are inherently rejected. By contrast, a `deny` list configuration provides a negative security model, in which certain CIDRS are explicitly denied access to the resource (and all others are inherently allowed). + +You can configure the plugin with both `allow` and `deny` configurations. An interesting use case of this flexibility is to allow a CIDR range, but deny an IP address on that CIDR range: + +```bash +curl -X POST http://kong:8001/services/{service}/plugins \ + --data "name=ip-restriction" \ + --data "config.allow=127.0.0.0/24" \ + --data "config.deny=127.0.0.1" +``` +{% endif_plugin_version %} + +{% if_plugin_version eq:2.0.x %} + +Note that the `whitelist` and `blacklist` models are mutually exclusive in their usage, as they provide complimentary approaches. That is, you cannot configure the plugin with both `whitelist` and `blacklist` configurations. A `whitelist` provides a positive security model, in which the configured CIDR ranges are allowed access to the resource, and all others are inherently rejected. In contrast, a `blacklist` configuration provides a negative security model, in which certain CIDRS are explicitly denied access to the resource (and all others are inherently allowed). + +{% endif_plugin_version %} - ```bash - $ curl -X POST http://kong:8001/services/{service}/plugins \ - --data "name=ip-restriction" \ - --data "config.allow=127.0.0.0/24" \ - --data "config.deny=127.0.0.1" - ``` --- ## Changelog -### 2.1.0 +**{{site.base_gateway}} 3.0.x** +- Removed the deprecated `whitelist` and `blacklist` parameters. +They are no longer supported. +**{{site.base_gateway}} 2.7.x** - Addition of `status` and `message` fields + +**{{site.base_gateway}} 2.1.x** - Use `allow` and `deny` instead of `whitelist` and `blacklist` diff --git a/app/_hub/kong-inc/ip-restriction/versions.yml b/app/_hub/kong-inc/ip-restriction/versions.yml index b724ebe7054f..499736e2925a 100644 --- a/app/_hub/kong-inc/ip-restriction/versions.yml +++ b/app/_hub/kong-inc/ip-restriction/versions.yml @@ -1,4 +1,12 @@ -- release: 2.1.x -- release: 2.0.x -- release: 1.0-x -- release: 0.1-x +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 2.0.0 + 2.7.x: 2.0.0 + 2.6.x: 2.0.0 + 2.5.x: 2.0.0 + 2.4.x: 2.0.0 + 2.3.x: 2.0.0 + 2.2.x: 2.0.0 + 2.1.x: 2.0.0 diff --git a/app/_hub/kong-inc/jq/_index.md b/app/_hub/kong-inc/jq/_index.md index c6bd00f4beae..5213c029bf37 100644 --- a/app/_hub/kong-inc/jq/_index.md +++ b/app/_hub/kong-inc/jq/_index.md @@ -1,7 +1,6 @@ --- name: jq publisher: Kong Inc. -versions: 0.0.1 desc: Transform JSON objects included in API requests or responses using jq programs. description: | The jq plugin enables arbitrary jq transformations on JSON objects included in API requests or responses. @@ -113,4 +112,3 @@ params: A list of HTTP response status codes. The response status code **must** match one of the response status codes on this list for the program to run. --- - diff --git a/app/_hub/kong-inc/jq/versions.yml b/app/_hub/kong-inc/jq/versions.yml index 49469c4d6959..7a75a7f51ac2 100644 --- a/app/_hub/kong-inc/jq/versions.yml +++ b/app/_hub/kong-inc/jq/versions.yml @@ -1 +1,14 @@ -- release: 0.0.1 +strategy: gateway + +releases: + - 3.0.x + - 2.8.x + - 2.7.x + - 2.6.x + +overrides: + 2.8.x: 0.0.2 + 2.7.x: 0.0.1 + 2.6.x: 0.0.1 + 2.5.x: 0.0.1 + 2.4.x: 0.0.1 diff --git a/app/_hub/kong-inc/jwt-signer/1.3-x.md b/app/_hub/kong-inc/jwt-signer/_1.3-x.md similarity index 100% rename from app/_hub/kong-inc/jwt-signer/1.3-x.md rename to app/_hub/kong-inc/jwt-signer/_1.3-x.md diff --git a/app/_hub/kong-inc/jwt-signer/2.2.x.md b/app/_hub/kong-inc/jwt-signer/_2.2.x.md similarity index 100% rename from app/_hub/kong-inc/jwt-signer/2.2.x.md rename to app/_hub/kong-inc/jwt-signer/_2.2.x.md diff --git a/app/_hub/kong-inc/jwt-signer/2.4.x.md b/app/_hub/kong-inc/jwt-signer/_2.4.x.md similarity index 100% rename from app/_hub/kong-inc/jwt-signer/2.4.x.md rename to app/_hub/kong-inc/jwt-signer/_2.4.x.md diff --git a/app/_hub/kong-inc/jwt-signer/_index.md b/app/_hub/kong-inc/jwt-signer/_index.md index 735c4059c2e3..5495501b1e7d 100644 --- a/app/_hub/kong-inc/jwt-signer/_index.md +++ b/app/_hub/kong-inc/jwt-signer/_index.md @@ -798,7 +798,7 @@ GET kong:8001/jwt-signer/jwks Example: ```bash -$ curl -X GET http://:8001/jwt-signer/jwks +curl -X GET http://:8001/jwt-signer/jwks ``` ```json { @@ -877,7 +877,7 @@ GET kong:8001/jwt-signer/jwks/ Example: ```bash -$ curl -X GET http://:8001/jwt-signer/jwks/kong +curl -X GET http://:8001/jwt-signer/jwks/kong ``` ```json { @@ -921,7 +921,7 @@ DELETE kong:8001/jwt-signer/jwks/ Example: ```bash -$ curl -X DELETE http://:8001/jwt-signer/jwks/kong +curl -X DELETE http://:8001/jwt-signer/jwks/kong ``` The plugin automatically reloads or regenerates missing JWKS if it cannot @@ -950,7 +950,7 @@ POST kong:8001/jwt-signer/jwks//rotate Example: ```bash -$ curl -X POST http://:8001/jwt-signer/jwks/kong/rotate +curl -X POST http://:8001/jwt-signer/jwks/kong/rotate ``` Response: diff --git a/app/_hub/kong-inc/jwt-signer/versions.yml b/app/_hub/kong-inc/jwt-signer/versions.yml index 4d18d87ced56..b53bfe793b14 100644 --- a/app/_hub/kong-inc/jwt-signer/versions.yml +++ b/app/_hub/kong-inc/jwt-signer/versions.yml @@ -1,7 +1,19 @@ -- release: 2.7.x -- release: 2.3.x -- release: 1.3.x -- release: 0.36-x -- release: 0.35-x -- release: 0.34-x -- release: 0.33-x +strategy: gateway +delegate_releases: true +sources: + 2.6.x: _2.4.x + 2.5.x: _2.4.x + 2.4.x: _2.2.x + 2.3.x: _2.2.x + 2.2.x: _2.2.x + 2.1.x: _1.3-x + +overrides: + 2.8.x: 1.9.1 + 2.7.x: 1.9.0 + 2.6.x: 1.8.0 + 2.5.x: 1.7.0 + 2.4.x: 1.7.0 + 2.3.x: 1.7.0 + 2.2.x: 1.7.0 + 2.1.x: 1.7.0 diff --git a/app/_hub/kong-inc/jwt/0.1-x.md b/app/_hub/kong-inc/jwt/0.1-x.md deleted file mode 100644 index 30e53608384a..000000000000 --- a/app/_hub/kong-inc/jwt/0.1-x.md +++ /dev/null @@ -1,546 +0,0 @@ ---- -name: JWT -publisher: Kong Inc. -version: 0.1-x - -desc: Verify and authenticate JSON Web Tokens -description: | - Verify requests containing HS256 or RS256 signed JSON Web Tokens (as specified in [RFC 7519](https://tools.ietf.org/html/rfc7519)). Each of your Consumers will have JWT credentials (public and secret keys) which must be used to sign their JWTs. A token can then be passed through: - - - a query string parameter, - - a cookie, - - or the Authorization header. - - Kong will either proxy the request to your upstream services if the token's signature is verified, or discard the request if not. Kong can also perform verifications on some of the registered claims of RFC 7519 (exp and nbf). - -
- Note: The functionality of this plugin as bundled - with versions of Kong Gateway (OSS) prior to 0.14.1 and Kong Gateway prior to 0.34 - differs from what is documented herein. Refer to the - CHANGELOG - for details. -
- - -type: plugin -categories: - - authentication - -kong_version_compatibility: - community_edition: - compatible: - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x - enterprise_edition: - compatible: - - 0.34-x - - 0.33-x - - 0.32-x - - 0.31-x - -params: - name: jwt - api_id: true - service_id: true - route_id: true - consumer_id: false - config: - - name: uri_param_names - required: false - default: "`jwt`" - description: A list of querystring parameters that Kong will inspect to retrieve JWTs. - - name: cookie_names - required: false - default: - description: A list of cookie names that Kong will inspect to retrieve JWTs. - - name: claims_to_verify - required: false - default: - description: | - A list of registered claims (according to [RFC 7519](https://tools.ietf.org/html/rfc7519)) that Kong can verify as well. Accepted values: `exp`, `nbf`. - - name: key_claim_name - required: false - default: "`iss`" - description: | - The name of the claim in which the `key` identifying the secret **must** be passed. Starting with version `0.13.1`, the plugin will attempt to read this claim from the JWT payload and the header, in this order. - - name: secret_is_base64 - required: false - default: "`false`" - description: | - If true, the plugin assumes the credential's `secret` to be base64 encoded. You will need to create a base64 encoded secret for your Consumer, and sign your JWT with the original secret. - - name: anonymous - required: false - default: - description: | - An optional string (consumer uuid) value to use as an "anonymous" consumer if authentication fails. If empty (default), the request will fail with an authentication failure `4xx`. Please note that this value must refer to the Consumer `id` attribute which is internal to Kong, and **not** its `custom_id`. - - name: run_on_preflight - required: false - default: "`true`" - description: | - A boolean value that indicates whether the plugin should run (and try to authenticate) on `OPTIONS` preflight requests, if set to `false` then `OPTIONS` requests will always be allowed. - - name: maximum_expiration - required: false - default: 0 - description: | - An integer limiting the lifetime of the JWT to `maximum_expiration` seconds in the future. Any JWT that has a longer lifetime will rejected (HTTP 403). If this value is specified, `exp` must be specified as well in the `claims_to_verify` property. The default value of `0` represents an indefinite period. Potential clock skew should be considered when configuring this setting. - - extra: | -
-
The option `config.run_on_preflight` is only available from version `0.11.1` and later
-
- ---- - -## Documentation - -In order to use the plugin, you first need to create a Consumer and associate one or more JWT credentials (holding the public and private keys used to verify the token) to it. The Consumer represents a developer using the final service. - -### Create a Consumer - -You need to associate a credential to an existing [Consumer][consumer-object] object. To create a Consumer, you can execute the following request: - -```bash -$ curl -X POST http://kong:8001/consumers \ - --data "username=" \ - --data "custom_id=" -HTTP/1.1 201 Created -``` - -form parameter | default | description ---- | --- | --- -`username`
*semi-optional* | | The username for this Consumer. Either this field or `custom_id` must be specified. -`custom_id`
*semi-optional* | | A custom identifier used to map the Consumer to an external database. Either this field or `username` must be specified. - -A [Consumer][consumer-object] can have many JWT credentials. - -### Create a JWT credential - -You can provision a new HS256 JWT credential by issuing the following HTTP request: - -```bash -$ curl -X POST http://kong:8001/consumers/{consumer}/jwt -H "Content-Type: application/x-www-form-urlencoded" -HTTP/1.1 201 Created - -{ - "consumer_id": "7bce93e1-0a90-489c-c887-d385545f8f4b", - "created_at": 1442426001000, - "id": "bcbfb45d-e391-42bf-c2ed-94e32946753a", - "key": "a36c3049b36249a3c9f8891cb127243c", - "secret": "e71829c351aa4242c2719cbfbe671c09" -} -``` - -- `consumer`: The `id` or `username` property of the [Consumer][consumer-object] entity to associate the credentials to. - -form parameter | default | description ---- | --- | --- -`key`
*optional* | | A unique string identifying the credential. If left out, it will be auto-generated. -`algorithm`
*optional* | `HS256` | The algorithm used to verify the token's signature. Can be `HS256`, `HS384`, `HS512`, `RS256`, or `ES256`. -`rsa_public_key`
*optional* | | If `algorithm` is `RS256` or `ES256`, the public key (in PEM format) to use to verify the token's signature. -`secret`
*optional* | | If `algorithm` is `HS256`, `HS384`, or `HS512`, the secret used to sign JWTs for this credential. If left out, will be auto-generated. - -### Delete a JWT credential - -You can remove a Consumer's JWT credential by issuing the following HTTP -request: - -```bash -$ curl -X DELETE http://kong:8001/consumers/{consumer}/jwt/{id} -HTTP/1.1 204 No Content -``` - -- `consumer`: The `id` or `username` property of the [Consumer][consumer-object] entity to associate the credentials to. -- `id`: The `id` of the JWT credential. - -### List JWT credentials - -You can list a Consumer's JWT credentials by issuing the following HTTP -request: - -```bash -$ curl -X GET http://kong:8001/consumers/{consumer}/jwt -HTTP/1.1 200 OK -``` - -- `consumer`: The `id` or `username` property of the - [Consumer][consumer-object] entity to list credentials for. - -```json -{ - "data": [ - { - "rsa_public_key": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgK .... -----END PUBLIC KEY-----", - "consumer_id": "39f52333-9741-48a7-9450-495960d91684", - "id": "3239880d-1de5-4dbc-bccf-78f7a4280f33", - "created_at": 1491430568000, - "key": "c5a55906cc244f483226e02bcff2b5e", - "algorithm": "RS256", - "secret": "b0970f7fc9564e65xklfn48930b5d08b1" - } - ], - "total": 1 -} -``` - -### Craft a JWT with a secret (HS256) - -Now that your Consumer has a credential, and assuming we want to sign it using `HS256`, the JWT should be crafted as follows (according to [RFC 7519](https://tools.ietf.org/html/rfc7519)): - -First, its header must be: - -```json -{ - "typ": "JWT", - "alg": "HS256" -} -``` - -Secondly, the claims **must** contain the secret's `key` in the configured claim (from `config.key_claim_name`). -That claim is `iss` (issuer field) by default. Set its value to our previously created credential's `key`. -The claims may contain other values. Since Kong `0.13.1`, the claim is searched in both the JWT payload and header, -in this order. - -```json -{ - "iss": "a36c3049b36249a3c9f8891cb127243c" -} -``` - -Using the JWT debugger at https://jwt.io with the header (HS256), claims (iss, etc), and `secret` associated with this `key` (e71829c351aa4242c2719cbfbe671c09), you'll end up with a JWT token of: - -``` -eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhMzZjMzA0OWIzNjI0OWEzYzlmODg5MWNiMTI3MjQzYyIsImV4cCI6MTQ0MjQzMDA1NCwibmJmIjoxNDQyNDI2NDU0LCJpYXQiOjE0NDI0MjY0NTR9.AhumfY35GFLuEEjrOXiaADo7Ae6gt_8VLwX7qffhQN4 -``` - -### Send a request with the JWT - -The JWT can now be included in a request to Kong by adding it to the `Authorization` header: - -```bash -$ curl http://kong:8000/{route path} \ - -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhMzZjMzA0OWIzNjI0OWEzYzlmODg5MWNiMTI3MjQzYyIsImV4cCI6MTQ0MjQzMDA1NCwibmJmIjoxNDQyNDI2NDU0LCJpYXQiOjE0NDI0MjY0NTR9.AhumfY35GFLuEEjrOXiaADo7Ae6gt_8VLwX7qffhQN4' -``` - -as a querystring parameter, if configured in `config.uri_param_names` (which contains `jwt` by default): - -```bash -$ curl http://kong:8000/{route path}?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhMzZjMzA0OWIzNjI0OWEzYzlmODg5MWNiMTI3MjQzYyIsImV4cCI6MTQ0MjQzMDA1NCwibmJmIjoxNDQyNDI2NDU0LCJpYXQiOjE0NDI0MjY0NTR9.AhumfY35GFLuEEjrOXiaADo7Ae6gt_8VLwX7qffhQN4 -``` - -or as cookie, if the name is configured in `config.cookie_names` (which is not enabled by default): - -```bash -curl --cookie jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhMzZjMzA0OWIzNjI0OWEzYzlmODg5MWNiMTI3MjQzYyIsImV4cCI6MTQ0MjQzMDA1NCwibmJmIjoxNDQyNDI2NDU0LCJpYXQiOjE0NDI0MjY0NTR9.AhumfY35GFLuEEjrOXiaADo7Ae6gt_8VLwX7qffhQN4 http://kong:8000/{route path} -``` - -The request will be inspected by Kong, whose behavior depends on the validity of the JWT: - -request | proxied to upstream service | response status code --------- |--------------------------|--------------------- -has no JWT | no | 401 -missing or invalid `iss` claim | no | 401 -invalid signature | no | 403 -valid signature | yes | from the upstream service -valid signature, invalid verified claim (**option**) | no | 403 - -
- Note: When the JWT is valid and proxied to the upstream service, Kong makes no modification to the request other than adding headers identifying the Consumer. The JWT will be forwarded to your upstream service, which can assume its validity. It is now the role of your service to base64 decode the JWT claims and make use of them. -
- -### (Optional) Verified claims - -Kong can also perform verification on registered claims, as defined in [RFC 7519](https://tools.ietf.org/html/rfc7519). To perform verification on a claim, add it to the `config.claims_to_verify` property: - -You can patch an existing jwt plugin: - -```bash -# This adds verification for both nbf and exp claims: -$ curl -X PATCH http://kong:8001/plugins/{jwt plugin id} \ - --data "config.claims_to_verify=exp,nbf" -``` - -Supported claims: - -claim name | verification ------------|------------- -`exp` | identifies the expiration time on or after which the JWT must not be accepted for processing. -`nbf` | identifies the time before which the JWT must not be accepted for processing. - -### (Optional) Base64 encoded secret - -If your secret contains binary data, you can store them as base64 encoded in Kong. Enable this option in the plugin's configuration: - -You can patch an existing Route: - -```bash -$ curl -X PATCH http://kong:8001/routes/{route id}/plugins/{jwt plugin id} \ - --data "config.secret_is_base64=true" -``` - -or patch an existing API: - -```bash -$ curl -X PATCH http://kong:8001/apis/{api}/plugins/{jwt plugin id} \ - --data "config.secret_is_base64=true" -``` -Then, base64 encode your consumers' secrets: - -```bash -# secret is: "blob data" -$ curl -X POST http://kong:8001/consumers/{consumer}/jwt \ - --data "secret=YmxvYiBkYXRh" -``` - -And sign your JWT using the original secret ("blob data"). - -### Craft a JWT with public/private keys (RS256 or ES256) - -If you wish to use RS256 or ES256 to verify your JWTs, then when creating a JWT credential, select `RS256` or `ES256` as the `algorithm`, and explicitly upload the public key in the `rsa_public_key` field (including for ES256 signed tokens). For example: - -```bash -$ curl -X POST http://kong:8001/consumers/{consumer}/jwt \ - -F "rsa_public_key=@/path/to/public_key.pem" \ -HTTP/1.1 201 Created - -{ - "consumer_id": "7bce93e1-0a90-489c-c887-d385545f8f4b", - "created_at": 1442426001000, - "id": "bcbfb45d-e391-42bf-c2ed-94e32946753a", - "key": "a36c3049b36249a3c9f8891cb127243c", - "rsa_public_key": "-----BEGIN PUBLIC KEY----- ..." -} -``` - -When creating the signature, make sure that the header is: - -```json -{ - "typ": "JWT", - "alg": "RS256" -} -``` - -Secondly, the claims **must** contain the secret's `key` field (this **isn't** your private key used to generate -the token, but just an identifier for this credential) in the configured claim (from `config.key_claim_name`). -That claim is `iss` (issuer field) by default. Set its value to our previously created credential's `key`. -The claims may contain other values. Since Kong `0.13.1`, the claim is searched in both the JWT payload and header, -in this order. - -```json -{ - "iss": "a36c3049b36249a3c9f8891cb127243c" -} -``` - -Then create the signature using your private keys. Using the JWT debugger at https://jwt.io, set the right header (RS256), the claims (iss, etc), and the associated public key. Then append the resulting value in the `Authorization` header, for example: - -```bash -$ curl http://kong:8000/{route path} \ - -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiIxM2Q1ODE0NTcyZTc0YTIyYjFhOWEwMDJmMmQxN2MzNyJ9.uNPTnDZXVShFYUSiii78Q-IAfhnc2ExjarZr_WVhGrHHBLweOBJxGJlAKZQEKE4rVd7D6hCtWSkvAAOu7BU34OnlxtQqB8ArGX58xhpIqHtFUkj882JQ9QD6_v2S2Ad-EmEx5402ge71VWEJ0-jyH2WvfxZ_pD90n5AG5rAbYNAIlm2Ew78q4w4GVSivpletUhcv31-U3GROsa7dl8rYMqx6gyo9oIIDcGoMh3bu8su5kQc5SQBFp1CcA5H8sHGfYs-Et5rCU2A6yKbyXtpHrd1Y9oMrZpEfQdgpLae0AfWRf6JutA9SPhst9-5rn4o3cdUmto_TBGqHsFmVyob8VQ' -``` - -### Generate public/private keys - -To create a brand new pair of public/private keys, you can run the following command: - -```bash -$ openssl genrsa -out private.pem 2048 -``` - -This private key must be kept secret. To generate a public key corresponding to the private key, execute: - -```bash -$ openssl rsa -in private.pem -outform PEM -pubout -out public.pem -``` - -If you run the commands above, the public key will be written in `public.pem`, while the private key will be written in `private.pem`. - -### Using the JWT plugin with Auth0 - -[Auth0](https://auth0.com/) is a popular solution for Authorization, and relies -heavily on JWTs. Auth0 relies on RS256, does not base64 encode, and publicly -hosts the public key certificate used to sign tokens. Account name is referred -to "COMPANYNAME" for the sake of the guide. - -To get started, create a Service, a Route that uses that Service, *or* create -an API. _Note: Auth0 does not use base64 encoded secrets._ - -Create a Service: - -```bash -$ curl -i -f -X POST http://localhost:8001/services \ - --data "name=example-service" \ - --data "=http://httpbin.org" -``` - -Then create a Route: - -```bash -$ curl -i -f -X POST http://localhost:8001/routes \ - --data "service.id={example-service's id}" \ - --data "paths[]=/example_path" -``` - - -or create an API, note these are depreciated: - -```bash -$ curl -i -X POST http://localhost:8001/apis \ - --data "name={api}" \ - --data "hosts=example.com" \ - --data "upstream_url=http://httpbin.org" -``` - -Add the JWT Plugin: - -Add the plugin to your Route: - -```bash -$ curl -X POST http://localhost:8001/route/{route id}/plugins \ - --data "name=jwt" -``` - -Add the plugin to your API: - -```bash -$ curl -X POST http://localhost:8001/apis/{api}/plugins \ - --data "name=jwt" -``` - -Download your Auth0 account's X509 Certificate: - -```bash -$ curl -o {COMPANYNAME}.pem https://{COMPANYNAME}.auth0.com/pem -``` - -Extract the public key from the X509 Certificate: - -```bash -$ openssl x509 -pubkey -noout -in {COMPANYNAME}.pem > pubkey.pem -``` - -Create a Consumer with the Auth0 public key: - -```bash -$ curl -i -X POST http://kong:8001/consumers \ - --data "username=" \ - --data "custom_id=" - -$ curl -i -X POST http://localhost:8001/consumers/{consumer}/jwt \ - -F "algorithm=RS256" \ - -F "rsa_public_key=@./pubkey.pem" \ - -F "key=https://{COMPANYNAME}.auth0.com/" # the `iss` field -``` - -The JWT plugin by default validates the `key_claim_name` against the `iss` -field in the token. Keys issued by Auth0 have their `iss` field set to -`http://{COMPANYNAME}.auth0.com/`. You can use [jwt.io](https://jwt.io) to -validate the `iss` field for the `key` parameter when creating the -Consumer. - -Send requests through, only tokens signed by Auth0 will work: - -```bash -$ curl -i http://localhost:8000 \ - -H "Host:example.com" \ - -H "Authorization:Bearer {{TOKEN}}" -``` - -### Upstream Headers - -When a JWT is valid, a Consumer has been authenticated, the plugin will append some headers to the request before proxying it to the upstream service, so that you can identify the Consumer in your code: - -* `X-Consumer-ID`, the ID of the Consumer on Kong -* `X-Consumer-Custom-ID`, the `custom_id` of the Consumer (if set) -* `X-Consumer-Username`, the `username` of the Consumer (if set) -* `X-Anonymous-Consumer`, will be set to `true` when authentication failed, and the 'anonymous' consumer was set instead. - -You can use this information on your side to implement additional logic. You can use the `X-Consumer-ID` value to query the Kong Admin API and retrieve more information about the Consumer. - -### Paginate through the JWTs - -
- Note: This endpoint was introduced in Kong 0.11.2. -
- -You can paginate through the JWTs for all Consumers using the following -request: - -```bash -$ curl -X GET http://kong:8001/jwts - -{ - "total": 3, - "data": [ - { - "created_at": 1509593911000, - "id": "381879e5-04a1-4c8a-9517-f85fbf90c3bc", - "algorithm": "HS256", - "key": "UHVwIly5ZxZH7g52E0HRlFkFC09v9yI0", - "secret": "KMWyDsTTcZgqqyOGgRWTDgZtIyWeEtJh", - "consumer_id": "3c2c8fc1-7245-4fbb-b48b-e5947e1ce941" - }, - { - "created_at": 1511389527000, - "id": "0dfc969b-02be-42ae-9d98-e04ed1c05850", - "algorithm": "ES256", - "key": "vcc1NlsPfK3N6uU03YdNrDZhzmFF4S19", - "secret": "b65Rs6wvnWPYaCEypNU7FnMOZ4lfMGM7", - "consumer_id": "c0d92ba9-8306-482a-b60d-0cfdd2f0e880" - }, - { - "created_at": 1509593912000, - "id": "d10c6f3b-71f1-424e-b1db-366abb783460", - "algorithm": "HS256", - "key": "SqSNfg9ARmPnpycyJSMAc2uR6nxdmc9S", - "secret": "CCh6ZIcwDSOIWacqkkWoJ0FWdZ5eTqrx", - "consumer_id": "3c2c8fc1-7245-4fbb-b48b-e5947e1ce941" - } - ] -} -``` - -You can filter the list using the following query parameters: - -Attributes | Description ----:| --- -`id`
*optional* | A filter on the list based on the JWT credential `id` field. -`key`
*optional* | A filter on the list based on the JWT credential `key` field. -`consumer_id`
*optional* | A filter on the list based on the JWT credential `consumer_id` field. -`size`
*optional, default is __100__* | A limit on the number of objects to be returned. -`offset`
*optional* | A cursor used for pagination. `offset` is an object identifier that defines a place in the list. - -### Retrieve the Consumer associated with a JWT - -
- Note: This endpoint was introduced in Kong 0.11.2. -
- -It is possible to retrieve a [Consumer][consumer-object] associated with a JWT -using the following request: - -```bash -curl -X GET http://kong:8001/jwts/{key or id}/consumer - -{ - "created_at":1507936639000, - "username":"foo", - "id":"c0d92ba9-8306-482a-b60d-0cfdd2f0e880" -} -``` - -`key or id`: The `id` or `key` property of the JWT for which to get the -associated [Consumer][consumer-object]. - -[api-object]: /gateway/latest/admin-api/#api-object -[configuration]: /gateway/latest/reference/configuration -[consumer-object]: /gateway/latest/admin-api/#consumer-object - diff --git a/app/_hub/kong-inc/jwt/2.1-x.md b/app/_hub/kong-inc/jwt/2.1-x.md deleted file mode 100644 index 66165d4f0522..000000000000 --- a/app/_hub/kong-inc/jwt/2.1-x.md +++ /dev/null @@ -1,585 +0,0 @@ ---- -name: JWT -publisher: Kong Inc. -version: 2.1-x - -desc: Verify and authenticate JSON Web Tokens -description: | - Verify requests containing HS256 or RS256 signed JSON Web Tokens (as specified in [RFC 7519](https://tools.ietf.org/html/rfc7519)). Each of your Consumers will have JWT credentials (public and secret keys) which must be used to sign their JWTs. A token can then be passed through: - - - a query string parameter, - - a cookie, - - or HTTP request headers - - Kong will either proxy the request to your upstream services if the token's signature is verified, or discard the request if not. Kong can also perform verifications on some of the registered claims of RFC 7519 (exp and nbf). - -
- Note: The functionality of this plugin as bundled - with versions of Kong Gateway (OSS) prior to 0.14.1 and Kong Gateway prior to 0.34 - differs from what is documented herein. Refer to the - CHANGELOG - for details. -
- - -type: plugin -categories: - - authentication - -kong_version_compatibility: - community_edition: - compatible: - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x - enterprise_edition: - compatible: - - 1.5.x - - 1.3-x - - 0.36-x - - 0.35-x - - 0.34-x - - 0.33-x - - 0.32-x - - 0.31-x - -params: - name: jwt - service_id: true - route_id: true - consumer_id: false - protocols: ["http", "https"] - dbless_compatible: partially - dbless_explanation: | - Consumers and JWT secrets can be created with declarative configuration. - - Admin API endpoints which do POST, PUT, PATCH or DELETE on secrets are not available on DB-less mode. - config: - - name: uri_param_names - required: false - default: "`jwt`" - description: A list of querystring parameters that Kong will inspect to retrieve JWTs. - - name: cookie_names - required: false - default: - description: A list of cookie names that Kong will inspect to retrieve JWTs. - - name: header_names - required: false - default: "`Authorization`" - description: A list of HTTP header names that Kong will inspect to retrieve JWTs. - - name: claims_to_verify - required: false - default: - description: | - A list of registered claims (according to [RFC 7519](https://tools.ietf.org/html/rfc7519)) that Kong can verify as well. Accepted values: `exp`, `nbf`. - - name: key_claim_name - required: false - default: "`iss`" - description: | - The name of the claim in which the `key` identifying the secret **must** be passed. Starting with version `0.13.1`, the plugin will attempt to read this claim from the JWT payload and the header, in this order. - - name: secret_is_base64 - required: false - default: "`false`" - description: | - If true, the plugin assumes the credential's `secret` to be base64 encoded. You will need to create a base64 encoded secret for your Consumer, and sign your JWT with the original secret. - - name: anonymous - required: false - default: - description: | - An optional string (consumer uuid) value to use as an "anonymous" consumer if authentication fails. If empty (default), the request will fail with an authentication failure `4xx`. Please note that this value must refer to the Consumer `id` attribute which is internal to Kong, and **not** its `custom_id`. - - name: run_on_preflight - required: false - default: "`true`" - description: | - A boolean value that indicates whether the plugin should run (and try to authenticate) on `OPTIONS` preflight requests, if set to `false` then `OPTIONS` requests will always be allowed. - - name: maximum_expiration - required: false - default: 0 - description: | - An integer limiting the lifetime of the JWT to `maximum_expiration` seconds in the future. Any JWT that has a longer lifetime will rejected (HTTP 403). If this value is specified, `exp` must be specified as well in the `claims_to_verify` property. The default value of `0` represents an indefinite period. Potential clock skew should be considered when configuring this setting. - - extra: | -
-
The option `config.run_on_preflight` is only available from version `0.11.1` and later
-
- ---- - -## Documentation - -In order to use the plugin, you first need to create a Consumer and associate one or more JWT credentials (holding the public and private keys used to verify the token) to it. The Consumer represents a developer using the final service. - -### Create a Consumer - -You need to associate a credential to an existing [Consumer][consumer-object] object. -A Consumer can have many credentials. - -{% navtabs %} -{% navtab With a Database %} -To create a Consumer, you can execute the following request: - -```bash -curl -d "username=user123&custom_id=SOME_CUSTOM_ID" http://kong:8001/consumers/ -``` -{% endnavtab %} -{% navtab Without a Database %} -Your declarative configuration file will need to have one or more Consumers. You can create them -on the `consumers:` yaml section: - -``` yaml -consumers: -- username: user123 - custom_id: SOME_CUSTOM_ID -``` -{% endnavtab %} -{% endnavtabs %} - -In both cases, the parameters are as described below: - -parameter | description ---- | --- -`username`
*semi-optional* | The username of the consumer. Either this field or `custom_id` must be specified. -`custom_id`
*semi-optional* | A custom identifier used to map the consumer to another database. Either this field or `username` must be specified. - - -### Create a JWT credential - -{% navtabs %} -{% navtab With a database %} -You can provision a new HS256 JWT credential by issuing the following HTTP request: - -```bash -$ curl -X POST http://kong:8001/consumers/{consumer}/jwt -H "Content-Type: application/x-www-form-urlencoded" -HTTP/1.1 201 Created - -{ - "consumer_id": "7bce93e1-0a90-489c-c887-d385545f8f4b", - "created_at": 1442426001000, - "id": "bcbfb45d-e391-42bf-c2ed-94e32946753a", - "key": "a36c3049b36249a3c9f8891cb127243c", - "secret": "e71829c351aa4242c2719cbfbe671c09" -} -``` -{% endnavtab %} -{% navtab Without a database %} -You can add JWT credentials on your declarative config file on the `jwt_secrets:` yaml entry: - -``` yaml -jwt_secrets: -- consumer: {consumer} -``` -{% endnavtab %} -{% endnavtabs %} - -In both cases the fields/parameters work as follows: - -field/parameter | default | description ---- | --- | --- -`{consumer}` | | The `id` or `username` property of the [Consumer][consumer-object] entity to associate the credentials to. -`key`
*optional* | | A unique string identifying the credential. If left out, it will be auto-generated. -`algorithm`
*optional* | `HS256` | The algorithm used to verify the token's signature. Can be `HS256`, `HS384`, `HS512`, `RS256`, or `ES256`. -`rsa_public_key`
*optional* | | If `algorithm` is `RS256` or `ES256`, the public key (in PEM format) to use to verify the token's signature. -`secret`
*optional* | | If `algorithm` is `HS256`, `HS384`, or `HS512`, the secret used to sign JWTs for this credential. If left out, will be auto-generated. - -### Delete a JWT credential - -You can remove a Consumer's JWT credential by issuing the following HTTP -request: - -```bash -$ curl -X DELETE http://kong:8001/consumers/{consumer}/jwt/{id} -HTTP/1.1 204 No Content -``` - -- `consumer`: The `id` or `username` property of the [Consumer][consumer-object] entity to associate the credentials to. -- `id`: The `id` of the JWT credential. - -### List JWT credentials - -You can list a Consumer's JWT credentials by issuing the following HTTP -request: - -```bash -$ curl -X GET http://kong:8001/consumers/{consumer}/jwt -HTTP/1.1 200 OK -``` - -- `consumer`: The `id` or `username` property of the - [Consumer][consumer-object] entity to list credentials for. - -```json -{ - "data": [ - { - "rsa_public_key": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgK .... -----END PUBLIC KEY-----", - "consumer_id": "39f52333-9741-48a7-9450-495960d91684", - "id": "3239880d-1de5-4dbc-bccf-78f7a4280f33", - "created_at": 1491430568000, - "key": "c5a55906cc244f483226e02bcff2b5e", - "algorithm": "RS256", - "secret": "b0970f7fc9564e65xklfn48930b5d08b1" - } - ], - "total": 1 -} -``` - -### Craft a JWT with a secret (HS256) - -Now that your Consumer has a credential, and assuming we want to sign it using `HS256`, the JWT should be crafted as follows (according to [RFC 7519](https://tools.ietf.org/html/rfc7519)): - -First, its header must be: - -```json -{ - "typ": "JWT", - "alg": "HS256" -} -``` - -Secondly, the claims **must** contain the secret's `key` in the configured claim (from `config.key_claim_name`). -That claim is `iss` (issuer field) by default. Set its value to our previously created credential's `key`. -The claims may contain other values. Since Kong `0.13.1`, the claim is searched in both the JWT payload and header, -in this order. - -```json -{ - "iss": "a36c3049b36249a3c9f8891cb127243c" -} -``` - -Using the JWT debugger at https://jwt.io with the header (HS256), claims (iss, etc), and `secret` associated with this `key` (e71829c351aa4242c2719cbfbe671c09), you'll end up with a JWT token of: - -``` -eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhMzZjMzA0OWIzNjI0OWEzYzlmODg5MWNiMTI3MjQzYyIsImV4cCI6MTQ0MjQzMDA1NCwibmJmIjoxNDQyNDI2NDU0LCJpYXQiOjE0NDI0MjY0NTR9.AhumfY35GFLuEEjrOXiaADo7Ae6gt_8VLwX7qffhQN4 -``` - -### Send a request with the JWT - -The JWT can now be included in a request to Kong by adding it as a header, if configured in `config.header_names` (which contains `Authorization` by default): - -```bash -$ curl http://kong:8000/{route path} \ - -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhMzZjMzA0OWIzNjI0OWEzYzlmODg5MWNiMTI3MjQzYyIsImV4cCI6MTQ0MjQzMDA1NCwibmJmIjoxNDQyNDI2NDU0LCJpYXQiOjE0NDI0MjY0NTR9.AhumfY35GFLuEEjrOXiaADo7Ae6gt_8VLwX7qffhQN4' -``` - -as a querystring parameter, if configured in `config.uri_param_names` (which contains `jwt` by default): - -```bash -$ curl http://kong:8000/{route path}?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhMzZjMzA0OWIzNjI0OWEzYzlmODg5MWNiMTI3MjQzYyIsImV4cCI6MTQ0MjQzMDA1NCwibmJmIjoxNDQyNDI2NDU0LCJpYXQiOjE0NDI0MjY0NTR9.AhumfY35GFLuEEjrOXiaADo7Ae6gt_8VLwX7qffhQN4 -``` - -or as cookie, if the name is configured in `config.cookie_names` (which is not enabled by default): - -```bash -curl --cookie jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhMzZjMzA0OWIzNjI0OWEzYzlmODg5MWNiMTI3MjQzYyIsImV4cCI6MTQ0MjQzMDA1NCwibmJmIjoxNDQyNDI2NDU0LCJpYXQiOjE0NDI0MjY0NTR9.AhumfY35GFLuEEjrOXiaADo7Ae6gt_8VLwX7qffhQN4 http://kong:8000/{route path} -``` - -The request will be inspected by Kong, whose behavior depends on the validity of the JWT: - -request | proxied to upstream service | response status code --------- |--------------------------|--------------------- -has no JWT | no | 401 -missing or invalid `iss` claim | no | 401 -invalid signature | no | 401 -valid signature | yes | from the upstream service -valid signature, invalid verified claim _optional_ | no | 401 - -
- Note: When the JWT is valid and proxied to the upstream service, Kong makes no modification to the request other than adding headers identifying the Consumer. The JWT will be forwarded to your upstream service, which can assume its validity. It is now the role of your service to base64 decode the JWT claims and make use of them. -
- -### (Optional) Verified claims - -Kong can also perform verification on registered claims, as defined in [RFC 7519](https://tools.ietf.org/html/rfc7519). To perform verification on a claim, add it to the `config.claims_to_verify` property: - -You can patch an existing jwt plugin: - -```bash -# This adds verification for both nbf and exp claims: -$ curl -X PATCH http://kong:8001/plugins/{jwt plugin id} \ - --data "config.claims_to_verify=exp,nbf" -``` - -Supported claims: - -claim name | verification ------------|------------- -`exp` | identifies the expiration time on or after which the JWT must not be accepted for processing. -`nbf` | identifies the time before which the JWT must not be accepted for processing. - -### (Optional) Base64 encoded secret - -If your secret contains binary data, you can store them as base64 encoded in Kong. Enable this option in the plugin's configuration: - -You can patch an existing Route: - -```bash -$ curl -X PATCH http://kong:8001/routes/{route id}/plugins/{jwt plugin id} \ - --data "config.secret_is_base64=true" -``` - -Then, base64 encode your consumers' secrets: - -```bash -# secret is: "blob data" -$ curl -X POST http://kong:8001/consumers/{consumer}/jwt \ - --data "secret=YmxvYiBkYXRh" -``` - -And sign your JWT using the original secret ("blob data"). - -### Craft a JWT with public/private keys (RS256 or ES256) - -If you wish to use RS256 or ES256 to verify your JWTs, then when creating a JWT credential, select `RS256` or `ES256` as the `algorithm`, and explicitly upload the public key in the `rsa_public_key` field (including for ES256 signed tokens). For example: - -```bash -$ curl -X POST http://kong:8001/consumers/{consumer}/jwt \ - -F "rsa_public_key=@/path/to/public_key.pem" \ -HTTP/1.1 201 Created - -{ - "consumer_id": "7bce93e1-0a90-489c-c887-d385545f8f4b", - "created_at": 1442426001000, - "id": "bcbfb45d-e391-42bf-c2ed-94e32946753a", - "key": "a36c3049b36249a3c9f8891cb127243c", - "rsa_public_key": "-----BEGIN PUBLIC KEY----- ..." -} -``` - -When creating the signature, make sure that the header is: - -```json -{ - "typ": "JWT", - "alg": "RS256" -} -``` - -Secondly, the claims **must** contain the secret's `key` field (this **isn't** your private key used to generate -the token, but just an identifier for this credential) in the configured claim (from `config.key_claim_name`). -That claim is `iss` (issuer field) by default. Set its value to our previously created credential's `key`. -The claims may contain other values. Since Kong `0.13.1`, the claim is searched in both the JWT payload and header, -in this order. - -```json -{ - "iss": "a36c3049b36249a3c9f8891cb127243c" -} -``` - -Then create the signature using your private keys. Using the JWT debugger at https://jwt.io, set the right header (RS256), the claims (iss, etc), and the associated public key. Then append the resulting value in the `Authorization` header, for example: - -```bash -$ curl http://kong:8000/{route path} \ - -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiIxM2Q1ODE0NTcyZTc0YTIyYjFhOWEwMDJmMmQxN2MzNyJ9.uNPTnDZXVShFYUSiii78Q-IAfhnc2ExjarZr_WVhGrHHBLweOBJxGJlAKZQEKE4rVd7D6hCtWSkvAAOu7BU34OnlxtQqB8ArGX58xhpIqHtFUkj882JQ9QD6_v2S2Ad-EmEx5402ge71VWEJ0-jyH2WvfxZ_pD90n5AG5rAbYNAIlm2Ew78q4w4GVSivpletUhcv31-U3GROsa7dl8rYMqx6gyo9oIIDcGoMh3bu8su5kQc5SQBFp1CcA5H8sHGfYs-Et5rCU2A6yKbyXtpHrd1Y9oMrZpEfQdgpLae0AfWRf6JutA9SPhst9-5rn4o3cdUmto_TBGqHsFmVyob8VQ' -``` - -### Generate public/private keys - -To create a brand new pair of public/private keys, you can run the following command: - -```bash -$ openssl genrsa -out private.pem 2048 -``` - -This private key must be kept secret. To generate a public key corresponding to the private key, execute: - -```bash -$ openssl rsa -in private.pem -outform PEM -pubout -out public.pem -``` - -If you run the commands above, the public key will be written in `public.pem`, while the private key will be written in `private.pem`. - -### Using the JWT plugin with Auth0 - -[Auth0](https://auth0.com/) is a popular solution for Authorization, and relies -heavily on JWTs. Auth0 relies on RS256, does not base64 encode, and publicly -hosts the public key certificate used to sign tokens. Account name is referred -to "COMPANYNAME" for the sake of the guide. - -To get started, create a Service and a Route that uses that Service. -_Note: Auth0 does not use base64 encoded secrets._ - -Create a Service: - -```bash -$ curl -i -f -X POST http://localhost:8001/services \ - --data "name=example-service" \ - --data "=http://httpbin.org" -``` - -Then create a Route: - -```bash -$ curl -i -f -X POST http://localhost:8001/routes \ - --data "service.id={example-service's id}" \ - --data "paths[]=/example_path" -``` - -Add the JWT Plugin: - -Add the plugin to your Route: - -```bash -$ curl -X POST http://localhost:8001/route/{route id}/plugins \ - --data "name=jwt" -``` - -Download your Auth0 account's X509 Certificate: - -```bash -$ curl -o {COMPANYNAME}.pem https://{COMPANYNAME}.auth0.com/pem -``` - -Extract the public key from the X509 Certificate: - -```bash -$ openssl x509 -pubkey -noout -in {COMPANYNAME}.pem > pubkey.pem -``` - -Create a Consumer with the Auth0 public key: - -```bash -$ curl -i -X POST http://kong:8001/consumers \ - --data "username=" \ - --data "custom_id=" - -$ curl -i -X POST http://localhost:8001/consumers/{consumer}/jwt \ - -F "algorithm=RS256" \ - -F "rsa_public_key=@./pubkey.pem" \ - -F "key=https://{COMPANYNAME}.auth0.com/" # the `iss` field -``` - -The JWT plugin by default validates the `key_claim_name` against the `iss` -field in the token. Keys issued by Auth0 have their `iss` field set to -`http://{COMPANYNAME}.auth0.com/`. You can use [jwt.io](https://jwt.io) to -validate the `iss` field for the `key` parameter when creating the -Consumer. - -Send requests through, only tokens signed by Auth0 will work: - -```bash -$ curl -i http://localhost:8000 \ - -H "Host:example.com" \ - -H "Authorization:Bearer {{TOKEN}}" -``` - -### Upstream Headers - -When a JWT is valid, a Consumer has been authenticated, the plugin will append some headers to the request before proxying it to the upstream service, so that you can identify the Consumer in your code: - -* `X-Consumer-ID`, the ID of the Consumer on Kong -* `X-Consumer-Custom-ID`, the `custom_id` of the Consumer (if set) -* `X-Consumer-Username`, the `username` of the Consumer (if set) -* `X-Anonymous-Consumer`, will be set to `true` when authentication failed, and the 'anonymous' consumer was set instead. - -You can use this information on your side to implement additional logic. You can use the `X-Consumer-ID` value to query the Kong Admin API and retrieve more information about the Consumer. - -### Paginate through the JWTs - -
- Note: This endpoint was introduced in Kong 0.11.2. -
- -You can paginate through the JWTs for all Consumers using the following -request: - -```bash -$ curl -X GET http://kong:8001/jwts - -{ - "total": 3, - "data": [ - { - "created_at": 1509593911000, - "id": "381879e5-04a1-4c8a-9517-f85fbf90c3bc", - "algorithm": "HS256", - "key": "UHVwIly5ZxZH7g52E0HRlFkFC09v9yI0", - "secret": "KMWyDsTTcZgqqyOGgRWTDgZtIyWeEtJh", - "consumer": { "id": "3c2c8fc1-7245-4fbb-b48b-e5947e1ce941" } - }, - { - "created_at": 1511389527000, - "id": "0dfc969b-02be-42ae-9d98-e04ed1c05850", - "algorithm": "ES256", - "key": "vcc1NlsPfK3N6uU03YdNrDZhzmFF4S19", - "secret": "b65Rs6wvnWPYaCEypNU7FnMOZ4lfMGM7", - "consumer": { "id": "c0d92ba9-8306-482a-b60d-0cfdd2f0e880" } - }, - { - "created_at": 1509593912000, - "id": "d10c6f3b-71f1-424e-b1db-366abb783460", - "algorithm": "HS256", - "key": "SqSNfg9ARmPnpycyJSMAc2uR6nxdmc9S", - "secret": "CCh6ZIcwDSOIWacqkkWoJ0FWdZ5eTqrx", - "consumer": { "id": "3c2c8fc1-7245-4fbb-b48b-e5947e1ce941" } - } - ] -} -``` - -You can filter the list by consumer by using this other path: - -```bash -$ curl -X GET http://kong:8001/consumers/{username or id}/jwt - -{ - "total": 1, - "data": [ - { - "created_at": 1511389527000, - "id": "0dfc969b-02be-42ae-9d98-e04ed1c05850", - "algorithm": "ES256", - "key": "vcc1NlsPfK3N6uU03YdNrDZhzmFF4S19", - "secret": "b65Rs6wvnWPYaCEypNU7FnMOZ4lfMGM7", - "consumer": { "id": "c0d92ba9-8306-482a-b60d-0cfdd2f0e880" } - - } - ] -} -``` - -`username or id`: The username or id of the consumer whose jwts need to be listed - - -### Retrieve the Consumer associated with a JWT - -
- Note: This endpoint was introduced in Kong 0.11.2. -
- -It is possible to retrieve a [Consumer][consumer-object] associated with a JWT -using the following request: - -```bash -curl -X GET http://kong:8001/jwts/{key or id}/consumer - -{ - "created_at":1507936639000, - "username":"foo", - "id":"c0d92ba9-8306-482a-b60d-0cfdd2f0e880" -} -``` - -`key or id`: The `id` or `key` property of the JWT for which to get the -associated [Consumer][consumer-object]. - -[api-object]: /gateway/latest/admin-api/#api-object -[configuration]: /gateway/latest/reference/configuration -[consumer-object]: /gateway/latest/admin-api/#consumer-object - diff --git a/app/_hub/kong-inc/jwt/_index.md b/app/_hub/kong-inc/jwt/_index.md index 490e1fc90e35..15745d94bc36 100644 --- a/app/_hub/kong-inc/jwt/_index.md +++ b/app/_hub/kong-inc/jwt/_index.md @@ -1,7 +1,6 @@ --- name: JWT publisher: Kong Inc. -version: 2.2.x desc: Verify and authenticate JSON Web Tokens description: | Verify requests containing HS256 or RS256 signed JSON Web Tokens (as specified @@ -21,45 +20,9 @@ categories: - authentication kong_version_compatibility: community_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x + compatible: true enterprise_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x + compatible: true params: name: jwt service_id: true @@ -179,7 +142,11 @@ parameter | description You can provision a new HS256 JWT credential by issuing the following HTTP request: ```bash -$ curl -X POST http://kong:8001/consumers/{consumer}/jwt -H "Content-Type: application/x-www-form-urlencoded" +curl -X POST http://kong:8001/consumers/{consumer}/jwt -H "Content-Type: application/x-www-form-urlencoded" +``` + +Response: +```json HTTP/1.1 201 Created { @@ -231,7 +198,11 @@ You can remove a Consumer's JWT credential by issuing the following HTTP request: ```bash -$ curl -X DELETE http://kong:8001/consumers/{consumer}/jwt/{id} +curl -X DELETE http://kong:8001/consumers/{consumer}/jwt/{id} +``` + +Response: +``` HTTP/1.1 204 No Content ``` @@ -244,7 +215,11 @@ You can list a Consumer's JWT credentials by issuing the following HTTP request: ```bash -$ curl -X GET http://kong:8001/consumers/{consumer}/jwt +curl -X GET http://kong:8001/consumers/{consumer}/jwt +``` + +Response: +``` HTTP/1.1 200 OK ``` @@ -293,7 +268,7 @@ in that order. } ``` -Using the JWT debugger at https://jwt.io with the header (HS256), claims (iss, etc.), +Using the JWT debugger at https://jwt.io with the header (HS256), claims (`iss`, etc.), and `secret` associated with this `key` (e71829c351aa4242c2719cbfbe671c09), you'll end up with a JWT token of: ``` @@ -305,14 +280,14 @@ eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhMzZjMzA0OWIzNjI0OWEzYzlmODg5MWN The JWT can now be included in a request to Kong by adding it as a header, if configured in `config.header_names` (which contains `Authorization` by default): ```bash -$ curl http://kong:8000/{route path} \ - -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhMzZjMzA0OWIzNjI0OWEzYzlmODg5MWNiMTI3MjQzYyIsImV4cCI6MTQ0MjQzMDA1NCwibmJmIjoxNDQyNDI2NDU0LCJpYXQiOjE0NDI0MjY0NTR9.AhumfY35GFLuEEjrOXiaADo7Ae6gt_8VLwX7qffhQN4' +curl http://kong:8000/{route path} \ + -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhMzZjMzA0OWIzNjI0OWEzYzlmODg5MWNiMTI3MjQzYyIsImV4cCI6MTQ0MjQzMDA1NCwibmJmIjoxNDQyNDI2NDU0LCJpYXQiOjE0NDI0MjY0NTR9.AhumfY35GFLuEEjrOXiaADo7Ae6gt_8VLwX7qffhQN4' ``` as a querystring parameter, if configured in `config.uri_param_names` (which contains `jwt` by default): ```bash -$ curl http://kong:8000/{route path}?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhMzZjMzA0OWIzNjI0OWEzYzlmODg5MWNiMTI3MjQzYyIsImV4cCI6MTQ0MjQzMDA1NCwibmJmIjoxNDQyNDI2NDU0LCJpYXQiOjE0NDI0MjY0NTR9.AhumfY35GFLuEEjrOXiaADo7Ae6gt_8VLwX7qffhQN4 +curl http://kong:8000/{route path}?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhMzZjMzA0OWIzNjI0OWEzYzlmODg5MWNiMTI3MjQzYyIsImV4cCI6MTQ0MjQzMDA1NCwibmJmIjoxNDQyNDI2NDU0LCJpYXQiOjE0NDI0MjY0NTR9.AhumfY35GFLuEEjrOXiaADo7Ae6gt_8VLwX7qffhQN4 ``` or as cookie, if the name is configured in `config.cookie_names` (which is not enabled by default): @@ -349,8 +324,8 @@ You can patch an existing JWT plugin: ```bash # This adds verification for both nbf and exp claims: -$ curl -X PATCH http://kong:8001/plugins/{jwt plugin id} \ - --data "config.claims_to_verify=exp,nbf" +curl -X PATCH http://kong:8001/plugins/{jwt plugin id} \ + --data "config.claims_to_verify=exp,nbf" ``` Supported claims: @@ -368,15 +343,15 @@ Enable this option in the plugin's configuration. You can patch an existing Route: ```bash -$ curl -X PATCH http://kong:8001/routes/{route id}/plugins/{jwt plugin id} \ - --data "config.secret_is_base64=true" +curl -X PATCH http://kong:8001/routes/{route id}/plugins/{jwt plugin id} \ + --data "config.secret_is_base64=true" ``` Then, base64 encode your Consumers' secrets: ```bash # secret is: "blob data" -$ curl -X POST http://kong:8001/consumers/{consumer}/jwt \ +curl -X POST http://kong:8001/consumers/{consumer}/jwt \ --data "secret=YmxvYiBkYXRh" ``` @@ -389,8 +364,12 @@ select `RS256` or `ES256` as the `algorithm`, and explicitly upload the public k in the `rsa_public_key` field (including for ES256 signed tokens). For example: ```bash -$ curl -X POST http://kong:8001/consumers/{consumer}/jwt \ - -F "rsa_public_key=@/path/to/public_key.pem" \ +curl -X POST http://kong:8001/consumers/{consumer}/jwt \ + -F "rsa_public_key=@/path/to/public_key.pem" \ +``` + +Response: +```json HTTP/1.1 201 Created { @@ -424,12 +403,12 @@ in that order. ``` Then, create the signature using your private keys. Using the JWT debugger at -[https://jwt.io](https://jwt.io), set the right header (RS256), the claims (iss, etc.), and the +[https://jwt.io](https://jwt.io), set the right header (RS256), the claims (`iss`, etc.), and the associated public key. Then, append the resulting value in the `Authorization` header, for example: ```bash -$ curl http://kong:8000/{route path} \ - -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiIxM2Q1ODE0NTcyZTc0YTIyYjFhOWEwMDJmMmQxN2MzNyJ9.uNPTnDZXVShFYUSiii78Q-IAfhnc2ExjarZr_WVhGrHHBLweOBJxGJlAKZQEKE4rVd7D6hCtWSkvAAOu7BU34OnlxtQqB8ArGX58xhpIqHtFUkj882JQ9QD6_v2S2Ad-EmEx5402ge71VWEJ0-jyH2WvfxZ_pD90n5AG5rAbYNAIlm2Ew78q4w4GVSivpletUhcv31-U3GROsa7dl8rYMqx6gyo9oIIDcGoMh3bu8su5kQc5SQBFp1CcA5H8sHGfYs-Et5rCU2A6yKbyXtpHrd1Y9oMrZpEfQdgpLae0AfWRf6JutA9SPhst9-5rn4o3cdUmto_TBGqHsFmVyob8VQ' +curl http://kong:8000/{route path} \ + -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiIxM2Q1ODE0NTcyZTc0YTIyYjFhOWEwMDJmMmQxN2MzNyJ9.uNPTnDZXVShFYUSiii78Q-IAfhnc2ExjarZr_WVhGrHHBLweOBJxGJlAKZQEKE4rVd7D6hCtWSkvAAOu7BU34OnlxtQqB8ArGX58xhpIqHtFUkj882JQ9QD6_v2S2Ad-EmEx5402ge71VWEJ0-jyH2WvfxZ_pD90n5AG5rAbYNAIlm2Ew78q4w4GVSivpletUhcv31-U3GROsa7dl8rYMqx6gyo9oIIDcGoMh3bu8su5kQc5SQBFp1CcA5H8sHGfYs-Et5rCU2A6yKbyXtpHrd1Y9oMrZpEfQdgpLae0AfWRf6JutA9SPhst9-5rn4o3cdUmto_TBGqHsFmVyob8VQ' ``` ### Generate public/private keys @@ -437,13 +416,13 @@ $ curl http://kong:8000/{route path} \ To create a brand new pair of public/private keys, run the following command: ```bash -$ openssl genrsa -out private.pem 2048 +openssl genrsa -out private.pem 2048 ``` This private key must be kept secret. To generate a public key corresponding to the private key, execute: ```bash -$ openssl rsa -in private.pem -outform PEM -pubout -out public.pem +openssl rsa -in private.pem -outform PEM -pubout -out public.pem ``` If you run the commands above, the public key is written to `public.pem`, whereas the @@ -463,17 +442,17 @@ _Note: Auth0 does not use base64-encoded secrets._ Create a Service: ```bash -$ curl -i -f -X POST http://localhost:8001/services \ - --data "name=example-service" \ - --data "url=http://httpbin.org" +curl -i -f -X POST http://localhost:8001/services \ + --data "name=example-service" \ + --data "url=http://httpbin.org" ``` Then create a Route: ```bash -$ curl -i -f -X POST http://localhost:8001/routes \ - --data "service.id={example-service's id}" \ - --data "paths[]=/example_path" +curl -i -f -X POST http://localhost:8001/routes \ + --data "service.id={example-service's id}" \ + --data "paths[]=/example_path" ``` #### Add the JWT Plugin @@ -481,33 +460,33 @@ $ curl -i -f -X POST http://localhost:8001/routes \ Add the plugin to your Route: ```bash -$ curl -X POST http://localhost:8001/route/{route id}/plugins \ - --data "name=jwt" +curl -X POST http://localhost:8001/route/{route id}/plugins \ + --data "name=jwt" ``` Download your Auth0 account's X509 Certificate: ```bash -$ curl -o {COMPANYNAME}.pem https://{COMPANYNAME}.{REGION-ID}.auth0.com/pem +curl -o {COMPANYNAME}.pem https://{COMPANYNAME}.{REGION-ID}.auth0.com/pem ``` Extract the public key from the X509 Certificate: ```bash -$ openssl x509 -pubkey -noout -in {COMPANYNAME}.pem > pubkey.pem +openssl x509 -pubkey -noout -in {COMPANYNAME}.pem > pubkey.pem ``` Create a Consumer with the Auth0 public key: ```bash -$ curl -i -X POST http://kong:8001/consumers \ - --data "username=" \ - --data "custom_id=" +curl -i -X POST http://kong:8001/consumers \ + --data "username=" \ + --data "custom_id=" -$ curl -i -X POST http://localhost:8001/consumers/{consumer}/jwt \ - -F "algorithm=RS256" \ - -F "rsa_public_key=@./pubkey.pem" \ - -F "key=https://{COMPANYNAME}.auth0.com/" # the `iss` field +curl -i -X POST http://localhost:8001/consumers/{consumer}/jwt \ + -F "algorithm=RS256" \ + -F "rsa_public_key=@./pubkey.pem" \ + -F "key=https://{COMPANYNAME}.auth0.com/" # the `iss` field ``` The JWT plugin by default validates the `key_claim_name` against the `iss` @@ -519,9 +498,9 @@ Consumer. Send requests through. Only tokens signed by Auth0 will work: ```bash -$ curl -i http://localhost:8000 \ - -H "Host:example.com" \ - -H "Authorization:Bearer " +curl -i http://localhost:8000 \ + -H "Host:example.com" \ + -H "Authorization:Bearer " ``` ### Upstream Headers @@ -550,8 +529,11 @@ You can paginate through the JWTs for all Consumers using the following request: ```bash -$ curl -X GET http://kong:8001/jwts +curl -X GET http://kong:8001/jwts +``` +Response: +```json { "total": 3, "data": [ @@ -586,8 +568,11 @@ $ curl -X GET http://kong:8001/jwts You can filter the list by consumer by using this other path: ```bash -$ curl -X GET http://kong:8001/consumers/{username or id}/jwt +curl -X GET http://kong:8001/consumers/{username or id}/jwt +``` +Response: +```json { "total": 1, "data": [ @@ -618,7 +603,10 @@ using the following request: ```bash curl -X GET http://kong:8001/jwts/{key or id}/consumer +``` +Response: +```json { "created_at":1507936639000, "username":"foo", @@ -632,4 +620,3 @@ associated [Consumer][consumer-object]. [api-object]: /gateway/latest/admin-api/#api-object [configuration]: /gateway/latest/reference/configuration [consumer-object]: /gateway/latest/admin-api/#consumer-object - diff --git a/app/_hub/kong-inc/jwt/versions.yml b/app/_hub/kong-inc/jwt/versions.yml index 14405d124ae7..66a1be48947c 100644 --- a/app/_hub/kong-inc/jwt/versions.yml +++ b/app/_hub/kong-inc/jwt/versions.yml @@ -1,3 +1,12 @@ -- release: 2.2-x -- release: 2.1-x -- release: 0.1-x +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 2.2.0 + 2.7.x: 2.2.0 + 2.6.x: 2.2.0 + 2.5.x: 2.2.0 + 2.4.x: 2.2.0 + 2.3.x: 2.2.0 + 2.2.x: 2.2.0 + 2.1.x: 2.2.0 diff --git a/app/_hub/kong-inc/kafka-log/0.1.x.md b/app/_hub/kong-inc/kafka-log/_0.1.x.md similarity index 100% rename from app/_hub/kong-inc/kafka-log/0.1.x.md rename to app/_hub/kong-inc/kafka-log/_0.1.x.md diff --git a/app/_hub/kong-inc/kafka-log/0.2.x.md b/app/_hub/kong-inc/kafka-log/_0.2.x.md similarity index 100% rename from app/_hub/kong-inc/kafka-log/0.2.x.md rename to app/_hub/kong-inc/kafka-log/_0.2.x.md diff --git a/app/_hub/kong-inc/kafka-log/0.3.x.md b/app/_hub/kong-inc/kafka-log/_0.3.x.md similarity index 100% rename from app/_hub/kong-inc/kafka-log/0.3.x.md rename to app/_hub/kong-inc/kafka-log/_0.3.x.md diff --git a/app/_hub/kong-inc/kafka-log/_index.md b/app/_hub/kong-inc/kafka-log/_index.md index fd502191e3c1..442a33e1dc3d 100644 --- a/app/_hub/kong-inc/kafka-log/_index.md +++ b/app/_hub/kong-inc/kafka-log/_index.md @@ -70,8 +70,8 @@ params: Username for SASL authentication. This field is _referenceable_, which means it can be securely stored as a - [secret](/gateway/latest/plan-and-deploy/security/secrets-management/getting-started) - in a vault. References must follow a [specific format](/gateway/latest/plan-and-deploy/security/secrets-management/reference-format). + [secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). - name: authentication.password required: false value_in_examples: admin-secret @@ -83,8 +83,8 @@ params: Password for SASL authentication. This field is _referenceable_, which means it can be securely stored as a - [secret](/gateway/latest/plan-and-deploy/security/secrets-management/getting-started) - in a vault. References must follow a [specific format](/gateway/latest/plan-and-deploy/security/secrets-management/reference-format). + [secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). - name: authentication.tokenauth required: false value_in_examples: false @@ -313,7 +313,7 @@ Known limitations: ## Changelog -### Kong Gateway 2.8.x (plugin version 0.4.0) +**{{site.base_gateway}} 2.8.x** * Added support for the `SCRAM-SHA-512` authentication mechanism. @@ -322,9 +322,9 @@ Known limitations: * The `authentication.user` and `authentication.password` configuration fields are now marked as referenceable, which means they can be securely stored as [secrets](/gateway/latest/plan-and-deploy/security/secrets-management/getting-started) -in a vault. References must follow a [specific format](/gateway/latest/plan-and-deploy/security/secrets-management/reference-format). +in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). -### Kong Gateway 2.7.x (plugin version 0.3.0) +**{{site.base_gateway}} 2.7.x** * Starting with {{site.base_gateway}} 2.7.0.0, if keyring encryption is enabled, the `config.authentication.user` and `config.authentication.password` parameter diff --git a/app/_hub/kong-inc/kafka-log/versions.yml b/app/_hub/kong-inc/kafka-log/versions.yml index 0d46db4aa615..451183e6e35b 100644 --- a/app/_hub/kong-inc/kafka-log/versions.yml +++ b/app/_hub/kong-inc/kafka-log/versions.yml @@ -1,4 +1,20 @@ -- release: 0.4.x -- release: 0.3.x -- release: 0.2.x -- release: 0.1.x +strategy: gateway +delegate_releases: true +sources: + 2.7.x: _0.3.x + 2.6.x: _0.2.x + 2.5.x: _0.1.x + 2.4.x: _0.1.x + 2.3.x: _0.1.x + 2.2.x: _0.1.x + 2.1.x: _0.1.x + +overrides: + 2.8.x: 0.4.0 + 2.7.x: 0.3.0 + 2.6.x: 0.2.0 + 2.5.x: 0.1.1 + 2.4.x: 0.1.1 + 2.3.x: 0.1.1 + 2.2.x: 0.1.1 + 2.1.x: 0.1.0 diff --git a/app/_hub/kong-inc/kafka-upstream/0.1.x.md b/app/_hub/kong-inc/kafka-upstream/_0.1.x.md similarity index 100% rename from app/_hub/kong-inc/kafka-upstream/0.1.x.md rename to app/_hub/kong-inc/kafka-upstream/_0.1.x.md diff --git a/app/_hub/kong-inc/kafka-upstream/0.2.x.md b/app/_hub/kong-inc/kafka-upstream/_0.2.x.md similarity index 100% rename from app/_hub/kong-inc/kafka-upstream/0.2.x.md rename to app/_hub/kong-inc/kafka-upstream/_0.2.x.md diff --git a/app/_hub/kong-inc/kafka-upstream/0.3.x.md b/app/_hub/kong-inc/kafka-upstream/_0.3.x.md similarity index 100% rename from app/_hub/kong-inc/kafka-upstream/0.3.x.md rename to app/_hub/kong-inc/kafka-upstream/_0.3.x.md diff --git a/app/_hub/kong-inc/kafka-upstream/_index.md b/app/_hub/kong-inc/kafka-upstream/_index.md index 37eded0b29e0..ce5bad675ca4 100644 --- a/app/_hub/kong-inc/kafka-upstream/_index.md +++ b/app/_hub/kong-inc/kafka-upstream/_index.md @@ -72,8 +72,8 @@ params: Username for SASL authentication. This field is _referenceable_, which means it can be securely stored as a - [secret](/gateway/latest/plan-and-deploy/security/secrets-management/getting-started) - in a vault. References must follow a [specific format](/gateway/latest/plan-and-deploy/security/secrets-management/reference-format). + [secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). - name: authentication.password required: false value_in_examples: admin-secret @@ -85,8 +85,8 @@ params: Password for SASL authentication. This field is _referenceable_, which means it can be securely stored as a - [secret](/gateway/latest/plan-and-deploy/security/secrets-management/getting-started) - in a vault. References must follow a [specific format](/gateway/latest/plan-and-deploy/security/secrets-management/reference-format). + [secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). - name: authentication.tokenauth required: false value_in_examples: false @@ -376,7 +376,7 @@ The following steps assume that {{site.base_gateway}} is installed and the Kafka ## Changelog -### Kong Gateway 2.8.x (plugin version 0.4.0) +**{{site.base_gateway}} 2.8.x** * Added support for the `SCRAM-SHA-512` authentication mechanism. @@ -385,9 +385,9 @@ The following steps assume that {{site.base_gateway}} is installed and the Kafka * The `authentication.user` and `authentication.password` configuration fields are now marked as referenceable, which means they can be securely stored as [secrets](/gateway/latest/plan-and-deploy/security/secrets-management/getting-started) -in a vault. References must follow a [specific format](/gateway/latest/plan-and-deploy/security/secrets-management/reference-format). +in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). -### Kong Gateway 2.7.x (plugin version 0.3.0) +**{{site.base_gateway}} 2.7.x** * Starting with {{site.base_gateway}} 2.7.0.0, if keyring encryption is enabled, the `config.authentication.user` and `config.authentication.password` parameter diff --git a/app/_hub/kong-inc/kafka-upstream/versions.yml b/app/_hub/kong-inc/kafka-upstream/versions.yml index 0d46db4aa615..130b2acf811f 100644 --- a/app/_hub/kong-inc/kafka-upstream/versions.yml +++ b/app/_hub/kong-inc/kafka-upstream/versions.yml @@ -1,4 +1,20 @@ -- release: 0.4.x -- release: 0.3.x -- release: 0.2.x -- release: 0.1.x +strategy: gateway +delegate_releases: true +sources: + 2.7.x: _0.3.x + 2.6.x: _0.2.x + 2.5.x: _0.1.x + 2.4.x: _0.1.x + 2.3.x: _0.1.x + 2.2.x: _0.1.x + 2.1.x: _0.1.x + +overrides: + 2.8.x: 0.4.0 + 2.7.x: 0.3.0 + 2.6.x: 0.2.0 + 2.5.x: 0.0.2 + 2.4.x: 0.0.2 + 2.3.x: 0.0.2 + 2.2.x: 0.0.2 + 2.1.x: 0.0.2 diff --git a/app/_hub/kong-inc/key-auth-enc/1.0.x.md b/app/_hub/kong-inc/key-auth-enc/1.0.x.md deleted file mode 100644 index bf2405cbb327..000000000000 --- a/app/_hub/kong-inc/key-auth-enc/1.0.x.md +++ /dev/null @@ -1,247 +0,0 @@ ---- -name: Key Authentication - Encrypted -publisher: Kong Inc. -version: 1.0.x - -desc: Add key authentication to your Services -description: | - Add key authentication (also sometimes referred to as an API key) to a Service or a Route. Consumers then add their key either in a query string parameter or a header to authenticate their requests. This plugin is functionally identical to the open source `key-auth` plugin, with the exception that API keys are stored in an encrypted format within the Kong data store. - -enterprise: true -alpha: false -type: plugin -categories: - - authentication - -kong_version_compatibility: - enterprise_edition: - compatible: - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3.x - -params: - name: key-auth-enc - service_id: true - route_id: true - consumer_id: false - konnect_examples: false - protocols: ["http", "https"] - - config: - - name: key_names - required: false - default: "`apikey`" - value_in_examples: ["apikey"] - description: | - Describes an array of parameter names where the plugin will look for a key. The client must send the authentication key in one of those key names, and the plugin will try to read the credential from a header or the query string parameter with the same name.

**Note**: the key names may only contain [a-z], [A-Z], [0-9], [_] and [-]. - - name: key_in_body - required: false - default: "`false`" - description: | - If enabled, the plugin will read the request body (if said request has one and its MIME type is supported) and try to find the key in it. Supported MIME types are `application/www-form-urlencoded`, `application/json`, and `multipart/form-data`. - - name: hide_credentials - required: false - default: "`false`" - description: | - An optional boolean value telling the plugin to show or hide the credential from the upstream service. If `true`, the plugin will strip the credential from the request (i.e. the header or querystring containing the key) before proxying it. - - name: anonymous - required: false - default: - description: | - An optional string (consumer uuid) value to use as an "anonymous" consumer if authentication fails. If empty (default), the request will fail with an authentication failure `4xx`. Please note that this value must refer to the Consumer `id` attribute which is internal to Kong, and **not** its `custom_id`. - - name: run_on_preflight - required: false - default: "`true`" - description: | - A boolean value that indicates whether the plugin should run (and try to authenticate) on `OPTIONS` preflight requests, if set to `false` then `OPTIONS` requests will always be allowed. - extra: | - Note that, according to their respective specifications, HTTP header names are treated as case _insensitive_, while HTTP query string parameter names are treated as case _sensitive_. Kong follows these specifications as designed, meaning that the `key_names` configuration values will be treated differently when searching the request header fields, versus searching the query string. Administrators are advised against defining case-sensitive `key_names` values when expecting the authorization keys to be sent in the request headers. - -
-
The option `config.run_on_preflight` is only available from version `0.11.1` and later.
-
- - Once applied, any user with a valid credential can access the Service. - To restrict usage to only some of the authenticated users, also add the - [ACL](/plugins/acl/) plugin (not covered here) and create allowed or - denied groups of users. - ---- - -## Usage - -Prior to creating this plugin, Kong's encryption keyring must be enabled. See the [keyring Getting Started guide](/gateway/latest/plan-and-deploy/security/db-encryption#getting-started) for more details. - -### Create a Consumer - -You need to associate a credential to an existing [Consumer][consumer-object] object. -A Consumer can have many credentials. - -To create a Consumer, execute the following request: - -```bash -curl -d "username=user123&custom_id=SOME_CUSTOM_ID" http://kong:8001/consumers/ -``` -The parameters are as described below: - -parameter | description ---- | --- -`username`
*semi-optional* | The username of the consumer. Either this field or `custom_id` must be specified. -`custom_id`
*semi-optional* | A custom identifier used to map the consumer to another database. Either this field or `username` must be specified. - -If you are also using the [ACL](/plugins/acl/) plugin and allow lists with this -service, you must add the new consumer to the allowed group. See -[ACL: Associating Consumers][acl-associating] for details. - -### Create a Key - -You can provision new credentials by making the following HTTP request: - -```bash -$ curl -X POST http://kong:8001/consumers/{consumer}/key-auth-enc -d '' -HTTP/1.1 201 Created - -{ - "consumer": { "id": "876bf719-8f18-4ce5-cc9f-5b5af6c36007" }, - "created_at": 1443371053000, - "id": "62a7d3b7-b995-49f9-c9c8-bac4d781fb59", - "key": "62eb165c070a41d5c1b58d9d3d725ca1" -} -``` - -
- Note: It is recommended to let Kong auto-generate the key. Only specify it yourself if you are migrating an existing system to Kong. You must re-use your keys to make the migration to Kong transparent to your Consumers. -
- -The fields/parameters work as follows: - -field/parameter | description ---- | --- -`{consumer}` | The `id` or `username` property of the [Consumer][consumer-object] entity to associate the credentials to. -`key`
*optional* | You can optionally set your own unique `key` to authenticate the client. If missing, the plugin will generate one. - -### Using the Key - -Simply make a request with the key as a querystring parameter: - -```bash -$ curl http://kong:8000/{proxy path}?apikey= -``` - -Or in a header: - -```bash -$ curl http://kong:8000/{proxy path} \ - -H 'apikey: ' -``` - -### Delete a Key - -You can delete an API Key by making the following HTTP request: - -```bash -$ curl -X DELETE http://kong:8001/consumers/{consumer}/key-auth-enc/{id} -HTTP/1.1 204 No Content -``` - -* `consumer`: The `id` or `username` property of the [Consumer][consumer-object] entity to associate the credentials to. -* `id`: The `id` attribute of the key credential object. - -### Upstream Headers - -When a client has been authenticated, the plugin will append some headers to the request before proxying it to the upstream service, so that you can identify the Consumer in your code: - -* `X-Consumer-ID`, the ID of the Consumer on Kong -* `X-Consumer-Custom-ID`, the `custom_id` of the Consumer (if set) -* `X-Consumer-Username`, the `username` of the Consumer (if set) -* `X-Credential-Username`, the `username` of the Credential (only if the consumer is not the 'anonymous' consumer) -* `X-Anonymous-Consumer`, will be set to `true` when authentication failed, and the 'anonymous' consumer was set instead. - -You can use this information on your side to implement additional logic. You can use the `X-Consumer-ID` value to query the Kong Admin API and retrieve more information about the Consumer. - -### Paginate through keys - -
- Note: This endpoint was introduced in Kong 0.11.2. -
- -You can paginate through the API keys for all Consumers using the following -request: - -```bash -$ curl -X GET http://kong:8001/key-auth-encs - -{ - "data":[ - { - "id":"17ab4e95-9598-424f-a99a-ffa9f413a821", - "created_at":1507941267000, - "key":"Qslaip2ruiwcusuSUdhXPv4SORZrfj4L", - "consumer": { "id": "c0d92ba9-8306-482a-b60d-0cfdd2f0e880" } - }, - { - "id":"6cb76501-c970-4e12-97c6-3afbbba3b454", - "created_at":1507936652000, - "key":"nCztu5Jrz18YAWmkwOGJkQe9T8lB99l4", - "consumer": { "id": "c0d92ba9-8306-482a-b60d-0cfdd2f0e880" } - }, - { - "id":"b1d87b08-7eb6-4320-8069-efd85a4a8d89", - "created_at":1507941307000, - "key":"26WUW1VEsmwT1ORBFsJmLHZLDNAxh09l", - "consumer": { "id": "3c2c8fc1-7245-4fbb-b48b-e5947e1ce941" } - } - ] - "next":null, -} -``` - -You can filter the list by consumer by using this other path: - -```bash -$ curl -X GET http://kong:8001/consumers/{username or id}/key-auth-enc - -{ - "data": [ - { - "id":"6cb76501-c970-4e12-97c6-3afbbba3b454", - "created_at":1507936652000, - "key":"nCztu5Jrz18YAWmkwOGJkQe9T8lB99l4", - "consumer": { "id": "c0d92ba9-8306-482a-b60d-0cfdd2f0e880" } - } - ] - "next":null, -} -``` - -`username or id`: The username or id of the consumer whose credentials need to be listed - -### Retrieve the Consumer associated with a key - -
- Note: This endpoint was introduced in Kong 0.11.2. -
- -It is possible to retrieve a [Consumer][consumer-object] associated with an API -Key using the following request: - -```bash -curl -X GET http://kong:8001/key-auth-encs/{key or id}/consumer - -{ - "created_at":1507936639000, - "username":"foo", - "id":"c0d92ba9-8306-482a-b60d-0cfdd2f0e880" -} -``` - -* `key or id`: The `id` or `key` property of the API key for which to get the -associated Consumer. - -[db-encryption]: /gateway/latest/plan-and-deploy/security/db-encryption -[configuration]: /gateway/latest/reference/configuration -[consumer-object]: /gateway/latest/admin-api/#consumer-object -[acl-associating]: /plugins/acl/#associating-consumers - diff --git a/app/_hub/kong-inc/key-auth-enc/_index.md b/app/_hub/kong-inc/key-auth-enc/_index.md index 1a45f79330ab..3b3a75b31529 100644 --- a/app/_hub/kong-inc/key-auth-enc/_index.md +++ b/app/_hub/kong-inc/key-auth-enc/_index.md @@ -1,7 +1,6 @@ --- name: Key Authentication - Encrypted publisher: Kong Inc. -version: 2.0.x desc: Add key authentication to your Services description: | Add key authentication (also sometimes referred to as an _API key_) to a Service @@ -16,17 +15,7 @@ categories: - authentication kong_version_compatibility: enterprise_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3.x + compatible: true params: name: key-auth-enc service_id: true @@ -171,7 +160,7 @@ service, you must add the new Consumer to the allowed group. See Provision new credentials by making the following HTTP request: ```bash -$ curl -X POST http://kong:8001/consumers/{consumer}/key-auth-enc -d "" +curl -X POST http://kong:8001/consumers/{consumer}/key-auth-enc -d "" ``` Response: @@ -211,7 +200,7 @@ field/parameter | description Make a request with the key as a query string parameter: ```bash -$ curl http://kong:8000/{proxy path}?apikey= +curl http://kong:8000/{proxy path}?apikey= ``` **Note:** The `key_in_query` parameter must be set to `true` (default). @@ -219,8 +208,8 @@ $ curl http://kong:8000/{proxy path}?apikey= Make a request with the key in the body: ```bash -$ curl http://kong:8000/{proxy path} \ - --data 'apikey: ' +curl http://kong:8000/{proxy path} \ + --data 'apikey: ' ``` **Note:** The `key_in_body` parameter must be set to `true` (default is `false`). @@ -228,8 +217,8 @@ $ curl http://kong:8000/{proxy path} \ Make a request with the key in a header: ```bash -$ curl http://kong:8000/{proxy path} \ - -H 'apikey: ' +curl http://kong:8000/{proxy path} \ + -H 'apikey: ' ``` **Note:** The `key_in_header` parameter must be set to `true` (default). @@ -237,7 +226,7 @@ $ curl http://kong:8000/{proxy path} \ gRPC clients are supported too: ```bash -$ grpcurl -H 'apikey: ' ... +grpcurl -H 'apikey: ' ... ``` ### About API Key Locations in a Request @@ -259,7 +248,7 @@ curl -X POST http://:8001/routes//plugins \ Delete an API Key by making the following request: ```bash -$ curl -X DELETE http://kong:8001/consumers/{consumer}/key-auth-enc/{id} +curl -X DELETE http://kong:8001/consumers/{consumer}/key-auth-enc/{id} ``` Response: @@ -273,16 +262,7 @@ HTTP/1.1 204 No Content ### Upstream Headers -When a client has been authenticated, the plugin appends some headers to the request before -proxying it to the upstream service so that you can identify the Consumer in your code: - -* `X-Consumer-ID`, the ID of the Consumer on Kong -* `X-Consumer-Custom-ID`, the `custom_id` of the Consumer (if set) -* `X-Consumer-Username`, the `username` of the Consumer (if set) -* `X-Credential-Username`, the `username` of the Credential (only if the consumer is not the 'anonymous' consumer) -* `X-Anonymous-Consumer`, will be set to `true` when authentication failed, and the 'anonymous' consumer was set instead. - -You can use this information on your side to implement additional logic. You can use the `X-Consumer-ID` value to query the Kong Admin API and retrieve more information about the Consumer. +{% include_cached /md/plugins-hub/upstream-headers.md %} ### Paginate through keys @@ -290,7 +270,7 @@ Paginate through the API keys for all Consumers using the following request: ```bash -$ curl -X GET http://kong:8001/key-auths-enc +curl -X GET http://kong:8001/key-auths-enc ``` Response: @@ -325,7 +305,7 @@ Response: Filter the list by Consumer by using a different endpoint: ```bash -$ curl -X GET http://kong:8001/consumers/{username or id}/key-auth-enc +curl -X GET http://kong:8001/consumers/{username or id}/key-auth-enc ``` `username or id`: The username or id of the Consumer whose credentials need to be listed. @@ -378,8 +358,10 @@ associated Consumer. ## Changelog -### 2.0.0 +**{{site.base_gateway}} 3.0.x** +* The deprecated `X-Credential-Username` header has been removed. +**{{site.base_gateway}} 2.7.x** * If keyring encryption is enabled and you are using key authentication, the `keyauth_credentials.key` field will be encrypted. diff --git a/app/_hub/kong-inc/key-auth-enc/versions.yml b/app/_hub/kong-inc/key-auth-enc/versions.yml index feac59c09064..499736e2925a 100644 --- a/app/_hub/kong-inc/key-auth-enc/versions.yml +++ b/app/_hub/kong-inc/key-auth-enc/versions.yml @@ -1,2 +1,12 @@ -- release: 2.0.x -- release: 1.0.x +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 2.0.0 + 2.7.x: 2.0.0 + 2.6.x: 2.0.0 + 2.5.x: 2.0.0 + 2.4.x: 2.0.0 + 2.3.x: 2.0.0 + 2.2.x: 2.0.0 + 2.1.x: 2.0.0 diff --git a/app/_hub/kong-inc/key-auth/0.2.x.md b/app/_hub/kong-inc/key-auth/0.2.x.md deleted file mode 100644 index 9927328420ad..000000000000 --- a/app/_hub/kong-inc/key-auth/0.2.x.md +++ /dev/null @@ -1,262 +0,0 @@ ---- -name: Key Authentication -publisher: Kong Inc. -version: 0.2-x - -desc: Add key authentication to your APIs -description: | - Add Key Authentication (also sometimes referred to as an API key) to a Service or a Route (or the deprecated API entity). Consumers then add their key either in a querystring parameter or a header to authenticate their requests. - -
- Note: The functionality of this plugin as bundled - with versions of Kong prior to 0.11.2 - differs from what is documented herein. Refer to the - CHANGELOG - for details. -
- -type: plugin -categories: - - authentication - -kong_version_compatibility: - community_edition: - compatible: - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x - - 0.4.x - - 0.3.x - - 0.2.x - enterprise_edition: - compatible: - - 0.34-x - - 0.33-x - - 0.32-x - - 0.31-x - -params: - name: key-auth - api_id: true - service_id: true - route_id: true - consumer_id: false - config: - - name: key_names - required: false - default: "`apikey`" - value_in_examples: ["apikey"] - description: | - Describes an array of comma separated parameter names where the plugin will look for a key. The client must send the authentication key in one of those key names, and the plugin will try to read the credential from a header or the querystring parameter with the same name.
*note*: the key names may only contain [a-z], [A-Z], [0-9], [_] and [-]. Underscores are not permitted for keys in headers due to [additional restrictions in the NGINX defaults](http://nginx.org/en/docs/http/ngx_http_core_module.html#ignore_invalid_headers). - - name: key_in_body - required: false - default: "`false`" - description: | - If enabled, the plugin will read the request body (if said request has one and its MIME type is supported) and try to find the key in it. Supported MIME types are `application/www-form-urlencoded`, `application/json`, and `multipart/form-data`. - - name: hide_credentials - required: false - default: "`false`" - description: | - An optional boolean value telling the plugin to show or hide the credential from the upstream service. If `true`, the plugin will strip the credential from the request (i.e. the header or querystring containing the key) before proxying it. - - name: anonymous - required: false - default: - description: | - An optional string (consumer uuid) value to use as an "anonymous" consumer if authentication fails. If empty (default), the request will fail with an authentication failure `4xx`. Please note that this value must refer to the Consumer `id` attribute which is internal to Kong, and **not** its `custom_id`. - - name: run_on_preflight - required: false - default: "`true`" - description: | - A boolean value that indicates whether the plugin should run (and try to authenticate) on `OPTIONS` preflight requests, if set to `false` then `OPTIONS` requests will always be allowed. - extra: | - Note that, according to their respective specifications, HTTP header names are treated as case _insensitive_, while HTTP query string parameter names are treated as case _sensitive_. Kong follows these specifications as designed, meaning that the `key_names` configuration values will be treated differently when searching the request header fields, versus searching the query string. Administrators are advised against defining case-sensitive `key_names` values when expecting the authorization keys to be sent in the request headers. - -
-
The option `config.run_on_preflight` is only available from version `0.11.1` and later
-
- - Once applied, any user with a valid credential can access the Service/API. - To restrict usage to only some of the authenticated users, also add the - [ACL](/plugins/acl/) plugin (not covered here) and create whitelist or - blacklist groups of users. - ---- - -## Usage - -In order to use the plugin, you first need to create a Consumer to associate one or more credentials to. The Consumer represents a developer using the upstream service. - -### Create a Consumer - -You need to associate a credential to an existing [Consumer][consumer-object] object. To create a Consumer, you can execute the following request: - -```bash -$ curl -X POST http://kong:8001/consumers/ \ - --data "username=" \ - --data "custom_id=" -HTTP/1.1 201 Created - -{ - "username":"", - "custom_id": "", - "created_at": 1472604384000, - "id": "7f853474-7b70-439d-ad59-2481a0a9a904" -} -``` - -parameter | default | description ---- | --- | --- -`username`
*semi-optional* | | The username of the Consumer. Either this field or `custom_id` must be specified. -`custom_id`
*semi-optional* | | A custom identifier used to map the Consumer to another database. Either this field or `username` must be specified. - -A [Consumer][consumer-object] can have many credentials. - -If you are also using the [ACL](/plugins/acl/) plugin and whitelists with this -service, you must add the new consumer to a whitelisted group. See -[ACL: Associating Consumers][acl-associating] for details. - -### Create a Key - -You can provision new credentials by making the following HTTP request: - -```bash -$ curl -X POST http://kong:8001/consumers/{consumer}/key-auth -d '' -HTTP/1.1 201 Created - -{ - "consumer_id": "876bf719-8f18-4ce5-cc9f-5b5af6c36007", - "created_at": 1443371053000, - "id": "62a7d3b7-b995-49f9-c9c8-bac4d781fb59", - "key": "62eb165c070a41d5c1b58d9d3d725ca1" -} -``` - -* `consumer`: The `id` or `username` property of the [Consumer][consumer-object] entity to associate the credentials to. - -form parameter | default | description ---- | --- | --- -`key`
*optional* | | You can optionally set your own unique `key` to authenticate the client. If missing, the plugin will generate one. - -
- Note: It is recommended to let Kong auto-generate the key. Only specify it yourself if you are migrating an existing system to Kong. You must re-use your keys to make the migration to Kong transparent to your Consumers. -
- -### Using the Key - -Simply make a request with the key as a querystring parameter: - -```bash -$ curl http://kong:8000/{proxy path}?apikey= -``` - -Or in a header: - -```bash -$ curl http://kong:8000/{proxy path} \ - -H 'apikey: ' -``` - -### Delete a Key - -You can delete an API Key by making the following HTTP request: - -```bash -$ curl -X DELETE http://kong:8001/consumers/{consumer}/key-auth/{id} -HTTP/1.1 204 No Content -``` - -* `consumer`: The `id` or `username` property of the [Consumer][consumer-object] entity to associate the credentials to. -* `id`: The `id` attribute of the key credential object. - -### Upstream Headers - -When a client has been authenticated, the plugin will append some headers to the request before proxying it to the upstream service, so that you can identify the Consumer in your code: - -* `X-Consumer-ID`, the ID of the Consumer on Kong -* `X-Consumer-Custom-ID`, the `custom_id` of the Consumer (if set) -* `X-Consumer-Username`, the `username` of the Consumer (if set) -* `X-Credential-Username`, the `username` of the Credential (only if the consumer is not the 'anonymous' consumer) -* `X-Anonymous-Consumer`, will be set to `true` when authentication failed, and the 'anonymous' consumer was set instead. - -You can use this information on your side to implement additional logic. You can use the `X-Consumer-ID` value to query the Kong Admin API and retrieve more information about the Consumer. - -### Paginate through keys - -
- Note: This endpoint was introduced in Kong 0.11.2. -
- -You can paginate through the API keys for all Consumers using the following -request: - -```bash -$ curl -X GET http://kong:8001/key-auths - -{ - "total":3, - "data":[ - { - "id":"17ab4e95-9598-424f-a99a-ffa9f413a821", - "created_at":1507941267000, - "key":"Qslaip2ruiwcusuSUdhXPv4SORZrfj4L", - "consumer_id":"c0d92ba9-8306-482a-b60d-0cfdd2f0e880" - }, - { - "id":"6cb76501-c970-4e12-97c6-3afbbba3b454", - "created_at":1507936652000, - "key":"nCztu5Jrz18YAWmkwOGJkQe9T8lB99l4", - "consumer_id":"c0d92ba9-8306-482a-b60d-0cfdd2f0e880" - }, - { - "id":"b1d87b08-7eb6-4320-8069-efd85a4a8d89", - "created_at":1507941307000, - "key":"26WUW1VEsmwT1ORBFsJmLHZLDNAxh09l", - "consumer_id":"3c2c8fc1-7245-4fbb-b48b-e5947e1ce941" - } - ] -} -``` - -You can filter the list using the following query parameters: - -Attributes | Description ----:| --- -`id`
*optional* | A filter on the list based on the key-auth credential `id` field. -`key`
*optional* | A filter on the list based on the key-auth credential `key` field. -`consumer_id`
*optional* | A filter on the list based on the key-auth credential `consumer_id` field. -`size`
*optional, default is __100__* | A limit on the number of objects to be returned. -`offset`
*optional* | A cursor used for pagination. `offset` is an object identifier that defines a place in the list. - -### Retrieve the Consumer associated with a key - -
- Note: This endpoint was introduced in Kong 0.11.2. -
- -It is possible to retrieve a [Consumer][consumer-object] associated with an API -Key using the following request: - -```bash -curl -X GET http://kong:8001/key-auths/{key or id}/consumer - -{ - "created_at":1507936639000, - "username":"foo", - "id":"c0d92ba9-8306-482a-b60d-0cfdd2f0e880" -} -``` - -* `key or id`: The `id` or `key` property of the API key for which to get the -associated Consumer. - -[api-object]: /gateway/latest/admin-api/#api-object -[configuration]: /gateway/latest/reference/configuration -[consumer-object]: /gateway/latest/admin-api/#consumer-object -[acl-associating]: /plugins/acl/#associating-consumers diff --git a/app/_hub/kong-inc/key-auth/2.1.x.md b/app/_hub/kong-inc/key-auth/2.1.x.md deleted file mode 100644 index 80fd26721428..000000000000 --- a/app/_hub/kong-inc/key-auth/2.1.x.md +++ /dev/null @@ -1,306 +0,0 @@ ---- -name: Key Authentication -publisher: Kong Inc. -version: 1.0.0 - -desc: Add key authentication to your Services -description: | - Add key authentication (also sometimes referred to as an API key) to a Service or a Route. Consumers then add their key either in a query string parameter or a header to authenticate their requests. - -
- Note: The functionality of this plugin as bundled - with versions of Kong prior to 0.11.2 - differs from what is documented herein. Refer to the - CHANGELOG - for details. -
- -type: plugin -categories: - - authentication - -kong_version_compatibility: - community_edition: - compatible: - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x - - 0.4.x - - 0.3.x - - 0.2.x - enterprise_edition: - compatible: - - 1.5.x - - 1.3-x - - 0.36-x - - 0.35-x - - 0.34-x - - 0.33-x - - 0.32-x - - 0.31-x - -params: - name: key-auth - service_id: true - route_id: true - consumer_id: false - protocols: ["http", "https"] - dbless_compatible: partially - dbless_explanation: | - Consumers and Credentials can be created with declarative configuration. - - Admin API endpoints which do POST, PUT, PATCH or DELETE on Credentials are not available on DB-less mode. - config: - - name: key_names - required: false - default: "`apikey`" - value_in_examples: ["apikey"] - description: | - Describes an array of parameter names where the plugin will look for a key. The client must send the authentication key in one of those key names, and the plugin will try to read the credential from a header or the query string parameter with the same name.

**Note**: the key names may only contain [a-z], [A-Z], [0-9], [_] and [-]. - - name: key_in_body - required: false - default: "`false`" - description: | - If enabled, the plugin will read the request body (if said request has one and its MIME type is supported) and try to find the key in it. Supported MIME types are `application/www-form-urlencoded`, `application/json`, and `multipart/form-data`. - - name: hide_credentials - required: false - default: "`false`" - description: | - An optional boolean value telling the plugin to show or hide the credential from the upstream service. If `true`, the plugin will strip the credential from the request (i.e. the header or querystring containing the key) before proxying it. - - name: anonymous - required: false - default: - description: | - An optional string (consumer uuid) value to use as an "anonymous" consumer if authentication fails. If empty (default), the request will fail with an authentication failure `4xx`. Please note that this value must refer to the Consumer `id` attribute which is internal to Kong, and **not** its `custom_id`. - - name: run_on_preflight - required: false - default: "`true`" - description: | - A boolean value that indicates whether the plugin should run (and try to authenticate) on `OPTIONS` preflight requests, if set to `false` then `OPTIONS` requests will always be allowed. - extra: | - Note that, according to their respective specifications, HTTP header names are treated as case _insensitive_, while HTTP query string parameter names are treated as case _sensitive_. Kong follows these specifications as designed, meaning that the `key_names` configuration values will be treated differently when searching the request header fields, versus searching the query string. Administrators are advised against defining case-sensitive `key_names` values when expecting the authorization keys to be sent in the request headers. - -
-
The option `config.run_on_preflight` is only available from version `0.11.1` and later
-
- - Once applied, any user with a valid credential can access the Service. - To restrict usage to only some of the authenticated users, also add the - [ACL](/plugins/acl/) plugin (not covered here) and create whitelist or - blacklist groups of users. - ---- - -## Usage - -### Create a Consumer - -You need to associate a credential to an existing [Consumer][consumer-object] object. -A Consumer can have many credentials. - -{% navtabs %} -{% navtab With a Database %} -To create a Consumer, you can execute the following request: - -```bash -curl -d "username=user123&custom_id=SOME_CUSTOM_ID" http://kong:8001/consumers/ -``` -{% endnavtab %} -{% navtab Without a Database %} -Your declarative configuration file will need to have one or more Consumers. You can create them -on the `consumers:` yaml section: - -``` yaml -consumers: -- username: user123 - custom_id: SOME_CUSTOM_ID -``` -{% endnavtab %} -{% endnavtabs %} - -In both cases, the parameters are as described below: - -parameter | description ---- | --- -`username`
*semi-optional* | The username of the consumer. Either this field or `custom_id` must be specified. -`custom_id`
*semi-optional* | A custom identifier used to map the consumer to another database. Either this field or `username` must be specified. - -If you are also using the [ACL](/plugins/acl/) plugin and whitelists with this -service, you must add the new consumer to a whitelisted group. See -[ACL: Associating Consumers][acl-associating] for details. - -### Create a Key - -{% navtabs %} -{% navtab With a database %} -You can provision new credentials by making the following HTTP request: - -```bash -$ curl -X POST http://kong:8001/consumers/{consumer}/key-auth -d '' -HTTP/1.1 201 Created - -{ - "consumer": { "id": "876bf719-8f18-4ce5-cc9f-5b5af6c36007" }, - "created_at": 1443371053000, - "id": "62a7d3b7-b995-49f9-c9c8-bac4d781fb59", - "key": "62eb165c070a41d5c1b58d9d3d725ca1" -} -``` - -
- Note: It is recommended to let Kong auto-generate the key. Only specify it yourself if you are migrating an existing system to Kong. You must re-use your keys to make the migration to Kong transparent to your Consumers. -
-{% endnavtab %} -{% navtab Without a database %} -You can add credentials on your declarative config file on the `keyauth_credentials` yaml entry: - -``` yaml -keyauth_credentials: -- consumer: {consumer} -``` -{% endnavtab %} -{% endnavtabs %} - -In both cases the fields/parameters work as follows: - -field/parameter | description ---- | --- -`{consumer}` | The `id` or `username` property of the [Consumer][consumer-object] entity to associate the credentials to. -`key`
*optional* | You can optionally set your own unique `key` to authenticate the client. If missing, the plugin will generate one. - -### Using the Key - -Simply make a request with the key as a querystring parameter: - -```bash -$ curl http://kong:8000/{proxy path}?apikey= -``` - -Or in a header: - -```bash -$ curl http://kong:8000/{proxy path} \ - -H 'apikey: ' -``` - -### Delete a Key - -You can delete an API Key by making the following HTTP request: - -```bash -$ curl -X DELETE http://kong:8001/consumers/{consumer}/key-auth/{id} -HTTP/1.1 204 No Content -``` - -* `consumer`: The `id` or `username` property of the [Consumer][consumer-object] entity to associate the credentials to. -* `id`: The `id` attribute of the key credential object. - -### Upstream Headers - -When a client has been authenticated, the plugin will append some headers to the request before proxying it to the upstream service, so that you can identify the Consumer in your code: - -* `X-Consumer-ID`, the ID of the Consumer on Kong -* `X-Consumer-Custom-ID`, the `custom_id` of the Consumer (if set) -* `X-Consumer-Username`, the `username` of the Consumer (if set) -* `X-Credential-Username`, the `username` of the Credential (only if the consumer is not the 'anonymous' consumer) -* `X-Anonymous-Consumer`, will be set to `true` when authentication failed, and the 'anonymous' consumer was set instead. - -You can use this information on your side to implement additional logic. You can use the `X-Consumer-ID` value to query the Kong Admin API and retrieve more information about the Consumer. - -### Paginate through keys - -
- Note: This endpoint was introduced in Kong 0.11.2. -
- -You can paginate through the API keys for all Consumers using the following -request: - -```bash -$ curl -X GET http://kong:8001/key-auths - -{ - "data":[ - { - "id":"17ab4e95-9598-424f-a99a-ffa9f413a821", - "created_at":1507941267000, - "key":"Qslaip2ruiwcusuSUdhXPv4SORZrfj4L", - "consumer": { "id": "c0d92ba9-8306-482a-b60d-0cfdd2f0e880" } - }, - { - "id":"6cb76501-c970-4e12-97c6-3afbbba3b454", - "created_at":1507936652000, - "key":"nCztu5Jrz18YAWmkwOGJkQe9T8lB99l4", - "consumer": { "id": "c0d92ba9-8306-482a-b60d-0cfdd2f0e880" } - }, - { - "id":"b1d87b08-7eb6-4320-8069-efd85a4a8d89", - "created_at":1507941307000, - "key":"26WUW1VEsmwT1ORBFsJmLHZLDNAxh09l", - "consumer": { "id": "3c2c8fc1-7245-4fbb-b48b-e5947e1ce941" } - } - ] - "next":null, -} -``` - -You can filter the list by consumer by using this other path: - -```bash -$ curl -X GET http://kong:8001/consumers/{username or id}/key-auth - -{ - "data": [ - { - "id":"6cb76501-c970-4e12-97c6-3afbbba3b454", - "created_at":1507936652000, - "key":"nCztu5Jrz18YAWmkwOGJkQe9T8lB99l4", - "consumer": { "id": "c0d92ba9-8306-482a-b60d-0cfdd2f0e880" } - } - ] - "next":null, -} -``` - -`username or id`: The username or id of the consumer whose credentials need to be listed - -### Retrieve the Consumer associated with a key - -
- Note: This endpoint was introduced in Kong 0.11.2. -
- -It is possible to retrieve a [Consumer][consumer-object] associated with an API -Key using the following request: - -```bash -curl -X GET http://kong:8001/key-auths/{key or id}/consumer - -{ - "created_at":1507936639000, - "username":"foo", - "id":"c0d92ba9-8306-482a-b60d-0cfdd2f0e880" -} -``` - -* `key or id`: The `id` or `key` property of the API key for which to get the -associated Consumer. - -[configuration]: /gateway/latest/reference/configuration -[consumer-object]: /gateway/latest/admin-api/#consumer-object -[acl-associating]: /plugins/acl/#associating-consumers - diff --git a/app/_hub/kong-inc/key-auth/2.2.x.md b/app/_hub/kong-inc/key-auth/2.2.x.md deleted file mode 100644 index 0e13b97ebf19..000000000000 --- a/app/_hub/kong-inc/key-auth/2.2.x.md +++ /dev/null @@ -1,353 +0,0 @@ ---- -name: Key Authentication -publisher: Kong Inc. -version: 2.2.0 - -desc: Add key authentication to your Services -description: | - Add key authentication (also sometimes referred to as an _API key_) to a Service or a Route. - Consumers then add their API key either in a query string parameter, a header, or a - request body to authenticate their requests. - - This plugin can be used for authentication in conjunction with the - [Application Registration](/hub/kong-inc/application-registration) plugin. - - **Tip:** The Kong Gateway [Key Authentication Encrypted](/hub/kong-inc/key-auth-enc/) - plugin provides the ability to encrypt keys. Keys are encrypted at rest in the API gateway datastore. - -type: plugin -categories: - - authentication - -kong_version_compatibility: - community_edition: - compatible: - - 2.2.x - - 2.1.x - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x - - 0.4.x - - 0.3.x - - 0.2.x - enterprise_edition: - compatible: - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x - - 0.35-x - - 0.34-x - - 0.33-x - - 0.32-x - - 0.31-x - -params: - name: key-auth - service_id: true - route_id: true - consumer_id: false - protocols: ["http", "https", "grpc", "grpcs"] - dbless_compatible: partially - dbless_explanation: | - Consumers and Credentials can be created with declarative configuration. - - Admin API endpoints that do POST, PUT, PATCH, or DELETE on Credentials are not available on DB-less mode. - config: - - name: key_names - required: true - default: "`apikey`" - value_in_examples: ["apikey"] - datatype: array of strings - description: | - Describes an array of parameter names where the plugin will look for a key. The client must send the - authentication key in one of those key names, and the plugin will try to read the credential from a - header, request body, or query string parameter with the same name. -
**Note**: The key names may only contain [a-z], [A-Z], [0-9], [_] underscore, and [-] hyphen. - - name: key_in_body - required: false - default: "`false`" - datatype: boolean - description: | - If enabled, the plugin reads the request body (if said request has one and its MIME type is supported) and tries to find the key in it. Supported MIME types: `application/www-form-urlencoded`, `application/json`, and `multipart/form-data`. - - name: hide_credentials - required: false - default: "`false`" - datatype: boolean - description: | - An optional boolean value telling the plugin to show or hide the credential from the upstream service. If `true`, - the plugin strips the credential from the request (i.e., the header, query string, or request body containing the key) before proxying it. - - name: anonymous - required: false - default: - datatype: string - description: | - An optional string (Consumer UUID) value to use as an anonymous Consumer if authentication fails. - If empty (default), the request will fail with an authentication failure `4xx`. Note that this value - must refer to the Consumer `id` attribute that is internal to Kong, and **not** its `custom_id`. - - name: run_on_preflight - required: false - default: "`true`" - datatype: boolean - description: | - A boolean value that indicates whether the plugin should run (and try to authenticate) on `OPTIONS` preflight requests. - If set to `false`, then `OPTIONS` requests are always allowed. - extra: | - - ## Case sensitivity - - Note that, according to their respective specifications, HTTP header names are treated as case _insensitive_, while HTTP query string parameter names are treated as case _sensitive_. Kong follows these specifications as designed, meaning that the `key_names` configuration values - are treated differently when searching the request header fields versus searching the query string. As a best practice, administrators - are advised against defining case-sensitive `key_names` values when expecting the authorization keys to be sent in the request headers. - - Once applied, any user with a valid credential can access the Service. - To restrict usage to certain authenticated users, also add the - [ACL](/plugins/acl/) plugin (not covered here) and create allowed or - denied groups of users. - ---- - -## Usage - -### Create a Consumer - -You need to associate a credential to an existing [Consumer][consumer-object] object. -A Consumer can have many credentials. - -{% navtabs %} -{% navtab With a database %} - -To create a Consumer, make the following request: - -```bash -curl -d "username=user123&custom_id=SOME_CUSTOM_ID" http://kong:8001/consumers/ -``` -{% endnavtab %} - -{% navtab Without a database %} - -Your declarative configuration file will need to have one or more Consumers. You can create them -on the `consumers:` yaml section: - -``` yaml -consumers: -- username: user123 - custom_id: SOME_CUSTOM_ID -``` - -{% endnavtab %} -{% endnavtabs %} - -In both cases, the parameters are as described below: - -parameter | description ---- | --- -`username`
*semi-optional* | The username of the Consumer. Either this field or `custom_id` must be specified. -`custom_id`
*semi-optional* | A custom identifier used to map the Consumer to another database. Either this field or `username` must be specified. - -If you are also using the [ACL](/plugins/acl/) plugin and allow lists with this -service, you must add the new consumer to the allowed group. See -[ACL: Associating Consumers][acl-associating] for details. - -### Create a Key - -
- Note: It is recommended to let the API gateway autogenerate the key. Only specify it yourself if - you are migrating an existing system to {{site.base_gateway}}. You must reuse your keys to make the - migration to {{site.base_gateway}} transparent to your Consumers. -
- -{% navtabs %} -{% navtab With a database %} - -Provision new credentials by making the following HTTP request: - -```bash -$ curl -X POST http://kong:8001/consumers/{consumer}/key-auth -d -``` - -Response: - -``` -HTTP/1.1 201 Created - -{ - "consumer": { "id": "876bf719-8f18-4ce5-cc9f-5b5af6c36007" }, - "created_at": 1443371053000, - "id": "62a7d3b7-b995-49f9-c9c8-bac4d781fb59", - "key": "62eb165c070a41d5c1b58d9d3d725ca1" -} -``` -{% endnavtab %} -{% navtab Without a database %} - -Add credentials to your declarative config file in the `keyauth_credentials` YAML -entry: - -```yaml -keyauth_credentials: -- consumer: {consumer} -``` -{% endnavtab %} -{% endnavtabs %} - -In both cases, the fields/parameters work as follows: - -field/parameter | description ---- | --- -`{consumer}` | The `id` or `username` property of the [Consumer][consumer-object] entity to associate the credentials to. -`key`
*optional* | You can optionally set your own unique `key` to authenticate the client. If missing, the plugin will generate one. - -### Make a Request with the Key - -Make a request with the key as a query string parameter: - -```bash -$ curl http://kong:8000/{proxy path}?apikey= -``` - -Make a request with the key in the body: - -```bash -$ curl http://kong:8000/{proxy path} \ - --data 'apikey: ' -``` - -**Note:** The `key_in_body` parameter must be set to `true`. - -Make a request with the key in a header: - -```bash -$ curl http://kong:8000/{proxy path} \ - -H 'apikey: ' -``` - -gRPC clients are supported too: - -```bash -$ grpcurl -H 'apikey: ' ... -``` - -### Delete a Key - -Delete an API Key by making the following request: - -```bash -$ curl -X DELETE http://kong:8001/consumers/{consumer}/key-auth/{id} -HTTP/1.1 204 No Content -``` - -* `consumer`: The `id` or `username` property of the [Consumer][consumer-object] entity to associate the credentials to. -* `id`: The `id` attribute of the key credential object. - -### Upstream Headers - -When a client has been authenticated, the plugin appends some headers to the request before -proxying it to the upstream service so that you can identify the Consumer in your code: - -* `X-Consumer-ID`, the ID of the Consumer on Kong -* `X-Consumer-Custom-ID`, the `custom_id` of the Consumer (if set) -* `X-Consumer-Username`, the `username` of the Consumer (if set) -* `X-Credential-Identifier`, the identifier of the Credential (only if the consumer is not the 'anonymous' consumer) -* `X-Anonymous-Consumer`, will be set to `true` when authentication failed, and the 'anonymous' consumer was set instead. - -You can use this information on your side to implement additional logic. You can use the `X-Consumer-ID` value to query the Kong Admin API and retrieve more information about the Consumer. - -### Paginate through keys - -
- Note: This endpoint was introduced in Kong 0.11.2. -
- -Paginate through the API keys for all Consumers by making the following -request: - -```bash -$ curl -X GET http://kong:8001/key-auths - -{ - "data":[ - { - "id":"17ab4e95-9598-424f-a99a-ffa9f413a821", - "created_at":1507941267000, - "key":"Qslaip2ruiwcusuSUdhXPv4SORZrfj4L", - "consumer": { "id": "c0d92ba9-8306-482a-b60d-0cfdd2f0e880" } - }, - { - "id":"6cb76501-c970-4e12-97c6-3afbbba3b454", - "created_at":1507936652000, - "key":"nCztu5Jrz18YAWmkwOGJkQe9T8lB99l4", - "consumer": { "id": "c0d92ba9-8306-482a-b60d-0cfdd2f0e880" } - }, - { - "id":"b1d87b08-7eb6-4320-8069-efd85a4a8d89", - "created_at":1507941307000, - "key":"26WUW1VEsmwT1ORBFsJmLHZLDNAxh09l", - "consumer": { "id": "3c2c8fc1-7245-4fbb-b48b-e5947e1ce941" } - } - ] - "next":null, -} -``` - -Filter the list by Consumer by using a different endpoint: - -```bash -$ curl -X GET http://kong:8001/consumers/{username or id}/key-auth - -{ - "data": [ - { - "id":"6cb76501-c970-4e12-97c6-3afbbba3b454", - "created_at":1507936652000, - "key":"nCztu5Jrz18YAWmkwOGJkQe9T8lB99l4", - "consumer": { "id": "c0d92ba9-8306-482a-b60d-0cfdd2f0e880" } - } - ] - "next":null, -} -``` - -`username or id`: The username or id of the Consumer whose credentials need to be listed - -### Retrieve the Consumer associated with a key - -
- Note: This endpoint was introduced in Kong 0.11.2. -
- -Retrieve a [Consumer][consumer-object] associated with an API -key by making the following request: - -```bash -curl -X GET http://kong:8001/key-auths/{key or id}/consumer - -{ - "created_at":1507936639000, - "username":"foo", - "id":"c0d92ba9-8306-482a-b60d-0cfdd2f0e880" -} -``` - -* `key or id`: The `id` or `key` property of the API key for which to get the -associated Consumer. - -[configuration]: /gateway/latest/reference/configuration -[consumer-object]: /gateway/latest/admin-api/#consumer-object -[acl-associating]: /plugins/acl/#associating-consumers - diff --git a/app/_hub/kong-inc/key-auth/_index.md b/app/_hub/kong-inc/key-auth/_index.md index b8486dd6af57..ebf0f6a499d3 100644 --- a/app/_hub/kong-inc/key-auth/_index.md +++ b/app/_hub/kong-inc/key-auth/_index.md @@ -1,10 +1,9 @@ --- name: Key Authentication publisher: Kong Inc. -version: 2.3.x (internal 2.4.0) desc: Add key authentication to your Services description: | - Add key authentication (also sometimes referred to as an _API key_) to a Service or a Route. + Add key authentication (also sometimes referred to as an _API key_) to a service or a route. Consumers then add their API key either in a query string parameter, a header, or a request body to authenticate their requests. @@ -18,48 +17,9 @@ categories: - authentication kong_version_compatibility: community_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x - - 0.4.x - - 0.3.x - - 0.2.x + compatible: true enterprise_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x + compatible: true params: name: key-auth service_id: true @@ -94,12 +54,14 @@ params: description: | If enabled, the plugin reads the request body (if said request has one and its MIME type is supported) and tries to find the key in it. Supported MIME types: `application/www-form-urlencoded`, `application/json`, and `multipart/form-data`. - name: key_in_header + minimum_version: "2.3.x" required: true default: '`true`' datatype: boolean description: | If enabled (default), the plugin reads the request header and tries to find the key in it. - name: key_in_query + minimum_version: "2.3.x" required: true default: '`true`' datatype: boolean @@ -127,22 +89,20 @@ params: description: | A boolean value that indicates whether the plugin should run (and try to authenticate) on `OPTIONS` preflight requests. If set to `false`, then `OPTIONS` requests are always allowed. - extra: | - - ## Case sensitivity +--- +## Case sensitivity - Note that, according to their respective specifications, HTTP header names are treated as - case _insensitive_, while HTTP query string parameter names are treated as case _sensitive_. - Kong follows these specifications as designed, meaning that the `key_names` - configuration values are treated differently when searching the request header fields versus - searching the query string. As a best practice, administrators are advised against defining - case-sensitive `key_names` values when expecting the authorization keys to be sent in the request headers. +Note that, according to their respective specifications, HTTP header names are treated as +case _insensitive_, while HTTP query string parameter names are treated as case _sensitive_. +Kong follows these specifications as designed, meaning that the `key_names` +configuration values are treated differently when searching the request header fields versus +searching the query string. As a best practice, administrators are advised against defining +case-sensitive `key_names` values when expecting the authorization keys to be sent in the request headers. - Once applied, any user with a valid credential can access the Service. - To restrict usage to certain authenticated users, also add the - [ACL](/plugins/acl/) plugin (not covered here) and create allowed or - denied groups of users. ---- +Once applied, any user with a valid credential can access the Service. +To restrict usage to certain authenticated users, also add the +[ACL](/plugins/acl/) plugin (not covered here) and create allowed or +denied groups of users. ## Usage @@ -242,6 +202,8 @@ field/parameter | description ### Make a Request with the Key +{% if_plugin_version gte:2.3.x %} + Make a request with the key as a query string parameter: ```bash @@ -250,29 +212,35 @@ curl http://localhost:8000/{proxy path}?apikey={some_key} **Note:** The `key_in_query` plugin parameter must be set to `true` (default). -Make a request with the key in the body: + +Make a request with the key in a header: ```bash curl http://localhost:8000/{proxy path} \ - --data 'apikey: {some_key}' + -H 'apikey: {some_key}' ``` -**Note:** The `key_in_body` plugin parameter must be set to `true` (default is `false`). +**Note:** The `key_in_header` plugin parameter must be set to `true` (default). -Make a request with the key in a header: +{% endif_plugin_version %} + +Make a request with the key in the body: ```bash curl http://localhost:8000/{proxy path} \ - -H 'apikey: {some_key}' + --data 'apikey: {some_key}' ``` -**Note:** The `key_in_header` plugin parameter must be set to `true` (default). +**Note:** The `key_in_body` plugin parameter must be set to `true` (default is `false`). gRPC clients are supported too: ```bash grpcurl -H 'apikey: {some_key}' ... ``` + +{% if_plugin_version gte:2.3.x %} + ### About API Key Locations in a Request {% include /md/plugins-hub/api-key-locations.md %} @@ -288,6 +256,8 @@ curl -X POST http://localhost:8001/routes/{NAME_OR_ID}/plugins \ --data "config.key_in_query=false" ``` +{% endif_plugin_version %} + ### Delete a Key Delete an API Key by making the following request: @@ -307,16 +277,7 @@ HTTP/1.1 204 No Content ### Upstream Headers -When a client has been authenticated, the plugin appends some headers to the request before -proxying it to the upstream service so that you can identify the Consumer in your code: - -* `X-Consumer-ID`, the ID of the Consumer on Kong -* `X-Consumer-Custom-ID`, the `custom_id` of the Consumer (if set) -* `X-Consumer-Username`, the `username` of the Consumer (if set) -* `X-Credential-Identifier`, the identifier of the Credential (only if the consumer is not the 'anonymous' consumer) -* `X-Anonymous-Consumer`, will be set to `true` when authentication failed, and the 'anonymous' consumer was set instead. - -You can use this information on your side to implement additional logic. You can use the `X-Consumer-ID` value to query the Kong Admin API and retrieve more information about the Consumer. +{% include_cached /md/plugins-hub/upstream-headers.md %} ### Paginate through keys @@ -329,7 +290,7 @@ curl -X GET http://localhost:8001/key-auths Response: -```bash +```json ... { "data":[ @@ -366,7 +327,7 @@ In the above, substitute the `username` or `id` property associated with the Con Response: -```bash +```json ... { "data": [ @@ -394,7 +355,7 @@ In the above, substitute either the `key` or `id` property associated with the k Response: -```bash +```json { "created_at":1507936639000, "username":"foo", @@ -405,3 +366,13 @@ Response: [configuration]: /gateway/latest/reference/configuration [consumer-object]: /gateway/latest/admin-api/#consumer-object [acl-associating]: /plugins/acl/#associating-consumers + +--- +## Changelog + +**{{site.base_gateway}} 3.0.x** +* The deprecated `X-Credential-Username` header has been removed. +* The `key-auth` plugin priority has changed from 1003 to 1250. + +**{{site.base_gateway}} 2.3.x** +* Added the configuration parameters `key_in_header` and `key_in_query`. diff --git a/app/_hub/kong-inc/key-auth/versions.yml b/app/_hub/kong-inc/key-auth/versions.yml index 8176298836de..bf8464a3cc93 100644 --- a/app/_hub/kong-inc/key-auth/versions.yml +++ b/app/_hub/kong-inc/key-auth/versions.yml @@ -1,4 +1,12 @@ -- release: 2.3.x -- release: 2.2.x -- release: 2.1.x -- release: 0.2.x +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 2.4.0 + 2.7.x: 2.4.0 + 2.6.x: 2.4.0 + 2.5.x: 2.4.0 + 2.4.x: 2.4.0 + 2.3.x: 2.4.0 + 2.2.x: 2.3.0 + 2.1.x: 2.2.0 diff --git a/app/_hub/kong-inc/kong-terraform-aws/_index.md b/app/_hub/kong-inc/kong-terraform-aws/_index.md index 079880137da9..42fe872dfab8 100644 --- a/app/_hub/kong-inc/kong-terraform-aws/_index.md +++ b/app/_hub/kong-inc/kong-terraform-aws/_index.md @@ -8,11 +8,12 @@ desc: Terraform module to provision Kong and Kong Gateway clusters on Amazon Web description: | Terraform module to provision Kong clusters in Amazon Web Service (AWS) using AWS best practices for architecture and security. Both Kong and Kong Gateway are supported. Available under the Apache License 2.0 license. support_url: 'https://github.com/Kong/kong-terraform-aws/issues' -source_url: 'https://github.com/kong/kong-terraform-aws' +source_code: 'https://github.com/kong/kong-terraform-aws' license_type: Apache-2.0 kong_version_compatibility: community_edition: compatible: + - 3.0.x - 2.8.x - 2.7.x - 2.6.x @@ -32,6 +33,7 @@ kong_version_compatibility: - 0.13.x enterprise_edition: compatible: + - 3.0.x - 2.8.x - 2.7.x - 2.6.x diff --git a/app/_hub/kong-inc/kubernetes-sidecar-injector/_index.md b/app/_hub/kong-inc/kubernetes-sidecar-injector/_index.md deleted file mode 100644 index e429ee2eab45..000000000000 --- a/app/_hub/kong-inc/kubernetes-sidecar-injector/_index.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -redirect_to: https://kuma.io/docs/latest/installation/kubernetes/ ---- diff --git a/app/_hub/kong-inc/ldap-auth-advanced/0.33-x.md b/app/_hub/kong-inc/ldap-auth-advanced/0.33-x.md deleted file mode 100644 index c4e0db855739..000000000000 --- a/app/_hub/kong-inc/ldap-auth-advanced/0.33-x.md +++ /dev/null @@ -1,177 +0,0 @@ ---- - -name: LDAP Authentication Advanced -publisher: Kong Inc. -version: 0.33-x - -desc: Secure Kong clusters, routes and services with username and password protection -description: | - Add LDAP Bind Authentication with username and password protection. The plugin will check for valid credentials in the `Proxy-Authorization` and `Authorization` header (in this order). - -enterprise: true -type: plugin -categories: - - authentication - -kong_version_compatibility: - community_edition: - compatible: - enterprise_edition: - compatible: - - 0.33-x - -params: - name: ldap-auth-advanced - api_id: true - service_id: true - route_id: true - consumer_id: true - config: - - name: ldap_host - required: - default: - value_in_examples: - description: | - Host on which the LDAP server is running - - name: ldap_port - required: - default: - value_in_examples: - description: | - TCP port where the LDAP server is listening - - name: ldap_password - required: - default: - value_in_examples: - description: | - The password to the LDAP server - - name: start_tls - required: - default: "`false`" - value_in_examples: - description: | - Set it to `true` to issue StartTLS (Transport Layer Security) extended operation over `ldap` connection - - name: base_dn - required: - default: - value_in_examples: - description: | - Base DN as the starting point for the search; e.g., "dc=example,dc=com" - - name: verify_ldap_host - required: - default: "`false`" - value_in_examples: - description: | - Set it to `true` to authenticate LDAP server. The server certificate will be verified according to the CA certificates specified by the `lua_ssl_trusted_certificate` directive. - - name: attribute - required: - default: - value_in_examples: - description: | - Attribute to be used to search the user; e.g., "cn" - - name: cache_ttl - required: - default: "`60`" - value_in_examples: - description: | - Cache expiry time in seconds - - name: timeout - required: false - default: "`10000`" - value_in_examples: - description: | - An optional timeout in milliseconds when waiting for connection with LDAP server - - name: keepalive - required: false - default: "`10000`" - value_in_examples: - description: | - An optional value in milliseconds that defines for how long an idle connection to LDAP server will live before being closed - - name: anonymous - required: false - default: - value_in_examples: - description: | - An optional string (consumer uuid) value to use as an "anonymous" consumer if authentication fails. If empty (default), the request will fail with an authentication failure `4xx`. Please note that this value must refer to the Consumer `id` attribute which is internal to Kong, and **not** its `custom_id`. - - name: header_type - required: false - default: "`ldap`" - value_in_examples: - description: | - An optional string to use as part of the Authorization header. By default, a valid Authorization header looks like this: `Authorization: ldap base64(username:password)`. If `header_type` is set to "basic" then the Authorization header would be `Authorization: basic base64(username:password)`. Note that `header_type` can take any string, not just `"ldap"` and `"basic"`. - - name: consumer_optional - required: false - default: "`false`" - value_in_examples: - description: | - Whether consumer mapping is optional. If `consumer_optional=true`, the plugin will not attempt to associate a consumer with the LDAP authenticated user. If `consumer_optional=false`, LDAP authenticated users can still access upstream resources. To prevent access from LDAP users that are not associated with consumers, set `consumer_optional=false`, set the `anonymous` field to an existing `consumer_id`, then use the Request Termination plugin to deny any requests from the anonymous consumer. - - name: consumer_by - required: false - default: "`username`" - value_in_examples: - description: | - Whether to authenticate consumer based on `username` or `custom_id` - - name: hide_credentials - required: false - default: "`false`" - value_in_examples: - description: | - An optional boolean value telling the plugin to hide the credential to the upstream server. It will be removed by Kong before proxying the request. - - name: bind_dn - required: - default: - value_in_examples: - description: | - The DN to bind to. Used to perform LDAP search of user. This bind_dn - should have permissions to search for the user being authenticated. - ---- - -### Usage - -In order to authenticate the user, client must set credentials in -`Proxy-Authorization` or `Authorization` header in following format: - - credentials := [ldap | LDAP] base64(username:password) - -The plugin will validate the user against the LDAP server and cache the -credential for future requests for the duration specified in -`config.cache_ttl`. - -#### Upstream Headers - -When a client has been authenticated, the plugin will append some headers to the - request before proxying it to the upstream service, so that you can identify - the consumer in your code: - -* `X-Credential-Username`, the `username` of the Credential (only if the -consumer is not the 'anonymous' consumer) -* `X-Anonymous-Consumer`, will be set to `true` when authentication failed, and -the 'anonymous' consumer was set instead. -* `X-Consumer-ID`, the ID of the 'anonymous' consumer on Kong (only if -authentication failed and 'anonymous' was set) -* `X-Consumer-Custom-ID`, the `custom_id` of the 'anonymous' consumer (only if -authentication failed and 'anonymous' was set) -* `X-Consumer-Username`, the `username` of the 'anonymous' consumer (only if -authentication failed and 'anonymous' was set) - - -#### LDAP Search and config.bind_dn - -LDAP directory searching is performed during the request/plugin lifecycle. It is -used to retrieve the fully qualified DN of the user so a bind -request can be performed with the user's given LDAP username and password. The -search for the user being authenticated uses the `config.bind_dn` property. The -search uses `scope="sub"`, `filter="="`, and -`base_dn=`. Here is an example of how it performs the search -using the `ldapsearch` command line utility: - -```bash -$ ldapsearch -x -h "" -D "" -b -"=" -w "" -``` - -[api-object]: /gateway/latest/admin-api/#api-object -[configuration]: /gateway/latest/reference/configuration -[consumer-object]: /gateway/latest/admin-api/#consumer-object - diff --git a/app/_hub/kong-inc/ldap-auth-advanced/0.34-x.md b/app/_hub/kong-inc/ldap-auth-advanced/0.34-x.md deleted file mode 100644 index 6c77e1121f57..000000000000 --- a/app/_hub/kong-inc/ldap-auth-advanced/0.34-x.md +++ /dev/null @@ -1,177 +0,0 @@ ---- - -name: LDAP Authentication Advanced -publisher: Kong Inc. -version: 0.34-x - -desc: Secure Kong clusters, routes and services with username and password protection -description: | - Add LDAP Bind Authentication with username and password protection. The plugin will check for valid credentials in the `Proxy-Authorization` and `Authorization` header (in this order). - -enterprise: true -type: plugin -categories: - - authentication - -kong_version_compatibility: - community_edition: - compatible: - enterprise_edition: - compatible: - - 0.34-x - -params: - name: ldap-auth-advanced - api_id: true - service_id: true - route_id: true - consumer_id: true - config: - - name: ldap_host - required: - default: - value_in_examples: - description: | - Host on which the LDAP server is running - - name: ldap_port - required: - default: - value_in_examples: - description: | - TCP port where the LDAP server is listening - - name: ldap_password - required: - default: - value_in_examples: - description: | - The password to the LDAP server - - name: start_tls - required: - default: "`false`" - value_in_examples: - description: | - Set it to `true` to issue StartTLS (Transport Layer Security) extended operation over `ldap` connection - - name: base_dn - required: - default: - value_in_examples: - description: | - Base DN as the starting point for the search; e.g., "dc=example,dc=com" - - name: verify_ldap_host - required: - default: "`false`" - value_in_examples: - description: | - Set it to `true` to authenticate LDAP server. The server certificate will be verified according to the CA certificates specified by the `lua_ssl_trusted_certificate` directive. - - name: attribute - required: - default: - value_in_examples: - description: | - Attribute to be used to search the user; e.g., "cn" - - name: cache_ttl - required: - default: "`60`" - value_in_examples: - description: | - Cache expiry time in seconds - - name: timeout - required: false - default: "`10000`" - value_in_examples: - description: | - An optional timeout in milliseconds when waiting for connection with LDAP server - - name: keepalive - required: false - default: "`10000`" - value_in_examples: - description: | - An optional value in milliseconds that defines for how long an idle connection to LDAP server will live before being closed - - name: anonymous - required: false - default: - value_in_examples: - description: | - An optional string (consumer uuid) value to use as an "anonymous" consumer if authentication fails. If empty (default), the request will fail with an authentication failure `4xx`. Please note that this value must refer to the Consumer `id` attribute which is internal to Kong, and **not** its `custom_id`. - - name: header_type - required: false - default: "`ldap`" - value_in_examples: - description: | - An optional string to use as part of the Authorization header. By default, a valid Authorization header looks like this: `Authorization: ldap base64(username:password)`. If `header_type` is set to "basic" then the Authorization header would be `Authorization: basic base64(username:password)`. Note that `header_type` can take any string, not just `"ldap"` and `"basic"`. - - name: consumer_optional - required: false - default: "`false`" - value_in_examples: - description: | - Whether consumer mapping is optional. If `consumer_optional=true`, the plugin will not attempt to associate a consumer with the LDAP authenticated user. If `consumer_optional=false`, LDAP authenticated users can still access upstream resources. To prevent access from LDAP users that are not associated with consumers, set `consumer_optional=false`, set the `anonymous` field to an existing `consumer_id`, then use the Request Termination plugin to deny any requests from the anonymous consumer. - - name: consumer_by - required: false - default: "`username`" - value_in_examples: - description: | - Whether to authenticate consumer based on `username` or `custom_id` - - name: hide_credentials - required: false - default: "`false`" - value_in_examples: - description: | - An optional boolean value telling the plugin to hide the credential to the upstream server. It will be removed by Kong before proxying the request. - - name: bind_dn - required: - default: - value_in_examples: - description: | - The DN to bind to. Used to perform LDAP search of user. This bind_dn - should have permissions to search for the user being authenticated. - ---- - -### Usage - -In order to authenticate the user, client must set credentials in -`Proxy-Authorization` or `Authorization` header in following format: - - credentials := [ldap | LDAP] base64(username:password) - -The plugin will validate the user against the LDAP server and cache the -credential for future requests for the duration specified in -`config.cache_ttl`. - -#### Upstream Headers - -When a client has been authenticated, the plugin will append some headers to the - request before proxying it to the upstream service, so that you can identify - the consumer in your code: - -* `X-Credential-Username`, the `username` of the Credential (only if the -consumer is not the 'anonymous' consumer) -* `X-Anonymous-Consumer`, will be set to `true` when authentication failed, and -the 'anonymous' consumer was set instead. -* `X-Consumer-ID`, the ID of the 'anonymous' consumer on Kong (only if -authentication failed and 'anonymous' was set) -* `X-Consumer-Custom-ID`, the `custom_id` of the 'anonymous' consumer (only if -authentication failed and 'anonymous' was set) -* `X-Consumer-Username`, the `username` of the 'anonymous' consumer (only if -authentication failed and 'anonymous' was set) - - -#### LDAP Search and config.bind_dn - -LDAP directory searching is performed during the request/plugin lifecycle. It is -used to retrieve the fully qualified DN of the user so a bind -request can be performed with the user's given LDAP username and password. The -search for the user being authenticated uses the `config.bind_dn` property. The -search uses `scope="sub"`, `filter="="`, and -`base_dn=`. Here is an example of how it performs the search -using the `ldapsearch` command line utility: - -```bash -$ ldapsearch -x -h "" -D "" -b -"=" -w "" -``` - -[api-object]: /gateway/latest/admin-api/#api-object -[configuration]: /gateway/latest/reference/configuration -[consumer-object]: /gateway/latest/admin-api/#consumer-object - diff --git a/app/_hub/kong-inc/ldap-auth-advanced/0.35-x.md b/app/_hub/kong-inc/ldap-auth-advanced/0.35-x.md deleted file mode 100644 index ebc904f539b1..000000000000 --- a/app/_hub/kong-inc/ldap-auth-advanced/0.35-x.md +++ /dev/null @@ -1,185 +0,0 @@ ---- - -name: LDAP Authentication Advanced -publisher: Kong Inc. -version: 0.35-x - -desc: Secure Kong clusters, routes and services with username and password protection -description: | - Add LDAP Bind Authentication with username and password protection. The plugin will check for valid credentials in the `Proxy-Authorization` and `Authorization` header (in this order). - -enterprise: true -type: plugin -categories: - - authentication - -kong_version_compatibility: - community_edition: - compatible: - enterprise_edition: - compatible: - - 0.35-x - - 0.34-x - -params: - name: ldap-auth-advanced - api_id: true - service_id: true - route_id: true - consumer_id: false - config: - - name: ldap_host - required: - default: - value_in_examples: - description: | - Host on which the LDAP server is running - - name: ldap_port - required: - default: - value_in_examples: - description: | - TCP port where the LDAP server is listening - - name: ldap_password - required: - default: - value_in_examples: - description: | - The password to the LDAP server - - name: start_tls - required: - default: "`false`" - value_in_examples: - description: | - Set it to `true` to issue StartTLS (Transport Layer Security) extended operation over `ldap` connection - - name: ldaps - required: - default: "`false`" - value_in_examples: - description: | - Set it to `true` to use `ldaps`, a secure protocol (that can be configured - to TLS) to connect to the LDAP server. - - name: base_dn - required: - default: - value_in_examples: - description: | - Base DN as the starting point for the search; e.g., "dc=example,dc=com" - - name: verify_ldap_host - required: - default: "`false`" - value_in_examples: - description: | - Set it to `true` to authenticate LDAP server. The server certificate will be verified according to the CA certificates specified by the `lua_ssl_trusted_certificate` directive. - - name: attribute - required: - default: - value_in_examples: - description: | - Attribute to be used to search the user; e.g., "cn" - - name: cache_ttl - required: - default: "`60`" - value_in_examples: - description: | - Cache expiry time in seconds - - name: timeout - required: false - default: "`10000`" - value_in_examples: - description: | - An optional timeout in milliseconds when waiting for connection with LDAP server - - name: keepalive - required: false - default: "`10000`" - value_in_examples: - description: | - An optional value in milliseconds that defines for how long an idle connection to LDAP server will live before being closed - - name: anonymous - required: false - default: - value_in_examples: - description: | - An optional string (consumer uuid) value to use as an "anonymous" consumer if authentication fails. If empty (default), the request will fail with an authentication failure `4xx`. Please note that this value must refer to the Consumer `id` attribute which is internal to Kong, and **not** its `custom_id`. - - name: header_type - required: false - default: "`ldap`" - value_in_examples: - description: | - An optional string to use as part of the Authorization header. By default, a valid Authorization header looks like this: `Authorization: ldap base64(username:password)`. If `header_type` is set to "basic" then the Authorization header would be `Authorization: basic base64(username:password)`. Note that `header_type` can take any string, not just `"ldap"` and `"basic"`. - - name: consumer_optional - required: false - default: "`false`" - value_in_examples: - description: | - Whether consumer mapping is optional. If `consumer_optional=true`, the plugin will not attempt to associate a consumer with the LDAP authenticated user. If `consumer_optional=false`, LDAP authenticated users can still access upstream resources. To prevent access from LDAP users that are not associated with consumers, set `consumer_optional=false`, set the `anonymous` field to an existing `consumer_id`, then use the Request Termination plugin to deny any requests from the anonymous consumer. - - name: consumer_by - required: false - default: '`[ "username", "custom_id" ]`' - value_in_examples: - description: | - Whether to authenticate consumer based on `username` and/or `custom_id` - - name: hide_credentials - required: false - default: "`false`" - value_in_examples: - description: | - An optional boolean value telling the plugin to hide the credential to the upstream server. It will be removed by Kong before proxying the request. - - name: bind_dn - required: - default: - value_in_examples: - description: | - The DN to bind to. Used to perform LDAP search of user. This bind_dn - should have permissions to search for the user being authenticated. - ---- - -### Usage - -In order to authenticate the user, client must set credentials in -`Proxy-Authorization` or `Authorization` header in following format: - - credentials := [ldap | LDAP] base64(username:password) - -The plugin will validate the user against the LDAP server and cache the -credential for future requests for the duration specified in -`config.cache_ttl`. - -#### Upstream Headers - -When a client has been authenticated, the plugin will append some headers to the - request before proxying it to the upstream service, so that you can identify - the consumer in your code: - -* `X-Credential-Username`, the `username` of the Credential (only if the -consumer is not the 'anonymous' consumer) -* `X-Anonymous-Consumer`, will be set to `true` when authentication failed, and -the 'anonymous' consumer was set instead. -* `X-Consumer-ID`, the ID of the 'anonymous' consumer on Kong (only if -authentication failed and 'anonymous' was set) -* `X-Consumer-Custom-ID`, the `custom_id` of the 'anonymous' consumer (only if -authentication failed and 'anonymous' was set) -* `X-Consumer-Username`, the `username` of the 'anonymous' consumer (only if -authentication failed and 'anonymous' was set) - - -#### LDAP Search and config.bind_dn - -LDAP directory searching is performed during the request/plugin lifecycle. It is -used to retrieve the fully qualified DN of the user so a bind -request can be performed with the user's given LDAP username and password. The -search for the user being authenticated uses the `config.bind_dn` property. The -search uses `scope="sub"`, `filter="="`, and -`base_dn=`. Here is an example of how it performs the search -using the `ldapsearch` command line utility: - -```bash -$ ldapsearch -x -h "" -D "" -b -"=" -w "" -``` - -[api-object]: /gateway/latest/admin-api/#api-object -[configuration]: /gateway/latest/reference/configuration -[consumer-object]: /gateway/latest/admin-api/#consumer-object - diff --git a/app/_hub/kong-inc/ldap-auth-advanced/0.36-x.md b/app/_hub/kong-inc/ldap-auth-advanced/0.36-x.md deleted file mode 100644 index 5c792efe6ffc..000000000000 --- a/app/_hub/kong-inc/ldap-auth-advanced/0.36-x.md +++ /dev/null @@ -1,186 +0,0 @@ ---- - -name: LDAP Authentication Advanced -publisher: Kong Inc. -version: 0.36-x - -desc: Secure Kong clusters, routes and services with username and password protection -description: | - Add LDAP Bind Authentication with username and password protection. The plugin will check for valid credentials in the `Proxy-Authorization` and `Authorization` header (in this order). - -enterprise: true -type: plugin -categories: - - authentication - -kong_version_compatibility: - community_edition: - compatible: - enterprise_edition: - compatible: - - 0.36-x - - 0.35-x - - 0.34-x - -params: - name: ldap-auth-advanced - api_id: true - service_id: true - route_id: true - consumer_id: false - config: - - name: ldap_host - required: - default: - value_in_examples: - description: | - Host on which the LDAP server is running - - name: ldap_port - required: - default: - value_in_examples: - description: | - TCP port where the LDAP server is listening - - name: ldap_password - required: - default: - value_in_examples: - description: | - The password to the LDAP server - - name: start_tls - required: - default: "`false`" - value_in_examples: - description: | - Set it to `true` to issue StartTLS (Transport Layer Security) extended operation over `ldap` connection - - name: ldaps - required: - default: "`false`" - value_in_examples: - description: | - Set it to `true` to use `ldaps`, a secure protocol (that can be configured - to TLS) to connect to the LDAP server. - - name: base_dn - required: - default: - value_in_examples: - description: | - Base DN as the starting point for the search; e.g., "dc=example,dc=com" - - name: verify_ldap_host - required: - default: "`false`" - value_in_examples: - description: | - Set it to `true` to authenticate LDAP server. The server certificate will be verified according to the CA certificates specified by the `lua_ssl_trusted_certificate` directive. - - name: attribute - required: - default: - value_in_examples: - description: | - Attribute to be used to search the user; e.g., "cn" - - name: cache_ttl - required: - default: "`60`" - value_in_examples: - description: | - Cache expiry time in seconds - - name: timeout - required: false - default: "`10000`" - value_in_examples: - description: | - An optional timeout in milliseconds when waiting for connection with LDAP server - - name: keepalive - required: false - default: "`10000`" - value_in_examples: - description: | - An optional value in milliseconds that defines for how long an idle connection to LDAP server will live before being closed - - name: anonymous - required: false - default: - value_in_examples: - description: | - An optional string (consumer uuid) value to use as an "anonymous" consumer if authentication fails. If empty (default), the request will fail with an authentication failure `4xx`. Please note that this value must refer to the Consumer `id` attribute which is internal to Kong, and **not** its `custom_id`. - - name: header_type - required: false - default: "`ldap`" - value_in_examples: - description: | - An optional string to use as part of the Authorization header. By default, a valid Authorization header looks like this: `Authorization: ldap base64(username:password)`. If `header_type` is set to "basic" then the Authorization header would be `Authorization: basic base64(username:password)`. Note that `header_type` can take any string, not just `"ldap"` and `"basic"`. - - name: consumer_optional - required: false - default: "`false`" - value_in_examples: - description: | - Whether consumer mapping is optional. If `consumer_optional=true`, the plugin will not attempt to associate a consumer with the LDAP authenticated user. If `consumer_optional=false`, LDAP authenticated users can still access upstream resources. To prevent access from LDAP users that are not associated with consumers, set `consumer_optional=false`, set the `anonymous` field to an existing `consumer_id`, then use the Request Termination plugin to deny any requests from the anonymous consumer.Whether consumer is optional - - name: consumer_by - required: false - default: '`[ "username", "custom_id" ]`' - value_in_examples: - description: | - Whether to authenticate consumer based on `username` and/or `custom_id` - - name: hide_credentials - required: false - default: "`false`" - value_in_examples: - description: | - An optional boolean value telling the plugin to hide the credential to the upstream server. It will be removed by Kong before proxying the request. - - name: bind_dn - required: - default: - value_in_examples: - description: | - The DN to bind to. Used to perform LDAP search of user. This bind_dn - should have permissions to search for the user being authenticated. - ---- - -### Usage - -In order to authenticate the user, client must set credentials in -`Proxy-Authorization` or `Authorization` header in following format: - - credentials := [ldap | LDAP] base64(username:password) - -The plugin will validate the user against the LDAP server and cache the -credential for future requests for the duration specified in -`config.cache_ttl`. - -#### Upstream Headers - -When a client has been authenticated, the plugin will append some headers to the - request before proxying it to the upstream service, so that you can identify - the consumer in your code: - -* `X-Credential-Username`, the `username` of the Credential (only if the -consumer is not the 'anonymous' consumer) -* `X-Anonymous-Consumer`, will be set to `true` when authentication failed, and -the 'anonymous' consumer was set instead. -* `X-Consumer-ID`, the ID of the 'anonymous' consumer on Kong (only if -authentication failed and 'anonymous' was set) -* `X-Consumer-Custom-ID`, the `custom_id` of the 'anonymous' consumer (only if -authentication failed and 'anonymous' was set) -* `X-Consumer-Username`, the `username` of the 'anonymous' consumer (only if -authentication failed and 'anonymous' was set) - - -#### LDAP Search and config.bind_dn - -LDAP directory searching is performed during the request/plugin lifecycle. It is -used to retrieve the fully qualified DN of the user so a bind -request can be performed with the user's given LDAP username and password. The -search for the user being authenticated uses the `config.bind_dn` property. The -search uses `scope="sub"`, `filter="="`, and -`base_dn=`. Here is an example of how it performs the search -using the `ldapsearch` command line utility: - -```bash -$ ldapsearch -x -h "" -D "" -b -"=" -w "" -``` - -[api-object]: /gateway/latest/admin-api/#api-object -[configuration]: /gateway/latest/reference/configuration -[consumer-object]: /gateway/latest/admin-api/#consumer-object - diff --git a/app/_hub/kong-inc/ldap-auth-advanced/1.3.x.md b/app/_hub/kong-inc/ldap-auth-advanced/1.3.x.md deleted file mode 100644 index b3acbf21117d..000000000000 --- a/app/_hub/kong-inc/ldap-auth-advanced/1.3.x.md +++ /dev/null @@ -1,233 +0,0 @@ ---- - -name: LDAP Authentication Advanced -publisher: Kong Inc. -version: 1.3-x - -desc: Secure Kong clusters, Routes, and Services with username and password protection -description: | - Add LDAP Bind Authentication with username and password protection. The plugin - checks for valid credentials in the `Proxy-Authorization` and `Authorization` headers - (in that order). - -enterprise: true -type: plugin -categories: - - authentication - -kong_version_compatibility: - community_edition: - compatible: - enterprise_edition: - compatible: - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x - - 0.35-x - - 0.34-x - -params: - name: ldap-auth-advanced - api_id: true - service_id: true - route_id: true - consumer_id: false - protocols: ["http", "https", "gprc", "grpcs"] - dbless_compatible: yes - config: - - name: ldap_host - required: true - default: - value_in_examples: ldap.example.com - description: | - Host on which the LDAP server is running. - - name: ldap_port - required: true - default: 389 - value_in_examples: 389 - description: | - TCP port where the LDAP server is listening. 389 is the default - port for non-SSL LDAP and AD. 636 is the port required for SSL LDAP and AD. If `ldaps` is - configured, you must use port 636. - - name: ldap_password - required: - default: - value_in_examples: - description: | - The password to the LDAP server. - - name: start_tls - required: true - default: "`false`" - value_in_examples: true - description: | - Set it to `true` to issue StartTLS (Transport Layer Security) extended operation - over `ldap` connection. If the `start_tls` setting is enabled, ensure the `ldaps` - setting is disabled. - - name: ldaps - required: true - default: "`false`" - value_in_examples: - description: | - Set it to `true` to use `ldaps`, a secure protocol (that can be configured - to TLS) to connect to the LDAP server. When `ldaps` is - configured, you must use port 636. If the `ldap` setting is enabled, ensure the - `start_tls` setting is disabled. - - name: base_dn - required: true - default: - value_in_examples: dc=example,dc=com - description: | - Base DN as the starting point for the search; e.g., "dc=example,dc=com". - - name: verify_ldap_host - required: true - default: "`false`" - value_in_examples: false - description: | - Set to `true` to authenticate LDAP server. The server certificate will be verified according to the CA certificates specified by the `lua_ssl_trusted_certificate` directive. - - name: attribute - required: true - default: - value_in_examples: cn - description: | - Attribute to be used to search the user; e.g., "cn". - - name: cache_ttl - required: true - default: "`60`" - value_in_examples: 60 - description: | - Cache expiry time in seconds. - - name: timeout - required: false - default: "`10000`" - value_in_examples: - description: | - An optional timeout in milliseconds when waiting for connection with LDAP server. - - name: keepalive - required: false - default: "`10000`" - value_in_examples: - description: | - An optional value in milliseconds that defines how long an idle connection to LDAP server will live before being closed. - - name: anonymous - required: false - default: - value_in_examples: - description: | - An optional string (consumer UUID) value to use as an "anonymous" consumer if authentication fails. If empty (default), the request will fail with an authentication failure `4xx`. The value must refer to the Consumer `id` attribute that is internal to Kong, **not** its `custom_id`. - - name: header_type - required: false - default: "`ldap`" - value_in_examples: ldap - description: | - An optional string to use as part of the Authorization header. By default, a valid Authorization header looks like this: `Authorization: ldap base64(username:password)`. If `header_type` is set to "basic", then the Authorization header would be `Authorization: basic base64(username:password)`. Note that `header_type` can take any string, not just `"ldap"` and `"basic"`. - - name: consumer_optional - required: false - default: "`false`" - value_in_examples: - description: | - Whether consumer mapping is optional. If `consumer_optional=true`, the plugin will not attempt to associate a consumer with the LDAP authenticated user. If `consumer_optional=false`, LDAP authenticated users can still access upstream resources. To prevent access from LDAP users that are not associated with consumers, set `consumer_optional=false`, set the `anonymous` field to an existing `consumer_id`, then use the Request Termination plugin to deny any requests from the anonymous consumer. - - name: consumer_by - required: false - default: '`[ "username", "custom_id" ]`' - value_in_examples: - description: | - Whether to authenticate Consumers based on `username` and/or `custom_id`. - - name: hide_credentials - required: false - default: "`false`" - value_in_examples: - description: | - An optional boolean value telling the plugin to hide the credential to the upstream server. It will be removed by Kong before proxying the request. - - name: bind_dn - required: - default: - value_in_examples: - description: | - The DN to bind to. Used to perform LDAP search of user. This `bind_dn` - should have permissions to search for the user being authenticated. - - name: group_base_dn - required: - default: "matches `conf.base_dn`" - value_in_examples: - description: | - Sets a distinguished name (DN) for the entry where LDAP searches for groups begin. - - name: group_name_attribute - required: - default: "matches `conf.attribute`" - value_in_examples: - description: | - Sets the attribute holding the name of a group, typically called `name` - (in Active Directory) or `cn` (in OpenLDAP). - - name: group_member_attribute - required: - default: "`memberOf`" - value_in_examples: - description: | - Sets the attribute holding the members of the LDAP group. - ---- - -## Usage - -To authenticate a user, the client must set credentials in either the -`Proxy-Authorization` or `Authorization` header in the following format: - - credentials := [ldap | LDAP] base64(username:password) - -The Authorization header would look something like: - - Authorization: ldap dGxibGVzc2luZzpLMG5nU3RyMG5n - -The plugin validates the user against the LDAP server and caches the -credentials for future requests for the duration specified in -`config.cache_ttl`. - -You can set the header type `ldap` to any string (such as `basic`) using -`config.header_type`. - - - -### Upstream Headers - -When a client has been authenticated, the plugin appends some headers to the -request before proxying it to the upstream service so that you can identify -the consumer in your code: - -* `X-Credential-Username`, the `username` of the Credential (only if the -consumer is not the 'anonymous' consumer) -* `X-Anonymous-Consumer`, will be set to `true` when authentication failed, and -the 'anonymous' consumer was set instead. -* `X-Consumer-ID`, the ID of the 'anonymous' consumer on Kong (only if -authentication failed and 'anonymous' was set) -* `X-Consumer-Custom-ID`, the `custom_id` of the 'anonymous' consumer (only if -authentication failed and 'anonymous' was set) -* `X-Consumer-Username`, the `username` of the 'anonymous' consumer (only if -authentication failed and 'anonymous' was set) - - -### LDAP Search and `config.bind_dn` - -LDAP directory searching is performed during the request/plugin lifecycle. It is -used to retrieve the fully qualified DN of the user so a bind -request can be performed with a user's given LDAP username and password. The -search for the user being authenticated uses the `config.bind_dn` property. The -search uses `scope="sub"`, `filter="="`, and -`base_dn=`. Here is an example of how it performs the search -using the `ldapsearch` command line utility: - -```bash -$ ldapsearch -x -h "" -D "" -b -"=" -w "" -``` - -[api-object]: /gateway/latest/admin-api/#api-object -[configuration]: /gateway/latest/reference/configuration -[consumer-object]: /gateway/latest/admin-api/#consumer-object - - - -### Using Service Directory Mapping on the CLI - -{% include /md/2.1.x/ldap/ldap-service-directory-mapping.md %} diff --git a/app/_hub/kong-inc/ldap-auth-advanced/2.2.x.md b/app/_hub/kong-inc/ldap-auth-advanced/2.2.x.md deleted file mode 100644 index 59b69fbf2189..000000000000 --- a/app/_hub/kong-inc/ldap-auth-advanced/2.2.x.md +++ /dev/null @@ -1,251 +0,0 @@ ---- - -name: LDAP Authentication Advanced -publisher: Kong Inc. -version: 2.2.x - -desc: Secure Kong clusters, Routes, and Services with username and password protection -description: | - Add LDAP Bind Authentication with username and password protection. The plugin - checks for valid credentials in the `Proxy-Authorization` and `Authorization` headers - (in that order). - -enterprise: true -type: plugin -categories: - - authentication - -kong_version_compatibility: - community_edition: - compatible: - enterprise_edition: - compatible: - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x - - 0.35-x - - 0.34-x - -params: - name: ldap-auth-advanced - api_id: true - service_id: true - route_id: true - consumer_id: false - protocols: ["http", "https", "gprc", "grpcs"] - dbless_compatible: yes - config: - - name: ldap_host - required: true - default: - value_in_examples: ldap.example.com - description: | - Host on which the LDAP server is running. - - name: ldap_port - required: true - default: 389 - value_in_examples: 389 - description: | - TCP port where the LDAP server is listening. 389 is the default - port for non-SSL LDAP and AD. 636 is the port required for SSL LDAP and AD. If `ldaps` is - configured, you must use port 636. - - name: ldap_password - required: - default: - value_in_examples: - description: | - The password to the LDAP server. - - name: start_tls - required: true - default: "`false`" - value_in_examples: true - description: | - Set it to `true` to issue StartTLS (Transport Layer Security) extended operation - over `ldap` connection. If the `start_tls` setting is enabled, ensure the `ldaps` - setting is disabled. - - name: ldaps - required: true - default: "`false`" - value_in_examples: - description: | - Set it to `true` to use `ldaps`, a secure protocol (that can be configured - to TLS) to connect to the LDAP server. When `ldaps` is - configured, you must use port 636. If the `ldap` setting is enabled, ensure the - `start_tls` setting is disabled. - - name: base_dn - required: true - default: - value_in_examples: dc=example,dc=com - description: | - Base DN as the starting point for the search; e.g., "dc=example,dc=com". - - name: verify_ldap_host - required: true - default: "`false`" - value_in_examples: false - description: | - Set to `true` to authenticate LDAP server. The server certificate will be verified according to the CA certificates specified by the `lua_ssl_trusted_certificate` directive. - - name: attribute - required: true - default: - value_in_examples: cn - description: | - Attribute to be used to search the user; e.g., "cn". - - name: cache_ttl - required: true - default: "`60`" - value_in_examples: 60 - description: | - Cache expiry time in seconds. - - name: timeout - required: false - default: "`10000`" - value_in_examples: - description: | - An optional timeout in milliseconds when waiting for connection with LDAP server. - - name: keepalive - required: false - default: "`10000`" - value_in_examples: - description: | - An optional value in milliseconds that defines how long an idle connection to LDAP server will live before being closed. - - name: anonymous - required: false - default: - value_in_examples: - description: | - An optional string (consumer UUID) value to use as an "anonymous" consumer if authentication fails. If empty (default), the request will fail with an authentication failure `4xx`. The value must refer to the Consumer `id` attribute that is internal to Kong, **not** its `custom_id`. - - name: header_type - required: false - default: "`ldap`" - value_in_examples: ldap - description: | - An optional string to use as part of the Authorization header. By default, a valid Authorization header looks like this: `Authorization: ldap base64(username:password)`. If `header_type` is set to "basic", then the Authorization header would be `Authorization: basic base64(username:password)`. Note that `header_type` can take any string, not just `"ldap"` and `"basic"`. - - name: consumer_optional - required: false - default: "`false`" - value_in_examples: - description: | - Whether consumer mapping is optional. If `consumer_optional=true`, the plugin will not attempt to associate a consumer with the LDAP authenticated user. If `consumer_optional=false`, LDAP authenticated users can still access upstream resources. To prevent access from LDAP users that are not associated with consumers, set `consumer_optional=false`, set the `anonymous` field to an existing `consumer_id`, then use the Request Termination plugin to deny any requests from the anonymous consumer. - - name: consumer_by - required: false - default: '`[ "username", "custom_id" ]`' - value_in_examples: - description: | - Whether to authenticate Consumers based on `username` and/or `custom_id`. - - name: hide_credentials - required: false - default: "`false`" - value_in_examples: - description: | - An optional boolean value telling the plugin to hide the credential to the upstream server. It will be removed by Kong before proxying the request. - - name: bind_dn - required: - default: - value_in_examples: - description: | - The DN to bind to. Used to perform LDAP search of user. This `bind_dn` - should have permissions to search for the user being authenticated. - - name: group_base_dn - required: - default: "matches `conf.base_dn`" - value_in_examples: - description: | - Sets a distinguished name (DN) for the entry where LDAP searches for groups begin. This field is case-insensitive. - - name: group_name_attribute - required: - default: "matches `conf.attribute`" - value_in_examples: - description: | - Sets the attribute holding the name of a group, typically - called `name` (in Active Directory) or `cn` (in OpenLDAP). This - field is case-insensitive. - - name: group_member_attribute - required: - default: "`memberOf`" - value_in_examples: - description: | - Sets the attribute holding the members of the LDAP group. This field is case-sensitive. - - name: log_search_results - required: false - default: "`false`" - value_in_examples: - description: | - Displays all the LDAP search results received from the LDAP - server for debugging purposes. Not recommended to be enabled in - a production environment. - ---- - -## Usage - -To authenticate a user, the client must set credentials in either the -`Proxy-Authorization` or `Authorization` header in the following format: - - credentials := [ldap | LDAP] base64(username:password) - -The Authorization header would look something like: - - Authorization: ldap dGxibGVzc2luZzpLMG5nU3RyMG5n - -The plugin validates the user against the LDAP server and caches the -credentials for future requests for the duration specified in -`config.cache_ttl`. - -You can set the header type `ldap` to any string (such as `basic`) using -`config.header_type`. - - - -### Upstream Headers - -When a client has been authenticated, the plugin appends some headers to the -request before proxying it to the upstream service so that you can identify -the consumer in your code: - -* `X-Credential-Username`, the `username` of the Credential (only if the -consumer is not the 'anonymous' consumer) -* `X-Anonymous-Consumer`, will be set to `true` when authentication failed, and -the 'anonymous' consumer was set instead. -* `X-Consumer-ID`, the ID of the 'anonymous' consumer on Kong (only if -authentication failed and 'anonymous' was set) -* `X-Consumer-Custom-ID`, the `custom_id` of the 'anonymous' consumer (only if -authentication failed and 'anonymous' was set) -* `X-Consumer-Username`, the `username` of the 'anonymous' consumer (only if -authentication failed and 'anonymous' was set) - - -### LDAP Search and `config.bind_dn` - -LDAP directory searching is performed during the request/plugin lifecycle. It is -used to retrieve the fully qualified DN of the user so a bind -request can be performed with a user's given LDAP username and password. The -search for the user being authenticated uses the `config.bind_dn` property. The -search uses `scope="sub"`, `filter="="`, and -`base_dn=`. Here is an example of how it performs the search -using the `ldapsearch` command line utility: - -```bash -$ ldapsearch -x -h "" -D "" -b -"=" -w "" -``` - -[api-object]: /gateway/latest/admin-api/#api-object -[configuration]: /gateway/latest/reference/configuration -[consumer-object]: /gateway/latest/admin-api/#consumer-object - - - -### Using Service Directory Mapping on the CLI - -{% include /md/2.1.x/ldap/ldap-service-directory-mapping.md %} - -## Notes - -`config.group_base_dn` and `config.base_dn` do not accept an array and -it has to fully match the full DN the group is in - it won’t work if it -is specified a more generic DN, therefore it needs to be specific. For -example, considering a case where there are nested `"OU's"`. If a -top-level DN such as `"ou=dev,o=company"` is specified instead of -`"ou=role,ou=groups,ou=dev,o=company"`, the authentication will fail. diff --git a/app/_hub/kong-inc/ldap-auth-advanced/2.3.x.md b/app/_hub/kong-inc/ldap-auth-advanced/2.3.x.md deleted file mode 100644 index 0a422765fc3e..000000000000 --- a/app/_hub/kong-inc/ldap-auth-advanced/2.3.x.md +++ /dev/null @@ -1,302 +0,0 @@ ---- -name: LDAP Authentication Advanced -publisher: Kong Inc. -version: 2.3.x -desc: 'Secure Kong clusters, Routes, and Services with username and password protection' -description: | - Add LDAP Bind Authentication with username and password protection. The plugin - checks for valid credentials in the `Proxy-Authorization` and `Authorization` headers - (in that order). - - The LDAP Authentication Advanced plugin - provides features not available in the open-source [LDAP Authentication plugin](/hub/kong-inc/ldap-auth/), - such as LDAP searches for group and consumer mapping: - * Ability to authenticate based on username or custom ID. - * The ability to bind to an enterprise LDAP directory with a password. - * The ability to obtain LDAP groups and set them in a header to the request before proxying to the upstream. This is useful for Kong Manager role mapping. -enterprise: true -plus: true -type: plugin -categories: - - authentication -kong_version_compatibility: - community_edition: - compatible: null - enterprise_edition: - compatible: - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x -params: - name: ldap-auth-advanced - service_id: true - route_id: true - consumer_id: false - protocols: - - http - - https - - gprc - - grpcs - dbless_compatible: 'yes' - config: - - name: ldap_host - required: true - default: null - value_in_examples: ldap.example.com - datatype: string - description: | - Host on which the LDAP server is running. - - name: ldap_port - required: true - default: 389 - value_in_examples: 389 - datatype: number - description: | - TCP port where the LDAP server is listening. 389 is the default - port for non-SSL LDAP and AD. 636 is the port required for SSL LDAP and AD. If `ldaps` is - configured, you must use port 636. - - name: ldap_password - required: null - default: null - value_in_examples: null - datatype: string - description: | - The password to the LDAP server. - - name: start_tls - required: true - default: '`false`' - value_in_examples: true - datatype: boolean - description: | - Set it to `true` to issue StartTLS (Transport Layer Security) extended operation - over `ldap` connection. If the `start_tls` setting is enabled, ensure the `ldaps` - setting is disabled. - - name: ldaps - required: true - default: '`false`' - value_in_examples: null - datatype: boolean - description: | - Set it to `true` to use `ldaps`, a secure protocol (that can be configured - to TLS) to connect to the LDAP server. When `ldaps` is - configured, you must use port 636. If the `ldap` setting is enabled, ensure the - `start_tls` setting is disabled. - - name: base_dn - required: true - default: null - value_in_examples: 'dc=example,dc=com' - datatype: string - description: | - Base DN as the starting point for the search; e.g., "dc=example,dc=com". - - name: verify_ldap_host - required: true - default: '`false`' - value_in_examples: false - datatype: boolean - description: | - Set to `true` to authenticate LDAP server. The server certificate will be verified according to the CA certificates specified by the `lua_ssl_trusted_certificate` directive. - - name: attribute - required: true - default: null - value_in_examples: cn - datatype: string - description: | - Attribute to be used to search the user; e.g., "cn". - - name: cache_ttl - required: true - default: '`60`' - value_in_examples: 60 - datatype: number - description: | - Cache expiry time in seconds. - - name: timeout - required: false - default: '`10000`' - value_in_examples: null - datatype: number - description: | - An optional timeout in milliseconds when waiting for connection with LDAP server. - - name: keepalive - required: false - default: '`60000`' - value_in_examples: null - datatype: number - description: | - An optional value in milliseconds that defines how long an idle connection to LDAP server will live before being closed. - - name: anonymous - required: false - default: null - value_in_examples: null - datatype: string - description: | - An optional string (consumer UUID) value to use as an "anonymous" consumer if authentication fails. If empty (default), the - request will fail with an authentication failure `4xx`. - - **Note:** The value must refer to the Consumer `id` attribute that is internal to Kong, **not** its `custom_id`. - - name: header_type - required: false - default: '`ldap`' - value_in_examples: ldap - datatype: string - description: | - An optional string to use as part of the Authorization header. By default, a valid Authorization header looks like this: - `Authorization: ldap base64(username:password)`. If `header_type` is set to "basic", then the Authorization header would be - `Authorization: basic base64(username:password)`. Note that `header_type` can take any string, not just `"ldap"` and `"basic"`. - - name: consumer_optional - required: false - default: '`false`' - value_in_examples: null - datatype: boolean - description: | - Whether consumer mapping is optional. If `consumer_optional=true`, the plugin will not attempt to associate a consumer with the - LDAP authenticated user. If `consumer_optional=false`, LDAP authenticated users can still access upstream resources. - - To prevent access from LDAP users that are not associated with consumers, set `consumer_optional=false`, set the `anonymous` field to an - existing `consumer_id`, then use the [Request Termination plugin](/hub/kong-inc/request-termination/) to deny any requests from the anonymous consumer. - - name: consumer_by - required: false - default: '`[ "username", "custom_id" ]`' - value_in_examples: null - datatype: array of string elements - description: | - Whether to authenticate consumers based on `username`, `custom_id`, or both. - - name: hide_credentials - required: true - default: '`false`' - value_in_examples: null - datatype: boolean - description: | - An optional boolean value telling the plugin to hide the credential to the upstream server. It will be removed by Kong before proxying the request. - - name: bind_dn - required: false - default: null - value_in_examples: null - datatype: string - description: | - The DN to bind to. Used to perform LDAP search of user. This `bind_dn` - should have permissions to search for the user being authenticated. - - name: group_base_dn - required: null - default: matches `conf.base_dn` - value_in_examples: null - datatype: string - description: | - Sets a distinguished name (DN) for the entry where LDAP searches for groups begin. This field is case-insensitive. - - name: group_name_attribute - required: null - default: matches `conf.attribute` - value_in_examples: null - datatype: string - description: | - Sets the attribute holding the name of a group, typically - called `name` (in Active Directory) or `cn` (in OpenLDAP). This - field is case-insensitive. - - name: group_member_attribute - required: null - default: '`memberOf`' - value_in_examples: null - datatype: string - description: | - Sets the attribute holding the members of the LDAP group. This field is case-sensitive. - - name: log_search_results - required: false - default: '`false`' - value_in_examples: null - datatype: boolean - description: | - Displays all the LDAP search results received from the LDAP - server for debugging purposes. Not recommended to be enabled in - a production environment. ---- - -## Usage - -To authenticate a user, the client must set credentials in either the -`Proxy-Authorization` or `Authorization` header in the following format: - - credentials := [ldap | LDAP] base64(username:password) - -The Authorization header would look something like: - - Authorization: ldap dGxibGVzc2luZzpLMG5nU3RyMG5n - -The plugin validates the user against the LDAP server and caches the -credentials for future requests for the duration specified in -`config.cache_ttl`. - -You can set the header type `ldap` to any string (such as `basic`) using -`config.header_type`. - - - -### Upstream Headers - -When a client has been authenticated, the plugin appends some headers to the -request before proxying it to the upstream service so that you can identify -the consumer in your code: - -* `X-Credential-Username`, the `username` of the Credential (only if the -consumer is not the 'anonymous' consumer) -* `X-Anonymous-Consumer`, will be set to `true` when authentication failed, and -the 'anonymous' consumer was set instead. -* `X-Consumer-ID`, the ID of the 'anonymous' consumer on Kong (only if -authentication failed and 'anonymous' was set) -* `X-Consumer-Custom-ID`, the `custom_id` of the 'anonymous' consumer (only if -authentication failed and 'anonymous' was set) -* `X-Consumer-Username`, the `username` of the 'anonymous' consumer (only if -authentication failed and 'anonymous' was set) - - -### LDAP Search and `config.bind_dn` - -LDAP directory searching is performed during the request/plugin lifecycle. It is -used to retrieve the fully qualified DN of the user so a bind -request can be performed with a user's given LDAP username and password. The -search for the user being authenticated uses the `config.bind_dn` property. The -search uses `scope="sub"`, `filter="="`, and -`base_dn=`. Here is an example of how it performs the search -using the `ldapsearch` command line utility: - -```bash -$ ldapsearch -x -h "" -D "" -b -"=" -w "" -``` - -[api-object]: /gateway/latest/admin-api/#api-object -[configuration]: /gateway/latest/reference/configuration -[consumer-object]: /gateway/latest/admin-api/#consumer-object - - - -### Using Service Directory Mapping on the CLI - -{% include /md/2.1.x/ldap/ldap-service-directory-mapping.md %} - -## Notes - -`config.group_base_dn` and `config.base_dn` do not accept an array and -it has to fully match the full DN the group is in - it won’t work if it -is specified a more generic DN, therefore it needs to be specific. For -example, considering a case where there are nested `"OU's"`. If a -top-level DN such as `"ou=dev,o=company"` is specified instead of -`"ou=role,ou=groups,ou=dev,o=company"`, the authentication will fail. - -Referrals are not supported in the plugin. A workaround is -to hit the LDAP Global Catalog instead, which is usually listening on a -different port than the default `389`. That way, referrals don't get sent -back to the plugin. - -The plugin doesn’t authenticate users (allow/deny requests) based on group -membership. For example: -- If the user is a member of an LDAP group, the request is allowed. -- if the user is not a member of an LDAP group, the request is still allowed. - -The plugin obtains LDAP groups and sets them in a header, `x-authenticated-groups`, -to the request before proxying to the upstream. This is useful for Kong Manager role -mapping. diff --git a/app/_hub/kong-inc/ldap-auth-advanced/2.7.x.md b/app/_hub/kong-inc/ldap-auth-advanced/2.7.x.md deleted file mode 100644 index b546939be6dd..000000000000 --- a/app/_hub/kong-inc/ldap-auth-advanced/2.7.x.md +++ /dev/null @@ -1,305 +0,0 @@ ---- -name: LDAP Authentication Advanced -publisher: Kong Inc. -version: 2.7.x # plugin version 1.2.x -desc: 'Secure Kong clusters, Routes, and Services with username and password protection' -description: | - Add LDAP Bind Authentication with username and password protection. The plugin - checks for valid credentials in the `Proxy-Authorization` and `Authorization` headers - (in that order). - - The LDAP Authentication Advanced plugin - provides features not available in the open-source [LDAP Authentication plugin](/hub/kong-inc/ldap-auth/), - such as LDAP searches for group and consumer mapping: - * Ability to authenticate based on username or custom ID. - * The ability to bind to an enterprise LDAP directory with a password. - * The ability to obtain LDAP groups and set them in a header to the request before proxying to the upstream. This is useful for Kong Manager role mapping. -enterprise: true -plus: true -type: plugin -categories: - - authentication -kong_version_compatibility: - community_edition: - compatible: null - enterprise_edition: - compatible: - - 2.7.x -params: - name: ldap-auth-advanced - service_id: true - route_id: true - consumer_id: false - protocols: - - http - - https - - gprc - - grpcs - dbless_compatible: 'yes' - config: - - name: ldap_host - required: true - default: null - value_in_examples: ldap.example.com - datatype: string - description: | - Host on which the LDAP server is running. - - name: ldap_port - required: true - default: 389 - value_in_examples: 389 - datatype: number - description: | - TCP port where the LDAP server is listening. 389 is the default - port for non-SSL LDAP and AD. 636 is the port required for SSL LDAP and AD. If `ldaps` is - configured, you must use port 636. - - name: ldap_password - required: null - default: null - value_in_examples: null - datatype: string - encrypted: true - description: | - The password to the LDAP server. - - name: start_tls - required: true - default: '`false`' - value_in_examples: true - datatype: boolean - description: | - Set it to `true` to issue StartTLS (Transport Layer Security) extended operation - over `ldap` connection. If the `start_tls` setting is enabled, ensure the `ldaps` - setting is disabled. - - name: ldaps - required: true - default: '`false`' - value_in_examples: null - datatype: boolean - description: | - Set it to `true` to use `ldaps`, a secure protocol (that can be configured - to TLS) to connect to the LDAP server. When `ldaps` is - configured, you must use port 636. If the `ldap` setting is enabled, ensure the - `start_tls` setting is disabled. - - name: base_dn - required: true - default: null - value_in_examples: 'dc=example,dc=com' - datatype: string - description: | - Base DN as the starting point for the search; e.g., "dc=example,dc=com". - - name: verify_ldap_host - required: true - default: '`false`' - value_in_examples: false - datatype: boolean - description: | - Set to `true` to authenticate LDAP server. The server certificate will be verified according to the CA certificates specified by the `lua_ssl_trusted_certificate` directive. - - name: attribute - required: true - default: null - value_in_examples: cn - datatype: string - description: | - Attribute to be used to search the user; e.g., "cn". - - name: cache_ttl - required: true - default: '`60`' - value_in_examples: 60 - datatype: number - description: | - Cache expiry time in seconds. - - name: timeout - required: false - default: '`10000`' - value_in_examples: null - datatype: number - description: | - An optional timeout in milliseconds when waiting for connection with LDAP server. - - name: keepalive - required: false - default: '`60000`' - value_in_examples: null - datatype: number - description: | - An optional value in milliseconds that defines how long an idle connection to LDAP server will live before being closed. - - name: anonymous - required: false - default: null - value_in_examples: null - datatype: string - description: | - An optional string (consumer UUID) value to use as an "anonymous" consumer if authentication fails. If empty (default), the - request will fail with an authentication failure `4xx`. - - **Note:** The value must refer to the Consumer `id` attribute that is internal to Kong, **not** its `custom_id`. - - name: header_type - required: false - default: '`ldap`' - value_in_examples: ldap - datatype: string - description: | - An optional string to use as part of the Authorization header. By default, a valid Authorization header looks like this: - `Authorization: ldap base64(username:password)`. If `header_type` is set to "basic", then the Authorization header would be - `Authorization: basic base64(username:password)`. Note that `header_type` can take any string, not just `"ldap"` and `"basic"`. - - name: consumer_optional - required: false - default: '`false`' - value_in_examples: null - datatype: boolean - description: | - Whether consumer mapping is optional. If `consumer_optional=true`, the plugin will not attempt to associate a consumer with the - LDAP authenticated user. If `consumer_optional=false`, LDAP authenticated users can still access upstream resources. - - To prevent access from LDAP users that are not associated with consumers, set `consumer_optional=false`, set the `anonymous` field to an - existing `consumer_id`, then use the [Request Termination plugin](/hub/kong-inc/request-termination/) to deny any requests from the anonymous consumer. - - name: consumer_by - required: false - default: '`[ "username", "custom_id" ]`' - value_in_examples: null - datatype: array of string elements - description: | - Whether to authenticate consumers based on `username`, `custom_id`, or both. - - name: hide_credentials - required: true - default: '`false`' - value_in_examples: null - datatype: boolean - description: | - An optional boolean value telling the plugin to hide the credential to the upstream server. It will be removed by Kong before proxying the request. - - name: bind_dn - required: false - default: null - value_in_examples: null - datatype: string - description: | - The DN to bind to. Used to perform LDAP search of user. This `bind_dn` - should have permissions to search for the user being authenticated. - - name: group_base_dn - required: null - default: matches `conf.base_dn` - value_in_examples: null - datatype: string - description: | - Sets a distinguished name (DN) for the entry where LDAP searches for groups begin. This field is case-insensitive. - - name: group_name_attribute - required: null - default: matches `conf.attribute` - value_in_examples: null - datatype: string - description: | - Sets the attribute holding the name of a group, typically - called `name` (in Active Directory) or `cn` (in OpenLDAP). This - field is case-insensitive. - - name: group_member_attribute - required: null - default: '`memberOf`' - value_in_examples: null - datatype: string - description: | - Sets the attribute holding the members of the LDAP group. This field is case-sensitive. - - name: log_search_results - required: false - default: '`false`' - value_in_examples: null - datatype: boolean - description: | - Displays all the LDAP search results received from the LDAP - server for debugging purposes. Not recommended to be enabled in - a production environment. ---- - -## Usage - -To authenticate a user, the client must set credentials in either the -`Proxy-Authorization` or `Authorization` header in the following format: - - credentials := [ldap | LDAP] base64(username:password) - -The Authorization header would look something like: - - Authorization: ldap dGxibGVzc2luZzpLMG5nU3RyMG5n - -The plugin validates the user against the LDAP server and caches the -credentials for future requests for the duration specified in -`config.cache_ttl`. - -You can set the header type `ldap` to any string (such as `basic`) using -`config.header_type`. - - - -### Upstream Headers - -When a client has been authenticated, the plugin appends some headers to the -request before proxying it to the upstream service so that you can identify -the consumer in your code: - -* `X-Credential-Username`, the `username` of the Credential (only if the -consumer is not the 'anonymous' consumer) -* `X-Anonymous-Consumer`, will be set to `true` when authentication failed, and -the 'anonymous' consumer was set instead. -* `X-Consumer-ID`, the ID of the 'anonymous' consumer on Kong (only if -authentication failed and 'anonymous' was set) -* `X-Consumer-Custom-ID`, the `custom_id` of the 'anonymous' consumer (only if -authentication failed and 'anonymous' was set) -* `X-Consumer-Username`, the `username` of the 'anonymous' consumer (only if -authentication failed and 'anonymous' was set) - - -### LDAP Search and `config.bind_dn` - -LDAP directory searching is performed during the request/plugin lifecycle. It is -used to retrieve the fully qualified DN of the user so a bind -request can be performed with a user's given LDAP username and password. The -search for the user being authenticated uses the `config.bind_dn` property. The -search uses `scope="sub"`, `filter="="`, and -`base_dn=`. Here is an example of how it performs the search -using the `ldapsearch` command line utility: - -```bash -$ ldapsearch -x -h "" -D "" -b -"=" -w "" -``` - -[api-object]: /gateway/latest/admin-api/#api-object -[configuration]: /gateway/latest/reference/configuration -[consumer-object]: /gateway/latest/admin-api/#consumer-object - - - -### Using Service Directory Mapping on the CLI - -{% include /md/2.1.x/ldap/ldap-service-directory-mapping.md %} - -## Notes - -`config.group_base_dn` and `config.base_dn` do not accept an array and -it has to fully match the full DN the group is in - it won’t work if it -is specified a more generic DN, therefore it needs to be specific. For -example, considering a case where there are nested `"OU's"`. If a -top-level DN such as `"ou=dev,o=company"` is specified instead of -`"ou=role,ou=groups,ou=dev,o=company"`, the authentication will fail. - -Referrals are not supported in the plugin. A workaround is -to hit the LDAP Global Catalog instead, which is usually listening on a -different port than the default `389`. That way, referrals don't get sent -back to the plugin. - -The plugin doesn’t authenticate users (allow/deny requests) based on group -membership. For example: -- If the user is a member of an LDAP group, the request is allowed. -- if the user is not a member of an LDAP group, the request is still allowed. - -The plugin obtains LDAP groups and sets them in a header, `x-authenticated-groups`, -to the request before proxying to the upstream. This is useful for Kong Manager role -mapping. - ---- - -## Changelog - -### Kong Gateway 2.7.x -> Plugin version: 1.2.0 - -* Starting with {{site.base_gateway}} 2.7.0.0, if keyring encryption is enabled, - the `config.ldap_password` parameter value will be encrypted. diff --git a/app/_hub/kong-inc/ldap-auth-advanced/_index.md b/app/_hub/kong-inc/ldap-auth-advanced/_index.md index 54f866470225..948f8294b9a6 100644 --- a/app/_hub/kong-inc/ldap-auth-advanced/_index.md +++ b/app/_hub/kong-inc/ldap-auth-advanced/_index.md @@ -1,7 +1,6 @@ --- name: LDAP Authentication Advanced publisher: Kong Inc. -version: 2.8.x desc: 'Secure Kong clusters, Routes, and Services with username and password protection' description: | Add LDAP Bind Authentication with username and password protection. The plugin @@ -21,11 +20,9 @@ categories: - authentication kong_version_compatibility: community_edition: - compatible: null + compatible: true enterprise_edition: - compatible: - - 2.8.x - - 2.7.x + compatible: true params: name: ldap-auth-advanced service_id: true @@ -64,8 +61,8 @@ params: The password to the LDAP server. This field is _referenceable_, which means it can be securely stored as a - [secret](/gateway/latest/plan-and-deploy/security/secrets-management/getting-started) - in a vault. References must follow a [specific format](/gateway/latest/plan-and-deploy/security/secrets-management/reference-format). + [secret](/gateway/latest/kong-enterprise/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/secrets-management/reference-format). - name: start_tls required: true default: '`false`' @@ -181,8 +178,8 @@ params: should have permissions to search for the user being authenticated. This field is _referenceable_, which means it can be securely stored as a - [secret](/gateway/latest/plan-and-deploy/security/secrets-management/getting-started) - in a vault. References must follow a [specific format](/gateway/latest/plan-and-deploy/security/secrets-management/reference-format). + [secret](/gateway/latest/kong-enterprise/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/secrets-management/reference-format). - name: group_base_dn required: null default: matches `conf.base_dn` @@ -215,6 +212,16 @@ params: Displays all the LDAP search results received from the LDAP server for debugging purposes. Not recommended to be enabled in a production environment. + minimum_version: "2.3.x" + - name: groups_required + required: false + default: null + datatype: array of string elements + description: | + The groups required to be present in the LDAP search result for successful authorization. This config parameter works in both **AND** / **OR** cases. + - When `["group1 group2"]` are in the same array indices, both `group1` AND `group2` need to be present in the LDAP search result. + - When `["group1", "group2"]` are in different array indices, either `group1` OR `group2` need to be present in the LDAP search result. + minimum_version: "3.0.x" --- ## Usage @@ -239,20 +246,7 @@ You can set the header type `ldap` to any string (such as `basic`) using ### Upstream Headers -When a client has been authenticated, the plugin appends some headers to the -request before proxying it to the upstream service so that you can identify -the consumer in your code: - -* `X-Credential-Username`, the `username` of the Credential (only if the -consumer is not the 'anonymous' consumer) -* `X-Anonymous-Consumer`, will be set to `true` when authentication failed, and -the 'anonymous' consumer was set instead. -* `X-Consumer-ID`, the ID of the 'anonymous' consumer on Kong (only if -authentication failed and 'anonymous' was set) -* `X-Consumer-Custom-ID`, the `custom_id` of the 'anonymous' consumer (only if -authentication failed and 'anonymous' was set) -* `X-Consumer-Username`, the `username` of the 'anonymous' consumer (only if -authentication failed and 'anonymous' was set) +{% include_cached /md/plugins-hub/upstream-headers.md %} ### LDAP Search and `config.bind_dn` @@ -266,8 +260,11 @@ search uses `scope="sub"`, `filter="="`, and using the `ldapsearch` command line utility: ```bash -$ ldapsearch -x -h "" -D "" -b -"=" -w "" +ldapsearch -x \ + -h "" \ + -D "" \ + -b "=" \ + -w "" ``` [api-object]: /gateway/latest/admin-api/#api-object @@ -282,6 +279,8 @@ $ ldapsearch -x -h "" -D "" -b ## Notes +{% if_plugin_version lte:2.8.x %} + `config.group_base_dn` and `config.base_dn` do not accept an array and it has to fully match the full DN the group is in - it won’t work if it is specified a more generic DN, therefore it needs to be specific. For @@ -289,16 +288,22 @@ example, considering a case where there are nested `"OU's"`. If a top-level DN such as `"ou=dev,o=company"` is specified instead of `"ou=role,ou=groups,ou=dev,o=company"`, the authentication will fail. +{% endif_plugin_version %} + Referrals are not supported in the plugin. A workaround is to hit the LDAP Global Catalog instead, which is usually listening on a different port than the default `389`. That way, referrals don't get sent back to the plugin. +{% if_plugin_version lte:2.8.x %} + The plugin doesn’t authenticate users (allow/deny requests) based on group membership. For example: - If the user is a member of an LDAP group, the request is allowed. - if the user is not a member of an LDAP group, the request is still allowed. +{% endif_plugin_version %} + The plugin obtains LDAP groups and sets them in a header, `x-authenticated-groups`, to the request before proxying to the upstream. This is useful for Kong Manager role mapping. @@ -307,14 +312,25 @@ mapping. ## Changelog -### Kong Gateway 2.8.x (plugin version 1.3.0) +**{{site.base_gateway}} 3.0.x** +* Added the `groups_required` parameter. +* The deprecated `X-Credential-Username` header has been removed. +* The character `.` is now allowed in group attributes. +* The character `:` is now allowed in the password field. + +**{{site.base_gateway}} 2.8.x** * The `ldap_password` and `bind_dn` configuration fields are now marked as referenceable, which means they can be securely stored as [secrets](/gateway/latest/plan-and-deploy/security/secrets-management/getting-started) -in a vault. References must follow a [specific format](/gateway/latest/plan-and-deploy/security/secrets-management/reference-format). +in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). -### Kong Gateway 2.7.x (plugin version 1.2.0) +**{{site.base_gateway}} 2.7.x** * Starting with {{site.base_gateway}} 2.7.0.0, if keyring encryption is enabled, the `config.ldap_password` parameter value will be encrypted. + +**{{site.base_gateway}} 2.3.x** + +* Added the parameter `log_search_results`, which lets the plugin display all the LDAP search results received from the LDAP server. +* Added new debug log statements for authenticated groups. diff --git a/app/_hub/kong-inc/ldap-auth-advanced/versions.yml b/app/_hub/kong-inc/ldap-auth-advanced/versions.yml index e42d76399cc2..9dabfa61559e 100644 --- a/app/_hub/kong-inc/ldap-auth-advanced/versions.yml +++ b/app/_hub/kong-inc/ldap-auth-advanced/versions.yml @@ -1,9 +1,12 @@ -- release: 2.8.x -- release: 2.7.x -- release: 2.3.x -- release: 2.2.x -- release: 1.3.x -- release: 0.36-x -- release: 0.35-x -- release: 0.34-x -- release: 0.33-x +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 1.3.0 + 2.7.x: 1.2.0 + 2.6.x: 1.1.0 + 2.5.x: 1.1.0 + 2.4.x: 1.1.0 + 2.3.x: 1.1.0 + 2.2.x: 1.0.4 + 2.1.x: 1.0.3 diff --git a/app/_hub/kong-inc/ldap-auth/0.1-x.md b/app/_hub/kong-inc/ldap-auth/0.1-x.md deleted file mode 100644 index ceed3396de59..000000000000 --- a/app/_hub/kong-inc/ldap-auth/0.1-x.md +++ /dev/null @@ -1,132 +0,0 @@ ---- -name: LDAP Authentication -publisher: Kong Inc. -version: 0.1-x - -desc: Integrate Kong with a LDAP server -description: | - Add LDAP Bind Authentication to a Route (or the deprecated API entity) with username and password protection. The plugin will check for valid credentials in the `Proxy-Authorization` and `Authorization` header (in this order). - -
- Note: The functionality of this plugin as bundled - with versions of Kong Gateway (OSS) prior to 0.14.1 and Kong Gateway prior to 0.34 - differs from what is documented herein. Refer to the - CHANGELOG - for details. -
- -type: plugin -categories: - - authentication - -kong_version_compatibility: - community_edition: - compatible: - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - enterprise_edition: - compatible: - - 0.34-x - - 0.33-x - - 0.32-x - - 0.31-x - -params: - name: ldap-auth - api_id: true - service_id: false - route_id: true - consumer_id: false - config: - - name: hide_credentials - required: false - default: "`false`" - value_in_examples: true - description: An optional boolean value telling the plugin to hide the credential to the upstream server. It will be removed by Kong before proxying the request. - - name: ldap_host - required: true - default: - value_in_examples: ldap.example.com - description: Host on which the LDAP server is running. - - name: ldap_port - required: true - default: - value_in_examples: 389 - description: TCP port where the LDAP server is listening. - - name: start_tls - required: true - default: "`false`" - description: | - Set it to `true` to issue StartTLS (Transport Layer Security) extended operation over `ldap` connection. - - name: base_dn - required: true - default: - value_in_examples: dc=example,dc=com - description: Base DN as the starting point for the search. - - name: verify_ldap_host - required: true - default: "`false`" - description: | - Set it to `true` to authenticate LDAP server. The server certificate will be verified according to the CA certificates specified by the `lua_ssl_trusted_certificate` directive. - - name: attribute - required: true - default: - value_in_examples: cn - description: Attribute to be used to search the user. - - name: cache_ttl - required: true - default: "`60`" - description: Cache expiry time in seconds. - - name: timeout - required: false - default: "`10000`" - description: An optional timeout in milliseconds when waiting for connection with LDAP server. - - name: keepalive - required: false - default: "`60000`" - description: An optional value in milliseconds that defines for how long an idle connection to LDAP server will live before being closed. - - name: anonymous - required: false - default: - description: | - An optional string (consumer uuid) value to use as an "anonymous" consumer if authentication fails. If empty (default), the request will fail with an authentication failure `4xx`. Please note that this value must refer to the Consumer `id` attribute which is internal to Kong, and **not** its `custom_id`. - - name: header_type - required: false - default: "`ldap`" - value_in_examples: ldap - description: | - An optional string to use as part of the Authorization header. By default, a valid Authorization header looks like this: `Authorization: ldap base64(username:password)`. If `header_type` is set to "basic" then the Authorization header would be `Authorization: basic base64(username:password)`. Note that `header_type` can take any string, not just `"ldap"` and `"basic"`. - extra: -
- Note: The config.header_type option was introduced in Kong 0.12.0. Previous versions of this plugin behave as if ldap was set for this value. -
- ---- - -## Usage - -In order to authenticate the user, client must set credentials in `Proxy-Authorization` or `Authorization` header in following format - - credentials := [ldap | LDAP] base64(username:password) - -The plugin will validate the user against the LDAP server and cache the credential for future requests for the duration specified in `config.cache_ttl`. - -### Upstream Headers - -When a client has been authenticated, the plugin will append some headers to the request before proxying it to the upstream service, so that you can identify the consumer in your code: - -* `X-Credential-Username`, the `username` of the Credential (only if the consumer is not the 'anonymous' consumer) -* `X-Anonymous-Consumer`, will be set to `true` when authentication failed, and the 'anonymous' consumer was set instead. -* `X-Consumer-ID`, the ID of the 'anonymous' consumer on Kong (only if authentication failed and 'anonymous' was set) -* `X-Consumer-Custom-ID`, the `custom_id` of the 'anonymous' consumer (only if authentication failed and 'anonymous' was set) -* `X-Consumer-Username`, the `username` of the 'anonymous' consumer (only if authentication failed and 'anonymous' was set) - -[api-object]: /gateway/latest/admin-api/#api-object -[configuration]: /gateway/latest/reference/configuration -[consumer-object]: /gateway/latest/admin-api/#consumer-object - diff --git a/app/_hub/kong-inc/ldap-auth/2.1-x.md b/app/_hub/kong-inc/ldap-auth/2.1-x.md deleted file mode 100644 index be2a9d163fb6..000000000000 --- a/app/_hub/kong-inc/ldap-auth/2.1-x.md +++ /dev/null @@ -1,148 +0,0 @@ ---- -name: LDAP Authentication -publisher: Kong Inc. -version: 1.0.0 - -desc: Integrate Kong with a LDAP server -description: | - Add LDAP Bind Authentication to a Route with username and password protection. The plugin will check for valid credentials in the `Proxy-Authorization` and `Authorization` header (in this order). - -
- Note: The functionality of this plugin as bundled - with versions of Kong Gateway (OSS) prior to 0.14.1 and Kong Gateway prior to 0.34 - differs from what is documented herein. Refer to the - CHANGELOG - for details. -
- -type: plugin -categories: - - authentication - -kong_version_compatibility: - community_edition: - compatible: - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - enterprise_edition: - compatible: - - 1.5.x - - 1.3-x - - 0.36-x - - 0.35-x - - 0.34-x - - 0.33-x - - 0.32-x - - 0.31-x - -params: - name: ldap-auth - service_id: false - route_id: true - consumer_id: false - protocols: ["http", "https"] - dbless_compatible: yes - config: - - name: hide_credentials - required: false - default: "`false`" - value_in_examples: true - description: An optional boolean value telling the plugin to hide the credential to the upstream server. It will be removed by Kong before proxying the request. - - name: ldap_host - required: true - default: - value_in_examples: ldap.example.com - description: Host on which the LDAP server is running. - - name: ldap_port - required: true - default: - value_in_examples: 389 - description: TCP port where the LDAP server is listening. - - name: start_tls - required: true - default: "`false`" - description: | - Set it to `true` to issue StartTLS (Transport Layer Security) extended operation over `ldap` connection. - - name: ldaps - required: true - default: "`false`" - description: | - Set it to `true` to connect using the LDAPS protocol (LDAP over TLS) - - name: base_dn - required: true - default: - value_in_examples: dc=example,dc=com - description: Base DN as the starting point for the search. - - name: verify_ldap_host - required: true - default: "`false`" - description: | - Set it to `true` to authenticate LDAP server. The server certificate will be verified according to the CA certificates specified by the `lua_ssl_trusted_certificate` directive. - - name: attribute - required: true - default: - value_in_examples: cn - description: Attribute to be used to search the user. - - name: cache_ttl - required: true - default: "`60`" - description: Cache expiry time in seconds. - - name: timeout - required: false - default: "`10000`" - description: An optional timeout in milliseconds when waiting for connection with LDAP server. - - name: keepalive - required: false - default: "`60000`" - description: An optional value in milliseconds that defines for how long an idle connection to LDAP server will live before being closed. - - name: anonymous - required: false - default: - description: | - An optional string (consumer uuid) value to use as an "anonymous" consumer if authentication fails. If empty (default), the request will fail with an authentication failure `4xx`. Please note that this value must refer to the Consumer `id` attribute which is internal to Kong, and **not** its `custom_id`. - - name: header_type - required: false - default: "`ldap`" - value_in_examples: ldap - description: | - An optional string to use as part of the Authorization header. By default, a valid Authorization header looks like this: `Authorization: ldap base64(username:password)`. If `header_type` is set to "basic" then the Authorization header would be `Authorization: basic base64(username:password)`. Note that `header_type` can take any string, not just `"ldap"` and `"basic"`. - extra: -
- Note: The config.header_type option was introduced in Kong 0.12.0. Previous versions of this plugin behave as if ldap was set for this value. -
- ---- - -## Usage - -In order to authenticate the user, client must set credentials in `Proxy-Authorization` or `Authorization` header in following format - - credentials := [ldap | LDAP] base64(username:password) - -The plugin will validate the user against the LDAP server and cache the credential for future requests for the duration specified in `config.cache_ttl`. - -### Upstream Headers - -When a client has been authenticated, the plugin will append some headers to the request before proxying it to the upstream service, so that you can identify the consumer in your code: - -* `X-Credential-Username`, the `username` of the Credential (only if the consumer is not the 'anonymous' consumer) -* `X-Anonymous-Consumer`, will be set to `true` when authentication failed, and the 'anonymous' consumer was set instead. -* `X-Consumer-ID`, the ID of the 'anonymous' consumer on Kong (only if authentication failed and 'anonymous' was set) -* `X-Consumer-Custom-ID`, the `custom_id` of the 'anonymous' consumer (only if authentication failed and 'anonymous' was set) -* `X-Consumer-Username`, the `username` of the 'anonymous' consumer (only if authentication failed and 'anonymous' was set) - -[configuration]: /gateway/latest/reference/configuration -[consumer-object]: /gateway/latest/admin-api/#consumer-object - diff --git a/app/_hub/kong-inc/ldap-auth/_index.md b/app/_hub/kong-inc/ldap-auth/_index.md index b5e34c94f22c..ec21d5cec58e 100644 --- a/app/_hub/kong-inc/ldap-auth/_index.md +++ b/app/_hub/kong-inc/ldap-auth/_index.md @@ -79,6 +79,7 @@ params: datatype: string description: Host on which the LDAP server is running. - name: ldap_port + minimum_version: "2.5.x" required: true default: 389 value_in_examples: 389 @@ -175,19 +176,8 @@ You can set the header type `ldap` to any string (such as `basic`) using ### Upstream Headers -When a client has been authenticated, the plugin appends some headers to the -request before proxying it to the upstream service so that you can identify -the consumer in your code: +{% include_cached /md/plugins-hub/upstream-headers.md %} -* `X-Anonymous-Consumer`, will be set to `true` when authentication failed, and the 'anonymous' consumer was set instead. -* `X-Consumer-ID`, the ID of the 'anonymous' consumer on Kong (only if authentication failed and 'anonymous' was set) -* `X-Consumer-Custom-ID`, the `custom_id` of the 'anonymous' consumer (only if authentication failed and 'anonymous' was set) -* `X-Consumer-Username`, the `username` of the 'anonymous' consumer (only if authentication failed and 'anonymous' was set) -* `X-Credential-Identifier`, the identifier of the Credential (only if the consumer is not the 'anonymous' consumer) - -
- Note:`X-Credential-Username` was deprecated in favor of `X-Credential-Identifier` in Kong 2.1. -
[configuration]: /gateway/latest/reference/configuration [consumer-object]: /gateway/latest/admin-api/#consumer-object @@ -197,3 +187,13 @@ the consumer in your code: ### Using Service Directory Mapping on the CLI {% include /md/2.1.x/ldap/ldap-service-directory-mapping.md %} + +--- +## Changelog + +**{{site.base_gateway}} 3.0.x** +* The deprecated `X-Credential-Username` header has been removed. + +**{{site.base_gateway}} 2.5.x** +* Added support for setting the `ldap_port`. +Previously, this parameter was documented but did not exist in the plugin. diff --git a/app/_hub/kong-inc/ldap-auth/versions.yml b/app/_hub/kong-inc/ldap-auth/versions.yml index 14405d124ae7..66a1be48947c 100644 --- a/app/_hub/kong-inc/ldap-auth/versions.yml +++ b/app/_hub/kong-inc/ldap-auth/versions.yml @@ -1,3 +1,12 @@ -- release: 2.2-x -- release: 2.1-x -- release: 0.1-x +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 2.2.0 + 2.7.x: 2.2.0 + 2.6.x: 2.2.0 + 2.5.x: 2.2.0 + 2.4.x: 2.2.0 + 2.3.x: 2.2.0 + 2.2.x: 2.2.0 + 2.1.x: 2.2.0 diff --git a/app/_hub/kong-inc/loggly/0.1-x.md b/app/_hub/kong-inc/loggly/0.1-x.md deleted file mode 100644 index 9b9730f044d1..000000000000 --- a/app/_hub/kong-inc/loggly/0.1-x.md +++ /dev/null @@ -1,203 +0,0 @@ ---- -name: Loggly -publisher: Kong Inc. -version: 0.1-x - -desc: Send request and response logs to Loggly -description: | - Log request and response data over UDP to [Loggly](https://www.loggly.com). - -type: plugin -categories: - - logging - -kong_version_compatibility: - community_edition: - compatible: - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - enterprise_edition: - compatible: - - 0.34-x - - 0.33-x - - 0.32-x - - 0.31-x - -params: - name: loggly - api_id: true - service_id: true - route_id: true - consumer_id: true - config: - - name: host - required: false - default: "`logs-01.loggly.com`" - description: The IP address or host name of Loggly server - - name: port - required: false - default: "`514`" - description: The UDP port to send data to on the Loggly server - - name: key - required: true - default: - value_in_examples: YOUR_LOGGLY_SERVICE_TOKEN - description: | - Loggly [customer token](https://www.loggly.com/docs/customer-token-authentication-token/). - - name: tags - required: false - default: "`kong`" - description: | - An optional list of [tags](https://www.loggly.com/docs/tags/) to support segmentation & filtering of logs. - - name: timeout - required: false - default: "`10000`" - description: An optional timeout in milliseconds when sending data to the Loggly server - - name: successful_severity - required: false - default: "`info`" - description: | - An optional logging severity assigned to the all successful requests with response status code 400 . - - name: client_errors_severity - required: false - default: "`info`" - description: | - An optional logging severity assigned to the all failed requests with response status code 400 or higher but less than 500. - - name: server_errors_severity - required: false - default: "`info`" - description: | - An optional logging severity assigned to the all failed requests with response status code 500 or higher. - - name: log_level - required: false - default: "`info`" - description: | - An optional logging severity, any request with equal or higher severity will be logged to Loggly. - ---- - -## Log Format - -Every request will be transmitted to Loggly in [SYSLOG](https://en.wikipedia.org/wiki/Syslog) standard, with `message` component in the following format: - -```json -{ - "request": { - "method": "GET", - "uri": "/get", - "url": "http://httpbin.org:8000/get", - "size": "75", - "querystring": {}, - "headers": { - "accept": "*/*", - "host": "httpbin.org", - "user-agent": "curl/7.37.1" - } - }, - "upstream_uri": "/", - "response": { - "status": 200, - "size": "434", - "headers": { - "Content-Length": "197", - "via": "kong/0.3.0", - "Connection": "close", - "access-control-allow-credentials": "true", - "Content-Type": "application/json", - "server": "nginx", - "access-control-allow-origin": "*" - } - }, - "tries": [ - { - "state": "next", - "code": 502, - "ip": "127.0.0.1", - "port": 8000 - }, - { - "ip": "127.0.0.1", - "port": 8000 - } - ], - "authenticated_entity": { - "consumer_id": "80f74eef-31b8-45d5-c525-ae532297ea8e", - "id": "eaa330c0-4cff-47f5-c79e-b2e4f355207e" - }, - "route": { - "created_at": 1521555129, - "hosts": null, - "id": "75818c5f-202d-4b82-a553-6a46e7c9a19e", - "methods": null, - "paths": [ - "/example-path" - ], - "preserve_host": false, - "protocols": [ - "http", - "https" - ], - "regex_priority": 0, - "service": { - "id": "0590139e-7481-466c-bcdf-929adcaaf804" - }, - "strip_path": true, - "updated_at": 1521555129 - }, - "service": { - "connect_timeout": 60000, - "created_at": 1521554518, - "host": "example.com", - "id": "0590139e-7481-466c-bcdf-929adcaaf804", - "name": "myservice", - "path": "/", - "port": 80, - "protocol": "http", - "read_timeout": 60000, - "retries": 5, - "updated_at": 1521554518, - "write_timeout": 60000 - }, - "consumer": { - "username": "demo", - "created_at": 1491847011000, - "id": "35b03bfc-7a5b-4a23-a594-aa350c585fa8" - }, - "latencies": { - "proxy": 1430, - "kong": 9, - "request": 1921 - }, - "client_ip": "127.0.0.1", - "started_at": 1433209822425 -} -``` - -A few considerations on the above JSON object: - -* `request` contains properties about the request sent by the client -* `response` contains properties about the response sent to the client -* `tries` contains the list of (re)tries (successes and failures) made by the load balancer for this request -* `route` contains Kong properties about the specific Route requested -* `service` contains Kong properties about the Service associated with the requested Route -* `authenticated_entity` contains Kong properties about the authenticated credential (if an authentication plugin has been enabled) -* `consumer` contains the authenticated Consumer (if an authentication plugin has been enabled) -* `latencies` contains some data about the latencies involved: - * `proxy` is the time it took for the final service to process the request - * `kong` is the internal Kong latency that it took to run all the plugins - * `request` is the time elapsed between the first bytes were read from the client and after the last bytes were sent to the client. Useful for detecting slow clients. -* `client_ip` contains the original client IP address -* `started_at` contains the UTC timestamp of when the API transaction has started to be processed. - ----- - -## Kong Process Errors - -This logging plugin will only log HTTP request and response data. If you are looking for the Kong process error file (which is the nginx error file), then you can find it at the following path: {[prefix](/gateway/latest/reference/configuration/#prefix)}/logs/error.log diff --git a/app/_hub/kong-inc/loggly/1.0.x.md b/app/_hub/kong-inc/loggly/1.0.x.md deleted file mode 100644 index 311e5d28f901..000000000000 --- a/app/_hub/kong-inc/loggly/1.0.x.md +++ /dev/null @@ -1,240 +0,0 @@ ---- -name: Loggly -publisher: Kong Inc. -version: 1.0.x - -desc: Send request and response logs to Loggly -description: | - Log request and response data over UDP to [Loggly](https://www.loggly.com). - -type: plugin -categories: - - logging - -kong_version_compatibility: - community_edition: - compatible: - - 2.3.x - - 2.2.x - - 2.1.x - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - enterprise_edition: - compatible: - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x - -params: - name: loggly - service_id: true - route_id: true - consumer_id: true - protocols: ["http", "https", "grpc", "grpcs", "tcp", "tls", "udp"] - dbless_compatible: yes - config: - - name: host - required: false - default: "`logs-01.loggly.com`" - datatype: string - description: The IP address or hostname of Loggly server. - - name: port - required: false - default: "`514`" - datatype: integer - description: The UDP port to send data to on the Loggly server. - - name: key - required: true - default: - value_in_examples: YOUR_LOGGLY_SERVICE_TOKEN - datatype: string - description: | - Loggly [customer token](https://www.loggly.com/docs/customer-token-authentication-token/). - - name: tags - required: false - default: "`kong`" - datatype: set of string elements - description: | - An optional list of [tags](https://www.loggly.com/docs/tags/) to support segmentation and filtering of logs. - - name: timeout - required: false - default: "`10000`" - datatype: number - description: An optional timeout in milliseconds when sending data to the Loggly server. - - name: successful_severity - required: false - default: "`info`" - datatype: string - description: | - An optional logging severity assigned to all the successful requests with a response - status code 400. Available options: `debug`, `info`, `notice`, `warning`, `err`, - `crit`, `alert`, `emerg`. - - name: client_errors_severity - required: false - default: "`info`" - datatype: string - description: | - An optional logging severity assigned to all the failed requests with a response - status code 400 or higher but less than 500. Available options: `debug`, `info`, - `notice`, `warning`, `err`, `crit`, `alert`, `emerg`. - - name: server_errors_severity - required: false - default: "`info`" - datatype: string - description: | - An optional logging severity assigned to all the failed requests with response status - code 500 or higher. Available options: `debug`, `info`, `notice`, `warning`, `err`, - `crit`, `alert`, `emerg`. - - name: log_level - required: false - default: "`info`" - datatype: string - description: | - An optional logging severity, any request with equal or higher severity will be - logged to Loggly. Available options: `debug`, `info`, `notice`, `warning`, `err`, - `crit`, `alert`, `emerg`. - ---- - -## Log Format - -Every request will be transmitted to Loggly in [SYSLOG](https://en.wikipedia.org/wiki/Syslog) standard, with `message` component in the following format: - -```json -{ - "request": { - "method": "GET", - "uri": "/get", - "url": "http://httpbin.org:8000/get", - "size": "75", - "querystring": {}, - "headers": { - "accept": "*/*", - "host": "httpbin.org", - "user-agent": "curl/7.37.1" - } - }, - "upstream_uri": "/", - "response": { - "status": 200, - "size": "434", - "headers": { - "Content-Length": "197", - "via": "kong/0.3.0", - "Connection": "close", - "access-control-allow-credentials": "true", - "Content-Type": "application/json", - "server": "nginx", - "access-control-allow-origin": "*" - } - }, - "tries": [ - { - "state": "next", - "code": 502, - "ip": "127.0.0.1", - "port": 8000 - }, - { - "ip": "127.0.0.1", - "port": 8000 - } - ], - "authenticated_entity": { - "consumer_id": "80f74eef-31b8-45d5-c525-ae532297ea8e", - "id": "eaa330c0-4cff-47f5-c79e-b2e4f355207e" - }, - "route": { - "created_at": 1521555129, - "hosts": null, - "id": "75818c5f-202d-4b82-a553-6a46e7c9a19e", - "methods": null, - "paths": [ - "/example-path" - ], - "preserve_host": false, - "protocols": [ - "http", - "https" - ], - "regex_priority": 0, - "service": { - "id": "0590139e-7481-466c-bcdf-929adcaaf804" - }, - "strip_path": true, - "updated_at": 1521555129 - }, - "service": { - "connect_timeout": 60000, - "created_at": 1521554518, - "host": "example.com", - "id": "0590139e-7481-466c-bcdf-929adcaaf804", - "name": "myservice", - "path": "/", - "port": 80, - "protocol": "http", - "read_timeout": 60000, - "retries": 5, - "updated_at": 1521554518, - "write_timeout": 60000 - }, - "workspaces": [ - { - "id":"b7cac81a-05dc-41f5-b6dc-b87e29b6c3a3", - "name": "default" - } - ], - "consumer": { - "username": "demo", - "created_at": 1491847011000, - "id": "35b03bfc-7a5b-4a23-a594-aa350c585fa8" - }, - "latencies": { - "proxy": 1430, - "kong": 9, - "request": 1921 - }, - "client_ip": "127.0.0.1", - "started_at": 1433209822425 -} -``` - -A few considerations on the above JSON object: - -* `request` contains properties about the request sent by the client -* `response` contains properties about the response sent to the client -* `tries` contains the list of (re)tries (successes and failures) made by the load balancer for this request -* `route` contains Kong properties about the specific Route requested -* `service` contains Kong properties about the Service associated with the requested Route -* `authenticated_entity` contains Kong properties about the authenticated credential (if an authentication plugin has been enabled) -* `workspaces` contains Kong properties of the Workspaces associated with the requested Route. **Only in Kong Gateway version >= 0.34**. -* `consumer` contains the authenticated Consumer (if an authentication plugin has been enabled) -* `latencies` contains some data about the latencies involved: - * `proxy` is the time it took for the final service to process the request - * `kong` is the internal Kong latency that it took to run all the plugins - * `request` is the time elapsed between the first bytes were read from the client and after the last bytes were sent to the client. Useful for detecting slow clients. -* `client_ip` contains the original client IP address -* `started_at` contains the UTC timestamp of when the API transaction has started to be processed. - ----- - -## Kong Process Errors - -{% include /md/plugins-hub/kong-process-errors.md %} diff --git a/app/_hub/kong-inc/loggly/2.0.x.md b/app/_hub/kong-inc/loggly/2.0.x.md deleted file mode 100644 index 4a8377b06530..000000000000 --- a/app/_hub/kong-inc/loggly/2.0.x.md +++ /dev/null @@ -1,133 +0,0 @@ ---- -name: Loggly -publisher: Kong Inc. -version: 2.0.x -# internal handler version 2.0.1 - -desc: Send request and response logs to Loggly -description: | - Log request and response data over UDP to [Loggly](https://www.loggly.com). - -type: plugin -categories: - - logging - -kong_version_compatibility: - community_edition: - compatible: - - 2.3.x - - 2.2.x - - 2.1.x - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - enterprise_edition: - compatible: - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x - -params: - name: loggly - service_id: true - route_id: true - consumer_id: true - protocols: ["http", "https", "grpc", "grpcs", "tcp", "tls", "udp"] - dbless_compatible: yes - config: - - name: host - required: false - default: "`logs-01.loggly.com`" - datatype: string - description: The IP address or hostname of Loggly server. - - name: port - required: false - default: "`514`" - datatype: integer - description: The UDP port to send data to on the Loggly server. - - name: key - required: true - default: - value_in_examples: YOUR_LOGGLY_SERVICE_TOKEN - datatype: string - description: | - Loggly [customer token](https://www.loggly.com/docs/customer-token-authentication-token/). - - name: tags - required: false - default: "`kong`" - datatype: set of string elements - description: | - An optional list of [tags](https://www.loggly.com/docs/tags/) to support segmentation and filtering of logs. - - name: timeout - required: false - default: "`10000`" - datatype: number - description: An optional timeout in milliseconds when sending data to the Loggly server. - - name: successful_severity - required: false - default: "`info`" - datatype: string - description: | - An optional logging severity assigned to all the successful requests with a response - status code 400. Available options: `debug`, `info`, `notice`, `warning`, `err`, - `crit`, `alert`, `emerg`. - - name: client_errors_severity - required: false - default: "`info`" - datatype: string - description: | - An optional logging severity assigned to all the failed requests with a response - status code 400 or higher but less than 500. Available options: `debug`, `info`, - `notice`, `warning`, `err`, `crit`, `alert`, `emerg`. - - name: server_errors_severity - required: false - default: "`info`" - datatype: string - description: | - An optional logging severity assigned to all the failed requests with response status - code 500 or higher. Available options: `debug`, `info`, `notice`, `warning`, `err`, - `crit`, `alert`, `emerg`. - - name: log_level - required: false - default: "`info`" - datatype: string - description: | - An optional logging severity, any request with equal or higher severity will be - logged to Loggly. Available options: `debug`, `info`, `notice`, `warning`, `err`, - `crit`, `alert`, `emerg`. - ---- - -## Log format - -Every request is logged to the System log in [SYSLOG](https://en.wikipedia.org/wiki/Syslog) standard, with the -with `message` component formatted as described below. - -**Note:** Make sure the Syslog daemon is running on the instance and it's configured with the -logging level severity the same as or lower than the set `config.log_level` for this plugin. - -{% include /md/plugins-hub/log-format.md %} - -### JSON object considerations - -{% include /md/plugins-hub/json-object-log.md %} - -## Kong process errors - -{% include /md/plugins-hub/kong-process-errors.md %} diff --git a/app/_hub/kong-inc/loggly/_index.md b/app/_hub/kong-inc/loggly/_index.md index ce04339252eb..611d4704f2b6 100644 --- a/app/_hub/kong-inc/loggly/_index.md +++ b/app/_hub/kong-inc/loggly/_index.md @@ -1,7 +1,6 @@ --- name: Loggly publisher: Kong Inc. -version: 2.1.x desc: Send request and response logs to Loggly description: | Log request and response data over UDP to [Loggly](https://www.loggly.com). @@ -10,19 +9,9 @@ categories: - logging kong_version_compatibility: community_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x + compatible: true enterprise_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x + compatible: true params: name: loggly service_id: true @@ -57,6 +46,10 @@ params: encrypted: true description: | Loggly [customer token](https://www.loggly.com/docs/customer-token-authentication-token/). + + This field is _referenceable_, which means it can be securely stored as a + [secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). - name: tags required: false default: '`kong`' @@ -128,15 +121,20 @@ logging level severity the same as or lower than the set `config.log_level` for {% include /md/plugins-hub/kong-process-errors.md %} +{% if_plugin_version gte:2.4.x %} ## Custom Fields by Lua {% include /md/plugins-hub/log_custom_fields_by_lua.md %} +{% endif_plugin_version %} --- - ## Changelog -### 2.1.0 +**{{site.base_gateway}} 2.7.x** * Starting with {{site.base_gateway}} 2.7.0.0, if keyring encryption is enabled, the `key` parameter value will be encrypted. + +**{{site.base_gateway}} 2.4.x** + +* Added `custom_fields_by_lua` configuration option. diff --git a/app/_hub/kong-inc/loggly/versions.yml b/app/_hub/kong-inc/loggly/versions.yml index 28b8d91826b3..6e6ff02e27da 100644 --- a/app/_hub/kong-inc/loggly/versions.yml +++ b/app/_hub/kong-inc/loggly/versions.yml @@ -1,4 +1,12 @@ -- release: 2.1.x -- release: 2.0.x -- release: 1.0.x -- release: 0.1-x +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 2.1.0 + 2.7.x: 2.1.0 + 2.6.x: 2.1.0 + 2.5.x: 2.1.0 + 2.4.x: 2.0.1 + 2.3.x: 2.0.1 + 2.2.x: 2.0.1 + 2.1.x: 2.0.1 diff --git a/app/_hub/kong-inc/mocking/0.1.x.md b/app/_hub/kong-inc/mocking/0.1.x.md deleted file mode 100644 index 165e0408fe94..000000000000 --- a/app/_hub/kong-inc/mocking/0.1.x.md +++ /dev/null @@ -1,910 +0,0 @@ ---- -name: Mocking -publisher: Kong Inc. -version: 0.1.x -# internal handler v 0.1.0 - -desc: Provide mock endpoints to test your APIs against your services -description: | - Provide mock endpoints to test your APIs in development against your services. - The Mocking plugin leverages standards based on the Open API Specification (OAS) - for sending out mock responses to APIs. - - Benefits of service mocking with the Kong Mocking plugin: - - - Conforms to a design-first approach since mock responses are within OAS. - - Accelerates development of services and APIs. - - Promotes parallel development of APIs across distributed teams. - - Provides an enhanced full lifecycle API development experience with Dev Portal - integration. - - Easily enable and disable the Mocking plugin for flexibility when - testing API behavior. - - This plugin can mock `200`, `201`, and `204` responses. - - {:.note} - > To use this plugin in Konnect Cloud, - [upgrade your runtimes](/konnect/runtime-manager/upgrade) to at least - v2.4.1.1. - -enterprise: true -plus: true -type: - plugin -categories: - - traffic-control - -kong_version_compatibility: - enterprise_edition: - compatible: - - 2.4.x -params: - name: mocking - service_id: true - consumer_id: true - route_id: true - protocols: ["http", "https"] - dbless_compatible: yes - dbless_explanation: | - Use the `api_specification` config for DB-less or hybrid mode. Attach the spec contents directly - instead of uploading to the Dev Portal. The API spec is configured directly in the plugin. - examples: false - - config: - - name: api_specification_filename - required: semi - default: - datatype: string - value_in_examples: - description: | - The path and name of the specification file loaded into Kong Gateway's database. You cannot - use this option for DB-less or hybrid mode. - - name: api_specification - required: semi - default: - datatype: string - value_in_examples: - description: | - The contents of the specification file. You must use this option for hybrid or DB-less mode. - With this configuration option, you can include the full specification as part of the configuration, - instead of referring to a separate file with `api_specification_filename` that lives next to the Kong Gateway (Enterprise). - In Kong Manager, you can copy and paste the contents of the spec directly into - the `Config.Api Specification` text field. - - name: random_delay - required: false - default: false - datatype: boolean - value_in_examples: true - description: | - Enables a random delay in the mocked response. Introduces delays to simulate - real-time response times by APIs. - - name: max_delay_time - required: semi - default: 1 - datatype: number - value_in_examples: 1 - description: | - The maximum value in seconds of delay time. Set this value when `random_delay` is enabled - and you want to adjust the default. The value must be greater than the - `min_delay_time`. - - name: min_delay_time - required: semi - default: 0.001 - datatype: number - value_in_examples: 0.001 - description: | - The minimum value in seconds of delay time. Set this value when `random_delay` is enabled - and you want to adjust the default. The value must be less than the - `max_delay_time`. - - extra: | - - Depending on the Kong Gateway deployment mode, set either the `api_specification_filename` - or the `api_specification` parameter. The plugin requires a spec to work. ---- - -## Configuration - -### Enable the plugin on a service - -Configure this plugin on a [service](/enterprise/latest/admin-api/#service-object): - -```bash -curl -X POST http://:8001/services//plugins \ - --data "name=mocking" \ - --data "config.api_specification_filename=multipleexamples.json" \ - --data "config.random_delay=true" \ - --data "config.max_delay_time=1" \ - --data "config.min_delay_time=0.01" -``` - -The `` is the id or name of the service that this plugin configuration will target. - -### Enable the plugin on a route - -Configure this plugin on a [route](/enterprise/latest/admin-api/#route-object): - -```bash -$ curl -X POST http://:8001/routes//plugins \ - --data "name=mocking" \ - --data "config.api_specification_filename=multipleexamples.json" \ - --data "config.random_delay=true" \ - --data "config.max_delay_time=1" \ - --data "config.min_delay_time=0.01" - ``` - -The `` is the id or name of the route that this plugin configuration will target. - -### Enable the plugin on a consumer - -Configure this plugin on a [consumer](/enterprise/latest/admin-api/#consumer-object): - -```bash -curl -X POST http://:8001/consumers//plugins \ - --data "name=mocking" \ - --data "config.api_specification_filename=multipleexamples.json" \ - --data "config.random_delay=true" \ - --data "config.max_delay_time=1" \ - --data "config.min_delay_time=0.001" -``` - -The `` is the id or username of the consumer that this plugin configuration will target. - -You can combine `consumer.id`, `service.id`, or `route.id` within the same request to further narrow the scope of the plugin. - -### Enable the plugin globally - -A plugin that is not associated to any service, route, or consumer is considered global, and -will run on every request. Read the [Plugin Reference](/gateway-oss/latest/admin-api/#add-plugin) and the -[Plugin Precedence](/gateway-oss/latest/admin-api/#precedence) sections for more information. - -Configure this plugin globally: - -```bash -curl -X POST http://:8001/plugins/ \ - --data "name=mocking" \ - --data "config.api_specification_filename=multipleexamples.json" \ - --data "config.random_delay=true" \ - --data "config.max_delay_time=1" \ - --data "config.min_delay_time=0.001" -``` - -## Tutorial Example - -This example tutorial steps you through testing a mock response for -a stock quote service API. - -{:.note} -> **Note:** Before following the steps in this -tutorial, you can view a video demonstration of the Mocking plugin -used in conjunction with the Dev Portal. See the -[Service Mocking video demo](https://www.youtube.com/watch?v=l8uKbgkK6_I) -available on YouTube. - -Prerequisites: - -- {{site.ee_product_name}} environment with the Dev Portal enabled on at least one workspace. See - [enable the Dev Portal](/enterprise/latest/developer-portal/enable-dev-portal/) using `kong.conf`. Also refer to - the instructions for your environment: - - [Docker](/enterprise/latest/deployment/installation/docker/#step-7-optional-enable-the-dev-portal) - - [Ubuntu](/enterprise/latest/deployment/installation/ubuntu/#optional-enable-the-dev-portal) - - [CentOS](/enterprise/latest/deployment/installation/centos/#optional-enable-the-dev-portal) - - [Amazon Linux 1](/enterprise/latest/deployment/installation/amazon-linux/#optional-enable-the-dev-portal) - - [Amazon Linux 2](/enterprise/latest/deployment/installation/amazon-linux-2/#optional-enable-the-dev-portal) - - [RHEL](/enterprise/latest/deployment/installation/rhel/#optional-enable-the-dev-portal) - -- An Open API Specification (`yaml` or `json`) that has at least one API method with an - embedded example response. Multiple examples within a spec are supported. See the - [Stock API spec example](#stock-spec). - - {:.note} - > **Note:** The spec must contain `200`, `201`, or `204` responses. The - Mocking plugin doesn't support any other response status codes. - -Tutorial steps: - -1. Deploy the example OAS spec that contains mocked responses to the [Dev Portal](#deploy-spec-portal) or - [Insomnia](#deploy-spec-insomnia). -2. Create the [Stock service](#create-stock-service). -3. Create the [`get stock quote` route](#create-stock-quote-route). -4. Enable the [Mocking plugin](#enable-mock-plugin) on the `get stock quote` route. -5. Enable the [CORS plugin](#enable-cors-plugin) on the `get stock quote` route. -6. [Test the mocked response](#testing123) from the Dev Portal, Insomnia, or the command line. -7. When you've completed your API mock testing, [disable the Mocking plugin and update the service URL](#post-test). - -### Step 1. Deploy the Stock API example spec - -Deploy the [Stock API spec example](#stock-spec) to either the [Dev Portal](#deploy-spec-portal) or -[Insomnia](#deploy-spec-insomnia). - -#### Deploy a spec to the Dev Portal {#deploy-spec-portal} - -Follow these steps to deploy a spec to the Dev Portal using Kong Manager. You can -copy and paste the `stock-01.json` example file into the Dev Portal using Editor Mode. - -![Dev Portal Specs](/assets/images/docs/dev-portal/stock-spec-mock-example.png) - -1. Open Editor Mode and click **New File**. -2. Name the file `stock-01.json`. -3. Copy and paste the contents in the [example](#stock-spec) into the new file. - -Alternatively, you can also use the [Portal Files API](/enterprise/latest/developer-portal/files-api/#post-a-content-file) -to upload a spec to the Dev Portal. - -#### Deploy a spec to Insomnia {#deploy-spec-insomnia} - -1. From the Insomnia dashboard, click **Create** > **Import from File** and select the - `stock-0.1.json` file. - - ![Insomnia Dashboard Import File](/assets/images/docs/insomnia/insomnia-import-spec.png) - - -2. Click **Design Document**, then click OK on the success message. - -3. (Optional) Click **Deploy to Portal** to deploy the spec to the Dev Portal. - - ![Insomnia Dashboard Deploy Spec to Portal](/assets/images/docs/insomnia/insomnia-deploy-spec-dev-portal.png) - -#### Stock API spec example {#stock-spec} - -The mocked responses in the example Stock spec `stock-0.1.json` are between lines `38` to `59` for `GET stock/historical`, -and from lines `86` to `103` for `GET stock/closing`. - -If applicable to your environment, replace the `host` entry in the spec with your -IP address or URL for {{site.ee_gateway_name}}. - -```json -{"swagger": "2.0", - "info" : { - "title": "Stock API", - "description": "Stock Information Service", - "version": "0.1" - }, - "host": "127.0.0.1:8000", - "basePath": "/", - "schemes": [ - "http", - "https" - ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "paths": { - "/stock/historical": { - "get": { - "description": "", - "operationId": "GET /stock/historical", - "produces": [ - "application/json" - ], - "tags": [ - "Production" - ], - "parameters": [ - { - "required": true, - "in": "query", - "name": "tickers", - "type": "string" - } - ], - "responses": { - "200": { - "description": "Status 200", - "examples": { - "application/json": - { - "meta_data" : { - "api_name" : "historical_stock_price_v2", - "num_total_data_points" : 1, - "credit_cost" : 10, - "start_date" : "yesterday", - "end_date" : "yesterday" - }, - "result_data" : { - "AAPL" : [ { - "date" : "2000-04-23", - "volume" : 33, - "high" : 100.75, - "low" : 100.87, - "adj_close" : 275.03, - "close" : 100.03, - "open" : 100.87 - } ] - } - } - } - } - } - } - }, - "/stock/closing": { - "get": { - "description": "", - "operationId": "GET /stock/closing", - "produces": [ - "application/json" - ], - "tags": [ - "Beta" - ], - "parameters": [ - { - "required": true, - "in": "query", - "name": "tickers", - "type": "string" - } - ], - "responses": { - "200": { - "description": "Status 200", - "examples": { - "application/json": - { - "meta_data" : { - "api_name" : "closing_stock_price_v1" - }, - "result_data" : { - "AAPL" : [ { - "date" : "2000-06-23", - "volume" : 33, - "high" : 100.75, - "low" : 100.87, - "adj_close" : 275.03, - "close" : 100.03, - "open" : 100.87 - } ] - } - } - } - } - } - } - } - } -} -``` - -### Step 2. Create the stock service {#create-stock-service} - -This example creates a service named `Stock-Service`. - -Command: - -{% navtabs %} -{% navtab cURL %} - -```bash -curl -i -X POST http://:8001/services \ - --data name=Stock-Service \ - --data url='http://httpbin.org/anything' -``` - -{% endnavtab %} -{% navtab HTTPie %} - -```bash -http :8001/services name=Stock-Service url='http://httpbin.org/anything' -``` - -{% endnavtab %} -{% endnavtabs %} - -Response: - -``` -HTTP/1.1 201 Created -Access-Control-Allow-Credentials: true -Access-Control-Allow-Origin: http://localhost:8002 -Connection: keep-alive -Content-Length: 362 -Content-Type: application/json; charset=utf-8 -Date: Fri, 23 Apr 2021 14:16:42 GMT -Server: kong/2.4.0.0-beta1-enterprise-edition -X-Kong-Admin-Latency: 28 -X-Kong-Admin-Request-ID: a4WLWEHkurc5IjKSZO2fy8GPmWd6ffs0 -vary: Origin - -{ - "ca_certificates": null, - "client_certificate": null, - "connect_timeout": 60000, - "created_at": 1619187402, - "host": "httpbin", - "id": "94d95e04-bb28-4707-bef7-32307091b5dc", - "name": "Stock-Service", - "path": "/anything", - "port": 80, - "protocol": "http", - "read_timeout": 60000, - "retries": 5, - "tags": null, - "tls_verify": null, - "tls_verify_depth": null, - "updated_at": 1619187402, - "write_timeout": 60000 -} -``` - -### Step 3. Create the get stock quote route {#create-stock-quote-route} - -This example creates a route named `getStockQuote` on the service named `Stock-Service`. - -{% navtabs %} -{% navtab cURL %} - -```bash -curl -X POST http://localhost:8001/services/Stock-Service/routes \ - --data "name=getStockQuote" \ - --data paths="/stock/historical" -``` - -{% endnavtab %} -{% navtab HTTPie %} - -```bash -http -f :8001/services/Stock-Service/routes name='getStockQuote' paths="/stock/historical" -``` - -{% endnavtab %} -{% endnavtabs %} - -Response: - -``` -HTTP/1.1 201 Created -Access-Control-Allow-Credentials: true -Access-Control-Allow-Origin: http://localhost:8002 -Connection: keep-alive -Content-Length: 497 -Content-Type: application/json; charset=utf-8 -Date: Fri, 23 Apr 2021 14:26:44 GMT -Server: kong/2.4.0.0-beta1-enterprise-edition -X-Kong-Admin-Latency: 29 -X-Kong-Admin-Request-ID: UtF0twm9PoeI3gD7SqH6XDvm3JRqKm8o -vary: Origin - -{ - "created_at": 1619188004, - "destinations": null, - "headers": null, - "hosts": null, - "https_redirect_status_code": 426, - "id": "5ada3c98-c732-4c05-903f-9ba8ef026776", - "methods": null, - "name": "getStockQuote", - "path_handling": "v0", - "paths": [ - "/stock/historical" - ], - "preserve_host": false, - "protocols": [ - "http", - "https" - ], - "regex_priority": 0, - "request_buffering": true, - "response_buffering": true, - "service": { - "id": "94d95e04-bb28-4707-bef7-32307091b5dc" - }, - "snis": null, - "sources": null, - "strip_path": true, - "tags": null, - "updated_at": 1619188004 -} -``` - -### Step 4. Enable the Mocking plugin {#enable-mock-plugin} - -This example enables the Mocking plugin on the `getStockQuote` route. - -Command: - -{% navtabs %} -{% navtab cURL %} - -```bash -curl -X POST http://:8001/routes/getStockQuote/plugins \ - --data "name=mocking" \ - --data "config.api_specification_filename=stock-0.1.json" -``` - -Optional configuration for random simulated delay: - -```bash -curl -X POST http://:8001/routes/getStockQuote/plugins \ - --data "name=mocking" \ - --data "config.api_specification_filename=stock-0.1.json" \ - --data "config.random_delay=true" \ - --data "config.max_delay_time=1" \ - --data "config.min_delay_time=0.001" -``` - -DB-less or hybrid mode configuration must use `config.api_specification`: - -```bash -curl -X POST http://:8001/routes/getStockQuote/plugins \ - --data "name=mocking" \ - --data "config.api_specification=" -``` - -Because a spec can be rather lengthy to put into a command, use a local variable to post -a spec: - -```bash -mock_ex=$(cat example.yaml); \ -curl -X POST http://:8001/routes//plugins \ - --data name=mocking \ - --data config.api_specification="$mock_ex" -``` - -In Kong Manager, you can copy and paste the contents of the spec directly into -the `Config.Api Specification` text field. - -![Kong Manager Config API Spec Text Field](/assets/images/docs/dev-portal/km-config-api-spec-txt-fld.png) - -{% endnavtab %} -{% navtab HTTPie %} - -```bash -http -f :8001/routes/getStockQuote/plugins name=mocking config.api_specification_filename=stock-0.1.json -``` - -Optional configuration for random simulated delay using default maximum and minimum delays: - -```bash -http -f :8001/routes/getStockQuote/plugins name=mocking config.api_specification_filename=stock-0.1.json config.random_delay=true -``` - -Specify the path to your spec file if you are using `config.api_specification`: - -```bash -http -f localhost:8001/routes/mocking/plugins name=mocking config.api_specification=@../stock-0.1.json -``` - -{% endnavtab %} -{% endnavtabs %} - -Response (random delay not enabled): - -``` -HTTP/1.1 201 Created -Access-Control-Allow-Credentials: true -Access-Control-Allow-Origin: http://localhost:8002 -Connection: keep-alive -Content-Length: 387 -Content-Type: application/json; charset=utf-8 -Date: Fri, 23 Apr 2021 20:40:51 GMT -Server: kong/2.4.0.0-beta1-enterprise-edition -X-Kong-Admin-Latency: 1510 -X-Kong-Admin-Request-ID: iCZdp9JsqWhtmGLStICwBcOY4jT2R391 -vary: Origin - -{ - "config": { - "api_specification": null, - "api_specification_filename": "stock-0.1.json", - "max_delay_time": 1, - "min_delay_time": 0.001, - "random_delay": false - }, - "consumer": null, - "created_at": 1619210451, - "enabled": true, - "id": "0d8ed6f6-6a4f-43df-8d81-980b5d9b2c7a", - "name": "mocking", - "protocols": [ - "grpc", - "grpcs", - "http", - "https" - ], - "route": { - "id": "5ada3c98-c732-4c05-903f-9ba8ef026776" - }, - "service": null, - "tags": null -} -``` - -Response (random delay enabled): - -``` -HTTP/1.1 201 Created -Access-Control-Allow-Credentials: true -Access-Control-Allow-Origin: http://localhost:8002 -Connection: keep-alive -Content-Length: 386 -Content-Type: application/json; charset=utf-8 -Date: Tue, 11 May 2021 14:50:19 GMT -Server: kong/2.4.0.0-beta1-enterprise-edition -X-Kong-Admin-Latency: 15 -X-Kong-Admin-Request-ID: 2ZPP5GE3T6vL2bhbLRL7PBA2u9zgUEB8 -vary: Origin - -{ - "config": { - "api_specification": null, - "api_specification_filename": "stock-0.1.json", - "max_delay_time": 1, - "min_delay_time": 0.001, - "random_delay": true - }, - "consumer": null, - "created_at": 1620744619, - "enabled": true, - "id": "273edea0-477a-4d9c-bb00-1cf99e48f191", - "name": "mocking", - "protocols": [ - "grpc", - "grpcs", - "http", - "https" - ], - "route": { - "id": "b0fad1db-eedf-4e1c-ace3-a394a640a514" - }, - "service": null, - "tags": null -} -``` - -### Step 5. Enable the CORS plugin {#enable-cors-plugin} - -Cross-origin resource sharing (CORS) is disabled by default for security reasons. To test the mock response -from the Dev Portal, enable the [CORS plugin](/hub/kong-inc/cors/) on the `getStockQuote` route. - -Command: - -{% navtabs %} -{% navtab cURL %} - -```bash -curl -X POST http://:8001/routes/getStockQuote/plugins \ - --data "name=cors" \ - --data "config.origins=*" -``` - -{% endnavtab %} -{% navtab HTTPie %} - -```bash -http -f :8001/routes/getStockQuote/plugins name=cors config.origins=* -``` - -{% endnavtab %} -{% endnavtabs %} - -Response: - -``` -HTTP/1.1 201 Created -Access-Control-Allow-Credentials: true -Access-Control-Allow-Origin: http://localhost:8002 -Connection: keep-alive -Content-Length: 449 -Content-Type: application/json; charset=utf-8 -Date: Fri, 23 Apr 2021 20:46:25 GMT -Server: kong/2.4.0.0-beta1-enterprise-edition -X-Kong-Admin-Latency: 10 -X-Kong-Admin-Request-ID: niWS3bFPIUeHOfbLkQTQLS3qeIxSVoPx -vary: Origin - -{ - "config": { - "credentials": false, - "exposed_headers": null, - "headers": null, - "max_age": null, - "methods": [ - "GET", - "HEAD", - "PUT", - "PATCH", - "POST", - "DELETE", - "OPTIONS", - "TRACE", - "CONNECT" - ], - "origins": [ - "*" - ], - "preflight_continue": false - }, - "consumer": null, - "created_at": 1619210785, - "enabled": true, - "id": "4573e790-b0b5-4535-a1ab-88c42ca56f69", - "name": "cors", - "protocols": [ - "grpc", - "grpcs", - "http", - "https" - ], - "route": { - "id": "5ada3c98-c732-4c05-903f-9ba8ef026776" - }, - "service": null, - "tags": null -} -``` - -### Step 6. Test the mock response {#testing123} - -Test the mocked response from within the Dev Portal Service, -[Insomnia](https://insomnia.rest/download), or from the command line. - -#### Dev Portal mock spec test - -Test the mock response from within the Dev Portal spec using the **Try it out** feature. - -1. From the Dev Portal home page, click the **Stock API** Service tile. - - ![Dev Portal Services](/assets/images/docs/dev-portal/stock-service.png) - -2. Click the **GET /stock/historical** method and the **Try it out** button. - -3. Enter the ticker sign **AAPL** in the **tickers** box and click **Execute** to see the server response. - - - ![Try it out Dev Portal](/assets/images/docs/dev-portal/tryitout-portal.png) - -#### Insomnia mock spec test {#insomnia} - -Test the mock response from within the Insomnia spec using the **Try it out** feature. - -1. From the Insomnia dashboard, click the **Stock API 0.1 Document** tile. - - ![Insomnia Dashboard](/assets/images/docs/insomnia/insomnia-stock-spec.png) - -2. Click the **GET /stock/historical** method and the **Try it out** button. - -3. Enter the ticker sign **AAPL** in the **tickers** box and click **Execute** to see the server response. - - - ![Try it out Insomnia](/assets/images/docs/insomnia/tryitout-insomnia.png) - -#### Command line test - -{% navtabs %} -{% navtab cURL %} - -```bash -curl -X GET "http://:8000/stock/historical?tickers=AAPL" \ - -H "accept: application/json" -``` - -{% endnavtab %} -{% navtab HTTPie %} - -```bash -http :8000/stock/historical?tickers=AAPL accept:application/json -``` - -{% endnavtab %} -{% endnavtabs %} - -The response matches the mocked response from within the spec: - -``` -HTTP/1.1 200 OK -Access-Control-Allow-Origin: * -Connection: keep-alive -Content-Length: 279 -Content-Type: application/json; charset=utf-8 -Date: Wed, 05 May 2021 19:59:06 GMT -Server: kong/2.4.0.0-beta1-enterprise-edition -X-Kong-Mocking-Plugin: true -X-Kong-Response-Latency: 40 -vary: Origin - -{ - "meta_data": { - "api_name": "historical_stock_price_v2", - "credit_cost": 10, - "end_date": "yesterday", - "num_total_data_points": 1, - "start_date": "yesterday" - }, - "result_data": { - "AAPL": [ - { - "adj_close": 275.03, - "close": 100.03, - "date": "2000-04-23", - "high": 100.75, - "low": 100.87, - "open": 100.87, - "volume": 33 - } - ] - } -} -``` - -### Step 7. Disable the Mocking plugin and update the Service URL {#post-test} - -When your API mock testing is completed, disable the Mocking plugin and update the service -URL. - -Disable the Mocking plugin either in Kong Manager by clicking **Disable** for the plugin, -or by using a command. You can copy and paste the plugin ID from within Kong Manager. - -![Copy Plugin ID](/assets/images/docs/dev-portal/km-copy-plugin-id.png) - -{% navtabs %} -{% navtab cURL %} - -``` -curl -X PATCH http://localhost:8001/plugins/ -i \ - --data "name=mocking" \ - --data "enabled=false" -``` - -{% endnavtab %} -{% navtab HTTPie %} - -``` -http PATCH :8001/plugins/ enabled=false -f -``` - -{% endnavtab %} -{% endnavtabs %} - -Response: - -``` -HTTP/1.1 200 OK -Access-Control-Allow-Credentials: true -Access-Control-Allow-Origin: http://localhost:8002 -Connection: keep-alive -Content-Length: 347 -Content-Type: application/json; charset=utf-8 -Date: Fri, 07 May 2021 18:18:11 GMT -Server: kong/2.4.0.0-beta1-enterprise-edition -X-Kong-Admin-Latency: 11 -X-Kong-Admin-Request-ID: 0s7xacYAUBFIY0LPanSkobV8mSdhOSvk -vary: Origin -{ - "config": { - "api_specification": null, - "api_specification_filename": "stock-0.1.json", - "max_delay_time": 1, - "min_delay_time": 0.001, - "random_delay": false - }, - "consumer": null, - "created_at": 1620403609, - "enabled": false, - "id": "9a7dbe34-da00-47df-9939-5787abf2d3a1", - "name": "mocking", - "protocols": [ - "grpc", - "grpcs", - "http", - "https" - ], - "route": null, - "service": null, - "tags": null -} -``` - -The `enabled` config reflects `false` in line `22`. - -The service URL can be anything for purposes of mocking. After you disable the Mocking plugin, -ensure you set the actual URL for your service so that the response can be received. - - ![Set Real Service URL](/assets/images/docs/dev-portal/km-service-url.png) - -## See also -* [`inso` CLI documentation](https://support.insomnia.rest/collection/105-inso-cli) -* [OpenAPI2Kong npm package](https://www.npmjs.com/package/openapi-2-kong) diff --git a/app/_hub/kong-inc/mocking/_index.md b/app/_hub/kong-inc/mocking/_index.md index d06d32ae42d5..614e6668eb6c 100644 --- a/app/_hub/kong-inc/mocking/_index.md +++ b/app/_hub/kong-inc/mocking/_index.md @@ -1,7 +1,6 @@ --- name: Mocking publisher: Kong Inc. -version: 0.2.x desc: Provide mock endpoints to test your APIs against your services description: | Provide mock endpoints to test your APIs in development against your services. @@ -20,10 +19,6 @@ description: | This plugin can mock `200`, `201`, and `204` responses. - {:.note} - > To use this plugin in Konnect Cloud, - [upgrade your runtimes](/konnect/runtime-manager/upgrade) to at least - v2.4.1.1. enterprise: true plus: true type: plugin @@ -31,12 +26,7 @@ categories: - traffic-control kong_version_compatibility: enterprise_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x + compatible: true params: name: mocking service_id: true @@ -103,6 +93,7 @@ params: value_in_examples: true description: | Randomly selects one example and returns it. This parameter requires the spec to have multiple examples configured. + minimum_version: "2.7.x" extra: | Depending on the Kong Gateway deployment mode, set either the `api_specification_filename` @@ -131,7 +122,7 @@ The `` is the id or name of the service that this plugin configuration Configure this plugin on a [route](/gateway/latest/admin-api/#route-object): ```bash -$ curl -X POST http://:8001/routes//plugins \ +curl -X POST http://:8001/routes//plugins \ --data "name=mocking" \ --data "config.api_specification_filename=multipleexamples.json" \ --data "config.random_delay=true" \ @@ -147,11 +138,11 @@ Configure this plugin on a [consumer](/gateway/latest/admin-api/#consumer-object ```bash curl -X POST http://:8001/consumers//plugins \ - --data "name=mocking" \ - --data "config.api_specification_filename=multipleexamples.json" \ - --data "config.random_delay=true" \ - --data "config.max_delay_time=1" \ - --data "config.min_delay_time=0.001" + --data "name=mocking" \ + --data "config.api_specification_filename=multipleexamples.json" \ + --data "config.random_delay=true" \ + --data "config.max_delay_time=1" \ + --data "config.min_delay_time=0.001" ``` The `` is the id or username of the consumer that this plugin configuration will target. @@ -911,4 +902,12 @@ ensure you set the actual URL for your service so that the response can be recei ## See also * [`inso` CLI documentation](https://support.insomnia.rest/collection/105-inso-cli) -* [OpenAPI2Kong npm package](https://www.npmjs.com/package/openapi-2-kong) + +--- + +## Changelog + +**{{site.base_gateway}} 2.7.x** + +* Added the `random_examples` parameter. +Use this setting to randomly select one example from a set of mocked responses. diff --git a/app/_hub/kong-inc/mocking/versions.yml b/app/_hub/kong-inc/mocking/versions.yml index 8f68dd8fa36b..a182fbfa56a3 100644 --- a/app/_hub/kong-inc/mocking/versions.yml +++ b/app/_hub/kong-inc/mocking/versions.yml @@ -1,2 +1,16 @@ -- release: 0.2.x -- release: 0.1.x +strategy: gateway + +releases: + - 3.0.x + - 2.8.x + - 2.7.x + - 2.6.x + - 2.5.x + - 2.4.x + +overrides: + 2.8.x: 0.3.0 + 2.7.x: 0.3.0 + 2.6.x: 0.2.2 + 2.5.x: 0.2.1 + 2.4.x: 0.2.1 diff --git a/app/_hub/kong-inc/mtls-auth/0.36-x.md b/app/_hub/kong-inc/mtls-auth/0.36-x.md deleted file mode 100644 index c98404efc5fc..000000000000 --- a/app/_hub/kong-inc/mtls-auth/0.36-x.md +++ /dev/null @@ -1,136 +0,0 @@ ---- - -name: Mutual TLS Authentication -publisher: Kong Inc. -version: 0.36-x - -desc: Secure routes and services with client certificate and mutual TLS authentication -description: | - Add mutual TLS authentication based on client-supplied certificate and configured trusted CA list. Automatically maps certificates to **Consumers** based on the common name field. - -enterprise: true -type: plugin -categories: - - authentication - -kong_version_compatibility: - community_edition: - compatible: - enterprise_edition: - compatible: - - 0.36-x - -params: - name: mtls-auth - service_id: true - route_id: true - config: - - name: anonymous - required: false - description: | - An optional string (consumer UUID) value to use as an "anonymous" **Consumer** if authentication fails. If the request is left empty (which it is by default), it will fail with an authentication failure of either `HTTP 495` if the client presented a certificate that is not acceptable, or `HTTP 496` if the client failed to present certificate as requested. Please note that this value must refer to the **Consumer** `id` attribute, which is internal to Kong, and **not** its `custom_id`. - - name: consumer_by - required: false - default: '`[ "username", "custom_id" ]`' - description: | - Whether to match the subject name of the client-supplied certificate against consumer's `username` and/or `custom_id` attribute. If set to `[]` (the empty array) then auto-matching is disabled. - - name: ca_certificates - required: true - value_in_examples: '`[ { "id": "fdac360e-7b19-4ade-a553-6dd22937c82f" }, { "id": "aabc360e-7b19-5aab-1231-6da229a7b82f"} ]`' - description: | - List of "CA Certificates" object to use as Certificate Authorities (CA) when validating client certificate. At least one is required but can specify as many as needed. The value of this array comprises of primary keys for the "Certificate Authority" object. - - name: cache_ttl - default: "`60`" - description: | - Cache expiry time in seconds. ---- - -### Usage - -In order to authenticate the **Consumer**, it must provide a valid certificate and -complete mutual TLS handshake with Kong. - -The plugin will validate the certificate provided against the configured CA list based on the requested **Route** or **Service**. -If the certificate is not trusted or has expired, the response will be `HTTP 401` "TLS certificate failed verification." -If **Consumer** did not present a valid certificate (this includes requests not sent to the HTTPS port), -then the response will be `HTTP 401` "No required TLS certificate was sent". That exception is if the `config.anonymous` -option was configured on the plugin, in which case the anonymous **Consumer** will be used -and the request will be allowed to proceed. - -### Adding certificate authorities - -In order to use this plugin, you must add certificate authority certificates. These are stored in a separate ca-certificates store rather than the main certificates store, as they do not require private keys. To add one, obtain a PEM-encoded copy of your CA certificate and POST it to `/ca_certificates`: - -```bash -$ curl -sX POST https://kong:8001/ca_certificates -F cert=@cert.pem -{ - "tags": null, - "created_at": 1566597621, - "cert": "-----BEGIN CERTIFICATE-----\FullPEMOmittedForBrevity==\n-----END CERTIFICATE-----\n", - "id": "322dce96-d434-4e0d-9038-311b3520f0a3" -} -``` - -The `id` value returned can now be used for mTLS plugin configurations or consumer mappings. - -### Create manual mappings between certificate and Consumer object - -Sometimes you may not wish to use automatic Consumer lookup or you have certificates -that contain a field value not associated with **Consumer** objects directly. In those -situations, you may manually assign one or more subject names to the **Consumer** object for -identifying the correct Consumer. - -**Note:** "Subject names" refers to the certificate's Subject Alternative Names (SAN) or -"Common Name" (CN). CN will only be used if the SAN extension does not exist. - -```bash -$ curl -X POST http://kong:8001/consumers/{consumer}/mtls-auth \ - -d 'subject_name=test@example.com' -HTTP/1.1 201 Created - -{ - "consumer": { "id": "876bf719-8f18-4ce5-cc9f-5b5af6c36007" }, - "created_at": 1443371053000, - "subject_name": "test@example.com" -} -``` - -* `consumer`: The `id` or `username` property of the [Consumer][consumer-object] entity to associate the credentials to. - -form parameter | default | description ---- | --- | --- -`subject_name`
*required* | | The Subject Alternative Name (SAN) or Common Name (CN) that should be mapped to `consumer` (in that order of lookup). -`ca_certificate`
*optional* | | UUID of the Certificate Authority (CA) that the certificate has to be verifiable by for the mapping to success. This is to help distinguish multiple certificates with the same subject name but are issued under different CAs. If empty, the subject name will match certificates issued by any CA under the corresponding `config.ca_certificates`. - -### Matching behaviors - -Once a client certificate has been verified as valid, the **Consumer** object will be determined in the following order: - -1. Manual mappings with `subject_name` matching the certificate's SAN or CN (in that order) and `ca_certificate = ` -2. Manual mappings with `subject_name` matching the certificate's SAN or CN (in that order) and `ca_certificate = NULL` -3. If `config.consumer_by` is not null, Consumer with `username` and/or `id` matching the certificate's SAN or CN (in that order) -4. The `config.anonymous` consumer (if set) - -**Note**: matching will stop as soon as the first successful match is found. - -When a client has been authenticated, the plugin will append headers to the request before proxying it to the upstream service so that you can identify the **Consumer** in your code: - -* `X-Consumer-ID`, the ID of the Consumer on Kong -* `X-Consumer-Custom-ID`, the `custom_id` of the Consumer (if set) -* `X-Consumer-Username`, the `username` of the Consumer (if set) -* `X-Credential-Username`, the `username` of the Credential (only if the consumer is not the 'anonymous' consumer) -* `X-Anonymous-Consumer` will be set to `true` if authentication failed and the 'anonymous' **Consumer** was set instead. - - -### Troubleshooting - -When authentication fails, the client does not have access to any details explaining the -failure. The security reason for this omission is to prevent malicious reconnaissance. -Instead, the details are recorded inside Kong's error logs under the `[mtls-auth]` -filter. - - -[configuration]: /gateway/latest/reference/configuration -[consumer-object]: /gateway/latest/admin-api/#consumer-object -[acl-associating]: /plugins/acl/#associating-consumers - diff --git a/app/_hub/kong-inc/mtls-auth/1.3-x.md b/app/_hub/kong-inc/mtls-auth/1.3-x.md deleted file mode 100644 index dde13cd17a78..000000000000 --- a/app/_hub/kong-inc/mtls-auth/1.3-x.md +++ /dev/null @@ -1,199 +0,0 @@ ---- - -name: Mutual TLS Authentication -publisher: Kong Inc. -version: 1.3-x - -desc: Secure routes and services with client certificate and mutual TLS authentication -description: | - Add mutual TLS authentication based on client-supplied certificate and configured trusted CA list. Automatically maps certificates to consumers based on the common name field. - -enterprise: true -type: plugin -categories: - - authentication - -kong_version_compatibility: - community_edition: - compatible: - enterprise_edition: - compatible: - - 1.3-x - - 0.36-x - -params: - name: mtls-auth - service_id: true - route_id: true - config: - - name: anonymous - required: false - description: | - An optional string (consumer UUID) value to use as an "anonymous" consumer if authentication fails. If the request is left empty (which it is by default), it fails with an authentication failure of either `HTTP 495` if the client presented a certificate that is not acceptable, or `HTTP 496` if the client failed to present certificate as requested. Please note that this value must refer to the consumer `id` attribute, which is internal to Kong, and **not** its `custom_id`. - - name: consumer_by - required: false - default: '`[ "username", "custom_id" ]`' - description: | - Whether to match the subject name of the client-supplied certificate against consumer's `username` and/or `custom_id` attribute. If set to `[]` (the empty array) then auto-matching is disabled. - - name: ca_certificates - required: true - value_in_examples: '`[ { "id": "fdac360e-7b19-4ade-a553-6dd22937c82f" }, { "id": "aabc360e-7b19-5aab-1231-6da229a7b82f"} ]`' - description: | - List of "CA Certificates" object to use as Certificate Authorities (CA) when validating client certificate. At least one is required but can specify as many as needed. The value of this array comprises of primary keys for the "Certificate Authority" object. - - name: skip_consumer_lookup - default: "`true`" - description: | - Skip consumer look once certificate is trusted against the configured CA list. - - name: authenticated_group_by - default: "`CN`" - required: true - description: | - Certificate property which is used as authenticated group. Once `skip_consumer_lookup` is applied, any client with a valid certificate can access the Service/API. To restrict usage to only some of the authenticated users, also add the ACL plugin (not covered here) and create whitelist or blacklist groups of users. ---- - -## Usage - -In order to authenticate the consumer, it must provide a valid certificate and -complete mutual TLS handshake with Kong. - -The plugin validates the certificate provided against the configured CA list based on the requested route or service. -If the certificate is not trusted or has expired, the response will be `HTTP 401` "TLS certificate failed verification." -If consumer did not present a valid certificate (this includes requests not sent to the HTTPS port), -then the response will be `HTTP 401` "No required TLS certificate was sent". That exception is if the `config.anonymous` -option was configured on the plugin, in which case the anonymous consumer is used -and the request is allowed to proceed. - - -### Client certificate request -Client certificates are requested in `ssl_certifica_by_lua` phase where Kong does not have access to `route` and `workspace` information. Due to this information gap, Kong asks for the client certificate by default on every handshake if the mtls-auth plugin is configured on any route or service. In most cases, the failure of the client to present a client certificate is not going to affect subsequent proxying if that route or service does not have the mtls-auth plugin applied. The exception is where the client is a desktop browser which prompts the end user to choose the client cert to send and lead to User Experience issues rather than proxy behavior problems. -To improve this situation, Kong builds an in-memory map of SNIs from the configured Kong routes that should present a client certificate. To limit client certificate requests during handshake while ensuring the client certificate is requested when needed, the in memory map is dependent on the routes in Kong having the SNIs attribute set. When any routes do not have SNIs set, Kong must request the client certificate during every TLS handshake. Kong requests the client certificate in the following scenarios: - -- On every request irrespective of Workspace when plugin enabled in global Workspace scope. -- On every request irrespective of Workspace when plugin applied at service level - and one or more of the routes *do not* have SNIs set. -- On every request irrespective of Workspace when plugin applied at route level - and one or more routes *do not* have SNIs set. -- On specific request only when plugin applied at route level and all routes have SNIs set. - -SNIs must be set for all routes that mtls-auth was meant to be effective. - -### Adding certificate authorities - -In order to use this plugin, you must add certificate authority certificates. These are stored in a separate ca-certificates store rather than the main certificates store, as they do not require private keys. To add one, obtain a PEM-encoded copy of your CA certificate and POST it to `/ca_certificates`: - -```bash -$ curl -sX POST https://kong:8001/ca_certificates -F cert=@cert.pem -{ - "tags": null, - "created_at": 1566597621, - "cert": "-----BEGIN CERTIFICATE-----\FullPEMOmittedForBrevity==\n-----END CERTIFICATE-----\n", - "id": "322dce96-d434-4e0d-9038-311b3520f0a3" -} -``` - -The `id` value returned can now be used for mTLS plugin configurations or consumer mappings. - -### Create manual mappings between certificate and consumer object - -Sometimes, you might not want to use automatic consumer lookup, or you have certificates -that contain a field value not directly associated with consumer objects. In those -situations, you may manually assign one or more subject names to the consumer object for -identifying the correct consumer. - -{:.note} -> **Note**: "Subject names" refers to the certificate's Subject Alternative Names (SAN) or -"Common Name" (CN). CN is only used if the SAN extension does not exist. - -{% navtabs %} -{% navtab Kong Admin API %} - -Create a mapping: - -```bash -$ curl -X POST http://kong:8001/consumers/{consumer}/mtls-auth \ - -d 'subject_name=test@example.com' -``` - -Where `{consumer}` is the `id` or `username` property of the -[consumer](/gateway/latest/admin-api/#consumer-object) entity to associate the -credentials to. - -Once created, you'll see a `201` success message: - -```bash -HTTP/1.1 201 Created - -{ - "consumer": { "id": "876bf719-8f18-4ce5-cc9f-5b5af6c36007" }, - "created_at": 1443371053000, - "subject_name": "test@example.com" -} -``` - -{% endnavtab %} -{% navtab Declarative (YAML) %} - -To create a subject name mapping using declarative configuration, you must generate a UUID for each `mtls_auth_credentials` mapping. You can use any -UUID generator to do this. Here are some common ones, depending on your OS: -* [Linux](https://man7.org/linux/man-pages/man1/uuidgen.1.html) -* [MacOS](https://www.unix.com/man-page/mojave/1/uuidgen/) -* [Windows](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/new-guid?view=powershell-7) - -After you have generated a UUID, add the following to your declarative -configuration file: - -```yaml -consumers: -- custom_id: my-consumer - username: {consumer} - mtls_auth_credentials: - - id: bda09448-3b10-4da7-a83b-2a8ba6021f0c - subject_name: test@example.com -``` - -{% endnavtab %} -{% endnavtabs %} - -#### Parameters for manual mapping - -Form Parameter | Default | Description ---- | --- | --- -`id`
*required for declarative config* | none | UUID of the consumer-mapping. Required if adding mapping using declarative configuration, otherwise generated automatically by Kong's Admin API. -`subject_name`
*required* | none | The Subject Alternative Name (SAN) or Common Name (CN) that should be mapped to `consumer` (in order of lookup). -`ca_certificate`
*optional* | none | **If using the Kong Admin API:** UUID of the Certificate Authority (CA).

**If using declarative configuration:** Full PEM-encoded CA certificate.

The provided CA UUID or full certificate has to be verifiable by the issuing certificate authority for the mapping to succeed. This is to help distinguish multiple certificates with the same subject name that are issued under different CAs.

If empty, the subject name matches certificates issued by any CA under the corresponding `config.ca_certificates`. - -### Matching behaviors - -After a client certificate has been verified as valid, the consumer object is determined in the following order, unless `skip_consumer_lookup` is set to `true`: - -1. Manual mappings with `subject_name` matching the certificate's SAN or CN (in that order) and `ca_certificate = ` -2. Manual mappings with `subject_name` matching the certificate's SAN or CN (in that order) and `ca_certificate = NULL` -3. If `config.consumer_by` is not null, consumer with `username` and/or `id` matching the certificate's SAN or CN (in that order) -4. The `config.anonymous` consumer (if set) - -{:.note} -> **Note**: Matching stops as soon as the first successful match is found. - -When a client has been authenticated, the plugin appends headers to the request before proxying it to the upstream service so that you can identify the consumer in your code: - -* `X-Consumer-ID`, the ID of the consumer on Kong -* `X-Consumer-Custom-ID`, the `custom_id` of the consumer (if set) -* `X-Consumer-Username`, the `username` of the consumer (if set) -* `X-Credential-Username`, the `username` of the Credential (only if the consumer is not the 'anonymous' consumer) -* `X-Anonymous-Consumer` is set to `true` if authentication failed and the 'anonymous' consumer was set instead. - -When `skip_consumer_lookup` is set to `true`, consumer lookup is skipped and instead of appending aforementioned headers, the plugin appends the following two headers - -* `X-Client-Cert-Dn`, distinguished name of the client certificate -* `X-Client-Cert-San`, SAN of the client certificate - -Once `skip_consumer_lookup` is applied, any client with a valid certificate can access the Service/API. -To restrict usage to only some of the authenticated users, also add the ACL plugin (not covered here) and create allowlist or denylist groups of users using same -certificate property being set in `authenticated_group_by`. - -### Troubleshooting - -When authentication fails, the client does not have access to any details that explain the -failure. The security reason for this omission is to prevent malicious reconnaissance. -Instead, the details are recorded inside Kong's error logs under the `[mtls-auth]` -filter. diff --git a/app/_hub/kong-inc/mtls-auth/_index.md b/app/_hub/kong-inc/mtls-auth/_index.md index c31d68bbb384..554cb8d33d23 100644 --- a/app/_hub/kong-inc/mtls-auth/_index.md +++ b/app/_hub/kong-inc/mtls-auth/_index.md @@ -1,7 +1,6 @@ --- name: Mutual TLS Authentication publisher: Kong Inc. -version: 1.5.x desc: Secure routes and services with client certificate and mutual TLS authentication description: | Add mutual TLS authentication based on client-supplied or server-supplied certificate, and on the configured trusted CA list. Automatically maps certificates to consumers based on the common name field. @@ -14,18 +13,7 @@ kong_version_compatibility: community_edition: compatible: null enterprise_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x + compatible: true params: name: mtls-auth service_id: true @@ -108,6 +96,7 @@ params: description: | Cache expiry time in seconds. - name: http_proxy_host + minimum_version: "2.8.x" required: semi default: null value_in_examples: example @@ -118,8 +107,8 @@ params: (CRL) or an OCSP server. Required if `http_proxy_port` is set. - # minimum_version: "2.8.x" - name: http_proxy_port + minimum_version: "2.8.x" required: semi default: null value_in_examples: 80 @@ -128,8 +117,8 @@ params: The TCP port of the HTTP proxy. Required if `http_proxy_host` is set. - # minimum_version: "2.8.x" - name: https_proxy_host + minimum_version: "2.8.x" required: semi default: null value_in_examples: @@ -140,8 +129,8 @@ params: (CRL) or an OCSP server. Required if `https_proxy_port` is set. - # minimum_version: "2.8.x" - name: https_proxy_port + minimum_version: "2.8.x" required: semi default: null value_in_examples: @@ -150,7 +139,6 @@ params: The TCP port of the HTTPS proxy. Required if `https_proxy_host` is set. - # minimum_version: "2.8.x" --- ## Usage @@ -214,9 +202,9 @@ curl -sX POST https://kong:8001/ca_certificates -F cert=@cert.pem {% navtab Konnect Cloud %} Go through the Runtime Manager: -1. In {{site.konnect_short_name}}, click {% konnect_icon runtimes %} **Runtime Manager**. +1. In {{site.konnect_short_name}}, click {% konnect_icon runtimes %} **Runtime Manager**. 2. Select the runtime instance you want to add the CA certificate to. -3. Click **Certificates**. +3. Click **Certificates**. 4. Select the **CA Certificates** tab. 5. Click **+ Add CA Certificate** 6. Copy and paste your certificate information and click **Save**. @@ -251,7 +239,7 @@ Common Name (CN). CN is only used if the SAN extension does not exist. Create a mapping: ```bash -$ curl -X POST http://kong:8001/consumers/{consumer}/mtls-auth \ +curl -X POST http://kong:8001/consumers/{consumer}/mtls-auth \ -d 'subject_name=test@example.com' ``` @@ -261,7 +249,7 @@ credentials to. Once created, you'll see a `201` success message: -```bash +```json HTTP/1.1 201 Created { @@ -315,13 +303,7 @@ After a client certificate has been verified as valid, the consumer object is de {:.note} > **Note**: Matching stops as soon as the first successful match is found. -When a client has been authenticated, the plugin appends headers to the request before proxying it to the upstream service so that you can identify the consumer in your code: - -* `X-Consumer-ID`, the ID of the consumer on Kong -* `X-Consumer-Custom-ID`, the `custom_id` of the consumer (if set) -* `X-Consumer-Username`, the `username` of the consumer (if set) -* `X-Credential-Username`, the `username` of the Credential (only if the consumer is not the 'anonymous' consumer) -* `X-Anonymous-Consumer` is set to `true` if authentication failed and the 'anonymous' consumer was set instead. +{% include_cached /md/plugins-hub/upstream-headers.md %} When `skip_consumer_lookup` is set to `true`, consumer lookup is skipped and instead of appending aforementioned headers, the plugin appends the following two headers @@ -340,9 +322,14 @@ failure. The security reason for this omission is to prevent malicious reconnais Instead, the details are recorded inside Kong's error logs under the `[mtls-auth]` filter. +--- + ## Changelog -### {{site.base_gateway}} 2.8.1.1 +**{{site.base_gateway}} 3.0.x** +* The deprecated `X-Credential-Username` header has been removed. + +**{{site.base_gateway}} 2.8.1.1** * Introduced certificate revocation list (CRL) and OCSP server support with the following parameters: `http_proxy_host`, `http_proxy_port`, `https_proxy_host`, diff --git a/app/_hub/kong-inc/mtls-auth/versions.yml b/app/_hub/kong-inc/mtls-auth/versions.yml index 0e9f6d96eb57..245f17824e85 100644 --- a/app/_hub/kong-inc/mtls-auth/versions.yml +++ b/app/_hub/kong-inc/mtls-auth/versions.yml @@ -1,3 +1,12 @@ -- release: 1.5.x -- release: 1.3-x -- release: 0.36-x +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 0.3.5 + 2.7.x: 0.3.4 + 2.6.x: 0.3.3 + 2.5.x: 0.3.3 + 2.4.x: 0.3.3 + 2.3.x: 0.3.1 + 2.2.x: 0.2.4 + 2.1.x: 0.2.4 diff --git a/app/_hub/kong-inc/oauth2-introspection/0.31-x.md b/app/_hub/kong-inc/oauth2-introspection/0.31-x.md deleted file mode 100644 index e27a2cf16ab4..000000000000 --- a/app/_hub/kong-inc/oauth2-introspection/0.31-x.md +++ /dev/null @@ -1,119 +0,0 @@ ---- - -name: OAuth 2.0 Introspection -publisher: Kong Inc. -version: 0.31-x - -desc: Integrate Kong with a third-party OAuth 2.0 Authorization Server -description: | - Validate access tokens sent by developers using a third-party OAuth 2.0 - Authorization Server, by leveraging its Introspection Endpoint - ([RFC 7662](https://tools.ietf.org/html/rfc7662)). This plugin assumes that - the Consumer already has an access token that will be validated against a - third-party OAuth 2.0 server. - -enterprise: true -type: plugin -categories: - - authentication - -kong_version_compatibility: - community_edition: - compatible: - enterprise_edition: - compatible: - - 0.31-x - -params: - name: oauth2-introspection - api_id: true - service_id: true - route_id: true - konnect_examples: false - config: - - name: introspection_url - required: - default: - value_in_examples: - description: | - The full URL to the third-party introspection endpoint - - name: authorization_value - required: - default: - value_in_examples: - description: | - The value to append to the Authorization header when requesting the introspection endpoint - - name: token_type_hint - required: false - default: - value_in_examples: - description: | - The token_type_hint value to associate to introspection requests - - name: ttl - required: false - default: 60 - value_in_examples: - description: | - The TTL in seconds for the introspection response - set to 0 to disable the expiration - - name: hide_credentials - required: false - default: - value_in_examples: - description: | - An optional boolean value telling the plugin to hide the credential to the upstream API server. It will be removed by Kong before proxying the request. - - name: timeout - required: false - default: 10000 - value_in_examples: - description: | - An optional timeout in milliseconds when sending data to the upstream server - - name: keepalive - required: false - default: 60000 - value_in_examples: - description: | - An optional value in milliseconds that defines for how long an idle connection will live before being closed - - name: anonymous - required: false - default: - value_in_examples: - description: | - An optional string (consumer uuid) value to use as an "anonymous" consumer if authentication fails. If empty (default), the request will fail with an authentication failure 4xx. - - name: run_on_preflight - required: false - default: true - value_in_examples: - description: | - A boolean value that indicates whether the plugin should run (and try to authenticate) on `OPTIONS` preflight requests. If set to `false` then `OPTIONS` requests will always be allowed. - ---- - -### Flow - -![OAuth2 Introspection Flow](/assets/images/docs/oauth2/oauth2-introspection.png) - -### Associate the response to a Consumer - -To associate the introspection response resolution to a Kong Consumer, you will have to provision a Kong Consumer with the same `username` returned by the Introspection Endpoint response. - -### Upstream Headers - -When a client has been authenticated, the plugin will append some headers to the request before proxying it to the upstream API/Microservice, so that you can identify the consumer in your code: - -- `X-Consumer-ID`, the ID of the Consumer on Kong (if matched) -- `X-Consumer-Custom-ID`, the custom_id of the Consumer (if matched and if existing) -- `X-Consumer-Username`, the username of the Consumer (if matched and if existing) -- `X-Anonymous-Consumer`, will be set to true when authentication failed, and the 'anonymous' consumer was set instead. -- `X-Credential-Scope`, as returned by the Introspection response (if any) -- `X-Credential-Client-ID`, as returned by the Introspection response (if any) -- `X-Credential-Username`, as returned by the Introspection response (if any) -- `X-Credential-Token-Type`, as returned by the Introspection response (if any) -- `X-Credential-Exp`, as returned by the Introspection response (if any) -- `X-Credential-Iat`, as returned by the Introspection response (if any) -- `X-Credential-Nbf`, as returned by the Introspection response (if any) -- `X-Credential-Sub`, as returned by the Introspection response (if any) -- `X-Credential-Aud`, as returned by the Introspection response (if any) -- `X-Credential-Iss`, as returned by the Introspection response (if any) -- `X-Credential-Jti`, as returned by the Introspection response (if any) - -Note: Aforementioned `X-Credential-*` headers are not set when authentication failed, and the 'anonymous' consumer was set instead. diff --git a/app/_hub/kong-inc/oauth2-introspection/0.32-x.md b/app/_hub/kong-inc/oauth2-introspection/0.32-x.md deleted file mode 100644 index 48a9f974bab0..000000000000 --- a/app/_hub/kong-inc/oauth2-introspection/0.32-x.md +++ /dev/null @@ -1,119 +0,0 @@ ---- - -name: OAuth 2.0 Introspection -publisher: Kong Inc. -version: 0.32-x - -desc: Integrate Kong with a third-party OAuth 2.0 Authorization Server -description: | - Validate access tokens sent by developers using a third-party OAuth 2.0 - Authorization Server, by leveraging its Introspection Endpoint - ([RFC 7662](https://tools.ietf.org/html/rfc7662)). This plugin assumes that - the Consumer already has an access token that will be validated against a - third-party OAuth 2.0 server. - -enterprise: true -type: plugin -categories: - - authentication - -kong_version_compatibility: - community_edition: - compatible: - enterprise_edition: - compatible: - - 0.32-x - -params: - name: oauth2-introspection - api_id: true - service_id: true - route_id: true - konnect_examples: false - config: - - name: introspection_url - required: - default: - value_in_examples: - description: | - The full URL to the third-party introspection endpoint - - name: authorization_value - required: - default: - value_in_examples: - description: | - The value to append to the Authorization header when requesting the introspection endpoint - - name: token_type_hint - required: false - default: - value_in_examples: - description: | - The token_type_hint value to associate to introspection requests - - name: ttl - required: false - default: 60 - value_in_examples: - description: | - The TTL in seconds for the introspection response - set to 0 to disable the expiration - - name: hide_credentials - required: false - default: - value_in_examples: - description: | - An optional boolean value telling the plugin to hide the credential to the upstream API server. It will be removed by Kong before proxying the request. - - name: timeout - required: false - default: 10000 - value_in_examples: - description: | - An optional timeout in milliseconds when sending data to the upstream server - - name: keepalive - required: false - default: 60000 - value_in_examples: - description: | - An optional value in milliseconds that defines for how long an idle connection will live before being closed - - name: anonymous - required: false - default: - value_in_examples: - description: | - An optional string (consumer uuid) value to use as an "anonymous" consumer if authentication fails. If empty (default), the request will fail with an authentication failure 4xx. - - name: run_on_preflight - required: false - default: true - value_in_examples: - description: | - A boolean value that indicates whether the plugin should run (and try to authenticate) on `OPTIONS` preflight requests. If set to `false` then `OPTIONS` requests will always be allowed. - ---- - -### Flow - -![OAuth2 Introspection Flow](/assets/images/docs/oauth2/oauth2-introspection.png) - -### Associate the response to a Consumer - -To associate the introspection response resolution to a Kong Consumer, you will have to provision a Kong Consumer with the same `username` returned by the Introspection Endpoint response. - -### Upstream Headers - -When a client has been authenticated, the plugin will append some headers to the request before proxying it to the upstream API/Microservice, so that you can identify the consumer in your code: - -- `X-Consumer-ID`, the ID of the Consumer on Kong (if matched) -- `X-Consumer-Custom-ID`, the custom_id of the Consumer (if matched and if existing) -- `X-Consumer-Username`, the username of the Consumer (if matched and if existing) -- `X-Anonymous-Consumer`, will be set to true when authentication failed, and the 'anonymous' consumer was set instead. -- `X-Credential-Scope`, as returned by the Introspection response (if any) -- `X-Credential-Client-ID`, as returned by the Introspection response (if any) -- `X-Credential-Username`, as returned by the Introspection response (if any) -- `X-Credential-Token-Type`, as returned by the Introspection response (if any) -- `X-Credential-Exp`, as returned by the Introspection response (if any) -- `X-Credential-Iat`, as returned by the Introspection response (if any) -- `X-Credential-Nbf`, as returned by the Introspection response (if any) -- `X-Credential-Sub`, as returned by the Introspection response (if any) -- `X-Credential-Aud`, as returned by the Introspection response (if any) -- `X-Credential-Iss`, as returned by the Introspection response (if any) -- `X-Credential-Jti`, as returned by the Introspection response (if any) - -Note: Aforementioned `X-Credential-*` headers are not set when authentication failed, and the 'anonymous' consumer was set instead. diff --git a/app/_hub/kong-inc/oauth2-introspection/0.33-x.md b/app/_hub/kong-inc/oauth2-introspection/0.33-x.md deleted file mode 100644 index 4630c7fb9e37..000000000000 --- a/app/_hub/kong-inc/oauth2-introspection/0.33-x.md +++ /dev/null @@ -1,119 +0,0 @@ ---- - -name: OAuth 2.0 Introspection -publisher: Kong Inc. -version: 0.33-x - -desc: Integrate Kong with a third-party OAuth 2.0 Authorization Server -description: | - Validate access tokens sent by developers using a third-party OAuth 2.0 - Authorization Server, by leveraging its Introspection Endpoint - ([RFC 7662](https://tools.ietf.org/html/rfc7662)). This plugin assumes that - the Consumer already has an access token that will be validated against a - third-party OAuth 2.0 server. - -enterprise: true -type: plugin -categories: - - authentication - -kong_version_compatibility: - community_edition: - compatible: - enterprise_edition: - compatible: - - 0.33-x - -params: - name: oauth2-introspection - api_id: true - service_id: true - route_id: true - konnect_examples: false - config: - - name: introspection_url - required: - default: - value_in_examples: - description: | - The full URL to the third-party introspection endpoint - - name: authorization_value - required: - default: - value_in_examples: - description: | - The value to append to the Authorization header when requesting the introspection endpoint - - name: token_type_hint - required: false - default: - value_in_examples: - description: | - The token_type_hint value to associate to introspection requests - - name: ttl - required: false - default: 60 - value_in_examples: - description: | - The TTL in seconds for the introspection response - set to 0 to disable the expiration - - name: hide_credentials - required: false - default: - value_in_examples: - description: | - An optional boolean value telling the plugin to hide the credential to the upstream API server. It will be removed by Kong before proxying the request. - - name: timeout - required: false - default: 10000 - value_in_examples: - description: | - An optional timeout in milliseconds when sending data to the upstream server - - name: keepalive - required: false - default: 60000 - value_in_examples: - description: | - An optional value in milliseconds that defines for how long an idle connection will live before being closed - - name: anonymous - required: false - default: - value_in_examples: - description: | - An optional string (consumer uuid) value to use as an "anonymous" consumer if authentication fails. If empty (default), the request will fail with an authentication failure 4xx. - - name: run_on_preflight - required: false - default: true - value_in_examples: - description: | - A boolean value that indicates whether the plugin should run (and try to authenticate) on `OPTIONS` preflight requests. If set to `false` then `OPTIONS` requests will always be allowed. - ---- - -### Flow - -![OAuth2 Introspection Flow](/assets/images/docs/oauth2/oauth2-introspection.png) - -### Associate the response to a Consumer - -To associate the introspection response resolution to a Kong Consumer, you will have to provision a Kong Consumer with the same `username` returned by the Introspection Endpoint response. - -### Upstream Headers - -When a client has been authenticated, the plugin will append some headers to the request before proxying it to the upstream API/Microservice, so that you can identify the consumer in your code: - -- `X-Consumer-ID`, the ID of the Consumer on Kong (if matched) -- `X-Consumer-Custom-ID`, the custom_id of the Consumer (if matched and if existing) -- `X-Consumer-Username`, the username of the Consumer (if matched and if existing) -- `X-Anonymous-Consumer`, will be set to true when authentication failed, and the 'anonymous' consumer was set instead. -- `X-Credential-Scope`, as returned by the Introspection response (if any) -- `X-Credential-Client-ID`, as returned by the Introspection response (if any) -- `X-Credential-Username`, as returned by the Introspection response (if any) -- `X-Credential-Token-Type`, as returned by the Introspection response (if any) -- `X-Credential-Exp`, as returned by the Introspection response (if any) -- `X-Credential-Iat`, as returned by the Introspection response (if any) -- `X-Credential-Nbf`, as returned by the Introspection response (if any) -- `X-Credential-Sub`, as returned by the Introspection response (if any) -- `X-Credential-Aud`, as returned by the Introspection response (if any) -- `X-Credential-Iss`, as returned by the Introspection response (if any) -- `X-Credential-Jti`, as returned by the Introspection response (if any) - -Note: Aforementioned `X-Credential-*` headers are not set when authentication failed, and the 'anonymous' consumer was set instead. diff --git a/app/_hub/kong-inc/oauth2-introspection/0.34-x.md b/app/_hub/kong-inc/oauth2-introspection/0.34-x.md deleted file mode 100644 index f3b4cec71e8d..000000000000 --- a/app/_hub/kong-inc/oauth2-introspection/0.34-x.md +++ /dev/null @@ -1,119 +0,0 @@ ---- - -name: OAuth 2.0 Introspection -publisher: Kong Inc. -version: 0.34-x - -desc: Integrate Kong with a third-party OAuth 2.0 Authorization Server -description: | - Validate access tokens sent by developers using a third-party OAuth 2.0 - Authorization Server, by leveraging its Introspection Endpoint - ([RFC 7662](https://tools.ietf.org/html/rfc7662)). This plugin assumes that - the Consumer already has an access token that will be validated against a - third-party OAuth 2.0 server. - -enterprise: true -type: plugin -categories: - - authentication - -kong_version_compatibility: - community_edition: - compatible: - enterprise_edition: - compatible: - - 0.34-x - -params: - name: oauth2-introspection - api_id: true - service_id: true - route_id: true - konnect_examples: false - config: - - name: introspection_url - required: - default: - value_in_examples: - description: | - The full URL to the third-party introspection endpoint - - name: authorization_value - required: - default: - value_in_examples: - description: | - The value to append to the Authorization header when requesting the introspection endpoint - - name: token_type_hint - required: false - default: - value_in_examples: - description: | - The token_type_hint value to associate to introspection requests - - name: ttl - required: false - default: 60 - value_in_examples: - description: | - The TTL in seconds for the introspection response - set to 0 to disable the expiration - - name: hide_credentials - required: false - default: - value_in_examples: - description: | - An optional boolean value telling the plugin to hide the credential to the upstream API server. It will be removed by Kong before proxying the request. - - name: timeout - required: false - default: 10000 - value_in_examples: - description: | - An optional timeout in milliseconds when sending data to the upstream server - - name: keepalive - required: false - default: 60000 - value_in_examples: - description: | - An optional value in milliseconds that defines for how long an idle connection will live before being closed - - name: anonymous - required: false - default: - value_in_examples: - description: | - An optional string (consumer uuid) value to use as an "anonymous" consumer if authentication fails. If empty (default), the request will fail with an authentication failure 4xx. - - name: run_on_preflight - required: false - default: true - value_in_examples: - description: | - A boolean value that indicates whether the plugin should run (and try to authenticate) on `OPTIONS` preflight requests. If set to `false` then `OPTIONS` requests will always be allowed. - ---- - -### Flow - -![OAuth2 Introspection Flow](/assets/images/docs/oauth2/oauth2-introspection.png) - -### Associate the response to a Consumer - -To associate the introspection response resolution to a Kong Consumer, you will have to provision a Kong Consumer with the same `username` returned by the Introspection Endpoint response. - -### Upstream Headers - -When a client has been authenticated, the plugin will append some headers to the request before proxying it to the upstream API/Microservice, so that you can identify the consumer in your code: - -- `X-Consumer-ID`, the ID of the Consumer on Kong (if matched) -- `X-Consumer-Custom-ID`, the custom_id of the Consumer (if matched and if existing) -- `X-Consumer-Username`, the username of the Consumer (if matched and if existing) -- `X-Anonymous-Consumer`, will be set to true when authentication failed, and the 'anonymous' consumer was set instead. -- `X-Credential-Scope`, as returned by the Introspection response (if any) -- `X-Credential-Client-ID`, as returned by the Introspection response (if any) -- `X-Credential-Username`, as returned by the Introspection response (if any) -- `X-Credential-Token-Type`, as returned by the Introspection response (if any) -- `X-Credential-Exp`, as returned by the Introspection response (if any) -- `X-Credential-Iat`, as returned by the Introspection response (if any) -- `X-Credential-Nbf`, as returned by the Introspection response (if any) -- `X-Credential-Sub`, as returned by the Introspection response (if any) -- `X-Credential-Aud`, as returned by the Introspection response (if any) -- `X-Credential-Iss`, as returned by the Introspection response (if any) -- `X-Credential-Jti`, as returned by the Introspection response (if any) - -Note: Aforementioned `X-Credential-*` headers are not set when authentication failed, and the 'anonymous' consumer was set instead. diff --git a/app/_hub/kong-inc/oauth2-introspection/0.35-x.md b/app/_hub/kong-inc/oauth2-introspection/0.35-x.md deleted file mode 100644 index c670270a9302..000000000000 --- a/app/_hub/kong-inc/oauth2-introspection/0.35-x.md +++ /dev/null @@ -1,120 +0,0 @@ ---- - -name: OAuth 2.0 Introspection -publisher: Kong Inc. -version: 0.35-x - -desc: Integrate Kong with a third-party OAuth 2.0 Authorization Server -description: | - Validate access tokens sent by developers using a third-party OAuth 2.0 - Authorization Server, by leveraging its Introspection Endpoint - ([RFC 7662](https://tools.ietf.org/html/rfc7662)). This plugin assumes that - the Consumer already has an access token that will be validated against a - third-party OAuth 2.0 server. - -enterprise: true -type: plugin -categories: - - authentication - -kong_version_compatibility: - community_edition: - compatible: - enterprise_edition: - compatible: - - 0.35-x - - 0.34-x - -params: - name: oauth2-introspection - api_id: true - service_id: true - route_id: true - konnect_examples: false - config: - - name: introspection_url - required: - default: - value_in_examples: - description: | - The full URL to the third-party introspection endpoint - - name: authorization_value - required: - default: - value_in_examples: - description: | - The value to append to the Authorization header when requesting the introspection endpoint - - name: token_type_hint - required: false - default: - value_in_examples: - description: | - The token_type_hint value to associate to introspection requests - - name: ttl - required: false - default: 60 - value_in_examples: - description: | - The TTL in seconds for the introspection response - set to 0 to disable the expiration - - name: hide_credentials - required: false - default: - value_in_examples: - description: | - An optional boolean value telling the plugin to hide the credential to the upstream API server. It will be removed by Kong before proxying the request. - - name: timeout - required: false - default: 10000 - value_in_examples: - description: | - An optional timeout in milliseconds when sending data to the upstream server - - name: keepalive - required: false - default: 60000 - value_in_examples: - description: | - An optional value in milliseconds that defines for how long an idle connection will live before being closed - - name: anonymous - required: false - default: - value_in_examples: - description: | - An optional string (consumer uuid) value to use as an "anonymous" consumer if authentication fails. If empty (default), the request will fail with an authentication failure 4xx. - - name: run_on_preflight - required: false - default: true - value_in_examples: - description: | - A boolean value that indicates whether the plugin should run (and try to authenticate) on `OPTIONS` preflight requests. If set to `false` then `OPTIONS` requests will always be allowed. - ---- - -### Flow - -![OAuth2 Introspection Flow](/assets/images/docs/oauth2/oauth2-introspection.png) - -### Associate the response to a Consumer - -To associate the introspection response resolution to a Kong Consumer, you will have to provision a Kong Consumer with the same `username` returned by the Introspection Endpoint response. - -### Upstream Headers - -When a client has been authenticated, the plugin will append some headers to the request before proxying it to the upstream API/Microservice, so that you can identify the consumer in your code: - -- `X-Consumer-ID`, the ID of the Consumer on Kong (if matched) -- `X-Consumer-Custom-ID`, the custom_id of the Consumer (if matched and if existing) -- `X-Consumer-Username`, the username of the Consumer (if matched and if existing) -- `X-Anonymous-Consumer`, will be set to true when authentication failed, and the 'anonymous' consumer was set instead. -- `X-Credential-Scope`, as returned by the Introspection response (if any) -- `X-Credential-Client-ID`, as returned by the Introspection response (if any) -- `X-Credential-Username`, as returned by the Introspection response (if any) -- `X-Credential-Token-Type`, as returned by the Introspection response (if any) -- `X-Credential-Exp`, as returned by the Introspection response (if any) -- `X-Credential-Iat`, as returned by the Introspection response (if any) -- `X-Credential-Nbf`, as returned by the Introspection response (if any) -- `X-Credential-Sub`, as returned by the Introspection response (if any) -- `X-Credential-Aud`, as returned by the Introspection response (if any) -- `X-Credential-Iss`, as returned by the Introspection response (if any) -- `X-Credential-Jti`, as returned by the Introspection response (if any) - -Note: Aforementioned `X-Credential-*` headers are not set when authentication failed, and the 'anonymous' consumer was set instead. diff --git a/app/_hub/kong-inc/oauth2-introspection/0.36-x.md b/app/_hub/kong-inc/oauth2-introspection/0.36-x.md deleted file mode 100644 index e016b12f9259..000000000000 --- a/app/_hub/kong-inc/oauth2-introspection/0.36-x.md +++ /dev/null @@ -1,154 +0,0 @@ ---- - -name: OAuth 2.0 Introspection -publisher: Kong Inc. -version: 0.36-x - -desc: Integrate Kong with a third-party OAuth 2.0 Authorization Server -description: | - Validate access tokens sent by developers using a third-party OAuth 2.0 - Authorization Server, by leveraging its Introspection Endpoint - ([RFC 7662](https://tools.ietf.org/html/rfc7662)). This plugin assumes that - the Consumer already has an access token that will be validated against a - third-party OAuth 2.0 server. - -enterprise: true -type: plugin -categories: - - authentication - -kong_version_compatibility: - community_edition: - compatible: - enterprise_edition: - compatible: - - 0.36-x - - 0.35-x - - 0.34-x - -params: - name: oauth2-introspection - api_id: true - service_id: true - route_id: true - konnect_examples: false - config: - - name: introspection_url - required: - default: - value_in_examples: - description: | - The full URL to the third-party introspection endpoint - - name: authorization_value - required: - default: - value_in_examples: - description: | - The value to append to the Authorization header when requesting the introspection endpoint - - name: token_type_hint - required: false - default: - value_in_examples: - description: | - The token_type_hint value to associate to introspection requests - - name: ttl - required: false - default: 60 - value_in_examples: - description: | - The TTL in seconds for the introspection response - set to 0 to disable the expiration - - name: hide_credentials - required: false - default: - value_in_examples: - description: | - An optional boolean value telling the plugin to hide the credential to the upstream API server. It will be removed by Kong before proxying the request. - - name: timeout - required: false - default: 10000 - value_in_examples: - description: | - An optional timeout in milliseconds when sending data to the upstream server - - name: keepalive - required: false - default: 60000 - value_in_examples: - description: | - An optional value in milliseconds that defines for how long an idle connection will live before being closed - - name: anonymous - required: false - default: - value_in_examples: - description: | - An optional string (consumer uuid) value to use as an "anonymous" consumer if authentication fails. If empty (default), the request will fail with an authentication failure 4xx. - - name: run_on_preflight - required: false - default: true - value_in_examples: - description: | - A boolean value that indicates whether the plugin should run (and try to authenticate) on `OPTIONS` preflight requests. If set to `false` then `OPTIONS` requests will always be allowed. - - name: consumer_by - required: false - default: username - value_in_examples: username - description: | - A string indicating whether to associate oauth2 `username` or `client_id` - with the consumer's username. Oauth2 `username` is mapped to a consumer's - `username` field, while an oauth2 `client_id` maps to a consumer's - `custom_id` - - name: introspect_request - required: false - default: false - value_in_examples: - description: | - A boolean indicating whether to forward information about the current - downstream request to the introspect endpoint. If true, headers - `X-Request-Path` and `X-Request-Http-Method` will be inserted in the - introspect request - - name: custom_introspection_headers - required: false - default: - value_in_examples: - description: | - A list of custom headers to be added in the introspection request - - name: custom_claims_forward - required: false - default: - value_in_examples: - description: | - A list of custom claims to be forwarded from the introspection response - to the upstream request. Claims are forwarded in headers with prefix - `X-Credential-{claim-name}` ---- - -### Flow - -![OAuth2 Introspection Flow](/assets/images/docs/oauth2/oauth2-introspection.png) - -### Associate the response to a Consumer - -To associate the introspection response resolution to a Kong Consumer, you will have to provision a Kong Consumer with the same `username` returned by the Introspection Endpoint response. - -### Upstream Headers - -When a client has been authenticated, the plugin will append some headers to the request before proxying it to the upstream API/Microservice, so that you can identify the consumer in your code: - -- `X-Consumer-ID`, the ID of the Consumer on Kong (if matched) -- `X-Consumer-Custom-ID`, the `custom_id` of the Consumer (if matched and if existing) -- `X-Consumer-Username`, the `username of` the Consumer (if matched and if existing) -- `X-Anonymous-Consumer`, will be set to true when authentication failed, and the 'anonymous' consumer was set instead. -- `X-Credential-Scope`, as returned by the Introspection response (if any) -- `X-Credential-Client-ID`, as returned by the Introspection response (if any) -- `X-Credential-Username`, as returned by the Introspection response (if any) -- `X-Credential-Token-Type`, as returned by the Introspection response (if any) -- `X-Credential-Exp`, as returned by the Introspection response (if any) -- `X-Credential-Iat`, as returned by the Introspection response (if any) -- `X-Credential-Nbf`, as returned by the Introspection response (if any) -- `X-Credential-Sub`, as returned by the Introspection response (if any) -- `X-Credential-Aud`, as returned by the Introspection response (if any) -- `X-Credential-Iss`, as returned by the Introspection response (if any) -- `X-Credential-Jti`, as returned by the Introspection response (if any) - -Additionally, any claims specified in `config.custom_claims_forward` will also be forwarded with the `X-Credential-` prefix. - -Note: Aforementioned `X-Credential-*` headers are not set when authentication failed, and the 'anonymous' consumer was set instead. diff --git a/app/_hub/kong-inc/oauth2-introspection/_index.md b/app/_hub/kong-inc/oauth2-introspection/_index.md index 3b92599b65a2..eb604a6c3c6e 100644 --- a/app/_hub/kong-inc/oauth2-introspection/_index.md +++ b/app/_hub/kong-inc/oauth2-introspection/_index.md @@ -1,7 +1,6 @@ --- name: OAuth 2.0 Introspection publisher: Kong Inc. -version: 1.3-x desc: Integrate Kong with a third-party OAuth 2.0 Authorization Server description: | Validate access tokens sent by developers using a third-party OAuth 2.0 @@ -25,18 +24,7 @@ kong_version_compatibility: community_edition: compatible: null enterprise_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x + compatible: true params: name: oauth2-introspection service_id: true @@ -173,7 +161,7 @@ Use these headers to identify the consumer in your code: - `X-Anonymous-Consumer`, set to true if authentication fails, and the `anonymous` consumer is set instead. - `X-Credential-Scope`, as returned by the Introspection response (if any) - `X-Credential-Client-ID`, as returned by the Introspection response (if any) -- `X-Credential-Username`, as returned by the Introspection response (if any) +- `X-Credential-Identifier`, as returned by the Introspection response (if any) - `X-Credential-Token-Type`, as returned by the Introspection response (if any) - `X-Credential-Exp`, as returned by the Introspection response (if any) - `X-Credential-Iat`, as returned by the Introspection response (if any) @@ -188,3 +176,9 @@ Additionally, any claims specified in `config.custom_claims_forward` are also fo {:.note} > **Note:** If authentication fails, the plugin doesn't set any `X-Credential-*` headers. It appends `X-Anonymous-Consumer: true` and sets the `anonymous` consumer instead. + +--- +## Changelog + +**{{site.base_gateway}} 3.0.x** +* The deprecated `X-Credential-Username` header has been removed. diff --git a/app/_hub/kong-inc/oauth2-introspection/versions.yml b/app/_hub/kong-inc/oauth2-introspection/versions.yml index 72b1e6fb3f0d..7e21f9d88251 100644 --- a/app/_hub/kong-inc/oauth2-introspection/versions.yml +++ b/app/_hub/kong-inc/oauth2-introspection/versions.yml @@ -1,7 +1,12 @@ -- release: 1.3-x -- release: 0.36-x -- release: 0.35-x -- release: 0.34-x -- release: 0.33-x -- release: 0.32-x -- release: 0.31-x +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 0.5.4 + 2.7.x: 0.5.3 + 2.6.x: 0.5.2 + 2.5.x: 0.5.2 + 2.4.x: 0.5.2 + 2.3.x: 0.5.2 + 2.2.x: 0.5.0 + 2.1.x: 0.5.0 diff --git a/app/_hub/kong-inc/oauth2/0.1.x.md b/app/_hub/kong-inc/oauth2/0.1.x.md deleted file mode 100644 index 81f00ec72fb6..000000000000 --- a/app/_hub/kong-inc/oauth2/0.1.x.md +++ /dev/null @@ -1,373 +0,0 @@ ---- -name: OAuth 2.0 Authentication -publisher: Kong Inc. -version: 0.1-x - -desc: Add OAuth 2.0 authentication to your APIs -description: | - Add an OAuth 2.0 authentication layer with the [Authorization Code Grant](https://tools.ietf.org/html/rfc6749#section-4.1), [Client Credentials](https://tools.ietf.org/html/rfc6749#section-4.4), - [Implicit Grant](https://tools.ietf.org/html/rfc6749#section-4.2) or [Resource Owner Password Credentials Grant](https://tools.ietf.org/html/rfc6749#section-4.3) flow. - - ---- - -
- Note: As per the OAuth2 specs, this plugin requires the - underlying service to be served over HTTPS. To avoid any - confusion, we recommend that you configure the Route used to serve the - underlying Service to only accept HTTPS traffic (via its `protocols` - property). -
- -
- Note: The functionality of this plugin as bundled - with versions of Kong prior to 0.12.0 - differs from what is documented herein. Refer to the - CHANGELOG - for details. -
- - - -type: plugin -categories: - - authentication - -kong_version_compatibility: - community_edition: - compatible: - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x - - 0.4.x - enterprise_edition: - compatible: - - 0.34-x - - 0.33-x - - 0.32-x - - 0.31-x - -params: - name: oauth2 - api_id: true - service_id: true - route_id: false - consumer_id: false - yaml_examples: false - konnect_examples: false - config: - - name: scopes - required: true - default: - value_in_examples: email,phone,address - description: Describes an array of comma separated scope names that will be available to the end user - - name: mandatory_scope - required: false - default: "`false`" - value_in_examples: true - description: An optional boolean value telling the plugin to require at least one scope to be authorized by the end user - - name: token_expiration - required: false - default: "`7200`" - description: | - An optional integer value telling the plugin how many seconds a token should last, after which the client will need to refresh the token. Set to `0` to disable the expiration. - - name: enable_authorization_code - required: false - default: "`false`" - value_in_examples: true - description: | - An optional boolean value to enable the three-legged Authorization Code flow ([RFC 6742 Section 4.1](https://tools.ietf.org/html/rfc6749#section-4.1)) - - name: enable_client_credentials - required: false - default: "`false`" - description: | - An optional boolean value to enable the Client Credentials Grant flow ([RFC 6742 Section 4.4](https://tools.ietf.org/html/rfc6749#section-4.4)) - - name: enable_implicit_grant - required: false - default: "`false`" - description: | - An optional boolean value to enable the Implicit Grant flow which allows to provision a token as a result of the authorization process ([RFC 6742 Section 4.2](https://tools.ietf.org/html/rfc6749#section-4.2)) - - name: enable_password_grant - required: false - default: "`false`" - description: | - An optional boolean value to enable the Resource Owner Password Credentials Grant flow ([RFC 6742 Section 4.3](https://tools.ietf.org/html/rfc6749#section-4.3)) - - name: auth_header_name - required: false - default: "`authorization`" - description: | - The name of the header supposed to carry the access token. Default: `authorization`. - - name: hide_credentials - required: false - default: "`false`" - description: | - An optional boolean value telling the plugin to show or hide the credential from the upstream service. If `true`, the plugin will strip the credential from the request (i.e. the header containing the client credentials) before proxying it. - - name: accept_http_if_already_terminated - required: false - default: "`false`" - description: | - Accepts HTTPs requests that have already been terminated by a proxy or load balancer and the `x-forwarded-proto: https` header has been added to the request. Only enable this option if the Kong server cannot be publicly accessed and the only entry-point is such proxy or load balancer. - - name: anonymous - required: false - default: - description: | - An optional string (consumer uuid) value to use as an "anonymous" consumer if authentication fails. If empty (default), the request will fail with an authentication failure `4xx`. Please note that this value must refer to the Consumer `id` attribute which is internal to Kong, and **not** its `custom_id`. - - name: global_credentials - required: false - default: "`false`" - description: | - An optional boolean value that allows to use the same OAuth credentials generated by the plugin with any other Service (or API) whose OAuth 2.0 plugin configuration also has `config.global_credentials=true`. - - name: refresh_token_ttl - required: false - default: "`1209600`" - description: | - An optional integer value telling the plugin how many seconds a token/refresh token pair is valid for, and can be used to generate a new access token. Default value is 2 weeks. Set to `0` to keep the token/refresh token pair indefinitely valid. - - extra: | -
-
The option config.refresh_token_ttl is only available from version 0.12.0 and later
-
- - Once applied, any user with a valid credential can access the Service/API. - To restrict usage to only some of the authenticated users, also add the - [ACL](/plugins/acl/) plugin (not covered here) and create whitelist or - blacklist groups of users. - ---- - -## Usage - -In order to use the plugin, you first need to create a consumer to associate one or more credentials to. The Consumer represents a developer using the upstream service. - -### Endpoints - -By default the OAuth 2.0 plugin listens on the following endpoints when a client consumes the underlying Service (or API) via the [proxy port][proxy-port]: - -Endpoint | description ---- | --- -`/oauth2/authorize` | The endpoint to the Authorization Server that provisions authorization codes for the [Authorization Code](https://tools.ietf.org/html/rfc6749#section-4.1) flow, or the access token when the [Implicit Grant](https://tools.ietf.org/html/rfc6749#section-4.2) flow is enabled. Only `POST` is supported. -`/oauth2/token` | The endpoint to the Authorization Server that provision access tokens. This is also the only endpoint to use for the [Client Credentials](https://tools.ietf.org/html/rfc6749#section-4.4) and [Resource Owner Password Credentials Grant](https://tools.ietf.org/html/rfc6749#section-4.3) flows. Only `POST` is supported. - -The clients trying to authorize and request access tokens must use these endpoints. Remember that the endpoints above must be combined with the right URI path or headers that you normally use to match a configured Route through Kong. - -### Create a Consumer - -You need to associate a credential to an existing [Consumer][consumer-object] object. To create a Consumer, you can execute the following request: - -```bash -$ curl -X POST http://kong:8001/consumers/ \ - --data "username=user123" \ - --data "custom_id=SOME_CUSTOM_ID" -``` - -parameter | default | description ---- | --- | --- -`username`
*semi-optional* | | The username of the consumer. Either this field or `custom_id` must be specified. -`custom_id`
*semi-optional* | | A custom identifier used to map the consumer to another database. Either this field or `username` must be specified. - -A [Consumer][consumer-object] can have many credentials. - -### Create an Application - -Then you can finally provision new OAuth 2.0 credentials (also called "OAuth applications") by making the following HTTP request: - -```bash -$ curl -X POST http://kong:8001/consumers/{consumer_id}/oauth2 \ - --data "name=Test%20Application" \ - --data "client_id=SOME-CLIENT-ID" \ - --data "client_secret=SOME-CLIENT-SECRET" \ - --data "redirect_uri=http://some-domain/endpoint/" -``` - -`consumer_id`: The [Consumer][consumer-object] entity to associate the credentials to - -form parameter | default | description ---- | --- | --- -`name` | | The name to associate to the credential. In OAuth 2.0 this would be the application name. -`client_id`
*optional* | | You can optionally set your own unique `client_id`. If missing, the plugin will generate one. -`client_secret`
*optional* | | You can optionally set your own unique `client_secret`. If missing, the plugin will generate one. -`redirect_uri` | | The URL in your app where users will be sent after authorization ([RFC 6742 Section 3.1.2](https://tools.ietf.org/html/rfc6749#section-3.1.2)) - -## Migrating Access Tokens - -If you are migrating your existing OAuth 2.0 applications and access tokens over to Kong, then you can: - -* Migrate consumers and applications by creating OAuth 2.0 applications as explained above. -* Migrate access tokens using the `/oauth2_tokens` endpoints in the Kong's Admin API. For example: - -```bash -$ curl -X POST http://kong:8001/oauth2_tokens \ - --data "credential_id=KONG-APPLICATION-ID" \ - --data "token_type=bearer" \ - --data "access_token=SOME-TOKEN" \ - --data "refresh_token=SOME-TOKEN" \ - --data "expires_in=3600" -``` - -form parameter | default | description ---- | --- | --- -`credential_id` | | The ID of the OAuth 2.0 application created on Kong. -`token_type`
*optional* | `bearer`| The [token type](https://tools.ietf.org/html/rfc6749#section-7.1). -`access_token`
*optional* | | You can optionally set your own access token value, otherwise a random string will be generated. -`refresh_token`
*optional* | | You can optionally set your own unique refresh token value, otherwise a random string will be generated. -`expires_in` | | The expiration time (in seconds) of the access token. -`scope`
*optional* | | The authorized scope associated with the token. -`authenticated_userid`
*optional* | | The custom ID of the user who authorized the application. - -## Upstream Headers - -When a client has been authenticated and authorized, the plugin will append some headers to the request before proxying it to the upstream service, so that you can identify the consumer and the end-user in your code: - -* `X-Consumer-ID`, the ID of the Consumer on Kong -* `X-Consumer-Custom-ID`, the `custom_id` of the Consumer (if set) -* `X-Consumer-Username`, the `username` of the Consumer (if set) -* `X-Authenticated-Scope`, the comma-separated list of scopes that the end user has authenticated, if available (only if the consumer is not the 'anonymous' consumer) -* `X-Authenticated-Userid`, the logged-in user ID who has granted permission to the client (only if the consumer is not the 'anonymous' consumer) -* `X-Anonymous-Consumer`, will be set to `true` when authentication failed, and the 'anonymous' consumer was set instead. - -You can use this information on your side to implement additional logic. You can use the `X-Consumer-ID` value to query the Kong Admin API and retrieve more information about the Consumer. - ----- - -## OAuth 2.0 Flows - -### Client Credentials - -The [Client Credentials](https://tools.ietf.org/html/rfc6749#section-4.4) flow will work out of the box, without building any authorization page. The clients will need to use the `/oauth2/token` endpoint to request an access token. - -### Authorization Code - -After provisioning Consumers and associating OAuth 2.0 credentials to them, it is important to understand how the OAuth 2.0 authorization flow works. As opposed to most of the Kong plugins, the OAuth 2.0 plugin requires some little additional work on your side to make everything work well: - -* You **must** implement an authorization page on your web application, that will talk with the plugin server-side. -* *Optionally* you need to explain on your website/documentation how to consume your OAuth 2.0 protected services, so that developers accessing your service know how to build their client implementations - -#### The flow explained - -Building the authorization page is going to be the primary task that the plugin itself cannot do out of the box, because it requires to check that the user is properly logged in, and this operation is strongly tied with your authentication implementation. - -The authorization page is made of two parts: - -* The frontend page that the user will see, and that will allow him to authorize the client application to access his data -* The backend that will process the HTML form displayed in the frontend, that will talk with the OAuth 2.0 plugin on Kong, and that will ultimately redirect the user to a third party URL. - - - -A diagram representing this flow: - -
- -
- -1. The client application will redirect the end user to the authorization page on your web application, passing `client_id`, `response_type` and `scope` (if required) as querystring parameters. This is a sample authorization page: -
-
-
- -2. Before showing the actual authorization page, the web application will make sure that the user is logged in. - -3. The client application will send the `client_id` in the querystring, from which the web application can retrieve both the OAuth 2.0 application name, and developer name, by making the following request to Kong: - - ```bash - $ curl kong:8001/oauth2?client_id=XXX - ``` - -4. If the end user authorized the application, the form will submit the data to your backend with a `POST` request, sending the `client_id`, `response_type` and `scope` parameters that were placed in `` fields. - -5. The backend must add the `provision_key` and `authenticated_userid` parameters to the `client_id`, `response_type` and `scope` parameters and it will make a `POST` request to Kong at your API address, on the `/oauth2/authorize` endpoint. If an `Authorization` header has been sent by the client, that must be added too. The equivalent of: - - ```bash - $ curl https://your.api.com/oauth2/authorize \ - --header "Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW" \ - --data "client_id=XXX" \ - --data "response_type=XXX" \ - --data "scope=XXX" \ - --data "provision_key=XXX" \ - --data "authenticated_userid=XXX" - ``` - - The `provision_key` is the key the plugin has generated when it has been added to the Service (or API) while `authenticated_userid` is the ID of the logged-in end user who has granted the permission. - -6. Kong will respond with a JSON response: - - ```json - { - "redirect_uri": "http://some/url" - } - ``` - - With either a `200 OK` or `400 Bad Request` response code depending if the request was successful or not. -7. In **both** cases, ignore the response status code and just redirect the user to whatever URI is being returned in the `redirect_uri` property. - -8. The client application will take it from here, and will continue the flow with Kong with no other interaction with your web application. Like exchanging the authorization code for an access token if it's an Authorization Code Grant flow. - -9. Once the Access Token has been retrieved, the client application will make requests on behalf of the user to your upstream service. - -10. Access Tokens can expire, and when that happens the client application needs to renew the Access Token with Kong and retrieve a new one. - -In this flow, the steps that you need to implement are: - -* The login page, you probably already have it (step 2) -* The Authorization page, with its backend that will simply collect the values, make a `POST` request to Kong and redirect the user to whatever URL Kong has returned (steps 3 to 7). - ----- - -## Resource Owner Password Credentials - -The [Resource Owner Password Credentials Grant](https://tools.ietf.org/html/rfc6749#section-4.3) is a much simpler version of the Authorization Code flow, but it still requires to build an authorization backend (without the frontend) in order to make it work properly. - -![OAuth 2.0 Flow](/assets/images/docs/oauth2/oauth2-flow2.png) - -1. On the first request, the client application make a request including some OAuth2 parameters, including `username` and `password` parameters, to your web-application. - -2. The backend of your web-application will authenticate the `username` and `password` sent by the client, and if successful will add the `provision_key`, `authenticated_userid` and `grant_type` parameters to the parameters originally sent by the client, and it will make a `POST` request to Kong at, on the `/oauth2/token` endpoint of the configured plugin. If an `Authorization` header has been sent by the client, that must be added too. The equivalent of: - - ```bash - $ curl https://your.api.com/oauth2/token \ - --header "Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW" \ - --data "client_id=XXX" \ - --data "client_secret=XXX" \ - --data "grant_type=password" \ - --data "scope=XXX" \ - --data "provision_key=XXX" \ - --data "authenticated_userid=XXX" \ - --data "username=XXX" \ - --data "password=XXX" - ``` - - The `provision_key` is the key the plugin has generated when it has been added to the Service (or API), while `authenticated_userid` is the ID of the end user whose `username` and `password` belong to. - -3. Kong will respond with a JSON response - -4. The JSON response sent by Kong must be sent back to the original client as it is. If the operation is successful, this response will include an access token, otherwise it will include an error. - -In this flow, the steps that you need to implement are: - -* The backend endpoint that will process the original request and will authenticate the `username` and `password` values sent by the client, and if the authentication is successful, make the request to Kong and return back to the client whatever response Kong has sent back. - ----- - -## Refresh Token - -When your access token expires, you can generate a new access token using the refresh token you received in conjunction to your expired access token. - -```bash -$ curl -X POST https://your.api.com/oauth2/token \ - --data "grant_type=refresh_token" \ - --data "client_id=XXX" \ - --data "client_secret=XXX" \ - --data "refresh_token=XXX" -``` - -[consumer-object]: /gateway/latest/admin-api/#consumer-object -[proxy-port]: https://docs.konghq.com/latest/configuration/#proxy_listen diff --git a/app/_hub/kong-inc/oauth2/1.0.x.md b/app/_hub/kong-inc/oauth2/1.0.x.md deleted file mode 100644 index f1399820b0fb..000000000000 --- a/app/_hub/kong-inc/oauth2/1.0.x.md +++ /dev/null @@ -1,434 +0,0 @@ ---- -name: OAuth 2.0 Authentication -publisher: Kong Inc. -version: 1.0-x - -desc: Add OAuth 2.0 authentication to your Services -description: | - Add an OAuth 2.0 authentication layer with the [Authorization Code Grant](https://tools.ietf.org/html/rfc6749#section-4.1), [Client Credentials](https://tools.ietf.org/html/rfc6749#section-4.4), - [Implicit Grant](https://tools.ietf.org/html/rfc6749#section-4.2) or [Resource Owner Password Credentials Grant](https://tools.ietf.org/html/rfc6749#section-4.3) flow. - - ---- - -
- Note: As per the OAuth2 specs, this plugin requires the - underlying service to be served over HTTPS. To avoid any - confusion, we recommend that you configure the Route used to serve the - underlying Service to only accept HTTPS traffic (via its `protocols` - property). -
- -
- Note: The functionality of this plugin as bundled - with versions of Kong prior to 0.12.0 - differs from what is documented herein. Refer to the - CHANGELOG - for details. -
- - - -type: plugin -categories: - - authentication - -kong_version_compatibility: - community_edition: - compatible: - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x - - 0.4.x - enterprise_edition: - compatible: - - 1.5.x - - 1.3-x - - 0.36-x - - 0.35-x - - 0.34-x - - 0.33-x - - 0.32-x - - 0.31-x - -params: - name: oauth2 - service_id: true - route_id: false - consumer_id: false - protocols: ["http", "https"] - yaml_examples: false - konnect_examples: false - dbless_compatible: no - dbless_explanation: | - For its regular work, the plugin needs to both generate and delete tokens, and commit those changes to the database, which is not compatible with DB-less. - - In addition to this, its Admin API endpoints offer several POST, PATCH, PUT and DELETE methods for tokens and credentials. None of them would work on DB-less. - config: - - name: scopes - required: true - default: - value_in_examples: [ "email", "phone", "address" ] - description: Describes an array of scope names that will be available to the end user - - name: mandatory_scope - required: false - default: "`false`" - value_in_examples: true - description: An optional boolean value telling the plugin to require at least one scope to be authorized by the end user - - name: token_expiration - required: false - default: "`7200`" - description: | - An optional integer value telling the plugin how many seconds a token should last, after which the client will need to refresh the token. Set to `0` to disable the expiration. - - name: enable_authorization_code - required: false - default: "`false`" - value_in_examples: true - description: | - An optional boolean value to enable the three-legged Authorization Code flow ([RFC 6742 Section 4.1](https://tools.ietf.org/html/rfc6749#section-4.1)) - - name: enable_client_credentials - required: false - default: "`false`" - description: | - An optional boolean value to enable the Client Credentials Grant flow ([RFC 6742 Section 4.4](https://tools.ietf.org/html/rfc6749#section-4.4)) - - name: enable_implicit_grant - required: false - default: "`false`" - description: | - An optional boolean value to enable the Implicit Grant flow which allows to provision a token as a result of the authorization process ([RFC 6742 Section 4.2](https://tools.ietf.org/html/rfc6749#section-4.2)) - - name: enable_password_grant - required: false - default: "`false`" - description: | - An optional boolean value to enable the Resource Owner Password Credentials Grant flow ([RFC 6742 Section 4.3](https://tools.ietf.org/html/rfc6749#section-4.3)) - - name: auth_header_name - required: false - default: "`authorization`" - description: | - The name of the header supposed to carry the access token. Default: `authorization`. - - name: hide_credentials - required: false - default: "`false`" - description: | - An optional boolean value telling the plugin to show or hide the credential from the upstream service. If `true`, the plugin will strip the credential from the request (i.e. the header containing the client credentials) before proxying it. - - name: accept_http_if_already_terminated - required: false - default: "`false`" - description: | - Accepts HTTPs requests that have already been terminated by a proxy or load balancer and the `x-forwarded-proto: https` header has been added to the request. Only enable this option if the Kong server cannot be publicly accessed and the only entry-point is such proxy or load balancer. - - name: anonymous - required: false - default: - description: | - An optional string (consumer uuid) value to use as an "anonymous" consumer if authentication fails. If empty (default), the request will fail with an authentication failure `4xx`. Please note that this value must refer to the Consumer `id` attribute which is internal to Kong, and **not** its `custom_id`. - - name: global_credentials - required: false - default: "`false`" - description: | - An optional boolean value that allows to use the same OAuth credentials generated by the plugin with any other Service whose OAuth 2.0 plugin configuration also has `config.global_credentials=true`. - - name: refresh_token_ttl - required: false - default: "`1209600`" - description: | - An optional integer value telling the plugin how many seconds a token/refresh token pair is valid for, and can be used to generate a new access token. Default value is 2 weeks. Set to `0` to keep the token/refresh token pair indefinitely valid. - - extra: | -
-
The option config.refresh_token_ttl is only available from version 0.12.0 and later
-
- - Once applied, any user with a valid credential can access the Service. - To restrict usage to only some of the authenticated users, also add the - [ACL](/plugins/acl/) plugin (not covered here) and create whitelist or - blacklist groups of users. - ---- - -## Usage - -In order to use the plugin, you first need to create a consumer to associate one or more credentials to. The Consumer represents a developer using the upstream service. - -
- Note: This plugin requires a database in order to work effectively. It *does not* work on DB-Less mode. -
- -### Endpoints - -By default the OAuth 2.0 plugin listens on the following endpoints when a client consumes the underlying Service via the [proxy port][proxy-port]: - -Endpoint | description ---- | --- -`/oauth2/authorize` | The endpoint to the Authorization Server that provisions authorization codes for the [Authorization Code](https://tools.ietf.org/html/rfc6749#section-4.1) flow, or the access token when the [Implicit Grant](https://tools.ietf.org/html/rfc6749#section-4.2) flow is enabled. Only `POST` is supported. -`/oauth2/token` | The endpoint to the Authorization Server that provision access tokens. This is also the only endpoint to use for the [Client Credentials](https://tools.ietf.org/html/rfc6749#section-4.4) and [Resource Owner Password Credentials Grant](https://tools.ietf.org/html/rfc6749#section-4.3) flows. Only `POST` is supported. -`/oauth2_tokens` | The endpoint to the Authorization Server that allows creating new tokens. Useful on migrations (see below). -`/oauth2_tokens/:token_id` | The endpoint to the Authorization Server that allows reading, modifying and deleting access tokens. - -The clients trying to authorize and request access tokens must use these endpoints. Remember that the endpoints above must be combined with the right URI path or headers that you normally use to match a configured Route through Kong. - -### Create a Consumer - -You need to associate a credential to an existing [Consumer][consumer-object] object. To create a Consumer, you can execute the following request: - -```bash -$ curl -X POST http://kong:8001/consumers/ \ - --data "username=user123" \ - --data "custom_id=SOME_CUSTOM_ID" -``` - -parameter | default | description ---- | --- | --- -`username`
*semi-optional* | | The username of the consumer. Either this field or `custom_id` must be specified. -`custom_id`
*semi-optional* | | A custom identifier used to map the consumer to another database. Either this field or `username` must be specified. - -A [Consumer][consumer-object] can have many credentials. - -### Create an Application - -Then you can finally provision new OAuth 2.0 credentials (also called "OAuth applications") by making the following HTTP request: - -```bash -$ curl -X POST http://kong:8001/consumers/{consumer_id}/oauth2 \ - --data "name=Test%20Application" \ - --data "client_id=SOME-CLIENT-ID" \ - --data "client_secret=SOME-CLIENT-SECRET" \ - --data "redirect_uris=http://some-domain/endpoint/" -``` - -`consumer_id`: The [Consumer][consumer-object] entity to associate the credentials to - -form parameter | default | description ---- | --- | --- -`name` | | The name to associate to the credential. In OAuth 2.0 this would be the application name. -`client_id`
*optional* | | You can optionally set your own unique `client_id`. If missing, the plugin will generate one. -`client_secret`
*optional* | | You can optionally set your own unique `client_secret`. If missing, the plugin will generate one. -`redirect_uris` | | An array with one or more URLs in your app where users will be sent after authorization ([RFC 6742 Section 3.1.2](https://tools.ietf.org/html/rfc6749#section-3.1.2)) - -## Migrating Access Tokens - -If you are migrating your existing OAuth 2.0 applications and access tokens over to Kong, then you can: - -* Migrate consumers and applications by creating OAuth 2.0 applications as explained above. -* Migrate access tokens using the `/oauth2_tokens` endpoints in the Kong's Admin API. For example: - -```bash -$ curl -X POST http://kong:8001/oauth2_tokens \ - --data 'credential.id=KONG-APPLICATION-ID' \ - --data "token_type=bearer" \ - --data "access_token=SOME-TOKEN" \ - --data "refresh_token=SOME-TOKEN" \ - --data "expires_in=3600" -``` - -form parameter | default | description ---- | --- | --- -`credential` | | Contains the ID of the OAuth 2.0 application created on Kong. -`token_type`
*optional* | `bearer`| The [token type](https://tools.ietf.org/html/rfc6749#section-7.1). -`access_token`
*optional* | | You can optionally set your own access token value, otherwise a random string will be generated. -`refresh_token`
*optional* | | You can optionally set your own unique refresh token value, otherwise a random string will be generated. -`expires_in` | | The expiration time (in seconds) of the access token. -`scope`
*optional* | | The authorized scope associated with the token. -`authenticated_userid`
*optional* | | The custom ID of the user who authorized the application. - -## Viewing and Invalidating Access Tokens - -Active tokens can be listed and modified using the Admin API. A GET on the `/oauth2_tokens` endpoint returns the following: - -```bash -$ curl -sX GET http://kong:8001/oauth2_tokens/ -{ - "total": 2, - "data": [ - { - "expires_in": 7200, - "created_at": 1523386491000, - "access_token": "FOEtUHwg0das9PhsasVmgMGbZn7nWSgK", - "credential_id": "2c74324f-fa2d-434b-b6de-bd138652158f", - "scope": "email", - "id": "610740e5-700a-45f0-889a-5c7f0422c48d", - "api_id": "898dfc5f-20f9-4315-a028-2ecb0193f834", - "token_type": "bearer" - }, - { - "expires_in": 7200, - "created_at": 1523386680000, - "access_token": "58eat7UHEiPOmjNb16uQAxt4vu3fbu95", - "credential_id": "2c74324f-fa2d-434b-b6de-bd138652158f", - "scope": "email", - "id": "edff2fc7-1634-4fb5-b714-de9435531e10", - "api_id": "898dfc5f-20f9-4315-a028-2ecb0193f834", - "token_type": "bearer" - } - ] -} -``` - -`credential_id` is the ID of the OAuth application at `kong:8001/consumers/{consumer_id}/oauth2` and `api_id` or `service_id` is the API or service that the token is valid for. - -Note that `expires_in` is static and does not decrement based on elapsed time: you must add it to `created_at` to calculate when the token will expire. - -`DELETE http://kong:8001/oauth2_tokens/` allows you to immediately invalidate a token if needed. - -## Upstream Headers - -When a client has been authenticated and authorized, the plugin will append some headers to the request before proxying it to the upstream service, so that you can identify the consumer and the end-user in your code: - -* `X-Consumer-ID`, the ID of the Consumer on Kong -* `X-Consumer-Custom-ID`, the `custom_id` of the Consumer (if set) -* `X-Consumer-Username`, the `username` of the Consumer (if set) -* `X-Authenticated-Scope`, the comma-separated list of scopes that the end user has authenticated, if available (only if the consumer is not the 'anonymous' consumer) -* `X-Authenticated-Userid`, the logged-in user ID who has granted permission to the client (only if the consumer is not the 'anonymous' consumer) -* `X-Anonymous-Consumer`, will be set to `true` when authentication failed, and the 'anonymous' consumer was set instead. - -You can use this information on your side to implement additional logic. You can use the `X-Consumer-ID` value to query the Kong Admin API and retrieve more information about the Consumer. - ----- - -## OAuth 2.0 Flows - -### Client Credentials - -The [Client Credentials](https://tools.ietf.org/html/rfc6749#section-4.4) flow will work out of the box, without building any authorization page. The clients will need to use the `/oauth2/token` endpoint to request an access token. - -### Authorization Code - -After provisioning Consumers and associating OAuth 2.0 credentials to them, it is important to understand how the OAuth 2.0 authorization flow works. As opposed to most of the Kong plugins, the OAuth 2.0 plugin requires some little additional work on your side to make everything work well: - -* You **must** implement an authorization page on your web application, that will talk with the plugin server-side. -* *Optionally* you need to explain on your website/documentation how to consume your OAuth 2.0 protected services, so that developers accessing your service know how to build their client implementations - -#### The flow explained - -Building the authorization page is going to be the primary task that the plugin itself cannot do out of the box, because it requires to check that the user is properly logged in, and this operation is strongly tied with your authentication implementation. - -The authorization page is made of two parts: - -* The frontend page that the user will see, and that will allow him to authorize the client application to access his data -* The backend that will process the HTML form displayed in the frontend, that will talk with the OAuth 2.0 plugin on Kong, and that will ultimately redirect the user to a third party URL. - - - -A diagram representing this flow: - -
- -
- -1. The client application will redirect the end user to the authorization page on your web application, passing `client_id`, `response_type` and `scope` (if required) as querystring parameters. This is a sample authorization page: -
-
-
- -2. Before showing the actual authorization page, the web application will make sure that the user is logged in. - -3. The client application will send the `client_id` in the querystring, from which the web application can retrieve both the OAuth 2.0 application name, and developer name, by making the following request to Kong: - - ```bash - $ curl kong:8001/oauth2?client_id=XXX - ``` - -4. If the end user authorized the application, the form will submit the data to your backend with a `POST` request, sending the `client_id`, `response_type` and `scope` parameters that were placed in `` fields. - -5. The backend must add the `provision_key` and `authenticated_userid` parameters to the `client_id`, `response_type` and `scope` parameters and it will make a `POST` request to Kong at your Service address, on the `/oauth2/authorize` endpoint. If an `Authorization` header has been sent by the client, that must be added too. The equivalent of: - - ```bash - $ curl https://your.service.com/oauth2/authorize \ - --header "Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW" \ - --data "client_id=XXX" \ - --data "response_type=XXX" \ - --data "scope=XXX" \ - --data "provision_key=XXX" \ - --data "authenticated_userid=XXX" - ``` - - The `provision_key` is the key the plugin has generated when it has been added to the Service while `authenticated_userid` is the ID of the logged-in end user who has granted the permission. - -6. Kong will respond with a JSON response: - - ```json - { - "redirect_uri": "http://some/url" - } - ``` - - With either a `200 OK` or `400 Bad Request` response code depending if the request was successful or not. -7. In **both** cases, ignore the response status code and just redirect the user to whatever URI is being returned in the `redirect_uri` property. - -8. The client application will take it from here, and will continue the flow with Kong with no other interaction with your web application. Like exchanging the authorization code for an access token if it's an Authorization Code Grant flow. - -9. Once the Access Token has been retrieved, the client application will make requests on behalf of the user to your upstream service. - -10. Access Tokens can expire, and when that happens the client application needs to renew the Access Token with Kong and retrieve a new one. - -In this flow, the steps that you need to implement are: - -* The login page, you probably already have it (step 2) -* The Authorization page, with its backend that will simply collect the values, make a `POST` request to Kong and redirect the user to whatever URL Kong has returned (steps 3 to 7). - ----- - -## Resource Owner Password Credentials - -The [Resource Owner Password Credentials Grant](https://tools.ietf.org/html/rfc6749#section-4.3) is a much simpler version of the Authorization Code flow, but it still requires to build an authorization backend (without the frontend) in order to make it work properly. - -![OAuth 2.0 Flow](/assets/images/docs/oauth2/oauth2-flow2.png) - -1. On the first request, the client application make a request including some OAuth2 parameters, including `username` and `password` parameters, to your web-application. - -2. The backend of your web-application will authenticate the `username` and `password` sent by the client, and if successful will add the `provision_key`, `authenticated_userid` and `grant_type` parameters to the parameters originally sent by the client, and it will make a `POST` request to Kong at, on the `/oauth2/token` endpoint of the configured plugin. If an `Authorization` header has been sent by the client, that must be added too. The equivalent of: - - ```bash - $ curl https://your.service.com/oauth2/token \ - --header "Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW" \ - --data "client_id=XXX" \ - --data "client_secret=XXX" \ - --data "grant_type=password" \ - --data "scope=XXX" \ - --data "provision_key=XXX" \ - --data "authenticated_userid=XXX" \ - --data "username=XXX" \ - --data "password=XXX" - ``` - - The `provision_key` is the key the plugin has generated when it has been added to the Service, while `authenticated_userid` is the ID of the end user whose `username` and `password` belong to. - -3. Kong will respond with a JSON response - -4. The JSON response sent by Kong must be sent back to the original client as it is. If the operation is successful, this response will include an access token, otherwise it will include an error. - -In this flow, the steps that you need to implement are: - -* The backend endpoint that will process the original request and will authenticate the `username` and `password` values sent by the client, and if the authentication is successful, make the request to Kong and return back to the client whatever response Kong has sent back. - ----- - -## Refresh Token - -When your access token expires, you can generate a new access token using the refresh token you received in conjunction to your expired access token. - -```bash -$ curl -X POST https://your.service.com/oauth2/token \ - --data "grant_type=refresh_token" \ - --data "client_id=XXX" \ - --data "client_secret=XXX" \ - --data "refresh_token=XXX" -``` - -[consumer-object]: /gateway/latest/admin-api/#consumer-object -[proxy-port]: https://docs.konghq.com/latest/configuration/#proxy_listen diff --git a/app/_hub/kong-inc/oauth2/_index.md b/app/_hub/kong-inc/oauth2/_index.md index 2e1f829cfe29..b7d1ef1a26e5 100644 --- a/app/_hub/kong-inc/oauth2/_index.md +++ b/app/_hub/kong-inc/oauth2/_index.md @@ -1,7 +1,6 @@ --- name: OAuth 2.0 Authentication publisher: Kong Inc. -version: 2.1.x desc: Add OAuth 2.0 authentication to your Services description: | Add an OAuth 2.0 authentication layer with the [Authorization Code Grant](https://tools.ietf.org/html/rfc6749#section-4.1), [Client Credentials](https://tools.ietf.org/html/rfc6749#section-4.4), @@ -22,25 +21,9 @@ categories: - authentication kong_version_compatibility: community_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x + compatible: true enterprise_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x + compatible: true params: name: oauth2 service_id: true @@ -212,9 +195,9 @@ The clients trying to authorize and request access tokens must use these endpoin You need to associate a credential to an existing [Consumer][consumer-object] object. To create a Consumer, you can execute the following request: ```bash -$ curl -X POST http://kong:8001/consumers/ \ - --data "username=user123" \ - --data "custom_id=SOME_CUSTOM_ID" +curl -X POST http://kong:8001/consumers/ \ + --data "username=user123" \ + --data "custom_id=SOME_CUSTOM_ID" ``` parameter | default | description @@ -229,12 +212,12 @@ A [Consumer][consumer-object] can have many credentials. Then you can finally provision new OAuth 2.0 credentials (also called "OAuth applications") by making the following HTTP request: ```bash -$ curl -X POST http://kong:8001/consumers/{consumer_id}/oauth2 \ - --data "name=Test%20Application" \ - --data "client_id=SOME-CLIENT-ID" \ - --data "client_secret=SOME-CLIENT-SECRET" \ - --data "redirect_uris=http://some-domain/endpoint/" \ - --data "hash_secret=true" +curl -X POST http://kong:8001/consumers/{consumer_id}/oauth2 \ + --data "name=Test%20Application" \ + --data "client_id=SOME-CLIENT-ID" \ + --data "client_secret=SOME-CLIENT-SECRET" \ + --data "redirect_uris=http://some-domain/endpoint/" \ + --data "hash_secret=true" ``` `consumer_id`: The [Consumer][consumer-object] entity to associate the credentials to @@ -255,12 +238,12 @@ If you are migrating your existing OAuth 2.0 applications and access tokens over * Migrate access tokens using the `/oauth2_tokens` endpoints in the Kong's Admin API. For example: ```bash -$ curl -X POST http://kong:8001/oauth2_tokens \ - --data 'credential.id=KONG-APPLICATION-ID' \ - --data "token_type=bearer" \ - --data "access_token=SOME-TOKEN" \ - --data "refresh_token=SOME-TOKEN" \ - --data "expires_in=3600" +curl -X POST http://kong:8001/oauth2_tokens \ + --data 'credential.id=KONG-APPLICATION-ID' \ + --data "token_type=bearer" \ + --data "access_token=SOME-TOKEN" \ + --data "refresh_token=SOME-TOKEN" \ + --data "expires_in=3600" ``` form parameter | default | description @@ -278,7 +261,11 @@ form parameter | default | description Active tokens can be listed and modified using the Admin API. A GET on the `/oauth2_tokens` endpoint returns the following: ```bash -$ curl -sX GET http://kong:8001/oauth2_tokens/ +curl -sX GET http://kong:8001/oauth2_tokens/ +``` + +Response: +```json { "total": 2, "data": [ @@ -356,9 +343,7 @@ The authorization page is made of two parts: A diagram representing this flow: -
- -
+![OAuth2 flow](/assets/images/docs/oauth2/oauth2-flow.png) 1. The client application will redirect the end user to the authorization page on your web application, passing `client_id`, `response_type` and `scope` (if required) as query string parameters. This is a sample authorization page:
@@ -370,7 +355,7 @@ A diagram representing this flow: 3. The client application will send the `client_id` in the query string, from which the web application can retrieve both the OAuth 2.0 application name, and developer name, by making the following request to Kong: ```bash - $ curl kong:8001/oauth2?client_id=XXX + curl kong:8001/oauth2?client_id=XXX ``` 4. If the end user authorized the application, the form will submit the data to your backend with a `POST` request, sending the `client_id`, `response_type` and `scope` parameters that were placed in `` fields. @@ -378,13 +363,13 @@ A diagram representing this flow: 5. The backend must add the `provision_key` and `authenticated_userid` parameters to the `client_id`, `response_type` and `scope` parameters and it will make a `POST` request to Kong at your Service address, on the `/oauth2/authorize` endpoint. If an `Authorization` header has been sent by the client, that must be added too. The equivalent of: ```bash - $ curl https://your.service.com/oauth2/authorize \ - --header "Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW" \ - --data "client_id=XXX" \ - --data "response_type=XXX" \ - --data "scope=XXX" \ - --data "provision_key=XXX" \ - --data "authenticated_userid=XXX" + curl https://your.service.com/oauth2/authorize \ + --header "Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW" \ + --data "client_id=XXX" \ + --data "response_type=XXX" \ + --data "scope=XXX" \ + --data "provision_key=XXX" \ + --data "authenticated_userid=XXX" ``` The `provision_key` is the key the plugin has generated when it has been added to the Service while `authenticated_userid` is the ID of the logged-in end user who has granted the permission. @@ -424,16 +409,16 @@ The [Resource Owner Password Credentials Grant](https://tools.ietf.org/html/rfc6 2. The backend of your web-application will authenticate the `username` and `password` sent by the client, and if successful will add the `provision_key`, `authenticated_userid` and `grant_type` parameters to the parameters originally sent by the client, and it will make a `POST` request to Kong at, on the `/oauth2/token` endpoint of the configured plugin. If an `Authorization` header has been sent by the client, that must be added too. The equivalent of: ```bash - $ curl https://your.service.com/oauth2/token \ - --header "Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW" \ - --data "client_id=XXX" \ - --data "client_secret=XXX" \ - --data "grant_type=password" \ - --data "scope=XXX" \ - --data "provision_key=XXX" \ - --data "authenticated_userid=XXX" \ - --data "username=XXX" \ - --data "password=XXX" + curl https://your.service.com/oauth2/token \ + --header "Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW" \ + --data "client_id=XXX" \ + --data "client_secret=XXX" \ + --data "grant_type=password" \ + --data "scope=XXX" \ + --data "provision_key=XXX" \ + --data "authenticated_userid=XXX" \ + --data "username=XXX" \ + --data "password=XXX" ``` The `provision_key` is the key the plugin has generated when it has been added to the Service, while `authenticated_userid` is the ID of the end user whose `username` and `password` belong to. @@ -453,11 +438,11 @@ In this flow, the steps that you need to implement are: When your access token expires, you can generate a new access token using the refresh token you received in conjunction to your expired access token. ```bash -$ curl -X POST https://your.service.com/oauth2/token \ - --data "grant_type=refresh_token" \ - --data "client_id=XXX" \ - --data "client_secret=XXX" \ - --data "refresh_token=XXX" +curl -X POST https://your.service.com/oauth2/token \ + --data "grant_type=refresh_token" \ + --data "client_id=XXX" \ + --data "client_secret=XXX" \ + --data "refresh_token=XXX" ``` ---- @@ -467,7 +452,7 @@ $ curl -X POST https://your.service.com/oauth2/token \ The same access tokens can be used by gRPC applications: ```bash -$ grpcurl -H 'authorization: bearer XXX' ... +grpcurl -H 'authorization: bearer XXX' ... ``` Note that the rest of the credentials flow uses HTTPS and not gRPC protocol. Depending on your application, you might have to configure the `oauth2` plugin on two separate routes: one under `protocols: ["https"]` and another under `protocols: ["grpcs"]`. @@ -475,6 +460,72 @@ Note that the rest of the credentials flow uses HTTPS and not gRPC protocol. De [consumer-object]: /gateway/latest/admin-api/#consumer-object [proxy-port]: https://docs.konghq.com/latest/configuration/#proxy_listen +## WebSocket requests +{:.badge .enterprise} + +This plugin cannot issue new tokens from a WebSocket route, because the request +will be rejected as an invalid WebSocket handshake. Therefore, to use this +plugin with WebSocket services, an additional non-WebSocket route must be used +to issue tokens. + +1. Create a WebSocket service: + ```bash + curl -X POST http://localhost:8001/services/ \ + --data "name=my-websocket-service" \ + --data "url=ws://my-websocket-backend:8080/" + ``` + +2. Attach a route to the service: + ```sh + curl -X POST http://localhost:8001/services/my-websocket-service/routes \ + --data "name=my-websocket-route" \ + --data "protocols=wss" \ + --data "hosts=my-websocket-hostname.com" \ + ``` + +3. Attach an OAuth2 plugin instance to the service: + + {:.note} + > **Note**: Setting `global_credentials=true` is necessary to allow tokens + created by other plugin instances. + + ```sh + curl -x POST http://localhost:8001/services/my-websocket-service/plugins \ + --data "name=oauth2" \ + --data "config.scopes=email" \ + --data "config.scopes=profile" \ + --data "config.global_credentials=true" + ``` + + +4. Create another route to handle token creation: + {:.note} + > **Note**: Adding a POST method matcher ensures that regular WebSocket + handshake requests will not match this route. + + ```sh + curl -X POST http://localhost:8001/routes \ + --data "name=my-websocket-token-helper" \ + --data "protocols=https" \ + --data "hosts=my-websocket-hostname.com" \ + --data "methods=POST" + ``` + +5. Finally, add the additional OAuth2 plugin instance, using the route: + + ```sh + curl -x POST http://localhost:8001/routes/my-websocket-token-helper/plugins \ + --data "name=oauth2" \ + --data "config.scopes=email" \ + --data "config.scopes=profile" \ + --data "config.global_credentials=true" + ``` + +Client token requests (for example: `POST https://my-websocket-hostname.com/oauth2/authorize`) +will be handled by the `oauth2` plugin instance attached to the `my-websocket-token-helper` +route, and tokens issued by this route can be used in the WebSocket handshake +request to the `my-websocket-route` route. + --- ## Changelog diff --git a/app/_hub/kong-inc/oauth2/versions.yml b/app/_hub/kong-inc/oauth2/versions.yml index dbabe2967461..f5899a2813f1 100644 --- a/app/_hub/kong-inc/oauth2/versions.yml +++ b/app/_hub/kong-inc/oauth2/versions.yml @@ -1,3 +1,12 @@ -- release: 2.1.x -- release: 1.0.x -- release: 0.1.x +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 2.2.0 + 2.7.x: 2.2.0 + 2.6.x: 2.2.0 + 2.5.x: 2.2.0 + 2.4.x: 2.2.0 + 2.3.x: 2.2.0 + 2.2.x: 2.1.0 + 2.1.x: 2.1.0 diff --git a/app/_hub/kong-inc/opa/0.1.x.md b/app/_hub/kong-inc/opa/0.1.x.md deleted file mode 100644 index 1f99b22ded44..000000000000 --- a/app/_hub/kong-inc/opa/0.1.x.md +++ /dev/null @@ -1,313 +0,0 @@ ---- -name: OPA -publisher: Kong Inc. -version: 0.1.x - -desc: Authorize requests against Open Policy Agent -description: | - Forward request to Open Policy Agent and process the request only if the - authorization policy allows for it. - - {:.note} - > To use this plugin in Konnect Cloud, - [upgrade your runtimes](/konnect/runtime-manager/upgrade) to at least - v2.4.1.1. - -enterprise: true -plus: true -type: plugin -categories: - - security - -kong_version_compatibility: - enterprise_edition: - compatible: - - 2.4.x - -params: - name: opa - service_id: true - route_id: true - consumer_id: false - protocols: ["http", "https"] - dbless_compatible: yes - config: - - name: opa_protocol - required: false - datatype: string - default: "`http`" - description: | - The protocol to use when talking to Open Policy Agent (OPA) server. Allowed protocols are `http` and `https`. - - name: opa_host - required: false - value_in_examples: localhost - datatype: string - default: "`localhost`" - description: | - The DNS name or IP address of the OPA server. - - name: opa_port - required: false - value_in_examples: 8181 - datatype: integer - default: "`8181`" - description: | - The port of the OPA server. - - name: opa_path - required: true - value_in_examples: - datatype: string - description: | - The HTTP path to use when making a request to the OPA server. This is usually the path to the policy and rule to evaluate, prefixed with `/v1/data/`. For example, - if you want to evaluate the `allow` rule inside `example.kong` package, then the path would be `/v1/data/example/kong/allowBoolean`. - - name: include_service_in_opa_input - required: false - datatype: boolean - default: false - description: | - If set to true, the Kong Gateway Service object in use for the current request is included as input to OPA. - - name: include_route_in_opa_input - required: false - datatype: boolean - default: false - description: | - If set to true, the Kong Gateway Route object in use for the current request is included as input to OPA. - - name: include_consumer_in_opa_input - required: false - datatype: boolean - default: false - description: | - If set to true, the Kong Gateway Consumer object in use for the current request (if any) is included as input to OPA. ---- - -## Usage - -### Set up an OPA server - -If you are not already running an OPA server, start one by following instructions -on [openpolicyagent.org](https://openpolicyagent.org). - -### Set up a dummy policy - -Create an `example.rego` file with the following content: - -```rego -package example - -default allow = false - -allowBoolean { - header_present -} - -header_present { - input.request.http.headers["my-secret-header"] == "open-sesame" -} - -allowDetailed = response { - header_present - response := { - "allow": true, - "headers": { - "header-from-opa": "accepted", - }, - } -} - -allowDetailed = response { - not header_present - response := { - "allow": false, - "status": 418, - "headers": { - "header-from-opa": "rejected", - }, - } -} -``` - -This policy allows the request to pass through if it contains the HTTP header -`my-secret-header` with value `open-sesame`. - - -Next, configure the policy with OPA: - -```bash -curl -XPUT localhost:8181/v1/policies/example --data-binary @example.rego -``` - -The above command uses OPA's default port 8181. It could be different for your -setup. - -### Set up Kong Gateway - -Set up a Route and Service in {{site.base_gateway}} and then enable the plugin: - -```bash -curl -X POST http://:8001/routes//plugins \ - --data "name=opa" \ - --data "config.opa_path=/v1/data/example/allowBoolean" \ - --data "config.opa_host=" -``` - -### Make a request - -Now, make a request to {{site.base_gateway}}: - -```bash -curl http://kong:8000/{proxy_path} -``` - -You will get a 403 response from the gateway because OPA has rejected the request. - -Next, make the same request providing the necessary header: - -```bash -curl http://kong:8000/{proxy_path} \ - -H 'my-secret-header: open-sesame' -``` - -This time you will get the response from your upstream service, as this request -is allowed by OPA. - -Next, update the plugin configuration to use `/v1/data/example/allowDetailed` as -`opa_path` and observe how the policy affects the response and proxied request. - -## OPA input structure - -The input to OPA has the following JSON structure: - -``` -{ - "input": { - "request": { # details about the request from client to Kong - "http": { - "host": "example.org", # host header used by the client to make the request - "port": "8000", # port to which the request was made - "tls": {}, # TLS details if the request was made on HTTPS and Kong terminated the TLS connection - "method": "GET", # HTTP method used in the request - "scheme": "http", # protocol used to make the request by the client, this can be either `http` or `https` - "querystring": { # Query string in the HTTP request as key-value pairs - "foo" : "bar", - "foo2" : "bar2", - }, - "headers": { # HTTP headers of the request - "accept-encoding": "gzip, deflate", - "connection": "keep-alive", - "accept": "*\\/*" - } - } - }, - "client_ip": "127.0.0.1",# client IP address as interpreted by Kong - "service": { # The Kong service resource to which this request will be forwarded to if OPA allows. Injected only if `include_service_in_opa_input` is set to `true`. - "host": "httpbin.org", - "created_at": 1612819937, - "connect_timeout": 60000, - "id": "e6fd8b19-89e5-44e6-8a2a-79e8bf3c31a5", - "protocol": "http", - "name": "foo", - "read_timeout": 60000, - "port": 80, - "updated_at": 1612819937, - "ws_id": "d6020dc4-67f5-4c62-8b45-e2f497c20f5c", - "retries": 5, - "write_timeout": 60000 - }, - "route": { # The Kong route that was matched for this request. Injected only if `include_route_in_opa_input` is set to `true`. - "id": "bc6d8617-76a7-441f-aa40-32eb1f5be9e6", - "paths": [ - "\\/" - ], - "protocols": [ - "http", - "https" - ], - "strip_path": true, - "created_at": 1612819949, - "ws_id": "d6020dc4-67f5-4c62-8b45-e2f497c20f5c", - "request_buffering": true, - "updated_at": 1612819949, - "preserve_host": false, - "regex_priority": 0, - "response_buffering": true, - "https_redirect_status_code": 426, - "path_handling": "v0", - "service": { - "id": "e6fd8b19-89e5-44e6-8a2a-79e8bf3c31a5" - } - }, - "consumer": { # Kong consumer that was used for authentication for this request. Injected only if `include_consumer_in_opa_input` is set to `true`. - "id": "bc6d8617-76a7-431f-aa40-32eb1f5be7e6", - "username": "kong-consumer-username" - } - } -} - -``` - -> Note that it is possible that Consumer and Service resources are not -present for any given request in {{site.base_gateway}}. - -## Expected response from OPA - -After OPA is done executing policies, the plugin expects the policy evaluation -result in one of the defined formats: boolean or object. Any other format -or a status code other than `200 OK` results in the plugin returning a -`500 Internal Server Error` to the client. - -### Boolean result - -OPA can return a `true` or `false` result after a policy evaluation. -This should suffice for most use cases. - -Examples: - -To allow the request to be processed further, OPA should send the following -response: - -```json -{ - "result": true -} -``` - -To deny the request and terminate its processing, OPA should send the following -response: - -```json -{ - "result": false -} -``` - -Any other fields in the response in this case are ignored. - -### Object result - -In this case, OPA returns an object instead of a boolean result. This -allows for injecting custom HTTP headers as well as changing the HTTP status code -for rejected requests. - -The plugin expects the following structure in the OPA response in this case: - -``` -{ - "result": { - "allow": , - "status": , - "headers": { - "": "", - "": "" - } - } -} -``` - -The only required field in this response is `result.allow`, which accepts a -`boolean` value. - -If `result.allow` is set to `true`, then the key-value pairs in `result.headers` (if any) -are injected into the request before it is forwarded to the upstream Service. - -If `result.allow` is set to `false`, then the key-value pairs in `result.headers` (if any) -are injected into the response and the status code of the response is set to `result.status`. -If `result.status` is absent then the default `403` status code is sent. diff --git a/app/_hub/kong-inc/opa/_index.md b/app/_hub/kong-inc/opa/_index.md index 08553a866a8e..975bce50d9b1 100644 --- a/app/_hub/kong-inc/opa/_index.md +++ b/app/_hub/kong-inc/opa/_index.md @@ -1,16 +1,11 @@ --- name: OPA publisher: Kong Inc. -version: 0.2.x desc: Authorize requests against Open Policy Agent description: | Forward request to Open Policy Agent and process the request only if the authorization policy allows for it. - {:.note} - > To use this plugin in Konnect Cloud, - [upgrade your runtimes](/konnect/runtime-manager/upgrade) to at least - v2.4.1.1. enterprise: true plus: true type: plugin @@ -18,12 +13,7 @@ categories: - security kong_version_compatibility: enterprise_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x + compatible: true params: name: opa service_id: true @@ -91,6 +81,13 @@ params: default: false description: | If set to true and the `Content-Type` header of the current request is `application/json`, the request body will be JSON decoded and the decoded struct is included as input to OPA. + - name: ssl_verify + required: true + datatype: boolean + default: true + description: | + If set to true, the OPA certificate will be verified according to the CA certificates specified in [lua_ssl_trusted_certificate](/gateway/latest/reference/configuration/#lua_ssl_trusted_certificate). + minimum_version: "3.0.x" --- ## Usage diff --git a/app/_hub/kong-inc/opa/versions.yml b/app/_hub/kong-inc/opa/versions.yml index 8f68dd8fa36b..8f296a7c1b71 100644 --- a/app/_hub/kong-inc/opa/versions.yml +++ b/app/_hub/kong-inc/opa/versions.yml @@ -1,2 +1,16 @@ -- release: 0.2.x -- release: 0.1.x +strategy: gateway + +releases: + - 3.0.x + - 2.8.x + - 2.7.x + - 2.6.x + - 2.5.x + - 2.4.x + +overrides: + 2.8.x: 0.2.0 + 2.7.x: 0.2.0 + 2.6.x: 0.2.0 + 2.5.x: 0.1.0 + 2.4.x: 0.1.0 diff --git a/app/_hub/kong-inc/openid-connect/2.0.x.md b/app/_hub/kong-inc/openid-connect/_2.0.x.md similarity index 100% rename from app/_hub/kong-inc/openid-connect/2.0.x.md rename to app/_hub/kong-inc/openid-connect/_2.0.x.md diff --git a/app/_hub/kong-inc/openid-connect/2.1.x.md b/app/_hub/kong-inc/openid-connect/_2.1.x.md similarity index 100% rename from app/_hub/kong-inc/openid-connect/2.1.x.md rename to app/_hub/kong-inc/openid-connect/_2.1.x.md diff --git a/app/_hub/kong-inc/openid-connect/2.2.x.md b/app/_hub/kong-inc/openid-connect/_2.2.x.md similarity index 100% rename from app/_hub/kong-inc/openid-connect/2.2.x.md rename to app/_hub/kong-inc/openid-connect/_2.2.x.md diff --git a/app/_hub/kong-inc/openid-connect/_index.md b/app/_hub/kong-inc/openid-connect/_index.md index 94dada11f29f..604a3b5be90d 100644 --- a/app/_hub/kong-inc/openid-connect/_index.md +++ b/app/_hub/kong-inc/openid-connect/_index.md @@ -262,8 +262,8 @@ params: Use the same array index when configuring related settings for the client. This field is _referenceable_, which means it can be securely stored as a - [secret](/gateway/latest/plan-and-deploy/security/secrets-management/getting-started) - in a vault. References must follow a [specific format](/gateway/latest/plan-and-deploy/security/secrets-management/reference-format). + [secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). - name: client_arg required: false default: null @@ -303,8 +303,8 @@ params: > the identity provider endpoints. This field is _referenceable_, which means it can be securely stored as a - [secret](/gateway/latest/plan-and-deploy/security/secrets-management/getting-started) - in a vault. References must follow a [specific format](/gateway/latest/plan-and-deploy/security/secrets-management/reference-format). + [secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). - name: client_jwk required: false default: (plugin managed) @@ -999,8 +999,8 @@ params: The session secret. This field is _referenceable_, which means it can be securely stored as a - [secret](/gateway/latest/plan-and-deploy/security/secrets-management/getting-started) - in a vault. References must follow a [specific format](/gateway/latest/plan-and-deploy/security/secrets-management/reference-format). + [secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). - name: disable_session required: false default: null @@ -1097,8 +1097,8 @@ params: If undefined, ACL authentication will not be performed. This requires Redis v6.0.0+. This field is _referenceable_, which means it can be securely stored as a - [secret](/gateway/latest/plan-and-deploy/security/secrets-management/getting-started) - in a vault. References must follow a [specific format](/gateway/latest/plan-and-deploy/security/secrets-management/reference-format). + [secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). - name: session_redis_password required: false default: (from kong) @@ -1109,8 +1109,8 @@ params: If undefined, no AUTH commands are sent to Redis. This field is _referenceable_, which means it can be securely stored as a - [secret](/gateway/latest/plan-and-deploy/security/secrets-management/getting-started) - in a vault. References must follow a [specific format](/gateway/latest/plan-and-deploy/security/secrets-management/reference-format). + [secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). - name: session_redis_auth required: false default: (from kong) @@ -1121,11 +1121,12 @@ params: If undefined, no AUTH commands are sent to Redis. {:.important} - > This field is deprecated and replaced with `session_redis_password`. The`session_redis_auth` - field will continue to work in a backwards compatible way, but it is recommended to use the - replacement field. - A deprecation warning will be logged in the log file, stating the field's deprecation and planned - removal in v3.x.x. + > In Kong Gateway 2.8.x, this field is deprecated and replaced with `session_redis_password`. + > The`session_redis_auth` field will continue to work in a backwards compatible way, + > but it is recommended to use the replacement field. + > + > Starting from Kong Gateway 3.0.0.0, this field has been removed. + - name: session_redis_connect_timeout required: false default: (from kong) @@ -1331,12 +1332,12 @@ params: datatype: array of string elements description: | Pass extra arguments from the client to the OpenID-Connect plugin. If arguments exist, the client can pass them using: - - Request Body + - Request Body - Query parameters - - This parameter can be used with `scope` values, like this: - `config.token_post_args_client=scope` + This parameter can be used with `scope` values, like this: + + `config.token_post_args_client=scope` In this case, the token would take the `scope` value from the query parameter or from the request body and send it to the token endpoint. - group: Token Endpoint Response Headers @@ -1649,12 +1650,17 @@ Below are descriptions of the record types. The JSON Web Key (JWK) record is specified in [RFC7517][jwk]. This record is used with the `config.client_jwk` when using `private_key_jwk` client authentication. -Here is an example of JWK record generated by the plugin itself (see: [JSON Web Key Set](#json-web-key-set): +Here is an example of JWK record generated by the plugin itself (see: [JSON Web Key Set](#json-web-key-set)): ```json {{ page.jwk }} ``` +The JWK private fields (`k`, `d`, `p`, `q`, `dp`, `dq`, `qi`, `oth`, `r`, `t`) are _referenceable_, +which means they can be securely stored as a +[secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) +in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). + ### Host Record The Host record used with the `config.session_redis_cluster_nodes` is simple. @@ -3381,7 +3387,10 @@ mean other gateways, load balancers, NATs, and such in front of Kong. If there i ## Changelog -### {{site.base_gateway}} 2.8.x (plugin version 2.2.1) +**{{site.base_gateway}} 3.0.x** +* The deprecated `session_redis_auth` field has been removed from the plugin. + +**{{site.base_gateway}} 2.8.x (plugin version 2.2.1)** * Added the `session_redis_username` and `session_redis_password` configuration parameters. @@ -3396,9 +3405,9 @@ parameters. and `session_redis_password` configuration fields are now marked as referenceable, which means they can be securely stored as [secrets](/gateway/latest/plan-and-deploy/security/secrets-management/getting-started) -in a vault. References must follow a [specific format](/gateway/latest/plan-and-deploy/security/secrets-management/reference-format). +in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). -### {{site.base_gateway}} 2.7.x (plugin version 2.2.0) +**{{site.base_gateway}} 2.7.x (plugin version 2.2.0)** * Starting with {{site.base_gateway}} 2.7.0.0, if keyring encryption is enabled, the `config.client_id`, `config.client_secret`, `config.session_auth`, and diff --git a/app/_hub/kong-inc/openid-connect/versions.yml b/app/_hub/kong-inc/openid-connect/versions.yml index 653311260c89..bc049b7d2f93 100644 --- a/app/_hub/kong-inc/openid-connect/versions.yml +++ b/app/_hub/kong-inc/openid-connect/versions.yml @@ -1,11 +1,20 @@ -- release: 2.3.x -- release: 2.2.x -- release: 2.1.x -- release: 2.0.x -- release: 1.5.x -- release: 1.3-x -- release: 0.35-x -- release: 0.34-x -- release: 0.33-x -- release: 0.32-x -- release: 0.31-x +strategy: gateway +delegate_releases: true +sources: + 2.7.x: _2.2.x + 2.6.x: _2.1.x + 2.5.x: _2.0.x + 2.4.x: _2.0.x + 2.3.x: _2.0.x + 2.2.x: _2.0.x + 2.1.x: _2.0.x + +overrides: + 2.8.x: 2.3.0 + 2.7.x: 2.2.0 + 2.6.x: 2.1.1 + 2.5.x: 1.8.7 + 2.4.x: 1.8.5 + 2.3.x: 1.8.5 + 2.2.x: 1.9.1 + 2.1.x: 1.9.1 diff --git a/app/_hub/kong-inc/opentelemetry/_index.md b/app/_hub/kong-inc/opentelemetry/_index.md new file mode 100644 index 000000000000..861c860b410f --- /dev/null +++ b/app/_hub/kong-inc/opentelemetry/_index.md @@ -0,0 +1,285 @@ +--- +name: OpenTelemetry +publisher: Kong Inc. +version: 0.1.0 +desc: Propagate spans and report space to a backend server through OTLP protocol. +description: | + Propagate distributed tracing spans and report low-level spans to a OTLP-compatible server. +type: plugin +categories: + - analytics-monitoring +kong_version_compatibility: + community_edition: + compatible: + - 3.0.x + enterprise_edition: + compatible: + - 3.0.x +params: + name: opentelemetry + konnect_examples: false + protocols: + - http + - https + dbless_compatible: 'yes' + config: + - name: endpoint + required: true + value_in_examples: 'http://opentelemetry.collector:4318/v1/traces' + datatype: string + description: | + The full HTTP(S) endpoint that Kong Gateway should send OpenTelemetry spans to. + The endpoint must be a [OTLP/HTTP](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/otlp.md#otlphttp) endpoint. + - name: headers + required: false + datatype: map + value_in_examples: + - X-Auth-Token:secret-token + description: | + The custom headers to be added in the HTTP request sent to the OTLP server. + It's useful to add the authentication headers (token) for the APM backend. + - name: resource_attributes + required: false + datatype: map + description: | + The attributes specified on this property are added to the OpenTelemetry resource object. + Kong follows the OpenTelemetry specification for [Semantic Attributes](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/semantic_conventions/README.md#service). + + The following attributes are automatically added to the resource object: + - `service.name`: The name of the service. This is `kong` by default. + - `service.version`: The version of Kong Gateway. + - `service.instance.id`: The node id of Kong Gateway. + + The default values for the above attributes can be overridden by specifying them in this property. For example, + to override the default value of `service.name` to `my-service`, you can specify `{ "service.name": "my-service" }`. + - name: batch_span_count + required: true + default: 200 + datatype: number + description: | + The number of spans to be sent in a single batch. + - name: batch_flush_delay + required: true + default: 3 + datatype: number + description: | + The delay, in seconds, between two consecutive batches. + - name: connect_timeout + default: 1000 + datatype: number + description: | + The timeout, in milliseconds, for the OTLP server connection. + - name: send_timeout + default: 5000 + datatype: number + description: | + The timeout, in milliseconds, for sending spans to the OTLP server. + - name: read_timeout + default: 5000 + datatype: number + description: | + The timeout, in milliseconds, for reading the response from the OTLP server. +--- + +The OpenTelemetry plugin is built on top of {{site.base_gateway}}'s tracing API +and is intended to be fully compatible with the OpenTelemetry specification. + +## Usage + +{:.note} +> **Note**: The OpenTelemetry plugin only works when {{site.base_gateway}}'s `opentelemetry_tracing` configuration is enabled. + +The OpenTelemetry plugin is fully compatible with the OpenTelemetry specification and can be used with any OpenTelemetry compatible backend. + +There are two ways to set up an OpenTelemetry backend: +* Using a OpenTelemetry compatible backend directly, like Jaeger (v1.35.0+) + All the vendors supported by OpenTelemetry are listed in the [OpenTelemetry's Vendor support](https://opentelemetry.io/vendors/). +* Using the OpenTelemetry Collector, which is middleware that can be used to proxy OpenTelemetry spans to a compatible backend. + You can view all the available OpenTelemetry Collector exporters at [open-telemetry/opentelemetry-collector-contrib](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter). + +### Set up {{site.base_gateway}} + +Enable the OpenTelemetry tracing capability in {{site.base_gateway}}'s configuration: + +- `opentelemetry_tracing = all`, Valid values can be found in the [Kong's configuration](/gateway/latest/reference/configuration/#opentelemetry_tracing). +- `opentelemetry_tracing_sampling_rate = 1.0`: Tracing instrumentation sampling rate. + Tracer samples a fixed percentage of all spans following the sampling rate. + Set the sampling rate to a lower value to reduce the impact of the instrumentation on {{site.base_gateway}}'s proxy performance in production. + +### Set up an OpenTelemetry compatible backend + +This section is optional if you are using a OpenTelemetry compatible APM vendor. +All the supported vendors are listed in the [OpenTelemetry's Vendor support](https://opentelemetry.io/vendors/). + +Jaeger [natively supports OpenTelemetry](https://www.jaegertracing.io/docs/features/#native-support-for-opentracing-and-opentelemetry) starting with v1.35 and can be used with the OpenTelemetry plugin. + +Deploy a Jaeger instance with Docker: + +```bash +docker run --name jaeger \ + -e COLLECTOR_OTLP_ENABLED=true \ + -p 16686:16686 \ + -p 4317:4317 \ + -p 4318:4318 \ + jaegertracing/all-in-one:1.36 +``` + +* The `COLLECTOR_OTLP_ENABLED` environment variable must be set to `true` to enable the OpenTelemetry Collector. + +* The `4318` port is the OTLP/HTTP port and the `4317` port is the OTLP/GRPC port that isn't supported by the OpenTelemetry plugin yet. + +### Set up a OpenTelemetry Collector + +This section is required if you are using an incompatible OpenTelemetry APM vendor. + +Create a config file (`otelcol.yaml`) for the OpenTelemetry Collector: + +```yaml +receivers: + otlp: + protocols: + grpc: + http: + +processors: + batch: + +exporters: + logging: + loglevel: debug + zipkin: + endpoint: "http://some.url:9411/api/v2/spans" + tls: + insecure: true + +service: + pipelines: + traces: + receivers: [otlp] + processors: [batch] + exporters: [logging, zipkin] +``` + +Run the OpenTelemetry Collector with Docker: + +```bash +docker run --name opentelemetry-collector + -p 4317:4317 \ + -p 4318:4318 \ + -p 55679:55679 \ + -v ./otelcol.yaml:/etc/otel-collector-config.yaml \ + otel/opentelemetry-collector-contrib:0.52.0 \ + --config=/etc/otel-collector-config.yaml +``` + +See the [OpenTelemetry Collector documentation](https://opentelemetry.io/docs/collector/configuration/) for more information. + +### Configure the OpenTelemetry plugin + +Enable the plugin: + +```bash +curl -X POST http://:8001/plugins \ + --data "name=opentelemetry" \ + --data "config.endpoint=http://:4318/v1/traces" \ + --data "config.resource_attributes.service.name=kong-dev" +``` + +## How the OpenTelemetry plugin functions + +This section describes how the OpenTelemetry plugin works. + +### Built-in tracing instrumentations + +{{site.base_gateway}} has a series of built-in tracing instrumentations +which are configured by the `opentelemetry_tracing` configuration. + +{{site.base_gateway}} creates a top-level span for each request by default when `opentelemetry_tracing` is enabled. + +The top level span has the following attributes: +- `http.method`: HTTP method +- `http.url`: HTTP URL +- `http.host`: HTTP host +- `http.scheme`: HTTP scheme (http or https) +- `http.flavor`: HTTP version +- `net.peer.ip`: Client IP address + + + +### Propagation + +The OpenTelemetry plugin propagates the following headers: +- `w3c`: [W3C trace context](https://www.w3.org/TR/trace-context/) +- `b3` and `b3-single`: [Zipkin headers](https://github.com/openzipkin/b3-propagation) +- `jaeger`: [Jaeger headers](https://www.jaegertracing.io/docs/client-libraries/#propagation-format) +- `ot`: [OpenTracing headers](https://github.com/opentracing/specification/blob/master/rfc/trace_identifiers.md) +- `datadog`: [Datadog headers](https://docs.datadoghq.com/tracing/agent/propagation/) (Enterprise only) + +The plugin detects the propagation format from the headers and will use the appropriate format to propagate the span context. +If no appropriate format is found, the plugin will fallback to the default format, which is `w3c`. + +### OTLP exporter + +The OpenTelemetry plugin implements the [OTLP/HTTP](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/otlp.md#otlphttp) exporter, which uses Protobuf payloads encoded in binary format and is sent via HTTP/1.1. + +`connect_timeout`, `read_timeout`, and `write_timeout` are used to set the timeouts for the HTTP request. + +`batch_span_count` and `batch_flush_delay` are used to set the maximum number of spans and the delay between two consecutive batches. + +## Customize OpenTelemetry spans as a developer + + + +The OpenTelemetry plugin is built on top of the {{site.base_gateway}} tracing PDK. + +It's possible to customize the spans and add your own spans through the universal tracing PDK. + +The following is an example for adding a custom span using {{site.base_gateway}}'s serverless plugin: + +1. Create a file named `custom-span.lua` with the following content: + + ```lua + -- Modify the root span + local root_span = kong.tracing.active_span() + root_span:set_attribute("custom.attribute", "custom value") + + -- Create a custom span + local span = kong.tracing.start_span("custom-span") + + -- Append attributes + span:set_attribute("custom.attribute", "custom value") + ``` + +2. Apply the Lua code using the `post-function` plugin using a cURL file upload: + + ```bash + curl -i -X POST http://:8001/plugins \ + -F "name=post-function" \ + -F "config.access[1]=@custom-span.lua" + + HTTP/1.1 201 Created + ... + ``` + +## Troubleshooting + +The OpenTelemetry spans are printed to the console when the log level is set to `debug` in the Kong configuration file. + +An example of debug logs output: + +```bash +2022/06/02 15:28:42 [debug] 650#0: *111 [lua] instrumentation.lua:302: runloop_log_after(): [tracing] collected 6 spans: +Span #1 name=GET /wrk duration=1502.994944ms attributes={"http.url":"/wrk","http.method":"GET","http.flavor":1.1,"http.host":"127.0.0.1","http.scheme":"http","net.peer.ip":"172.18.0.1"} +Span #2 name=rewrite phase: opentelemetry duration=0.391936ms +Span #3 name=router duration=0.013824ms +Span #4 name=access phase: cors duration=1500.824576ms +Span #5 name=cors: heavy works duration=1500.709632ms attributes={"username":"kongers"} +Span #6 name=balancer try #1 duration=0.99328ms attributes={"net.peer.ip":"104.21.11.162","net.peer.port":80} +``` + +## Known issues + +- Only supports the HTTP protocols (http/https) of {{site.base_gateway}}. +- May impact the performance of {{site.base_gateway}}. + It's recommended to set the sampling rate (`opentelemetry_tracing_sampling_rate`) + via Kong configuration file when using the OpenTelemetry plugin. diff --git a/app/_hub/kong-inc/opentelemetry/versions.yml b/app/_hub/kong-inc/opentelemetry/versions.yml new file mode 100644 index 000000000000..bd590d3e0ca8 --- /dev/null +++ b/app/_hub/kong-inc/opentelemetry/versions.yml @@ -0,0 +1,5 @@ +strategy: gateway +releases: + - 3.0.x +overrides: + 3.0.x: 0.1.0 diff --git a/app/_hub/kong-inc/openwhisk/0.1-x.md b/app/_hub/kong-inc/openwhisk/0.1-x.md deleted file mode 100644 index 16bcb8f0e3ef..000000000000 --- a/app/_hub/kong-inc/openwhisk/0.1-x.md +++ /dev/null @@ -1,300 +0,0 @@ ---- -name: Apache OpenWhisk -publisher: Kong Inc. -version: 0.1-x - -source_url: https://github.com/Kong/kong-plugin-openwhisk - -desc: Invoke and manage OpenWhisk actions from Kong -description: | - This plugin invokes - [OpenWhisk Action](https://github.com/openwhisk/openwhisk/blob/master/docs/actions.md). - It can be used in combination with other request plugins to secure, manage - or extend the function. - -type: plugin -categories: - - serverless - -installation: | - - You can either use the LuaRocks package manager to install the plugin - - ```bash - $ luarocks install kong-plugin-openwhisk - ``` - - or install it from [source](https://github.com/Kong/kong-plugin-openwhisk). - For more information on Plugin installation, please see the documentation - [Plugin Development - (un)Install your plugin](/gateway/latest/plugin-development/distribution/) - -params: - name: openwhisk - api_id: true - service_id: true - route_id: true - consumer_id: true - konnect_examples: false - config: - - name: host - required: true - default: - value_in_examples: OPENWHISK_HOST - description: Host of the OpenWhisk server. - - name: port - required: false - default: "`443`" - description: Port of the OpenWhisk server. - - name: path - required: true - default: - value_in_examples: PATH_TO_ACTION - description: | - The path to `Action` resource. - - name: action - required: true - default: - value_in_examples: ACTION_NAME - description: | - Name of the `Action` to be invoked by the plugin. - - name: service_token - required: true - default: - value_in_examples: AUTHENTICATION_TOKEN - description: The service token to access Openwhisk resources. - - name: https_verify - required: false - default: "`false`" - description: | - Set it to `true` to authenticate Openwhisk server. - - name: https - required: false - default: "`true`" - description: Use of HTTPS to connect with the OpenWhisk server. - - name: result - required: false - default: "`true`" - description: | - Return only the result of the `Action` invoked. - - name: timeout - required: false - default: "`60000`" - description: Timeout in milliseconds before aborting a connection to OpenWhisk server. - - name: keepalive - required: false - default: "`60000`" - description: Time in milliseconds for which an idle connection to OpenWhisk server will live before being closed. - - extra: | - Note: If `config.https_verify` is set as `true` then the server certificate - will be verified according to the CA certificates specified by the - `lua_ssl_trusted_certificate` directive in your Kong configuration. - ---- - -## Demonstration - -For this demonstration we are running Kong and -[Openwhisk platform](https://github.com/openwhisk/openwhisk) locally on a -Vagrant machine on a MacOS. - -1. Create a javascript Action `hello` with the following code snippet on the -Openwhisk platform using [`wsk cli`](https://github.com/openwhisk/openwhisk-cli). - - ```javascript - function main(params) { - var name = params.name || 'World'; - return {payload: 'Hello, ' + name + '!'}; - } - ``` - - ```bash - $ wsk action create hello hello.js - - ok: created action hello - ``` - -2. Create a Service or Route (or use the depreciated API entity) - - Create a Service. - - ```bash - $ curl -i -X POST http://localhost:8001/services/ \ - --data "name=openwhisk-test" \ - --data "url=http://example.com" - - HTTP/1.1 201 Created - ... - - ``` - - Create a Route that uses the Service. - - ```bash - $ curl -i -f -X POST http://localhost:8001/services/openwhisk-test/routes/ \ - --data "paths[]=/" - - HTTP/1.1 201 Created - ... - - ``` - - Or you could use the API entity. - - ```bash - $ curl -i -X POST http://localhost:8001/apis/ \ - --data "name=openwhisk-test" -d "hosts=example.com" \ - --data "upstream_url=http://example.com" - - HTTP/1.1 201 Created - ... - - ``` - -3. Enable the `openwhisk` plugin on the Route - -Plugins can be enabled on a Service or a Route. This example uses a Service. - - ```bash - $ curl -i -X POST http://localhost:8001/services/openwhisk-test/plugins \ - --data "name=openwhisk" \ - --data "config.host=192.168.33.13" \ - --data "config.service_token=username:key" \ - --data "config.action=hello" \ - --data "config.path=/api/v1/namespaces/guest" - - HTTP/1.1 201 Created - ... - - ``` - -4. Make a request to invoke the action - - **Without parameters** - - ```bash - $ curl -i -X POST http://localhost:8000/ -H "Host:example.com" - HTTP/1.1 200 OK - ... - - { - "payload": "Hello, World!" - } - ``` - - **Parameters as form-urlencoded** - - ```bash - $ curl -i -X POST http://localhost:8000/ -H "Host:example.com" --data "name=bar" - HTTP/1.1 200 OK - ... - - { - "payload": "Hello, bar!" - } - ``` - - **Parameters as JSON body** - - ```bash - $ curl -i -X POST http://localhost:8000/ -H "Host:example.com" \ - -H "Content-Type:application/json" --data '{"name":"bar"}' - HTTP/1.1 200 OK - ... - - { - "payload": "Hello, bar!" - } - ``` - - **Parameters as multipart form** - - ```bash - $ curl -i -X POST http://localhost:8000/ -H "Host:example.com" -F name=bar - HTTP/1.1 100 Continue - - HTTP/1.1 200 OK - ... - - { - "payload": "Hello, bar!" - } - ``` - - **Parameters as querystring** - - ```bash - $ curl -i -X POST http://localhost:8000/?name=foo -H "Host:example.com" - HTTP/1.1 200 OK - ... - - { - "payload": "Hello, foo!" - } - ``` - - **OpenWhisk metadata in response** - - When Kong's `config.result` is set to false, OpenWhisk's metadata will - be returned in response: - - ```bash - $ curl -i -X POST http://localhost:8000/?name=foo -H "Host:example.com" - HTTP/1.1 200 OK - ... - - { - "duration": 4, - "name": "hello", - "subject": "guest", - "activationId": "50218ff03f494f62abbde5dfd2fcc68a", - "publish": false, - "annotations": [{ - "key": "limits", - "value": { - "timeout": 60000, - "memory": 256, - "logs": 10 - } - }, { - "key": "path", - "value": "guest/hello" - }], - "version": "0.0.4", - "response": { - "result": { - "payload": "Hello, foo!" - }, - "success": true, - "status": "success" - }, - "end": 1491855076125, - "logs": [], - "start": 1491855076121, - "namespace": "guest" - } - ``` - ----- - -### Limitations - -#### Use a fake upstream service - -When using the OpenWhisk plugin, the response will be returned by the plugin -itself without proxying the request to any upstream service. This means that -a Service's `host`, `port`, `path` properties will be ignored, but must still -be specified for the entity to be validated by Kong. The `host` property in -particular must either be an IP address, or a hostname that gets resolved by -your nameserver. - -When the plugin is added to an API entity (which is deprecated as of 0.13.0), -it is the `upsream_url` property which must be specified and resolvable as well -(but ignored). - -#### Response plugins - -There is a known limitation in the system that prevents some response plugins -from being executed. We are planning to remove this limitation in the future. - -[api-object]: /gateway/latest/admin-api/#api-object diff --git a/app/_hub/kong-inc/openwhisk/_index.md b/app/_hub/kong-inc/openwhisk/_index.md index 450b16dc123e..02bda07c031f 100644 --- a/app/_hub/kong-inc/openwhisk/_index.md +++ b/app/_hub/kong-inc/openwhisk/_index.md @@ -1,9 +1,8 @@ --- name: Apache OpenWhisk publisher: Kong Inc. -version: 1.0.x -source_url: https://github.com/Kong/kong-plugin-openwhisk +source_code: https://github.com/Kong/kong-plugin-openwhisk desc: Invoke and manage OpenWhisk actions from Kong description: | @@ -22,7 +21,7 @@ installation: | You can either use the LuaRocks package manager to install the plugin ```bash - $ luarocks install kong-plugin-openwhisk + luarocks install kong-plugin-openwhisk ``` or install it from [source](https://github.com/Kong/kong-plugin-openwhisk). @@ -122,7 +121,7 @@ function main(params) { ``` ```bash -$ wsk action create hello hello.js +wsk action create hello hello.js ``` ``` @@ -137,7 +136,7 @@ ok: created action hello Create a service: ```bash -$ curl -i -X POST http://localhost:8001/services/ \ +curl -i -X POST http://localhost:8001/services/ \ --data "name=openwhisk-test" \ --data "url=http://example.com" ``` @@ -151,7 +150,7 @@ HTTP/1.1 201 Created Create a route that uses the service: ```bash -$ curl -i -f -X POST http://localhost:8001/services/openwhisk-test/routes/ \ +curl -i -f -X POST http://localhost:8001/services/openwhisk-test/routes/ \ --data "paths[]=/" ``` @@ -187,12 +186,12 @@ routes: Plugins can be enabled on a service or a route (or globally). This example uses a service. ```bash -$ curl -i -X POST http://localhost:8001/services/openwhisk-test/plugins \ - --data "name=openwhisk" \ - --data "config.host=192.168.33.13" \ - --data "config.service_token=username:key" \ - --data "config.action=hello" \ - --data "config.path=/api/v1/namespaces/guest" +curl -i -X POST http://localhost:8001/services/openwhisk-test/plugins \ + --data "name=openwhisk" \ + --data "config.host=192.168.33.13" \ + --data "config.service_token=username:key" \ + --data "config.action=hello" \ + --data "config.path=/api/v1/namespaces/guest" ``` Response: @@ -226,7 +225,7 @@ plugins: **Without parameters:** ```bash - $ curl -i -X POST http://localhost:8000/ -H "Host:example.com" + curl -i -X POST http://localhost:8000/ -H "Host:example.com" ``` Response: @@ -243,7 +242,7 @@ plugins: **Parameters as form-urlencoded:** ```bash - $ curl -i -X POST http://localhost:8000/ -H "Host:example.com" --data "name=bar" + curl -i -X POST http://localhost:8000/ -H "Host:example.com" --data "name=bar" ``` Response: ``` @@ -258,7 +257,7 @@ plugins: **Parameters as JSON body:** ```bash - $ curl -i -X POST http://localhost:8000/ -H "Host:example.com" \ + curl -i -X POST http://localhost:8000/ -H "Host:example.com" \ -H "Content-Type:application/json" --data '{"name":"bar"}' ``` Response: @@ -274,7 +273,7 @@ plugins: **Parameters as multipart form:** ```bash - $ curl -i -X POST http://localhost:8000/ -H "Host:example.com" -F name=bar + curl -i -X POST http://localhost:8000/ -H "Host:example.com" -F name=bar ``` Response: ``` @@ -291,9 +290,9 @@ plugins: **Parameters as querystring:** ```bash - $ curl -i -X POST http://localhost:8000/?name=foo -H "Host:example.com" + curl -i -X POST http://localhost:8000/?name=foo -H "Host:example.com" ``` -Response: + Response: ``` HTTP/1.1 200 OK ... @@ -309,9 +308,9 @@ Response: returned in the response. ```bash - $ curl -i -X POST http://localhost:8000/?name=foo -H "Host:example.com" + curl -i -X POST http://localhost:8000/?name=foo -H "Host:example.com" ``` -Response: + Response: ``` HTTP/1.1 200 OK ... diff --git a/app/_hub/kong-inc/openwhisk/versions.yml b/app/_hub/kong-inc/openwhisk/versions.yml deleted file mode 100644 index f56356207baf..000000000000 --- a/app/_hub/kong-inc/openwhisk/versions.yml +++ /dev/null @@ -1,2 +0,0 @@ -- release: 1.0-x -- release: 0.1-x diff --git a/app/_hub/kong-inc/prometheus/0.1-x.md b/app/_hub/kong-inc/prometheus/0.1-x.md deleted file mode 100644 index f5d7a9fe5c03..000000000000 --- a/app/_hub/kong-inc/prometheus/0.1-x.md +++ /dev/null @@ -1,200 +0,0 @@ ---- -name: Prometheus -publisher: Kong Inc. -version: 0.1-x - -desc: Expose metrics related to Kong and proxied upstream services in Prometheus exposition format -description: | - Expose metrics related to Kong and proxied upstream services in [Prometheus](https://prometheus.io/docs/introduction/overview/) exposition format, which can be scraped by a Prometheus Server. - -type: plugin -categories: - - analytics-monitoring - -kong_version_compatibility: - community_edition: - compatible: - - 0.14.x - enterprise_edition: - compatible: - -params: - name: prometheus - api_id: true - service_id: true - route_id: true - ---- - -Metrics are available on the Admin API at the `http://localhost:8001/metrics` -endpoint. Note that the URL to the Admin API will be specific to your -installation; see _Accessing the metrics_ below. - -This plugin records and exposes metrics at the node-level. Your Prometheus -server will need to discover all Kong nodes via a service discovery mechanism, -and consume data from each node's configured `/metric` endpoint. Kong nodes -that are set to proxy only (that is their Admin API has been disabled by -specifying `admin_listen = off`) will need to use a [custom Nginx -configuration template](/gateway/latest/reference/configuration/#custom-nginx-configuration) -to expose the metrics data. - -### Grafana dashboard - -Metrics exported by the plugin can be graphed in Grafana using a drop in -dashboard: [https://grafana.com/dashboards/7424](https://grafana.com/dashboards/7424). - -### Available metrics - -- **Status codes**: HTTP status codes returned by upstream services. - These are available per service and across all services. -- **Latencies Histograms**: Latency as measured at Kong: - - **Request**: Total time taken by Kong and upstream services to serve - requests. - - **Kong**: Time taken for Kong to route a request and run all configured - plugins. - - **Upstream**: Time taken by the upstream service to respond to requests. -- **Bandwidth**: Total Bandwidth (egress/ingress) flowing through Kong. - This metric is available per service and as a sum across all services. -- **DB reachability**: A gauge type with a value of 0 or 1, representing if DB - can be reached by a Kong node or not. -- **Connections**: Various Nginx connection metrics like active, reading, - writing, and number of accepted connections. - -Here is an example of output you could expect from the `/metrics` endpoint: - -```bash -$ curl -i http://localhost:8001/metrics -HTTP/1.1 200 OK -Server: openresty/1.11.2.5 -Date: Mon, 11 Jun 2018 01:39:38 GMT -Content-Type: text/plain; charset=UTF-8 -Transfer-Encoding: chunked -Connection: keep-alive -Access-Control-Allow-Origin: * - -# HELP kong_bandwidth_total Total bandwidth in bytes for all proxied requests in Kong -# TYPE kong_bandwidth_total counter -kong_bandwidth_total{type="egress"} 1277 -kong_bandwidth_total{type="ingress"} 254 -# HELP kong_bandwidth Total bandwidth in bytes consumed per service in Kong -# TYPE kong_bandwidth counter -kong_bandwidth{type="egress",service="google"} 1277 -kong_bandwidth{type="ingress",service="google"} 254 -# HELP kong_datastore_reachable Datastore reachable from Kong, 0 is unreachable -# TYPE kong_datastore_reachable gauge -kong_datastore_reachable 1 -# HELP kong_http_status_total HTTP status codes aggreggated across all services in Kong -# TYPE kong_http_status_total counter -kong_http_status_total{code="301"} 2 -# HELP kong_http_status HTTP status codes per service in Kong -# TYPE kong_http_status counter -kong_http_status{code="301",service="google"} 2 -# HELP kong_latency Latency added by Kong, total request time and upstream latency for each service in Kong -# TYPE kong_latency histogram -kong_latency_bucket{type="kong",service="google",le="00001.0"} 1 -kong_latency_bucket{type="kong",service="google",le="00002.0"} 1 -. -. -. -kong_latency_bucket{type="kong",service="google",le="+Inf"} 2 -kong_latency_bucket{type="request",service="google",le="00300.0"} 1 -kong_latency_bucket{type="request",service="google",le="00400.0"} 1 -. -. -kong_latency_bucket{type="request",service="google",le="+Inf"} 2 -kong_latency_bucket{type="upstream",service="google",le="00300.0"} 2 -kong_latency_bucket{type="upstream",service="google",le="00400.0"} 2 -. -. -kong_latency_bucket{type="upstream",service="google",le="+Inf"} 2 -kong_latency_count{type="kong",service="google"} 2 -kong_latency_count{type="request",service="google"} 2 -kong_latency_count{type="upstream",service="google"} 2 -kong_latency_sum{type="kong",service="google"} 2145 -kong_latency_sum{type="request",service="google"} 2672 -kong_latency_sum{type="upstream",service="google"} 527 -# HELP kong_latency_total Latency added by Kong, total request time and upstream latency aggreggated across all services in Kong -# TYPE kong_latency_total histogram -kong_latency_total_bucket{type="kong",le="00001.0"} 1 -kong_latency_total_bucket{type="kong",le="00002.0"} 1 -. -. -kong_latency_total_bucket{type="kong",le="+Inf"} 2 -kong_latency_total_bucket{type="request",le="00300.0"} 1 -kong_latency_total_bucket{type="request",le="00400.0"} 1 -. -. -kong_latency_total_bucket{type="request",le="+Inf"} 2 -kong_latency_total_bucket{type="upstream",le="00300.0"} 2 -kong_latency_total_bucket{type="upstream",le="00400.0"} 2 -. -. -. -kong_latency_total_bucket{type="upstream",le="+Inf"} 2 -kong_latency_total_count{type="kong"} 2 -kong_latency_total_count{type="request"} 2 -kong_latency_total_count{type="upstream"} 2 -kong_latency_total_sum{type="kong"} 2145 -kong_latency_total_sum{type="request"} 2672 -kong_latency_total_sum{type="upstream"} 527 -# HELP kong_nginx_http_current_connections Number of HTTP connections -# TYPE kong_nginx_http_current_connections gauge -kong_nginx_http_current_connections{state="accepted"} 8 -kong_nginx_http_current_connections{state="active"} 1 -kong_nginx_http_current_connections{state="handled"} 8 -kong_nginx_http_current_connections{state="reading"} 0 -kong_nginx_http_current_connections{state="total"} 8 -kong_nginx_http_current_connections{state="waiting"} 0 -kong_nginx_http_current_connections{state="writing"} 1 -# HELP kong_nginx_metric_errors_total Number of nginx-lua-prometheus errors -# TYPE kong_nginx_metric_errors_total counter -kong_nginx_metric_errors_total 0 -``` - -### Accessing the metrics - -In most configurations, the Kong Admin API will be behind a firewall or would -need to be set up to require authentication, here are a couple of options to -allow access to the `/metrics` endpoint to Prometheus. - - -1. Kong Gateway users can protect the admin `/metrics` endpoint with an - [RBAC user](/gateway/latest/admin-api/rbac/reference/) that the - Prometheus servers use to access the metric data. Access through any - firewalls would also need to be configured. - -2. You can proxy the Admin API through Kong itself then use plugins to limit - access. For example, you can create a route `/metrics` endpoint and have - Prometheus access this endpoint to slurp in the metrics while preventing - others from access it. The specifics of how this is configured will depend - on your specific setup. Read the docs [Securing the Admin - API](https://docs.konghq.com/latest/secure-admin-api/#kong-api-loopback) for - details. - -3. Finally, you could serve the content on a different port with a custom server - block using a [custom Nginx - template](/gateway/latest/reference/configuration/#custom-nginx-configuration) with Kong. - - The following block is an example custom nginx template which can be used - by Kong: - - ``` - server { - server_name kong_prometheus_exporter; - listen 0.0.0.0:9542; # can be any other port as well - - location / { - default_type text/plain; - content_by_lua_block { - local prometheus = require "kong.plugins.prometheus.exporter" - prometheus:collect() - } - } - - location /nginx_status { - internal; - access_log off; - stub_status; - } - } - ``` diff --git a/app/_hub/kong-inc/prometheus/1.6.0.md b/app/_hub/kong-inc/prometheus/1.6.0.md new file mode 100644 index 000000000000..6bf0648a486a --- /dev/null +++ b/app/_hub/kong-inc/prometheus/1.6.0.md @@ -0,0 +1,225 @@ +--- +name: Prometheus +publisher: Kong Inc. +version: 1.6.0 +desc: Expose metrics related to Kong and proxied upstream services in Prometheus exposition format +description: | + Expose metrics related to Kong and proxied upstream services in [Prometheus](https://prometheus.io/docs/introduction/overview/) exposition format, which can be scraped by a Prometheus Server. +type: plugin +categories: + - analytics-monitoring +kong_version_compatibility: + community_edition: + compatible: + - 2.8.x + enterprise_edition: + compatible: + - 2.8.x +params: + name: prometheus + service_id: true + route_id: false + protocols: + - http + - https + - tcp + - tls + - grpc + - grpcs + dbless_compatible: 'yes' + dbless_explanation: | + The database will always be reported as reachable in Prometheus with DB-less. + Additionally, the DB entity count metric (`kong_db_entities_total`) is not + emitted in DB-less mode. + config: + - name: per_consumer + required: false + datatype: boolean + default: '`false`' + description: | + A boolean value that determines if per-consumer metrics should be + collected. + If enabled, a `kong_http_consumer_status` metric is added to + exported metrics. +--- + +Metrics tracked by this plugin are available on both the Admin API and Status +API at the `http://localhost:PORT/metrics` +endpoint. Note that the URL to those APIs will be specific to your +installation, see [Accessing the metrics](#accessing-the-metrics). + +This plugin records and exposes metrics at the node level. Your Prometheus +server must discover all Kong nodes via a service discovery mechanism +and consume data from each node's configured `/metrics` endpoint. + +## Grafana dashboard + +Metrics exported by the plugin can be graphed in Grafana using a drop in +dashboard: [https://grafana.com/dashboards/7424](https://grafana.com/dashboards/7424). + +## Available metrics + +- **Status codes**: HTTP status codes returned by upstream services. + These are available per service, across all services, and per route per consumer. +- **Latencies Histograms**: Latency (in ms), as measured at Kong: + - **Request**: Total time taken by Kong and upstream services to serve + requests. + - **Kong**: Time taken for Kong to route a request and run all configured + plugins. + - **Upstream**: Time taken by the upstream service to respond to requests. +- **Bandwidth**: Total Bandwidth (egress/ingress) flowing through Kong. + This metric is available per service and as a sum across all services. +- **DB reachability**: A gauge type with a value of 0 or 1, which represents + whether DB can be reached by a Kong node. +- **Connections**: Various Nginx connection metrics like active, reading, + writing, and number of accepted connections. +- **Target Health**: The healthiness status (`healthchecks_off`, `healthy`, `unhealthy`, or `dns_error`) of targets + belonging to a given upstream as well as their subsystem (`http` or `stream`). +- **Dataplane Status**: The last seen timestamp, config hash, config sync status, and certificate expiration timestamp for +data plane nodes is exported to control plane. +- **Enterprise License Information**: The {{site.base_gateway}} license expiration date, features, and +license signature. Those metrics are only exported on {{site.base_gateway}}. +- **DB Entity Count** : A gauge metric that + measures the current number of database entities. +- **Number of Nginx timers** : A gauge metric that measures the total number of Nginx + timers, in Running or Pending state. + +Here is an example of output you could expect from the `/metrics` endpoint: + +```bash +$ curl -i http://localhost:8001/metrics +HTTP/1.1 200 OK +Server: openresty/1.15.8.3 +Date: Tue, 7 Jun 2020 16:35:40 GMT +Content-Type: text/plain; charset=UTF-8 +Transfer-Encoding: chunked +Connection: keep-alive +Access-Control-Allow-Origin: * + +# HELP kong_bandwidth Total bandwidth in bytes consumed per service/route in Kong +# TYPE kong_bandwidth counter +kong_bandwidth{type="egress",service="google",route="google.route-1"} 1277 +kong_bandwidth{type="ingress",service="google",route="google.route-1"} 254 +# HELP kong_nginx_timers Number of nginx timers +# TYPE kong_nginx_timers gauge +kong_nginx_timers{state="running"} 3 +kong_nginx_timers{state="pending"} 1 +# HELP kong_datastore_reachable Datastore reachable from Kong, 0 is unreachable +# TYPE kong_datastore_reachable gauge +kong_datastore_reachable 1 +# HELP kong_http_consumer_status HTTP status codes for customer per service/route in Kong +# TYPE kong_http_consumer_status counter +kong_http_consumer_status{service="s1",route="s1.route-1",code="200",consumer="CONSUMER_USERNAME"} 3 +# HELP kong_http_status HTTP status codes per service/route in Kong +# TYPE kong_http_status counter +kong_http_status{code="301",service="google",route="google.route-1"} 2 +# HELP kong_latency Latency added by Kong in ms, total request time and upstream latency for each service in Kong +# TYPE kong_latency histogram +kong_latency_bucket{type="kong",service="google",route="google.route-1",le="00001.0"} 1 +kong_latency_bucket{type="kong",service="google",route="google.route-1",le="00002.0"} 1 +. +. +. +kong_latency_bucket{type="kong",service="google",route="google.route-1",le="+Inf"} 2 +kong_latency_bucket{type="request",service="google",route="google.route-1",le="00300.0"} 1 +kong_latency_bucket{type="request",service="google",route="google.route-1",le="00400.0"} 1 +. +. +kong_latency_bucket{type="request",service="google",route="google.route-1",le="+Inf"} 2 +kong_latency_bucket{type="upstream",service="google",route="google.route-1",le="00300.0"} 2 +kong_latency_bucket{type="upstream",service="google",route="google.route-1",le="00400.0"} 2 +. +. +kong_latency_bucket{type="upstream",service="google",route="google.route-1",le="+Inf"} 2 +kong_latency_count{type="kong",service="google",route="google.route-1"} 2 +kong_latency_count{type="request",service="google",route="google.route-1"} 2 +kong_latency_count{type="upstream",service="google",route="google.route-1"} 2 +kong_latency_sum{type="kong",service="google",route="google.route-1"} 2145 +kong_latency_sum{type="request",service="google",route="google.route-1"} 2672 +kong_latency_sum{type="upstream",service="google",route="google.route-1"} 527 +# HELP kong_nginx_http_current_connections Number of HTTP connections +# TYPE kong_nginx_http_current_connections gauge +kong_nginx_http_current_connections{state="accepted"} 8 +kong_nginx_http_current_connections{state="active"} 1 +kong_nginx_http_current_connections{state="handled"} 8 +kong_nginx_http_current_connections{state="reading"} 0 +kong_nginx_http_current_connections{state="total"} 8 +kong_nginx_http_current_connections{state="waiting"} 0 +kong_nginx_http_current_connections{state="writing"} 1 +# HELP kong_memory_lua_shared_dict_bytes Allocated slabs in bytes in a shared_dict +# TYPE kong_memory_lua_shared_dict_bytes gauge +kong_memory_lua_shared_dict_bytes{shared_dict="kong",kong_subsystem="http"} 40960 +. +. +# HELP kong_memory_lua_shared_dict_total_bytes Total capacity in bytes of a shared_dict +# TYPE kong_memory_lua_shared_dict_total_bytes gauge +kong_memory_lua_shared_dict_total_bytes{shared_dict="kong",kong_subsystem="http"} 5242880 +. +. +# HELP kong_memory_workers_lua_vms_bytes Allocated bytes in worker Lua VM +# TYPE kong_memory_workers_lua_vms_bytes gauge +kong_memory_workers_lua_vms_bytes{pid="7281",kong_subsystem="http"} 41124353 +# HELP kong_data_plane_config_hash Config hash value of the data plane +# TYPE kong_data_plane_config_hash gauge +kong_data_plane_config_hash{node_id="d4e7584e-b2f2-415b-bb68-3b0936f1fde3",hostname="ubuntu-bionic",ip="127.0.0.1"} 1.7158931820287e+38 +# HELP kong_data_plane_last_seen Last time data plane contacted control plane +# TYPE kong_data_plane_last_seen gauge +kong_data_plane_last_seen{node_id="d4e7584e-b2f2-415b-bb68-3b0936f1fde3",hostname="ubuntu-bionic",ip="127.0.0.1"} 1600190275 +# HELP kong_data_plane_version_compatible Version compatible status of the data plane, 0 is incompatible +# TYPE kong_data_plane_version_compatible gauge +kong_data_plane_version_compatible{node_id="d4e7584e-b2f2-415b-bb68-3b0936f1fde3",hostname="ubuntu-bionic",ip="127.0.0.1",kong_version="2.4.1"} 1 +# HELP kong_nginx_metric_errors_total Number of nginx-lua-prometheus errors +# TYPE kong_nginx_metric_errors_total counter +kong_nginx_metric_errors_total 0 +# HELP kong_upstream_target_health Health status of targets of upstream. States = healthchecks_off|healthy|unhealthy|dns_error, value is 1 when state is populated. +kong_upstream_target_health{upstream="UPSTREAM_NAME",target="TARGET",address="IP:PORT",state="healthchecks_off",subsystem="http"} 0 +kong_upstream_target_health{upstream="UPSTREAM_NAME",target="TARGET",address="IP:PORT",state="healthy",subsystem="http"} 1 +kong_upstream_target_health{upstream="UPSTREAM_NAME",target="TARGET",address="IP:PORT",state="unhealthy",subsystem="http"} 0 +kong_upstream_target_health{upstream="UPSTREAM_NAME",target="TARGET",address="IP:PORT",state="dns_error",subsystem="http"} 0 +# HELP kong_db_entities_total Total number of Kong db entities +# TYPE kong_db_entities_total gauge +kong_db_entities_total 42 +# HELP kong_db_entity_count_errors Errors during entity count collection +# TYPE kong_db_entity_count_errors counter +kong_db_entity_count_errors 0 + +``` + +{:.note} +> **Note:** Upstream targets' health information is exported once per subsystem. If both +stream and HTTP listeners are enabled, targets' health will appear twice. Health metrics +have a `subsystem` label to indicate which subsystem the metric refers to. + +## Accessing the metrics + +In most configurations, the Kong Admin API will be behind a firewall or would +need to be set up to require authentication. Here are a couple of options to +allow access to the `/metrics` endpoint to Prometheus: + + +1. If the [Status API](/gateway/latest/reference/configuration/#status_listen) + is enabled, then its `/metrics` endpoint can be used. + This is the preferred method. + +1. The `/metrics` endpoint is also available on the Admin API, which can be used + if the Status API is not enabled. Note that this endpoint is unavailable + when [RBAC](/gateway/latest/admin-api/rbac/reference/) is enabled on the + Admin API (Prometheus does not support Key-Auth to pass the token). + +--- + +## Changelog + +### 1.6.x + +* Adds a new metric: + * `kong_nginx_timers` (gauge): total number of Nginx timers, in Running or Pending state. +* Add two new metrics: + * `kong_db_entities_total` (gauge): total number of entities in the database + * `kong_db_entity_count_errors` (counter): measures the number of errors + encountered during the measurement of `kong_db_entities_total` + +### 1.4.x + +* New `data_plane_cluster_cert_expiry_timestamp` metric +* Added `subsystem` label to Upstream Target health metrics diff --git a/app/_hub/kong-inc/prometheus/0.8.x.md b/app/_hub/kong-inc/prometheus/_0.8.x.md similarity index 100% rename from app/_hub/kong-inc/prometheus/0.8.x.md rename to app/_hub/kong-inc/prometheus/_0.8.x.md diff --git a/app/_hub/kong-inc/prometheus/_index.md b/app/_hub/kong-inc/prometheus/_index.md index 4c231cb2945e..54148b1690ab 100644 --- a/app/_hub/kong-inc/prometheus/_index.md +++ b/app/_hub/kong-inc/prometheus/_index.md @@ -1,20 +1,20 @@ --- name: Prometheus publisher: Kong Inc. -version: 1.6.0 -desc: Expose metrics related to Kong and proxied Upstream services in Prometheus exposition format +version: 3.0.0 +desc: Expose metrics related to Kong and proxied upstream services in Prometheus exposition format description: | - Expose metrics related to Kong and proxied Upstream services in [Prometheus](https://prometheus.io/docs/introduction/overview/) exposition format, which can be scraped by a Prometheus Server. + Expose metrics related to Kong and proxied upstream services in [Prometheus](https://prometheus.io/docs/introduction/overview/) exposition format, which can be scraped by a Prometheus Server. type: plugin categories: - analytics-monitoring kong_version_compatibility: community_edition: compatible: - - 2.8.x + - 3.0.x enterprise_edition: compatible: - - 2.8.x + - 3.0.x params: name: prometheus service_id: true @@ -39,8 +39,41 @@ params: description: | A boolean value that determines if per-consumer metrics should be collected. - If enabled, a `kong_http_consumer_status` metric is added to - exported metrics. + If enabled, the `kong_http_requests_total` and `kong_bandwidth_bytes` + metrics fill in the consumer label when available. + - name: status_code_metrics + required: false + datatype: boolean + default: '`false`' + description: | + A boolean value that determines if status code metrics should be + collected. + If enabled, `http_requests_total`, `stream_sessions_total` metrics will be exported. + - name: lantency_metrics + required: false + datatype: boolean + default: '`false`' + description: | + A boolean value that determines if status code metrics should be + collected. + If enabled, `kong_latency_ms`, `upstream_latency_ms` and `request_latency_ms` + metrics will be exported. + - name: bandwidth_metrics + required: false + datatype: boolean + default: '`false`' + description: | + A boolean value that determines if status code metrics should be + collected. + If enabled, `bandwidth_bytes` and `stream_sessions_total` metrics will be exported. + - name: upstream_health_metrics + required: false + datatype: boolean + default: '`false`' + description: | + A boolean value that determines if status code metrics should be + collected. + If enabled, `upstream_target_health` metric will be exported. --- Metrics tracked by this plugin are available on both the Admin API and Status @@ -59,35 +92,50 @@ dashboard: [https://grafana.com/dashboards/7424](https://grafana.com/dashboards/ ## Available metrics -- **Status codes**: HTTP status codes returned by Upstream services. - These are available per service, across all services, and per route per consumer. -- **Latencies Histograms**: Latency in ms, as measured at Kong: - - **Request**: Total time taken by Kong and Upstream services to serve - requests. - - **Kong**: Time taken for Kong to route a request and run all configured - plugins. - - **Upstream**: Time taken by the Upstream service to respond to requests. -- **Bandwidth**: Total Bandwidth (egress/ingress) flowing through Kong. - This metric is available per service and as a sum across all services. - **DB reachability**: A gauge type with a value of 0 or 1, which represents whether DB can be reached by a Kong node. - **Connections**: Various Nginx connection metrics like active, reading, writing, and number of accepted connections. -- **Target Health**: The healthiness status (`healthchecks_off`, `healthy`, `unhealthy`, or `dns_error`) of Targets - belonging to a given Upstream as well as their subsystem (`http` or `stream`). - **Dataplane Status**: The last seen timestamp, config hash, config sync status and certificate expiration timestamp for data plane nodes is exported to control plane. - **Enterprise License Information**: The {{site.base_gateway}} license expiration date, features and license signature. Those metrics are only exported on {{site.base_gateway}}. - **DB Entity Count** : A gauge metric that measures the current number of database entities. -- **Number of Nginx timers** : A gauge metric that measures the total number of Nginx +- **Number of Nginx timers** : A gauge metric that measures the total number of Nginx timers, in Running or Pending state. +Following metrics are disabled by default as it may create high cardinality of metrics and may +cause performance issues: + +When `status_code_metrics` is set to true: +- **Status codes**: HTTP status codes returned by upstream services. + These are available per service, across all services, and per route per consumer. + +When `lantency_metrics` is set to true: +- **Latencies Histograms**: Latency (in ms), as measured at Kong: + - **Request**: Total time taken by Kong and upstream services to serve + requests. + - **Kong**: Time taken for Kong to route a request and run all configured + plugins. + - **Upstream**: Time taken by the upstream service to respond to requests. + +When `bandwidth_metrics` is set to true: +- **Bandwidth**: Total Bandwidth (egress/ingress) flowing through Kong. + This metric is available per service and as a sum across all services. + +When `upstream_health_metrics` is set to true: +- **Target Health**: The healthiness status (`healthchecks_off`, `healthy`, `unhealthy`, or `dns_error`) of targets + belonging to a given upstream as well as their subsystem (`http` or `stream`). + Here is an example of output you could expect from the `/metrics` endpoint: ```bash -$ curl -i http://localhost:8001/metrics +curl -i http://localhost:8001/metrics +``` + +Response: +```sh HTTP/1.1 200 OK Server: openresty/1.15.8.3 Date: Tue, 7 Jun 2020 16:35:40 GMT @@ -96,92 +144,128 @@ Transfer-Encoding: chunked Connection: keep-alive Access-Control-Allow-Origin: * -# HELP kong_bandwidth Total bandwidth in bytes consumed per service/route in Kong -# TYPE kong_bandwidth counter -kong_bandwidth{type="egress",service="google",route="google.route-1"} 1277 -kong_bandwidth{type="ingress",service="google",route="google.route-1"} 254 -# HELP kong_nginx_timers Number of nginx timers -# TYPE kong_nginx_timers gauge -kong_nginx_timers{state="running"} 3 -kong_nginx_timers{state="pending"} 1 +# HELP kong_bandwidth_bytes Total bandwidth (ingress/egress) throughput in bytes +# TYPE kong_bandwidth_bytes counter +kong_bandwidth_bytes{service="google",route="google.route-1",direction="egress",consumer=""} 264 +kong_bandwidth_bytes{service="google",route="google.route-1",direction="ingress",consumer=""} 93 # HELP kong_datastore_reachable Datastore reachable from Kong, 0 is unreachable # TYPE kong_datastore_reachable gauge kong_datastore_reachable 1 -# HELP kong_http_consumer_status HTTP status codes for customer per service/route in Kong -# TYPE kong_http_consumer_status counter -kong_http_consumer_status{service="s1",route="s1.route-1",code="200",consumer=""} 3 -# HELP kong_http_status HTTP status codes per service/route in Kong -# TYPE kong_http_status counter -kong_http_status{code="301",service="google",route="google.route-1"} 2 -# HELP kong_latency Latency added by Kong in ms, total request time and upstream latency for each service in Kong -# TYPE kong_latency histogram -kong_latency_bucket{type="kong",service="google",route="google.route-1",le="00001.0"} 1 -kong_latency_bucket{type="kong",service="google",route="google.route-1",le="00002.0"} 1 -. -. -. -kong_latency_bucket{type="kong",service="google",route="google.route-1",le="+Inf"} 2 -kong_latency_bucket{type="request",service="google",route="google.route-1",le="00300.0"} 1 -kong_latency_bucket{type="request",service="google",route="google.route-1",le="00400.0"} 1 -. -. -kong_latency_bucket{type="request",service="google",route="google.route-1",le="+Inf"} 2 -kong_latency_bucket{type="upstream",service="google",route="google.route-1",le="00300.0"} 2 -kong_latency_bucket{type="upstream",service="google",route="google.route-1",le="00400.0"} 2 -. -. -kong_latency_bucket{type="upstream",service="google",route="google.route-1",le="+Inf"} 2 -kong_latency_count{type="kong",service="google",route="google.route-1"} 2 -kong_latency_count{type="request",service="google",route="google.route-1"} 2 -kong_latency_count{type="upstream",service="google",route="google.route-1"} 2 -kong_latency_sum{type="kong",service="google",route="google.route-1"} 2145 -kong_latency_sum{type="request",service="google",route="google.route-1"} 2672 -kong_latency_sum{type="upstream",service="google",route="google.route-1"} 527 -# HELP kong_nginx_http_current_connections Number of HTTP connections -# TYPE kong_nginx_http_current_connections gauge -kong_nginx_http_current_connections{state="accepted"} 8 -kong_nginx_http_current_connections{state="active"} 1 -kong_nginx_http_current_connections{state="handled"} 8 -kong_nginx_http_current_connections{state="reading"} 0 -kong_nginx_http_current_connections{state="total"} 8 -kong_nginx_http_current_connections{state="waiting"} 0 -kong_nginx_http_current_connections{state="writing"} 1 +# HELP kong_http_requests_total HTTP status codes per consumer/service/route in Kong +# TYPE kong_http_requests_total counter +kong_http_requests_total{service="google",route="google.route-1",code="200",source="service",consumer=""} 1 +# HELP kong_node_info Kong Node metadata information +# TYPE kong_node_info gauge +kong_node_info{node_id="849373c5-45c1-4c1d-b595-fdeaea6daed8",version="3.0.0"} 1 +# HELP kong_kong_latency_ms Latency added by Kong and enabled plugins for each service/route in Kong +# TYPE kong_kong_latency_ms histogram +kong_kong_latency_ms_bucket{service="google",route="google.route-1",le="5"} 1 +kong_kong_latency_ms_bucket{service="google",route="google.route-1",le="7"} 1 +kong_kong_latency_ms_bucket{service="google",route="google.route-1",le="10"} 1 +kong_kong_latency_ms_bucket{service="google",route="google.route-1",le="15"} 1 +kong_kong_latency_ms_bucket{service="google",route="google.route-1",le="20"} 1 +kong_kong_latency_ms_bucket{service="google",route="google.route-1",le="30"} 1 +kong_kong_latency_ms_bucket{service="google",route="google.route-1",le="50"} 1 +kong_kong_latency_ms_bucket{service="google",route="google.route-1",le="75"} 1 +kong_kong_latency_ms_bucket{service="google",route="google.route-1",le="100"} 1 +kong_kong_latency_ms_bucket{service="google",route="google.route-1",le="200"} 1 +kong_kong_latency_ms_bucket{service="google",route="google.route-1",le="500"} 1 +kong_kong_latency_ms_bucket{service="google",route="google.route-1",le="750"} 1 +kong_kong_latency_ms_bucket{service="google",route="google.route-1",le="1000"} 1 +kong_kong_latency_ms_bucket{service="google",route="google.route-1",le="+Inf"} 1 +kong_kong_latency_ms_count{service="google",route="google.route-1"} 1 +kong_kong_latency_ms_sum{service="google",route="google.route-1"} 4 # HELP kong_memory_lua_shared_dict_bytes Allocated slabs in bytes in a shared_dict # TYPE kong_memory_lua_shared_dict_bytes gauge -kong_memory_lua_shared_dict_bytes{shared_dict="kong",kong_subsystem="http"} 40960 -. -. +kong_memory_lua_shared_dict_bytes{node_id="849373c5-45c1-4c1d-b595-fdeaea6daed8",shared_dict="kong",kong_subsystem="http"} 40960 +kong_memory_lua_shared_dict_bytes{node_id="849373c5-45c1-4c1d-b595-fdeaea6daed8",shared_dict="kong_cluster_events",kong_subsystem="http"} 40960 +kong_memory_lua_shared_dict_bytes{node_id="849373c5-45c1-4c1d-b595-fdeaea6daed8",shared_dict="kong_core_db_cache",kong_subsystem="http"} 823296 +kong_memory_lua_shared_dict_bytes{node_id="849373c5-45c1-4c1d-b595-fdeaea6daed8",shared_dict="kong_core_db_cache_miss",kong_subsystem="http"} 90112 +kong_memory_lua_shared_dict_bytes{node_id="849373c5-45c1-4c1d-b595-fdeaea6daed8",shared_dict="kong_db_cache",kong_subsystem="http"} 794624 +kong_memory_lua_shared_dict_bytes{node_id="849373c5-45c1-4c1d-b595-fdeaea6daed8",shared_dict="kong_db_cache_miss",kong_subsystem="http"} 86016 +kong_memory_lua_shared_dict_bytes{node_id="849373c5-45c1-4c1d-b595-fdeaea6daed8",shared_dict="kong_healthchecks",kong_subsystem="http"} 40960 +kong_memory_lua_shared_dict_bytes{node_id="849373c5-45c1-4c1d-b595-fdeaea6daed8",shared_dict="kong_locks",kong_subsystem="http"} 61440 +kong_memory_lua_shared_dict_bytes{node_id="849373c5-45c1-4c1d-b595-fdeaea6daed8",shared_dict="kong_process_events",kong_subsystem="http"} 40960 +kong_memory_lua_shared_dict_bytes{node_id="849373c5-45c1-4c1d-b595-fdeaea6daed8",shared_dict="kong_rate_limiting_counters",kong_subsystem="http"} 86016 +kong_memory_lua_shared_dict_bytes{node_id="849373c5-45c1-4c1d-b595-fdeaea6daed8",shared_dict="prometheus_metrics",kong_subsystem="http"} 57344 # HELP kong_memory_lua_shared_dict_total_bytes Total capacity in bytes of a shared_dict # TYPE kong_memory_lua_shared_dict_total_bytes gauge -kong_memory_lua_shared_dict_total_bytes{shared_dict="kong",kong_subsystem="http"} 5242880 -. -. +kong_memory_lua_shared_dict_total_bytes{node_id="849373c5-45c1-4c1d-b595-fdeaea6daed8",shared_dict="kong",kong_subsystem="http"} 5242880 +kong_memory_lua_shared_dict_total_bytes{node_id="849373c5-45c1-4c1d-b595-fdeaea6daed8",shared_dict="kong_cluster_events",kong_subsystem="http"} 5242880 +kong_memory_lua_shared_dict_total_bytes{node_id="849373c5-45c1-4c1d-b595-fdeaea6daed8",shared_dict="kong_core_db_cache",kong_subsystem="http"} 134217728 +kong_memory_lua_shared_dict_total_bytes{node_id="849373c5-45c1-4c1d-b595-fdeaea6daed8",shared_dict="kong_core_db_cache_miss",kong_subsystem="http"} 12582912 +kong_memory_lua_shared_dict_total_bytes{node_id="849373c5-45c1-4c1d-b595-fdeaea6daed8",shared_dict="kong_db_cache",kong_subsystem="http"} 134217728 +kong_memory_lua_shared_dict_total_bytes{node_id="849373c5-45c1-4c1d-b595-fdeaea6daed8",shared_dict="kong_db_cache_miss",kong_subsystem="http"} 12582912 +kong_memory_lua_shared_dict_total_bytes{node_id="849373c5-45c1-4c1d-b595-fdeaea6daed8",shared_dict="kong_healthchecks",kong_subsystem="http"} 5242880 +kong_memory_lua_shared_dict_total_bytes{node_id="849373c5-45c1-4c1d-b595-fdeaea6daed8",shared_dict="kong_locks",kong_subsystem="http"} 8388608 +kong_memory_lua_shared_dict_total_bytes{node_id="849373c5-45c1-4c1d-b595-fdeaea6daed8",shared_dict="kong_process_events",kong_subsystem="http"} 5242880 +kong_memory_lua_shared_dict_total_bytes{node_id="849373c5-45c1-4c1d-b595-fdeaea6daed8",shared_dict="kong_rate_limiting_counters",kong_subsystem="http"} 12582912 +kong_memory_lua_shared_dict_total_bytes{node_id="849373c5-45c1-4c1d-b595-fdeaea6daed8",shared_dict="prometheus_metrics",kong_subsystem="http"} 5242880 # HELP kong_memory_workers_lua_vms_bytes Allocated bytes in worker Lua VM # TYPE kong_memory_workers_lua_vms_bytes gauge -kong_memory_workers_lua_vms_bytes{pid="7281",kong_subsystem="http"} 41124353 -# HELP kong_data_plane_config_hash Config hash value of the data plane -# TYPE kong_data_plane_config_hash gauge -kong_data_plane_config_hash{node_id="d4e7584e-b2f2-415b-bb68-3b0936f1fde3",hostname="ubuntu-bionic",ip="127.0.0.1"} 1.7158931820287e+38 -# HELP kong_data_plane_last_seen Last time data plane contacted control plane -# TYPE kong_data_plane_last_seen gauge -kong_data_plane_last_seen{node_id="d4e7584e-b2f2-415b-bb68-3b0936f1fde3",hostname="ubuntu-bionic",ip="127.0.0.1"} 1600190275 -# HELP kong_data_plane_version_compatible Version compatible status of the data plane, 0 is incompatible -# TYPE kong_data_plane_version_compatible gauge -kong_data_plane_version_compatible{node_id="d4e7584e-b2f2-415b-bb68-3b0936f1fde3",hostname="ubuntu-bionic",ip="127.0.0.1",kong_version="2.4.1"} 1 +kong_memory_workers_lua_vms_bytes{node_id="849373c5-45c1-4c1d-b595-fdeaea6daed8",pid="21173",kong_subsystem="http"} 64329517 +kong_memory_workers_lua_vms_bytes{node_id="849373c5-45c1-4c1d-b595-fdeaea6daed8",pid="21174",kong_subsystem="http"} 46314808 +kong_memory_workers_lua_vms_bytes{node_id="849373c5-45c1-4c1d-b595-fdeaea6daed8",pid="21175",kong_subsystem="http"} 46681598 +kong_memory_workers_lua_vms_bytes{node_id="849373c5-45c1-4c1d-b595-fdeaea6daed8",pid="21176",kong_subsystem="http"} 46637209 +kong_memory_workers_lua_vms_bytes{node_id="849373c5-45c1-4c1d-b595-fdeaea6daed8",pid="21177",kong_subsystem="http"} 46234336 +kong_memory_workers_lua_vms_bytes{node_id="849373c5-45c1-4c1d-b595-fdeaea6daed8",pid="21178",kong_subsystem="http"} 46180420 +kong_memory_workers_lua_vms_bytes{node_id="849373c5-45c1-4c1d-b595-fdeaea6daed8",pid="21179",kong_subsystem="http"} 46161105 +kong_memory_workers_lua_vms_bytes{node_id="849373c5-45c1-4c1d-b595-fdeaea6daed8",pid="21180",kong_subsystem="http"} 46366877 +# HELP kong_nginx_connections_total Number of connections by subsystem +# TYPE kong_nginx_connections_total gauge +kong_nginx_connections_total{node_id="849373c5-45c1-4c1d-b595-fdeaea6daed8",subsystem="http",state="accepted"} 296 +kong_nginx_connections_total{node_id="849373c5-45c1-4c1d-b595-fdeaea6daed8",subsystem="http",state="active"} 9 +kong_nginx_connections_total{node_id="849373c5-45c1-4c1d-b595-fdeaea6daed8",subsystem="http",state="handled"} 296 +kong_nginx_connections_total{node_id="849373c5-45c1-4c1d-b595-fdeaea6daed8",subsystem="http",state="reading"} 0 +kong_nginx_connections_total{node_id="849373c5-45c1-4c1d-b595-fdeaea6daed8",subsystem="http",state="total"} 296 +kong_nginx_connections_total{node_id="849373c5-45c1-4c1d-b595-fdeaea6daed8",subsystem="http",state="waiting"} 0 +kong_nginx_connections_total{node_id="849373c5-45c1-4c1d-b595-fdeaea6daed8",subsystem="http",state="writing"} 9 # HELP kong_nginx_metric_errors_total Number of nginx-lua-prometheus errors # TYPE kong_nginx_metric_errors_total counter kong_nginx_metric_errors_total 0 -# HELP kong_upstream_target_health Health status of targets of upstream. States = healthchecks_off|healthy|unhealthy|dns_error, value is 1 when state is populated. -kong_upstream_target_health{upstream="",target="",address=":",state="healthchecks_off",subsystem="http"} 0 -kong_upstream_target_health{upstream="",target="",address=":",state="healthy",subsystem="http"} 1 -kong_upstream_target_health{upstream="",target="",address=":",state="unhealthy",subsystem="http"} 0 -kong_upstream_target_health{upstream="",target="",address=":",state="dns_error",subsystem="http"} 0 -# HELP kong_db_entities_total Total number of Kong db entities -# TYPE kong_db_entities_total gauge -kong_db_entities_total 42 -# HELP kong_db_entity_count_errors Errors during entity count collection -# TYPE kong_db_entity_count_errors counter -kong_db_entity_count_errors 0 +# HELP kong_nginx_requests_total Total number of requests +# TYPE kong_nginx_requests_total gauge +kong_nginx_requests_total{node_id="849373c5-45c1-4c1d-b595-fdeaea6daed8",subsystem="http"} 296 +# HELP kong_nginx_timers Number of Nginx timers +# TYPE kong_nginx_timers gauge +kong_nginx_timers{state="pending"} 1 +kong_nginx_timers{state="running"} 39 +# HELP kong_request_latency_ms Total latency incurred during requests for each service/route in Kong +# TYPE kong_request_latency_ms histogram +kong_request_latency_ms_bucket{service="google",route="google.route-1",le="25"} 1 +kong_request_latency_ms_bucket{service="google",route="google.route-1",le="50"} 1 +kong_request_latency_ms_bucket{service="google",route="google.route-1",le="80"} 1 +kong_request_latency_ms_bucket{service="google",route="google.route-1",le="100"} 1 +kong_request_latency_ms_bucket{service="google",route="google.route-1",le="250"} 1 +kong_request_latency_ms_bucket{service="google",route="google.route-1",le="400"} 1 +kong_request_latency_ms_bucket{service="google",route="google.route-1",le="700"} 1 +kong_request_latency_ms_bucket{service="google",route="google.route-1",le="1000"} 1 +kong_request_latency_ms_bucket{service="google",route="google.route-1",le="2000"} 1 +kong_request_latency_ms_bucket{service="google",route="google.route-1",le="5000"} 1 +kong_request_latency_ms_bucket{service="google",route="google.route-1",le="10000"} 1 +kong_request_latency_ms_bucket{service="google",route="google.route-1",le="30000"} 1 +kong_request_latency_ms_bucket{service="google",route="google.route-1",le="60000"} 1 +kong_request_latency_ms_bucket{service="google",route="google.route-1",le="+Inf"} 1 +kong_request_latency_ms_count{service="google",route="google.route-1"} 1 +kong_request_latency_ms_sum{service="google",route="google.route-1"} 6 +# HELP kong_upstream_latency_ms Latency added by upstream response for each service/route in Kong +# TYPE kong_upstream_latency_ms histogram +kong_upstream_latency_ms_bucket{service="google",route="google.route-1",le="25"} 1 +kong_upstream_latency_ms_bucket{service="google",route="google.route-1",le="50"} 1 +kong_upstream_latency_ms_bucket{service="google",route="google.route-1",le="80"} 1 +kong_upstream_latency_ms_bucket{service="google",route="google.route-1",le="100"} 1 +kong_upstream_latency_ms_bucket{service="google",route="google.route-1",le="250"} 1 +kong_upstream_latency_ms_bucket{service="google",route="google.route-1",le="400"} 1 +kong_upstream_latency_ms_bucket{service="google",route="google.route-1",le="700"} 1 +kong_upstream_latency_ms_bucket{service="google",route="google.route-1",le="1000"} 1 +kong_upstream_latency_ms_bucket{service="google",route="google.route-1",le="2000"} 1 +kong_upstream_latency_ms_bucket{service="google",route="google.route-1",le="5000"} 1 +kong_upstream_latency_ms_bucket{service="google",route="google.route-1",le="10000"} 1 +kong_upstream_latency_ms_bucket{service="google",route="google.route-1",le="30000"} 1 +kong_upstream_latency_ms_bucket{service="google",route="google.route-1",le="60000"} 1 +kong_upstream_latency_ms_bucket{service="google",route="google.route-1",le="+Inf"} 1 +kong_upstream_latency_ms_count{service="google",route="google.route-1"} 1 +kong_upstream_latency_ms_sum{service="google",route="google.route-1"} 2 ``` @@ -210,6 +294,26 @@ allow access to the `/metrics` endpoint to Prometheus: ## Changelog +### 3.0.x + +* High cardinality metrics are now disabled by default. +* Decreased performance penalty to proxy traffic when collecting metrics. +* The following metric names were adjusted to add units to standardize where possible: + * `http_status` to `http_requests_total` + * `latency` to `kong_request_latency_ms`/`kong_upstream_latency_ms`/`kong_kong_latency_ms` + * `kong_bandwidh` to `kong_bandwidth_bytes` + * `nginx_http_current_connections`/`nginx_stream_current_connections` to `nginx_connections_total` + * Removed: `http_consumer_status` +* New metric: `session_duration_ms` for monitoring stream connections +* New metric: `node_info` is a single gauge set to 1 that outputs the node's ID and {{site.base_gateway}} version +* Latency was split into four different metrics: `kong_latency_ms`, `upstream_latency_ms`, `request_latency_ms` (HTTP), and `session_duration_ms` (stream). Buckets details follow: + * Kong Latency and Upstream Latency can operate at orders of different magnitudes. Separate these buckets to reduce memory overhead. +* `request_count` and `consumer_status` were merged into `http_requests_total`. If the `per_consumer` config is set to false, the `consumer` label will be empty. If the `per_consumer` config is true, the `consumer` label will be filled. +* `http_requests_total` has a new label [`source`](/gateway/latest/plugin-development/pdk/kong.response/#kongresponseget_source/). It can be set to `exit`, `error`, or `service`. +* All Memory metrics have a new label, `node_id`. +* Plugin version bumped to 3.0.0 +* The `node_id` label was added to memory metrics. + ### 1.6.x * Adds a new metric: diff --git a/app/_hub/kong-inc/prometheus/versions.yml b/app/_hub/kong-inc/prometheus/versions.yml index 5bf42e6629af..9e1975cce7cb 100644 --- a/app/_hub/kong-inc/prometheus/versions.yml +++ b/app/_hub/kong-inc/prometheus/versions.yml @@ -1,6 +1,19 @@ -- release: 1.6.x -- release: 1.4.x -- release: 1.3.x -- release: 0.9.x -- release: 0.8.x -- release: 0.1-x +strategy: gateway +delegate_releases: true +releases: + - 3.0.x + - 2.8.x + - 2.7.x + - 2.5.x + - 2.0.x-CE + - 1.5.x-EE +sources: + 2.0.x-CE: _0.8.x + 1.5.x-EE: _0.8.x +overrides: + 3.0.x: 3.0.x + 2.8.x: 1.6.x + 2.7.x: 1.4.x + 2.5.x: 1.3.x + 2.0.x-CE: 0.8.x + 1.5.x-EE: 0.8.x \ No newline at end of file diff --git a/app/_hub/kong-inc/proxy-cache-advanced/0.4.x.md b/app/_hub/kong-inc/proxy-cache-advanced/0.4.x.md deleted file mode 100644 index d1acf1ee95f6..000000000000 --- a/app/_hub/kong-inc/proxy-cache-advanced/0.4.x.md +++ /dev/null @@ -1,292 +0,0 @@ ---- - -name: Proxy Caching Advanced -publisher: Kong Inc. -version: 0.4.x - -desc: Cache and serve commonly requested responses in Kong -description: | - This plugin provides a reverse proxy cache implementation for Kong. It caches response entities based on configurable response code and content type, as well as request method. It can cache per-Consumer or per-API. Cache entities are stored for a configurable period of time, after which subsequent requests to the same resource will re-fetch and re-store the resource. Cache entities can also be forcefully purged via the Admin API prior to their expiration time. - -type: plugin -enterprise: true -categories: - - traffic-control - -kong_version_compatibility: - community_edition: - compatible: - enterprise_edition: - compatible: - - 0.36-x - - 0.35-x - - 0.34-x - -params: - name: proxy-cache-advanced - api_id: true - service_id: true - route_id: true - consumer_id: true - config: - - name: response_code - required: - default: 200, 301, 404 - value_in_examples: - description: | - Upstream response status code considered cacheable. - - name: request_method - required: - default: '`["GET","HEAD"]`' - value_in_examples: - description: | - Downstream request methods considered cacheable. Available options: "HEAD", "GET", "POST", "PATCH", "PUT". - - name: content_type - required: - default: text/plain, application/json - value_in_examples: - description: | - Upstream response content types considered cacheable. The plugin performs an **exact match** against each specified value; for example, if the upstream is expected to respond with a `application/json; charset=utf-8` content-type, the plugin configuration must contain said value or a `Bypass` cache status is returned. - - name: vary_headers - required: false - default: - value_in_examples: - description: | - Relevant headers considered for the cache key. If undefined, none of the headers are taken into consideration. - - name: vary_query_params - required: false - default: - value_in_examples: - description: | - Relevant query parameters considered for the cache key. If undefined, all params are taken into consideration. - - name: cache_ttl - required: - default: 300 - value_in_examples: - description: | - TTL, in seconds, of cache entities. - - name: cache_control - required: - default: false - value_in_examples: - description: | - When enabled, respect the Cache-Control behaviors defined in [RFC7234](https://tools.ietf.org/html/rfc7234#section-5.2). - - name: storage_ttl - required: false - default: - value_in_examples: - description: | - Number of seconds to keep resources in the storage backend. This value is independent of `cache_ttl` or resource TTLs defined by Cache-Control behaviors. - - name: strategy - required: - default: - value_in_examples: memory - description: | - The backing data store in which to hold cache entities. Accepted values are: `memory`, and `redis`. - - name: memory.dictionary_name - required: - default: kong_db_cache - value_in_examples: - description: | - The name of the shared dictionary in which to hold cache entities when the memory strategy is selected. Note that this dictionary currently must be defined manually in the Kong Nginx template. - - name: redis.host - required: semi - default: - value_in_examples: - description: | - Host to use for Redis connection when the redis strategy is defined. - - name: redis.port - required: semi - default: - value_in_examples: - description: | - Port to use for Redis connection when the redis strategy is defined. - - name: redis.timeout - required: semi - default: 2000 - value_in_examples: - description: | - Connection timeout to use for Redis connection when the redis strategy is defined. - - name: redis.password - required: semi - default: - value_in_examples: - description: | - Password to use for Redis connection when the redis strategy is defined. If undefined, no AUTH commands are sent to Redis. - - name: redis.database - required: semi - default: 0 - value_in_examples: - description: | - Database to use for Redis connection when the redis strategy is defined. - - name: redis.sentinel_master - required: semi - default: - value_in_examples: - description: | - Sentinel master to use for Redis connection when the redis strategy is defined. Defining this value implies using Redis Sentinel. - - name: redis.sentinel_role - required: semi - default: - value_in_examples: - description: | - Sentinel role to use for Redis connection when the redis strategy is defined. Defining this value implies using Redis Sentinel. - - name: redis.sentinel_addresses - required: semi - default: - value_in_examples: - description: | - Sentinel addresses to use for Redis connection when the redis strategy is defined. Defining this value implies using Redis Sentinel. - - name: redis.cluster_addresses - required: semi - default: - value_in_examples: - description: | - Cluster addresses to use for Redis connection when the `redis` strategy is defined. Defining this value implies using Redis cluster. - - name: bypass_on_err - required: false - default: false - value_in_examples: - description: | - Unhandled errors while trying to retrieve a cache entry (such as redis down) are resolved with `Bypass`, with the request going upstream. - extra: | - -
- Warning: The content_type parameter requires - an exact match. For example, if your Upstream expects - application/json; charset=utf-8 and the - config.content_type value is only application/json - (a partial match), then the proxy cache is bypassed. -
- - ---- -### Strategies - -`kong-plugin-enterprise-proxy-cache` is designed to support storing proxy cache data in different backend formats. Currently the following strategies are provided: -- `memory`: A `lua_shared_dict`. Note that the default dictionary, `kong_db_cache`, is also used by other plugins and elements of Kong to store unrelated database cache entities. Using this dictionary is an easy way to bootstrap the proxy-cache-advanced plugin, but it is not recommended for large-scale installations as significant usage will put pressure on other facets of Kong's database caching operations. It is recommended to define a separate `lua_shared_dict` via a custom Nginx template at this time. -- `redis`: Supports Redis and Redis Sentinel deployments. - -### Cache Key - -Kong keys each cache elements based on the request method, the full client request (e.g., the request path and query parameters), and the UUID of either the API or Consumer associated with the request. This also implies that caches are distinct between APIs and/or Consumers. Currently the cache key format is hard-coded and cannot be adjusted. Internally, cache keys are represented as a hexadecimal-encoded MD5 sum of the concatenation of the constituent parts. This is calculated as follows: - -``` -key = md5(UUID | method | request) -``` - -Where `method` is defined via the OpenResty `ngx.req.get_method()` call, and `request` is defined via the Nginx `$request` variable. Kong will return the cache key associated with a given request as the `X-Cache-Key` response header. It is also possible to precalculate the cache key for a given request as noted above. - -### Cache Control - -When the `cache_control` configuration option is enabled, Kong will respect request and response Cache-Control headers as defined by [RFC7234](https://tools.ietf.org/html/rfc7234#section-5.2), with a few exceptions: - -- Cache revalidation is not yet supported, and so directives such as `proxy-revalidate` are ignored. -- Similarly, the behavior of `no-cache` is simplified to exclude the entity from being cached entirely. -- Secondary key calculation via `Vary` is not yet supported. - -### Cache Status - -Kong identifies the status of the request's proxy cache behavior via the `X-Cache-Status` header. There are several possible values for this header: - -- `Miss`: The request could be satisfied in cache, but an entry for the resource was not found in cache, and the request was proxied upstream. -- `Hit`: The request was satisfied and served from cache. -- `Refresh`: The resource was found in cache, but could not satisfy the request, due to Cache-Control behaviors or reaching its hard-coded cache_ttl threshold. -- `Bypass`: The request could not be satisfied from cache based on plugin configuration. - -### Storage TTL - -Kong can store resource entities in the storage engine longer than the prescribed `cache_ttl` or `Cache-Control` values indicate. This allows Kong to maintain a cached copy of a resource past its expiration. This allows clients capable of using `max-age` and `max-stale` headers to request stale copies of data if necessary. - -### Upstream Outages - -Due to an implementation in Kong's core request processing model, at this point the proxy-cache-advanced plugin cannot be used to serve stale cache data when an upstream is unreachable. To equip Kong to serve cache data in place of returning an error when an upstream is unreachable, we recommend defining a very large `storage_ttl` (on the order of hours or days) in order to keep stale data in the cache. In the event of an upstream outage, stale data can be considered "fresh" by increasing the `cache_ttl` plugin configuration value. By doing so, data that would have been previously considered stale is now served to the client, before Kong attempts to connect to a failed upstream service. - -### Admin API - -This plugin provides several endpoints to managed cache entities. These endpoints are assigned to the `proxy-cache-advanced` RBAC resource. - -The following endpoints are provided on the Admin API to examine and purge cache entities: - -### Retrieve a Cache Entity - -Two separate endpoints are available: one to look up a known plugin instance, and another that searches all proxy-cache-advanced plugins data stores for the given cache key. Both endpoints have the same return value. - -**Endpoint** - -
/proxy-cache-advanced/:plugin_id/caches/:cache_id
- -| Attributes | Description -| -------------- | ------- -|`plugin_id` | The UUID of the proxy-cache-advanced plugin -| `cache_id` | The cache entity key as reported by the X-Cache-Key response header - -**Endpoint** - -
/proxy-cache-advanced/:cache_id
- -| Attributes | Description -| -------------- | ------- -|`cache_id` | The cache entity key as reported by the X-Cache-Key response header - -**Response** - -If the cache entity exists - -``` -HTTP 200 OK -``` - -If the entity with the given key does not exist - -``` -HTTP 400 Not Found -``` - -### Delete Cache Entity - -Two separate endpoints are available: one to look up a known plugin instance, and another that searches all proxy-cache-advanced plugins data stores for the given cache key. Both endpoints have the same return value. - -**Endpoint** - -
/proxy-cache-advanced/:plugin_id/caches/:cache_id
- -| Attributes | Description -| -------------- | ------- -|`plugin_id` | The UUID of the proxy-cache-advanced plugin -|`cache_id` | The cache entity key as reported by the `X-Cache-Key` response header - -**Endpoint** - -
/proxy-cache-advanced/:cache_id
- -| Attributes | Description -| -------------- | ------- -|`cache_id` | he cache entity key as reported by the `X-Cache-Key` response header - -**Response** - -If the cache entity exists: - -``` -HTTP 204 No Content -``` - -If the entity with the given key does not exist: - -``` -HTTP 400 Not Found -``` - -### Purge All Cache Entities -**Endpoint** - -
/proxy-cache-advanced/
- -**Response** - -``` -HTTP 204 No Content -``` - -Note that this endpoint purges all cache entities across all `proxy-cache-advanced` plugins. diff --git a/app/_hub/kong-inc/proxy-cache-advanced/_index.md b/app/_hub/kong-inc/proxy-cache-advanced/_index.md index e8564cd398ab..5a95ff8b49d4 100644 --- a/app/_hub/kong-inc/proxy-cache-advanced/_index.md +++ b/app/_hub/kong-inc/proxy-cache-advanced/_index.md @@ -1,7 +1,6 @@ --- name: Proxy Caching Advanced publisher: Kong Inc. -version: 0.5.x desc: Cache and serve commonly requested responses in Kong description: | This plugin provides a reverse proxy cache implementation for Kong. It caches @@ -19,17 +18,7 @@ kong_version_compatibility: community_edition: compatible: null enterprise_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x + compatible: true params: name: proxy-cache-advanced service_id: true @@ -184,8 +173,8 @@ params: If undefined, no AUTH commands are sent to Redis. This field is _referenceable_, which means it can be securely stored as a - [secret](/gateway/latest/plan-and-deploy/security/secrets-management/getting-started) - in a vault. References must follow a [specific format](/gateway/latest/plan-and-deploy/security/secrets-management/reference-format). + [secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). - name: redis.database required: semi default: 0 @@ -201,6 +190,7 @@ params: description: | Sentinel master to use for Redis connection when the `redis` strategy is defined. Defining this value implies using Redis Sentinel. - name: redis.sentinel_username + minimum_version: "2.8.x" required: semi default: null value_in_examples: null @@ -210,9 +200,10 @@ params: If undefined, ACL authentication will not be performed. This requires Redis v6.2.0+. This field is _referenceable_, which means it can be securely stored as a - [secret](/gateway/latest/plan-and-deploy/security/secrets-management/getting-started) - in a vault. References must follow a [specific format](/gateway/latest/plan-and-deploy/security/secrets-management/reference-format). + [secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). - name: redis.sentinel_password + minimum_version: "2.8.x" required: semi default: null value_in_examples: null @@ -222,8 +213,8 @@ params: If undefined, no AUTH commands are sent to Redis Sentinels. This field is _referenceable_, which means it can be securely stored as a - [secret](/gateway/latest/plan-and-deploy/security/secrets-management/getting-started) - in a vault. References must follow a [specific format](/gateway/latest/plan-and-deploy/security/secrets-management/reference-format). + [secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). - name: redis.sentinel_role required: semi default: null @@ -256,11 +247,11 @@ params: value_in_examples: null datatype: integer description: | - If specified, limits the total number of opened connections for a pool. If the - connection pool is full, all connection queues beyond the maximum limit go into - the backlog queue. Once the backlog queue is full, subsequent connect operations - will fail and return `nil`. Queued connect operations resume once the number of - connections in the pool is less than `keepalive_pool_size`. Note that queued + If specified, limits the total number of opened connections for a pool. If the + connection pool is full, all connection queues beyond the maximum limit go into + the backlog queue. Once the backlog queue is full, subsequent connect operations + will fail and return `nil`. Queued connect operations resume once the number of + connections in the pool is less than `keepalive_pool_size`. Note that queued connect operations are subject to set timeouts. - name: redis.keepalive_pool required: false @@ -456,7 +447,7 @@ Note that this endpoint purges all cache entities across all `proxy-cache-advanc ## Changelog -### Kong Gateway 2.8.x (plugin version 0.5.7) +**{{site.base_gateway}} 2.8.x** * Added the `redis.sentinel_username` and `redis.sentinel_password` configuration parameters. @@ -464,7 +455,7 @@ parameters. * The `redis.password`, `redis.sentinel_username`, and `redis.sentinel_password` configuration fields are now marked as referenceable, which means they can be securely stored as [secrets](/gateway/latest/plan-and-deploy/security/secrets-management/getting-started) -in a vault. References must follow a [specific format](/gateway/latest/plan-and-deploy/security/secrets-management/reference-format). +in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). * Fixed plugin versions in the documentation. Previously, the plugin versions were labelled as `1.3-x` and `2.2.x`. They are now updated to align with the diff --git a/app/_hub/kong-inc/proxy-cache-advanced/versions.yml b/app/_hub/kong-inc/proxy-cache-advanced/versions.yml index 1c1e60c46d54..76c5efe2c754 100644 --- a/app/_hub/kong-inc/proxy-cache-advanced/versions.yml +++ b/app/_hub/kong-inc/proxy-cache-advanced/versions.yml @@ -1,2 +1,12 @@ -- release: 0.5.x -- release: 0.4.x +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 0.5.8 + 2.7.x: 0.5.7 + 2.6.x: 0.5.6 + 2.5.x: 0.5.6 + 2.4.x: 0.5.6 + 2.3.x: 0.5.6 + 2.2.x: 0.5.6 + 2.1.x: 0.5.4 diff --git a/app/_hub/kong-inc/proxy-cache/0.31-x.md b/app/_hub/kong-inc/proxy-cache/0.31-x.md deleted file mode 100644 index 416cad3afe0e..000000000000 --- a/app/_hub/kong-inc/proxy-cache/0.31-x.md +++ /dev/null @@ -1,256 +0,0 @@ ---- - -name: Proxy Caching -publisher: Kong Inc. -version: 0.31-x - -desc: Cache and serve commonly requested responses in Kong -description: | - This plugin provides a reverse proxy cache implementation for Kong. It caches response entities based on configurable response code and content type, as well as request method. It can cache per-Consumer or per-API. Cache entities are stored for a configurable period of time, after which subsequent requests to the same resource will re-fetch and re-store the resource. Cache entities can also be forcefully purged via the Admin API prior to their expiration time. - -enterprise: true -type: plugin -categories: - - traffic-control - -kong_version_compatibility: - community_edition: - compatible: - enterprise_edition: - compatible: - - 0.31-x - -params: - name: proxy-cache - api_id: true - service_id: true - route_id: true - consumer_id: true - config: - - name: response_code - required: - default: 200, 301, 404 - value_in_examples: - description: | - Upstream response status code considered cacheable - - name: request_method - required: - default: GET, HEAD - value_in_examples: - description: | - Downstream request methods considered cacheable - - name: content_type - required: - default: text/plain - value_in_examples: - description: | - Upstream response content types considered cacheable. The plugin performs an exact match against each specified value; for example, if the upstream is expected to respond with a `application/json; charset=utf-8` content-type, the plugin configuration must contain said value or a `Bypass` cache status will be returned - - name: cache_ttl - required: - default: 300 - value_in_examples: - description: | - TTL, in seconds, of cache entities - - name: cache_control - required: - default: false - value_in_examples: - description: | - When enabled, respect the Cache-Control behaviors defined in [RFC7234](https://tools.ietf.org/html/rfc7234#section-5.2) - - name: storage_ttl - required: - default: - value_in_examples: - description: | - Number of seconds to keep resources in the storage backend. This value is independent of `cache_ttl` or resource TTLs defined by Cache-Control behaviors. - - name: strategy - required: - default: - value_in_examples: - description: | - The backing data store in which to hold cache entities - - name: memory.dictionary_name - required: - default: kong_db_cache - value_in_examples: - description: | - The name of the shared dictionary in which to hold cache entities when the memory strategy is selected. Note that this dictionary currently must be defined manually in the Kong Nginx template. - - name: redis.host - required: semi - default: - value_in_examples: - description: | - Host to use for Redis connection when the redis strategy is defined - - name: redis.port - required: semi - default: - value_in_examples: - description: | - Port to use for Redis connection when the redis strategy is defined - - name: redis.timeout - required: semi - default: 2000 - value_in_examples: - description: | - Connection timeout to use for Redis connection when the redis strategy is defined - - name: redis.password - required: semi - default: - value_in_examples: - description: | - Password to use for Redis connection when the redis strategy is defined. If undefined, no AUTH commands are sent to Redis. - - name: redis.database - required: semi - default: 0 - value_in_examples: - description: | - Database to use for Redis connection when the redis strategy is defined - - name: redis.sentinel_master - required: semi - default: - value_in_examples: - description: | - Sentinel master to use for Redis connection when the redis strategy is defined. Defining this value implies using Redis Sentinel. - - name: redis.sentinel_role - required: semi - default: - value_in_examples: - description: | - Sentinel role to use for Redis connection when the redis strategy is defined. Defining this value implies using Redis Sentinel. - - name: redis.sentinel_addresses - required: semi - default: - value_in_examples: - description: | - Sentinel addresses to use for Redis connection when the redis strategy is defined. Defining this value implies using Redis Sentinel. - ---- -### Strategies - -`kong-plugin-enterprise-proxy-cache` is designed to support storing proxy cache data in different backend formats. Currently the following strategies are provided: -- `memory`: A `lua_shared_dict`. Note that the default dictionary, `kong_db_cache`, is also used by other plugins and elements of Kong to store unrelated database cache entities. Using this dictionary is an easy way to bootstrap the proxy-cache plugin, but it is not recommended for large-scale installations as significant usage will put pressure on other facets of Kong's database caching operations. It is recommended to define a separate `lua_shared_dict` via a custom Nginx template at this time. -- `redis`: Supports Redis and Redis Sentinel deployments. - -### Cache Key - -Kong keys each cache elements based on the request method, the full client request (e.g., the request path and query parameters), and the UUID of either the API or Consumer associated with the request. This also implies that caches are distinct between APIs and/or Consumers. Currently the cache key format is hard-coded and cannot be adjusted. Internally, cache keys are represented as a hexadecimal-encoded MD5 sum of the concatenation of the constituent parts. This is calculated as follows: - -``` -key = md5(UUID | method | request) -``` - -Where `method` is defined via the OpenResty `ngx.req.get_method()` call, and `request` is defined via the Nginx `$request` variable. Kong will return the cache key associated with a given request as the `X-Cache-Key` response header. It is also possible to precalculate the cache key for a given request as noted above. - -### Cache Control - -When the `cache_control` configuration option is enabled, Kong will respect request and response Cache-Control headers as defined by [RFC7234](https://tools.ietf.org/html/rfc7234#section-5.2), with a few exceptions: - -- Cache revalidation is not yet supported, and so directives such as `proxy-revalidate` are ignored. -- Similarly, the behavior of `no-cache` is simplified to exclude the entity from being cached entirely. -- Secondary key calculation via `Vary` is not yet supported. - -### Cache Status - -Kong identifies the status of the request's proxy cache behavior via the `X-Cache-Status` header. There are several possible values for this header: - -- `Miss`: The request could be satisfied in cache, but an entry for the resource was not found in cache, and the request was proxied upstream. -- `Hit`: The request was satisfied and served from cache. -- `Refresh`: The resource was found in cache, but could not satisfy the request, due to Cache-Control behaviors or reaching its hard-coded cache_ttl threshold. -- `Bypass`: The request could not be satisfied from cache based on plugin configuration. - -### Storage TTL - -Kong can store resource entities in the storage engine longer than the prescribed `cache_ttl` or `Cache-Control` values indicate. This allows Kong to maintain a cached copy of a resource past its expiration. This allows clients capable of using `max-age` and `max-stale` headers to request stale copies of data if necessary. - -### Upstream Outages - -Due to an implementation in Kong's core request processing model, at this point the proxy-cache plugin cannot be used to serve stale cache data when an upstream is unreachable. To equip Kong to serve cache data in place of returning an error when an upstream is unreachable, we recommend defining a very large `storage_ttl` (on the order of hours or days) in order to keep stale data in the cache. In the event of an upstream outage, stale data can be considered "fresh" by increasing the `cache_ttl` plugin configuration value. By doing so, data that would have been previously considered stale is now served to the client, before Kong attempts to connect to a failed upstream service. - -### Admin API - -This plugin provides several endpoints to managed cache entities. These endpoints are assigned to the `proxy-cache` RBAC resource. - -The following endpoints are provided on the Admin API to examine and purge cache entities: - -### Retrieve a Cache Entity - -Two separate endpoints are available: one to look up a known plugin instance, and another that searches all proxy-cache plugins data stores for the given cache key. Both endpoints have the same return value. - -**Endpoint** - -
/proxy-cache/:plugin_id/caches/:cache_id
- -| Attributes | Description -| -------------- | ------- -|`plugin_id` | The UUID of the proxy-cache plugin -| `cache_id` | The cache entity key as reported by the X-Cache-Key response header - -**Endpoint** - -
/proxy-cache/:plugin_id/caches/:cache_id
- -| Attributes | Description -| -------------- | ------- -|`cache_id` | The cache entity key as reported by the X-Cache-Key response header - -**Response** - -If the cache entity exists - -``` -HTTP 200 OK -``` - -If the entity with the given key does not exist - -``` -HTTP 400 Not Found -``` - -### Delete Cache Entity - -Two separate endpoints are available: one to look up a known plugin instance, and another that searches all proxy-cache plugins data stores for the given cache key. Both endpoints have the same return value. - -**Endpoint** - -
/proxy-cache/:plugin_id/caches/:cache_id
- -| Attributes | Description -| -------------- | ------- -|`plugin_id` | The UUID of the proxy-cache plugin -|`cache_id` | The cache entity key as reported by the `X-Cache-Key` response header - -**Endpoint** - -
/proxy-cache/:cache_id
- -| Attributes | Description -| -------------- | ------- -|`cache_id` | he cache entity key as reported by the `X-Cache-Key` response header - -**Response** - -If the cache entity exists - -``` -HTTP 204 No Content -``` - -If the entity with the given key does not exist - -``` -HTTP 400 Not Found -``` - -### Purge All Cache Entities -**Endpoint** - -
/proxy-cache/
- -**Response** - -``` -HTTP 204 No Content -``` - -Note that this endpoint purges all cache entities across all `proxy-cache` plugins. diff --git a/app/_hub/kong-inc/proxy-cache/0.32-x.md b/app/_hub/kong-inc/proxy-cache/0.32-x.md deleted file mode 100644 index bfcef3d05b13..000000000000 --- a/app/_hub/kong-inc/proxy-cache/0.32-x.md +++ /dev/null @@ -1,268 +0,0 @@ ---- - -name: Proxy Caching -publisher: Kong Inc. -version: 0.32-x - -desc: Cache and serve commonly requested responses in Kong -description: | - This plugin provides a reverse proxy cache implementation for Kong. It caches response entities based on configurable response code and content type, as well as request method. It can cache per-Consumer or per-API. Cache entities are stored for a configurable period of time, after which subsequent requests to the same resource will re-fetch and re-store the resource. Cache entities can also be forcefully purged via the Admin API prior to their expiration time. - -enterprise: true -type: plugin -categories: - - traffic-control - -kong_version_compatibility: - community_edition: - compatible: - enterprise_edition: - compatible: - - 0.32-x - -params: - name: proxy-cache - api_id: true - service_id: true - route_id: true - consumer_id: true - config: - - name: response_code - required: - default: 200, 301, 404 - value_in_examples: - description: | - Upstream response status code considered cacheable - - name: request_method - required: - default: GET, HEAD - value_in_examples: - description: | - Downstream request methods considered cacheable - - name: content_type - required: - default: text/plain - value_in_examples: - description: | - Upstream response content types considered cacheable. The plugin performs an exact match against each specified value; for example, if the upstream is expected to respond with a `application/json; charset=utf-8` content-type, the plugin configuration must contain said value or a `Bypass` cache status will be returned - - name: vary_headers - required: - default: - value_in_examples: - description: | - Relevant headers considered for the cache key. If undefined, none of the headers are taken into consideration. - - name: vary_query_params - required: - default: - value_in_examples: - description: | - Relevant query parameters considered for the cache key. If undefined, all params are taken into consideration. - - name: cache_ttl - required: - default: 300 - value_in_examples: - description: | - TTL, in seconds, of cache entities - - name: cache_control - required: - default: false - value_in_examples: - description: | - When enabled, respect the Cache-Control behaviors defined in [RFC7234](https://tools.ietf.org/html/rfc7234#section-5.2) - - name: storage_ttl - required: - default: - value_in_examples: - description: | - Number of seconds to keep resources in the storage backend. This value is independent of `cache_ttl` or resource TTLs defined by Cache-Control behaviors. - - name: strategy - required: - default: - value_in_examples: - description: | - The backing data store in which to hold cache entities - - name: memory.dictionary_name - required: - default: kong_db_cache - value_in_examples: - description: | - The name of the shared dictionary in which to hold cache entities when the memory strategy is selected. Note that this dictionary currently must be defined manually in the Kong Nginx template. - - name: redis.host - required: semi - default: - value_in_examples: - description: | - Host to use for Redis connection when the redis strategy is defined - - name: redis.port - required: semi - default: - value_in_examples: - description: | - Port to use for Redis connection when the redis strategy is defined - - name: redis.timeout - required: semi - default: 2000 - value_in_examples: - description: | - Connection timeout to use for Redis connection when the redis strategy is defined - - name: redis.password - required: semi - default: - value_in_examples: - description: | - Password to use for Redis connection when the redis strategy is defined. If undefined, no AUTH commands are sent to Redis. - - name: redis.database - required: semi - default: 0 - value_in_examples: - description: | - Database to use for Redis connection when the redis strategy is defined - - name: redis.sentinel_master - required: semi - default: - value_in_examples: - description: | - Sentinel master to use for Redis connection when the redis strategy is defined. Defining this value implies using Redis Sentinel. - - name: redis.sentinel_role - required: semi - default: - value_in_examples: - description: | - Sentinel role to use for Redis connection when the redis strategy is defined. Defining this value implies using Redis Sentinel. - - name: redis.sentinel_addresses - required: semi - default: - value_in_examples: - description: | - Sentinel addresses to use for Redis connection when the redis strategy is defined. Defining this value implies using Redis Sentinel. - ---- -### Strategies - -`kong-plugin-enterprise-proxy-cache` is designed to support storing proxy cache data in different backend formats. Currently the following strategies are provided: -- `memory`: A `lua_shared_dict`. Note that the default dictionary, `kong_db_cache`, is also used by other plugins and elements of Kong to store unrelated database cache entities. Using this dictionary is an easy way to bootstrap the proxy-cache plugin, but it is not recommended for large-scale installations as significant usage will put pressure on other facets of Kong's database caching operations. It is recommended to define a separate `lua_shared_dict` via a custom Nginx template at this time. -- `redis`: Supports Redis and Redis Sentinel deployments. - -### Cache Key - -Kong keys each cache elements based on the request method, the full client request (e.g., the request path and query parameters), and the UUID of either the API or Consumer associated with the request. This also implies that caches are distinct between APIs and/or Consumers. Currently the cache key format is hard-coded and cannot be adjusted. Internally, cache keys are represented as a hexadecimal-encoded MD5 sum of the concatenation of the constituent parts. This is calculated as follows: - -``` -key = md5(UUID | method | request) -``` - -Where `method` is defined via the OpenResty `ngx.req.get_method()` call, and `request` is defined via the Nginx `$request` variable. Kong will return the cache key associated with a given request as the `X-Cache-Key` response header. It is also possible to precalculate the cache key for a given request as noted above. - -### Cache Control - -When the `cache_control` configuration option is enabled, Kong will respect request and response Cache-Control headers as defined by [RFC7234](https://tools.ietf.org/html/rfc7234#section-5.2), with a few exceptions: - -- Cache revalidation is not yet supported, and so directives such as `proxy-revalidate` are ignored. -- Similarly, the behavior of `no-cache` is simplified to exclude the entity from being cached entirely. -- Secondary key calculation via `Vary` is not yet supported. - -### Cache Status - -Kong identifies the status of the request's proxy cache behavior via the `X-Cache-Status` header. There are several possible values for this header: - -- `Miss`: The request could be satisfied in cache, but an entry for the resource was not found in cache, and the request was proxied upstream. -- `Hit`: The request was satisfied and served from cache. -- `Refresh`: The resource was found in cache, but could not satisfy the request, due to Cache-Control behaviors or reaching its hard-coded cache_ttl threshold. -- `Bypass`: The request could not be satisfied from cache based on plugin configuration. - -### Storage TTL - -Kong can store resource entities in the storage engine longer than the prescribed `cache_ttl` or `Cache-Control` values indicate. This allows Kong to maintain a cached copy of a resource past its expiration. This allows clients capable of using `max-age` and `max-stale` headers to request stale copies of data if necessary. - -### Upstream Outages - -Due to an implementation in Kong's core request processing model, at this point the proxy-cache plugin cannot be used to serve stale cache data when an upstream is unreachable. To equip Kong to serve cache data in place of returning an error when an upstream is unreachable, we recommend defining a very large `storage_ttl` (on the order of hours or days) in order to keep stale data in the cache. In the event of an upstream outage, stale data can be considered "fresh" by increasing the `cache_ttl` plugin configuration value. By doing so, data that would have been previously considered stale is now served to the client, before Kong attempts to connect to a failed upstream service. - -### Admin API - -This plugin provides several endpoints to managed cache entities. These endpoints are assigned to the `proxy-cache` RBAC resource. - -The following endpoints are provided on the Admin API to examine and purge cache entities: - -### Retrieve a Cache Entity - -Two separate endpoints are available: one to look up a known plugin instance, and another that searches all proxy-cache plugins data stores for the given cache key. Both endpoints have the same return value. - -**Endpoint** - -
/proxy-cache/:plugin_id/caches/:cache_id
- -| Attributes | Description -| -------------- | ------- -|`plugin_id` | The UUID of the proxy-cache plugin -| `cache_id` | The cache entity key as reported by the X-Cache-Key response header - -**Endpoint** - -
/proxy-cache/:plugin_id/caches/:cache_id
- -| Attributes | Description -| -------------- | ------- -|`cache_id` | The cache entity key as reported by the X-Cache-Key response header - -**Response** - -If the cache entity exists - -``` -HTTP 200 OK -``` - -If the entity with the given key does not exist - -``` -HTTP 400 Not Found -``` - -### Delete Cache Entity - -Two separate endpoints are available: one to look up a known plugin instance, and another that searches all proxy-cache plugins data stores for the given cache key. Both endpoints have the same return value. - -**Endpoint** - -
/proxy-cache/:plugin_id/caches/:cache_id
- -| Attributes | Description -| -------------- | ------- -|`plugin_id` | The UUID of the proxy-cache plugin -|`cache_id` | The cache entity key as reported by the `X-Cache-Key` response header - -**Endpoint** - -
/proxy-cache/:cache_id
- -| Attributes | Description -| -------------- | ------- -|`cache_id` | he cache entity key as reported by the `X-Cache-Key` response header - -**Response** - -If the cache entity exists - -``` -HTTP 204 No Content -``` - -If the entity with the given key does not exist - -``` -HTTP 400 Not Found -``` - -### Purge All Cache Entities -**Endpoint** - -
/proxy-cache/
- -**Response** - -``` -HTTP 204 No Content -``` - -Note that this endpoint purges all cache entities across all `proxy-cache` plugins. diff --git a/app/_hub/kong-inc/proxy-cache/0.33-x.md b/app/_hub/kong-inc/proxy-cache/0.33-x.md deleted file mode 100644 index c34df4cc6aa3..000000000000 --- a/app/_hub/kong-inc/proxy-cache/0.33-x.md +++ /dev/null @@ -1,268 +0,0 @@ ---- - -name: Proxy Caching -publisher: Kong Inc. -version: 0.33-x - -desc: Cache and serve commonly requested responses in Kong -description: | - This plugin provides a reverse proxy cache implementation for Kong. It caches response entities based on configurable response code and content type, as well as request method. It can cache per-Consumer or per-API. Cache entities are stored for a configurable period of time, after which subsequent requests to the same resource will re-fetch and re-store the resource. Cache entities can also be forcefully purged via the Admin API prior to their expiration time. - -enterprise: true -type: plugin -categories: - - traffic-control - -kong_version_compatibility: - community_edition: - compatible: - enterprise_edition: - compatible: - - 0.33-x - -params: - name: proxy-cache - api_id: true - service_id: true - route_id: true - consumer_id: true - config: - - name: response_code - required: - default: 200, 301, 404 - value_in_examples: - description: | - Upstream response status code considered cacheable - - name: request_method - required: - default: GET, HEAD - value_in_examples: - description: | - Downstream request methods considered cacheable - - name: content_type - required: - default: text/plain - value_in_examples: - description: | - Upstream response content types considered cacheable. The plugin performs an exact match against each specified value; for example, if the upstream is expected to respond with a `application/json; charset=utf-8` content-type, the plugin configuration must contain said value or a `Bypass` cache status will be returned - - name: vary_headers - required: - default: - value_in_examples: - description: | - Relevant headers considered for the cache key. If undefined, none of the headers are taken into consideration. - - name: vary_query_params - required: - default: - value_in_examples: - description: | - Relevant query parameters considered for the cache key. If undefined, all params are taken into consideration. - - name: cache_ttl - required: - default: 300 - value_in_examples: - description: | - TTL, in seconds, of cache entities - - name: cache_control - required: - default: false - value_in_examples: - description: | - When enabled, respect the Cache-Control behaviors defined in [RFC7234](https://tools.ietf.org/html/rfc7234#section-5.2) - - name: storage_ttl - required: - default: - value_in_examples: - description: | - Number of seconds to keep resources in the storage backend. This value is independent of `cache_ttl` or resource TTLs defined by Cache-Control behaviors. - - name: strategy - required: - default: - value_in_examples: - description: | - The backing data store in which to hold cache entities - - name: memory.dictionary_name - required: - default: kong_db_cache - value_in_examples: - description: | - The name of the shared dictionary in which to hold cache entities when the memory strategy is selected. Note that this dictionary currently must be defined manually in the Kong Nginx template. - - name: redis.host - required: semi - default: - value_in_examples: - description: | - Host to use for Redis connection when the redis strategy is defined - - name: redis.port - required: semi - default: - value_in_examples: - description: | - Port to use for Redis connection when the redis strategy is defined - - name: redis.timeout - required: semi - default: 2000 - value_in_examples: - description: | - Connection timeout to use for Redis connection when the redis strategy is defined - - name: redis.password - required: semi - default: - value_in_examples: - description: | - Password to use for Redis connection when the redis strategy is defined. If undefined, no AUTH commands are sent to Redis. - - name: redis.database - required: semi - default: 0 - value_in_examples: - description: | - Database to use for Redis connection when the redis strategy is defined - - name: redis.sentinel_master - required: semi - default: - value_in_examples: - description: | - Sentinel master to use for Redis connection when the redis strategy is defined. Defining this value implies using Redis Sentinel. - - name: redis.sentinel_role - required: semi - default: - value_in_examples: - description: | - Sentinel role to use for Redis connection when the redis strategy is defined. Defining this value implies using Redis Sentinel. - - name: redis.sentinel_addresses - required: semi - default: - value_in_examples: - description: | - Sentinel addresses to use for Redis connection when the redis strategy is defined. Defining this value implies using Redis Sentinel. - ---- -### Strategies - -`kong-plugin-enterprise-proxy-cache` is designed to support storing proxy cache data in different backend formats. Currently the following strategies are provided: -- `memory`: A `lua_shared_dict`. Note that the default dictionary, `kong_db_cache`, is also used by other plugins and elements of Kong to store unrelated database cache entities. Using this dictionary is an easy way to bootstrap the proxy-cache plugin, but it is not recommended for large-scale installations as significant usage will put pressure on other facets of Kong's database caching operations. It is recommended to define a separate `lua_shared_dict` via a custom Nginx template at this time. -- `redis`: Supports Redis and Redis Sentinel deployments. - -### Cache Key - -Kong keys each cache elements based on the request method, the full client request (e.g., the request path and query parameters), and the UUID of either the API or Consumer associated with the request. This also implies that caches are distinct between APIs and/or Consumers. Currently the cache key format is hard-coded and cannot be adjusted. Internally, cache keys are represented as a hexadecimal-encoded MD5 sum of the concatenation of the constituent parts. This is calculated as follows: - -``` -key = md5(UUID | method | request) -``` - -Where `method` is defined via the OpenResty `ngx.req.get_method()` call, and `request` is defined via the Nginx `$request` variable. Kong will return the cache key associated with a given request as the `X-Cache-Key` response header. It is also possible to precalculate the cache key for a given request as noted above. - -### Cache Control - -When the `cache_control` configuration option is enabled, Kong will respect request and response Cache-Control headers as defined by [RFC7234](https://tools.ietf.org/html/rfc7234#section-5.2), with a few exceptions: - -- Cache revalidation is not yet supported, and so directives such as `proxy-revalidate` are ignored. -- Similarly, the behavior of `no-cache` is simplified to exclude the entity from being cached entirely. -- Secondary key calculation via `Vary` is not yet supported. - -### Cache Status - -Kong identifies the status of the request's proxy cache behavior via the `X-Cache-Status` header. There are several possible values for this header: - -- `Miss`: The request could be satisfied in cache, but an entry for the resource was not found in cache, and the request was proxied upstream. -- `Hit`: The request was satisfied and served from cache. -- `Refresh`: The resource was found in cache, but could not satisfy the request, due to Cache-Control behaviors or reaching its hard-coded cache_ttl threshold. -- `Bypass`: The request could not be satisfied from cache based on plugin configuration. - -### Storage TTL - -Kong can store resource entities in the storage engine longer than the prescribed `cache_ttl` or `Cache-Control` values indicate. This allows Kong to maintain a cached copy of a resource past its expiration. This allows clients capable of using `max-age` and `max-stale` headers to request stale copies of data if necessary. - -### Upstream Outages - -Due to an implementation in Kong's core request processing model, at this point the proxy-cache plugin cannot be used to serve stale cache data when an upstream is unreachable. To equip Kong to serve cache data in place of returning an error when an upstream is unreachable, we recommend defining a very large `storage_ttl` (on the order of hours or days) in order to keep stale data in the cache. In the event of an upstream outage, stale data can be considered "fresh" by increasing the `cache_ttl` plugin configuration value. By doing so, data that would have been previously considered stale is now served to the client, before Kong attempts to connect to a failed upstream service. - -### Admin API - -This plugin provides several endpoints to managed cache entities. These endpoints are assigned to the `proxy-cache` RBAC resource. - -The following endpoints are provided on the Admin API to examine and purge cache entities: - -### Retrieve a Cache Entity - -Two separate endpoints are available: one to look up a known plugin instance, and another that searches all proxy-cache plugins data stores for the given cache key. Both endpoints have the same return value. - -**Endpoint** - -
/proxy-cache/:plugin_id/caches/:cache_id
- -| Attributes | Description -| -------------- | ------- -|`plugin_id` | The UUID of the proxy-cache plugin -| `cache_id` | The cache entity key as reported by the X-Cache-Key response header - -**Endpoint** - -
/proxy-cache/:plugin_id/caches/:cache_id
- -| Attributes | Description -| -------------- | ------- -|`cache_id` | The cache entity key as reported by the X-Cache-Key response header - -**Response** - -If the cache entity exists - -``` -HTTP 200 OK -``` - -If the entity with the given key does not exist - -``` -HTTP 400 Not Found -``` - -### Delete Cache Entity - -Two separate endpoints are available: one to look up a known plugin instance, and another that searches all proxy-cache plugins data stores for the given cache key. Both endpoints have the same return value. - -**Endpoint** - -
/proxy-cache/:plugin_id/caches/:cache_id
- -| Attributes | Description -| -------------- | ------- -|`plugin_id` | The UUID of the proxy-cache plugin -|`cache_id` | The cache entity key as reported by the `X-Cache-Key` response header - -**Endpoint** - -
/proxy-cache/:cache_id
- -| Attributes | Description -| -------------- | ------- -|`cache_id` | he cache entity key as reported by the `X-Cache-Key` response header - -**Response** - -If the cache entity exists - -``` -HTTP 204 No Content -``` - -If the entity with the given key does not exist - -``` -HTTP 400 Not Found -``` - -### Purge All Cache Entities -**Endpoint** - -
/proxy-cache/
- -**Response** - -``` -HTTP 204 No Content -``` - -Note that this endpoint purges all cache entities across all `proxy-cache` plugins. diff --git a/app/_hub/kong-inc/proxy-cache/0.34-x.md b/app/_hub/kong-inc/proxy-cache/0.34-x.md deleted file mode 100644 index d757b7f9e047..000000000000 --- a/app/_hub/kong-inc/proxy-cache/0.34-x.md +++ /dev/null @@ -1,268 +0,0 @@ ---- - -name: Proxy Caching -publisher: Kong Inc. -version: 0.34-x - -desc: Cache and serve commonly requested responses in Kong -description: | - This plugin provides a reverse proxy cache implementation for Kong. It caches response entities based on configurable response code and content type, as well as request method. It can cache per-Consumer or per-API. Cache entities are stored for a configurable period of time, after which subsequent requests to the same resource will re-fetch and re-store the resource. Cache entities can also be forcefully purged via the Admin API prior to their expiration time. - -enterprise: true -type: plugin -categories: - - traffic-control - -kong_version_compatibility: - community_edition: - compatible: - enterprise_edition: - compatible: - - 0.34-x - -params: - name: proxy-cache - api_id: true - service_id: true - route_id: true - consumer_id: true - config: - - name: response_code - required: - default: 200, 301, 404 - value_in_examples: - description: | - Upstream response status code considered cacheable - - name: request_method - required: - default: GET, HEAD - value_in_examples: - description: | - Downstream request methods considered cacheable - - name: content_type - required: - default: text/plain, application/json - value_in_examples: - description: | - Upstream response content types considered cacheable. The plugin performs an exact match against each specified value; for example, if the upstream is expected to respond with a `application/json; charset=utf-8` content-type, the plugin configuration must contain said value or a `Bypass` cache status will be returned - - name: vary_headers - required: false - default: - value_in_examples: - description: | - Relevant headers considered for the cache key. If undefined, none of the headers are taken into consideration. - - name: vary_query_params - required: false - default: - value_in_examples: - description: | - Relevant query parameters considered for the cache key. If undefined, all params are taken into consideration. - - name: cache_ttl - required: - default: 300 - value_in_examples: - description: | - TTL, in seconds, of cache entities - - name: cache_control - required: - default: false - value_in_examples: - description: | - When enabled, respect the Cache-Control behaviors defined in [RFC7234](https://tools.ietf.org/html/rfc7234#section-5.2) - - name: storage_ttl - required: false - default: - value_in_examples: - description: | - Number of seconds to keep resources in the storage backend. This value is independent of `cache_ttl` or resource TTLs defined by Cache-Control behaviors. - - name: strategy - required: - default: - value_in_examples: - description: | - The backing data store in which to hold cache entities. Accepted values are; `memory`, and `redis`. - - name: memory.dictionary_name - required: - default: kong_db_cache - value_in_examples: - description: | - The name of the shared dictionary in which to hold cache entities when the memory strategy is selected. Note that this dictionary currently must be defined manually in the Kong Nginx template. - - name: redis.host - required: semi - default: - value_in_examples: - description: | - Host to use for Redis connection when the redis strategy is defined - - name: redis.port - required: semi - default: - value_in_examples: - description: | - Port to use for Redis connection when the redis strategy is defined - - name: redis.timeout - required: semi - default: 2000 - value_in_examples: - description: | - Connection timeout to use for Redis connection when the redis strategy is defined - - name: redis.password - required: semi - default: - value_in_examples: - description: | - Password to use for Redis connection when the redis strategy is defined. If undefined, no AUTH commands are sent to Redis. - - name: redis.database - required: semi - default: 0 - value_in_examples: - description: | - Database to use for Redis connection when the redis strategy is defined - - name: redis.sentinel_master - required: semi - default: - value_in_examples: - description: | - Sentinel master to use for Redis connection when the redis strategy is defined. Defining this value implies using Redis Sentinel. - - name: redis.sentinel_role - required: semi - default: - value_in_examples: - description: | - Sentinel role to use for Redis connection when the redis strategy is defined. Defining this value implies using Redis Sentinel. - - name: redis.sentinel_addresses - required: semi - default: - value_in_examples: - description: | - Sentinel addresses to use for Redis connection when the redis strategy is defined. Defining this value implies using Redis Sentinel. - ---- -### Strategies - -`kong-plugin-enterprise-proxy-cache` is designed to support storing proxy cache data in different backend formats. Currently the following strategies are provided: -- `memory`: A `lua_shared_dict`. Note that the default dictionary, `kong_db_cache`, is also used by other plugins and elements of Kong to store unrelated database cache entities. Using this dictionary is an easy way to bootstrap the proxy-cache plugin, but it is not recommended for large-scale installations as significant usage will put pressure on other facets of Kong's database caching operations. It is recommended to define a separate `lua_shared_dict` via a custom Nginx template at this time. -- `redis`: Supports Redis and Redis Sentinel deployments. - -### Cache Key - -Kong keys each cache elements based on the request method, the full client request (e.g., the request path and query parameters), and the UUID of either the API or Consumer associated with the request. This also implies that caches are distinct between APIs and/or Consumers. Currently the cache key format is hard-coded and cannot be adjusted. Internally, cache keys are represented as a hexadecimal-encoded MD5 sum of the concatenation of the constituent parts. This is calculated as follows: - -``` -key = md5(UUID | method | request) -``` - -Where `method` is defined via the OpenResty `ngx.req.get_method()` call, and `request` is defined via the Nginx `$request` variable. Kong will return the cache key associated with a given request as the `X-Cache-Key` response header. It is also possible to precalculate the cache key for a given request as noted above. - -### Cache Control - -When the `cache_control` configuration option is enabled, Kong will respect request and response Cache-Control headers as defined by [RFC7234](https://tools.ietf.org/html/rfc7234#section-5.2), with a few exceptions: - -- Cache revalidation is not yet supported, and so directives such as `proxy-revalidate` are ignored. -- Similarly, the behavior of `no-cache` is simplified to exclude the entity from being cached entirely. -- Secondary key calculation via `Vary` is not yet supported. - -### Cache Status - -Kong identifies the status of the request's proxy cache behavior via the `X-Cache-Status` header. There are several possible values for this header: - -- `Miss`: The request could be satisfied in cache, but an entry for the resource was not found in cache, and the request was proxied upstream. -- `Hit`: The request was satisfied and served from cache. -- `Refresh`: The resource was found in cache, but could not satisfy the request, due to Cache-Control behaviors or reaching its hard-coded cache_ttl threshold. -- `Bypass`: The request could not be satisfied from cache based on plugin configuration. - -### Storage TTL - -Kong can store resource entities in the storage engine longer than the prescribed `cache_ttl` or `Cache-Control` values indicate. This allows Kong to maintain a cached copy of a resource past its expiration. This allows clients capable of using `max-age` and `max-stale` headers to request stale copies of data if necessary. - -### Upstream Outages - -Due to an implementation in Kong's core request processing model, at this point the proxy-cache plugin cannot be used to serve stale cache data when an upstream is unreachable. To equip Kong to serve cache data in place of returning an error when an upstream is unreachable, we recommend defining a very large `storage_ttl` (on the order of hours or days) in order to keep stale data in the cache. In the event of an upstream outage, stale data can be considered "fresh" by increasing the `cache_ttl` plugin configuration value. By doing so, data that would have been previously considered stale is now served to the client, before Kong attempts to connect to a failed upstream service. - -### Admin API - -This plugin provides several endpoints to managed cache entities. These endpoints are assigned to the `proxy-cache` RBAC resource. - -The following endpoints are provided on the Admin API to examine and purge cache entities: - -### Retrieve a Cache Entity - -Two separate endpoints are available: one to look up a known plugin instance, and another that searches all proxy-cache plugins data stores for the given cache key. Both endpoints have the same return value. - -**Endpoint** - -
/proxy-cache/:plugin_id/caches/:cache_id
- -| Attributes | Description -| -------------- | ------- -|`plugin_id` | The UUID of the proxy-cache plugin -| `cache_id` | The cache entity key as reported by the X-Cache-Key response header - -**Endpoint** - -
/proxy-cache/:plugin_id/caches/:cache_id
- -| Attributes | Description -| -------------- | ------- -|`cache_id` | The cache entity key as reported by the X-Cache-Key response header - -**Response** - -If the cache entity exists - -``` -HTTP 200 OK -``` - -If the entity with the given key does not exist - -``` -HTTP 400 Not Found -``` - -### Delete Cache Entity - -Two separate endpoints are available: one to look up a known plugin instance, and another that searches all proxy-cache plugins data stores for the given cache key. Both endpoints have the same return value. - -**Endpoint** - -
/proxy-cache/:plugin_id/caches/:cache_id
- -| Attributes | Description -| -------------- | ------- -|`plugin_id` | The UUID of the proxy-cache plugin -|`cache_id` | The cache entity key as reported by the `X-Cache-Key` response header - -**Endpoint** - -
/proxy-cache/:cache_id
- -| Attributes | Description -| -------------- | ------- -|`cache_id` | he cache entity key as reported by the `X-Cache-Key` response header - -**Response** - -If the cache entity exists - -``` -HTTP 204 No Content -``` - -If the entity with the given key does not exist - -``` -HTTP 400 Not Found -``` - -### Purge All Cache Entities -**Endpoint** - -
/proxy-cache/
- -**Response** - -``` -HTTP 204 No Content -``` - -Note that this endpoint purges all cache entities across all `proxy-cache` plugins. diff --git a/app/_hub/kong-inc/proxy-cache/_index.md b/app/_hub/kong-inc/proxy-cache/_index.md index 93fcf1d6873b..819e842e5570 100644 --- a/app/_hub/kong-inc/proxy-cache/_index.md +++ b/app/_hub/kong-inc/proxy-cache/_index.md @@ -1,7 +1,6 @@ --- name: Proxy Cache publisher: Kong Inc. -version: 1.3-x desc: Cache and serve commonly requested responses in Kong description: | This plugin provides a reverse proxy cache implementation for Kong. It caches response entities based on configurable response code and content type, as well as request method. It can cache per-Consumer or per-API. Cache entities are stored for a configurable period of time, after which subsequent requests to the same resource will re-fetch and re-store the resource. Cache entities can also be forcefully purged via the Admin API prior to their expiration time. @@ -10,33 +9,9 @@ categories: - traffic-control kong_version_compatibility: community_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x + compatible: true enterprise_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x + compatible: true params: name: proxy-cache service_id: true diff --git a/app/_hub/kong-inc/proxy-cache/versions.yml b/app/_hub/kong-inc/proxy-cache/versions.yml index 84f275a0a794..7193576a3779 100644 --- a/app/_hub/kong-inc/proxy-cache/versions.yml +++ b/app/_hub/kong-inc/proxy-cache/versions.yml @@ -1,5 +1,12 @@ -- release: 0.36-x -- release: 0.34-x -- release: 0.33-x -- release: 0.32-x -- release: 0.31-x +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 1.3.2 + 2.7.x: 1.3.2 + 2.6.x: 1.3.1 + 2.5.x: 1.3.0 + 2.4.x: 1.3.0 + 2.3.x: 1.3.0 + 2.2.x: 1.3.0 + 2.1.x: 1.3.0 diff --git a/app/_hub/kong-inc/rate-limiting-advanced/0.31.x.md b/app/_hub/kong-inc/rate-limiting-advanced/0.31.x.md deleted file mode 100644 index 18248044849c..000000000000 --- a/app/_hub/kong-inc/rate-limiting-advanced/0.31.x.md +++ /dev/null @@ -1,163 +0,0 @@ ---- - -name: Rate Limiting Advanced -publisher: Kong Inc. -version: 0.31.x - -desc: Upgrades Kong Rate Limiting with more flexibility and higher performance -description: | - The Rate Limiting Advanced plugin for Kong Gateway is a re-engineered - version of the incredibly popular Kong Rate Limiting plugin, with greatly - enhanced configuration options and performance. - -enterprise: true -type: plugin -categories: - - traffic-control - -kong_version_compatibility: - community_edition: - compatible: - enterprise_edition: - compatible: - - 0.36-x - - 0.35-x - - 0.34-x - -params: - name: rate-limiting-advanced - api_id: true - service_id: true - route_id: true - consumer_id: true - config: - - name: limit - required: - default: - value_in_examples: - description: | - One of more request per window to apply - - name: window_size - required: - default: - value_in_examples: - description: | - One more more window sizes to apply (defined in seconds) - - name: identifier - required: - default: consumer - value_in_examples: - description: | - How to define the rate limit key. Can be `ip`, `credential`, `consumer`, `service`, or `header`. - - name: header_name - required: semi - description: | - Header name to use as the rate limit key when the `header` identifier is defined. - - name: dictionary_name - required: - default: kong_rate_limiting_counters - value_in_examples: - description: | - The shared dictionary where counters will be stored until the next sync cycle - - name: sync_rate - required: - default: - value_in_examples: - description: | - How often to sync counter data to the central data store. A value of 0 - results in synchronous behavior; a value of -1 ignores sync behavior - entirely and only stores counters in node memory. A value greater than - 0 will sync the counters in that many number of seconds. - - name: namespace - required: false - default: random string - value_in_examples: - description: | - The rate limiting library namespace to use for this plugin instance. Counter data and sync configuration is shared in a namespace. - - name: strategy - required: - default: cluster - value_in_examples: - description: | - The sync strategy to use; `cluster` and `redis` are supported - - name: redis.host - required: semi - default: - value_in_examples: - description: | - Host to use for Redis connection when the `redis` strategy is defined - - name: redis.port - required: semi - default: - value_in_examples: - description: | - Port to use for Redis connection when the `redis` strategy is defined - - name: redis.timeout - required: semi - default: 2000 - value_in_examples: - description: | - Connection timeout (in milliseconds) to use for Redis connection when the `redis` strategy is defined - - name: redis.password - required: semi - default: - value_in_examples: - description: | - Password to use for Redis connection when the `redis` strategy is defined. If undefined, no AUTH commands are sent to Redis. - - name: redis.database - required: semi - default: 0 - value_in_examples: - description: | - Database to use for Redis connection when the `redis` strategy is defined - - name: redis.sentinel_master - required: semi - default: - value_in_examples: - description: | - Sentinel master to use for Redis connection when the `redis` strategy is defined. Defining this value implies using Redis Sentinel. - - name: redis.sentinel_role - required: semi - default: - value_in_examples: - description: | - Sentinel role to use for Redis connection when the `redis` strategy is defined. Defining this value implies using Redis Sentinel. - - name: redis.sentinel_addresses - required: semi - default: - value_in_examples: - description: | - Sentinel addresses to use for Redis connection when the `redis` strategy is defined. Defining this value implies using Redis Sentinel. - - name: redis.cluster_addresses - required: semi - default: - value_in_examples: - description: | - Cluster addresses to use for Redis connection when the `redis` strategy is defined. Defining this value implies using Redis cluster. - - name: window_type - required: - default: sliding - value_in_examples: - description: | - This sets the time window to either `sliding` or `fixed` - extra: | - **Note: Redis configuration values are ignored if the `cluster` strategy is used.** - - **Note: PostgreSQL 9.5+ is required when using the `cluster` strategy with `postgres` as the backing Kong cluster data store. This requirement varies from the PostgreSQL 9.4+ requirement as described in the Kong Community Edition documentation.** - - **Note: The `dictionary_name` directive was added to prevent the usage of the `kong` shared dictionary, which could lead to `no memory` errors** - ---- - -### Notes - -An arbitrary number of limits/window sizes can be applied per plugin instance. This allows users to create multiple rate limiting windows (e.g., rate limit per minute and per hour, and/or per any arbitrary window size); because of limitation with Kong's plugin configuration interface, each *nth* limit will apply to each *nth* window size. For example: - -```bash -$ curl -i -X POST http://kong:8001/services/{service}/plugins \ - --data name=rate-limiting-advanced \ - --data config.limit=10,100 \ - --data config.window_size=60,3600 \ - --data config.sync_rate=10 -``` -This will apply rate limiting policies, one of which will trip when 10 hits have been counted in 60 seconds, or when 100 hits have been counted in 3600 seconds. For more information, please see [Enterprise Rate Limiting Library](https://docs.konghq.com/gateway/latest/reference/rate-limiting/). diff --git a/app/_hub/kong-inc/rate-limiting-advanced/1.0.x.md b/app/_hub/kong-inc/rate-limiting-advanced/1.0.x.md deleted file mode 100644 index 9f284a8429b0..000000000000 --- a/app/_hub/kong-inc/rate-limiting-advanced/1.0.x.md +++ /dev/null @@ -1,225 +0,0 @@ ---- - -name: Rate Limiting Advanced -publisher: Kong Inc. -version: 1.0.x - -desc: Upgrades Kong Rate Limiting with more flexibility and higher performance -description: | - The Rate Limiting Advanced plugin for Kong Gateway is a re-engineered - version of the incredibly popular Kong Rate Limiting plugin, with greatly - enhanced configuration options and performance. - -enterprise: true -type: plugin -categories: - - traffic-control - -kong_version_compatibility: - community_edition: - compatible: - enterprise_edition: - compatible: - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x - - 0.35-x - - 0.34-x - -params: - name: rate-limiting-advanced - api_id: true - service_id: true - route_id: true - consumer_id: true - config: - - name: limit - required: true - default: - value_in_examples: [ "5" ] - description: | - One or more requests-per-window limits to apply. - - name: window_size - required: true - default: - value_in_examples: [ "30" ] - description: | - One or more window sizes to apply a limit to (defined in seconds). - - name: identifier - required: - default: consumer - value_in_examples: - description: | - How to define the rate limit key. Can be `ip`, `credential`, `consumer`, `service`, or `header`. - - name: header_name - required: semi - description: | - Header name to use as the rate limit key when the `header` identifier is defined. - - name: dictionary_name - required: - default: kong_rate_limiting_counters - value_in_examples: - description: | - The shared dictionary where counters will be stored until the next sync cycle. - - name: sync_rate - required: true - default: - value_in_examples: -1 - description: | - How often to sync counter data to the central data store. A value of 0 - results in synchronous behavior; a value of -1 ignores sync behavior - entirely and only stores counters in node memory. A value greater than - 0 will sync the counters in that many number of seconds. - - name: namespace - required: false - default: random string - value_in_examples: - description: | - The rate limiting library namespace to use for this plugin instance. Counter data and sync configuration is shared in a namespace. - - name: strategy - required: - default: cluster - value_in_examples: - description: | - The sync strategy to use; `cluster` and `redis` are supported. Hybrid mode does not support the `cluster` strategy. - - name: redis.host - required: semi - default: - value_in_examples: - description: | - Host to use for Redis connection when the `redis` strategy is defined. - - name: redis.port - required: semi - default: - value_in_examples: - description: | - Port to use for Redis connection when the `redis` strategy is defined. - - name: redis.timeout - required: semi - default: 2000 - value_in_examples: - description: | - Connection timeout (in milliseconds) to use for Redis connection when the `redis` strategy is defined. - - name: redis.password - required: semi - default: - value_in_examples: - description: | - Password to use for Redis connection when the `redis` strategy is defined. If undefined, no AUTH commands are sent to Redis. - - name: redis.database - required: semi - default: 0 - value_in_examples: - description: | - Database to use for Redis connection when the `redis` strategy is defined. - - name: redis.sentinel_master - required: semi - default: - value_in_examples: - description: | - Sentinel master to use for Redis connection when the `redis` strategy is defined. Defining this value implies using Redis Sentinel. - - name: redis.sentinel_password - required: semi - default: - value_in_examples: - description: | - Sentinel password to authenticate with a Redis Sentinel instance. - **Note:** This parameter is only available for Kong Gateway versions - 1.3.0.2 and later. - - name: redis.sentinel_role - required: semi - default: - value_in_examples: - description: | - Sentinel role to use for Redis connection when the `redis` strategy is defined. Defining this value implies using Redis Sentinel. - - name: redis.sentinel_addresses - required: semi - default: - value_in_examples: - description: | - Sentinel addresses to use for Redis connection when the `redis` strategy is defined. Defining this value implies using Redis Sentinel. - - name: redis.cluster_addresses - required: semi - default: - value_in_examples: - description: | - Cluster addresses to use for Redis connection when the `redis` strategy is defined. Defining this value implies using Redis cluster. - - name: window_type - required: - default: sliding - value_in_examples: - description: | - This sets the time window to either `sliding` or `fixed`. - extra: | - **Notes:** - - * The plugin does not support the `cluster` strategy in - [hybrid mode](/gateway/latest/plan-and-deploy/hybrid-mode/). - The `redis` strategy must be used instead. - - * Redis configuration values are ignored if the `cluster` strategy is used. - - * PostgreSQL 9.5+ is required when using the `cluster` strategy with `postgres` as the backing Kong cluster data store. This requirement varies from the PostgreSQL 9.4+ requirement as described in the Kong Community Edition documentation. - - * The `dictionary_name` directive was added to prevent the usage of the `kong` shared dictionary, which could lead to `no memory` errors. - ---- - -## Headers sent to the client - -When this plugin is enabled, Kong will send some additional headers back to the client indicating the allowed limits, how many requests are available, and how long it will take until the quota will be restored. For example: - -``` -RateLimit-Limit: 6 -RateLimit-Remaining: 4 -RateLimit-Reset: 47 -``` - -The plugin also sends headers indicating the limits in the time frame and the number of remaining requests: - -``` -X-RateLimit-Limit-Minute: 10 -X-RateLimit-Remaining-Minute: 9 -``` - -Or, it will return a combination of more time limits, if more than one is being set: - -``` -X-RateLimit-Limit-Second: 5 -X-RateLimit-Remaining-Second: 4 -X-RateLimit-Limit-Minute: 10 -X-RateLimit-Remaining-Minute: 9 -``` - -If any of the limits configured has been reached, the plugin returns an `HTTP/1.1 429` status code to the client with the following JSON body: - -```json -{ "message": "API rate limit exceeded" } -``` - -The [`Retry-After`] header will be present on `429` errors to indicate how long the service is expected to be unavailable to the client. When using `window_type=sliding`, `RateLimit-Reset`, and `Retry-After` may increase due to the rate calculation for the sliding window. - -**NOTE**: - -
-The headers `RateLimit-Limit`, `RateLimit-Remaining`, and `RateLimit-Reset` are based on the Internet-Draft RateLimit Header Fields for HTTP and may change in the future to respect specification updates. -
- -### Notes - -An arbitrary number of limits/window sizes can be applied per plugin instance. This allows users to create multiple rate limiting windows (e.g., rate limit per minute and per hour, and/or per any arbitrary window size); because of limitation with Kong's plugin configuration interface, each *nth* limit will apply to each *nth* window size. For example: - -```bash -$ curl -X POST http://kong:8001/services/{service}/plugins \ - --data name=rate-limiting-advanced \ - --data config.limit=10 \ - --data config.limit=100 \ - --data config.window_size=60 \ - --data config.window_size=3600 \ - --data config.sync_rate=10 -``` - -This will apply rate limiting policies, one of which will trip when 10 hits have been counted in 60 seconds, or when 100 hits have been counted in 3600 seconds. For more information, please see [Enterprise Rate Limiting Library](https://docs.konghq.com/enterprise/references/rate-limiting/). - -[`Retry-After`]: https://tools.ietf.org/html/rfc7231#section-7.1.3 diff --git a/app/_hub/kong-inc/rate-limiting-advanced/1.3.x.md b/app/_hub/kong-inc/rate-limiting-advanced/1.3.x.md deleted file mode 100644 index a0d6eb1afbc5..000000000000 --- a/app/_hub/kong-inc/rate-limiting-advanced/1.3.x.md +++ /dev/null @@ -1,326 +0,0 @@ ---- - -name: Rate Limiting Advanced -publisher: Kong Inc. -version: 1.3.x - -desc: Upgrades Kong Rate Limiting with more flexibility and higher performance -description: | - The Rate Limiting Advanced plugin for Kong Gateway is a re-engineered - version of the incredibly popular Kong Community - [Rate Limiting plugin](/hub/kong-inc/rate-limiting/), - with greatly enhanced configuration options and performance. - -type: plugin -enterprise: true -categories: - - traffic-control - -kong_version_compatibility: - community_edition: - compatible: - enterprise_edition: - compatible: - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x - - 0.35-x - - 0.34-x - -params: - name: rate-limiting-advanced - service_id: true - route_id: true - consumer_id: true - protocols: ["http", "https", "grpc", "grpcs"] - config: - - name: limit - required: true - default: - value_in_examples: [ "5" ] - datatype: array of number elements - description: | - One or more requests-per-window limits to apply. There must be a matching - number of window limits and sizes specified. - - name: window_size - required: true - default: - value_in_examples: [ "30" ] - datatype: array of number elements - description: | - One or more window sizes to apply a limit to (defined in seconds). There - must be a matching number of window limits and sizes specified. - - name: identifier - required: true - default: consumer - value_in_examples: consumer - datatype: string - description: | - How to define the rate limit key. Can be `ip`, `credential`, `consumer`, `service`, or `header`. - - name: header_name - required: semi - datatype: string - description: | - Header name to use as the rate limit key when the `header` identifier is defined. - - name: dictionary_name - required: true - default: kong_rate_limiting_counters - value_in_examples: - datatype: string - description: | - The shared dictionary where counters will be stored until the next sync cycle. - - name: sync_rate - required: true - default: - value_in_examples: -1 - datatype: number - description: | - How often to sync counter data to the central data store. A value of 0 - results in synchronous behavior; a value of -1 ignores sync behavior - entirely and only stores counters in node memory. A value greater than - 0 will sync the counters in the specified number of seconds. - - name: namespace - required: true - default: random_auto_generated_string - value_in_examples: - datatype: string - description: | - The rate limiting library namespace to use for this plugin instance. Counter - data and sync configuration is shared in a namespace. - - name: strategy - required: true - default: cluster - value_in_examples: - datatype: string - description: | - The sync strategy to use; `cluster` and `redis` are supported. Hybrid mode does - not support the `cluster` strategy. - - name: hide_client_headers - required: false - default: false - value_in_examples: false - datatype: boolean - description: | - Optionally hide informative response headers. Available options: `true` or `false`. - - name: redis.host - required: semi - default: - value_in_examples: - datatype: string - description: | - Host to use for Redis connection when the `redis` strategy is defined. - - name: redis.port - required: semi - default: 6379 - value_in_examples: - datatype: integer - description: | - Specifies the Redis server port when using the `redis` strategy. Must be a - value between 0 and 65535. Default: 6379. - - name: redis.ssl - required: false - default: false - value_in_examples: - datatype: boolean - description: | - If set to true, then uses SSL to connect to Redis. - - **Note:** This parameter is only available for Kong Gateway versions - 2.2.x and later. - - name: redis.ssl_verify - required: false - default: false - value_in_examples: - datatype: boolean - description: | - If set to true, then verifies the validity of the server SSL certificate. Note that you need to configure the - [lua_ssl_trusted_certificate](/gateway/latest/reference/configuration/#lua_ssl_trusted_certificate) - to specify the CA (or server) certificate used by your redis server. You may also need to configure - [lua_ssl_verify_depth](/gateway/latest/reference/configuration/#lua_ssl_verify_depth) accordingly. - - **Note:** This parameter is only available for Kong Gateway versions - 2.2.x and later. - - name: redis.server_name - required: false - default: - value_in_examples: - datatype: string - description: | - Specifies the server name for the new TLS extension Server Name Indication (SNI) when connecting over SSL. - - **Note:** This parameter is only available for Kong Gateway versions - 2.2.x and later. - - name: redis.timeout - required: semi - default: 2000 - value_in_examples: - datatype: number - description: | - Connection timeout (in milliseconds) to use for Redis connection when the `redis` strategy is defined. - - name: redis.password - required: semi - default: - value_in_examples: - datatype: string - description: | - Password to use for Redis connection when the `redis` strategy is defined. If undefined, no AUTH commands are sent to Redis. - - name: redis.database - required: semi - default: 0 - value_in_examples: - datatype: integer - description: | - Database to use for Redis connection when the `redis` strategy is defined. - - name: redis.sentinel_master - required: semi - default: - value_in_examples: - datatype: string - description: | - Sentinel master to use for Redis connections when the `redis` strategy is defined. - Defining this value implies using Redis Sentinel. - - name: redis.sentinel_password - required: semi - default: - value_in_examples: - datatype: string - description: | - Sentinel password to authenticate with a Redis Sentinel instance. - **Note:** This parameter is only available for Kong Gateway versions - 1.3.0.2 and later. - - name: redis.sentinel_role - required: semi - default: - value_in_examples: - datatype: string - description: | - Sentinel role to use for Redis connections when the `redis` strategy is defined. - Defining this value implies using Redis Sentinel. Available options: `master`, `slave`, `any`. - - name: redis.sentinel_addresses - required: semi - default: - value_in_examples: - datatype: array of string elements - description: | - Sentinel addresses to use for Redis connections when the `redis` strategy is defined. - Defining this value implies using Redis Sentinel. Each string element must - be a hostname. The minimum length of the array is 1 element. - - name: redis.cluster_addresses - required: semi - default: - value_in_examples: - datatype: array of string elements - description: | - Cluster addresses to use for Redis connections when the `redis` strategy is defined. - Defining this value implies using Redis cluster. Each string element must - be a hostname. The minimum length of the array is 1 element. - - name: window_type - required: true - default: sliding - value_in_examples: - datatype: string - description: | - Sets the time window type to either `sliding` (default) or `fixed`. - extra: | - **Notes:** - - * The plugin does not support the `cluster` strategy in - [hybrid mode](/gateway/latest/plan-and-deploy/hybrid-mode/). - The `redis` strategy must be used instead. - - * Redis configuration values are ignored if the `cluster` strategy is used. - - * PostgreSQL 9.5+ is required when using the `cluster` strategy with `postgres` as the backing Kong cluster data store. - - * The `dictionary_name` directive was added to prevent the usage of the `kong` shared dictionary, - which could lead to `no memory` errors. - ---- - -### Headers sent to the client - -When this plugin is enabled, Kong sends some additional headers back to the client -indicating the allowed limits, how many requests are available, and how long it will take -until the quota will be restored. - -For example: - -``` -RateLimit-Limit: 6 -RateLimit-Remaining: 4 -RateLimit-Reset: 47 -``` - -The plugin also sends headers indicating the limits in the time frame and the number -of remaining minutes: - -``` -X-RateLimit-Limit-Minute: 10 -X-RateLimit-Remaining-Minute: 9 -``` - -You can optionally hide the limit and remaining headers with the `hide_client_headers` option. - -If more than one limit is being set, the plugin returns a combination of more time limits: - -``` -X-RateLimit-Limit-Second: 5 -X-RateLimit-Remaining-Second: 4 -X-RateLimit-Limit-Minute: 10 -X-RateLimit-Remaining-Minute: 9 -``` - -If any of the limits configured has been reached, the plugin returns an `HTTP/1.1 429` status -code to the client with the following JSON body: - -```json -{ "message": "API rate limit exceeded" } -``` - -The [`Retry-After`] header will be present on `429` errors to indicate how long the service is -expected to be unavailable to the client. When using `window_type=sliding` and `RateLimit-Reset`, `Retry-After` -may increase due to the rate calculation for the sliding window. - -
-The headers `RateLimit-Limit`, `RateLimit-Remaining`, and `RateLimit-Reset` are based on the Internet-Draft -RateLimit Header Fields for HTTP -and may change in the future to respect specification updates. -
- -### Multiple Limits and Window Sizes {#multi-limits-windows} - -An arbitrary number of limits/window sizes can be applied per plugin instance. This allows you to create -multiple rate limiting windows (e.g., rate limit per minute and per hour, and per any arbitrary window size). -Because of limitations with Kong's plugin configuration interface, each *nth* limit will apply to each *nth* window size. -For example: - -```bash -$ curl -X POST http://kong:8001/services/{service}/plugins \ - --data name=rate-limiting-advanced \ - --data config.limit=10 \ - --data config.limit=100 \ - --data config.window_size=60 \ - --data config.window_size=3600 \ - --data config.sync_rate=10 -``` - -This example applies rate limiting policies, one of which will trip when 10 hits have been counted in 60 seconds, -or the other when 100 hits have been counted in 3600 seconds. For more information, see the -[Enterprise Rate Limiting Library](/gateway/latest/reference/rate-limiting/). - -The number of configured window sizes and limits parameters must be equal (as shown above); -otherwise, an error occurs: - -```bash -You must provide the same number of windows and limits -``` - -### Fallback to IP - -When the selected strategy cannot be retrieved, the `rate-limiting-advanced` plugin will fall back -to limit using IP as the identifier. This can happen for several reasons, such as the -selected header was not sent by the client or the configured service was not found. - -[`Retry-After`]: https://tools.ietf.org/html/rfc7231#section-7.1.3 diff --git a/app/_hub/kong-inc/rate-limiting-advanced/1.4.x.md b/app/_hub/kong-inc/rate-limiting-advanced/1.4.x.md deleted file mode 100644 index f93937d6e03f..000000000000 --- a/app/_hub/kong-inc/rate-limiting-advanced/1.4.x.md +++ /dev/null @@ -1,382 +0,0 @@ ---- - -name: Rate Limiting Advanced -publisher: Kong Inc. -version: 1.4.x - -desc: Upgrades Kong Rate Limiting with more flexibility and higher performance -description: | - The Rate Limiting Advanced plugin for Konnect Enterprise is a re-engineered version of the Kong Gateway (OSS) [Rate Limiting plugin](/hub/kong-inc/rate-limiting/). - - As compared to the standard Rate Limiting plugin, Rate Limiting Advanced provides: - * Additional configurations: `limit`, `window_size`, and `sync_rate` - * Support for Redis Sentinel, Redis cluster, and Redis SSL - * Increased performance: Rate Limiting Advanced has better throughput performance with better accuracy. Configure `sync_rate` to periodically sync with backend storage. - * More limiting algorithms to choose from: These algorithms are more accurate and they enable configuration with more specificity. Learn more about our algorithms in [How to Design a Scalable Rate Limiting Algorithm](https://konghq.com/blog/how-to-design-a-scalable-rate-limiting-algorithm). - -type: plugin -enterprise: true -categories: - - traffic-control - -kong_version_compatibility: - community_edition: - compatible: - enterprise_edition: - compatible: - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x - - -params: - name: rate-limiting-advanced - service_id: true - route_id: true - consumer_id: true - protocols: ["http", "https", "grpc", "grpcs"] - dbless_compatible: partially - dbless_explanation: | - The cluster strategy is not supported in DB-less and hybrid modes. For Kong - Gateway in DB-less or hybrid mode, use the `redis` strategy. - config: - - name: limit - required: true - default: - value_in_examples: [ "5" ] - datatype: array of number elements - description: | - One or more requests-per-window limits to apply. There must be a matching - number of window limits and sizes specified. - - name: window_size - required: true - default: - value_in_examples: [ "30" ] - datatype: array of number elements - description: | - One or more window sizes to apply a limit to (defined in seconds). There - must be a matching number of window limits and sizes specified. - - name: identifier - required: true - default: consumer - value_in_examples: consumer - datatype: string - description: | - How to define the rate limit key. Can be `ip`, `credential`, `consumer`, `service`, or `header`. - - name: header_name - required: semi - datatype: string - description: | - Header name to use as the rate limit key when the `header` identifier is defined. - - name: dictionary_name - required: true - default: kong_rate_limiting_counters - value_in_examples: - datatype: string - description: | - The shared dictionary where counters will be stored until the next sync cycle. - - name: sync_rate - required: true - default: - value_in_examples: -1 - datatype: number - description: | - How often to sync counter data to the central data store. A value of 0 - results in synchronous behavior; a value of -1 ignores sync behavior - entirely and only stores counters in node memory. A value greater than - 0 will sync the counters in the specified number of seconds. - - name: namespace - required: true - default: random_auto_generated_string - value_in_examples: - datatype: string - description: | - The rate limiting library namespace to use for this plugin instance. Counter - data and sync configuration is shared in a namespace. - - name: strategy - required: true - default: cluster - value_in_examples: cluster - datatype: string - description: | - The rate-limiting strategy to use for retrieving and incrementing the - limits. Available values are: - - `cluster`: Counters are stored in the Kong datastore and shared across - the nodes. - - `redis`: Counters are stored on a Redis server and shared - across the nodes. - - In DB-less and hybrid modes, the `cluster` config strategy is not - supported. - - In Konnect Cloud, the default strategy is `redis`. - - {:.important} - > There is no local storage strategy. However, you can achieve local - rate limiting by using a placeholder `strategy` value (either `cluster` or `redis`) - and a `sync_rate` of `-1`. This setting stores counters in-memory on the - node. -

If using `redis` as the placeholder value, you must fill in all - additional `redis` configuration parameters with placeholder values. - - For details on which strategy should be used, refer to the - [implementation considerations](/hub/kong-inc/rate-limiting/#implementation-considerations). - - name: hide_client_headers - required: false - default: false - value_in_examples: false - datatype: boolean - description: | - Optionally hide informative response headers. Available options: `true` or `false`. - - name: redis.host - required: semi - default: - value_in_examples: - datatype: string - description: | - Host to use for Redis connection when the `redis` strategy is defined. - - name: redis.port - required: semi - default: 6379 - value_in_examples: - datatype: integer - description: | - Specifies the Redis server port when using the `redis` strategy. Must be a - value between 0 and 65535. Default: 6379. - - name: redis.ssl - required: false - default: false - value_in_examples: - datatype: boolean - description: | - If set to true, then uses SSL to connect to Redis. - - **Note:** This parameter is only available for Kong Gateway versions - 2.2.x and later. - - name: redis.ssl_verify - required: false - default: false - value_in_examples: - datatype: boolean - description: | - If set to true, then verifies the validity of the server SSL certificate. Note that you need to configure the - [lua_ssl_trusted_certificate](/gateway/latest/reference/configuration/#lua_ssl_trusted_certificate) - to specify the CA (or server) certificate used by your redis server. You may also need to configure - [lua_ssl_verify_depth](/gateway/latest/reference/configuration/#lua_ssl_verify_depth) accordingly. - - **Note:** This parameter is only available for Kong Gateway versions - 2.2.x and later. - - name: redis.server_name - required: false - default: - value_in_examples: - datatype: string - description: | - Specifies the server name for the new TLS extension Server Name Indication (SNI) when connecting over SSL. - - **Note:** This parameter is only available for Kong Gateway versions - 2.2.x and later. - - name: redis.timeout - required: semi - default: 2000 - value_in_examples: - datatype: number - description: | - Connection timeout (in milliseconds) to use for Redis connection when the `redis` strategy is defined. - This field is deprecated and replaced with `redis.connect_timeout`, `redis.send_timeout`, and `redis.read_timeout`. - The `redis.timeout` field will continue to work in a backwards compatible way, but it is recommended to use the replacement fields. - If set to something other than the default, a deprecation warning will be logged in the log file, stating the field's deprecation - and planned removal in v3.x.x. - - name: redis.connect_timeout - required: semi - default: 2000 - datatype: number - description: | - Connection timeout to use for Redis connection when the `redis` strategy is defined. - - name: redis.send_timeout - required: semi - default: 2000 - datatype: number - description: | - Send timeout to use for Redis connection when the `redis` strategy is defined. - - name: redis.read_timeout - required: semi - default: 2000 - datatype: number - description: | - Read timeout to use for Redis connection when the `redis` strategy is defined. - - name: redis.password - required: semi - default: - value_in_examples: - datatype: string - description: | - Password to use for Redis connection when the `redis` strategy is defined. If undefined, no AUTH commands are sent to Redis. - - name: redis.database - required: semi - default: 0 - value_in_examples: - datatype: integer - description: | - Database to use for Redis connection when the `redis` strategy is defined. - - name: redis.sentinel_master - required: semi - default: - value_in_examples: - datatype: string - description: | - Sentinel master to use for Redis connections when the `redis` strategy is defined. - Defining this value implies using Redis Sentinel. - - name: redis.sentinel_password - required: semi - default: - value_in_examples: - datatype: string - description: | - Sentinel password to authenticate with a Redis Sentinel instance. If undefined, no AUTH commands are sent to Redis Sentinels. - **Note:** This parameter is only available for Kong Gateway versions - 1.3.0.2 and later. - - name: redis.sentinel_role - required: semi - default: - value_in_examples: - datatype: string - description: | - Sentinel role to use for Redis connections when the `redis` strategy is defined. - Defining this value implies using Redis Sentinel. Available options: `master`, `slave`, `any`. - - name: redis.sentinel_addresses - required: semi - default: - value_in_examples: - datatype: array of string elements - description: | - Sentinel addresses to use for Redis connections when the `redis` strategy is defined. - Defining this value implies using Redis Sentinel. Each string element must - be a hostname. The minimum length of the array is 1 element. - - name: redis.cluster_addresses - required: semi - default: - value_in_examples: - datatype: array of string elements - description: | - Cluster addresses to use for Redis connections when the `redis` strategy is defined. - Defining this value implies using Redis cluster. Each string element must - be a hostname. The minimum length of the array is 1 element. - - name: window_type - required: true - default: sliding - value_in_examples: - datatype: string - description: | - Sets the time window type to either `sliding` (default) or `fixed`. - - name: retry_after_jitter_max - required: true - default: 0 - value_in_examples: - datatype: number - description: | - The upper bound of a jitter (random delay) in seconds to be added to the `Retry-After` - header of denied requests (status = `429`) in order to prevent all the clients - from coming back at the same time. The lower bound of the jitter is `0`; in this case, - the `Retry-After` header is equal to the `RateLimit-Reset` header. - extra: | - **Notes:** - - * The plugin does not support the `cluster` strategy in - [hybrid mode](/gateway/latest/plan-and-deploy/hybrid-mode/). - The `redis` strategy must be used instead. - - * Redis configuration values are ignored if the `cluster` strategy is used. - - * PostgreSQL 9.5+ is required when using the `cluster` strategy with `postgres` as the backing Kong cluster data store. - - * The `dictionary_name` directive was added to prevent the usage of the `kong` shared dictionary, - which could lead to `no memory` errors. - ---- - -### Headers sent to the client - -When this plugin is enabled, Kong sends some additional headers back to the client -indicating the allowed limits, how many requests are available, and how long it will take -until the quota will be restored. - -For example: - -```plaintext -RateLimit-Limit: 6 -RateLimit-Remaining: 4 -RateLimit-Reset: 47 -``` - -The plugin also sends headers indicating the limits in the time frame and the number -of remaining minutes: - -```plaintext -X-RateLimit-Limit-Minute: 10 -X-RateLimit-Remaining-Minute: 9 -``` - -You can optionally hide the limit and remaining headers with the `hide_client_headers` option. - -If more than one limit is being set, the plugin returns a combination of more time limits: - -```plaintext -X-RateLimit-Limit-Second: 5 -X-RateLimit-Remaining-Second: 4 -X-RateLimit-Limit-Minute: 10 -X-RateLimit-Remaining-Minute: 9 -``` - -If any of the limits configured has been reached, the plugin returns an `HTTP/1.1 429` status -code to the client with the following JSON body: - -```plaintext -{ "message": "API rate limit exceeded" } -``` - -The [`Retry-After`] header will be present on `429` errors to indicate how long the service is -expected to be unavailable to the client. When using `window_type=sliding` and `RateLimit-Reset`, `Retry-After` -may increase due to the rate calculation for the sliding window. - -{:.important} -> The headers `RateLimit-Limit`, `RateLimit-Remaining`, and `RateLimit-Reset` are based on the Internet-Draft [RateLimit Header Fields for HTTP](https://tools.ietf.org/html/draft-polli-ratelimit-headers-02) and may change in the future to respect specification updates. - - -### Multiple Limits and Window Sizes {#multi-limits-windows} - -An arbitrary number of limits/window sizes can be applied per plugin instance. This allows you to create -multiple rate limiting windows (e.g., rate limit per minute and per hour, and per any arbitrary window size). -Because of limitations with Kong's plugin configuration interface, each *nth* limit will apply to each *nth* window size. -For example: - -
curl -X POST http://kong:8001/services/
{SERVICE}
/plugins \ - --data name=rate-limiting-advanced \ - --data config.limit=10 \ - --data config.limit=100 \ - --data config.window_size=60 \ - --data config.window_size=3600 \ - --data config.sync_rate=10
- -This example applies rate limiting policies, one of which will trip when 10 hits have been counted in 60 seconds, -or the other when 100 hits have been counted in 3600 seconds. For more information, see the -[Enterprise Rate Limiting Library](/gateway/latest/reference/rate-limiting/). - -The number of configured window sizes and limits parameters must be equal (as shown above); -otherwise, an error occurs: - -```plaintext -You must provide the same number of windows and limits -``` - -### Fallback to IP - -When the selected strategy cannot be retrieved, the `rate-limiting-advanced` plugin will fall back -to limit using IP as the identifier. This can happen for several reasons, such as the -selected header was not sent by the client or the configured service was not found. - -[`Retry-After`]: https://tools.ietf.org/html/rfc7231#section-7.1.3 diff --git a/app/_hub/kong-inc/rate-limiting-advanced/1.5.x.md b/app/_hub/kong-inc/rate-limiting-advanced/1.5.x.md deleted file mode 100644 index e7ecdcad7db2..000000000000 --- a/app/_hub/kong-inc/rate-limiting-advanced/1.5.x.md +++ /dev/null @@ -1,384 +0,0 @@ ---- - -name: Rate Limiting Advanced -publisher: Kong Inc. -version: 1.5.x - -desc: Upgrades Kong Rate Limiting with more flexibility and higher performance -description: | - The Rate Limiting Advanced plugin for Konnect Enterprise is a re-engineered version of the Kong Gateway (OSS) [Rate Limiting plugin](/hub/kong-inc/rate-limiting/). - - As compared to the standard Rate Limiting plugin, Rate Limiting Advanced provides: - * Additional configurations: `limit`, `window_size`, and `sync_rate` - * Support for Redis Sentinel, Redis cluster, and Redis SSL - * Increased performance: Rate Limiting Advanced has better throughput performance with better accuracy. Configure `sync_rate` to periodically sync with backend storage. - * More limiting algorithms to choose from: These algorithms are more accurate and they enable configuration with more specificity. Learn more about our algorithms in [How to Design a Scalable Rate Limiting Algorithm](https://konghq.com/blog/how-to-design-a-scalable-rate-limiting-algorithm). - -type: plugin -enterprise: true -categories: - - traffic-control - -kong_version_compatibility: - community_edition: - compatible: - enterprise_edition: - compatible: - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x - - -params: - name: rate-limiting-advanced - service_id: true - route_id: true - consumer_id: true - protocols: ["http", "https", "grpc", "grpcs"] - dbless_compatible: partially - dbless_explanation: | - The cluster strategy is not supported in DB-less and hybrid modes. For Kong - Gateway in DB-less or hybrid mode, use the `redis` strategy. - config: - - name: limit - required: true - default: - value_in_examples: [ "5" ] - datatype: array of number elements - description: | - One or more requests-per-window limits to apply. There must be a matching - number of window limits and sizes specified. - - name: window_size - required: true - default: - value_in_examples: [ "30" ] - datatype: array of number elements - description: | - One or more window sizes to apply a limit to (defined in seconds). There - must be a matching number of window limits and sizes specified. - - name: identifier - required: true - default: consumer - value_in_examples: consumer - datatype: string - description: | - How to define the rate limit key. Can be `ip`, `credential`, `consumer`, `service`, `header`, or `path`. - - name: path - required: semi - datatype: string - description: | - Request path to use as the rate limit key when the `path` identifier is defined. - - name: header_name - required: semi - datatype: string - description: | - Header name to use as the rate limit key when the `header` identifier is defined. - - name: dictionary_name - required: true - default: kong_rate_limiting_counters - value_in_examples: - datatype: string - description: | - The shared dictionary where counters will be stored until the next sync cycle. - - name: sync_rate - required: true - default: - value_in_examples: -1 - datatype: number - description: | - How often to sync counter data to the central data store. A value of 0 - results in synchronous behavior; a value of -1 ignores sync behavior - entirely and only stores counters in node memory. A value greater than - 0 will sync the counters in the specified number of seconds. The minimum - allowed interval is 0.02 seconds (20ms). - - name: namespace - required: true - default: random_auto_generated_string - value_in_examples: - datatype: string - description: | - The rate limiting library namespace to use for this plugin instance. Counter - data and sync configuration is shared in a namespace. - - name: strategy - required: true - default: cluster - value_in_examples: cluster - datatype: string - description: | - The rate-limiting strategy to use for retrieving and incrementing the - limits. Available values are: - - `cluster`: Counters are stored in the Kong datastore and shared across - the nodes. - - `redis`: Counters are stored on a Redis server and shared - across the nodes. - - `local`: Counters are stored locally in-memory on the node (same effect - as setting `sync_rate` to `-1`). - - In DB-less and hybrid modes, the `cluster` config strategy is not - supported. - - In Konnect Cloud, the default strategy is `redis`. - - For details on which strategy should be used, refer to the - [implementation considerations](/hub/kong-inc/rate-limiting/#implementation-considerations). - - name: hide_client_headers - required: false - default: false - value_in_examples: false - datatype: boolean - description: | - Optionally hide informative response headers. Available options: `true` or `false`. - - name: redis.host - required: semi - default: - value_in_examples: - datatype: string - description: | - Host to use for Redis connection when the `redis` strategy is defined. - - name: redis.port - required: semi - default: 6379 - value_in_examples: - datatype: integer - description: | - Specifies the Redis server port when using the `redis` strategy. Must be a - value between 0 and 65535. Default: 6379. - - name: redis.ssl - required: false - default: false - value_in_examples: - datatype: boolean - description: | - If set to true, then uses SSL to connect to Redis. - - **Note:** This parameter is only available for Kong Gateway versions - 2.2.x and later. - - name: redis.ssl_verify - required: false - default: false - value_in_examples: - datatype: boolean - description: | - If set to true, then verifies the validity of the server SSL certificate. Note that you need to configure the - [lua_ssl_trusted_certificate](/gateway/latest/reference/configuration/#lua_ssl_trusted_certificate) - to specify the CA (or server) certificate used by your redis server. You may also need to configure - [lua_ssl_verify_depth](/gateway/latest/reference/configuration/#lua_ssl_verify_depth) accordingly. - - **Note:** This parameter is only available for Kong Gateway versions - 2.2.x and later. - - name: redis.server_name - required: false - default: - value_in_examples: - datatype: string - description: | - Specifies the server name for the new TLS extension Server Name Indication (SNI) when connecting over SSL. - - **Note:** This parameter is only available for Kong Gateway versions - 2.2.x and later. - - name: redis.timeout - required: semi - default: 2000 - value_in_examples: - datatype: number - description: | - Connection timeout (in milliseconds) to use for Redis connection when the `redis` strategy is defined. - This field is deprecated and replaced with `redis.connect_timeout`, `redis.send_timeout`, and `redis.read_timeout`. - The `redis.timeout` field will continue to work in a backwards compatible way, but it is recommended to use the replacement fields. - If set to something other than the default, a deprecation warning will be logged in the log file, stating the field's deprecation - and planned removal in v3.x.x. - - name: redis.connect_timeout - required: semi - default: 2000 - datatype: number - description: | - Connection timeout to use for Redis connection when the `redis` strategy is defined. - - name: redis.send_timeout - required: semi - default: 2000 - datatype: number - description: | - Send timeout to use for Redis connection when the `redis` strategy is defined. - - name: redis.read_timeout - required: semi - default: 2000 - datatype: number - description: | - Read timeout to use for Redis connection when the `redis` strategy is defined. - - name: redis.password - required: semi - default: - value_in_examples: - datatype: string - description: | - Password to use for Redis connection when the `redis` strategy is defined. If undefined, no AUTH commands are sent to Redis. - - name: redis.database - required: semi - default: 0 - value_in_examples: - datatype: integer - description: | - Database to use for Redis connection when the `redis` strategy is defined. - - name: redis.sentinel_master - required: semi - default: - value_in_examples: - datatype: string - description: | - Sentinel master to use for Redis connections when the `redis` strategy is defined. - Defining this value implies using Redis Sentinel. - - name: redis.sentinel_password - required: semi - default: - value_in_examples: - datatype: string - description: | - Sentinel password to authenticate with a Redis Sentinel instance. If undefined, no AUTH commands are sent to Redis Sentinels. - **Note:** This parameter is only available for Kong Gateway versions - 1.3.0.2 and later. - - name: redis.sentinel_role - required: semi - default: - value_in_examples: - datatype: string - description: | - Sentinel role to use for Redis connections when the `redis` strategy is defined. - Defining this value implies using Redis Sentinel. Available options: `master`, `slave`, `any`. - - name: redis.sentinel_addresses - required: semi - default: - value_in_examples: - datatype: array of string elements - description: | - Sentinel addresses to use for Redis connections when the `redis` strategy is defined. - Defining this value implies using Redis Sentinel. Each string element must - be a hostname. The minimum length of the array is 1 element. - - name: redis.cluster_addresses - required: semi - default: - value_in_examples: - datatype: array of string elements - description: | - Cluster addresses to use for Redis connections when the `redis` strategy is defined. - Defining this value implies using Redis cluster. Each string element must - be a hostname. The minimum length of the array is 1 element. - - name: window_type - required: true - default: sliding - value_in_examples: - datatype: string - description: | - Sets the time window type to either `sliding` (default) or `fixed`. - - name: retry_after_jitter_max - required: true - default: 0 - value_in_examples: - datatype: number - description: | - The upper bound of a jitter (random delay) in seconds to be added to the `Retry-After` - header of denied requests (status = `429`) in order to prevent all the clients - from coming back at the same time. The lower bound of the jitter is `0`; in this case, - the `Retry-After` header is equal to the `RateLimit-Reset` header. - extra: | - **Notes:** - - * The plugin does not support the `cluster` strategy in - [hybrid mode](/gateway/latest/plan-and-deploy/hybrid-mode/). - The `redis` strategy must be used instead. - - * Redis configuration values are ignored if the `cluster` strategy is used. - - * PostgreSQL 9.5+ is required when using the `cluster` strategy with `postgres` as the backing Kong cluster data store. - - * The `dictionary_name` directive was added to prevent the usage of the `kong` shared dictionary, - which could lead to `no memory` errors. - ---- - -### Headers sent to the client - -When this plugin is enabled, Kong sends some additional headers back to the client -indicating the allowed limits, how many requests are available, and how long it will take -until the quota will be restored. - -For example: - -```plaintext -RateLimit-Limit: 6 -RateLimit-Remaining: 4 -RateLimit-Reset: 47 -``` - -The plugin also sends headers indicating the limits in the time frame and the number -of remaining minutes: - -```plaintext -X-RateLimit-Limit-Minute: 10 -X-RateLimit-Remaining-Minute: 9 -``` - -You can optionally hide the limit and remaining headers with the `hide_client_headers` option. - -If more than one limit is being set, the plugin returns a combination of more time limits: - -```plaintext -X-RateLimit-Limit-Second: 5 -X-RateLimit-Remaining-Second: 4 -X-RateLimit-Limit-Minute: 10 -X-RateLimit-Remaining-Minute: 9 -``` - -If any of the limits configured has been reached, the plugin returns an `HTTP/1.1 429` status -code to the client with the following JSON body: - -```plaintext -{ "message": "API rate limit exceeded" } -``` - -The [`Retry-After`] header will be present on `429` errors to indicate how long the service is -expected to be unavailable to the client. When using `window_type=sliding` and `RateLimit-Reset`, `Retry-After` -may increase due to the rate calculation for the sliding window. - -{:.important} -> The headers `RateLimit-Limit`, `RateLimit-Remaining`, and `RateLimit-Reset` are based on the Internet-Draft [RateLimit Header Fields for HTTP](https://tools.ietf.org/html/draft-polli-ratelimit-headers-02) and may change in the future to respect specification updates. - - -### Multiple Limits and Window Sizes {#multi-limits-windows} - -An arbitrary number of limits/window sizes can be applied per plugin instance. This allows you to create -multiple rate limiting windows (e.g., rate limit per minute and per hour, and per any arbitrary window size). -Because of limitations with Kong's plugin configuration interface, each *nth* limit will apply to each *nth* window size. -For example: - -
curl -X POST http://kong:8001/services/
{SERVICE}
/plugins \ - --data name=rate-limiting-advanced \ - --data config.limit=10 \ - --data config.limit=100 \ - --data config.window_size=60 \ - --data config.window_size=3600 \ - --data config.sync_rate=10
- -This example applies rate limiting policies, one of which will trip when 10 hits have been counted in 60 seconds, -or the other when 100 hits have been counted in 3600 seconds. For more information, see the -[Enterprise Rate Limiting Library](/gateway/latest/reference/rate-limiting/). - -The number of configured window sizes and limits parameters must be equal (as shown above); -otherwise, an error occurs: - -```plaintext -You must provide the same number of windows and limits -``` - -### Fallback to IP - -When the selected strategy cannot be retrieved, the `rate-limiting-advanced` plugin will fall back -to limit using IP as the identifier. This can happen for several reasons, such as the -selected header was not sent by the client or the configured service was not found. - -[`Retry-After`]: https://tools.ietf.org/html/rfc7231#section-7.1.3 diff --git a/app/_hub/kong-inc/rate-limiting-advanced/_index.md b/app/_hub/kong-inc/rate-limiting-advanced/_index.md index 9e17d530f785..53fc93fc3c34 100644 --- a/app/_hub/kong-inc/rate-limiting-advanced/_index.md +++ b/app/_hub/kong-inc/rate-limiting-advanced/_index.md @@ -20,9 +20,7 @@ kong_version_compatibility: community_edition: compatible: null enterprise_edition: - compatible: - - 2.8.x - - 2.7.x + compatible: true params: name: rate-limiting-advanced service_id: true @@ -99,7 +97,9 @@ params: description: | The rate limiting library namespace to use for this plugin instance. Counter data and sync configuration is shared in a namespace. - - name: strategy + + - name: strategy # old version of param description + maximum_version: "2.8.x" required: true default: cluster value_in_examples: cluster @@ -114,13 +114,40 @@ params: - `local`: Counters are stored locally in-memory on the node (same effect as setting `sync_rate` to `-1`). - In DB-less and hybrid modes, the `cluster` config strategy is not - supported. + In DB-less and hybrid modes, the `cluster` config strategy + is not supported. In Konnect Cloud, the default strategy is `redis`. For details on which strategy should be used, refer to the [implementation considerations](/hub/kong-inc/rate-limiting/#implementation-considerations). + + - name: strategy # current + minimum_version: "3.0.x" + required: true + default: local + value_in_examples: local + datatype: string + description: | + The rate-limiting strategy to use for retrieving and incrementing the + limits. Available values are: + - `local`: Counters are stored locally in-memory on the node (same effect + as setting `sync_rate` to `-1`). + - `cluster`: Counters are stored in the Kong datastore and shared across + the nodes. + - `redis`: Counters are stored on a Redis server and shared + across the nodes. + + In DB-less and hybrid modes, the `cluster` config strategy + is not supported. From `3.0.0.0` onwards, Kong disallows + the plugin enablement if `cluster` strategy is set with DB-less + or hybrid mode. + + In Konnect Cloud, the default strategy is `redis`. + + For details on which strategy should be used, refer to the + [implementation considerations](/hub/kong-inc/rate-limiting/#implementation-considerations). + - name: hide_client_headers required: false default: false @@ -144,6 +171,7 @@ params: Specifies the Redis server port when using the `redis` strategy. Must be a value between 0 and 65535. Default: 6379. - name: redis.ssl + minimum_version: "2.2.x" required: false default: false value_in_examples: null @@ -151,9 +179,8 @@ params: description: | If set to true, then uses SSL to connect to Redis. - **Note:** This parameter is only available for Kong Gateway versions - 2.2.x and later. - name: redis.ssl_verify + minimum_version: "2.2.x" required: false default: false value_in_examples: null @@ -164,9 +191,8 @@ params: to specify the CA (or server) certificate used by your redis server. You may also need to configure [lua_ssl_verify_depth](/gateway/latest/reference/configuration/#lua_ssl_verify_depth) accordingly. - **Note:** This parameter is only available for Kong Gateway versions - 2.2.x and later. - name: redis.server_name + minimum_version: "2.2.x" required: false default: null value_in_examples: null @@ -174,9 +200,17 @@ params: description: | Specifies the server name for the new TLS extension Server Name Indication (SNI) when connecting over SSL. - **Note:** This parameter is only available for Kong Gateway versions - 2.2.x and later. - - name: redis.timeout + - name: redis.timeout # old version + maximum_version: "2.4.x" + required: semi + default: 2000 + value_in_examples: null + datatype: number + description: | + Connection timeout (in milliseconds) to use for Redis connection when the `redis` strategy is defined. + + - name: redis.timeout # current + minimum_version: "2.5.x" required: semi default: 2000 value_in_examples: null @@ -188,24 +222,28 @@ params: If set to something other than the default, a deprecation warning will be logged in the log file, stating the field's deprecation and planned removal in v3.x.x. - name: redis.connect_timeout + minimum_version: "2.5.x" required: semi default: 2000 datatype: number description: | Connection timeout to use for Redis connection when the `redis` strategy is defined. - name: redis.send_timeout + minimum_version: "2.5.x" required: semi default: 2000 datatype: number description: | Send timeout to use for Redis connection when the `redis` strategy is defined. - name: redis.read_timeout + minimum_version: "2.5.x" required: semi default: 2000 datatype: number description: | Read timeout to use for Redis connection when the `redis` strategy is defined. - name: redis.username + minimum_version: "2.8.x" required: semi default: null value_in_examples: null @@ -215,8 +253,8 @@ params: If undefined, ACL authentication will not be performed. This requires Redis v6.0.0+. This field is _referenceable_, which means it can be securely stored as a - [secret](/gateway/latest/plan-and-deploy/security/secrets-management/getting-started) - in a vault. References must follow a [specific format](/gateway/latest/plan-and-deploy/security/secrets-management/reference-format). + [secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). - name: redis.password required: semi default: null @@ -227,8 +265,8 @@ params: If undefined, no AUTH commands are sent to Redis. This field is _referenceable_, which means it can be securely stored as a - [secret](/gateway/latest/plan-and-deploy/security/secrets-management/getting-started) - in a vault. References must follow a [specific format](/gateway/latest/plan-and-deploy/security/secrets-management/reference-format). + [secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). - name: redis.database required: semi default: 0 @@ -245,6 +283,7 @@ params: Sentinel master to use for Redis connections when the `redis` strategy is defined. Defining this value implies using Redis Sentinel. - name: redis.sentinel_username + minimum_version: "2.8.x" required: semi default: null value_in_examples: null @@ -254,8 +293,8 @@ params: If undefined, ACL authentication will not be performed. This requires Redis v6.2.0+. This field is _referenceable_, which means it can be securely stored as a - [secret](/gateway/latest/plan-and-deploy/security/secrets-management/getting-started) - in a vault. References must follow a [specific format](/gateway/latest/plan-and-deploy/security/secrets-management/reference-format). + [secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). - name: redis.sentinel_password required: semi default: null @@ -266,8 +305,8 @@ params: If undefined, no AUTH commands are sent to Redis Sentinels. This field is _referenceable_, which means it can be securely stored as a - [secret](/gateway/latest/plan-and-deploy/security/secrets-management/getting-started) - in a vault. References must follow a [specific format](/gateway/latest/plan-and-deploy/security/secrets-management/reference-format). + [secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). - name: redis.sentinel_role required: semi default: null @@ -295,18 +334,20 @@ params: Defining this value implies using Redis cluster. Each string element must be a hostname. The minimum length of the array is 1 element. - name: redis.keepalive_backlog + minimum_version: "2.5.x" required: false default: null value_in_examples: null datatype: integer description: | - If specified, limits the total number of opened connections for a pool. If the - connection pool is full, all connection queues beyond the maximum limit go into - the backlog queue. Once the backlog queue is full, subsequent connect operations - will fail and return `nil`. Queued connect operations resume once the number of - connections in the pool is less than `keepalive_pool_size`. Note that queued + If specified, limits the total number of opened connections for a pool. If the + connection pool is full, all connection queues beyond the maximum limit go into + the backlog queue. Once the backlog queue is full, subsequent connect operations + will fail and return `nil`. Queued connect operations resume once the number of + connections in the pool is less than `keepalive_pool_size`. Note that queued connect operations are subject to set timeouts. - name: redis.keepalive_pool + minimum_version: "2.5.x" required: false default: generated from string template value_in_examples: null @@ -315,6 +356,7 @@ params: The custom name of the connection pool. If not specified, the connection pool name is generated from the string template `":"` or `""`. - name: redis.keepalive_pool_size + minimum_version: "2.5.x" required: false default: 30 value_in_examples: null @@ -342,6 +384,7 @@ params: from coming back at the same time. The lower bound of the jitter is `0`; in this case, the `Retry-After` header is equal to the `RateLimit-Reset` header. - name: enforce_consumer_groups + minimum_version: "2.7.x" required: false default: false value_in_examples: true @@ -351,6 +394,7 @@ params: from one of the allowed consumer groups to override the given plugin configuration. - name: consumer_groups + minimum_version: "2.7.x" required: semi default: null value_in_examples: @@ -441,8 +485,7 @@ For example: --data "config.limit=10" \ --data "config.limit=100" \ --data "config.window_size=60" \ - --data "config.window_size=3600" \ - --data "config.sync_rate=10" + --data "config.window_size=3600" This example applies rate limiting policies, one of which will trip when 10 hits have been counted in 60 seconds, or the other when 100 hits have been counted in 3600 seconds. For more information, see the @@ -470,6 +513,7 @@ When the `redis` strategy is used and a {{site.base_gateway}} node is disconnect {{site.base_gateway}} will still rate limit, but the {{site.base_gateway}} nodes can't sync the counters. As a result, users will be able to perform more requests than the limit, but there will still be a limit per node. +{% if_plugin_version gte:2.7.x %} ## Rate limiting for consumer groups You can use consumer groups to manage custom rate limiting configuration for @@ -487,19 +531,35 @@ the Admin API documentation. > **Note:** Consumer groups are not supported in declarative configuration with decK. If you have consumer groups in your configuration, decK will ignore them. +{% endif_plugin_version %} + --- ## Changelog -### {{site.base_gateway}} 2.8.x (plugin version 1.6.1) +**{{site.base_gateway}} 3.0.x** + +* {{site.base_gateway}} now disallows enabling the plugin if the `cluster` +strategy is set with DB-less or hybrid mode. + +**{{site.base_gateway}} 2.8.x** * Added the `redis.username` and `redis.sentinel_username` configuration parameters. * The `redis.username`, `redis.password`, `redis.sentinel_username`, and `redis.sentinel_password` configuration fields are now marked as referenceable, which means they can be securely stored as -[secrets](/gateway/latest/plan-and-deploy/security/secrets-management/getting-started) -in a vault. References must follow a [specific format](/gateway/latest/plan-and-deploy/security/secrets-management/reference-format). +[secrets](/gateway/latest/kong-enterprise/secrets-management/getting-started) +in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/secrets-management/reference-format). -### {{site.base_gateway}} 2.7.x (plugin version 1.6.0) +**{{site.base_gateway}} 2.7.x** * Added the `enforce_consumer_groups` and `consumer_groups` configuration parameters. + +**{{site.base_gateway}} 2.5.x** + +* Deprecated the `timeout` field and replaces it with three precise options: `connect_timeout`, `read_timeout`, and `send_timeout`. +* Added `redis.keepalive_pool`, `redis.keepalive_pool_size`, and `redis.keepalive_backlog` configuration options. +* `ssl_verify` and `server_name` configuration options now support Redis Sentinel-based connections. + +**{{site.base_gateway}} 2.2.x** +* Added the `redis.ssl`, `redis.ssl_verify`, and `redis.server_name` parameters for configuring TLS connections. diff --git a/app/_hub/kong-inc/rate-limiting-advanced/versions.yml b/app/_hub/kong-inc/rate-limiting-advanced/versions.yml index 5e97539096ed..29be0842e42b 100644 --- a/app/_hub/kong-inc/rate-limiting-advanced/versions.yml +++ b/app/_hub/kong-inc/rate-limiting-advanced/versions.yml @@ -1,5 +1,12 @@ -- release: 1.6.x -- release: 1.5.x -- release: 1.4.x -- release: 1.3.x -- release: 0.31.x +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 1.6.2 + 2.7.x: 1.6.1 + 2.6.x: 1.5.0 + 2.5.x: 1.4.4 + 2.4.x: 1.4.2 + 2.3.x: 1.4.1 + 2.2.x: 1.3.8 + 2.1.x: 1.3.7 diff --git a/app/_hub/kong-inc/rate-limiting/0.1-x.md b/app/_hub/kong-inc/rate-limiting/0.1-x.md deleted file mode 100644 index 2b7ae7923b2a..000000000000 --- a/app/_hub/kong-inc/rate-limiting/0.1-x.md +++ /dev/null @@ -1,201 +0,0 @@ ---- -name: Rate Limiting -publisher: Kong Inc. -version: 0.1-x - -desc: Rate-limit how many HTTP requests a developer can make -description: | - Rate limit how many HTTP requests a developer can make in a given period of seconds, minutes, hours, days, months or years. If the underlying Service/Route (or deprecated API entity) has no authentication layer, the **Client IP** address will be used, otherwise the Consumer will be used if an authentication plugin has been configured. - -
- Note: The functionality of this plugin as bundled - with versions of Kong prior to 0.13.1 and Kong Gateway prior to 0.32 - differs from what is documented herein. Refer to the - CHANGELOG - for details. -
- -type: plugin -categories: - - traffic-control - -kong_version_compatibility: - community_edition: - compatible: - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x - - 0.4.x - - 0.3.x - - 0.2.x - enterprise_edition: - compatible: - - 0.34-x - - 0.33-x - - 0.32-x - -params: - name: rate-limiting - api_id: true - service_id: true - route_id: true - consumer_id: true - config: - - name: second - required: semi - value_in_examples: 5 - description: The amount of HTTP requests the developer can make per second. At least one limit must exist. - - name: minute - required: semi - description: The amount of HTTP requests the developer can make per minute. At least one limit must exist. - - name: hour - required: semi - value_in_examples: 10000 - description: The amount of HTTP requests the developer can make per hour. At least one limit must exist. - - name: day - required: semi - description: The amount of HTTP requests the developer can make per day. At least one limit must exist. - - name: month - required: semi - description: The amount of HTTP requests the developer can make per month. At least one limit must exist. - - name: year - required: semi - description: The amount of HTTP requests the developer can make per year. At least one limit must exist. - - name: limit_by - required: false - default: "`consumer`" - description: | - The entity that will be used when aggregating the limits: `consumer`, `credential`, `ip`. If the `consumer` or the `credential` cannot be determined, the system will always fallback to `ip`. - - name: policy - required: false - value_in_examples: "local" - default: "`cluster`" - description: | - The rate-limiting policies to use for retrieving and incrementing the limits. Available values are `local` (counters will be stored locally in-memory on the node), `cluster` (counters are stored in the datastore and shared across the nodes) and `redis` (counters are stored on a Redis server and will be shared across the nodes). In case of DB-less mode, at least one of `local` or `redis` must be specified. Please refer Implementation Considerations for details on which policy should be used. - - name: fault_tolerant - required: false - default: "`true`" - description: | - A boolean value that determines if the requests should be proxied even if Kong has troubles connecting a third-party datastore. If `true` requests will be proxied anyways effectively disabling the rate-limiting function until the datastore is working again. If `false` then the clients will see `500` errors. - - name: hide_client_headers - required: false - default: "`false`" - description: Optionally hide informative response headers. - - name: redis_host - required: semi - description: | - When using the `redis` policy, this property specifies the address to the Redis server. - - name: redis_port - required: false - default: "`6379`" - description: | - When using the `redis` policy, this property specifies the port of the Redis server. By default is `6379`. - - name: redis_password - required: false - description: | - When using the `redis` policy, this property specifies the password to connect to the Redis server. - - name: redis_timeout - required: false - default: "`2000`" - description: | - When using the `redis` policy, this property specifies the timeout in milliseconds of any command submitted to the Redis server. - - name: redis_database - required: false - default: "`0`" - description: | - When using the `redis` policy, this property specifies Redis database to use. - ---- - -## Headers sent to the client - -When this plugin is enabled, Kong will send some additional headers back to the client telling how many requests are available and what are the limits allowed, for example: - -``` -X-RateLimit-Limit-Minute: 10 -X-RateLimit-Remaining-Minute: 9 -``` - -or it will return a combination of more time limits, if more than one is being set: - -``` -X-RateLimit-Limit-Second: 5 -X-RateLimit-Remaining-Second: 4 -X-RateLimit-Limit-Minute: 10 -X-RateLimit-Remaining-Minute: 9 -``` - -If any of the limits configured is being reached, the plugin will return a `HTTP/1.1 429` status code to the client with the following JSON body: - -```json -{"message":"API rate limit exceeded"} -``` - -## Implementation considerations - -The plugin supports 3 policies, which each have their specific pros and cons. - -policy | pros | cons ---- | --- | --- -`cluster` | accurate, no extra components to support | relatively the biggest performance impact, each request forces a read and a write on the underlying datastore. -`redis` | accurate, lesser performance impact than a `cluster` policy | extra redis installation required, bigger performance impact than a `local` policy -`local` | minimal performance impact | less accurate, and unless a consistent-hashing load balancer is used in front of Kong, it diverges when scaling the number of nodes - -There are 2 use cases that are most common: - -1. _every transaction counts_. These are for example transactions with financial - consequences. Here the highest level of accuracy is required. -2. _backend protection_. This is where accuracy is not as relevant, but it is - merely used to protect backend services from overload. Either by specific - users, or to protect against an attack in general. - -**NOTE**: - -
- Enterprise-Only The Kong Community Edition of this Rate Limiting plugin does not -include Redis Sentinel support. -Kong Gateway Subscription customers have the option -of using Redis Sentinel with Kong Rate Limiting to deliver highly available primary-replica deployments. -
- -### Every transaction counts - -In this scenario, the `local` policy is not an option. So here the decision is between -the extra performance of the `redis` policy against its extra support effort. Based on that balance, -the choice should either be `cluster` or `redis`. - -The recommendation is to start with the `cluster` policy, with the option to move over to `redis` -if performance reduces drastically. Keep in mind existing usage metrics cannot -be ported from the datastore to redis. Generally with shortlived metrics (per second or per minute) -this is not an issue, but with longer lived ones (months) it might be, so you might want to plan -your switch more carefully. - -### Backend protection - -As accuracy is of lesser importance, the `local` policy can be used. It might require some experimenting -to get the proper setting. For example, if the user is bound to 100 requests per second, and you have an -equally balanced 5 node Kong cluster, setting the `local` limit to something like 30 requests per second -should work. If you are worried about too many false-negatives, increase the value. - -Keep in mind as the cluster scales to more nodes, the users will get more requests granted, and likewise -when the cluster scales down the probability of false-negatives increases. So in general, update your -limits when scaling. - -The above mentioned inaccuracy can be mitigated by using a consistent-hashing load balancer in front of -Kong, that ensures the same user is always directed to the same Kong node. This will both reduce the -inaccuracy and prevent the scaling issues. - -Most likely the user will be granted more than was agreed when using the `local` policy, but it will -effectively block any attacks while maintaining the best performance. - -[api-object]: /gateway/latest/admin-api/#api-object -[configuration]: /gateway/latest/reference/configuration -[consumer-object]: /gateway/latest/admin-api/#consumer-object - diff --git a/app/_hub/kong-inc/rate-limiting/1.0-x.md b/app/_hub/kong-inc/rate-limiting/1.0-x.md deleted file mode 100644 index 881e093d2732..000000000000 --- a/app/_hub/kong-inc/rate-limiting/1.0-x.md +++ /dev/null @@ -1,214 +0,0 @@ ---- -name: Rate Limiting -publisher: Kong Inc. -version: 1.0.0 - -desc: Rate-limit how many HTTP requests a developer can make -description: | - Rate limit how many HTTP requests a developer can make in a given period of seconds, minutes, hours, days, months or years. If the underlying Service/Route (or deprecated API entity) has no authentication layer, the **Client IP** address will be used, otherwise the Consumer will be used if an authentication plugin has been configured. - -
- Note: The functionality of this plugin as bundled - with versions of Kong prior to 0.13.1 and Kong Gateway prior to 0.32 - differs from what is documented herein. Refer to the - CHANGELOG - for details. -
- -type: plugin -categories: - - traffic-control - -kong_version_compatibility: - community_edition: - compatible: - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x - - 0.4.x - - 0.3.x - - 0.2.x - enterprise_edition: - compatible: - - 1.3-x - - 0.36-x - - 0.35-x - - 0.34-x - - 0.33-x - - 0.32-x - -params: - name: rate-limiting - service_id: true - route_id: true - consumer_id: true - protocols: ['http', 'https'] - dbless_compatible: partially - dbless_explanation: | - The plugin will run fine with the `local` policy (which doesn't use the database) or - the `redis` policy (which uses an independent Redis, so it is compatible with DB-less). - - The plugin will not work with the `cluster` policy, which requires writes to the database. - - config: - - name: second - required: semi - value_in_examples: 5 - description: The amount of HTTP requests the developer can make per second. At least one limit must exist. - - name: minute - required: semi - description: The amount of HTTP requests the developer can make per minute. At least one limit must exist. - - name: hour - required: semi - value_in_examples: 10000 - description: The amount of HTTP requests the developer can make per hour. At least one limit must exist. - - name: day - required: semi - description: The amount of HTTP requests the developer can make per day. At least one limit must exist. - - name: month - required: semi - description: The amount of HTTP requests the developer can make per month. At least one limit must exist. - - name: year - required: semi - description: The amount of HTTP requests the developer can make per year. At least one limit must exist. - - name: limit_by - required: false - default: '`consumer`' - description: | - The entity that will be used when aggregating the limits: `consumer`, `credential`, `ip`, `service`. If the `consumer`, the `credential` or the `service` cannot be determined, the system will always fallback to `ip`. - - name: policy - required: false - value_in_examples: "local" - default: '`cluster`' - description: | - The rate-limiting policies to use for retrieving and incrementing the limits. Available values are `local` (counters will be stored locally in-memory on the node), `cluster` (counters are stored in the datastore and shared across the nodes) and `redis` (counters are stored on a Redis server and will be shared across the nodes). In case of DB-less mode, at least one of `local` or `redis` must be specified. Please refer Implementation Considerations for details on which policy should be used. - - name: fault_tolerant - required: false - default: '`true`' - description: | - A boolean value that determines if the requests should be proxied even if Kong has troubles connecting a third-party datastore. If `true` requests will be proxied anyways effectively disabling the rate-limiting function until the datastore is working again. If `false` then the clients will see `500` errors. - - name: hide_client_headers - required: false - default: '`false`' - description: Optionally hide informative response headers. - - name: redis_host - required: semi - description: | - When using the `redis` policy, this property specifies the address to the Redis server. - - name: redis_port - required: false - default: '`6379`' - description: | - When using the `redis` policy, this property specifies the port of the Redis server. By default is `6379`. - - name: redis_password - required: false - description: | - When using the `redis` policy, this property specifies the password to connect to the Redis server. - - name: redis_timeout - required: false - default: '`2000`' - description: | - When using the `redis` policy, this property specifies the timeout in milliseconds of any command submitted to the Redis server. - - name: redis_database - required: false - default: '`0`' - description: | - When using the `redis` policy, this property specifies Redis database to use. ---- - -## Headers sent to the client - -When this plugin is enabled, Kong will send some additional headers back to the client telling how many requests are available and what are the limits allowed, for example: - -``` -X-RateLimit-Limit-Minute: 10 -X-RateLimit-Remaining-Minute: 9 -``` - -or it will return a combination of more time limits, if more than one is being set: - -``` -X-RateLimit-Limit-Second: 5 -X-RateLimit-Remaining-Second: 4 -X-RateLimit-Limit-Minute: 10 -X-RateLimit-Remaining-Minute: 9 -``` - -If any of the limits configured is being reached, the plugin will return a `HTTP/1.1 429` status code to the client with the following JSON body: - -```json -{ "message": "API rate limit exceeded" } -``` - -## Implementation considerations - -The plugin supports 3 policies, which each have their specific pros and cons. - -| policy | pros | cons | -| --------- | ----------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | -| `cluster` | accurate, no extra components to support | relatively the biggest performance impact, each request forces a read and a write on the underlying datastore. | -| `redis` | accurate, lesser performance impact than a `cluster` policy | extra redis installation required, bigger performance impact than a `local` policy | -| `local` | minimal performance impact | less accurate, and unless a consistent-hashing load balancer is used in front of Kong, it diverges when scaling the number of nodes | - -There are 2 use cases that are most common: - -1. _every transaction counts_. These are for example transactions with financial - consequences. Here the highest level of accuracy is required. -2. _backend protection_. This is where accuracy is not as relevant, but it is - merely used to protect backend services from overload. Either by specific - users, or to protect against an attack in general. - -**NOTE**: - -
- Enterprise-Only The Kong Community Edition of this Rate Limiting plugin does not -include Redis Sentinel support. -Kong Gateway Subscription customers have the option -of using Redis Sentinel with Kong Rate Limiting to deliver highly available primary-replica deployments. -
- -### Every transaction counts - -In this scenario, the `local` policy is not an option. So here the decision is between -the extra performance of the `redis` policy against its extra support effort. Based on that balance, -the choice should either be `cluster` or `redis`. - -The recommendation is to start with the `cluster` policy, with the option to move over to `redis` -if performance reduces drastically. Keep in mind existing usage metrics cannot -be ported from the datastore to redis. Generally with shortlived metrics (per second or per minute) -this is not an issue, but with longer lived ones (months) it might be, so you might want to plan -your switch more carefully. - -### Backend protection - -As accuracy is of lesser importance, the `local` policy can be used. It might require some experimenting -to get the proper setting. For example, if the user is bound to 100 requests per second, and you have an -equally balanced 5 node Kong cluster, setting the `local` limit to something like 30 requests per second -should work. If you are worried about too many false-negatives, increase the value. - -Keep in mind as the cluster scales to more nodes, the users will get more requests granted, and likewise -when the cluster scales down the probability of false-negatives increases. So in general, update your -limits when scaling. - -The above mentioned inaccuracy can be mitigated by using a consistent-hashing load balancer in front of -Kong, that ensures the same user is always directed to the same Kong node. This will both reduce the -inaccuracy and prevent the scaling issues. - -Most likely the user will be granted more than was agreed when using the `local` policy, but it will -effectively block any attacks while maintaining the best performance. - -[api-object]: /gateway/latest/admin-api/#api-object -[configuration]: /gateway/latest/reference/configuration -[consumer-object]: /gateway/latest/admin-api/#consumer-object diff --git a/app/_hub/kong-inc/rate-limiting/2.1-x.md b/app/_hub/kong-inc/rate-limiting/2.1-x.md deleted file mode 100644 index 2beb245b6b0b..000000000000 --- a/app/_hub/kong-inc/rate-limiting/2.1-x.md +++ /dev/null @@ -1,236 +0,0 @@ ---- -name: Rate Limiting -publisher: Kong Inc. -version: 2.2.0 - -desc: Rate-limit how many HTTP requests a developer can make -description: | - Rate limit how many HTTP requests a developer can make in a given period of seconds, minutes, hours, days, months or years. If the underlying Service/Route (or deprecated API entity) has no authentication layer, the **Client IP** address will be used, otherwise the Consumer will be used if an authentication plugin has been configured. - -
- Note: The functionality of this plugin as bundled - with versions of Kong prior to 0.13.1 and Kong Gateway prior to 0.32 - differs from what is documented herein. Refer to the - CHANGELOG - for details. -
- -type: plugin -categories: - - traffic-control - -kong_version_compatibility: - community_edition: - compatible: - - 2.0.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x - - 0.4.x - - 0.3.x - - 0.2.x - enterprise_edition: - compatible: - - 1.5.x - - 1.3-x - - 0.36-x - - 0.35-x - - 0.34-x - - 0.33-x - - 0.32-x - -params: - name: rate-limiting - service_id: true - route_id: true - consumer_id: true - protocols: ['http', 'https'] - dbless_compatible: partially - dbless_explanation: | - The plugin will run fine with the `local` policy (which doesn't use the database) or - the `redis` policy (which uses an independent Redis, so it is compatible with DB-less). - - The plugin will not work with the `cluster` policy, which requires writes to the database. - - config: - - name: second - required: semi - value_in_examples: 5 - description: The amount of HTTP requests the developer can make per second. At least one limit must exist. - - name: minute - required: semi - description: The amount of HTTP requests the developer can make per minute. At least one limit must exist. - - name: hour - required: semi - value_in_examples: 10000 - description: The amount of HTTP requests the developer can make per hour. At least one limit must exist. - - name: day - required: semi - description: The amount of HTTP requests the developer can make per day. At least one limit must exist. - - name: month - required: semi - description: The amount of HTTP requests the developer can make per month. At least one limit must exist. - - name: year - required: semi - description: The amount of HTTP requests the developer can make per year. At least one limit must exist. - - name: limit_by - required: false - default: '`consumer`' - description: | - The entity that will be used when aggregating the limits: `consumer`, `credential`, `ip`, `service`, `header`. If the `consumer`, the `credential` or the `service` cannot be determined, the system will always fallback to `ip`. - - name: service_id - required: semi - description: The service id to be used if `limit_by` is set to `service`. - - name: header_name - required: semi - description: Header name to be used if `limit_by` is set to `header`. - - name: policy - required: false - value_in_examples: "local" - default: '`cluster`' - description: | - The rate-limiting policies to use for retrieving and incrementing the limits. Available values are `local` (counters will be stored locally in-memory on the node), `cluster` (counters are stored in the datastore and shared across the nodes) and `redis` (counters are stored on a Redis server and will be shared across the nodes). In case of DB-less mode, at least one of `local` or `redis` must be specified. Please refer Implementation Considerations for details on which policy should be used. - - name: fault_tolerant - required: false - default: '`true`' - description: | - A boolean value that determines if the requests should be proxied even if Kong has troubles connecting a third-party datastore. If `true` requests will be proxied anyways effectively disabling the rate-limiting function until the datastore is working again. If `false` then the clients will see `500` errors. - - name: hide_client_headers - required: false - default: '`false`' - description: Optionally hide informative response headers. - - name: redis_host - required: semi - description: | - When using the `redis` policy, this property specifies the address to the Redis server. - - name: redis_port - required: false - default: '`6379`' - description: | - When using the `redis` policy, this property specifies the port of the Redis server. By default is `6379`. - - name: redis_password - required: false - description: | - When using the `redis` policy, this property specifies the password to connect to the Redis server. - - name: redis_timeout - required: false - default: '`2000`' - description: | - When using the `redis` policy, this property specifies the timeout in milliseconds of any command submitted to the Redis server. - - name: redis_database - required: false - default: '`0`' - description: | - When using the `redis` policy, this property specifies Redis database to use. ---- - -## Headers sent to the client - -When this plugin is enabled, Kong will send some additional headers back to the client telling what are the limits allowed, how many requests are available and how long it will take until the quota will be restored, for example: - -``` -RateLimit-Limit: 6 -RateLimit-Remaining: 4 -RateLimit-Reset: 47 -``` - -The plugin will also send headers telling the limits in the time frame and the number of requests remaining: - -``` -X-RateLimit-Limit-Minute: 10 -X-RateLimit-Remaining-Minute: 9 -``` - -or it will return a combination of more time limits, if more than one is being set: - -``` -X-RateLimit-Limit-Second: 5 -X-RateLimit-Remaining-Second: 4 -X-RateLimit-Limit-Minute: 10 -X-RateLimit-Remaining-Minute: 9 -``` - -If any of the limits configured is being reached, the plugin will return a `HTTP/1.1 429` status code to the client with the following JSON body: - -```json -{ "message": "API rate limit exceeded" } -``` - -**NOTE**: - -
-The headers `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` are based on the Internet-Draft RateLimit Header Fields for HTTP and may change in the future, respecting updates to the specification. -
- -## Implementation considerations - -The plugin supports 3 policies, which each have their specific pros and cons. - -| policy | pros | cons | -| --------- | ----------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | -| `cluster` | accurate, no extra components to support | relatively the biggest performance impact, each request forces a read and a write on the underlying datastore. | -| `redis` | accurate, lesser performance impact than a `cluster` policy | extra redis installation required, bigger performance impact than a `local` policy | -| `local` | minimal performance impact | less accurate, and unless a consistent-hashing load balancer is used in front of Kong, it diverges when scaling the number of nodes | - -There are 2 use cases that are most common: - -1. _every transaction counts_. These are for example transactions with financial - consequences. Here the highest level of accuracy is required. -2. _backend protection_. This is where accuracy is not as relevant, but it is - merely used to protect backend services from overload. Either by specific - users, or to protect against an attack in general. - -**NOTE**: - -
- Enterprise-Only The Kong Community Edition of this Rate Limiting plugin does not -include Redis Sentinel support. -Kong Gateway Subscription customers have the option -of using Redis Sentinel with Kong Rate Limiting to deliver highly available primary-replica deployments. -
- -### Every transaction counts - -In this scenario, the `local` policy is not an option. So here the decision is between -the extra performance of the `redis` policy against its extra support effort. Based on that balance, -the choice should either be `cluster` or `redis`. - -The recommendation is to start with the `cluster` policy, with the option to move over to `redis` -if performance reduces drastically. Keep in mind existing usage metrics cannot -be ported from the datastore to redis. Generally with shortlived metrics (per second or per minute) -this is not an issue, but with longer lived ones (months) it might be, so you might want to plan -your switch more carefully. - -### Backend protection - -As accuracy is of lesser importance, the `local` policy can be used. It might require some experimenting -to get the proper setting. For example, if the user is bound to 100 requests per second, and you have an -equally balanced 5 node Kong cluster, setting the `local` limit to something like 30 requests per second -should work. If you are worried about too many false-negatives, increase the value. - -Keep in mind as the cluster scales to more nodes, the users will get more requests granted, and likewise -when the cluster scales down the probability of false-negatives increases. So in general, update your -limits when scaling. - -The above mentioned inaccuracy can be mitigated by using a consistent-hashing load balancer in front of -Kong, that ensures the same user is always directed to the same Kong node. This will both reduce the -inaccuracy and prevent the scaling issues. - -Most likely the user will be granted more than was agreed when using the `local` policy, but it will -effectively block any attacks while maintaining the best performance. - -[api-object]: /gateway/latest/admin-api/#api-object -[configuration]: /gateway/latest/reference/configuration -[consumer-object]: /gateway/latest/admin-api/#consumer-object diff --git a/app/_hub/kong-inc/rate-limiting/2.2.x.md b/app/_hub/kong-inc/rate-limiting/2.2.x.md deleted file mode 100644 index 7541a1ff94db..000000000000 --- a/app/_hub/kong-inc/rate-limiting/2.2.x.md +++ /dev/null @@ -1,274 +0,0 @@ ---- -name: Rate Limiting -publisher: Kong Inc. -version: 2.2.x -desc: Rate-limit how many HTTP requests can be made in a period of time -description: | - Rate limit how many HTTP requests can be made in a given period of seconds, minutes, hours, days, months, or years. - If the underlying Service/Route (or deprecated API entity) has no authentication layer, - the **Client IP** address will be used; otherwise, the Consumer will be used if an - authentication plugin has been configured. - - **Tip:** The [Rate Limiting Advanced](/hub/kong-inc/rate-limiting-advanced/) - plugin provides the ability to apply - [multiple limits in sliding or fixed windows](/hub/kong-inc/rate-limiting-advanced/#multi-limits-windows). -type: plugin -categories: - - traffic-control -kong_version_compatibility: - community_edition: - compatible: - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 2.0.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x - - 0.4.x - - 0.3.x - - 0.2.x - enterprise_edition: - compatible: - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x -params: - name: rate-limiting - service_id: true - route_id: true - consumer_id: true - protocols: - - http - - https - dbless_compatible: partially - dbless_explanation: | - The plugin will run fine with the `local` policy (which doesn't use the database) or - the `redis` policy (which uses an independent Redis, so it is compatible with DB-less). - - The plugin will not work with the `cluster` policy, which requires writes to the database. - config: - - name: second - required: semi - value_in_examples: 5 - datatype: number - description: The number of HTTP requests that can be made per second. - - name: minute - required: semi - datatype: number - description: The number of HTTP requests that can be made per minute. - - name: hour - required: semi - value_in_examples: 10000 - datatype: number - description: The number of HTTP requests that can be made per hour. - - name: day - required: semi - datatype: number - description: The number of HTTP requests that can be made per day. - - name: month - required: semi - datatype: number - description: The number of HTTP requests that can be made per month. - - name: year - required: semi - datatype: number - description: The number of HTTP requests that can be made per year. - - name: limit_by - required: false - default: '`consumer`' - datatype: string - description: | - The entity that will be used when aggregating the limits: `consumer`, `credential`, `ip`, `service`, `header`, `path`. If the value for the entity chosen to aggregate the limit cannot be determined, the system will always fallback to `ip`. If value `service` is chosen, the `service_id` configuration must be provided. If value `header` is chosen, the `header_name` configuration must be provided. If value `path` is chosen, the `path` configuration must be provided. - - name: service_id - required: semi - datatype: string - description: The service id to be used if `limit_by` is set to `service`. - - name: header_name - required: semi - datatype: string - description: Header name to be used if `limit_by` is set to `header`. - - name: path - required: semi - datatype: string - description: Path to be used if `limit_by` is set to `path`. - - name: policy - required: false - value_in_examples: local - default: '`cluster`' - datatype: string - description: | - The rate-limiting policies to use for retrieving and incrementing the - limits. Available values are: - - `local`: Counters are stored locally in-memory on the node. - - `cluster`: Counters are stored in the Kong datastore and shared across - the nodes. - - `redis`: Counters are stored on a Redis server and shared - across the nodes. - - In DB-less and hybrid modes, the `cluster` config policy is not supported. - For DB-less mode, use one of `redis` or `local`; for hybrid mode, use - `redis`, or `local` for data planes only. - - In Konnect Cloud, the default policy is `redis`. - - For details on which policy should be used, refer to the - [implementation considerations](#implementation-considerations). - - name: fault_tolerant - required: true - default: '`true`' - datatype: boolean - description: | - A boolean value that determines if the requests should be proxied even if Kong has troubles connecting a third-party datastore. If `true`, requests will be proxied anyway, effectively disabling the rate-limiting function until the datastore is working again. If `false`, then the clients will see `500` errors. - - name: hide_client_headers - required: true - default: '`false`' - datatype: boolean - description: Optionally hide informative response headers. - - name: redis_host - required: semi - datatype: string - description: | - When using the `redis` policy, this property specifies the address to the Redis server. - - name: redis_port - required: false - default: '`6379`' - datatype: integer - description: | - When using the `redis` policy, this property specifies the port of the Redis server. By default is `6379`. - - name: redis_password - required: false - datatype: string - description: | - When using the `redis` policy, this property specifies the password to connect to the Redis server. - - name: redis_timeout - required: false - default: '`2000`' - datatype: number - description: | - When using the `redis` policy, this property specifies the timeout in milliseconds of any command submitted to the Redis server. - - name: redis_database - required: false - default: '`0`' - datatype: integer - description: | - When using the `redis` policy, this property specifies the Redis database to use. - extra: '
Note: At least one limit (`second`, `minute`, `hour`, `day`, `month`, `year`) must be configured. Multiple limits can be configured.
' ---- - -## Headers sent to the client - -When this plugin is enabled, Kong sends additional headers -to show the allowed limits, number of available requests, -and the time remaining (in seconds) until the quota is reset. Here's an example header: - -``` -RateLimit-Limit: 6 -RateLimit-Remaining: 4 -RateLimit-Reset: 47 -``` - -The plugin also sends headers to show the time limit and the minutes still available: - -``` -X-RateLimit-Limit-Minute: 10 -X-RateLimit-Remaining-Minute: 9 -``` - -If more than one time limit is set, the header contains all of these: - -``` -X-RateLimit-Limit-Second: 5 -X-RateLimit-Remaining-Second: 4 -X-RateLimit-Limit-Minute: 10 -X-RateLimit-Remaining-Minute: 9 -``` - -When a limit is reached, the plugin returns an `HTTP/1.1 429` status code, with the following JSON body: - -```json -{ "message": "API rate limit exceeded" } -``` - -{:.warning} -> **Warning**: The headers `RateLimit-Limit`, `RateLimit-Remaining`, and `RateLimit-Reset` are based on the Internet-Draft [RateLimit Header Fields for HTTP](https://tools.ietf.org/html/draft-polli-ratelimit-headers-01). These could change if the specification is updated. - -## Implementation considerations - -The plugin supports three policies. - -| Policy | Pros | Cons | -| --------- | ---- | ------ | -| `cluster` | Accurate, no extra components to support. | Each request forces a read and a write on the datastore. Therefore, relatively, the biggest performance impact. | -| `redis` | Accurate, less performance impact than a `cluster` policy. | Needs a Redis installation. Bigger performance impact than a `local` policy. | -| `local` | Minimal performance impact. | Less accurate. Unless there's a consistent-hashing load balancer in front of Kong, it diverges when scaling the number of nodes. | - -Two common use cases are: - -1. _Every transaction counts_. The highest level of accuracy is needed. An example is a transaction with financial - consequences. -2. _Backend protection_. Accuracy is not as relevant. The requirement is - only to protect backend services from overloading that's caused either by specific - users or by attacks. - -{:.warning} -> **Note**: **Enterprise-Only**: The Kong Community Edition of this Rate Limiting plugin does not -include [Redis Sentinel](https://redis.io/topics/sentinel) support. Only [Kong Gateway Subscription](https://www.konghq.com/kong) customers can use Redis Sentinel with Kong Rate Limiting, enabling them to deliver highly available primary-replica deployments. - -### Every transaction counts - -In this scenario, because accuracy is important, the `local` policy is not an option. Consider the support effort you might need -for Redis, and then choose either `cluster` or `redis`. - -You could start with the `cluster` policy, and move to `redis` -if performance reduces drastically. - -Do remember that you cannot port the existing usage metrics from the datastore to Redis. -This might not be a problem with shortlived metrics (for example, seconds or minutes) -but if you use metrics with a longer time frame (for example, months), plan -your switch carefully. - -### Backend protection - -If accuracy is of lesser importance, choose the `local` policy. You might need to experiment a little -before you get a setting that works for your scenario. As the cluster scales to more nodes, more user requests are handled. -When the cluster scales down, the probability of false negatives increases. So, adjust your limits when scaling. - -For example, if a user can make 100 requests every second, and you have an -equally balanced 5-node Kong cluster, setting the `local` limit to something like 30 requests every second -should work. If you see too many false negatives, increase the limit. - -To minimise inaccuracies, consider using a consistent-hashing load balancer in front of -Kong. The load balancer ensures that a user is always directed to the same Kong node, thus reducing -inaccuracies and preventing scaling problems. - -### Fallback to IP - -When the selected policy cannot be retrieved, the plugin falls back -to limiting usage by identifying the IP address. This can happen for several reasons, such as the -selected header was not sent by the client or the configured service was not found. - -[api-object]: /gateway/latest/admin-api/#api-object -[configuration]: /gateway/latest/reference/configuration -[consumer-object]: /gateway/latest/admin-api/#consumer-object diff --git a/app/_hub/kong-inc/rate-limiting/_index.md b/app/_hub/kong-inc/rate-limiting/_index.md index d2926a5b31b9..80d43427cb66 100644 --- a/app/_hub/kong-inc/rate-limiting/_index.md +++ b/app/_hub/kong-inc/rate-limiting/_index.md @@ -1,7 +1,6 @@ --- name: Rate Limiting publisher: Kong Inc. -version: 2.3.x desc: Rate-limit how many HTTP requests can be made in a period of time description: | Rate limit how many HTTP requests can be made in a given period of seconds, minutes, hours, days, months, or years. @@ -17,13 +16,9 @@ categories: - traffic-control kong_version_compatibility: community_edition: - compatible: - - 2.8.x - - 2.7.x + compatible: true enterprise_edition: - compatible: - - 2.8.x - - 2.7.x + compatible: true params: name: rate-limiting service_id: true @@ -86,13 +81,13 @@ params: - name: policy required: false value_in_examples: local - default: '`cluster`' + default: '`local`' datatype: string description: | The rate-limiting policies to use for retrieving and incrementing the limits. Available values are: - `local`: Counters are stored locally in-memory on the node. - - `cluster`: Counters are stored in the Kong datastore and shared across + - `cluster`: Counters are stored in the Kong data store and shared across the nodes. - `redis`: Counters are stored on a Redis server and shared across the nodes. @@ -110,7 +105,7 @@ params: default: '`true`' datatype: boolean description: | - A boolean value that determines if the requests should be proxied even if Kong has troubles connecting a third-party datastore. If `true`, requests will be proxied anyway, effectively disabling the rate-limiting function until the datastore is working again. If `false`, then the clients will see `500` errors. + A boolean value that determines if the requests should be proxied even if Kong has troubles connecting a third-party data store. If `true`, requests will be proxied anyway, effectively disabling the rate-limiting function until the data store is working again. If `false`, then the clients will see `500` errors. - name: hide_client_headers required: true default: '`false`' @@ -128,16 +123,27 @@ params: description: | When using the `redis` policy, this property specifies the port of the Redis server. By default is `6379`. - name: redis_username + minimum_version: "2.8.x" required: false datatype: string description: | When using the `redis` policy, this property specifies the username to connect to the Redis server when ACL authentication is desired. + + This field is _referenceable_, which means it can be securely stored as a + [secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). - name: redis_password + minimum_version: "2.7.x" required: false datatype: string description: | When using the `redis` policy, this property specifies the password to connect to the Redis server. + + This field is _referenceable_, which means it can be securely stored as a + [secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). - name: redis_ssl + minimum_version: "2.7.x" required: true default: '`false`' datatype: boolean @@ -212,9 +218,9 @@ The plugin supports three policies. | Policy | Pros | Cons | | --------- | ---- | ------ | -| `cluster` | Accurate, no extra components to support. | Each request forces a read and a write on the datastore. Therefore, relatively, the biggest performance impact. | -| `redis` | Accurate, less performance impact than a `cluster` policy. | Needs a Redis installation. Bigger performance impact than a `local` policy. | -| `local` | Minimal performance impact. | Less accurate. Unless there's a consistent-hashing load balancer in front of Kong, it diverges when scaling the number of nodes. | +| `local` | Minimal performance impact. | Less accurate. Unless there's a consistent-hashing load balancer in front of Kong, it diverges when scaling the number of nodes. +| `cluster` | Accurate, no extra components to support. | Each request forces a read and a write on the data store. Therefore, relatively, the biggest performance impact. | +| `redis` | Accurate, less performance impact than a `cluster` policy. | Needs a Redis installation. Bigger performance impact than a `local` policy. || Two common use cases are: @@ -226,7 +232,7 @@ Two common use cases are: {:.warning} > **Note**: **Enterprise-Only**: The Kong Community Edition of this Rate Limiting plugin does not -include [Redis Sentinel](https://redis.io/topics/sentinel) support. Only [Kong Gateway Subscription](https://www.konghq.com/kong) customers can use Redis Sentinel with Kong Rate Limiting, enabling them to deliver highly available primary-replica deployments. +include [Redis Sentinel](https://redis.io/topics/sentinel) support. Only [{{site.base_gateway}} Enterprise](https://www.konghq.com/kong) customers can use Redis Sentinel with Kong Rate Limiting, enabling them to deliver highly available primary-replica deployments. ### Every transaction counts @@ -236,8 +242,8 @@ for Redis, and then choose either `cluster` or `redis`. You could start with the `cluster` policy, and move to `redis` if performance reduces drastically. -Do remember that you cannot port the existing usage metrics from the datastore to Redis. -This might not be a problem with shortlived metrics (for example, seconds or minutes) +Do remember that you cannot port the existing usage metrics from the data store to Redis. +This might not be a problem with short-lived metrics (for example, seconds or minutes) but if you use metrics with a longer time frame (for example, months), plan your switch carefully. @@ -265,11 +271,11 @@ selected header was not sent by the client or the configured service was not fou ## Changelog -### Kong Gateway 2.8.x (plugin version 2.3.1) +**{{site.base_gateway}} 2.8.x** * Added the `redis_username` configuration parameter. -### Kong Gateway 2.7.x (plugin version 2.3.0) +**{{site.base_gateway}} 2.7.x** * Added the `redis_ssl`, `redis_ssl_verify`, and `redis_server_name` configuration parameters. diff --git a/app/_hub/kong-inc/rate-limiting/versions.yml b/app/_hub/kong-inc/rate-limiting/versions.yml index 66dbba38a10a..e3c408b4a8aa 100644 --- a/app/_hub/kong-inc/rate-limiting/versions.yml +++ b/app/_hub/kong-inc/rate-limiting/versions.yml @@ -1,5 +1,12 @@ -- release: 2.3.x -- release: 2.2.x -- release: 2.1-x -- release: 1.0-x -- release: 0.1-x +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 2.4.0 + 2.7.x: 2.3.0 + 2.6.x: 2.2.2 + 2.5.x: 2.2.2 + 2.4.x: 2.2.2 + 2.3.x: 2.2.2 + 2.2.x: 2.2.0 + 2.1.x: 2.2.0 diff --git a/app/_hub/kong-inc/request-size-limiting/0.1-x.md b/app/_hub/kong-inc/request-size-limiting/0.1-x.md deleted file mode 100644 index 1dbc44e531a0..000000000000 --- a/app/_hub/kong-inc/request-size-limiting/0.1-x.md +++ /dev/null @@ -1,62 +0,0 @@ ---- -name: Request Size Limiting -publisher: Kong Inc. -version: 0.1-x - -desc: Block requests with bodies greater than a specified size -description: | -
- For security reasons we suggest enabling this plugin for any API you add to Kong to prevent a DOS (Denial of Service) attack. -
- - Block incoming requests whose body is greater than a specific size in megabytes. - -
- Note: The functionality of this plugin as bundled - with versions of Kong prior to 0.9.0 - differs from what is documented herein. Refer to the - CHANGELOG - for details. -
- -type: plugin -categories: - - traffic-control - -kong_version_compatibility: - community_edition: - compatible: - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x - - 0.4.x - - 0.3.x - enterprise_edition: - compatible: - - 0.34-x - - 0.33-x - - 0.32-x - - 0.31-x - -params: - name: request-size-limiting - api_id: true - service_id: true - route_id: true - consumer_id: true - konnect_examples: false - config: - - name: allowed_payload_size - required: true - default: "`128`" - value_in_examples: 128 - description: Allowed request payload size in megabytes, default is `128` (128000000 Bytes) - ---- diff --git a/app/_hub/kong-inc/request-size-limiting/1.0.x.md b/app/_hub/kong-inc/request-size-limiting/1.0.x.md deleted file mode 100644 index d8fdda514f49..000000000000 --- a/app/_hub/kong-inc/request-size-limiting/1.0.x.md +++ /dev/null @@ -1,74 +0,0 @@ ---- -name: Request Size Limiting -publisher: Kong Inc. -version: 1.0.0 - -desc: Block requests with bodies greater than a specified size -description: | -
- For security reasons we suggest enabling this plugin for any Service you add to Kong to prevent a DOS (Denial of Service) attack. -
- - Block incoming requests whose body is greater than a specific size in megabytes. - -type: plugin -categories: - - traffic-control - -kong_version_compatibility: - community_edition: - compatible: - - 2.2.x - - 2.1.x - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x - - 0.4.x - - 0.3.x - enterprise_edition: - compatible: - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x - - 0.35-x - - 0.34-x - - 0.33-x - - 0.32-x - - 0.31-x - -params: - name: request-size-limiting - service_id: true - route_id: true - consumer_id: true - konnect_examples: false - protocols: ["http", "https"] - dbless_compatible: yes - config: - - name: allowed_payload_size - required: true - default: "`128`" - value_in_examples: 128 - description: Allowed request payload size in megabytes, default is `128` (128000000 Bytes) - - name: size_unit - required: true - default: "`megabytes`" - description: Size unit can be set either in `bytes`, `kilobytes`, or `megabytes`. Note this configuration is not available in versions prior to Kong Gateway 1.3 and Kong Gateway 2.0. - ---- diff --git a/app/_hub/kong-inc/request-size-limiting/_index.md b/app/_hub/kong-inc/request-size-limiting/_index.md index 178c8ecca221..0a9daff7abfa 100644 --- a/app/_hub/kong-inc/request-size-limiting/_index.md +++ b/app/_hub/kong-inc/request-size-limiting/_index.md @@ -1,7 +1,6 @@ --- name: Request Size Limiting publisher: Kong Inc. -version: 2.0.0 desc: Block requests with bodies greater than a specified size description: |
@@ -15,47 +14,9 @@ categories: - traffic-control kong_version_compatibility: community_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x - - 0.4.x - - 0.3.x + compatible: true enterprise_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x + compatible: true params: name: request-size-limiting service_id: true @@ -79,6 +40,7 @@ params: datatype: string description: 'Size unit can be set either in `bytes`, `kilobytes`, or `megabytes` (default). This configuration is not available in versions prior to Kong Gateway 1.3 and Kong Gateway (OSS) 2.0.' - name: require_content_length + minimum_version: "2.3.x" required: true default: false datatype: boolean @@ -86,3 +48,7 @@ params: description: Set to `true` to ensure a valid `Content-Length` header exists before reading the request body. --- +## Changelog + +**{{site.base_gateway}} 2.3.x** +* Added the `require_content_length` configuration option. diff --git a/app/_hub/kong-inc/request-size-limiting/versions.yml b/app/_hub/kong-inc/request-size-limiting/versions.yml index bc466d57ec2e..499736e2925a 100644 --- a/app/_hub/kong-inc/request-size-limiting/versions.yml +++ b/app/_hub/kong-inc/request-size-limiting/versions.yml @@ -1,3 +1,12 @@ -- release: 2.0.x -- release: 1.0.x -- release: 0.1-x +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 2.0.0 + 2.7.x: 2.0.0 + 2.6.x: 2.0.0 + 2.5.x: 2.0.0 + 2.4.x: 2.0.0 + 2.3.x: 2.0.0 + 2.2.x: 2.0.0 + 2.1.x: 2.0.0 diff --git a/app/_hub/kong-inc/request-termination/0.1-x.md b/app/_hub/kong-inc/request-termination/0.1-x.md deleted file mode 100644 index d398b24fe8cc..000000000000 --- a/app/_hub/kong-inc/request-termination/0.1-x.md +++ /dev/null @@ -1,65 +0,0 @@ ---- -name: Request Termination -publisher: Kong Inc. -version: 0.1-x - -desc: Terminates all requests with a specific response -description: | - This plugin terminates incoming requests with a specified status code and - message. This allows to (temporarily) stop traffic on a Service or a Route - (or the deprecated API entity), or even block a Consumer. - -type: plugin -categories: - - traffic-control - -kong_version_compatibility: - community_edition: - compatible: - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - enterprise_edition: - compatible: - - 0.34-x - - 0.33-x - - 0.32-x - - 0.31-x - -params: - name: request-termination - api_id: true - service_id: true - route_id: true - consumer_id: true - config: - - name: status_code - required: false - default: "`503`" - value_in_examples: 403 - description: The response code to send. - - name: message - required: false - value_in_examples: "So long and thanks for all the fish!" - description: The message to send, if using the default response generator. - - name: body - required: false - description: The raw response body to send, this is mutually exclusive with the `config.message` field. - - name: content_type - required: false - default: "`application/json; charset=utf-8`" - description: Content type of the raw response configured with `config.body`. - extra: | - Once applied, every request (within the configured plugin scope of a Service, - Route, Consumer, API, or global) will be immediately terminated by - sending the configured response. - ---- - -## Example Use Cases - -- Temporarily disable a Service (e.g. it is under maintenance). -- Temporarily disable a Route (e.g. the rest of the Service is up and running, but a particular endpoint must be disabled). -- Temporarily disable a Consumer (e.g. excessive consumption). -- Block anonymous access with multiple auth plugins in a logical `OR` setup. diff --git a/app/_hub/kong-inc/request-termination/1.0.x.md b/app/_hub/kong-inc/request-termination/1.0.x.md deleted file mode 100644 index db8373c0f274..000000000000 --- a/app/_hub/kong-inc/request-termination/1.0.x.md +++ /dev/null @@ -1,84 +0,0 @@ ---- -name: Request Termination -publisher: Kong Inc. -version: 1.0.0 - -desc: Terminates all requests with a specific response -description: | - This plugin terminates incoming requests with a specified status code and - message. This allows to (temporarily) stop traffic on a Service or a Route, - or even block a Consumer. - -type: plugin -categories: - - traffic-control - -kong_version_compatibility: - community_edition: - compatible: - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - enterprise_edition: - compatible: - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x - -params: - name: request-termination - service_id: true - route_id: true - consumer_id: true - protocols: ["http", "https"] - dbless_compatible: yes - config: - - name: status_code - required: false - default: "`503`" - value_in_examples: 403 - datatype: integer - description: The response code to send. Must be an integer between 100 and 599. - - name: message - required: false - value_in_examples: "So long and thanks for all the fish!" - datatype: string - description: The message to send, if using the default response generator. - - name: body - required: false - datatype: string - description: The raw response body to send. This is mutually exclusive with the `config.message` field. - - name: content_type - required: false - default: "`application/json; charset=utf-8`" - datatype: string - description: Content type of the raw response configured with `config.body`. - extra: | - Once applied, every request (within the configured plugin scope of a Service, - Route, Consumer, or global) will be immediately terminated by - sending the configured response. - ---- - -## Example Use Cases - -- Temporarily disable a Service (e.g. it is under maintenance). -- Temporarily disable a Route (e.g. the rest of the Service is up and running, but a particular endpoint must be disabled). -- Temporarily disable a Consumer (e.g. excessive consumption). -- Block anonymous access with multiple auth plugins in a logical `OR` setup. diff --git a/app/_hub/kong-inc/request-termination/2.0.x.md b/app/_hub/kong-inc/request-termination/2.0.x.md deleted file mode 100644 index 9fbb05ee1ca3..000000000000 --- a/app/_hub/kong-inc/request-termination/2.0.x.md +++ /dev/null @@ -1,90 +0,0 @@ ---- -name: Request Termination -publisher: Kong Inc. -version: 2.0.0 - -desc: Terminates all requests with a specific response -description: | - This plugin terminates incoming requests with a specified status code and - message. This allows to (temporarily) stop traffic on a Service or a Route, - or even block a Consumer. - -type: plugin -categories: - - traffic-control - -kong_version_compatibility: - community_edition: - compatible: - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - enterprise_edition: - compatible: - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x - -params: - name: request-termination - service_id: true - route_id: true - consumer_id: true - protocols: ["http", "https"] - dbless_compatible: yes - config: - - name: status_code - required: false - default: "`503`" - value_in_examples: 403 - datatype: integer - description: The response code to send. Must be an integer between 100 and 599. - - name: message - required: false - value_in_examples: "So long and thanks for all the fish!" - datatype: string - description: The message to send, if using the default response generator. - - name: body - required: false - datatype: string - description: The raw response body to send. This is mutually exclusive with the `config.message` field. - - name: content_type - required: false - default: "`application/json; charset=utf-8`" - datatype: string - description: Content type of the raw response configured with `config.body`. - extra: | - Once applied, every request (within the configured plugin scope of a Service, - Route, Consumer, or global) will be immediately terminated by - sending the configured response. - ---- - -## New in 2.0.0 - -There were changes in the Plugin Handler structure and on the Plugins DAO (`load_plugin_schemas`) that make this plugin -backwards-incompatible if another plugin depended on it. - - -## Example Use Cases - -- Temporarily disable a Service (e.g. it is under maintenance). -- Temporarily disable a Route (e.g. the rest of the Service is up and running, but a particular endpoint must be disabled). -- Temporarily disable a Consumer (e.g. excessive consumption). -- Block anonymous access with multiple auth plugins in a logical `OR` setup. diff --git a/app/_hub/kong-inc/request-termination/_index.md b/app/_hub/kong-inc/request-termination/_index.md index 26c7c519842f..64f9715878e0 100644 --- a/app/_hub/kong-inc/request-termination/_index.md +++ b/app/_hub/kong-inc/request-termination/_index.md @@ -1,7 +1,6 @@ --- name: Request Termination publisher: Kong Inc. -version: 2.1.0 desc: Terminates all requests with a specific response description: | This plugin terminates incoming requests with a specified status code and @@ -12,39 +11,9 @@ categories: - traffic-control kong_version_compatibility: community_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x + compatible: true enterprise_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x + compatible: true params: name: request-termination service_id: true @@ -76,10 +45,12 @@ params: datatype: string description: Content type of the raw response configured with `config.body`. - name: trigger + minimum_version: "2.6.x" required: false default: null description: 'When not set, the plugin always activates. When set to a string, the plugin will activate exclusively on requests containing either a header or a query parameter that is named the string.' - name: echo + minimum_version: "2.6.x" required: false default: false description: 'When set, the plugin will echo a copy of the request back to the client. The main usecase for this is debugging. It can be combined with `trigger` in order to debug requests on live systems without disturbing real traffic.' @@ -89,11 +60,6 @@ params: sending the configured response. --- -## New in 2.1.0 - -- `trigger` config option -- `echo` config option - ## Example Use Cases - Temporarily disable a Service (e.g. it is under maintenance). @@ -101,3 +67,14 @@ params: - Temporarily disable a Consumer (e.g. excessive consumption). - Block anonymous access with multiple auth plugins in a logical `OR` setup. - Debugging erroneous requests in live systems. + +--- + +## Changelog + +**{{site.base_gateway}} 2.6.x** +* Added the `trigger` and `echo` configuration options + +**{{site.base_gateway}} 2.1.x** +* There were changes in the plugin handler structure and on the plugins DAO (`load_plugin_schemas`) that make this plugin +backwards-incompatible if another plugin depended on it. diff --git a/app/_hub/kong-inc/request-termination/versions.yml b/app/_hub/kong-inc/request-termination/versions.yml index 28b8d91826b3..de5f8b805cb3 100644 --- a/app/_hub/kong-inc/request-termination/versions.yml +++ b/app/_hub/kong-inc/request-termination/versions.yml @@ -1,4 +1,12 @@ -- release: 2.1.x -- release: 2.0.x -- release: 1.0.x -- release: 0.1-x +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 2.1.0 + 2.7.x: 2.1.0 + 2.6.x: 2.1.0 + 2.5.x: 2.0.1 + 2.4.x: 2.0.1 + 2.3.x: 2.0.1 + 2.2.x: 2.0.1 + 2.1.x: 2.0.0 diff --git a/app/_hub/kong-inc/request-transformer-advanced/0.31-x.md b/app/_hub/kong-inc/request-transformer-advanced/0.31-x.md deleted file mode 100644 index 7020d3e643b5..000000000000 --- a/app/_hub/kong-inc/request-transformer-advanced/0.31-x.md +++ /dev/null @@ -1,295 +0,0 @@ ---- - -name: Request Transformer Advanced -publisher: Kong Inc. -version: 0.31-x - -desc: Use powerful regular expressions, variables and templates to transform API requests -description: | - The Request Transformer plugin for Kong Gateway Edition builds on the Community Edition version of this plugin with enhanced capabilities to match portions of incoming requests using regular expressions, save those matched strings into variables, and substitute those strings into transformed requests via flexible templates. - -enterprise: true -type: plugin -categories: - - transformations - -kong_version_compatibility: - community_edition: - compatible: - enterprise_edition: - compatible: - - 0.31-x - -params: - name: request-transformer-advanced - api_id: true - service_id: true - route_id: true - consumer_id: true - konnect_examples: false - config: - - name: http_method - required: false - default: - value_in_examples: - description: | - Changes the HTTP method for the upstream request - - name: remove.headers - required: false - default: - value_in_examples: - description: | - List of header names. Unset the headers with the given name. - - name: remove.querystring - required: false - default: - value_in_examples: - description: | - List of querystring names. Remove the querystring if it is present. - - name: remove.body - required: false - default: - value_in_examples: - description: | - List of parameter names. Remove the parameter if and only if content-type is one the following [`application/json`, `multipart/form-data`, `application/x-www-form-urlencoded`] and parameter is present. - - name: replace.headers - required: false - default: - value_in_examples: - description: | - List of headername:value pairs. If and only if the header is already set, replace its old value with the new one. Ignored if the header is not already set. - - name: replace.querystring - required: false - default: - value_in_examples: - description: | - List of queryname:value pairs. If and only if the querystring name is already set, replace its old value with the new one. Ignored if the header is not already set. - - name: replace.uri - required: false - default: - value_in_examples: - description: | - Updates the upstream request URI with given value. This value can only be used to update the path part of the URI, not the scheme, nor the hostname. - - name: replace.body - required: false - default: - value_in_examples: - description: | - List of paramname:value pairs. If and only if content-type is one the following [`application/json`, `multipart/form-data`, `application/x-www-form-urlencoded`] and the parameter is already present, replace its old value with the new one. Ignored if the parameter is not already present. - - name: rename.headers - required: false - default: - value_in_examples: - description: | - List of headername:value pairs. If and only if the header is already set, rename the header. The value is unchanged. Ignored if the header is not already set. - - name: rename.querystring - required: false - default: - value_in_examples: - description: | - List of queryname:value pairs. If and only if the field name is already set, rename the field name. The value is unchanged. Ignored if the field name is not already set. - - name: rename.body - required: false - default: - value_in_examples: - description: | - List of parameter name:value pairs. Rename the parameter name if and only if content-type is one the following [`application/json`, `multipart/form-data`, `application/x-www-form-urlencoded`] and parameter is present. - - name: add.headers - required: false - default: - value_in_examples: - description: | - List of headername:value pairs. If and only if the header is not already set, set a new header with the given value. Ignored if the header is already set. - - name: add.querystring - required: false - default: - value_in_examples: - description: | - List of queryname:value pairs. If and only if the querystring name is not already set, set a new querystring with the given value. Ignored if the querystring name is already set. - - name: add.body - required: false - default: - value_in_examples: - description: | - List of paramname:value pairs. If and only if content-type is one the following [`application/json, multipart/form-data`, `application/x-www-form-urlencoded`] and the parameter is not present, add a new parameter with the given value to form-encoded body. Ignored if the parameter is already present. - - name: append.headers - required: false - default: - value_in_examples: - description: | - List of headername:value pairs. If the header is not set, set it with the given value. If it is already set, a new header with the same name and the new value will be set. - - name: append.querystring - required: false - default: - value_in_examples: - description: | - List of queryname:value pairs. If the querystring is not set, set it with the given value. If it is already set, a new querystring with the same name and the new value will be set. - - name: append.body - required: false - default: - value_in_examples: - description: | - List of paramname:value pairs. If the content-type is one the following [`application/json`, `application/x-www-form-urlencoded`], add a new parameter with the given value if the parameter is not present, otherwise if it is already present, the two values (old and new) will be aggregated in an array. - extra: | - Note: if the value contains a `,` then the comma separated format cannot be used. The array notation must be used instead. - ---- - -### Template as Value - -User can use any of the the current request headers, query params, and captured URI named groups as template to populate above supported config fields. - -| Request Param | Template -| --------- | ----------- -| header | $(headers. or $(headers['']) or 'optional_default') -| querystring | $(query_params. or $(query_params['query-param-name']) or 'optional_default') -| captured URIs | $(uri_captures. or $(uri_captures['group-name']) or 'optional_default') - -To escape a template, wrap it inside quotes and pass inside another template.
-Ex. $('$(some_needs_to_escaped)') - -Note: Plugin creates a non mutable table of request headers, querystrings, and captured URIs before transformation. So any update or removal of params used in template does not affect the rendered value of template. - -#### Examples Using Template as Value - -Add an API `test` with `uris` configured with a named capture group `user_id` - -```bash -$ curl -X POST http://localhost:8001/apis \ - --data 'name=test' \ - --data 'upstream_url=http://mockbin.com' \ - --data-urlencode 'uris=/requests/user/(?\w+)' \ - --data "strip_uri=false" -``` - -Enable the ‘request-transformer-advanced’ plugin to add a new header `x-consumer-id` -and its value is being set with the value sent with header `x-user-id` or -with the default value alice is `header` is missing. - -```bash -$ curl -X POST http://localhost:8001/apis/test/plugins \ - --data "name=request-transformer-advanced" \ - --data-urlencode "config.add.headers=x-consumer-id:\$(headers['x-user-id'] or 'alice')" \ - --data "config.remove.headers=x-user-id" -``` - -Now send a request without setting header `x-user-id` - -```bash -$ curl -i -X GET localhost:8000/requests/user/foo -``` - -Plugin will add a new header `x-consumer-id` with value alice before proxying -request upstream. Now try sending request with header `x-user-id` set - -```bash -$ curl -i -X GET localhost:8000/requests/user/foo \ - -H "X-User-Id:bob" -``` - -This time plugin will add a new header `x-consumer-id` with value sent along -with header `x-user-id`, i.e.`bob` - -### Order of Execution - -Plugin performs the response transformation in following order - -remove –> replace –> add –> append - -### Configuration Examples - -Add multiple headers by passing each header:value pair separately: - -```bash -$ curl -X POST http://localhost:8001/apis/mockbin/plugins \ - --data "name=request-transformer-advanced" \ - --data "config.add.headers[1]=h1:v1" \ - --data "config.add.headers[2]=h2:v1" -``` - -| Incoming Request Headers | Upstream Proxied Headers -| --------- | ----------- -| h1: v1 | h1: v1, h2: v1 - -Add multiple headers by passing comma separated header:value pair: - -```bash -$ curl -X POST http://localhost:8001/apis/mockbin/plugins \ - --data "name=request-transformer-advanced" \ - --data "config.add.headers=h1:v1,h2:v2" -``` - -| Incoming Request Headers | Upstream Proxied Headers -| --------- | ----------- -| h1: v1 | h1: v1, h2: v1 - -Add multiple headers passing config as JSON body: - -```bash -$ curl -X POST http://localhost:8001/apis/mockbin/plugins \ - --header 'content-type: application/json' \ - --data '{"name": "request-transformer-advanced", "config": {"add": {"headers": ["h1:v2", "h2:v1"]}}}' -``` - -| Incoming Request Headers | Upstream Proxied Headers -| --------- | ----------- -| h1: v1 | h1: v1, h2: v1 - -Add a querystring and a header: - -```bash -$ curl -X POST http://localhost:8001/apis/mockbin/plugins \ - --data "name=request-transformer-advanced" \ - --data "config.add.querystring=q1:v2,q2=v1" \ - --data "config.add.headers=h1:v1" - -``` - -| Incoming Request Headers | Upstream Proxied Headers -| --------- | ----------- -| h1: v1 | h1: v1, h2: v1 -| h3: v1 | h1: v1, h2: v1, h3: v1 - -| Incoming Request Querystring | Upstream Proxied Querystring -| --------- | ----------- -| ?q1=v1 | ?q1=v1&q2=v1 -| | ?q1=v2&q2=v1 - -Append multiple headers and remove a body parameter: - -```bash -$ curl -X POST http://localhost:8001/apis/mockbin/plugins \ - --data "name=request-transformer-advanced" \ - --data "config.add.headers=h1:v2,h2:v1" \ - --data "config.remove.body=p1" \ - -``` - -| Incoming Request Headers | Upstream Proxied Headers -| --------- | ----------- -| h1: v1 | h1: v1, h1: v2, h2: v1 - -| Incoming URL Encoded Body | Upstream Proxied URL Encoded Body -| --------- | ----------- -| p1=v1&p2=v1 | p2=v1 -| p2=v1 | p2=v1 - -Add multiple headers and querystring parameters if not already set: - -```bash -$ curl -X POST http://localhost:8001/apis/mockbin/plugins \ - --data "name=request-transformer-advanced" \ - --data "config.add.headers=h1:v1,h2:v1" \ - --data "config.add.querystring=q1:v2,q2:v1" \ - -``` - -| Incoming Request Headers | Upstream Proxied Headers -| --------- | ----------- -| h1: v1 | h1: v1, h2: v1 -| h3: v1 | h1: v1, h2: v1, h3: v1 - -| Incoming Request Querystring | Upstream Proxied Querystring -| --------- | ----------- -| ?q1=v1 | ?q1=v1&q2=v1 -| | ?q1=v2&q2=v1 diff --git a/app/_hub/kong-inc/request-transformer-advanced/0.32-x.md b/app/_hub/kong-inc/request-transformer-advanced/0.32-x.md deleted file mode 100644 index 833b5601f599..000000000000 --- a/app/_hub/kong-inc/request-transformer-advanced/0.32-x.md +++ /dev/null @@ -1,295 +0,0 @@ ---- - -name: Request Transformer Advanced -publisher: Kong Inc. -version: 0.32-x - -desc: Use powerful regular expressions, variables and templates to transform API requests -description: | - The Request Transformer plugin for Kong Gateway Edition builds on the Community Edition version of this plugin with enhanced capabilities to match portions of incoming requests using regular expressions, save those matched strings into variables, and substitute those strings into transformed requests via flexible templates. - -enterprise: true -type: plugin -categories: - - transformations - -kong_version_compatibility: - community_edition: - compatible: - enterprise_edition: - compatible: - - 0.32-x - -params: - name: request-transformer-advanced - api_id: true - service_id: true - route_id: true - consumer_id: true - konnect_examples: false - config: - - name: http_method - required: false - default: - value_in_examples: - description: | - Changes the HTTP method for the upstream request - - name: remove.headers - required: false - default: - value_in_examples: - description: | - List of header names. Unset the headers with the given name. - - name: remove.querystring - required: false - default: - value_in_examples: - description: | - List of querystring names. Remove the querystring if it is present. - - name: remove.body - required: false - default: - value_in_examples: - description: | - List of parameter names. Remove the parameter if and only if content-type is one the following [`application/json`, `multipart/form-data`, `application/x-www-form-urlencoded`] and parameter is present. - - name: replace.headers - required: false - default: - value_in_examples: - description: | - List of headername:value pairs. If and only if the header is already set, replace its old value with the new one. Ignored if the header is not already set. - - name: replace.querystring - required: false - default: - value_in_examples: - description: | - List of queryname:value pairs. If and only if the querystring name is already set, replace its old value with the new one. Ignored if the header is not already set. - - name: replace.uri - required: false - default: - value_in_examples: - description: | - Updates the upstream request URI with given value. This value can only be used to update the path part of the URI, not the scheme, nor the hostname. - - name: replace.body - required: false - default: - value_in_examples: - description: | - List of paramname:value pairs. If and only if content-type is one the following [`application/json`, `multipart/form-data`, `application/x-www-form-urlencoded`] and the parameter is already present, replace its old value with the new one. Ignored if the parameter is not already present. - - name: rename.headers - required: false - default: - value_in_examples: - description: | - List of headername:value pairs. If and only if the header is already set, rename the header. The value is unchanged. Ignored if the header is not already set. - - name: rename.querystring - required: false - default: - value_in_examples: - description: | - List of queryname:value pairs. If and only if the field name is already set, rename the field name. The value is unchanged. Ignored if the field name is not already set. - - name: rename.body - required: false - default: - value_in_examples: - description: | - List of parameter name:value pairs. Rename the parameter name if and only if content-type is one the following [`application/json`, `multipart/form-data`, `application/x-www-form-urlencoded`] and parameter is present. - - name: add.headers - required: false - default: - value_in_examples: - description: | - List of headername:value pairs. If and only if the header is not already set, set a new header with the given value. Ignored if the header is already set. - - name: add.querystring - required: false - default: - value_in_examples: - description: | - List of queryname:value pairs. If and only if the querystring name is not already set, set a new querystring with the given value. Ignored if the querystring name is already set. - - name: add.body - required: false - default: - value_in_examples: - description: | - List of paramname:value pairs. If and only if content-type is one the following [`application/json, multipart/form-data`, `application/x-www-form-urlencoded`] and the parameter is not present, add a new parameter with the given value to form-encoded body. Ignored if the parameter is already present. - - name: append.headers - required: false - default: - value_in_examples: - description: | - List of headername:value pairs. If the header is not set, set it with the given value. If it is already set, a new header with the same name and the new value will be set. - - name: append.querystring - required: false - default: - value_in_examples: - description: | - List of queryname:value pairs. If the querystring is not set, set it with the given value. If it is already set, a new querystring with the same name and the new value will be set. - - name: append.body - required: false - default: - value_in_examples: - description: | - List of paramname:value pairs. If the content-type is one the following [`application/json`, `application/x-www-form-urlencoded`], add a new parameter with the given value if the parameter is not present, otherwise if it is already present, the two values (old and new) will be aggregated in an array. - extra: | - Note: if the value contains a `,` then the comma separated format cannot be used. The array notation must be used instead. - ---- - -### Template as Value - -User can use any of the the current request headers, query params, and captured URI named groups as template to populate above supported config fields. - -| Request Param | Template -| --------- | ----------- -| header | $(headers. or $(headers['']) or 'optional_default') -| querystring | $(query_params. or $(query_params['query-param-name']) or 'optional_default') -| captured URIs | $(uri_captures. or $(uri_captures['group-name']) or 'optional_default') - -To escape a template, wrap it inside quotes and pass inside another template.
-Ex. $('$(some_needs_to_escaped)') - -Note: Plugin creates a non mutable table of request headers, querystrings, and captured URIs before transformation. So any update or removal of params used in template does not affect the rendered value of template. - -#### Examples Using Template as Value - -Add an API `test` with `uris` configured with a named capture group `user_id` - -```bash -$ curl -X POST http://localhost:8001/apis \ - --data 'name=test' \ - --data 'upstream_url=http://mockbin.com' \ - --data-urlencode 'uris=/requests/user/(?\w+)' \ - --data "strip_uri=false" -``` - -Enable the ‘request-transformer-advanced’ plugin to add a new header `x-consumer-id` -and its value is being set with the value sent with header `x-user-id` or -with the default value alice is `header` is missing. - -```bash -$ curl -X POST http://localhost:8001/apis/test/plugins \ - --data "name=request-transformer-advanced" \ - --data-urlencode "config.add.headers=x-consumer-id:\$(headers['x-user-id'] or 'alice')" \ - --data "config.remove.headers=x-user-id" -``` - -Now send a request without setting header `x-user-id` - -```bash -$ curl -i -X GET localhost:8000/requests/user/foo -``` - -Plugin will add a new header `x-consumer-id` with value alice before proxying -request upstream. Now try sending request with header `x-user-id` set - -```bash -$ curl -i -X GET localhost:8000/requests/user/foo \ - -H "X-User-Id:bob" -``` - -This time plugin will add a new header `x-consumer-id` with value sent along -with header `x-user-id`, i.e.`bob` - -### Order of Execution - -Plugin performs the response transformation in following order - -remove –> replace –> add –> append - -### Configuration Examples - -Add multiple headers by passing each header:value pair separately: - -```bash -$ curl -X POST http://localhost:8001/apis/mockbin/plugins \ - --data "name=request-transformer-advanced" \ - --data "config.add.headers[1]=h1:v1" \ - --data "config.add.headers[2]=h2:v1" -``` - -| Incoming Request Headers | Upstream Proxied Headers -| --------- | ----------- -| h1: v1 | h1: v1, h2: v1 - -Add multiple headers by passing comma separated header:value pair: - -```bash -$ curl -X POST http://localhost:8001/apis/mockbin/plugins \ - --data "name=request-transformer-advanced" \ - --data "config.add.headers=h1:v1,h2:v2" -``` - -| Incoming Request Headers | Upstream Proxied Headers -| --------- | ----------- -| h1: v1 | h1: v1, h2: v1 - -Add multiple headers passing config as JSON body: - -```bash -$ curl -X POST http://localhost:8001/apis/mockbin/plugins \ - --header 'content-type: application/json' \ - --data '{"name": "request-transformer-advanced", "config": {"add": {"headers": ["h1:v2", "h2:v1"]}}}' -``` - -| Incoming Request Headers | Upstream Proxied Headers -| --------- | ----------- -| h1: v1 | h1: v1, h2: v1 - -Add a querystring and a header: - -```bash -$ curl -X POST http://localhost:8001/apis/mockbin/plugins \ - --data "name=request-transformer-advanced" \ - --data "config.add.querystring=q1:v2,q2=v1" \ - --data "config.add.headers=h1:v1" - -``` - -| Incoming Request Headers | Upstream Proxied Headers -| --------- | ----------- -| h1: v1 | h1: v1, h2: v1 -| h3: v1 | h1: v1, h2: v1, h3: v1 - -| Incoming Request Querystring | Upstream Proxied Querystring -| --------- | ----------- -| ?q1=v1 | ?q1=v1&q2=v1 -| | ?q1=v2&q2=v1 - -Append multiple headers and remove a body parameter: - -```bash -$ curl -X POST http://localhost:8001/apis/mockbin/plugins \ - --data "name=request-transformer-advanced" \ - --data "config.add.headers=h1:v2,h2:v1" \ - --data "config.remove.body=p1" \ - -``` - -| Incoming Request Headers | Upstream Proxied Headers -| --------- | ----------- -| h1: v1 | h1: v1, h1: v2, h2: v1 - -| Incoming URL Encoded Body | Upstream Proxied URL Encoded Body -| --------- | ----------- -| p1=v1&p2=v1 | p2=v1 -| p2=v1 | p2=v1 - -Add multiple headers and querystring parameters if not already set: - -```bash -$ curl -X POST http://localhost:8001/apis/mockbin/plugins \ - --data "name=request-transformer-advanced" \ - --data "config.add.headers=h1:v1,h2:v1" \ - --data "config.add.querystring=q1:v2,q2:v1" \ - -``` - -| Incoming Request Headers | Upstream Proxied Headers -| --------- | ----------- -| h1: v1 | h1: v1, h2: v1 -| h3: v1 | h1: v1, h2: v1, h3: v1 - -| Incoming Request Querystring | Upstream Proxied Querystring -| --------- | ----------- -| ?q1=v1 | ?q1=v1&q2=v1 -| | ?q1=v2&q2=v1 diff --git a/app/_hub/kong-inc/request-transformer-advanced/0.33-x.md b/app/_hub/kong-inc/request-transformer-advanced/0.33-x.md deleted file mode 100644 index a63d12102bd6..000000000000 --- a/app/_hub/kong-inc/request-transformer-advanced/0.33-x.md +++ /dev/null @@ -1,295 +0,0 @@ ---- - -name: Request Transformer Advanced -publisher: Kong Inc. -version: 0.33-x - -desc: Use powerful regular expressions, variables and templates to transform API requests -description: | - The Request Transformer plugin for Kong Gateway builds on the Kong version of this plugin with enhanced capabilities to match portions of incoming requests using regular expressions, save those matched strings into variables, and substitute those strings into transformed requests via flexible templates. - -enterprise: true -type: plugin -categories: - - transformations - -kong_version_compatibility: - community_edition: - compatible: - enterprise_edition: - compatible: - - 0.33-x - -params: - name: request-transformer-advanced - api_id: true - service_id: true - route_id: true - consumer_id: true - konnect_examples: false - config: - - name: http_method - required: false - default: - value_in_examples: - description: | - Changes the HTTP method for the upstream request - - name: remove.headers - required: false - default: - value_in_examples: - description: | - List of header names. Unset the headers with the given name. - - name: remove.querystring - required: false - default: - value_in_examples: - description: | - List of querystring names. Remove the querystring if it is present. - - name: remove.body - required: false - default: - value_in_examples: - description: | - List of parameter names. Remove the parameter if and only if content-type is one the following [`application/json`, `multipart/form-data`, `application/x-www-form-urlencoded`] and parameter is present. - - name: replace.headers - required: false - default: - value_in_examples: - description: | - List of headername:value pairs. If and only if the header is already set, replace its old value with the new one. Ignored if the header is not already set. - - name: replace.querystring - required: false - default: - value_in_examples: - description: | - List of queryname:value pairs. If and only if the querystring name is already set, replace its old value with the new one. Ignored if the header is not already set. - - name: replace.uri - required: false - default: - value_in_examples: - description: | - Updates the upstream request URI with given value. This value can only be used to update the path part of the URI, not the scheme, nor the hostname. - - name: replace.body - required: false - default: - value_in_examples: - description: | - List of paramname:value pairs. If and only if content-type is one the following [`application/json`, `multipart/form-data`, `application/x-www-form-urlencoded`] and the parameter is already present, replace its old value with the new one. Ignored if the parameter is not already present. - - name: rename.headers - required: false - default: - value_in_examples: - description: | - List of headername:value pairs. If and only if the header is already set, rename the header. The value is unchanged. Ignored if the header is not already set. - - name: rename.querystring - required: false - default: - value_in_examples: - description: | - List of queryname:value pairs. If and only if the field name is already set, rename the field name. The value is unchanged. Ignored if the field name is not already set. - - name: rename.body - required: false - default: - value_in_examples: - description: | - List of parameter name:value pairs. Rename the parameter name if and only if content-type is one the following [`application/json`, `multipart/form-data`, `application/x-www-form-urlencoded`] and parameter is present. - - name: add.headers - required: false - default: - value_in_examples: - description: | - List of headername:value pairs. If and only if the header is not already set, set a new header with the given value. Ignored if the header is already set. - - name: add.querystring - required: false - default: - value_in_examples: - description: | - List of queryname:value pairs. If and only if the querystring name is not already set, set a new querystring with the given value. Ignored if the querystring name is already set. - - name: add.body - required: false - default: - value_in_examples: - description: | - List of paramname:value pairs. If and only if content-type is one the following [`application/json, multipart/form-data`, `application/x-www-form-urlencoded`] and the parameter is not present, add a new parameter with the given value to form-encoded body. Ignored if the parameter is already present. - - name: append.headers - required: false - default: - value_in_examples: - description: | - List of headername:value pairs. If the header is not set, set it with the given value. If it is already set, a new header with the same name and the new value will be set. - - name: append.querystring - required: false - default: - value_in_examples: - description: | - List of queryname:value pairs. If the querystring is not set, set it with the given value. If it is already set, a new querystring with the same name and the new value will be set. - - name: append.body - required: false - default: - value_in_examples: - description: | - List of paramname:value pairs. If the content-type is one the following [`application/json`, `application/x-www-form-urlencoded`], add a new parameter with the given value if the parameter is not present, otherwise if it is already present, the two values (old and new) will be aggregated in an array. - extra: | - Note: if the value contains a `,` then the comma separated format cannot be used. The array notation must be used instead. - ---- - -### Template as Value - -User can use any of the the current request headers, query params, and captured URI named groups as template to populate above supported config fields. - -| Request Param | Template -| --------- | ----------- -| header | $(headers. or $(headers['']) or 'optional_default') -| querystring | $(query_params. or $(query_params['query-param-name']) or 'optional_default') -| captured URIs | $(uri_captures. or $(uri_captures['group-name']) or 'optional_default') - -To escape a template, wrap it inside quotes and pass inside another template.
-Ex. $('$(some_needs_to_escaped)') - -Note: Plugin creates a non mutable table of request headers, querystrings, and captured URIs before transformation. So any update or removal of params used in template does not affect the rendered value of template. - -#### Examples Using Template as Value - -Add an API `test` with `uris` configured with a named capture group `user_id` - -```bash -$ curl -X POST http://localhost:8001/apis \ - --data 'name=test' \ - --data 'upstream_url=http://mockbin.com' \ - --data-urlencode 'uris=/requests/user/(?\w+)' \ - --data "strip_uri=false" -``` - -Enable the ‘request-transformer-advanced’ plugin to add a new header `x-consumer-id` -and its value is being set with the value sent with header `x-user-id` or -with the default value alice is `header` is missing. - -```bash -$ curl -X POST http://localhost:8001/apis/test/plugins \ - --data "name=request-transformer-advanced" \ - --data-urlencode "config.add.headers=x-consumer-id:\$(headers['x-user-id'] or 'alice')" \ - --data "config.remove.headers=x-user-id" -``` - -Now send a request without setting header `x-user-id` - -```bash -$ curl -i -X GET localhost:8000/requests/user/foo -``` - -Plugin will add a new header `x-consumer-id` with value alice before proxying -request upstream. Now try sending request with header `x-user-id` set - -```bash -$ curl -i -X GET localhost:8000/requests/user/foo \ - -H "X-User-Id:bob" -``` - -This time plugin will add a new header `x-consumer-id` with value sent along -with header `x-user-id`, i.e.`bob` - -### Order of Execution - -Plugin performs the response transformation in following order - -remove –> replace –> add –> append - -### Configuration Examples - -Add multiple headers by passing each header:value pair separately: - -```bash -$ curl -X POST http://localhost:8001/apis/mockbin/plugins \ - --data "name=request-transformer-advanced" \ - --data "config.add.headers[1]=h1:v1" \ - --data "config.add.headers[2]=h2:v1" -``` - -| Incoming Request Headers | Upstream Proxied Headers -| --------- | ----------- -| h1: v1 | h1: v1, h2: v1 - -Add multiple headers by passing comma separated header:value pair: - -```bash -$ curl -X POST http://localhost:8001/apis/mockbin/plugins \ - --data "name=request-transformer-advanced" \ - --data "config.add.headers=h1:v1,h2:v2" -``` - -| Incoming Request Headers | Upstream Proxied Headers -| --------- | ----------- -| h1: v1 | h1: v1, h2: v1 - -Add multiple headers passing config as JSON body: - -```bash -$ curl -X POST http://localhost:8001/apis/mockbin/plugins \ - --header 'content-type: application/json' \ - --data '{"name": "request-transformer-advanced", "config": {"add": {"headers": ["h1:v2", "h2:v1"]}}}' -``` - -| Incoming Request Headers | Upstream Proxied Headers -| --------- | ----------- -| h1: v1 | h1: v1, h2: v1 - -Add a querystring and a header: - -```bash -$ curl -X POST http://localhost:8001/apis/mockbin/plugins \ - --data "name=request-transformer-advanced" \ - --data "config.add.querystring=q1:v2,q2=v1" \ - --data "config.add.headers=h1:v1" - -``` - -| Incoming Request Headers | Upstream Proxied Headers -| --------- | ----------- -| h1: v1 | h1: v1, h2: v1 -| h3: v1 | h1: v1, h2: v1, h3: v1 - -| Incoming Request Querystring | Upstream Proxied Querystring -| --------- | ----------- -| ?q1=v1 | ?q1=v1&q2=v1 -| | ?q1=v2&q2=v1 - -Append multiple headers and remove a body parameter: - -```bash -$ curl -X POST http://localhost:8001/apis/mockbin/plugins \ - --data "name=request-transformer-advanced" \ - --data "config.add.headers=h1:v2,h2:v1" \ - --data "config.remove.body=p1" \ - -``` - -| Incoming Request Headers | Upstream Proxied Headers -| --------- | ----------- -| h1: v1 | h1: v1, h1: v2, h2: v1 - -| Incoming URL Encoded Body | Upstream Proxied URL Encoded Body -| --------- | ----------- -| p1=v1&p2=v1 | p2=v1 -| p2=v1 | p2=v1 - -Add multiple headers and querystring parameters if not already set: - -```bash -$ curl -X POST http://localhost:8001/apis/mockbin/plugins \ - --data "name=request-transformer-advanced" \ - --data "config.add.headers=h1:v1,h2:v1" \ - --data "config.add.querystring=q1:v2,q2:v1" \ - -``` - -| Incoming Request Headers | Upstream Proxied Headers -| --------- | ----------- -| h1: v1 | h1: v1, h2: v1 -| h3: v1 | h1: v1, h2: v1, h3: v1 - -| Incoming Request Querystring | Upstream Proxied Querystring -| --------- | ----------- -| ?q1=v1 | ?q1=v1&q2=v1 -| | ?q1=v2&q2=v1 diff --git a/app/_hub/kong-inc/request-transformer-advanced/0.34-x.md b/app/_hub/kong-inc/request-transformer-advanced/0.34-x.md deleted file mode 100644 index 64354f2a6a0c..000000000000 --- a/app/_hub/kong-inc/request-transformer-advanced/0.34-x.md +++ /dev/null @@ -1,295 +0,0 @@ ---- - -name: Request Transformer Advanced -publisher: Kong Inc. -version: 0.34-x - -desc: Use powerful regular expressions, variables and templates to transform API requests -description: | - The Request Transformer plugin for Kong Gateway builds on the Kong version of this plugin with enhanced capabilities to match portions of incoming requests using regular expressions, save those matched strings into variables, and substitute those strings into transformed requests via flexible templates. - -enterprise: true -type: plugin -categories: - - transformations - -kong_version_compatibility: - community_edition: - compatible: - enterprise_edition: - compatible: - - 0.34-x - -params: - name: request-transformer-advanced - api_id: true - service_id: true - route_id: true - consumer_id: true - konnect_examples: false - config: - - name: http_method - required: false - default: - value_in_examples: - description: | - Changes the HTTP method for the upstream request - - name: remove.headers - required: false - default: - value_in_examples: - description: | - List of header names. Unset the headers with the given name. - - name: remove.querystring - required: false - default: - value_in_examples: - description: | - List of querystring names. Remove the querystring if it is present. - - name: remove.body - required: false - default: - value_in_examples: - description: | - List of parameter names. Remove the parameter if and only if content-type is one the following [`application/json`, `multipart/form-data`, `application/x-www-form-urlencoded`] and parameter is present. - - name: replace.headers - required: false - default: - value_in_examples: - description: | - List of headername:value pairs. If and only if the header is already set, replace its old value with the new one. Ignored if the header is not already set. - - name: replace.querystring - required: false - default: - value_in_examples: - description: | - List of queryname:value pairs. If and only if the querystring name is already set, replace its old value with the new one. Ignored if the header is not already set. - - name: replace.uri - required: false - default: - value_in_examples: - description: | - Updates the upstream request URI with given value. This value can only be used to update the path part of the URI, not the scheme, nor the hostname. - - name: replace.body - required: false - default: - value_in_examples: - description: | - List of paramname:value pairs. If and only if content-type is one the following [`application/json`, `multipart/form-data`, `application/x-www-form-urlencoded`] and the parameter is already present, replace its old value with the new one. Ignored if the parameter is not already present. - - name: rename.headers - required: false - default: - value_in_examples: - description: | - List of headername:value pairs. If and only if the header is already set, rename the header. The value is unchanged. Ignored if the header is not already set. - - name: rename.querystring - required: false - default: - value_in_examples: - description: | - List of queryname:value pairs. If and only if the field name is already set, rename the field name. The value is unchanged. Ignored if the field name is not already set. - - name: rename.body - required: false - default: - value_in_examples: - description: | - List of parameter name:value pairs. Rename the parameter name if and only if content-type is one the following [`application/json`, `multipart/form-data`, `application/x-www-form-urlencoded`] and parameter is present. - - name: add.headers - required: false - default: - value_in_examples: - description: | - List of headername:value pairs. If and only if the header is not already set, set a new header with the given value. Ignored if the header is already set. - - name: add.querystring - required: false - default: - value_in_examples: - description: | - List of queryname:value pairs. If and only if the querystring name is not already set, set a new querystring with the given value. Ignored if the querystring name is already set. - - name: add.body - required: false - default: - value_in_examples: - description: | - List of paramname:value pairs. If and only if content-type is one the following [`application/json, multipart/form-data`, `application/x-www-form-urlencoded`] and the parameter is not present, add a new parameter with the given value to form-encoded body. Ignored if the parameter is already present. - - name: append.headers - required: false - default: - value_in_examples: - description: | - List of headername:value pairs. If the header is not set, set it with the given value. If it is already set, a new header with the same name and the new value will be set. - - name: append.querystring - required: false - default: - value_in_examples: - description: | - List of queryname:value pairs. If the querystring is not set, set it with the given value. If it is already set, a new querystring with the same name and the new value will be set. - - name: append.body - required: false - default: - value_in_examples: - description: | - List of paramname:value pairs. If the content-type is one the following [`application/json`, `application/x-www-form-urlencoded`], add a new parameter with the given value if the parameter is not present, otherwise if it is already present, the two values (old and new) will be aggregated in an array. - extra: | - Note: if the value contains a `,` then the comma separated format cannot be used. The array notation must be used instead. - ---- - -### Template as Value - -User can use any of the the current request headers, query params, and captured URI named groups as template to populate above supported config fields. - -| Request Param | Template -| --------- | ----------- -| header | $(headers. or $(headers['']) or 'optional_default') -| querystring | $(query_params. or $(query_params['query-param-name']) or 'optional_default') -| captured URIs | $(uri_captures. or $(uri_captures['group-name']) or 'optional_default') - -To escape a template, wrap it inside quotes and pass inside another template.
-Ex. $('$(some_needs_to_escaped)') - -Note: Plugin creates a non mutable table of request headers, querystrings, and captured URIs before transformation. So any update or removal of params used in template does not affect the rendered value of template. - -#### Examples Using Template as Value - -Add an API `test` with `uris` configured with a named capture group `user_id` - -```bash -$ curl -X POST http://localhost:8001/apis \ - --data 'name=test' \ - --data 'upstream_url=http://mockbin.com' \ - --data-urlencode 'uris=/requests/user/(?\w+)' \ - --data "strip_uri=false" -``` - -Enable the ‘request-transformer-advanced’ plugin to add a new header `x-consumer-id` -and its value is being set with the value sent with header `x-user-id` or -with the default value alice is `header` is missing. - -```bash -$ curl -X POST http://localhost:8001/apis/test/plugins \ - --data "name=request-transformer-advanced" \ - --data-urlencode "config.add.headers=x-consumer-id:\$(headers['x-user-id'] or 'alice')" \ - --data "config.remove.headers=x-user-id" -``` - -Now send a request without setting header `x-user-id` - -```bash -$ curl -i -X GET localhost:8000/requests/user/foo -``` - -Plugin will add a new header `x-consumer-id` with value alice before proxying -request upstream. Now try sending request with header `x-user-id` set - -```bash -$ curl -i -X GET localhost:8000/requests/user/foo \ - -H "X-User-Id:bob" -``` - -This time plugin will add a new header `x-consumer-id` with value sent along -with header `x-user-id`, i.e.`bob` - -### Order of Execution - -Plugin performs the response transformation in following order - -remove –> replace –> add –> append - -### Configuration Examples - -Add multiple headers by passing each header:value pair separately: - -```bash -$ curl -X POST http://localhost:8001/apis/mockbin/plugins \ - --data "name=request-transformer-advanced" \ - --data "config.add.headers[1]=h1:v1" \ - --data "config.add.headers[2]=h2:v1" -``` - -| Incoming Request Headers | Upstream Proxied Headers -| --------- | ----------- -| h1: v1 | h1: v1, h2: v1 - -Add multiple headers by passing comma separated header:value pair: - -```bash -$ curl -X POST http://localhost:8001/apis/mockbin/plugins \ - --data "name=request-transformer-advanced" \ - --data "config.add.headers=h1:v1,h2:v2" -``` - -| Incoming Request Headers | Upstream Proxied Headers -| --------- | ----------- -| h1: v1 | h1: v1, h2: v1 - -Add multiple headers passing config as JSON body: - -```bash -$ curl -X POST http://localhost:8001/apis/mockbin/plugins \ - --header 'content-type: application/json' \ - --data '{"name": "request-transformer-advanced", "config": {"add": {"headers": ["h1:v2", "h2:v1"]}}}' -``` - -| Incoming Request Headers | Upstream Proxied Headers -| --------- | ----------- -| h1: v1 | h1: v1, h2: v1 - -Add a querystring and a header: - -```bash -$ curl -X POST http://localhost:8001/apis/mockbin/plugins \ - --data "name=request-transformer-advanced" \ - --data "config.add.querystring=q1:v2,q2=v1" \ - --data "config.add.headers=h1:v1" - -``` - -| Incoming Request Headers | Upstream Proxied Headers -| --------- | ----------- -| h1: v1 | h1: v1, h2: v1 -| h3: v1 | h1: v1, h2: v1, h3: v1 - -| Incoming Request Querystring | Upstream Proxied Querystring -| --------- | ----------- -| ?q1=v1 | ?q1=v1&q2=v1 -| | ?q1=v2&q2=v1 - -Append multiple headers and remove a body parameter: - -```bash -$ curl -X POST http://localhost:8001/apis/mockbin/plugins \ - --data "name=request-transformer-advanced" \ - --data "config.add.headers=h1:v2,h2:v1" \ - --data "config.remove.body=p1" \ - -``` - -| Incoming Request Headers | Upstream Proxied Headers -| --------- | ----------- -| h1: v1 | h1: v1, h1: v2, h2: v1 - -| Incoming URL Encoded Body | Upstream Proxied URL Encoded Body -| --------- | ----------- -| p1=v1&p2=v1 | p2=v1 -| p2=v1 | p2=v1 - -Add multiple headers and querystring parameters if not already set: - -```bash -$ curl -X POST http://localhost:8001/apis/mockbin/plugins \ - --data "name=request-transformer-advanced" \ - --data "config.add.headers=h1:v1,h2:v1" \ - --data "config.add.querystring=q1:v2,q2:v1" \ - -``` - -| Incoming Request Headers | Upstream Proxied Headers -| --------- | ----------- -| h1: v1 | h1: v1, h2: v1 -| h3: v1 | h1: v1, h2: v1, h3: v1 - -| Incoming Request Querystring | Upstream Proxied Querystring -| --------- | ----------- -| ?q1=v1 | ?q1=v1&q2=v1 -| | ?q1=v2&q2=v1 diff --git a/app/_hub/kong-inc/request-transformer-advanced/0.35-x.md b/app/_hub/kong-inc/request-transformer-advanced/0.35-x.md deleted file mode 100644 index ab3d1eb66d44..000000000000 --- a/app/_hub/kong-inc/request-transformer-advanced/0.35-x.md +++ /dev/null @@ -1,295 +0,0 @@ ---- - -name: Request Transformer Advanced -publisher: Kong Inc. -version: 0.35-x - -desc: Use powerful regular expressions, variables and templates to transform API requests -description: | - The Request Transformer plugin for Kong Gateway builds on the Kong version of this plugin with enhanced capabilities to match portions of incoming requests using regular expressions, save those matched strings into variables, and substitute those strings into transformed requests via flexible templates. - -enterprise: true -type: plugin -categories: - - transformations - -kong_version_compatibility: - community_edition: - compatible: - enterprise_edition: - compatible: - - 0.35-x - -params: - name: request-transformer-advanced - api_id: true - service_id: true - route_id: true - consumer_id: true - konnect_examples: false - config: - - name: http_method - required: false - default: - value_in_examples: - description: | - Changes the HTTP method for the upstream request - - name: remove.headers - required: false - default: - value_in_examples: - description: | - List of header names. Unset the headers with the given name. - - name: remove.querystring - required: false - default: - value_in_examples: - description: | - List of querystring names. Remove the querystring if it is present. - - name: remove.body - required: false - default: - value_in_examples: - description: | - List of parameter names. Remove the parameter if and only if content-type is one the following [`application/json`, `multipart/form-data`, `application/x-www-form-urlencoded`] and parameter is present. - - name: replace.headers - required: false - default: - value_in_examples: - description: | - List of headername:value pairs. If and only if the header is already set, replace its old value with the new one. Ignored if the header is not already set. - - name: replace.querystring - required: false - default: - value_in_examples: - description: | - List of queryname:value pairs. If and only if the querystring name is already set, replace its old value with the new one. Ignored if the header is not already set. - - name: replace.uri - required: false - default: - value_in_examples: - description: | - Updates the upstream request URI with given value. This value can only be used to update the path part of the URI, not the scheme, nor the hostname. - - name: replace.body - required: false - default: - value_in_examples: - description: | - List of paramname:value pairs. If and only if content-type is one the following [`application/json`, `multipart/form-data`, `application/x-www-form-urlencoded`] and the parameter is already present, replace its old value with the new one. Ignored if the parameter is not already present. - - name: rename.headers - required: false - default: - value_in_examples: - description: | - List of headername:value pairs. If and only if the header is already set, rename the header. The value is unchanged. Ignored if the header is not already set. - - name: rename.querystring - required: false - default: - value_in_examples: - description: | - List of queryname:value pairs. If and only if the field name is already set, rename the field name. The value is unchanged. Ignored if the field name is not already set. - - name: rename.body - required: false - default: - value_in_examples: - description: | - List of parameter name:value pairs. Rename the parameter name if and only if content-type is one the following [`application/json`, `multipart/form-data`, `application/x-www-form-urlencoded`] and parameter is present. - - name: add.headers - required: false - default: - value_in_examples: - description: | - List of headername:value pairs. If and only if the header is not already set, set a new header with the given value. Ignored if the header is already set. - - name: add.querystring - required: false - default: - value_in_examples: - description: | - List of queryname:value pairs. If and only if the querystring name is not already set, set a new querystring with the given value. Ignored if the querystring name is already set. - - name: add.body - required: false - default: - value_in_examples: - description: | - List of paramname:value pairs. If and only if content-type is one the following [`application/json, multipart/form-data`, `application/x-www-form-urlencoded`] and the parameter is not present, add a new parameter with the given value to form-encoded body. Ignored if the parameter is already present. - - name: append.headers - required: false - default: - value_in_examples: - description: | - List of headername:value pairs. If the header is not set, set it with the given value. If it is already set, a new header with the same name and the new value will be set. - - name: append.querystring - required: false - default: - value_in_examples: - description: | - List of queryname:value pairs. If the querystring is not set, set it with the given value. If it is already set, a new querystring with the same name and the new value will be set. - - name: append.body - required: false - default: - value_in_examples: - description: | - List of paramname:value pairs. If the content-type is one the following [`application/json`, `application/x-www-form-urlencoded`], add a new parameter with the given value if the parameter is not present, otherwise if it is already present, the two values (old and new) will be aggregated in an array. - extra: | - Note: if the value contains a `,` then the comma separated format cannot be used. The array notation must be used instead. - ---- - -### Template as Value - -User can use any of the the current request headers, query params, and captured URI named groups as template to populate above supported config fields. - -| Request Param | Template -| --------- | ----------- -| header | $(headers. or $(headers['']) or 'optional_default') -| querystring | $(query_params. or $(query_params['query-param-name']) or 'optional_default') -| captured URIs | $(uri_captures. or $(uri_captures['group-name']) or 'optional_default') - -To escape a template, wrap it inside quotes and pass inside another template.
-Ex. $('$(some_needs_to_escaped)') - -Note: Plugin creates a non mutable table of request headers, querystrings, and captured URIs before transformation. So any update or removal of params used in template does not affect the rendered value of template. - -#### Examples Using Template as Value - -Add an API `test` with `uris` configured with a named capture group `user_id` - -```bash -$ curl -X POST http://localhost:8001/apis \ - --data 'name=test' \ - --data 'upstream_url=http://mockbin.com' \ - --data-urlencode 'uris=/requests/user/(?\w+)' \ - --data "strip_uri=false" -``` - -Enable the ‘request-transformer-advanced’ plugin to add a new header `x-consumer-id` -and its value is being set with the value sent with header `x-user-id` or -with the default value alice is `header` is missing. - -```bash -$ curl -X POST http://localhost:8001/apis/test/plugins \ - --data "name=request-transformer-advanced" \ - --data-urlencode "config.add.headers=x-consumer-id:\$(headers['x-user-id'] or 'alice')" \ - --data "config.remove.headers=x-user-id" -``` - -Now send a request without setting header `x-user-id` - -```bash -$ curl -i -X GET localhost:8000/requests/user/foo -``` - -Plugin will add a new header `x-consumer-id` with value alice before proxying -request upstream. Now try sending request with header `x-user-id` set - -```bash -$ curl -i -X GET localhost:8000/requests/user/foo \ - -H "X-User-Id:bob" -``` - -This time plugin will add a new header `x-consumer-id` with value sent along -with header `x-user-id`, i.e.`bob` - -### Order of Execution - -Plugin performs the response transformation in following order - -remove –> replace –> add –> append - -### Configuration Examples - -Add multiple headers by passing each header:value pair separately: - -```bash -$ curl -X POST http://localhost:8001/apis/mockbin/plugins \ - --data "name=request-transformer-advanced" \ - --data "config.add.headers[1]=h1:v1" \ - --data "config.add.headers[2]=h2:v1" -``` - -| Incoming Request Headers | Upstream Proxied Headers -| --------- | ----------- -| h1: v1 | h1: v1, h2: v1 - -Add multiple headers by passing comma separated header:value pair: - -```bash -$ curl -X POST http://localhost:8001/apis/mockbin/plugins \ - --data "name=request-transformer-advanced" \ - --data "config.add.headers=h1:v1,h2:v2" -``` - -| Incoming Request Headers | Upstream Proxied Headers -| --------- | ----------- -| h1: v1 | h1: v1, h2: v1 - -Add multiple headers passing config as JSON body: - -```bash -$ curl -X POST http://localhost:8001/apis/mockbin/plugins \ - --header 'content-type: application/json' \ - --data '{"name": "request-transformer-advanced", "config": {"add": {"headers": ["h1:v2", "h2:v1"]}}}' -``` - -| Incoming Request Headers | Upstream Proxied Headers -| --------- | ----------- -| h1: v1 | h1: v1, h2: v1 - -Add a querystring and a header: - -```bash -$ curl -X POST http://localhost:8001/apis/mockbin/plugins \ - --data "name=request-transformer-advanced" \ - --data "config.add.querystring=q1:v2,q2=v1" \ - --data "config.add.headers=h1:v1" - -``` - -| Incoming Request Headers | Upstream Proxied Headers -| --------- | ----------- -| h1: v1 | h1: v1, h2: v1 -| h3: v1 | h1: v1, h2: v1, h3: v1 - -| Incoming Request Querystring | Upstream Proxied Querystring -| --------- | ----------- -| ?q1=v1 | ?q1=v1&q2=v1 -| | ?q1=v2&q2=v1 - -Append multiple headers and remove a body parameter: - -```bash -$ curl -X POST http://localhost:8001/apis/mockbin/plugins \ - --data "name=request-transformer-advanced" \ - --data "config.add.headers=h1:v2,h2:v1" \ - --data "config.remove.body=p1" \ - -``` - -| Incoming Request Headers | Upstream Proxied Headers -| --------- | ----------- -| h1: v1 | h1: v1, h1: v2, h2: v1 - -| Incoming URL Encoded Body | Upstream Proxied URL Encoded Body -| --------- | ----------- -| p1=v1&p2=v1 | p2=v1 -| p2=v1 | p2=v1 - -Add multiple headers and querystring parameters if not already set: - -```bash -$ curl -X POST http://localhost:8001/apis/mockbin/plugins \ - --data "name=request-transformer-advanced" \ - --data "config.add.headers=h1:v1,h2:v1" \ - --data "config.add.querystring=q1:v2,q2:v1" \ - -``` - -| Incoming Request Headers | Upstream Proxied Headers -| --------- | ----------- -| h1: v1 | h1: v1, h2: v1 -| h3: v1 | h1: v1, h2: v1, h3: v1 - -| Incoming Request Querystring | Upstream Proxied Querystring -| --------- | ----------- -| ?q1=v1 | ?q1=v1&q2=v1 -| | ?q1=v2&q2=v1 diff --git a/app/_hub/kong-inc/request-transformer-advanced/0.36-x.md b/app/_hub/kong-inc/request-transformer-advanced/0.36-x.md deleted file mode 100644 index c7185dc4fb66..000000000000 --- a/app/_hub/kong-inc/request-transformer-advanced/0.36-x.md +++ /dev/null @@ -1,294 +0,0 @@ ---- - -name: Request Transformer Advanced -publisher: Kong Inc. -version: 0.36-x - -desc: Use powerful regular expressions, variables and templates to transform API requests -description: | - The Request Transformer plugin for Kong Gateway builds on the Kong version of this plugin with enhanced capabilities to match portions of incoming requests using regular expressions, save those matched strings into variables, and substitute those strings into transformed requests via flexible templates. - -enterprise: true -type: plugin -categories: - - transformations - -kong_version_compatibility: - community_edition: - compatible: - enterprise_edition: - compatible: - - 0.36-x - -params: - name: request-transformer-advanced - service_id: true - route_id: true - consumer_id: true - konnect_examples: false - config: - - name: http_method - required: false - default: - value_in_examples: - description: | - Changes the HTTP method for the upstream request - - name: remove.headers - required: false - default: - value_in_examples: - description: | - List of header names. Unset the headers with the given name. - - name: remove.querystring - required: false - default: - value_in_examples: - description: | - List of querystring names. Remove the querystring if it is present. - - name: remove.body - required: false - default: - value_in_examples: - description: | - List of parameter names. Remove the parameter if and only if content-type is one the following [`application/json`, `multipart/form-data`, `application/x-www-form-urlencoded`] and parameter is present. - - name: replace.headers - required: false - default: - value_in_examples: - description: | - List of headername:value pairs. If and only if the header is already set, replace its old value with the new one. Ignored if the header is not already set. - - name: replace.querystring - required: false - default: - value_in_examples: - description: | - List of queryname:value pairs. If and only if the querystring name is already set, replace its old value with the new one. Ignored if the header is not already set. - - name: replace.uri - required: false - default: - value_in_examples: - description: | - Updates the upstream request URI with given value. This value can only be used to update the path part of the URI, not the scheme, nor the hostname. - - name: replace.body - required: false - default: - value_in_examples: - description: | - List of paramname:value pairs. If and only if content-type is one the following [`application/json`, `multipart/form-data`, `application/x-www-form-urlencoded`] and the parameter is already present, replace its old value with the new one. Ignored if the parameter is not already present. - - name: rename.headers - required: false - default: - value_in_examples: - description: | - List of headername:value pairs. If and only if the header is already set, rename the header. The value is unchanged. Ignored if the header is not already set. - - name: rename.querystring - required: false - default: - value_in_examples: - description: | - List of queryname:value pairs. If and only if the field name is already set, rename the field name. The value is unchanged. Ignored if the field name is not already set. - - name: rename.body - required: false - default: - value_in_examples: - description: | - List of parameter name:value pairs. Rename the parameter name if and only if content-type is one the following [`application/json`, `multipart/form-data`, `application/x-www-form-urlencoded`] and parameter is present. - - name: add.headers - required: false - default: - value_in_examples: - description: | - List of headername:value pairs. If and only if the header is not already set, set a new header with the given value. Ignored if the header is already set. - - name: add.querystring - required: false - default: - value_in_examples: - description: | - List of queryname:value pairs. If and only if the querystring name is not already set, set a new querystring with the given value. Ignored if the querystring name is already set. - - name: add.body - required: false - default: - value_in_examples: - description: | - List of paramname:value pairs. If and only if content-type is one the following [`application/json, multipart/form-data`, `application/x-www-form-urlencoded`] and the parameter is not present, add a new parameter with the given value to form-encoded body. Ignored if the parameter is already present. - - name: append.headers - required: false - default: - value_in_examples: - description: | - List of headername:value pairs. If the header is not set, set it with the given value. If it is already set, a new header with the same name and the new value will be set. - - name: append.querystring - required: false - default: - value_in_examples: - description: | - List of queryname:value pairs. If the querystring is not set, set it with the given value. If it is already set, a new querystring with the same name and the new value will be set. - - name: append.body - required: false - default: - value_in_examples: - description: | - List of paramname:value pairs. If the content-type is one the following [`application/json`, `application/x-www-form-urlencoded`], add a new parameter with the given value if the parameter is not present, otherwise if it is already present, the two values (old and new) will be aggregated in an array. - extra: | - Note: if the value contains a `,` then the comma separated format cannot be used. The array notation must be used instead. - ---- - -### Template as Value - -User can use any of the the current request headers, query params, and captured URI named groups as template to populate above supported config fields. - -| Request Param | Template -| --------- | ----------- -| header | $(headers. or $(headers['']) or 'optional_default') -| querystring | $(query_params. or $(query_params['query-param-name']) or 'optional_default') -| captured URIs | $(uri_captures. or $(uri_captures['group-name']) or 'optional_default') - -To escape a template, wrap it inside quotes and pass inside another template.
-Ex. $('$(some_needs_to_escaped)') - -Note: Plugin creates a non mutable table of request headers, querystrings, and captured URIs before transformation. So any update or removal of params used in template does not affect the rendered value of template. - -#### Examples Using Template as Value - -Add a Service named `test` with `uris` configured with a named capture group `user_id`: - -```bash -$ curl -X POST http://localhost:8001/services \ - --data 'name=test' \ - --data 'upstream_url=http://mockbin.com' \ - --data-urlencode 'uris=/requests/user/(?\w+)' \ - --data "strip_uri=false" -``` - -Enable the ‘request-transformer-advanced’ plugin to add a new header `x-consumer-id` -and its value is being set with the value sent with header `x-user-id` or -with the default value alice is `header` is missing. - -```bash -$ curl -X POST http://localhost:8001/services/test/plugins \ - --data "name=request-transformer-advanced" \ - --data-urlencode "config.add.headers=x-consumer-id:\$(headers['x-user-id'] or 'alice')" \ - --data "config.remove.headers=x-user-id" -``` - -Now send a request without setting header `x-user-id` - -```bash -$ curl -i -X GET localhost:8000/requests/user/foo -``` - -Plugin will add a new header `x-consumer-id` with value alice before proxying -request upstream. Now try sending request with header `x-user-id` set - -```bash -$ curl -i -X GET localhost:8000/requests/user/foo \ - -H "X-User-Id:bob" -``` - -This time plugin will add a new header `x-consumer-id` with value sent along -with header `x-user-id`, i.e.`bob` - -### Order of Execution - -Plugin performs the response transformation in following order - -remove –> replace –> add –> append - -### Configuration Examples - -Add multiple headers by passing each header:value pair separately: - -```bash -$ curl -X POST http://localhost:8001/services/mockbin/plugins \ - --data "name=request-transformer-advanced" \ - --data "config.add.headers[1]=h1:v1" \ - --data "config.add.headers[2]=h2:v1" -``` - -| Incoming Request Headers | Upstream Proxied Headers -| --------- | ----------- -| h1: v1 | h1: v1, h2: v1 - -Add multiple headers by passing comma separated header:value pair: - -```bash -$ curl -X POST http://localhost:8001/services/mockbin/plugins \ - --data "name=request-transformer-advanced" \ - --data "config.add.headers=h1:v1,h2:v2" -``` - -| Incoming Request Headers | Upstream Proxied Headers -| --------- | ----------- -| h1: v1 | h1: v1, h2: v1 - -Add multiple headers passing config as JSON body: - -```bash -$ curl -X POST http://localhost:8001/services/mockbin/plugins \ - --header 'content-type: application/json' \ - --data '{"name": "request-transformer-advanced", "config": {"add": {"headers": ["h1:v2", "h2:v1"]}}}' -``` - -| Incoming Request Headers | Upstream Proxied Headers -| --------- | ----------- -| h1: v1 | h1: v1, h2: v1 - -Add a querystring and a header: - -```bash -$ curl -X POST http://localhost:8001/services/mockbin/plugins \ - --data "name=request-transformer-advanced" \ - --data "config.add.querystring=q1:v2,q2=v1" \ - --data "config.add.headers=h1:v1" - -``` - -| Incoming Request Headers | Upstream Proxied Headers -| --------- | ----------- -| h1: v1 | h1: v1, h2: v1 -| h3: v1 | h1: v1, h2: v1, h3: v1 - -| Incoming Request Querystring | Upstream Proxied Querystring -| --------- | ----------- -| ?q1=v1 | ?q1=v1&q2=v1 -| | ?q1=v2&q2=v1 - -Append multiple headers and remove a body parameter: - -```bash -$ curl -X POST http://localhost:8001/services/mockbin/plugins \ - --data "name=request-transformer-advanced" \ - --data "config.add.headers=h1:v2,h2:v1" \ - --data "config.remove.body=p1" \ - -``` - -| Incoming Request Headers | Upstream Proxied Headers -| --------- | ----------- -| h1: v1 | h1: v1, h1: v2, h2: v1 - -| Incoming URL Encoded Body | Upstream Proxied URL Encoded Body -| --------- | ----------- -| p1=v1&p2=v1 | p2=v1 -| p2=v1 | p2=v1 - -Add multiple headers and querystring parameters if not already set: - -```bash -$ curl -X POST http://localhost:8001/services/mockbin/plugins \ - --data "name=request-transformer-advanced" \ - --data "config.add.headers=h1:v1,h2:v1" \ - --data "config.add.querystring=q1:v2,q2:v1" \ - -``` - -| Incoming Request Headers | Upstream Proxied Headers -| --------- | ----------- -| h1: v1 | h1: v1, h2: v1 -| h3: v1 | h1: v1, h2: v1, h3: v1 - -| Incoming Request Querystring | Upstream Proxied Querystring -| --------- | ----------- -| ?q1=v1 | ?q1=v1&q2=v1 -| | ?q1=v2&q2=v1 diff --git a/app/_hub/kong-inc/request-transformer-advanced/1.3-x.md b/app/_hub/kong-inc/request-transformer-advanced/1.3-x.md deleted file mode 100644 index 229b1409b995..000000000000 --- a/app/_hub/kong-inc/request-transformer-advanced/1.3-x.md +++ /dev/null @@ -1,355 +0,0 @@ ---- - -name: Request Transformer Advanced -publisher: Kong Inc. -version: 1.3-x - -desc: Use powerful regular expressions, variables and templates to transform API requests -description: | - The Request Transformer plugin for Kong Gateway builds on the Kong version of this plugin with enhanced capabilities to match portions of incoming requests using regular expressions, save those matched strings into variables, and substitute those strings into transformed requests via flexible templates. - -enterprise: true -type: plugin -categories: - - transformations - -kong_version_compatibility: - community_edition: - compatible: - enterprise_edition: - compatible: - - 1.3-x - -params: - name: request-transformer-advanced - service_id: true - route_id: true - consumer_id: true - konnect_examples: false - config: - - name: http_method - required: false - default: - value_in_examples: - description: | - Changes the HTTP method for the upstream request - - name: remove.headers - required: false - default: - value_in_examples: - description: | - List of header names. Unset the headers with the given name. - - name: remove.querystring - required: false - default: - value_in_examples: - description: | - List of querystring names. Remove the querystring if it is present. - - name: remove.body - required: false - default: - value_in_examples: - description: | - List of parameter names. Remove the parameter if and only if content-type is one the following [`application/json`, `multipart/form-data`, `application/x-www-form-urlencoded`] and parameter is present. - - name: replace.headers - required: false - default: - value_in_examples: - description: | - List of headername:value pairs. If and only if the header is already set, replace its old value with the new one. Ignored if the header is not already set. - - name: replace.querystring - required: false - default: - value_in_examples: - description: | - List of queryname:value pairs. If and only if the querystring name is already set, replace its old value with the new one. Ignored if the header is not already set. - - name: replace.uri - required: false - default: - value_in_examples: - description: | - Updates the upstream request URI with given value. This value can only be used to update the path part of the URI, not the scheme, nor the hostname. - - name: replace.body - required: false - default: - value_in_examples: - description: | - List of paramname:value pairs. If and only if content-type is one the following [`application/json`, `multipart/form-data`, `application/x-www-form-urlencoded`] and the parameter is already present, replace its old value with the new one. Ignored if the parameter is not already present. - - name: rename.headers - required: false - default: - value_in_examples: - description: | - List of headername:value pairs. If and only if the header is already set, rename the header. The value is unchanged. Ignored if the header is not already set. - - name: rename.querystring - required: false - default: - value_in_examples: - description: | - List of queryname:value pairs. If and only if the field name is already set, rename the field name. The value is unchanged. Ignored if the field name is not already set. - - name: rename.body - required: false - default: - value_in_examples: - description: | - List of parameter name:value pairs. Rename the parameter name if and only if content-type is one the following [`application/json`, `multipart/form-data`, `application/x-www-form-urlencoded`] and parameter is present. - - name: add.headers - required: false - default: - value_in_examples: - description: | - List of headername:value pairs. If and only if the header is not already set, set a new header with the given value. Ignored if the header is already set. - - name: add.querystring - required: false - default: - value_in_examples: - description: | - List of queryname:value pairs. If and only if the querystring name is not already set, set a new querystring with the given value. Ignored if the querystring name is already set. - - name: add.body - required: false - default: - value_in_examples: - description: | - List of paramname:value pairs. If and only if content-type is one the following [`application/json, multipart/form-data`, `application/x-www-form-urlencoded`] and the parameter is not present, add a new parameter with the given value to form-encoded body. Ignored if the parameter is already present. - - name: append.headers - required: false - default: - value_in_examples: - description: | - List of headername:value pairs. If the header is not set, set it with the given value. If it is already set, a new header with the same name and the new value will be set. - - name: append.querystring - required: false - default: - value_in_examples: - description: | - List of queryname:value pairs. If the querystring is not set, set it with the given value. If it is already set, a new querystring with the same name and the new value will be set. - - name: append.body - required: false - default: - value_in_examples: - description: | - List of paramname:value pairs. If the content-type is one the following [`application/json`, `application/x-www-form-urlencoded`], add a new parameter with the given value if the parameter is not present, otherwise if it is already present, the two values (old and new) will be aggregated in an array. - - name: whitelist.body - required: false - default: - value_in_examples: - description: | - Set of parameter name. If and only if content-type is one the following [`application/json`, `multipart/form-data`, `application/x-www-form-urlencoded`], allow only allowed parameters in the body. - extra: | - **Notes:** - * If the value contains a `,` then the comma separated format cannot be used. The array notation must be used instead. - * The `X-Forwarded-*` fields are non-standard header fields written by Nginx to inform the upstream about client details and can't be overwritten by this plugin. If you need to overwrite these header fields, see the [post-function plugin in Serverless Functions](https://docs.konghq.com/hub/kong-inc/serverless-functions/). - ---- - -## Template as Value - -User can use any of the the current request headers, query params, and captured URI groups as template to populate above supported config fields. - -| Request Param | Template -| ------------- | ----------- -| header | `$(headers.)` or `$(headers[""])`) -| querystring | `$(query_params.)` or `$(query_params[""])`) -| captured URIs | `$(uri_captures.)` or `$(uri_captures[""])`) - -To escape a template, wrap it inside quotes and pass inside another template.
-Ex. $('$(some_needs_to_escaped)') - -Note: The plugin creates a non-mutable table of request headers, querystrings, and captured URIs before transformation. So any update or removal of params used in template does not affect the rendered value of template. - -### Advanced templates - -The content of the placeholder `$(...)` is evaluated as a Lua expression, so -logical operators may be used. For example: - - Header-Name:$(uri_captures["user-id"] or query_params["user"] or "unknown") - -This will first look for the path parameter (`uri_captures`); if not found, it will -return the query parameter; or if that also doesn't exist, it returns the default -value '"unknown"'. - -Constant parts can be specified as part of the template outside the dynamic -placeholders. For example, creating a basic-auth header from a query parameter -called `auth` that only contains the base64-encoded part: - - Authorization:Basic $(query_params["auth"]) - -Lambdas are also supported if wrapped as an expression like this: - - $((function() ... implementation here ... end)()) - -A complete lambda example for pefixing a header value with "Basic " if not -already there: - - Authorization:$((function() - local value = headers.Authorization - if not value then - return - end - if value:sub(1, 6) == "Basic " then - return value -- was already properly formed - end - return "Basic " .. value -- added proper prefix - end)()) - -*NOTE:* Especially in multi-line templates like the example above, make sure not -to add any trailing white-space or new-lines. Since these would be outside the -placeholders, they would be considered part of the template, and hence would be -appended to the generated value. - -The environment is sandboxed, meaning that Lambda's will not have access to any -library functions, except for the string methods (like `sub()` in the example -above). - -### Examples Using Template as Value - -Add a Service named `test` with `uris` configured with a named capture group `user_id`: - -```bash -$ curl -X POST http://localhost:8001/services \ - --data 'name=test' \ - --data 'upstream_url=http://mockbin.com' \ - --data-urlencode 'uris=/requests/user/(?\w+)' \ - --data "strip_uri=false" -``` - - - -Enable the ‘request-transformer-advanced’ plugin to add a new header `x-consumer-id` -and its value is being set with the value sent with header `x-user-id` or -with the default value alice is `header` is missing. - -```bash -$ curl -X POST http://localhost:8001/services/test/plugins \ - --data "name=request-transformer-advanced" \ - --data-urlencode "config.add.headers=x-consumer-id:\$(headers['x-user-id'] or 'alice')" \ - --data "config.remove.headers=x-user-id" -``` - -Now send a request without setting header `x-user-id` - -```bash -$ curl -i -X GET localhost:8000/requests/user/foo -``` - -Plugin will add a new header `x-consumer-id` with value alice before proxying -request upstream. Now try sending request with header `x-user-id` set - -```bash -$ curl -i -X GET localhost:8000/requests/user/foo \ - -H "X-User-Id:bob" -``` - -This time plugin will add a new header `x-consumer-id` with value sent along -with header `x-user-id`, i.e.`bob` - -## Order of Execution - -This plugin performs the response transformation in the following order: - -remove –> replace –> add –> append - -## Configuration Examples - -Add multiple headers by passing each header:value pair separately: - -```bash -$ curl -X POST http://localhost:8001/services/mockbin/plugins \ - --data "name=request-transformer-advanced" \ - --data "config.add.headers[1]=h1:v1" \ - --data "config.add.headers[2]=h2:v1" -``` - -| Incoming Request Headers | Upstream Proxied Headers -| --------- | ----------- -| h1: v1 | h1: v1, h2: v1 - -Add multiple headers by passing comma separated header:value pair: - -```bash -$ curl -X POST http://localhost:8001/services/mockbin/plugins \ - --data "name=request-transformer-advanced" \ - --data "config.add.headers=h1:v1,h2:v2" -``` - -| Incoming Request Headers | Upstream Proxied Headers -| --------- | ----------- -| h1: v1 | h1: v1, h2: v1 - -Add multiple headers passing config as JSON body: - -```bash -$ curl -X POST http://localhost:8001/services/mockbin/plugins \ - --header 'content-type: application/json' \ - --data '{"name": "request-transformer-advanced", "config": {"add": {"headers": ["h1:v2", "h2:v1"]}}}' -``` - -| Incoming Request Headers | Upstream Proxied Headers -| --------- | ----------- -| h1: v1 | h1: v1, h2: v1 - -Add a querystring and a header: - -```bash -$ curl -X POST http://localhost:8001/services/mockbin/plugins \ - --data "name=request-transformer-advanced" \ - --data "config.add.querystring=q1:v2,q2=v1" \ - --data "config.add.headers=h1:v1" - -``` - -| Incoming Request Headers | Upstream Proxied Headers -| --------- | ----------- -| h1: v1 | h1: v1, h2: v1 -| h3: v1 | h1: v1, h2: v1, h3: v1 - -| Incoming Request Querystring | Upstream Proxied Querystring -| --------- | ----------- -| ?q1=v1 | ?q1=v1&q2=v1 -| | ?q1=v2&q2=v1 - -Append multiple headers and remove a body parameter: - -```bash -$ curl -X POST http://localhost:8001/services/mockbin/plugins \ - --data "name=request-transformer-advanced" \ - --data "config.add.headers=h1:v2,h2:v1" \ - --data "config.remove.body=p1" \ - -``` - -| Incoming Request Headers | Upstream Proxied Headers -| --------- | ----------- -| h1: v1 | h1: v1, h1: v2, h2: v1 - -| Incoming URL Encoded Body | Upstream Proxied URL Encoded Body -| --------- | ----------- -| p1=v1&p2=v1 | p2=v1 -| p2=v1 | p2=v1 - -Add multiple headers and querystring parameters if not already set: - -```bash -$ curl -X POST http://localhost:8001/services/mockbin/plugins \ - --data "name=request-transformer-advanced" \ - --data "config.add.headers=h1:v1,h2:v1" \ - --data "config.add.querystring=q1:v2,q2:v1" \ - -``` - -| Incoming Request Headers | Upstream Proxied Headers -| --------- | ----------- -| h1: v1 | h1: v1, h2: v1 -| h3: v1 | h1: v1, h2: v1, h3: v1 - -| Incoming Request Querystring | Upstream Proxied Querystring -| --------- | ----------- -| ?q1=v1 | ?q1=v1&q2=v1 -| | ?q1=v2&q2=v1 diff --git a/app/_hub/kong-inc/request-transformer-advanced/1.5.x.md b/app/_hub/kong-inc/request-transformer-advanced/1.5.x.md deleted file mode 100644 index adf0c53dc556..000000000000 --- a/app/_hub/kong-inc/request-transformer-advanced/1.5.x.md +++ /dev/null @@ -1,355 +0,0 @@ ---- - -name: Request Transformer Advanced -publisher: Kong Inc. -version: 1.5.x - -desc: Use powerful regular expressions, variables and templates to transform API requests -description: | - The Request Transformer plugin for Kong Gateway builds on the Kong version of this plugin with enhanced capabilities to match portions of incoming requests using regular expressions, save those matched strings into variables, and substitute those strings into transformed requests via flexible templates. - -enterprise: true -type: plugin -categories: - - transformations - -kong_version_compatibility: - community_edition: - compatible: - enterprise_edition: - compatible: - - 1.5.x - -params: - name: request-transformer-advanced - service_id: true - route_id: true - consumer_id: true - konnect_examples: false - config: - - name: http_method - required: false - default: - value_in_examples: - description: | - Changes the HTTP method for the upstream request - - name: remove.headers - required: false - default: - value_in_examples: - description: | - List of header names. Unset the headers with the given name. - - name: remove.querystring - required: false - default: - value_in_examples: - description: | - List of querystring names. Remove the querystring if it is present. - - name: remove.body - required: false - default: - value_in_examples: - description: | - List of parameter names. Remove the parameter if and only if content-type is one the following [`application/json`, `multipart/form-data`, `application/x-www-form-urlencoded`] and parameter is present. - - name: replace.headers - required: false - default: - value_in_examples: - description: | - List of headername:value pairs. If and only if the header is already set, replace its old value with the new one. Ignored if the header is not already set. - - name: replace.querystring - required: false - default: - value_in_examples: - description: | - List of queryname:value pairs. If and only if the querystring name is already set, replace its old value with the new one. Ignored if the header is not already set. - - name: replace.uri - required: false - default: - value_in_examples: - description: | - Updates the upstream request URI with given value. This value can only be used to update the path part of the URI, not the scheme, nor the hostname. - - name: replace.body - required: false - default: - value_in_examples: - description: | - List of paramname:value pairs. If and only if content-type is one the following [`application/json`, `multipart/form-data`, `application/x-www-form-urlencoded`] and the parameter is already present, replace its old value with the new one. Ignored if the parameter is not already present. - - name: rename.headers - required: false - default: - value_in_examples: - description: | - List of headername:value pairs. If and only if the header is already set, rename the header. The value is unchanged. Ignored if the header is not already set. - - name: rename.querystring - required: false - default: - value_in_examples: - description: | - List of queryname:value pairs. If and only if the field name is already set, rename the field name. The value is unchanged. Ignored if the field name is not already set. - - name: rename.body - required: false - default: - value_in_examples: - description: | - List of parameter name:value pairs. Rename the parameter name if and only if content-type is one the following [`application/json`, `multipart/form-data`, `application/x-www-form-urlencoded`] and parameter is present. - - name: add.headers - required: false - default: - value_in_examples: - description: | - List of headername:value pairs. If and only if the header is not already set, set a new header with the given value. Ignored if the header is already set. - - name: add.querystring - required: false - default: - value_in_examples: - description: | - List of queryname:value pairs. If and only if the querystring name is not already set, set a new querystring with the given value. Ignored if the querystring name is already set. - - name: add.body - required: false - default: - value_in_examples: - description: | - List of paramname:value pairs. If and only if content-type is one the following [`application/json, multipart/form-data`, `application/x-www-form-urlencoded`] and the parameter is not present, add a new parameter with the given value to form-encoded body. Ignored if the parameter is already present. - - name: append.headers - required: false - default: - value_in_examples: - description: | - List of headername:value pairs. If the header is not set, set it with the given value. If it is already set, a new header with the same name and the new value will be set. - - name: append.querystring - required: false - default: - value_in_examples: - description: | - List of queryname:value pairs. If the querystring is not set, set it with the given value. If it is already set, a new querystring with the same name and the new value will be set. - - name: append.body - required: false - default: - value_in_examples: - description: | - List of paramname:value pairs. If the content-type is one the following [`application/json`, `application/x-www-form-urlencoded`], add a new parameter with the given value if the parameter is not present, otherwise if it is already present, the two values (old and new) will be aggregated in an array. - - name: whitelist.body - required: false - default: - value_in_examples: - description: | - Set of parameter name. If and only if content-type is one the following [`application/json`, `multipart/form-data`, `application/x-www-form-urlencoded`], allow only allowed parameters in the body. - extra: | - **Notes:** - * If the value contains a `,` then the comma separated format cannot be used. The array notation must be used instead. - * The `X-Forwarded-*` fields are non-standard header fields written by Nginx to inform the upstream about client details and can't be overwritten by this plugin. If you need to overwrite these header fields, see the [post-function plugin in Serverless Functions](https://docs.konghq.com/hub/kong-inc/serverless-functions/). - ---- - -## Template as Value - -User can use any of the the current request headers, query params, and captured URI groups as template to populate above supported config fields. - -| Request Param | Template -| ------------- | ----------- -| header | `$(headers.)` or `$(headers[""])`) -| querystring | `$(query_params.)` or `$(query_params[""])`) -| captured URIs | `$(uri_captures.)` or `$(uri_captures[""])`) - -To escape a template, wrap it inside quotes and pass inside another template.
-Ex. $('$(some_needs_to_escaped)') - -Note: The plugin creates a non-mutable table of request headers, querystrings, and captured URIs before transformation. So any update or removal of params used in template does not affect the rendered value of template. - -### Advanced templates - -The content of the placeholder `$(...)` is evaluated as a Lua expression, so -logical operators may be used. For example: - - Header-Name:$(uri_captures["user-id"] or query_params["user"] or "unknown") - -This will first look for the path parameter (`uri_captures`); if not found, it will -return the query parameter; or if that also doesn't exist, it returns the default -value '"unknown"'. - -Constant parts can be specified as part of the template outside the dynamic -placeholders. For example, creating a basic-auth header from a query parameter -called `auth` that only contains the base64-encoded part: - - Authorization:Basic $(query_params["auth"]) - -Lambdas are also supported if wrapped as an expression like this: - - $((function() ... implementation here ... end)()) - -A complete lambda example for pefixing a header value with "Basic " if not -already there: - - Authorization:$((function() - local value = headers.Authorization - if not value then - return - end - if value:sub(1, 6) == "Basic " then - return value -- was already properly formed - end - return "Basic " .. value -- added proper prefix - end)()) - -*NOTE:* Especially in multi-line templates like the example above, make sure not -to add any trailing white-space or new-lines. Since these would be outside the -placeholders, they would be considered part of the template, and hence would be -appended to the generated value. - -The environment is sandboxed, meaning that Lambda's will not have access to any -library functions, except for the string methods (like `sub()` in the example -above). - -### Examples Using Template as Value - -Add a Service named `test` with `uris` configured with a named capture group `user_id`: - -```bash -$ curl -X POST http://localhost:8001/services \ - --data 'name=test' \ - --data 'upstream_url=http://mockbin.com' \ - --data-urlencode 'uris=/requests/user/(?\w+)' \ - --data "strip_uri=false" -``` - - - -Enable the ‘request-transformer-advanced’ plugin to add a new header `x-consumer-id` -and its value is being set with the value sent with header `x-user-id` or -with the default value alice is `header` is missing. - -```bash -$ curl -X POST http://localhost:8001/services/test/plugins \ - --data "name=request-transformer-advanced" \ - --data-urlencode "config.add.headers=x-consumer-id:\$(headers['x-user-id'] or 'alice')" \ - --data "config.remove.headers=x-user-id" -``` - -Now send a request without setting header `x-user-id` - -```bash -$ curl -i -X GET localhost:8000/requests/user/foo -``` - -Plugin will add a new header `x-consumer-id` with value alice before proxying -request upstream. Now try sending request with header `x-user-id` set - -```bash -$ curl -i -X GET localhost:8000/requests/user/foo \ - -H "X-User-Id:bob" -``` - -This time plugin will add a new header `x-consumer-id` with value sent along -with header `x-user-id`, i.e.`bob` - -## Order of Execution - -This plugin performs the response transformation in the following order: - -remove –> replace –> add –> append - -## Configuration Examples - -Add multiple headers by passing each header:value pair separately: - -```bash -$ curl -X POST http://localhost:8001/services/mockbin/plugins \ - --data "name=request-transformer-advanced" \ - --data "config.add.headers[1]=h1:v1" \ - --data "config.add.headers[2]=h2:v1" -``` - -| Incoming Request Headers | Upstream Proxied Headers -| --------- | ----------- -| h1: v1 | h1: v1, h2: v1 - -Add multiple headers by passing comma separated header:value pair: - -```bash -$ curl -X POST http://localhost:8001/services/mockbin/plugins \ - --data "name=request-transformer-advanced" \ - --data "config.add.headers=h1:v1,h2:v2" -``` - -| Incoming Request Headers | Upstream Proxied Headers -| --------- | ----------- -| h1: v1 | h1: v1, h2: v1 - -Add multiple headers passing config as JSON body: - -```bash -$ curl -X POST http://localhost:8001/services/mockbin/plugins \ - --header 'content-type: application/json' \ - --data '{"name": "request-transformer-advanced", "config": {"add": {"headers": ["h1:v2", "h2:v1"]}}}' -``` - -| Incoming Request Headers | Upstream Proxied Headers -| --------- | ----------- -| h1: v1 | h1: v1, h2: v1 - -Add a querystring and a header: - -```bash -$ curl -X POST http://localhost:8001/services/mockbin/plugins \ - --data "name=request-transformer-advanced" \ - --data "config.add.querystring=q1:v2,q2=v1" \ - --data "config.add.headers=h1:v1" - -``` - -| Incoming Request Headers | Upstream Proxied Headers -| --------- | ----------- -| h1: v1 | h1: v1, h2: v1 -| h3: v1 | h1: v1, h2: v1, h3: v1 - -| Incoming Request Querystring | Upstream Proxied Querystring -| --------- | ----------- -| ?q1=v1 | ?q1=v1&q2=v1 -| | ?q1=v2&q2=v1 - -Append multiple headers and remove a body parameter: - -```bash -$ curl -X POST http://localhost:8001/services/mockbin/plugins \ - --data "name=request-transformer-advanced" \ - --data "config.add.headers=h1:v2,h2:v1" \ - --data "config.remove.body=p1" \ - -``` - -| Incoming Request Headers | Upstream Proxied Headers -| --------- | ----------- -| h1: v1 | h1: v1, h1: v2, h2: v1 - -| Incoming URL Encoded Body | Upstream Proxied URL Encoded Body -| --------- | ----------- -| p1=v1&p2=v1 | p2=v1 -| p2=v1 | p2=v1 - -Add multiple headers and querystring parameters if not already set: - -```bash -$ curl -X POST http://localhost:8001/services/mockbin/plugins \ - --data "name=request-transformer-advanced" \ - --data "config.add.headers=h1:v1,h2:v1" \ - --data "config.add.querystring=q1:v2,q2:v1" \ - -``` - -| Incoming Request Headers | Upstream Proxied Headers -| --------- | ----------- -| h1: v1 | h1: v1, h2: v1 -| h3: v1 | h1: v1, h2: v1, h3: v1 - -| Incoming Request Querystring | Upstream Proxied Querystring -| --------- | ----------- -| ?q1=v1 | ?q1=v1&q2=v1 -| | ?q1=v2&q2=v1 diff --git a/app/_hub/kong-inc/request-transformer-advanced/_index.md b/app/_hub/kong-inc/request-transformer-advanced/_index.md index 98fb372e5787..af34da4f3e86 100644 --- a/app/_hub/kong-inc/request-transformer-advanced/_index.md +++ b/app/_hub/kong-inc/request-transformer-advanced/_index.md @@ -1,13 +1,13 @@ --- name: Request Transformer Advanced publisher: Kong Inc. -version: 2.1.x -desc: 'Use powerful regular expressions, variables, and templates to transform API requests' +desc: Use powerful regular expressions, variables, and templates to transform API requests description: | - The Request Transformer plugin for Kong Gateway builds on the Kong version - of this plugin with enhanced capabilities to match portions of incoming requests - using regular expressions, save those matched strings into variables, and - substitute those strings into transformed requests via flexible templates. + Transform client requests before they reach the upstream server. The plugin lets you match portions of incoming requests using regular expressions, save those matched strings into variables, and substitute the strings into transformed requests via flexible templates. + + The Request Transformer Advanced plugin builds on the open-source [Request Transformer plugin](/hub/kong-inc/request-transformer/) with the following enhanced capability: + * Limit the list of allowed parameters in the request body. Set this up with the `allow.body` configuration parameter. + enterprise: true type: plugin categories: @@ -16,15 +16,7 @@ kong_version_compatibility: community_edition: compatible: null enterprise_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x + compatible: true params: name: request-transformer-advanced service_id: true @@ -76,6 +68,10 @@ params: description: | List of headername:value pairs. If and only if the header is already set, replace its old value with the new one. Ignored if the header is not already set. + + This field is _referenceable_, which means it can be securely stored as a + [secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). - name: replace.querystring required: false default: null @@ -84,6 +80,10 @@ params: description: | List of queryname:value pairs. If and only if the querystring name is already set, replace its old value with the new one. Ignored if the header is not already set. + + This field is _referenceable_, which means it can be securely stored as a + [secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). - name: replace.uri required: false default: null @@ -103,6 +103,10 @@ params: List of paramname:value pairs. If and only if content-type is one the following: [`application/json`, `multipart/form-data`, `application/x-www-form-urlencoded`]; and the parameter is already present, replace its old value with the new one. Ignored if the parameter is not already present. + + This field is _referenceable_, which means it can be securely stored as a + [secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). - name: rename.headers required: false default: null @@ -113,6 +117,10 @@ params: description: | List of `headername:value` pairs. If and only if the header is already set, rename the header. The value is unchanged. Ignored if the header is not already set. + + This field is _referenceable_, which means it can be securely stored as a + [secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). - name: rename.querystring required: false default: null @@ -123,6 +131,10 @@ params: description: | List of `queryname:value` pairs. If and only if the field name is already set, rename the field name. The value is unchanged. Ignored if the field name is not already set. + + This field is _referenceable_, which means it can be securely stored as a + [secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). - name: rename.body required: false default: null @@ -133,6 +145,10 @@ params: description: | List of parameter `name:value` pairs. Rename the parameter name if and only if content-type is one of the following: [`application/json`, `multipart/form-data`, `application/x-www-form-urlencoded`]; and parameter is present. + + This field is _referenceable_, which means it can be securely stored as a + [secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). - name: add.headers required: false default: null @@ -143,6 +159,10 @@ params: description: | List of `headername:value` pairs. If and only if the header is not already set, set a new header with the given value. Ignored if the header is already set. + + This field is _referenceable_, which means it can be securely stored as a + [secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). - name: add.querystring required: false default: null @@ -153,6 +173,10 @@ params: description: | List of `queryname:value` pairs. If and only if the querystring name is not already set, set a new querystring with the given value. Ignored if the querystring name is already set. + + This field is _referenceable_, which means it can be securely stored as a + [secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). - name: add.body required: false default: null @@ -161,6 +185,10 @@ params: description: | List of `paramname:value` pairs. If and only if content-type is one the following: [`application/json, multipart/form-data`, `application/x-www-form-urlencoded`]; and the parameter is not present, add a new parameter with the given value to form-encoded body. Ignored if the parameter is already present. + + This field is _referenceable_, which means it can be securely stored as a + [secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). - name: append.headers required: false default: null @@ -169,6 +197,10 @@ params: description: | List of `headername:value` pairs. If the header is not set, set it with the given value. If it is already set, a new header with the same name and the new value will be set. + + This field is _referenceable_, which means it can be securely stored as a + [secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). - name: append.querystring required: false default: null @@ -177,6 +209,10 @@ params: description: | List of `queryname:value` pairs. If the querystring is not set, set it with the given value. If it is already set, a new querystring with the same name and the new value will be set. + + This field is _referenceable_, which means it can be securely stored as a + [secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). - name: append.body required: false default: null @@ -185,6 +221,10 @@ params: description: | List of `paramname:value` pairs. If the content-type is one the following: [`application/json`, `application/x-www-form-urlencoded`]; add a new parameter with the given value if the parameter is not present. Otherwise, if it is already present, the two values (old and new) will be aggregated in an array. + + This field is _referenceable_, which means it can be securely stored as a + [secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). - name: allow.body required: false default: null @@ -202,7 +242,7 @@ params: ## Template as Value -You can use any of the the current request headers, query parameters, and captured +You can use any of the current request headers, query parameters, and captured URI groups as templates to populate supported config fields. | Request Parameter | Template @@ -290,7 +330,7 @@ Create a route for the `test` service, capturing a `user_id` field from the thir ```bash curl -X POST http://localhost:8001/services/test/routes --data "name=test_user" \ - --data-urlencode 'paths=/requests/user/(?\w+)' + --data-urlencode 'paths=~/requests/user/(?\w+)' ``` Enable the `request-transformer-advanced` plugin to add a new header, `x-user-id`, @@ -300,7 +340,7 @@ whose value is being set from the captured group in the route path specified abo curl -XPOST http://localhost:8001/routes/test_user/plugins --data "name=request-transformer-advanced" --data "config.add.headers=x-user-id:\$(uri_captures['user_id'])" ``` -Now send a request with a user id in the route path: +Now send a request with a user id in the route path: ```bash curl -i -X GET localhost:8000/requests/user/foo @@ -409,3 +449,16 @@ curl -X POST http://localhost:8001/services/mockbin/plugins \ | --------- | ----------- | ?q1=v1 | ?q1=v1&q2=v1 | | ?q1=v2&q2=v1 + + +--- + +## Changelog + +**{{site.base_gateway}} 3.0.x** +- Removed the deprecated `whitelist` parameter. +It is no longer supported. + +**{{site.base_gateway}} 2.1.x** + +- Use `allow` instead of `whitelist`. diff --git a/app/_hub/kong-inc/request-transformer-advanced/versions.yml b/app/_hub/kong-inc/request-transformer-advanced/versions.yml index 358ca7ded9a5..1dc829aa71d6 100644 --- a/app/_hub/kong-inc/request-transformer-advanced/versions.yml +++ b/app/_hub/kong-inc/request-transformer-advanced/versions.yml @@ -1,9 +1,12 @@ -- release: 2.1.x -- release: 1.5.x -- release: 1.3-x -- release: 0.36-x -- release: 0.35-x -- release: 0.34-x -- release: 0.33-x -- release: 0.32-x -- release: 0.31-x +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 0.38.1 + 2.7.x: 0.38.1 + 2.6.x: 0.38.1 + 2.5.x: 0.38.0 + 2.4.x: 0.38.0 + 2.3.x: 0.38.0 + 2.2.x: 0.37.4 + 2.1.x: 0.37.3 diff --git a/app/_hub/kong-inc/request-transformer/0.1-x.md b/app/_hub/kong-inc/request-transformer/0.1-x.md deleted file mode 100644 index a59699b3e0ef..000000000000 --- a/app/_hub/kong-inc/request-transformer/0.1-x.md +++ /dev/null @@ -1,276 +0,0 @@ ---- -name: Request Transformer -publisher: Kong Inc. -version: 0.1-x - -desc: Modify the request before hitting the upstream server -description: | - Transform the request sent by a client on the fly on Kong, before hitting the upstream server. - -
- Note: The functionality of this plugin as bundled - with versions of Kong prior to 0.10.0 - differs from what is documented herein. Refer to the - CHANGELOG - for details. -
- -type: plugin -categories: - - transformations - -kong_version_compatibility: - community_edition: - compatible: - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x - - 0.4.x - - 0.3.x - enterprise_edition: - compatible: - - 0.34-x - - 0.33-x - - 0.32-x - -params: - name: request-transformer - api_id: true - service_id: true - route_id: true - consumer_id: true - konnect_examples: false - config: - - name: http_method - required: false - description: Changes the HTTP method for the upstream request. - - name: remove.headers - required: false - value_in_examples: "x-toremove, x-another-one" - description: List of header names. Unset the header(s) with the given name. - - name: remove.querystring - required: false - value_in_examples: "qs-old-name:qs-new-name, qs2-old-name:qs2-new-name" - description: List of querystring names. Remove the querystring if it is present. - - name: remove.body - required: false - value_in_examples: "formparam-toremove, formparam-another-one" - description: List of parameter names. Remove the parameter if and only if content-type is one the following [`application/json`, `multipart/form-data`, `application/x-www-form-urlencoded`] and parameter is present. - - name: replace.headers - required: false - description: List of headername:value pairs. If and only if the header is already set, replace its old value with the new one. Ignored if the header is not already set. - - name: replace.querystring - required: false - description: List of queryname:value pairs. If and only if the field name is already set, replace its old value with the new one. Ignored if the field name is not already set. - - name: rename.headers - required: false - value_in_examples: "header-old-name:header-new-name, another-old-name:another-new-name" - description: List of headername:value pairs. If and only if the header is already set, rename the header. The value is unchanged. Ignored if the header is not already set. - - name: rename.querystring - required: false - value_in_examples: "qs-old-name:qs-new-name, qs2-old-name:qs2-new-name" - description: List of queryname:value pairs. If and only if the field name is already set, rename the field name. The value is unchanged. Ignored if the field name is not already set. - - name: rename.body - required: false - value_in_examples: "param-old:param-new, param2-old:param2-new" - description: List of parameter name:value pairs. Rename the parameter name if and only if content-type is one the following [`application/json`, `multipart/form-data`, `application/x-www-form-urlencoded`] and parameter is present. - - name: append.headers - required: false - value_in_examples: "x-existing-header:some_value, x-another-header:some_value" - description: List of headername:value pairs. If the header is not set, set it with the given value. If it is already set, a new header with the same name and the new value will be set. - - name: replace.body - required: false - description: List of paramname:value pairs. If and only if content-type is one the following [`application/json`, `multipart/form-data`, `application/x-www-form-urlencoded`] and the parameter is already present, replace its old value with the new one. Ignored if the parameter is not already present. - - name: add.headers - required: false - value_in_examples: "x-new-header:value,x-another-header:something" - description: List of headername:value pairs. If and only if the header is not already set, set a new header with the given value. Ignored if the header is already set. - - name: add.querystring - required: false - value_in_examples: "new-param:some_value, another-param:some_value" - description: List of queryname:value pairs. If and only if the querystring is not already set, set a new querystring with the given value. Ignored if the header is already set. - - name: add.body - required: false - value_in_examples: "new-form-param:some_value, another-form-param:some_value" - description: List of pramname:value pairs. If and only if content-type is one the following [`application/json`, `multipart/form-data`, `application/x-www-form-urlencoded`] and the parameter is not present, add a new parameter with the given value to form-encoded body. Ignored if the parameter is already present. - - name: append.headers - required: false - description: List of headername:value pairs. If the header is not set, set it with the given value. If it is already set, an additional new header with the same name and the new value will be appended. - - name: append.querystring - required: false - description: List of queryname:value pairs. If the querystring is not set, set it with the given value. If it is already set, a new querystring with the same name and the new value will be set. - - name: append.body - required: false - description: List of paramname:value pairs. If the content-type is one the following [`application/json`, `application/x-www-form-urlencoded`], add a new parameter with the given value if the parameter is not present, otherwise if it is already present, the two values (old and new) will be aggregated in an array. - extra: | - Note: if the value contains a `,` then the comma-separated format for lists cannot be used. The array notation must be used instead. - ---- - - -## Order of execution - -Plugin performs the response transformation in following order - -remove --> rename --> replace --> add --> append - -## Examples - -In these examples we have the plugin enabled on a Service. This would work -similarly for Routes, or the depreciated API entity. - -- Add multiple headers by passing each header:value pair separately: - -```bash -$ curl -X POST http://localhost:8001/services/example-service/plugins \ - --data "name=request-transformer" \ - --data "config.add.headers[1]=h1:v1" \ - --data "config.add.headers[2]=h2:v1" -``` - - - - - - - - - - -
incoming request headersupstream proxied headers:
h1: v1 -
    -
  • h1: v1
  • -
  • h2: v1
  • -
-
- -- Add multiple headers by passing comma separated header:value pair: - -```bash -$ curl -X POST http://localhost:8001/services/example-service/plugins \ - --data "name=request-transformer" \ - --data "config.add.headers=h1:v1,h2:v2" -``` - - - - - - - - - - -
incoming request headersupstream proxied headers:
h1: v1 -
    -
  • h1: v1
  • -
  • h2: v1
  • -
-
- -- Add multiple headers passing config as JSON body: - -```bash -$ curl -X POST http://localhost:8001/services/example-service/plugins \ - --header 'content-type: application/json' \ - --data '{"name": "request-transformer", "config": {"add": {"headers": ["h1:v2", "h2:v1"]}}}' -``` - - - - - - - - - - -
incoming request headersupstream proxied headers:
h1: v1 -
    -
  • h1: v1
  • -
  • h2: v1
  • -
-
- -- Add a querystring and a header: - -```bash -$ curl -X POST http://localhost:8001/services/example-service/plugins \ - --data "name=request-transformer" \ - --data "config.add.querystring=q1:v2,q2:v1" \ - --data "config.add.headers=h1:v1" -``` - - - - - - - - - - - - - - -
incoming request headersupstream proxied headers:
h1: v2 -
    -
  • h1: v2
  • -
  • h2: v1
  • -
-
h3: v1 -
    -
  • h1: v1
  • -
  • h2: v1
  • -
  • h3: v1
  • -
-
- -|incoming request querystring | upstream proxied querystring | -|--- | --- | -| ?q1=v1 | ?q1=v1&q2=v1 | -| | ?q1=v2&q2=v1 | - - -- Append multiple headers and remove a body parameter: - -```bash -$ curl -X POST http://localhost:8001/services/example-service/plugins \ - --header 'content-type: application/json' \ - --data '{"name": "request-transformer", "config": {"append": {"headers": ["h1:v2", "h2:v1"]}, "remove": {"body": ["p1"]}}}' -``` - - - - - - - - - - -
incoming request headersupstream proxied headers:
h1: v1 -
    -
  • h1: v1
  • -
  • h1: v2
  • -
  • h2: v1
  • -
-
- -|incoming url encoded body | upstream proxied url encoded body: | -|--- | --- | -|p1=v1&p2=v1 | p2=v1 | -|p2=v1 | p2=v1 | - -[api-object]: /gateway/latest/admin-api/#api-object -[consumer-object]: /gateway/latest/admin-api/#consumer-object -[configuration]: /gateway/latest/reference/configuration - diff --git a/app/_hub/kong-inc/request-transformer/1.2.x.md b/app/_hub/kong-inc/request-transformer/1.2.x.md deleted file mode 100644 index 5ba0a75feec4..000000000000 --- a/app/_hub/kong-inc/request-transformer/1.2.x.md +++ /dev/null @@ -1,420 +0,0 @@ ---- -name: Request Transformer -publisher: Kong Inc. -version: 1.0.x - -desc: Use regular expressions, variables, and templates to transform requests -description: | - The Request Transformer plugin for Kong allows simple transformation of requests before they reach the upstream server. These transformations can be simple substitutions or complex ones matching portions of incoming requests using regular expressions, saving those matched strings into variables, and substituting those strings into transformed requests using flexible templates. - -type: plugin -categories: - - transformations - -kong_version_compatibility: - community_edition: - compatible: - - 2.3.x - - 2.2.x - - 2.1.x - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - enterprise_edition: - compatible: - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x - -params: - name: request-transformer - service_id: true - route_id: true - consumer_id: true - konnect_examples: false - protocols: ["http", "https"] - dbless_compatible: yes - config: - - name: http_method - required: false - description: Changes the HTTP method for the upstream request. - - name: remove.headers - required: false - value_in_examples: [ "x-toremove", "x-another-one" ] - description: List of header names. Unset the header(s) with the given name. - - name: remove.querystring - required: false - value_in_examples: [ "qs-old-name:qs-new-name", "qs2-old-name:qs2-new-name" ] - description: List of querystring names. Remove the querystring if it is present. - - name: remove.body - required: false - value_in_examples: [ "formparam-toremove", "formparam-another-one" ] - description: List of parameter names. Remove the parameter if and only if content-type is one the following [`application/json`, `multipart/form-data`, `application/x-www-form-urlencoded`] and parameter is present. - - name: replace.uri - required: false - description: Updates the upstream request URI with a given value. This value can be used to update only the path part of the URI, not the scheme or the hostname. - - name: replace.body - required: false - value_in_examples: [ "body-param1:new-value-1", "body-param2:new-value-2" ] - description: List of paramname:value pairs. If and only if content-type is one the following [`application/json`, `multipart/form-data`, `application/x-www-form-urlencoded`] and the parameter is already present, replace its old value with the new one. Ignored if the parameter is not already present. - - name: replace.headers - required: false - description: List of headername:value pairs. If and only if the header is already set, replace its old value with the new one. Ignored if the header is not already set. - - name: replace.querystring - required: false - description: List of queryname:value pairs. If and only if the field name is already set, replace its old value with the new one. Ignored if the field name is not already set. - - name: rename.headers - required: false - value_in_examples: [ "header-old-name:header-new-name", "another-old-name:another-new-name" ] - description: List of headername:value pairs. If and only if the header is already set, rename the header. The value is unchanged. Ignored if the header is not already set. - - name: rename.querystring - required: false - value_in_examples: [ "qs-old-name:qs-new-name", "qs2-old-name:qs2-new-name" ] - description: List of queryname:value pairs. If and only if the field name is already set, rename the field name. The value is unchanged. Ignored if the field name is not already set. - - name: rename.body - required: false - value_in_examples: [ "param-old:param-new", "param2-old:param2-new" ] - description: List of parameter name:value pairs. Rename the parameter name if and only if content-type is one the following [`application/json`, `multipart/form-data`, `application/x-www-form-urlencoded`] and parameter is present. - - name: replace.body - required: false - description: List of paramname:value pairs. If and only if content-type is one the following [`application/json`, `multipart/form-data`, `application/x-www-form-urlencoded`] and the parameter is already present, replace its old value with the new one. Ignored if the parameter is not already present. - - name: add.headers - required: false - value_in_examples: [ "x-new-header:value", "x-another-header:something" ] - description: List of headername:value pairs. If and only if the header is not already set, set a new header with the given value. Ignored if the header is already set. - - name: add.querystring - required: false - value_in_examples: [ "new-param:some_value", "another-param:some_value" ] - description: List of queryname:value pairs. If and only if the querystring is not already set, set a new querystring with the given value. Ignored if the header is already set. - - name: add.body - required: false - value_in_examples: [ "new-form-param:some_value", "another-form-param:some_value" ] - description: List of pramname:value pairs. If and only if content-type is one the following [`application/json`, `multipart/form-data`, `application/x-www-form-urlencoded`] and the parameter is not present, add a new parameter with the given value to form-encoded body. Ignored if the parameter is already present. - - name: append.headers - required: false - description: List of headername:value pairs. If the header is not set, set it with the given value. If it is already set, an additional new header with the same name and the new value will be appended. - - name: append.querystring - required: false - description: List of queryname:value pairs. If the querystring is not set, set it with the given value. If it is already set, a new querystring with the same name and the new value will be set. - - name: append.body - required: false - description: List of paramname:value pairs. If the content-type is one the following [`application/json`, `application/x-www-form-urlencoded`], add a new parameter with the given value if the parameter is not present, otherwise if it is already present, the two values (old and new) will be aggregated in an array. - extra: | - **Notes**: - * If the value contains a `,` then the comma-separated format for lists cannot be used. The array notation must be used instead. - * The `X-Forwarded-*` fields are non-standard header fields written by Nginx to inform the upstream about client details and can't be overwritten by this plugin. If you need to overwrite these header fields, see the [post-function plugin in Serverless Functions](https://docs.konghq.com/hub/kong-inc/serverless-functions/). - ---- - -## Template as Value - -You can use any of the current request headers, query params, and captured URI groups as a template to populate the above supported configuration fields. - -| Request Param | Template -| ------------- | ----------- -| header | `$(headers.)`, `$(headers[""])` or `$(headers[""])`) -| querystring | `$(query_params.)` or `$(query_params[""])`) -| captured URIs | `$(uri_captures.)` or `$(uri_captures[""])`) - -To escape a template, wrap it inside quotes and pass it inside another template.
-`$('$(some_escaped_template)')` - -Note: The plugin creates a non-mutable table of request headers, querystrings, and captured URIs before transformation. Therefore, any update or removal of params used in template does not affect the rendered value of a template. - -### Advanced templates - -The content of the placeholder `$(...)` is evaluated as a Lua expression, so -logical operators may be used. For example: - - Header-Name:$(uri_captures["user-id"] or query_params["user"] or "unknown") - -This will first look for the path parameter (`uri_captures`). If not found, it will -return the query parameter. If that also doesn't exist, it returns the default -value '"unknown"'. - -Constant parts can be specified as part of the template outside the dynamic -placeholders. For example, creating a basic-auth header from a query parameter -called `auth` that only contains the base64-encoded part: - - Authorization:Basic $(query_params["auth"]) - -Lambdas are also supported if wrapped as an expression like this: - - $((function() ... implementation here ... end)()) - -A complete Lambda example for prefixing a header value with "Basic" if not -already there: - - Authorization:$((function() - local value = headers.Authorization - if not value then - return - end - if value:sub(1, 6) == "Basic " then - return value -- was already properly formed - end - return "Basic " .. value -- added proper prefix - end)()) - -*NOTE:* Especially in multi-line templates like the example above, make sure not -to add any trailing white-space or new-lines. Because these would be outside the -placeholders, they would be considered part of the template, and hence would be -appended to the generated value. - -The environment is sandboxed, meaning that Lambdas will not have access to any -library functions, except for the string methods (like `sub()` in the example -above). - -### Examples Using Template as Value - -Add a Service named `test` with `uris` configured with a named capture group `user_id`: - -```bash -$ curl -X POST http://localhost:8001/services \ - --data 'name=test' \ - --data 'upstream_url=http://mockbin.com' \ - --data-urlencode 'uris=/requests/user/(?\w+)' \ - --data "strip_uri=false" -``` - -Enable the `request-transformer` plugin to add a new header `x-consumer-id` -whose value is being set with the value sent with header `x-user-id` or -with the default value `alice` is `header` is missing. - -```bash -$ curl -X POST http://localhost:8001/services/test/plugins \ - --data "name=request-transformer" \ - --data-urlencode "config.add.headers=x-consumer-id:\$(headers['x-user-id'] or 'alice')" \ - --data "config.remove.headers=x-user-id" -``` - -Now send a request without setting header `x-user-id` - -```bash -$ curl -i -X GET localhost:8000/requests/user/foo -``` - -Plugin will add a new header `x-consumer-id` with value `alice` before proxying -request upstream. Now try sending request with header `x-user-id` set - -```bash -$ curl -i -X GET localhost:8000/requests/user/foo \ - -H "X-User-Id:bob" -``` - -This time the plugin will add a new header `x-consumer-id` with the value sent along -with the header `x-user-id`, i.e.`bob` - -## Order of execution - -Plugin performs the response transformation in the following order: - -* remove → rename → replace → add → append - -## Examples - - - -In these examples we have the plugin enabled on a Service. This would work -similarly for Routes. - -- Add multiple headers by passing each header:value pair separately: - -{% navtabs %} -{% navtab With a database %} -```bash -$ curl -X POST http://localhost:8001/services/example-service/plugins \ - --data "name=request-transformer" \ - --data "config.add.headers[1]=h1:v1" \ - --data "config.add.headers[2]=h2:v1" -``` -{% endnavtab %} -{% navtab Without a database %} -```yaml -plugins: -- name: request-transformer - config: - add: - headers: ["h1:v1", "h2:v1"] -``` -{% endnavtab %} -{% endnavtabs %} - - - - - - - - - - -
incoming request headersupstream proxied headers:
h1: v1 -
    -
  • h1: v1
  • -
  • h2: v1
  • -
-
- -- Add multiple headers by passing comma separated header:value pair (only possible with a database): - -```bash -$ curl -X POST http://localhost:8001/services/example-service/plugins \ - --data "name=request-transformer" \ - --data "config.add.headers=h1:v1,h2:v2" -``` - - - - - - - - - - -
incoming request headersupstream proxied headers:
h1: v1 -
    -
  • h1: v1
  • -
  • h2: v1
  • -
-
- -- Add multiple headers passing config as JSON body (only possible with a database): - -```bash -$ curl -X POST http://localhost:8001/services/example-service/plugins \ - --header 'content-type: application/json' \ - --data '{"name": "request-transformer", "config": {"add": {"headers": ["h1:v2", "h2:v1"]}}}' -``` - - - - - - - - - - -
incoming request headersupstream proxied headers:
h1: v1 -
    -
  • h1: v1
  • -
  • h2: v1
  • -
-
- -- Add a querystring and a header: - -{% navtabs %} -{% navtab With a database %} -```bash -$ curl -X POST http://localhost:8001/services/example-service/plugins \ - --data "name=request-transformer" \ - --data "config.add.querystring=q1:v2,q2:v1" \ - --data "config.add.headers=h1:v1" -``` -{% endnavtab %} -{% navtab Without a database %} -```yaml -plugins: -- name: request-transformer - config: - add: - headers: ["h1:v1"], - querystring: ["q1:v1", "q2:v2"] - -``` -{% endnavtab %} -{% endnavtabs %} - - - - - - - - - - - - - - -
incoming request headersupstream proxied headers:
h1: v2 -
    -
  • h1: v2
  • -
  • h2: v1
  • -
-
h3: v1 -
    -
  • h1: v1
  • -
  • h2: v1
  • -
  • h3: v1
  • -
-
- -|incoming request querystring | upstream proxied querystring -|--- | --- -| ?q1=v1 | ?q1=v1&q2=v1 -| | ?q1=v2&q2=v1 - -- Append multiple headers and remove a body parameter: - -{% navtabs %} -{% navtab With a database %} -```bash -$ curl -X POST http://localhost:8001/services/example-service/plugins \ - --header 'content-type: application/json' \ - --data '{"name": "request-transformer", "config": {"append": {"headers": ["h1:v2", "h2:v1"]}, "remove": {"body": ["p1"]}}}' -``` -{% endnavtab %} -{% navtab Without a database %} -``` yaml -plugins: -- name: request-transformer - config: - add: - headers: ["h1:v1", "h2:v1"] - remove: - body: [ "p1" ] - -``` -{% endnavtab %} -{% endnavtabs %} - - - - - - - - - - -
incoming request headersupstream proxied headers:
h1: v1 -
    -
  • h1: v1
  • -
  • h1: v2
  • -
  • h2: v1
  • -
-
- -|incoming url encoded body | upstream proxied url encoded body -|--- | --- -|p1=v1&p2=v1 | p2=v1 -|p2=v1 | p2=v1 diff --git a/app/_hub/kong-inc/request-transformer/_index.md b/app/_hub/kong-inc/request-transformer/_index.md index b4b14326d2e8..4140103b2a26 100644 --- a/app/_hub/kong-inc/request-transformer/_index.md +++ b/app/_hub/kong-inc/request-transformer/_index.md @@ -1,31 +1,25 @@ --- name: Request Transformer publisher: Kong Inc. -version: 1.3.x -desc: 'Use regular expressions, variables, and templates to transform requests' +desc: Use regular expressions, variables, and templates to transform requests description: | The Request Transformer plugin for Kong allows simple transformation of requests before they reach the upstream server. These transformations can be simple substitutions or complex ones matching portions of incoming requests using regular expressions, saving those matched strings into variables, and substituting those strings into transformed requests using flexible templates. + + For additional request transformation features, check out the + [Request Transformer Advanced plugin](/hub/kong-inc/request-transformer-advanced/). + With the advanced plugin, you can also limit the list of allowed parameters in the request body. + type: plugin categories: - transformations kong_version_compatibility: community_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x + compatible: true enterprise_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x + compatible: true params: name: request-transformer service_id: true @@ -274,7 +268,7 @@ Create a route for the `test` service, capturing a `user_id` field from the thir ```bash curl -X POST http://localhost:8001/services/test/routes --data "name=test_user" \ - --data-urlencode 'paths=/requests/user/(?\w+)' + --data-urlencode 'paths=~/requests/user/(?\w+)' ``` Enable the `request-transformer` plugin to add a new header, `x-user-id`, @@ -284,7 +278,7 @@ whose value is being set from the captured group in the route path specified abo curl -XPOST http://localhost:8001/routes/test_user/plugins --data "name=request-transformer" --data "config.add.headers=x-user-id:\$(uri_captures['user_id'])" ``` -Now send a request with a user id in the route path: +Now send a request with a user id in the route path: ```bash curl -i -X GET localhost:8000/requests/user/foo diff --git a/app/_hub/kong-inc/request-transformer/versions.yml b/app/_hub/kong-inc/request-transformer/versions.yml index 6be2b8ae6d66..f6c2987e3cfd 100644 --- a/app/_hub/kong-inc/request-transformer/versions.yml +++ b/app/_hub/kong-inc/request-transformer/versions.yml @@ -1,3 +1,12 @@ -- release: 1.3.x -- release: 1.2.x -- release: 0.1-x +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 1.3.3 + 2.7.x: 1.3.3 + 2.6.x: 1.3.2 + 2.5.x: 1.3.2 + 2.4.x: 1.3.2 + 2.3.x: 1.3.2 + 2.2.x: 1.2.8 + 2.1.x: 1.2.8 diff --git a/app/_hub/kong-inc/request-validator/0.35-x.md b/app/_hub/kong-inc/request-validator/0.35-x.md deleted file mode 100644 index c26b2e5075cf..000000000000 --- a/app/_hub/kong-inc/request-validator/0.35-x.md +++ /dev/null @@ -1,257 +0,0 @@ ---- -name: Request Validator -publisher: Kong Inc. -version: 0.35-x - -desc: Validates requests before they reach the upstream service -description: | - Validate requests before they reach their upstream Service. Supports request - body validation, according to a schema. **Note**: the schema format is **NOT** - [JSON schema](https://json-schema.org/) compliant; instead, Kong's own schema - format is used. - -enterprise: true -type: plugin -categories: - - traffic-control - -kong_version_compatibility: - enterprise_edition: - compatible: - - 0.35-x - -params: - name: request-validator - service_id: true - route_id: true - consumer_id: true - config: - - name: body_schema - required: true - value_in_examples: '[{"name":{"type": "string", "required": true}}]' - description: Array of schema fields ---- - -## Examples - -### Overview - -By applying the plugin to a Service, all requests to that Service will be validated -before being proxied. - -{% navtabs %} -{% navtab With a database %} - -Use a request like this: - -``` bash -curl -i -X POST http://kong:8001/services/{service}/plugins \ - --data "name=request-validator" \ - --data 'config.body_schema=[{"name":{"type": "string", "required": true}}]' -``` -{% endnavtab %} -{% navtab Without a database %} - -Add the following entry to the `plugins:` section in the declarative configuration file: - -``` yaml -plugins: -- name: request-validator - service: {service} - config: - body_schema: - name: - type: string - required: true -``` -{% endnavtab %} -{% endnavtabs %} - -The parameters/fields in both cases mean: - -| form parameter | description | -| --- | --- | -| `{service}` | The `id` or `name` of the Service to which the plugin will be associated. | -| `name` | The name of the plugin to use, in this case: `request-validator` | -| `config.body_schema` | The request body schema specification | - -In this example, the request body data would have to be a valid JSON and -conform to the schema specified in `body_schema` - i.e., it would be required -to contain a `name` field only, which needs to be a string. - -### Schema Definition - -The `config.body_schema` field expects a JSON array with the definition of each -field expected to be in the request body; for example: - -Each field definition contains the following attributes: - -| Attribute | Required | Description | -| --- | --- | --- | -| `type` | yes | The expected type for the field | -| `required` | no | Whether or not the field is required | - -Additionally, specific types may have their own required fields: - -Map: - -| Attribute | Required | Description | -| --- | --- | --- | -| `keys` | yes | The schema for the map keys | -| `values` | yes | The schema for the map values | - -Example string-boolean map: - -``` -{ - "type": "map", - "keys": { - "type": "string" - }, - "values": { - "type": "boolean" - } -} -``` - -Array: - -| Attribute | Required | Description | -| --- | --- | --- | -| `elements` | yes | The array's elements schema | - -Example integer array schema: - -``` -{ - "type": "array", - "elements": { - "type": "integer" - } -} -``` - -Record: - -| Attribute | Required | Description | -| --- | --- | --- | -| `fields` | yes | The record schema | - -Example record schema: - -``` -{ - "type": "record", - "fields": [ - { - "street": { - "type": "string", - } - }, - { - "zipcode": { - "type": "string", - } - } - ] -} -``` - -The `type` field assumes one the following values: - -- `string` -- `number` -- `integer` -- `boolean` -- `map` -- `array` -- `record` - -Each field specification may also contain "validators", which perform specific -validations: - -| Validator | Applies to | Description | -| --- | --- | --- | -| `between` | Integers | Whether the value is between two integer. Specified as an array; e.g., `{1, 10}` | -| `len_eq` | Arrays, Maps, Strings | Whether an array's length is a given value | -| `len_min` | Arrays, Maps, Strings | Whether an array's length is at least a given value | -| `len_max` | Arrays, Maps, strings | Whether an array's length is at most a given value | -| `match` | Strings | True if the value matches a given Lua pattern ** | -| `not_match` | String | True if the value doesn't match a given Lua pattern ** | -| `match_all` | Arrays | True if all strings in the array match the specified Lua pattern ** | -| `match_none` | Arrays | True if none of the strings in the array match the specified Lua pattern ** | -| `match_any` | Arrays | True if any one of the strings in the array matches the specified Lua pattern ** | -| `starts_with` | Strings | True if the string value starts with the specified substring | -| `one_of` | Strings, Numbers, Integers | True if the string field value matches one of the specified values | -| `timestamp` | Integers | True if the field value is a valid timestamp | -| `uuid`| Strings | True if the string is a valud UUID | - -**Note**: check [this][lua-patterns] out to learn about Lua patterns. - -### Schema Example - -``` -[ - { - "name": { - "type": "string", - "required": true - } - }, - { - "age": { - "type": "integer", - "required": true - } - }, - { - "address": { - "type": "record", - "required": true, - "fields": [ - { - "street": { - "type": "string", - "required": true - } - }, - { - "zipcode": { - "type": "string", - "required": true - } - } - ] - } - } -] -``` - -Such a schema would validate the following request body: - -``` -{ - "name": "Gruce The Great", - "age": 4, - "address": { - "street": "251 Post St.", - "zipcode": "94108" - } -} - -``` - -In case either the JSON or schema validation fail, a `400 Bad Request` will -be returned as response. - -### Further References - -Check out the Kong docs on storing custom entities [here][schema-docs]. - ---- - -[schema-docs]: /1.0.x/plugin-development/custom-entities/#defining-a-schema -[lua-patterns]: https://www.lua.org/pil/20.2.html -[consumer-object]: /gateway/latest/admin-api/#consumer-object -[configuration]: /gateway/latest/reference/configuration - diff --git a/app/_hub/kong-inc/request-validator/0.36-x.md b/app/_hub/kong-inc/request-validator/0.36-x.md deleted file mode 100644 index 70545c5bf187..000000000000 --- a/app/_hub/kong-inc/request-validator/0.36-x.md +++ /dev/null @@ -1,443 +0,0 @@ ---- -name: Request Validator -publisher: Kong Inc. -version: 0.36-x - -desc: Validates requests before they reach the upstream service -description: | - Validate requests before they reach their upstream Service. Supports validating - the schema of the body and the parameters of the request using either Kong's own - schema validator (body only) or a JSON Schema Draft 4-compliant validator. - -enterprise: true -type: plugin -categories: - - traffic-control - -kong_version_compatibility: - enterprise_edition: - compatible: - - 0.36-x - - 0.35-x - -params: - name: request-validator - service_id: true - route_id: true - consumer_id: true - config: - - name: body_schema - required: true - value_in_examples: '[{"name":{"type": "string", "required": true}}]' - description: Array of schema fields - - - name: allowed_content_types - required: false - default: "application/json" - value_in_examples: - description: | - List of allowed content types.
**Note:** Body validation is only - done for `application/json` and skipped for any other allowed content types. - - - name: version - required: true - default: "kong" - value_in_examples: - description: | - What validator to use. Supported values are `kong` (default) for using Kong's own schema - validator, or `draft4` for using a JSON Schema Draft 4-compliant validator. - - - name: parameter_schema - required: false - value_in_examples: - description: Array of parameter validator specifications - ---- - -## Examples - -### Overview - -By applying the plugin to a Service, all requests to that Service will be validated -before being proxied. - -{% navtabs %} -{% navtab With a database %} - -Use a request like this: - -``` bash -curl -i -X POST http://kong:8001/services/{service}/plugins \ - --data "name=request-validator" \ - --data "config.version=kong" \ - --data 'config.body_schema=[{"name":{"type": "string", "required": true}}]' -``` - -{% endnavtab %} -{% navtab Without a database %} - -Add the following entry to the `plugins:` section in the declarative configuration file: - -``` yaml -plugins: -- name: request-validator - service: {service} - config: - version: kong - body_schema: - name: - type: string - required: true -``` -{% endnavtab %} -{% endnavtabs %} - -In this example, the request body data would have to be valid JSON and -conform to the schema specified in `body_schema` - i.e., it would be required -to contain a `name` field only, which needs to be a string. - -In case the validation fails, a `400 Bad Request` will be returned as the response. - -### Schema Definition - -*For using the JSON Schema Draft 4-compliant validator, see the [JSON Schema website]( -https://json-schema.org/) for details on the format and examples. The rest of -this paragraph will explain the Kong schema.* - -The `config.body_schema` field expects a JSON array with the definition of each -field expected to be in the request body; for example: - -Each field definition contains the following attributes: - -| Attribute | Required | Description | -| --- | --- | --- | -| `type` | yes | The expected type for the field | -| `required` | no | Whether or not the field is required | - -Additionally, specific types may have their own required fields: - -Map: - -| Attribute | Required | Description | -| --- | --- | --- | -| `keys` | yes | The schema for the map keys | -| `values` | yes | The schema for the map values | - -Example string-boolean map: - -``` -{ - "type": "map", - "keys": { - "type": "string" - }, - "values": { - "type": "boolean" - } -} -``` - -Array: - -| Attribute | Required | Description | -| --- | --- | --- | -| `elements` | yes | The array's elements schema | - -Example integer array schema: - -``` -{ - "type": "array", - "elements": { - "type": "integer" - } -} -``` - -Record: - -| Attribute | Required | Description | -| --- | --- | --- | -| `fields` | yes | The record schema | - -Example record schema: - -``` -{ - "type": "record", - "fields": [ - { - "street": { - "type": "string", - } - }, - { - "zipcode": { - "type": "string", - } - } - ] -} -``` - -The `type` field assumes one the following values: - -- `string` -- `number` -- `integer` -- `boolean` -- `map` -- `array` -- `record` - -Each field specification may also contain "validators", which perform specific -validations: - -| Validator | Applies to | Description | -| --- | --- | --- | -| `between` | Integers | Whether the value is between two integer. Specified as an array; e.g., `{1, 10}` | -| `len_eq` | Arrays, Maps, Strings | Whether an array's length is a given value | -| `len_min` | Arrays, Maps, Strings | Whether an array's length is at least a given value | -| `len_max` | Arrays, Maps, strings | Whether an array's length is at most a given value | -| `match` | Strings | True if the value matches a given Lua pattern ** | -| `not_match` | String | True if the value doesn't match a given Lua pattern ** | -| `match_all` | Arrays | True if all strings in the array match the specified Lua pattern ** | -| `match_none` | Arrays | True if none of the strings in the array match the specified Lua pattern ** | -| `match_any` | Arrays | True if any one of the strings in the array matches the specified Lua pattern ** | -| `starts_with` | Strings | True if the string value starts with the specified substring | -| `one_of` | Strings, Numbers, Integers | True if the string field value matches one of the specified values | -| `timestamp` | Integers | True if the field value is a valid timestamp | -| `uuid`| Strings | True if the string is a valud UUID | - -**Note**: To learn more, see [Lua patterns][lua-patterns]. - -### Kong Schema Example - -``` -[ - { - "name": { - "type": "string", - "required": true - } - }, - { - "age": { - "type": "integer", - "required": true - } - }, - { - "address": { - "type": "record", - "required": true, - "fields": [ - { - "street": { - "type": "string", - "required": true - } - }, - { - "zipcode": { - "type": "string", - "required": true - } - } - ] - } - } -] -``` - -Such a schema would validate the following request body: - -``` -{ - "name": "Gruce The Great", - "age": 4, - "address": { - "street": "251 Post St.", - "zipcode": "94108" - } -} - -``` - -### Parameter Schema Definition - -You can setup definitions for each parameter based on the OpenAPI Specification and -the plugin will validate each parameter against it. For more information see the -[OpenAPI specification](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#parameter-object) or the [OpenAPI examples](https://swagger.io/docs/specification/serialization/). - -#### Fixed Fields - -|Field Name | Type | Description| -| --- | --- | --- | -|name | `string` | **REQUIRED**. The name of the parameter. Parameter names are *case sensitive*, and corresponds to the parameter name used by the `in` property. If `in` is `"path"`, the `name` field MUST correspond to the [named capture group](https://docs.konghq.com/latest/proxy/#capturing-groups) from the configured `route`.| -|in | `string` | **REQUIRED**. The location of the parameter. Possible values are `query`, `header`, or `path`.| -|required | `boolean` | **REQUIRED** Determines whether this parameter is mandatory.| -|style | `string` | **REQUIRED** when schema and explode are set
Describes how the parameter value will be serialized depending on the type of the parameter value.| -|schema | `string` | **REQUIRED** when style and explode are set
The schema defining the type used for the parameter. It is validated using `draft4` for JSONschema draft 4 compliant validator.| -|explode | `boolean` | **REQUIRED** when schema and style are set
When this is true, parameter values of type `array` or `object` generate separate parameters for each value of the array or key-value pair of the map. For other types of parameters this property has no effect.| - -#### Examples - -In this example we will use the plugin to validate a request's path parameter. - -1. Add a service to Kong - - ``` - curl -i -X POST http://kong:8001/services \ - --data name=httpbin \ - --data url=http://httpbin.org - - HTTP/1.1 201 Created - .. - - { - "host":"httpbin.org", - "created_at":1563479714, - "connect_timeout":60000, - "id":"0a7f3795-bc92-43b5-aada-258113b7c4ed", - "protocol":"http", - "name":"httpbin", - "read_timeout":60000, - "port":80, - "path":null, - "updated_at":1563479714, - "retries":5, - "write_timeout":60000 - } - ``` - -2. Add a route with [named capture group](https://docs.konghq.com/latest/proxy/#capturing-groups) - - ``` - curl -i -X POST http://kong:8001/services/httpbin/routes \ - --data paths="/status/(?\d%+)" \ - --data strip_path=false - - HTTP/1.1 201 Created - .. - - { - "created_at": 1563481399, - "methods": null, - "id": "cd78749a-33a3-4bbd-9560-588eaf4116d3", - "service": { - "id": "0a7f3795-bc92-43b5-aada-258113b7c4ed" - }, - "name": null, - "hosts": null, - "updated_at": 1563481399, - "preserve_host": false, - "regex_priority": 0, - "paths": [ - "\\/status\\/(?\\d+)" - ], - "sources": null, - "destinations": null, - "snis": null, - "protocols": [ - "http", - "https" - ], - "strip_path": false - } - ``` - -3. Enable request-validator plugin to validate body and parameter - - ``` - curl -i -X POST http://kong:8001/services/httpbin/plugins \ - --header "Content-Type: application/json" \ - --data @parameter_schema.json - - HTTP/1.1 201 Created - .. - - { - "created_at": 1563483059, - "config": { - "body_schema": "{\"name\":{\"type\": \"string\", \"required\": false}}", - "parameter_schema": [ - { - "style": "simple", - "required": true, - "in": "path", - "schema": "{\"type\": \"number\"}", - "explode": false, - "name": "status_code" - } - ], - "version": "draft4" - }, - "id": "ad91a2d4-6217-4d34-9133-4a2508ddda9f", - "service": { - "id": "0a7f3795-bc92-43b5-aada-258113b7c4ed" - }, - "enabled": true, - "run_on": "first", - "consumer": null, - "route": null, - "name": "request-validator" - } - ``` - - Content of file `parameter_schema.json`: - - ```json - { - "name": "request-validator", - "config": { - "body_schema": "{\"name\":{\"type\": \"string\", \"required\": false}}", - "version": "draft4", - "parameter_schema": [ - { - "name": "status_code", - "in": "path", - "required": true, - "schema": "{\"type\": \"number\"}", - "style": "simple", - "explode": false - } - ] - } - } - ``` - - Here validation will make sure `status_code` is a number. - -4. A proxy request with a non-numerical status code will be blocked - - ``` - curl -i -X GET http://kong:8000/status/abc - HTTP/1.1 400 Bad Request - .. - - {"message":"request param doesn't conform to schema"} - ``` - - but it will be allowed with a numeric status code - - ``` - curl -i -X GET http://kong:8000/status/200 - HTTP/1.1 200 OK - X-Kong-Upstream-Latency: 163 - X-Kong-Proxy-Latency: 37 - .. - - ``` - -### Further References - -See the Kong docs on storing custom entities [here][schema-docs]. - ---- - -[schema-docs]: /1.0.x/plugin-development/custom-entities/#defining-a-schema -[lua-patterns]: https://www.lua.org/pil/20.2.html -[consumer-object]: /gateway/latest/admin-api/#consumer-object -[configuration]: /gateway/latest/reference/configuration - diff --git a/app/_hub/kong-inc/request-validator/_index.md b/app/_hub/kong-inc/request-validator/_index.md index 87328143ae3f..f6f2f1085e64 100755 --- a/app/_hub/kong-inc/request-validator/_index.md +++ b/app/_hub/kong-inc/request-validator/_index.md @@ -1,7 +1,6 @@ --- name: Request Validator publisher: Kong Inc. -version: 1.3-x desc: Validates requests before they reach the Upstream service description: | Validate requests before they reach their Upstream service. Supports validating @@ -14,18 +13,7 @@ categories: - traffic-control kong_version_compatibility: enterprise_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x + compatible: true params: name: request-validator service_id: true @@ -371,7 +359,7 @@ In this example, use the plugin to validate a request's path parameter. ``` curl -i -X POST http://kong:8001/services/httpbin/routes \ - --data paths="/status/(?\d%+)" \ + --data paths="~/status/(?\d%+)" \ --data strip_path=false HTTP/1.1 201 Created diff --git a/app/_hub/kong-inc/request-validator/versions.yml b/app/_hub/kong-inc/request-validator/versions.yml index 3fdf07ac597b..35b9bea82c9e 100644 --- a/app/_hub/kong-inc/request-validator/versions.yml +++ b/app/_hub/kong-inc/request-validator/versions.yml @@ -1,3 +1,12 @@ -- release: 1.3-x -- release: 0.36-x -- release: 0.35-x +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 1.2.0 + 2.7.x: 1.2.0 + 2.6.x: 1.1.6 + 2.5.x: 1.1.5 + 2.4.x: 1.1.5 + 2.3.x: 1.1.3 + 2.2.x: 1.1.2 + 2.1.x: 1.1.1 diff --git a/app/_hub/kong-inc/response-ratelimiting/1.0.x.md b/app/_hub/kong-inc/response-ratelimiting/1.0.x.md deleted file mode 100644 index 485fc9b03760..000000000000 --- a/app/_hub/kong-inc/response-ratelimiting/1.0.x.md +++ /dev/null @@ -1,169 +0,0 @@ ---- -name: Response Rate Limiting -publisher: Kong Inc. -version: 1.0.x - -desc: Rate-limiting based on a custom response header value -description: | - This plugin allows you to limit the number of requests a developer can make based on a custom response header returned by the upstream service. You can arbitrary set as many rate-limiting objects (or quotas) as you want and instruct Kong to increase or decrease them by any number of units. Each custom rate-limiting object can limit the inbound requests per seconds, minutes, hours, days, months or years. - - If the underlying Service/Route (or deprecated API entity) has no authentication layer, the **Client IP** address will be used, otherwise the Consumer will be used if an authentication plugin has been configured. - -
- Note: The functionality of this plugin as bundled - with versions of Kong prior to 0.13.1 and Kong Gateway prior to 0.32 - differs from what is documented herein. Refer to the - CHANGELOG - for details. -
- -type: plugin -categories: - - traffic-control - -kong_version_compatibility: - community_edition: - compatible: - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x - enterprise_edition: - compatible: - - 0.34-x - - 0.33-x - - 0.32-x - - 0.31-x - -params: - name: response-ratelimiting - api_id: true - service_id: true - route_id: true - consumer_id: true - config: - - name: limits.{limit_name} - required: true - description: This is a list of custom objects that you can set, with arbitrary names set in the `{limit_name`} placeholder, like `config.limits.sms.minute=20` if your object is called "SMS". - - name: limits.{limit_name}.second - required: semi - description: The amount of HTTP requests the developer can make per second. At least one limit must exist. - - name: limits.{limit_name}.minute - required: semi - value_in_examples: 10 - description: The amount of HTTP requests the developer can make per minute. At least one limit must exist. - - name: limits.{limit_name}.hour - required: semi - description: The amount of HTTP requests the developer can make per hour. At least one limit must exist. - - name: limits.{limit_name}.day - required: semi - description: The amount of HTTP requests the developer can make per day. At least one limit must exist. - - name: limits.{limit_name}.month - required: semi - description: The amount of HTTP requests the developer can make per month. At least one limit must exist. - - name: limits.{limit_name}.year - required: semi - description: The amount of HTTP requests the developer can make per year. At least one limit must exist. - - name: header_name - required: false - default: "`X-Kong-Limit`" - description: The name of the response header used to increment the counters. - - name: block_on_first_violation - required: false - default: "`false`" - description: A boolean value that determines if the requests should be blocked as soon as one limit is being exceeded. This will block requests that are supposed to consume other limits too. - - name: limit_by - required: false - default: "`consumer`" - description: "The entity that will be used when aggregating the limits: `consumer`, `credential`, `ip`. If the `consumer` or the `credential` cannot be determined, the system will always fallback to `ip`." - - name: policy - required: false - default: "`cluster`" - description: The rate-limiting policies to use for retrieving and incrementing the limits. Available values are `local` (counters will be stored locally in-memory on the node), `cluster` (counters are stored in the datastore and shared across the nodes) and `redis` (counters are stored on a Redis server and will be shared across the nodes). - - name: fault_tolerant - required: false - default: "`true`" - description: A boolean value that determines if the requests should be proxied even if Kong has troubles connecting a third-party datastore. If `true` requests will be proxied anyways effectively disabling the rate-limiting function until the datastore is working again. If `false` then the clients will see `500` errors. - - name: hide_client_headers - required: false - default: "`false`" - description: Optionally hide informative response headers. - - name: redis_host - required: semi - description: When using the `redis` policy, this property specifies the address to the Redis server. - - name: redis_port - required: false - default: "`6379`" - description: When using the `redis` policy, this property specifies the port of the Redis server. - - name: redis_password - required: false - description: When using the `redis` policy, this property specifies the password to connect to the Redis server. - - name: redis_timeout - required: false - default: "`2000`" - description: When using the `redis` policy, this property specifies the timeout in milliseconds of any command submitted to the Redis server. - - name: redis_database - required: false - default: "`0`" - description: When using the `redis` policy, this property specifies Redis database to use. - ---- - -## Configuring Quotas - -After adding the plugin, you can increment the configured limits by adding the following response header: - -``` -Header-Name: Limit=Value [,Limit=Value] -``` - -Since `X-Kong-Limit` is the default header name (you can optionally change it), it will look like: - -``` -X-Kong-Limit: limitname1=2, limitname2=4 -``` - -That will increment the limit `limitname1` by 2 units, and `limitname2` by 4 units. - -You can optionally increment more than one limit by comma separating the entries. The header will be removed before returning the response to the original client. - ----- - -## Headers sent to the client - -When this plugin is enabled, Kong will send some additional headers back to the client telling how many units are available and how many are allowed. For example if you created a limit/quota called "Videos" with a per-minute limit: - -``` -X-RateLimit-Limit-Videos-Minute: 10 -X-RateLimit-Remaining-Videos-Minute: 9 -``` - -or it will return a combination of more time limits, if more than one is being set: - -``` -X-RateLimit-Limit-Videos-Second: 5 -X-RateLimit-Remaining-Videos-Second: 5 -X-RateLimit-Limit-Videos-Minute: 10 -X-RateLimit-Remaining-Videos-Minute: 10 -``` - -If any of the limits configured is being reached, the plugin will return a `HTTP/1.1 429` status code and an empty body. - -### Upstream Headers - -The plugin will append the usage headers for each limit before proxying it to the upstream service, so that you can properly refuse to process the request if there are no more limits remaining. The headers are in the form of `X-RateLimit-Remaining-{limit_name}`, like: - -``` -X-RateLimit-Remaining-Videos: 3 -X-RateLimit-Remaining-Images: 0 -``` - -[api-object]: /gateway/latest/admin-api/#api-object -[configuration]: /gateway/latest/reference/configuration -[consumer-object]: /gateway/latest/admin-api/#consumer-object diff --git a/app/_hub/kong-inc/response-ratelimiting/_index.md b/app/_hub/kong-inc/response-ratelimiting/_index.md index 69e691427827..213be7e3c4ca 100644 --- a/app/_hub/kong-inc/response-ratelimiting/_index.md +++ b/app/_hub/kong-inc/response-ratelimiting/_index.md @@ -110,7 +110,7 @@ params: description: 'The entity that will be used when aggregating the limits: `consumer`, `credential`, `ip`. If the `consumer` or the `credential` cannot be determined, the system will always fallback to `ip`.' - name: policy required: false - default: '`cluster`' + default: '`local`' value_in_examples: local datatype: string description: | @@ -150,14 +150,24 @@ params: datatype: integer description: 'When using the `redis` policy, this property specifies the port of the Redis server.' - name: redis_username + minimum_version: "2.8.x" required: false datatype: string description: | When using the `redis` policy, this property specifies the username to connect to the Redis server when ACL authentication is desired. + + This field is _referenceable_, which means it can be securely stored as a + [secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). - name: redis_password required: false datatype: string - description: 'When using the `redis` policy, this property specifies the password to connect to the Redis server.' + description: | + When using the `redis` policy, this property specifies the password to connect to the Redis server. + + This field is _referenceable_, which means it can be securely stored as a + [secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). - name: redis_timeout required: false default: '`2000`' @@ -234,9 +244,6 @@ X-RateLimit-Remaining-Images: 0 --- ## Changelog -### Kong Gateway 2.8.x (plugin version 2.0.1) +**{{site.base_gateway}} 2.8.x** * Added the `redis_username` configuration parameter. -* Fixed plugin versions in the documentation. Previously, the plugin versions -were labelled as `0.1-x` and `1.0-x`. They are now updated to align with the -plugin's actual versions, `1.0.x` and `2.0.x`. diff --git a/app/_hub/kong-inc/response-ratelimiting/versions.yml b/app/_hub/kong-inc/response-ratelimiting/versions.yml index feac59c09064..aab8277bd3ed 100644 --- a/app/_hub/kong-inc/response-ratelimiting/versions.yml +++ b/app/_hub/kong-inc/response-ratelimiting/versions.yml @@ -1,2 +1,12 @@ -- release: 2.0.x -- release: 1.0.x +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 2.1.0 + 2.7.x: 2.0.1 + 2.6.x: 2.0.1 + 2.5.x: 2.0.1 + 2.4.x: 2.0.1 + 2.3.x: 2.0.0 + 2.2.x: 2.0.0 + 2.1.x: 2.0.0 diff --git a/app/_hub/kong-inc/response-transformer-advanced/0.35-x.md b/app/_hub/kong-inc/response-transformer-advanced/0.35-x.md deleted file mode 100755 index 2c202e60c6b6..000000000000 --- a/app/_hub/kong-inc/response-transformer-advanced/0.35-x.md +++ /dev/null @@ -1,231 +0,0 @@ ---- -name: Response Transformer Advanced -publisher: Kong Inc. -version: 0.35-x - -desc: Modify the upstream response before returning it to the client -description: | - Transform the response sent by the upstream server on the fly on Kong, before returning the response to the client. - -
- Note on transforming bodies: Be aware of the performance of transformations on the response body. In order to parse and modify a JSON body, the plugin needs to retain it in memory, which might cause pressure on the worker's Lua VM when dealing with large bodies (several MBs). Because of Nginx's internals, the `Content-Length` header will not be set when transforming a response body. -
- -type: plugin -categories: - - transformations - -enterprise: true -kong_version_compatibility: - enterprise_edition: - compatible: - - 0.35-x - -params: - name: response-transformer-advanced - service_id: true - route_id: true - consumer_id: true - konnect_examples: false - config: - - name: remove.headers - required: false - value_in_examples: "x-toremove, x-another-one" - description: List of header names. Unset the header(s) with the given name. - - name: remove.json - required: false - value_in_examples: "json-key-toremove, another-json-key" - description: List of property names. Remove the property from the JSON body if it is present. - - name: remove.if_status - required: false - description: List of response status codes or status code ranges to which the transformation will apply. Empty means all response codes. - - name: replace.headers - required: false - description: List of headername:value pairs. If and only if the header is already set, replace its old value with the new one. Ignored if the header is not already set. - - name: replace.json - required: false - description: List of property:value pairs. If and only if the parameter is already present, replace its old value with the new one. Ignored if the parameter is not already present. - - name: replace.body - required: false - description: String with which to replace the entire response body - - name: replace.if_status - required: false - description: List of response status codes or status code ranges to which the transformation will apply. Empty means all response codes - - name: add.headers - required: false - value_in_examples: "x-new-header:value,x-another-header:something" - description: List of headername:value pairs. If and only if the header is not already set, set a new header with the given value. Ignored if the header is already set. - - name: add.json - required: false - value_in_examples: "new-json-key:some_value, another-json-key:some_value" - description: List of property:value pairs. If and only if the property is not present, add a new property with the given value to the JSON body. Ignored if the property is already present. - - name: add.if_status - required: false - description: List of response status codes or status code ranges to which the transformation will apply. Empty means all response codes - - name: append.headers - required: false - value_in_examples: "x-existing-header:some_value, x-another-header:some_value" - description: List of headername:value pairs. If the header is not set, set it with the given value. If it is already set, a new header with the same name and the new value will be set. - - name: append.json - required: false - description: List of property:value pairs. If the property is not present in the JSON body, add it with the given value. If it is already present, the two values (old and new) will be aggregated in an array. - - name: append.if_status - required: false - description: List of response status codes or status code ranges to which the transformation will apply. Empty means all response codes - ---- - -Note: if the value contains a `,` then the comma separated format for lists cannot be used. The array notation must be used instead. - -## Order of execution - -Plugin performs the response transformation in following order - -remove --> replace --> add --> append - -## Examples - -In these examples we have the plugin enabled on a Route. This would work -similar for Services. - -- Add multiple headers by passing each header:value pair separately: - -```bash -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - --data "name=response-transformer-advanced" \ - --data "config.add.headers[1]=h1:v1" \ - --data "config.add.headers[2]=h2:v1" -``` - - - - - - - - - - -
upstream response headersproxied response headers
h1: v1 -
  • h1: v1
  • h2: v1
-
- -- Add multiple headers by passing comma separated header:value pair: - -```bash -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - --data "name=response-transformer-advanced" \ - --data "config.add.headers=h1:v1,h2:v2" -``` - - - - - - - - - - -
upstream response headersproxied response headers
h1: v1 -
  • h1: v1
  • h2: v1
-
- - -- Add multiple headers passing config as JSON body: - -```bash -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - --header 'content-type: application/json' \ - --data '{"name": "response-transformer-advanced", "config": {"add": {"headers": ["h1:v2", "h2:v1"]}}}' -``` - - - - - - - - - - -
upstream response headersproxied response headers
h1: v1 -
  • h1: v1
  • h2: v1
-
- -- Add a body property and a header: - -```bash -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - --data "name=response-transformer-advanced" \ - --data "config.add.json=p1:v1,p2=v2" \ - --data "config.add.headers=h1:v1" -``` - - - - - - - - - - - - - - -
upstream response headersproxied response headers
h1: v2 -
  • h1: v2
  • h2: v1
-
h3: v1 -
  • h1: v1
  • h2: v1
  • h3: v1
-
- - -| upstream response JSON body | proxied response body | -| --- | --- | -| {} | {"p1" : "v1", "p2": "v2"} | -| {"p1" : "v2"} | {"p1" : "v2", "p2": "v2"} | - -- Append multiple headers and remove a body property: - -```bash -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - --header 'content-type: application/json' \ - --data '{"name": "response-transformer-advanced", "config": {"append": {"headers": ["h1:v2", "h2:v1"]}, "remove": {"json": ["p1"]}}}' -``` - - - - - - - - - - -
upstream response headersproxied response headers
h1: v1 -
  • h1: v1
  • h1: v2
  • h2: v1
-
- -|upstream response JSON body | proxied response body | -|--- | --- | -|{"p2": "v2"} | {"p2": "v2"} | -|{"p1" : "v1", "p2" : "v1"} | {"p2": "v2"} | - -- Replace entire response body if response code is 500 - -``` -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - --data "name=response-transformer-advanced" \ - --data "config.replace.body='{\"error\": \"internal server error\"}'" \ - --data "config.replace.if_status=500" -``` - -**Note**: the plugin doesn't validate the value in `config.replace.body` against -the content type as defined in the `Content-Type` response header. - -[api-object]: /gateway/latest/admin-api/#api-object -[consumer-object]: /gateway/latest/admin-api/#consumer-object -[configuration]: /gateway/latest/reference/configuration - diff --git a/app/_hub/kong-inc/response-transformer-advanced/0.36-x.md b/app/_hub/kong-inc/response-transformer-advanced/0.36-x.md deleted file mode 100755 index 0cf29934e38e..000000000000 --- a/app/_hub/kong-inc/response-transformer-advanced/0.36-x.md +++ /dev/null @@ -1,232 +0,0 @@ ---- -name: Response Transformer Advanced -publisher: Kong Inc. -version: 0.36-x - -desc: Modify the upstream response before returning it to the client -description: | - Transform the response sent by the upstream server on the fly on Kong, before returning the response to the client. - -
- Note on transforming bodies: Be aware of the performance of transformations on the response body. In order to parse and modify a JSON body, the plugin needs to retain it in memory, which might cause pressure on the worker's Lua VM when dealing with large bodies (several MBs). Because of Nginx's internals, the `Content-Length` header will not be set when transforming a response body. -
- -type: plugin -categories: - - transformations - -enterprise: true -kong_version_compatibility: - enterprise_edition: - compatible: - - 0.36-x - - 0.35-x - -params: - name: response-transformer-advanced - service_id: true - route_id: true - consumer_id: true - konnect_examples: false - config: - - name: remove.headers - required: false - value_in_examples: "x-toremove, x-another-one" - description: List of header names. Unset the header(s) with the given name. - - name: remove.json - required: false - value_in_examples: "json-key-toremove, another-json-key" - description: List of property names. Remove the property from the JSON body if it is present. - - name: remove.if_status - required: false - description: List of response status codes or status code ranges to which the transformation will apply. Empty means all response codes. - - name: replace.headers - required: false - description: List of headername:value pairs. If and only if the header is already set, replace its old value with the new one. Ignored if the header is not already set. - - name: replace.json - required: false - description: List of property:value pairs. If and only if the parameter is already present, replace its old value with the new one. Ignored if the parameter is not already present. - - name: replace.body - required: false - description: String with which to replace the entire response body - - name: replace.if_status - required: false - description: List of response status codes or status code ranges to which the transformation will apply. Empty means all response codes - - name: add.headers - required: false - value_in_examples: "x-new-header:value,x-another-header:something" - description: List of headername:value pairs. If and only if the header is not already set, set a new header with the given value. Ignored if the header is already set. - - name: add.json - required: false - value_in_examples: "new-json-key:some_value, another-json-key:some_value" - description: List of property:value pairs. If and only if the property is not present, add a new property with the given value to the JSON body. Ignored if the property is already present. - - name: add.if_status - required: false - description: List of response status codes or status code ranges to which the transformation will apply. Empty means all response codes - - name: append.headers - required: false - value_in_examples: "x-existing-header:some_value, x-another-header:some_value" - description: List of headername:value pairs. If the header is not set, set it with the given value. If it is already set, a new header with the same name and the new value will be set. - - name: append.json - required: false - description: List of property:value pairs. If the property is not present in the JSON body, add it with the given value. If it is already present, the two values (old and new) will be aggregated in an array. - - name: append.if_status - required: false - description: List of response status codes or status code ranges to which the transformation will apply. Empty means all response codes - ---- - -Note: if the value contains a `,` then the comma separated format for lists cannot be used. The array notation must be used instead. - -## Order of execution - -Plugin performs the response transformation in following order - -remove --> replace --> add --> append - -## Examples - -In these examples we have the plugin enabled on a Route. This would work -similar for Services. - -- Add multiple headers by passing each header:value pair separately: - -```bash -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - --data "name=response-transformer-advanced" \ - --data "config.add.headers[1]=h1:v1" \ - --data "config.add.headers[2]=h2:v1" -``` - - - - - - - - - - -
upstream response headersproxied response headers
h1: v1 -
  • h1: v1
  • h2: v1
-
- -- Add multiple headers by passing comma separated header:value pair: - -```bash -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - --data "name=response-transformer-advanced" \ - --data "config.add.headers=h1:v1,h2:v2" -``` - - - - - - - - - - -
upstream response headersproxied response headers
h1: v1 -
  • h1: v1
  • h2: v1
-
- - -- Add multiple headers passing config as JSON body: - -```bash -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - --header 'content-type: application/json' \ - --data '{"name": "response-transformer-advanced", "config": {"add": {"headers": ["h1:v2", "h2:v1"]}}}' -``` - - - - - - - - - - -
upstream response headersproxied response headers
h1: v1 -
  • h1: v1
  • h2: v1
-
- -- Add a body property and a header: - -```bash -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - --data "name=response-transformer-advanced" \ - --data "config.add.json=p1:v1,p2=v2" \ - --data "config.add.headers=h1:v1" -``` - - - - - - - - - - - - - - -
upstream response headersproxied response headers
h1: v2 -
  • h1: v2
  • h2: v1
-
h3: v1 -
  • h1: v1
  • h2: v1
  • h3: v1
-
- - -| upstream response JSON body | proxied response body | -| --- | --- | -| {} | {"p1" : "v1", "p2": "v2"} | -| {"p1" : "v2"} | {"p1" : "v2", "p2": "v2"} | - -- Append multiple headers and remove a body property: - -```bash -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - --header 'content-type: application/json' \ - --data '{"name": "response-transformer-advanced", "config": {"append": {"headers": ["h1:v2", "h2:v1"]}, "remove": {"json": ["p1"]}}}' -``` - - - - - - - - - - -
upstream response headersproxied response headers
h1: v1 -
  • h1: v1
  • h1: v2
  • h2: v1
-
- -|upstream response JSON body | proxied response body | -|--- | --- | -|{"p2": "v2"} | {"p2": "v2"} | -|{"p1" : "v1", "p2" : "v1"} | {"p2": "v2"} | - -- Replace entire response body if response code is 500 - -``` -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - --data "name=response-transformer-advanced" \ - --data "config.replace.body='{\"error\": \"internal server error\"}'" \ - --data "config.replace.if_status=500" -``` - -**Note**: the plugin doesn't validate the value in `config.replace.body` against -the content type as defined in the `Content-Type` response header. - -[api-object]: /gateway/latest/admin-api/#api-object -[consumer-object]: /gateway/latest/admin-api/#consumer-object -[configuration]: /gateway/latest/reference/configuration - diff --git a/app/_hub/kong-inc/response-transformer-advanced/1.3-x.md b/app/_hub/kong-inc/response-transformer-advanced/1.3-x.md deleted file mode 100755 index 2a742418671b..000000000000 --- a/app/_hub/kong-inc/response-transformer-advanced/1.3-x.md +++ /dev/null @@ -1,330 +0,0 @@ ---- -name: Response Transformer Advanced -publisher: Kong Inc. -version: 1.3-x - -desc: Modify the upstream response before returning it to the client -description: | - Transform the response sent by the upstream server on the fly on Kong, before returning the response to the client. - -
- Note on transforming bodies: Be aware of the performance of transformations on the response body. In order to parse and modify a JSON body, the plugin needs to retain it in memory, which might cause pressure on the worker's Lua VM when dealing with large bodies (several MBs). Because of Nginx's internals, the `Content-Length` header will not be set when transforming a response body. -
- -type: plugin -categories: - - transformations - -enterprise: true -kong_version_compatibility: - enterprise_edition: - compatible: - - 1.3-x - - 0.36-x - - 0.35-x - -params: - name: response-transformer-advanced - service_id: true - route_id: true - consumer_id: true - konnect_examples: false - config: - - name: remove.headers - required: false - value_in_examples: ["x-toremove", "x-another-one:application/json", "x-list-of-values:v1,v2,v3", "Set-Cookie:/JSESSIONID=.*/", "x-another-regex://status/$/", "x-one-more-regex:/^/begin//"] - description: List of header_name[:header_value]. If only header_name is given, unset the header field with the given header_name. If header_name:header_value is given, remove a specific header_value. If header_value starts and ends with a '/' (slash character), then it is considered to be a regular expression. Note that as per https://httpwg.org/specs/rfc7230.html#field.order multiple header values with the same header name are allowed if the entire field value for that header field is defined as a comma-separated list or the header field is a Set-Cookie header field. - - name: remove.json - required: false - value_in_examples: ["json-key-toremove", "another-json-key"] - description: List of property names. Remove the property from the JSON body if it is present. - - name: remove.if_status - required: false - description: List of response status codes or status code ranges to which the transformation will apply. Empty means all response codes. - - name: replace.headers - required: false - description: List of headername:value pairs. If and only if the header is already set, replace its old value with the new one. Ignored if the header is not already set. - - name: replace.json - required: false - description: List of property:value pairs. If and only if the parameter is already present, replace its old value with the new one. Ignored if the parameter is not already present. - - name: replace.body - required: false - description: String with which to replace the entire response body - - name: replace.if_status - required: false - description: List of response status codes or status code ranges to which the transformation will apply. Empty means all response codes - - name: add.headers - required: false - value_in_examples: ["x-new-header:value","x-another-header:something"] - description: List of headername:value pairs. If and only if the header is not already set, set a new header with the given value. Ignored if the header is already set. - - name: add.json - required: false - value_in_examples: ["new-json-key:some_value", "another-json-key:some_value"] - description: List of property:value pairs. If and only if the property is not present, add a new property with the given value to the JSON body. Ignored if the property is already present. - - name: add.if_status - required: false - description: List of response status codes or status code ranges to which the transformation will apply. Empty means all response codes - - name: append.headers - required: false - value_in_examples: ["x-existing-header:some_value", "x-another-header:some_value"] - description: List of headername:value pairs. If the header is not set, set it with the given value. If it is already set, a new header with the same name and the new value will be set. - - name: append.json - required: false - description: List of property:value pairs. If the property is not present in the JSON body, add it with the given value. If it is already present, the two values (old and new) will be aggregated in an array. - - name: append.if_status - required: false - description: List of response status codes or status code ranges to which the transformation will apply. Empty means all response codes - - name: whitelist.json - required: false - default: - value_in_examples: - description: | - Set of parameter names. Only allowed parameters are present in the JSON response body. - - name: transform.functions - required: false - description: Set of Lua functions to perform arbitrary transforms in a response JSON body. - - name: transform.if_status - required: false - description: List of response status codes or ranges to which the arbitrary transformation applies. Leaving empty implies that the transformations apply to all response codes. - ---- - -Note: if the value contains a `,` then the comma separated format for lists cannot be used. The array notation must be used instead. - -## Order of execution - -Plugin performs the response transformation in following order - -remove --> replace --> add --> append - -## Examples - -In these examples we have the plugin enabled on a Route. This would work -similar for Services. - -- Add multiple headers by passing each header:value pair separately: - -```bash -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - --data "name=response-transformer-advanced" \ - --data "config.add.headers[1]=h1:v1" \ - --data "config.add.headers[2]=h2:v1" -``` - - - - - - - - - - -
upstream response headersproxied response headers
h1: v1 -
  • h1: v1
  • h2: v1
-
- -- Add multiple headers by passing comma separated header:value pair: - -```bash -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - --data "name=response-transformer-advanced" \ - --data "config.add.headers=h1:v1,h2:v2" -``` - - - - - - - - - - -
upstream response headersproxied response headers
h1: v1 -
  • h1: v1
  • h2: v1
-
- - -- Add multiple headers passing config as JSON body: - -```bash -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - --header 'content-type: application/json' \ - --data '{"name": "response-transformer-advanced", "config": {"add": {"headers": ["h1:v2", "h2:v1"]}}}' -``` - - - - - - - - - - -
upstream response headersproxied response headers
h1: v1 -
  • h1: v1
  • h2: v1
-
- -- Add a body property and a header: - -```bash -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - --data "name=response-transformer-advanced" \ - --data "config.add.json=p1:v1,p2=v2" \ - --data "config.add.headers=h1:v1" -``` - - - - - - - - - - - - - - -
upstream response headersproxied response headers
h1: v2 -
  • h1: v2
  • h2: v1
-
h3: v1 -
  • h1: v1
  • h2: v1
  • h3: v1
-
- - -| upstream response JSON body | proxied response body | -| --- | --- | -| {} | {"p1" : "v1", "p2": "v2"} | -| {"p1" : "v2"} | {"p1" : "v2", "p2": "v2"} | - -- Append multiple headers and remove a body property: - -```bash -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - --header 'content-type: application/json' \ - --data '{"name": "response-transformer-advanced", "config": {"append": {"headers": ["h1:v2", "h2:v1"]}, "remove": {"json": ["p1"]}}}' -``` - - - - - - - - - - -
upstream response headersproxied response headers
h1: v1 -
  • h1: v1
  • h1: v2
  • h2: v1
-
- -|upstream response JSON body | proxied response body | -|--- | --- | -|{"p2": "v2"} | {"p2": "v2"} | -|{"p1" : "v1", "p2" : "v1"} | {"p2": "v2"} | - -- Replace entire response body if response code is 500 - -``` -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - --data "name=response-transformer-advanced" \ - --data "config.replace.body='{\"error\": \"internal server error\"}'" \ - --data "config.replace.if_status=500" -``` - -**Note**: the plugin doesn't validate the value in `config.replace.body` against -the content type as defined in the `Content-Type` response header. - -- Perform arbitrary transforms to a JSON body - -Use the power of embedding Lua to perform arbitrary transformations on JSON bodies. Transformation functions -receive an argument with the JSON body, and must return the transformed response body: - -```lua --- transform.lua --- this function transforms --- { "foo": "something", "something": "else" } --- into --- { "foobar": "hello world", "something": "else" } -return function (data) - if type(data) ~= "table" then - return data - end - - -- remove foo key - data["foo"] = nil - - -- add a new key - data["foobar"] = "hello world" - - return data -end -``` - -```bash -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - -F "name=response-transformer-advanced" \ - -F "config.transform.functions=@transform.lua" - -F "config.transform.if_status=200" -``` - -- Remove the entire header field with a given header name - -``` -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - --data "name=response-transformer-advanced" \ - --data "config.remove.headers=h1, h2" \ -``` - -|upstream response headers | proxied response headers | -|--- | --- | -|h1:v1,v2,v3 | {} | -|h2:v2 | {} | - -- Remove a specific header value of a given header field - -``` -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - --data "name=response-transformer-advanced" \ - --data "config.remove.headers=h1:v1, h1:v2" \ -``` - -|upstream response headers | proxied response headers | -|--- | --- | -|h1:v1,v2,v3 | h1:v3 | - -- Remove a specific header value from a comma-separated list of a header values - -``` -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - --data "name=response-transformer-advanced" \ - --data "config.remove.headers=h1:v1, h1:v2" \ -``` - -|upstream response headers | proxied response headers | -|--- | --- | -|h1:v1,v2,v3 | h1:v3 | - -**Note**: the plugin doesn't remove header values if the values are not separated by commas, unless it's a Set-Cookie header field. RFC reference: https://httpwg.org/specs/rfc7230.html#field.order - -- Remove a specific header value defined by a regular expression - -``` -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - --data "name=response-transformer-advanced" \ - --data "config.remove.headers=h1:/JSESSIONID=.*/, h2://status/$/" \ -``` - -|upstream response headers | proxied response headers | -|--- | --- | -|h1:JSESSIONID=1876832,path=/ | h1:path=/ | -|h2:/match/status/,/status/no-match/ | h2:/status/no-match/ | - -[api-object]: /gateway/latest/admin-api/#api-object -[consumer-object]: /gateway/latest/admin-api/#consumer-object -[configuration]: /gateway/latest/reference/configuration - diff --git a/app/_hub/kong-inc/response-transformer-advanced/1.5.x.md b/app/_hub/kong-inc/response-transformer-advanced/1.5.x.md deleted file mode 100755 index 93587f613ab9..000000000000 --- a/app/_hub/kong-inc/response-transformer-advanced/1.5.x.md +++ /dev/null @@ -1,334 +0,0 @@ ---- -name: Response Transformer Advanced -publisher: Kong Inc. -version: 1.5.x - -desc: Modify the upstream response before returning it to the client -description: | - Transform the response sent by the upstream server on the fly on Kong, before returning the response to the client. - -
- Note on transforming bodies: Be aware of the performance of transformations on the response body. In order to parse and modify a JSON body, the plugin needs to retain it in memory, which might cause pressure on the worker's Lua VM when dealing with large bodies (several MBs). Because of Nginx's internals, the `Content-Length` header will not be set when transforming a response body. -
- -type: plugin -categories: - - transformations - -enterprise: true -kong_version_compatibility: - enterprise_edition: - compatible: - - 1.5.x - - 1.3-x - - 0.36-x - - 0.35-x - -params: - name: response-transformer-advanced - service_id: true - route_id: true - consumer_id: true - konnect_examples: false - config: - - name: remove.headers - required: false - value_in_examples: ["x-toremove", "x-another-one:application/json", "x-list-of-values:v1,v2,v3", "Set-Cookie:/JSESSIONID=.*/", "x-another-regex://status/$/", "x-one-more-regex:/^/begin//"] - description: List of header_name[:header_value]. If only header_name is given, unset the header field with the given header_name. If header_name:header_value is given, remove a specific header_value. If header_value starts and ends with a '/' (slash character), then it is considered to be a regular expression. Note that as per https://httpwg.org/specs/rfc7230.html#field.order multiple header values with the same header name are allowed if the entire field value for that header field is defined as a comma-separated list or the header field is a Set-Cookie header field. - - name: remove.json - required: false - value_in_examples: ["json-key-toremove", "another-json-key"] - description: List of property names. Remove the property from the JSON body if it is present. - - name: remove.if_status - required: false - description: List of response status codes or status code ranges to which the transformation will apply. Empty means all response codes. - - name: rename.headers - required: false - description: List of headername:value pairs. Renames header with headername to new name. - - name: replace.headers - required: false - description: List of headername:value pairs. If and only if the header is already set, replace its old value with the new one. Ignored if the header is not already set. - - name: replace.json - required: false - description: List of property:value pairs. If and only if the parameter is already present, replace its old value with the new one. Ignored if the parameter is not already present. - - name: replace.body - required: false - description: String with which to replace the entire response body - - name: replace.if_status - required: false - description: List of response status codes or status code ranges to which the transformation will apply. Empty means all response codes - - name: add.headers - required: false - value_in_examples: ["x-new-header:value","x-another-header:something"] - description: List of headername:value pairs. If and only if the header is not already set, set a new header with the given value. Ignored if the header is already set. - - name: add.json - required: false - value_in_examples: ["new-json-key:some_value", "another-json-key:some_value"] - description: List of property:value pairs. If and only if the property is not present, add a new property with the given value to the JSON body. Ignored if the property is already present. - - name: add.if_status - required: false - description: List of response status codes or status code ranges to which the transformation will apply. Empty means all response codes - - name: append.headers - required: false - value_in_examples: ["x-existing-header:some_value", "x-another-header:some_value"] - description: List of headername:value pairs. If the header is not set, set it with the given value. If it is already set, a new header with the same name and the new value will be set. - - name: append.json - required: false - description: List of property:value pairs. If the property is not present in the JSON body, add it with the given value. If it is already present, the two values (old and new) will be aggregated in an array. - - name: append.if_status - required: false - description: List of response status codes or status code ranges to which the transformation will apply. Empty means all response codes - - name: whitelist.json - required: false - default: - value_in_examples: - description: | - Set of parameter names. Only allowed parameters are present in the JSON response body. - - name: transform.functions - required: false - description: Set of Lua functions to perform arbitrary transforms in a response JSON body. - - name: transform.if_status - required: false - description: List of response status codes or ranges to which the arbitrary transformation applies. Leaving empty implies that the transformations apply to all response codes. - ---- - -Note: if the value contains a `,` then the comma separated format for lists cannot be used. The array notation must be used instead. - -## Order of execution - -Plugin performs the response transformation in following order - -remove --> replace --> add --> append - -## Examples - -In these examples we have the plugin enabled on a Route. This would work -similar for Services. - -- Add multiple headers by passing each header:value pair separately: - -```bash -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - --data "name=response-transformer-advanced" \ - --data "config.add.headers[1]=h1:v1" \ - --data "config.add.headers[2]=h2:v1" -``` - - - - - - - - - - -
upstream response headersproxied response headers
h1: v1 -
  • h1: v1
  • h2: v1
-
- -- Add multiple headers by passing comma separated header:value pair: - -```bash -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - --data "name=response-transformer-advanced" \ - --data "config.add.headers=h1:v1,h2:v2" -``` - - - - - - - - - - -
upstream response headersproxied response headers
h1: v1 -
  • h1: v1
  • h2: v1
-
- - -- Add multiple headers passing config as JSON body: - -```bash -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - --header 'content-type: application/json' \ - --data '{"name": "response-transformer-advanced", "config": {"add": {"headers": ["h1:v2", "h2:v1"]}}}' -``` - - - - - - - - - - -
upstream response headersproxied response headers
h1: v1 -
  • h1: v1
  • h2: v1
-
- -- Add a body property and a header: - -```bash -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - --data "name=response-transformer-advanced" \ - --data "config.add.json=p1:v1,p2=v2" \ - --data "config.add.headers=h1:v1" -``` - - - - - - - - - - - - - - -
upstream response headersproxied response headers
h1: v2 -
  • h1: v2
  • h2: v1
-
h3: v1 -
  • h1: v1
  • h2: v1
  • h3: v1
-
- - -| upstream response JSON body | proxied response body | -| --- | --- | -| {} | {"p1" : "v1", "p2": "v2"} | -| {"p1" : "v2"} | {"p1" : "v2", "p2": "v2"} | - -- Append multiple headers and remove a body property: - -```bash -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - --header 'content-type: application/json' \ - --data '{"name": "response-transformer-advanced", "config": {"append": {"headers": ["h1:v2", "h2:v1"]}, "remove": {"json": ["p1"]}}}' -``` - - - - - - - - - - -
upstream response headersproxied response headers
h1: v1 -
  • h1: v1
  • h1: v2
  • h2: v1
-
- -|upstream response JSON body | proxied response body | -|--- | --- | -|{"p2": "v2"} | {"p2": "v2"} | -|{"p1" : "v1", "p2" : "v1"} | {"p2": "v2"} | - -- Replace entire response body if response code is 500 - -``` -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - --data "name=response-transformer-advanced" \ - --data "config.replace.body='{\"error\": \"internal server error\"}'" \ - --data "config.replace.if_status=500" -``` - -**Note**: the plugin doesn't validate the value in `config.replace.body` against -the content type as defined in the `Content-Type` response header. - -- Perform arbitrary transforms to a JSON body - -Use the power of embedding Lua to perform arbitrary transformations on JSON bodies. Transformation functions -receive an argument with the JSON body, and must return the transformed response body: - -```lua --- transform.lua --- this function transforms --- { "foo": "something", "something": "else" } --- into --- { "foobar": "hello world", "something": "else" } -return function (data) - if type(data) ~= "table" then - return data - end - - -- remove foo key - data["foo"] = nil - - -- add a new key - data["foobar"] = "hello world" - - return data -end -``` - -```bash -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - -F "name=response-transformer-advanced" \ - -F "config.transform.functions=@transform.lua" - -F "config.transform.if_status=200" -``` - -- Remove the entire header field with a given header name - -``` -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - --data "name=response-transformer-advanced" \ - --data "config.remove.headers=h1, h2" \ -``` - -|upstream response headers | proxied response headers | -|--- | --- | -|h1:v1,v2,v3 | {} | -|h2:v2 | {} | - -- Remove a specific header value of a given header field - -``` -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - --data "name=response-transformer-advanced" \ - --data "config.remove.headers=h1:v1, h1:v2" \ -``` - -|upstream response headers | proxied response headers | -|--- | --- | -|h1:v1,v2,v3 | h1:v3 | - -- Remove a specific header value from a comma-separated list of a header values - -``` -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - --data "name=response-transformer-advanced" \ - --data "config.remove.headers=h1:v1, h1:v2" \ -``` - -|upstream response headers | proxied response headers | -|--- | --- | -|h1:v1,v2,v3 | h1:v3 | - -**Note**: the plugin doesn't remove header values if the values are not separated by commas, unless it's a Set-Cookie header field. RFC reference: https://httpwg.org/specs/rfc7230.html#field.order - -- Remove a specific header value defined by a regular expression - -``` -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - --data "name=response-transformer-advanced" \ - --data "config.remove.headers=h1:/JSESSIONID=.*/, h2://status/$/" \ -``` - -|upstream response headers | proxied response headers | -|--- | --- | -|h1:JSESSIONID=1876832,path=/ | h1:path=/ | -|h2:/match/status/,/status/no-match/ | h2:/status/no-match/ | - -[api-object]: /gateway/latest/admin-api/#api-object -[consumer-object]: /gateway/latest/admin-api/#consumer-object -[configuration]: /gateway/latest/reference/configuration - diff --git a/app/_hub/kong-inc/response-transformer-advanced/2.1.x.md b/app/_hub/kong-inc/response-transformer-advanced/2.1.x.md deleted file mode 100644 index 5bbacb467f31..000000000000 --- a/app/_hub/kong-inc/response-transformer-advanced/2.1.x.md +++ /dev/null @@ -1,357 +0,0 @@ ---- -name: Response Transformer Advanced -publisher: Kong Inc. -version: 2.1.x - -desc: Modify the upstream response before returning it to the client -description: | - Transform the response sent by the upstream server on the fly on Kong, before returning the response to the client. - -
- Note on transforming bodies: Be aware of the performance of transformations on the response body. In order to parse and modify a JSON body, the plugin needs to retain it in memory, which might cause pressure on the worker's Lua VM when dealing with large bodies (several MBs). Because of Nginx's internals, the `Content-Length` header will not be set when transforming a response body. -
- -type: plugin -categories: - - transformations - -enterprise: true -kong_version_compatibility: - enterprise_edition: - compatible: - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x - - 0.35-x - -params: - name: response-transformer-advanced - service_id: true - route_id: true - consumer_id: true - konnect_examples: false - config: - - name: remove.headers - required: false - value_in_examples: ["x-toremove", "x-another-one:application/json", "x-list-of-values:v1,v2,v3", "Set-Cookie:/JSESSIONID=.*/", "x-another-regex://status/$/", "x-one-more-regex:/^/begin//"] - description: List of header_name[:header_value]. If only header_name is given, unset the header field with the given header_name. If header_name:header_value is given, remove a specific header_value. If header_value starts and ends with a '/' (slash character), then it is considered to be a regular expression. Note that as per https://httpwg.org/specs/rfc7230.html#field.order multiple header values with the same header name are allowed if the entire field value for that header field is defined as a comma-separated list or the header field is a Set-Cookie header field. - - name: remove.json - required: false - value_in_examples: ["json-key-toremove", "another-json-key"] - description: List of property names. Remove the property from the JSON body if it is present. - - name: remove.if_status - required: false - description: List of response status codes or status code ranges to which the transformation will apply. Empty means all response codes. - - name: rename.headers - required: false - description: List of headername:value pairs. Renames header with headername to new name. - - name: replace.headers - required: false - description: List of headername:value pairs. If and only if the header is already set, replace its old value with the new one. Ignored if the header is not already set. - - name: replace.json - required: false - description: List of property:value pairs. If and only if the parameter is already present, replace its old value with the new one. Ignored if the parameter is not already present. - - name: replace.json_types - required: false - description: List of JSON type names. Specify the types of the JSON values returned when replacing JSON properties. - - name: replace.body - required: false - description: String with which to replace the entire response body - - name: replace.if_status - required: false - description: List of response status codes or status code ranges to which the transformation will apply. Empty means all response codes - - name: add.headers - required: false - value_in_examples: ["x-new-header:value","x-another-header:something"] - description: List of headername:value pairs. If and only if the header is not already set, set a new header with the given value. Ignored if the header is already set. - - name: add.json - required: false - value_in_examples: ["new-json-key:some_value", "another-json-key:some_value"] - description: List of property:value pairs. If and only if the property is not present, add a new property with the given value to the JSON body. Ignored if the property is already present. - - name: add.json_types - required: false - value_in_examples: ["new-json-key:string", "another-json-key:boolean"] - description: List of JSON type names. Specify the types of the JSON values returned when adding a new JSON property. - - name: add.if_status - required: false - description: List of response status codes or status code ranges to which the transformation will apply. Empty means all response codes - - name: append.headers - required: false - value_in_examples: ["x-existing-header:some_value", "x-another-header:some_value"] - description: List of headername:value pairs. If the header is not set, set it with the given value. If it is already set, a new header with the same name and the new value will be set. - - name: append.json - required: false - description: List of property:value pairs. If the property is not present in the JSON body, add it with the given value. If it is already present, the two values (old and new) will be aggregated in an array. - - name: append.json_types - required: false - description: List of JSON type names. Specify the types of the JSON values returned when appending JSON properties. - - name: append.if_status - required: false - description: List of response status codes or status code ranges to which the transformation will apply. Empty means all response codes - - name: allow.json - required: false - default: - value_in_examples: - description: | - Set of parameter names. Only allowed parameters are present in the JSON response body. - - name: transform.functions - required: false - description: Set of Lua functions to perform arbitrary transforms in a response JSON body. - - name: transform.if_status - required: false - description: List of response status codes or ranges to which the arbitrary transformation applies. Leaving empty implies that the transformations apply to all response codes. - ---- - -Note: if the value contains a `,` then the comma separated format for lists cannot be used. The array notation must be used instead. - -## Order of execution - -The plugin performs the response transformation in following order: - -remove --> replace --> add --> append - -## Examples - -In these examples, we have the plugin enabled on a Route. This would work -similar for Services. - -- Add multiple headers by passing each header:value pair separately: - -```bash -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - --data "name=response-transformer-advanced" \ - --data "config.add.headers[1]=h1:v1" \ - --data "config.add.headers[2]=h2:v1" -``` - - - - - - - - - - -
upstream response headersproxied response headers
h1: v1 -
  • h1: v1
  • h2: v1
-
- -- Add multiple headers by passing comma separated header:value pair: - -```bash -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - --data "name=response-transformer-advanced" \ - --data "config.add.headers=h1:v1,h2:v2" -``` - - - - - - - - - - -
upstream response headersproxied response headers
h1: v1 -
  • h1: v1
  • h2: v1
-
- - -- Add multiple headers passing config as JSON body: - -```bash -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - --header 'content-type: application/json' \ - --data '{"name": "response-transformer-advanced", "config": {"add": {"headers": ["h1:v2", "h2:v1"]}}}' -``` - - - - - - - - - - -
upstream response headersproxied response headers
h1: v1 -
  • h1: v1
  • h2: v1
-
- -- Add a body property and a header: - -```bash -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - --data "name=response-transformer-advanced" \ - --data "config.add.json=p1:v1,p2=v2" \ - --data "config.add.headers=h1:v1" -``` - - - - - - - - - - - - - - -
upstream response headersproxied response headers
h1: v2 -
  • h1: v2
  • h2: v1
-
h3: v1 -
  • h1: v1
  • h2: v1
  • h3: v1
-
- - -| upstream response JSON body | proxied response body | -| --- | --- | -| {} | {"p1" : "v1", "p2": "v2"} | -| {"p1" : "v2"} | {"p1" : "v2", "p2": "v2"} | - -- Append multiple headers and remove a body property: - -```bash -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - --header 'content-type: application/json' \ - --data '{"name": "response-transformer-advanced", "config": {"append": {"headers": ["h1:v2", "h2:v1"]}, "remove": {"json": ["p1"]}}}' -``` - - - - - - - - - - -
upstream response headersproxied response headers
h1: v1 -
  • h1: v1
  • h1: v2
  • h2: v1
-
- -|upstream response JSON body | proxied response body | -|--- | --- | -|{"p2": "v2"} | {"p2": "v2"} | -|{"p1" : "v1", "p2" : "v1"} | {"p2": "v2"} | - -- Replace entire response body if response code is 500 - -``` -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - --data "name=response-transformer-advanced" \ - --data "config.replace.body='{\"error\": \"internal server error\"}'" \ - --data "config.replace.if_status=500" -``` - -**Note**: the plugin doesn't validate the value in `config.replace.body` against -the content type as defined in the `Content-Type` response header. - -- Perform arbitrary transforms to a JSON body - -Use the power of embedding Lua to perform arbitrary transformations on JSON bodies. Transformation functions -receive an argument with the JSON body, and must return the transformed response body: - -```lua --- transform.lua --- this function transforms --- { "foo": "something", "something": "else" } --- into --- { "foobar": "hello world", "something": "else" } -return function (data) - if type(data) ~= "table" then - return data - end - - -- remove foo key - data["foo"] = nil - - -- add a new key - data["foobar"] = "hello world" - - return data -end -``` - -```bash -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - -F "name=response-transformer-advanced" \ - -F "config.transform.functions=@transform.lua" - -F "config.transform.if_status=200" -``` - -- Remove the entire header field with a given header name - -``` -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - --data "name=response-transformer-advanced" \ - --data "config.remove.headers=h1, h2" \ -``` - -|upstream response headers | proxied response headers | -|--- | --- | -|h1:v1,v2,v3 | {} | -|h2:v2 | {} | - -- Remove a specific header value of a given header field - -``` -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - --data "name=response-transformer-advanced" \ - --data "config.remove.headers=h1:v1, h1:v2" \ -``` - -|upstream response headers | proxied response headers | -|--- | --- | -|h1:v1,v2,v3 | h1:v3 | - -- Remove a specific header value from a comma-separated list of a header values - -``` -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - --data "name=response-transformer-advanced" \ - --data "config.remove.headers=h1:v1, h1:v2" \ -``` - -|upstream response headers | proxied response headers | -|--- | --- | -|h1:v1,v2,v3 | h1:v3 | - -**Note**: the plugin doesn't remove header values if the values are not separated by commas, unless it's a Set-Cookie header field. RFC reference: https://httpwg.org/specs/rfc7230.html#field.order - -- Remove a specific header value defined by a regular expression - -``` -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - --data "name=response-transformer-advanced" \ - --data "config.remove.headers=h1:/JSESSIONID=.*/, h2://status/$/" \ -``` - -|upstream response headers | proxied response headers | -|--- | --- | -|h1:JSESSIONID=1876832,path=/ | h1:path=/ | -|h2:/match/status/,/status/no-match/ | h2:/status/no-match/ | - -[api-object]: /gateway/latest/admin-api/#api-object -[consumer-object]: /gateway/latest/admin-api/#consumer-object -[configuration]: /gateway/latest/reference/configuration - - - -- Explicitly set the type of the added JSON value `-1` to be a `number` (instead of the implicitly inferred type `string`) if the response code is 500: - -``` -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - --data "name=response-transformer-advanced" \ - --data "config.add.json=p1:-1" \ - --data "config.add.json_types=number" \ - --data "config.add.if_status=500" -``` diff --git a/app/_hub/kong-inc/response-transformer-advanced/_index.md b/app/_hub/kong-inc/response-transformer-advanced/_index.md index bf76f526d11a..eeac5ba51a16 100755 --- a/app/_hub/kong-inc/response-transformer-advanced/_index.md +++ b/app/_hub/kong-inc/response-transformer-advanced/_index.md @@ -1,7 +1,6 @@ --- name: Response Transformer Advanced publisher: Kong Inc. -version: 2.3.x (0.4.4 internal) desc: Modify the upstream response before returning it to the client description: | Transform the response sent by the upstream server on the fly before returning @@ -24,7 +23,7 @@ description: | when the `Content-Encoding` header is `gzip`. Response Transformer Advanced includes the following additional configurations: `add.if_status`, `append.if_status`, - `remove.if_status`, `replace.body`, `replace.if_status`, `transform.functions`, `transform.if_status`, + `remove.if_status`, `replace.body`, `replace.if_status`, `transform.functions`, `transform.if_status`, `allow.json`, `rename.if_status`, `transform.json`, and `dots_in_keys`.
@@ -39,18 +38,7 @@ categories: enterprise: true kong_version_compatibility: enterprise_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x + compatible: true params: name: response-transformer-advanced service_id: true @@ -194,7 +182,7 @@ The plugin allows navigating complex JSON objects (arrays and nested objects) when `config.dots_in_keys` is set to `false` (the default is `true`). - `array[*]`: Loops through all elements of the array. -- `array[N]`: Navigates to the `N`th element of the array (the index of the first element is `1`). +- `array[N]`: Navigates to the nth element of the array (the index of the first element is `1`). - `top.sub`: Navigates to the `sub` property of the `top` object. These can be combined. For example, `config.remove.json: customers[*].info.phone` removes @@ -208,7 +196,7 @@ similarly for Services. - Add multiple headers by passing each `header:value` pair separately: ```bash -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ +curl -X POST http://localhost:8001/routes/{route id}/plugins \ --data "name=response-transformer-advanced" \ --data "config.add.headers[1]=h1:v1" \ --data "config.add.headers[2]=h2:v1" @@ -230,7 +218,7 @@ $ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - Add multiple headers by passing comma-separated `header:value` pair: ```bash -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ +curl -X POST http://localhost:8001/routes/{route id}/plugins \ --data "name=response-transformer-advanced" \ --data "config.add.headers=h1:v1,h2:v2" ``` @@ -252,7 +240,7 @@ $ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - Add multiple headers passing config as a JSON body: ```bash -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ +curl -X POST http://localhost:8001/routes/{route id}/plugins \ --header 'content-type: application/json' \ --data '{"name": "response-transformer-advanced", "config": {"add": {"headers": ["h1:v2", "h2:v1"]}}}' ``` @@ -273,7 +261,7 @@ $ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - Add a body property and a header: ```bash -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ +curl -X POST http://localhost:8001/routes/{route id}/plugins \ --data "name=response-transformer-advanced" \ --data "config.add.json=p1:v1,p2=v2" \ --data "config.add.headers=h1:v1" @@ -307,7 +295,7 @@ $ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - Append multiple headers and remove a body property: ```bash -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ +curl -X POST http://localhost:8001/routes/{route id}/plugins \ --header 'content-type: application/json' \ --data '{"name": "response-transformer-advanced", "config": {"append": {"headers": ["h1:v2", "h2:v1"]}, "remove": {"json": ["p1"]}}}' ``` @@ -333,7 +321,7 @@ $ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - Replace entire response body if response code is 500: ```bash -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ +curl -X POST http://localhost:8001/routes/{route id}/plugins \ --data "name=response-transformer-advanced" \ --data "config.replace.body='{\"error\": \"internal server error\"}'" \ --data "config.replace.if_status=500" @@ -381,7 +369,7 @@ end ``` ```bash -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ +curl -X POST http://localhost:8001/routes/{route id}/plugins \ -F "name=response-transformer-advanced" \ -F "config.transform.functions=@transform.lua" \ -F "config.transform.if_status=200" @@ -390,7 +378,7 @@ $ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - Remove the entire header field with a given header name: ```bash -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ +curl -X POST http://localhost:8001/routes/{route id}/plugins \ --data "name=response-transformer-advanced" \ --data "config.remove.headers=h1,h2" ``` @@ -403,7 +391,7 @@ $ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - Remove a specific header value of a given header field: ```bash -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ +curl -X POST http://localhost:8001/routes/{route id}/plugins \ --data "name=response-transformer-advanced" \ --data "config.remove.headers=h1:v1,h1:v2" ``` @@ -415,7 +403,7 @@ $ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - Remove a specific header value from a comma-separated list of header values: ```bash -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ +curl -X POST http://localhost:8001/routes/{route id}/plugins \ --data "name=response-transformer-advanced" \ --data "config.remove.headers=h1:v1,h1:v2" ``` @@ -430,7 +418,7 @@ $ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - Remove a specific header value defined by a regular expression ```bash -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ +curl -X POST http://localhost:8001/routes/{route id}/plugins \ --data "name=response-transformer-advanced" \ --data "config.remove.headers=h1:/JSESSIONID=.*/, h2://status/$/" ``` @@ -449,7 +437,7 @@ $ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - Explicitly set the type of the added JSON value `-1` to be a `number` (instead of the implicitly inferred type `string`) if the response code is 500: ```bash -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ +curl -X POST http://localhost:8001/routes/{route id}/plugins \ --data "name=response-transformer-advanced" \ --data "config.add.json=p1:-1" \ --data "config.add.json_types=number" \ diff --git a/app/_hub/kong-inc/response-transformer-advanced/versions.yml b/app/_hub/kong-inc/response-transformer-advanced/versions.yml index 53aa80338567..aad992f551eb 100644 --- a/app/_hub/kong-inc/response-transformer-advanced/versions.yml +++ b/app/_hub/kong-inc/response-transformer-advanced/versions.yml @@ -1,6 +1,12 @@ -- release: 2.3.x -- release: 2.1.x -- release: 1.5.x -- release: 1.3-x -- release: 0.36-x -- release: 0.35-x +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 0.4.6 + 2.7.x: 0.4.5 + 2.6.x: 0.4.5 + 2.5.x: 0.4.5 + 2.4.x: 0.4.5 + 2.3.x: 0.4.5 + 2.2.x: 0.4.3 + 2.1.x: 0.4.3 diff --git a/app/_hub/kong-inc/response-transformer/0.1-x.md b/app/_hub/kong-inc/response-transformer/0.1-x.md deleted file mode 100644 index c77f681483bf..000000000000 --- a/app/_hub/kong-inc/response-transformer/0.1-x.md +++ /dev/null @@ -1,168 +0,0 @@ ---- -name: Response Transformer -publisher: Kong Inc. -version: 0.1-x - -desc: Modify the upstream response before returning it to the client -description: | - Transform the response sent by the upstream server on the fly on Kong, before returning the response to the client. - -
- Note on transforming bodies: Be aware of the performance of transformations on the response body. In order to parse and modify a JSON body, the plugin needs to retain it in memory, which might cause pressure on the worker's Lua VM when dealing with large bodies (several MBs). Because of Nginx's internals, the `Content-Length` header will not be set when transforming a response body. -
- -type: plugin -categories: - - transformations - -kong_version_compatibility: - community_edition: - compatible: - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x - enterprise_edition: - compatible: - - 0.34-x - - 0.33-x - - 0.32-x - - 0.31-x - -params: - name: response-transformer - api_id: true - service_id: true - route_id: true - consumer_id: true - config: - - name: remove.headers - required: false - value_in_examples: "x-toremove, x-another-one" - description: List of header names. Unset the header(s) with the given name. - - name: remove.json - required: false - value_in_examples: "json-key-toremove, another-json-key" - description: List of property names. Remove the property from the JSON body if it is present. - - name: replace.headers - required: false - description: List of headername:value pairs. If and only if the header is already set, replace its old value with the new one. Ignored if the header is not already set. - - name: replace.json - required: false - description: List of property:value pairs. If and only if the parameter is already present, replace its old value with the new one. Ignored if the parameter is not already present. - - name: add.headers - required: false - value_in_examples: "x-new-header:value,x-another-header:something" - description: List of headername:value pairs. If and only if the header is not already set, set a new header with the given value. Ignored if the header is already set. - - name: add.json - required: false - value_in_examples: "new-json-key:some_value, another-json-key:some_value" - description: List of property:value pairs. If and only if the property is not present, add a new property with the given value to the JSON body. Ignored if the property is already present. - - name: append.headers - required: false - value_in_examples: "x-existing-header:some_value, x-another-header:some_value" - description: List of headername:value pairs. If the header is not set, set it with the given value. If it is already set, a new header with the same name and the new value will be set. - - name: append.json - required: false - description: List of property:value pairs. If the property is not present in the JSON body, add it with the given value. If it is already present, the two values (old and new) will be aggregated in an array. - ---- - -Note: if the value contains a `,` then the comma separated format for lists cannot be used. The array notation must be used instead. - -## Order of execution - -Plugin performs the response transformation in following order - -remove --> replace --> add --> append - -## Examples - -In these examples we have the plugin enabled on a Route. This would work -similar for Services, or the depreciated API entity. - -- Add multiple headers by passing each header:value pair separately: - -```bash -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - --data "name=response-transformer" \ - --data "config.add.headers[1]=h1:v1" \ - --data "config.add.headers[2]=h2:v1" -``` -upstream response headers | proxied response headers ---- | --- -h1: v1 |
  • h1: v1
  • h2: v1
---- - -- Add multiple headers by passing comma separated header:value pair: - -```bash -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - --data "name=response-transformer" \ - --data "config.add.headers=h1:v1,h2:v2" -``` -upstream response headers | proxied response headers ---- | --- -h1: v1 |
  • h1: v1
  • h2: v1
---- - -- Add multiple headers passing config as JSON body: - -```bash -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - --header 'content-type: application/json' \ - --data '{"name": "response-transformer", "config": {"add": {"headers": ["h1:v2", "h2:v1"]}}}' -``` - -upstream response headers | proxied response headers ---- | --- -h1: v1 |
  • h1: v1
  • h2: v1
---- - -- Add a body property and a header: - -```bash -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - --data "name=response-transformer" \ - --data "config.add.json=p1:v1,p2=v2" \ - --data "config.add.headers=h1:v1" -``` - -upstream response headers | proxied response headers: ---- | --- -h1: v2 |
  • h1: v2
  • h2: v1
-h3: v1 |
  • h1: v1
  • h2: v1
  • h3: v1
- -upstream response JSON body | proxied response body ---- | --- -{} | {"p1" : "v1", "p2": "v2"} -{"p1" : "v2"} | {"p1" : "v2", "p2": "v2"} ---- - -- Append multiple headers and remove a body property: - -```bash -$ curl -X POST http://localhost:8001/routes/{route id}/plugins \ - --header 'content-type: application/json' \ - --data '{"name": "response-transformer", "config": {"append": {"headers": ["h1:v2", "h2:v1"]}, "remove": {"json": ["p1"]}}}' -``` - -upstream response headers | proxied response headers ---- | --- -h1: v1 |
  • h1: v1
  • h1: v2
  • h2: v1
- -upstream response JSON body | proxied response body ---- | --- -{"p2": "v2"} | {"p2": "v2"} -{"p1" : "v1", "p2" : "v1"} | {"p2": "v2"} - -[api-object]: /gateway/latest/admin-api/#api-object -[consumer-object]: /gateway/latest/admin-api/#consumer-object -[configuration]: /gateway/latest/reference/configuration - diff --git a/app/_hub/kong-inc/response-transformer/_index.md b/app/_hub/kong-inc/response-transformer/_index.md index b1dea7bea560..f6fedc08f90e 100644 --- a/app/_hub/kong-inc/response-transformer/_index.md +++ b/app/_hub/kong-inc/response-transformer/_index.md @@ -1,7 +1,6 @@ --- name: Response Transformer publisher: Kong Inc. -version: 1.0.x desc: Modify the upstream response before returning it to the client description: | Transform the response sent by the upstream server on the fly before returning the response to the client. @@ -14,9 +13,9 @@ description: |
For additional response transformation features, check out the - [Response Transformer Advanced plugin](/hub/kong-inc/response-transformer-advanced/). Response Transformer + [Response Transformer Advanced plugin](/hub/kong-inc/response-transformer-advanced/). Response Transformer Advanced adds the following abilities: - + * When transforming a JSON payload, transformations are applied to nested JSON objects and arrays. This can be turned off and on using the `config.dots_in_keys` configuration parameter. See [Response Transformed Advanced arrays and nested objects](/hub/kong-inc/response-transformer-advanced/#arrays-and-nested-objects). @@ -30,52 +29,16 @@ description: | when the `Content-Encoding` header is `gzip`. Response Transformer Advanced includes the following additional configurations: `add.if_status`, `append.if_status`, - `remove.if_status`, `replace.body`, `replace.if_status`, `transform.functions`, `transform.if_status`, + `remove.if_status`, `replace.body`, `replace.if_status`, `transform.functions`, `transform.if_status`, `allow.json`, `rename.if_status`, `transform.json`, and `dots_in_keys`. type: plugin categories: - transformations kong_version_compatibility: community_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x + compatible: true enterprise_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x + compatible: true params: name: response-transformer service_id: true @@ -184,7 +147,7 @@ similar for Services. {% navtab With a database %} ```bash -$ curl -X POST http://localhost:8001/routes/{route}/plugins \ +curl -X POST http://localhost:8001/routes/{route}/plugins \ --data "name=response-transformer" \ --data "config.add.headers[1]=h1:v1" \ --data "config.add.headers[2]=h2:v1" @@ -223,7 +186,7 @@ plugins: - Add multiple headers by passing comma separated header:value pair (only possible with a database): ```bash -$ curl -X POST http://localhost:8001/routes/{route}/plugins \ +curl -X POST http://localhost:8001/routes/{route}/plugins \ --data "name=response-transformer" \ --data "config.add.headers=h1:v1,h2:v2" ``` @@ -244,7 +207,7 @@ $ curl -X POST http://localhost:8001/routes/{route}/plugins \ - Add multiple headers passing config as JSON body (only possible with a database): ```bash -$ curl -X POST http://localhost:8001/routes/{route}/plugins \ +curl -X POST http://localhost:8001/routes/{route}/plugins \ --header 'content-type: application/json' \ --data '{"name": "response-transformer", "config": {"add": {"headers": ["h1:v2", "h2:v1"]}}}' ``` @@ -268,7 +231,7 @@ $ curl -X POST http://localhost:8001/routes/{route}/plugins \ {% navtab With a database %} ```bash -$ curl -X POST http://localhost:8001/routes/{route}/plugins \ +curl -X POST http://localhost:8001/routes/{route}/plugins \ --data "name=response-transformer" \ --data "config.add.json=p1:v1,p2=v2" \ --data "config.add.headers=h1:v1" @@ -318,7 +281,7 @@ plugins: {% navtab With a database %} ```bash -$ curl -X POST http://localhost:8001/routes/{route}/plugins \ +curl -X POST http://localhost:8001/routes/{route}/plugins \ --header 'content-type: application/json' \ --data '{"name": "response-transformer", "config": {"append": {"headers": ["h1:v2", "h2:v1"]}, "remove": {"json": ["p1"]}}}' ``` @@ -361,7 +324,7 @@ plugins: - Explicitly set the type of the added JSON value `-1` to be a `number` (instead of the implicitly inferred type `string`) if the response code is 500: ``` -$ curl -X POST http://localhost:8001/routes/{route}/plugins \ +curl -X POST http://localhost:8001/routes/{route}/plugins \ --data "name=response-transformer" \ --data "config.add.json=p1:-1" \ --data "config.add.json_types=number" @@ -370,4 +333,3 @@ $ curl -X POST http://localhost:8001/routes/{route}/plugins \ [api-object]: /gateway/latest/admin-api/#api-object [consumer-object]: /gateway/latest/admin-api/#consumer-object [configuration]: /gateway/latest/reference/configuration - diff --git a/app/_hub/kong-inc/response-transformer/versions.yml b/app/_hub/kong-inc/response-transformer/versions.yml index 51b988ab6d12..220a59b20c7e 100644 --- a/app/_hub/kong-inc/response-transformer/versions.yml +++ b/app/_hub/kong-inc/response-transformer/versions.yml @@ -1,2 +1,12 @@ -- release: 1.0.x -- release: 0.1-x +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 2.0.2 + 2.7.x: 2.0.2 + 2.6.x: 2.0.1 + 2.5.x: 2.0.1 + 2.4.x: 2.0.1 + 2.3.x: 2.0.1 + 2.2.x: 2.0.0 + 2.1.x: 2.0.0 diff --git a/app/_hub/kong-inc/route-by-header/0.34-x.md b/app/_hub/kong-inc/route-by-header/0.34-x.md deleted file mode 100644 index ea6deb9c04c8..000000000000 --- a/app/_hub/kong-inc/route-by-header/0.34-x.md +++ /dev/null @@ -1,159 +0,0 @@ ---- - -name: Route By Header -publisher: Kong Inc. -version: 0.34-x - -desc: Route request based on request headers -description: | - Kong Gateway plugin to route requests based on request headers. -enterprise: true -type: plugin -categories: - - traffic-control - -kong_version_compatibility: - community_edition: - compatible: - enterprise_edition: - compatible: - - 0.34-x - -params: - name: route-by-header - api_id: true - service_id: true - route_id: true - consumer_id: true - config: - - name: rules - required: false - default: {} - value_in_examples: - description: | - List of [rules](#rules) - ---- - -## Rules - -| parameter | description | -| --- | --- | -| `condition` | List of headers name and value pairs | -| `upstream_name` | Target hostname where traffic will be routed in case of condition match | - -Note: if more than one pair of header name and value is provided, the plugin looks for all of these -in the request - that is, requests must contain all of the specified headers with the specified -values for a match to occur. - -## Usage - -The plugin will route a request to a new upstream target if it matches one of the -configured rules. Each `rule` consists of a `condition` object and an -`upstream_name` object. For each request coming into Kong, the plugin will try to find a `rule` where -all the headers defined in the `condition` field have the same value as in the incoming request. -The first such match dictates the upstream to which the request is forwarded to. - -## Example - -Let's run through an example scenario to demonstrate the plugin. Let's say we have -a Kong service `searviceA`, which routes all the requests to upstream `default.domain.com`. - -Add an upstream object and a target: - -```bash -$ curl -i -X POST http://kong:8001/upstreams -d name=default.domain.com -HTTP/1.1 201 Created -... -{created_at":1534537731231, .. "slots":10000} -``` - -```bash -$ curl -i -X POST http://kong:8001/upstreams/default.domain.com/targets --data target="default.host.com:9000" -HTTP/1.1 201 Created -... -{"created_at":1534538010468, .. ,"id":"ffd8815b-fd6c-4e0e-aa67-06e9cda39c3b"} -``` - -Now we will add a `service` and a `route` object, using the upstream `default.domain.com` we just created: - -```bash -$ curl -i -X POST http://kong:8001/services --data protocol=http --data host=default.domain.com --data name=serviceA -HTTP/1.1 201 Created -... -{"host":"default.domain.com", .. ,"write_timeout":60000} -``` - -```bash -$ curl -i -X POST http://kong:8001/routes --data "paths[]=/" --data service.id=6e7f5274-62da-469e-bdd5-03c4a212c15b -HTTP/1.1 201 Created -... -{"created_at":1534538701, .. ,"id":"12ceb66b-51ed-488a-9de0-112270e6f370"} -``` - -Now any request made to service `serviceA` will be routed to the upstream `default.domain.com`. -But let's say we want to route some of these requests to different upstreams, dynamically, based on some -information provided through request headers. This is the exact situation where this plugin can be helpful. - -Let's apply this plugin on `serviceA` to route all requests with a header `Location` -set to `us-east` to upstream `east.domain.com` and requests with a header `Location` -set to `us-west` to upstream `west.domain.com`. - -Add the two upstreams and corresponding targets: - -```bash -$ curl -i -X POST http://localhost:8001/upstreams -d name=east.domain.com -HTTP/1.1 201 Created -... -{"created_at":1534541064946, .. ,"slots":10000} -``` - -```bash -$ curl -i -X POST http://kong:8001/upstreams/east.domain.com/targets --data target="east.host.com:9001" -HTTP/1.1 201 Created -... -{"created_at":1534541248416, .. ,"id":"3164a588-09d7-4a72-895f-fa19535e3682"} -``` - -```bash -$ curl -i -X POST http://localhost:8001/upstreams -d name=west.domain.com -HTTP/1.1 201 Created -... -{"created_at":1534541385227, .. ,"slots":10000} -``` - -```bash -$ curl -i -X POST http://kong:8001/upstreams/west.domain.com/targets --data target="west.host.com:9002" -HTTP/1.1 201 Created -... -{"created_at":1534541405038, .. ,"id":"96cb469f-280f-4b0a-bd3d-1a0599b82585"} -``` - -Enable plugin on service `serviceA`: - -```bash -$ curl -i -X POST http://kong:8001/services/serviceA/plugins -H 'Content-Type: application/json' --data '{"name": "route-by-header", "config": {"rules":[{"condition": {"location":"us-east"}, "upstream_name": "east.doamin.com"}, {"condition": {"location":"us-west"}, "upstream_name": "west.doamin.com"}]}}' -HTTP/1.1 201 Created -... -{"created_at":1534540916000,"config":{"rules":{"":"{\"condition\": {\"location\":\"us-east\"}, \"upstream_name\": \"east.doamin.com\"}, {\"condition\": {\"location\":\"us-west\"}, \"upstream_name\": \"west.doamin.com\"}"}},"id":"0df16085-76b2-4a50-ac30-c8a1eade389a","enabled":true,"service_id":"6e7f5274-62da-469e-bdd5-03c4a212c15b","name":"route-by-header"} - -``` - -Now, any request with header `Location` set to `us-east` will route to upstream -`east.domain.com` and requests with header `Location` set to `us-west` will route -to upstream `west.domain.com`. - -You can also provide multiple headers as matching condition. The plugin does an `AND` -on the provided headers in the `condition` field of each rule. - -Let's patch above plugin to add one more rule with multiple headers: - -```bash -$ curl -i -X PATCH http://kong:8001/plugins/0df16085-76b2-4a50-ac30-c8a1eade389a -H 'Content-Type: application/json' --data '{"name": "route-by-header", "config": {"rules":[{"condition": {"location":"us-east"}, "upstream_name": "east.doamin.com"}, {"condition": {"location":"us-west"}, "upstream_name": "west.doamin.com"}, {"condition": {"location":"us-south", "region": "US"}, "upstream_name": "south.doamin.com"}]}}' -HTTP/1.1 200 OK -... -{"created_at":1534540916000,"config":{"rules":{"":"{\"condition\": {\"location\":\"us-east\"}, \"upstream_name\": \"east.doamin.com\"}, {\"condition\": {\"location\":\"us-west\"}, \"upstream_name\": \"west.doamin.com\"}, {\"condition\": {\"location\":\"us-south\", \"region\": \"us\"}, \"upstream_name\": \"south.doamin.com\"}"}},"id":"0df16085-76b2-4a50-ac30-c8a1eade389a","enabled":true,"service_id":"6e7f5274-62da-469e-bdd5-03c4a212c15b","name":"route-by-header"} -``` - -Now we have an additional rule which routes any request with header `Location` set to -`us-south` and `Region` set to `US` route to upstream `south.domain.com`. diff --git a/app/_hub/kong-inc/route-by-header/0.35-x.md b/app/_hub/kong-inc/route-by-header/0.35-x.md deleted file mode 100644 index 5212dee85c28..000000000000 --- a/app/_hub/kong-inc/route-by-header/0.35-x.md +++ /dev/null @@ -1,160 +0,0 @@ ---- - -name: Route By Header -publisher: Kong Inc. -version: 0.35-x - -desc: Route request based on request headers -description: | - Kong Gateway plugin to route requests based on request headers. -enterprise: true -type: plugin -categories: - - traffic-control - -kong_version_compatibility: - community_edition: - compatible: - enterprise_edition: - compatible: - - 0.35-x - - 0.34-x - -params: - name: route-by-header - api_id: true - service_id: true - route_id: true - consumer_id: true - config: - - name: rules - required: false - default: {} - value_in_examples: - description: | - List of [rules](#rules) - ---- - -## Rules - -| parameter | description | -| --- | --- | -| `condition` | List of headers name and value pairs | -| `upstream_name` | Target hostname where traffic will be routed in case of condition match | - -Note: if more than one pair of header name and value is provided, the plugin looks for all of these -in the request - that is, requests must contain all of the specified headers with the specified -values for a match to occur. - -## Usage - -The plugin will route a request to a new upstream target if it matches one of the -configured rules. Each `rule` consists of a `condition` object and an -`upstream_name` object. For each request coming into Kong, the plugin will try to find a `rule` where -all the headers defined in the `condition` field have the same value as in the incoming request. -The first such match dictates the upstream to which the request is forwarded to. - -## Example - -Let's run through an example scenario to demonstrate the plugin. Let's say we have -a Kong service `searviceA`, which routes all the requests to upstream `default.domain.com`. - -Add an upstream object and a target: - -```bash -$ curl -i -X POST http://kong:8001/upstreams -d name=default.domain.com -HTTP/1.1 201 Created -... -{created_at":1534537731231, .. "slots":10000} -``` - -```bash -$ curl -i -X POST http://kong:8001/upstreams/default.domain.com/targets --data target="default.host.com:9000" -HTTP/1.1 201 Created -... -{"created_at":1534538010468, .. ,"id":"ffd8815b-fd6c-4e0e-aa67-06e9cda39c3b"} -``` - -Now we will add a `service` and a `route` object, using the upstream `default.domain.com` we just created: - -```bash -$ curl -i -X POST http://kong:8001/services --data protocol=http --data host=default.domain.com --data name=serviceA -HTTP/1.1 201 Created -... -{"host":"default.domain.com", .. ,"write_timeout":60000} -``` - -```bash -$ curl -i -X POST http://kong:8001/routes --data "paths[]=/" --data service.id=6e7f5274-62da-469e-bdd5-03c4a212c15b -HTTP/1.1 201 Created -... -{"created_at":1534538701, .. ,"id":"12ceb66b-51ed-488a-9de0-112270e6f370"} -``` - -Now any request made to service `serviceA` will be routed to the upstream `default.domain.com`. -But let's say we want to route some of these requests to different upstreams, dynamically, based on some -information provided through request headers. This is the exact situation where this plugin can be helpful. - -Let's apply this plugin on `serviceA` to route all requests with a header `Location` -set to `us-east` to upstream `east.domain.com` and requests with a header `Location` -set to `us-west` to upstream `west.domain.com`. - -Add the two upstreams and corresponding targets: - -```bash -$ curl -i -X POST http://localhost:8001/upstreams -d name=east.domain.com -HTTP/1.1 201 Created -... -{"created_at":1534541064946, .. ,"slots":10000} -``` - -```bash -$ curl -i -X POST http://kong:8001/upstreams/east.domain.com/targets --data target="east.host.com:9001" -HTTP/1.1 201 Created -... -{"created_at":1534541248416, .. ,"id":"3164a588-09d7-4a72-895f-fa19535e3682"} -``` - -```bash -$ curl -i -X POST http://localhost:8001/upstreams -d name=west.domain.com -HTTP/1.1 201 Created -... -{"created_at":1534541385227, .. ,"slots":10000} -``` - -```bash -$ curl -i -X POST http://kong:8001/upstreams/west.domain.com/targets --data target="west.host.com:9002" -HTTP/1.1 201 Created -... -{"created_at":1534541405038, .. ,"id":"96cb469f-280f-4b0a-bd3d-1a0599b82585"} -``` - -Enable plugin on service `serviceA`: - -```bash -$ curl -i -X POST http://kong:8001/services/serviceA/plugins -H 'Content-Type: application/json' --data '{"name": "route-by-header", "config": {"rules":[{"condition": {"location":"us-east"}, "upstream_name": "east.doamin.com"}, {"condition": {"location":"us-west"}, "upstream_name": "west.doamin.com"}]}}' -HTTP/1.1 201 Created -... -{"created_at":1534540916000,"config":{"rules":{"":"{\"condition\": {\"location\":\"us-east\"}, \"upstream_name\": \"east.doamin.com\"}, {\"condition\": {\"location\":\"us-west\"}, \"upstream_name\": \"west.doamin.com\"}"}},"id":"0df16085-76b2-4a50-ac30-c8a1eade389a","enabled":true,"service_id":"6e7f5274-62da-469e-bdd5-03c4a212c15b","name":"route-by-header"} - -``` - -Now, any request with header `Location` set to `us-east` will route to upstream -`east.domain.com` and requests with header `Location` set to `us-west` will route -to upstream `west.domain.com`. - -You can also provide multiple headers as matching condition. The plugin does an `AND` -on the provided headers in the `condition` field of each rule. - -Let's patch above plugin to add one more rule with multiple headers: - -```bash -$ curl -i -X PATCH http://kong:8001/plugins/0df16085-76b2-4a50-ac30-c8a1eade389a -H 'Content-Type: application/json' --data '{"name": "route-by-header", "config": {"rules":[{"condition": {"location":"us-east"}, "upstream_name": "east.doamin.com"}, {"condition": {"location":"us-west"}, "upstream_name": "west.doamin.com"}, {"condition": {"location":"us-south", "region": "US"}, "upstream_name": "south.doamin.com"}]}}' -HTTP/1.1 200 OK -... -{"created_at":1534540916000,"config":{"rules":{"":"{\"condition\": {\"location\":\"us-east\"}, \"upstream_name\": \"east.doamin.com\"}, {\"condition\": {\"location\":\"us-west\"}, \"upstream_name\": \"west.doamin.com\"}, {\"condition\": {\"location\":\"us-south\", \"region\": \"us\"}, \"upstream_name\": \"south.doamin.com\"}"}},"id":"0df16085-76b2-4a50-ac30-c8a1eade389a","enabled":true,"service_id":"6e7f5274-62da-469e-bdd5-03c4a212c15b","name":"route-by-header"} -``` - -Now we have an additional rule which routes any request with header `Location` set to -`us-south` and `Region` set to `US` route to upstream `south.domain.com`. diff --git a/app/_hub/kong-inc/route-by-header/0.36-x.md b/app/_hub/kong-inc/route-by-header/0.36-x.md deleted file mode 100644 index 95f70e31fb77..000000000000 --- a/app/_hub/kong-inc/route-by-header/0.36-x.md +++ /dev/null @@ -1,161 +0,0 @@ ---- - -name: Route By Header -publisher: Kong Inc. -version: 0.36-x - -desc: Route request based on request headers -description: | - Kong Gateway plugin to route requests based on request headers. -enterprise: true -type: plugin -categories: - - traffic-control - -kong_version_compatibility: - community_edition: - compatible: - enterprise_edition: - compatible: - - 0.36-x - - 0.35-x - - 0.34-x - -params: - name: route-by-header - api_id: true - service_id: true - route_id: true - consumer_id: true - config: - - name: rules - required: false - default: {} - value_in_examples: - description: | - List of [rules](#rules) - ---- - -## Rules - -| parameter | description | -| --- | --- | -| `condition` | List of headers name and value pairs | -| `upstream_name` | Target hostname where traffic will be routed in case of condition match | - -Note: if more than one pair of header name and value is provided, the plugin looks for all of these -in the request - that is, requests must contain all of the specified headers with the specified -values for a match to occur. - -## Usage - -The plugin will route a request to a new upstream target if it matches one of the -configured rules. Each `rule` consists of a `condition` object and an -`upstream_name` object. For each request coming into Kong, the plugin will try to find a `rule` where -all the headers defined in the `condition` field have the same value as in the incoming request. -The first such match dictates the upstream to which the request is forwarded to. - -## Example - -Let's run through an example scenario to demonstrate the plugin. Let's say we have -a Kong service `searviceA`, which routes all the requests to upstream `default.domain.com`. - -Add an upstream object and a target: - -```bash -$ curl -i -X POST http://kong:8001/upstreams -d name=default.domain.com -HTTP/1.1 201 Created -... -{created_at":1534537731231, .. "slots":10000} -``` - -```bash -$ curl -i -X POST http://kong:8001/upstreams/default.domain.com/targets --data target="default.host.com:9000" -HTTP/1.1 201 Created -... -{"created_at":1534538010468, .. ,"id":"ffd8815b-fd6c-4e0e-aa67-06e9cda39c3b"} -``` - -Now we will add a `service` and a `route` object, using the upstream `default.domain.com` we just created: - -```bash -$ curl -i -X POST http://kong:8001/services --data protocol=http --data host=default.domain.com --data name=serviceA -HTTP/1.1 201 Created -... -{"host":"default.domain.com", .. ,"write_timeout":60000} -``` - -```bash -$ curl -i -X POST http://kong:8001/routes --data "paths[]=/" --data service.id=6e7f5274-62da-469e-bdd5-03c4a212c15b -HTTP/1.1 201 Created -... -{"created_at":1534538701, .. ,"id":"12ceb66b-51ed-488a-9de0-112270e6f370"} -``` - -Now any request made to service `serviceA` will be routed to the upstream `default.domain.com`. -But let's say we want to route some of these requests to different upstreams, dynamically, based on some -information provided through request headers. This is the exact situation where this plugin can be helpful. - -Let's apply this plugin on `serviceA` to route all requests with a header `Location` -set to `us-east` to upstream `east.domain.com` and requests with a header `Location` -set to `us-west` to upstream `west.domain.com`. - -Add the two upstreams and corresponding targets: - -```bash -$ curl -i -X POST http://localhost:8001/upstreams -d name=east.domain.com -HTTP/1.1 201 Created -... -{"created_at":1534541064946, .. ,"slots":10000} -``` - -```bash -$ curl -i -X POST http://kong:8001/upstreams/east.domain.com/targets --data target="east.host.com:9001" -HTTP/1.1 201 Created -... -{"created_at":1534541248416, .. ,"id":"3164a588-09d7-4a72-895f-fa19535e3682"} -``` - -```bash -$ curl -i -X POST http://localhost:8001/upstreams -d name=west.domain.com -HTTP/1.1 201 Created -... -{"created_at":1534541385227, .. ,"slots":10000} -``` - -```bash -$ curl -i -X POST http://kong:8001/upstreams/west.domain.com/targets --data target="west.host.com:9002" -HTTP/1.1 201 Created -... -{"created_at":1534541405038, .. ,"id":"96cb469f-280f-4b0a-bd3d-1a0599b82585"} -``` - -Enable plugin on service `serviceA`: - -```bash -$ curl -i -X POST http://kong:8001/services/serviceA/plugins -H 'Content-Type: application/json' --data '{"name": "route-by-header", "config": {"rules":[{"condition": {"location":"us-east"}, "upstream_name": "east.doamin.com"}, {"condition": {"location":"us-west"}, "upstream_name": "west.doamin.com"}]}}' -HTTP/1.1 201 Created -... -{"created_at":1534540916000,"config":{"rules":{"":"{\"condition\": {\"location\":\"us-east\"}, \"upstream_name\": \"east.doamin.com\"}, {\"condition\": {\"location\":\"us-west\"}, \"upstream_name\": \"west.doamin.com\"}"}},"id":"0df16085-76b2-4a50-ac30-c8a1eade389a","enabled":true,"service_id":"6e7f5274-62da-469e-bdd5-03c4a212c15b","name":"route-by-header"} - -``` - -Now, any request with header `Location` set to `us-east` will route to upstream -`east.domain.com` and requests with header `Location` set to `us-west` will route -to upstream `west.domain.com`. - -You can also provide multiple headers as matching condition. The plugin does an `AND` -on the provided headers in the `condition` field of each rule. - -Let's patch above plugin to add one more rule with multiple headers: - -```bash -$ curl -i -X PATCH http://kong:8001/plugins/0df16085-76b2-4a50-ac30-c8a1eade389a -H 'Content-Type: application/json' --data '{"name": "route-by-header", "config": {"rules":[{"condition": {"location":"us-east"}, "upstream_name": "east.doamin.com"}, {"condition": {"location":"us-west"}, "upstream_name": "west.doamin.com"}, {"condition": {"location":"us-south", "region": "US"}, "upstream_name": "south.doamin.com"}]}}' -HTTP/1.1 200 OK -... -{"created_at":1534540916000,"config":{"rules":{"":"{\"condition\": {\"location\":\"us-east\"}, \"upstream_name\": \"east.doamin.com\"}, {\"condition\": {\"location\":\"us-west\"}, \"upstream_name\": \"west.doamin.com\"}, {\"condition\": {\"location\":\"us-south\", \"region\": \"us\"}, \"upstream_name\": \"south.doamin.com\"}"}},"id":"0df16085-76b2-4a50-ac30-c8a1eade389a","enabled":true,"service_id":"6e7f5274-62da-469e-bdd5-03c4a212c15b","name":"route-by-header"} -``` - -Now we have an additional rule which routes any request with header `Location` set to -`us-south` and `Region` set to `US` route to upstream `south.domain.com`. diff --git a/app/_hub/kong-inc/route-by-header/_index.md b/app/_hub/kong-inc/route-by-header/_index.md index f47888ca9c27..69ad388e6c0a 100644 --- a/app/_hub/kong-inc/route-by-header/_index.md +++ b/app/_hub/kong-inc/route-by-header/_index.md @@ -1,7 +1,6 @@ --- name: Route By Header publisher: Kong Inc. -version: 1.3-x desc: Route request based on request headers description: | Kong Gateway plugin to route requests based on request headers. @@ -14,18 +13,7 @@ kong_version_compatibility: community_edition: compatible: null enterprise_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x + compatible: true params: name: route-by-header service_id: true @@ -68,14 +56,22 @@ a Kong service `serviceA`, which routes all the requests to upstream `default.do Add an upstream object and a target: ```bash -$ curl -i -X POST http://kong:8001/upstreams -d name=default.domain.com +curl -i -X POST http://kong:8001/upstreams -d name=default.domain.com +``` + +Response: +``` HTTP/1.1 201 Created ... {created_at":1534537731231, .. "slots":10000} ``` ```bash -$ curl -i -X POST http://kong:8001/upstreams/default.domain.com/targets --data target="default.host.com:9000" +curl -i -X POST http://kong:8001/upstreams/default.domain.com/targets --data target="default.host.com:9000" +``` + +Response: +``` HTTP/1.1 201 Created ... {"created_at":1534538010468, .. ,"id":"ffd8815b-fd6c-4e0e-aa67-06e9cda39c3b"} @@ -84,14 +80,22 @@ HTTP/1.1 201 Created Now we will add a `service` and a `route` object, using the upstream `default.domain.com` we just created: ```bash -$ curl -i -X POST http://kong:8001/services --data protocol=http --data host=default.domain.com --data name=serviceA +curl -i -X POST http://kong:8001/services --data protocol=http --data host=default.domain.com --data name=serviceA +``` + +Response: +``` HTTP/1.1 201 Created ... {"host":"default.domain.com", .. ,"write_timeout":60000} ``` ```bash -$ curl -i -X POST http://kong:8001/routes --data "paths[]=/" --data service.id=6e7f5274-62da-469e-bdd5-03c4a212c15b +curl -i -X POST http://kong:8001/routes --data "paths[]=/" --data service.id=6e7f5274-62da-469e-bdd5-03c4a212c15b +``` + +Response: +``` HTTP/1.1 201 Created ... {"created_at":1534538701, .. ,"id":"12ceb66b-51ed-488a-9de0-112270e6f370"} @@ -108,28 +112,44 @@ set to `us-west` to upstream `west.domain.com`. Add the two upstreams and corresponding targets: ```bash -$ curl -i -X POST http://localhost:8001/upstreams -d name=east.domain.com +curl -i -X POST http://localhost:8001/upstreams -d name=east.domain.com +``` + +Response: +``` HTTP/1.1 201 Created ... {"created_at":1534541064946, .. ,"slots":10000} ``` ```bash -$ curl -i -X POST http://kong:8001/upstreams/east.domain.com/targets --data target="east.host.com:9001" +curl -i -X POST http://kong:8001/upstreams/east.domain.com/targets --data target="east.host.com:9001" +``` + +Response: +``` HTTP/1.1 201 Created ... {"created_at":1534541248416, .. ,"id":"3164a588-09d7-4a72-895f-fa19535e3682"} ``` ```bash -$ curl -i -X POST http://localhost:8001/upstreams -d name=west.domain.com +curl -i -X POST http://localhost:8001/upstreams -d name=west.domain.com +``` + +Response: +``` HTTP/1.1 201 Created ... {"created_at":1534541385227, .. ,"slots":10000} ``` ```bash -$ curl -i -X POST http://kong:8001/upstreams/west.domain.com/targets --data target="west.host.com:9002" +curl -i -X POST http://kong:8001/upstreams/west.domain.com/targets --data target="west.host.com:9002" +``` + +Response: +``` HTTP/1.1 201 Created ... {"created_at":1534541405038, .. ,"id":"96cb469f-280f-4b0a-bd3d-1a0599b82585"} @@ -138,7 +158,13 @@ HTTP/1.1 201 Created Enable plugin on service `serviceA`: ```bash -$ curl -i -X POST http://kong:8001/services/serviceA/plugins -H 'Content-Type: application/json' --data '{"name": "route-by-header", "config": {"rules":[{"condition": {"location":"us-east"}, "upstream_name": "east.doamin.com"}, {"condition": {"location":"us-west"}, "upstream_name": "west.doamin.com"}]}}' +curl -i -X POST http://kong:8001/services/serviceA/plugins \ + -H 'Content-Type: application/json' \ + --data '{"name": "route-by-header", "config": {"rules":[{"condition": {"location":"us-east"}, "upstream_name": "east.doamin.com"}, {"condition": {"location":"us-west"}, "upstream_name": "west.doamin.com"}]}}' +``` + +Response: +``` HTTP/1.1 201 Created ... {"created_at":1534540916000,"config":{"rules":{"":"{\"condition\": {\"location\":\"us-east\"}, \"upstream_name\": \"east.doamin.com\"}, {\"condition\": {\"location\":\"us-west\"}, \"upstream_name\": \"west.doamin.com\"}"}},"id":"0df16085-76b2-4a50-ac30-c8a1eade389a","enabled":true,"service_id":"6e7f5274-62da-469e-bdd5-03c4a212c15b","name":"route-by-header"} @@ -155,7 +181,13 @@ on the provided headers in the `condition` field of each rule. Let's patch above plugin to add one more rule with multiple headers: ```bash -$ curl -i -X PATCH http://kong:8001/plugins/0df16085-76b2-4a50-ac30-c8a1eade389a -H 'Content-Type: application/json' --data '{"name": "route-by-header", "config": {"rules":[{"condition": {"location":"us-east"}, "upstream_name": "east.doamin.com"}, {"condition": {"location":"us-west"}, "upstream_name": "west.doamin.com"}, {"condition": {"location":"us-south", "region": "US"}, "upstream_name": "south.doamin.com"}]}}' +curl -i -X PATCH http://kong:8001/plugins/0df16085-76b2-4a50-ac30-c8a1eade389a \ + -H 'Content-Type: application/json' \ + --data '{"name": "route-by-header", "config": {"rules":[{"condition": {"location":"us-east"}, "upstream_name": "east.doamin.com"}, {"condition": {"location":"us-west"}, "upstream_name": "west.doamin.com"}, {"condition": {"location":"us-south", "region": "US"}, "upstream_name": "south.doamin.com"}]}}' +``` + +Response: +``` HTTP/1.1 200 OK ... {"created_at":1534540916000,"config":{"rules":{"":"{\"condition\": {\"location\":\"us-east\"}, \"upstream_name\": \"east.doamin.com\"}, {\"condition\": {\"location\":\"us-west\"}, \"upstream_name\": \"west.doamin.com\"}, {\"condition\": {\"location\":\"us-south\", \"region\": \"us\"}, \"upstream_name\": \"south.doamin.com\"}"}},"id":"0df16085-76b2-4a50-ac30-c8a1eade389a","enabled":true,"service_id":"6e7f5274-62da-469e-bdd5-03c4a212c15b","name":"route-by-header"} diff --git a/app/_hub/kong-inc/route-by-header/versions.yml b/app/_hub/kong-inc/route-by-header/versions.yml index db1009c910e9..f9b2588c8fcd 100644 --- a/app/_hub/kong-inc/route-by-header/versions.yml +++ b/app/_hub/kong-inc/route-by-header/versions.yml @@ -1,4 +1,12 @@ -- release: 1.3-x -- release: 0.36-x -- release: 0.35-x -- release: 0.34-x +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 0.3.2 + 2.7.x: 0.3.2 + 2.6.x: 0.3.2 + 2.5.x: 0.3.2 + 2.4.x: 0.3.2 + 2.3.x: 0.3.2 + 2.2.x: 0.3.2 + 2.1.x: 0.3.2 diff --git a/app/_hub/kong-inc/route-transformer-advanced/_index.md b/app/_hub/kong-inc/route-transformer-advanced/_index.md index 066fccb6ee36..62b977192d54 100644 --- a/app/_hub/kong-inc/route-transformer-advanced/_index.md +++ b/app/_hub/kong-inc/route-transformer-advanced/_index.md @@ -12,17 +12,7 @@ kong_version_compatibility: community_edition: compatible: null enterprise_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x + compatible: true params: name: route-transformer-advanced service_id: true diff --git a/app/_hub/kong-inc/route-transformer-advanced/versions.yml b/app/_hub/kong-inc/route-transformer-advanced/versions.yml index 3676eb6b1787..69c58daa498b 100644 --- a/app/_hub/kong-inc/route-transformer-advanced/versions.yml +++ b/app/_hub/kong-inc/route-transformer-advanced/versions.yml @@ -1 +1,12 @@ -- release: 0.2.x +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 0.2.1 + 2.7.x: 0.2.1 + 2.6.x: 0.2.1 + 2.5.x: 0.2.1 + 2.4.x: 0.2.1 + 2.3.x: 0.2.1 + 2.2.x: 0.2.1 + 2.1.x: 0.2.0 diff --git a/app/_hub/kong-inc/serverless-functions/0.1-x.md b/app/_hub/kong-inc/serverless-functions/0.1-x.md deleted file mode 100644 index 7b2cd9351d3a..000000000000 --- a/app/_hub/kong-inc/serverless-functions/0.1-x.md +++ /dev/null @@ -1,161 +0,0 @@ ---- -name: Serverless Functions -publisher: Kong Inc. -version: 0.1-x - -source_url: https://github.com/Kong/kong-plugin-serverless-functions - -desc: Dynamically run Lua code from Kong during the access phase -description: | - Dynamically run Lua code from Kong during access phase. - -type: plugin -categories: - - serverless - -kong_version_compatibility: - community_edition: - compatible: - - 0.14.x - enterprise_edition: - compatible: - - 0.34-x - - 0.33-x - - 0.32-x - -params: - name: serverless-functions - api_id: true - service_id: true - route_id: true - consumer_id: false - konnect_examples: false - config: - - name: functions - required: true - default: "[]" - value_in_examples: "[]" - description: Array of stringified Lua code to be cached and run in sequence during access phase. - ---- - -## Plugin Names - -Serverless Functions come as two separate plugins. Each one runs with a -different priority in the plugin chain. - -- `pre-function` - - Runs before other plugins run during access phase. -- `post-function` - - Runs after other plugins in the access phase. - -## Demonstration - -1. Create a Service on Kong: - - ```bash - $ curl -i -X POST http://localhost:8001/services/ \ - --data "name=plugin-testing" \ - --data "url=http://httpbin.org/headers" - - HTTP/1.1 201 Created - ... - ``` - -2. Add a Route to the Service: - - ```bash - $ curl -i -X POST http://localhost:8001/services/plugin-testing/routes \ - --data "paths[]=/test" - - HTTP/1.1 201 Created - ... - ``` - -1. Create a file named `custom-auth.lua` with the following content: - - ```lua - -- Get list of request headers - local custom_auth = kong.request.get_header("x-custom-auth") - - -- Terminate request early if our custom authentication header - -- does not exist - if not custom_auth then - return kong.response.exit(401\, "Invalid Credentials") - end - - -- Remove custom authentication header from request - kong.service.request.clear_header('x-custom-auth') - ``` - -4. Ensure the file contents: - - ```bash - $ cat custom-auth.lua - ``` - -5. Apply our Lua code using the `pre-function` plugin using cURL file upload: - - ```bash - $ curl -i -X POST http://localhost:8001/services/plugin-testing/plugins \ - -F "name=pre-function" \ - -F "config.functions=@custom-auth.lua" - - HTTP/1.1 201 Created - ... - ``` - -6. Test that our Lua code will terminate the request when no header is passed: - - ```bash - curl -i -X GET http://localhost:8000/test - - HTTP/1.1 401 Unauthorized - ... - "Invalid Credentials" - ``` - -7. Test the Lua code we just applied by making a valid request: - - ```bash - curl -i -X GET http://localhost:8000/test \ - --header "x-custom-auth: demo" - - HTTP/1.1 200 OK - ... - ``` - -This is just a small demonstration of the power these plugins grant. We were -able to dynamically inject Lua code into the plugin access phase to dynamically -terminate, or transform the request without creating a custom plugin or -reloading / redeploying Kong. - -In short, serverless functions give you the full capabilities of a custom plugin -in the access phase without ever redeploying / restarting Kong. - ----- - -### Notes - -#### Fake Upstreams - -Since the [Service][service-url] entity requires defining an upstream you may -define a fake upstream and take care to terminate the request. See the -[`lua-ngx-module`](https://github.com/openresty/lua-nginx-module#ngxexit) -documentation for more information. - -#### Escaping Commas - -Since the Lua code blocks are sent in an Array, when using `form-data` you might -run into an issue with code being split when using commas. To avoid this situation -escape commas using the backslash character `\,`. - -#### Minifying Lua - -Since we send our code over in a string format, it is advisable to use either -curl file upload `@file.lua` (see demonstration) or to minify your Lua code -using a [minifier][lua-minifier]. - - -[service-url]: https://getkong.org/docs/latest/admin-api/#service-object -[lua-minifier]: https://mothereff.in/lua-minifier diff --git a/app/_hub/kong-inc/serverless-functions/0.2-x.md b/app/_hub/kong-inc/serverless-functions/0.2-x.md deleted file mode 100644 index ccf49350e272..000000000000 --- a/app/_hub/kong-inc/serverless-functions/0.2-x.md +++ /dev/null @@ -1,167 +0,0 @@ ---- -name: Serverless Functions -publisher: Kong Inc. -version: 0.2-x - -source_url: https://github.com/Kong/kong-plugin-serverless-functions - -desc: Dynamically run Lua code from Kong during the access phase -description: | - Dynamically run Lua code from Kong during access phase. - -type: plugin -categories: - - serverless - -kong_version_compatibility: - community_edition: - compatible: - - 1.1.x - - 1.0.x - - 0.14.x - enterprise_edition: - compatible: - - 0.35-x - - 0.34-x - - 0.33-x - - 0.32-x - -params: - name: serverless-functions - service_id: true - route_id: true - consumer_id: false - protocols: ["http", "https"] - konnect_examples: false - dbless_compatible: partially - dbless_explanation: | - The functions will be executed, but if the configured functions attempt to write to the database, the writes will fail. - config: - - name: functions - required: true - default: "[]" - value_in_examples: "[]" - description: Array of stringified Lua code to be cached and run in sequence during access phase. - ---- - -## Plugin Names - -Serverless Functions come as two separate plugins. Each one runs with a -different priority in the plugin chain. - -- `pre-function` - - Runs before other plugins run during access phase. -- `post-function` - - Runs after other plugins in the access phase. - -## Demonstration - -1. Create a Service on Kong: - - ```bash - $ curl -i -X POST http://localhost:8001/services/ \ - --data "name=plugin-testing" \ - --data "url=http://httpbin.org/headers" - - HTTP/1.1 201 Created - ... - ``` - -2. Add a Route to the Service: - - ```bash - $ curl -i -X POST http://localhost:8001/services/plugin-testing/routes \ - --data "paths[]=/test" - - HTTP/1.1 201 Created - ... - ``` - -1. Create a file named `custom-auth.lua` with the following content: - - ```lua - -- Get list of request headers - local custom_auth = kong.request.get_header("x-custom-auth") - - -- Terminate request early if our custom authentication header - -- does not exist - if not custom_auth then - return kong.response.exit(401, "Invalid Credentials") - end - - -- Remove custom authentication header from request - kong.service.request.clear_header('x-custom-auth') - ``` - -4. Ensure the file contents: - - ```bash - $ cat custom-auth.lua - ``` - -5. Apply our Lua code using the `pre-function` plugin using cURL file upload: - - ```bash - $ curl -i -X POST http://localhost:8001/services/plugin-testing/plugins \ - -F "name=pre-function" \ - -F "config.functions=@custom-auth.lua" - - HTTP/1.1 201 Created - ... - ``` - -6. Test that our Lua code will terminate the request when no header is passed: - - ```bash - curl -i -X GET http://localhost:8000/test - - HTTP/1.1 401 Unauthorized - ... - "Invalid Credentials" - ``` - -7. Test the Lua code we just applied by making a valid request: - - ```bash - curl -i -X GET http://localhost:8000/test \ - --header "x-custom-auth: demo" - - HTTP/1.1 200 OK - ... - ``` - -This is just a small demonstration of the power these plugins grant. We were -able to dynamically inject Lua code into the plugin access phase to dynamically -terminate, or transform the request without creating a custom plugin or -reloading / redeploying Kong. - -In short, serverless functions give you the full capabilities of a custom plugin -in the access phase without ever redeploying / restarting Kong. - ----- - -### Notes - -#### Fake Upstreams - -Since the [Service][service-url] entity requires defining an upstream you may -define a fake upstream and take care to terminate the request. See the -[`lua-ngx-module`](https://github.com/openresty/lua-nginx-module#ngxexit) -documentation for more information. - -#### Escaping Commas - -Since the Lua code blocks are sent in an Array, when using `form-data` you might -run into an issue with code being split when using commas. To avoid this situation -escape commas using the backslash character `\,`. - -#### Minifying Lua - -Since we send our code over in a string format, it is advisable to use either -curl file upload `@file.lua` (see demonstration) or to minify your Lua code -using a [minifier][lua-minifier]. - - -[service-url]: https://getkong.org/docs/latest/admin-api/#service-object -[lua-minifier]: https://mothereff.in/lua-minifier diff --git a/app/_hub/kong-inc/serverless-functions/0.3-x.md b/app/_hub/kong-inc/serverless-functions/0.3-x.md deleted file mode 100644 index fa6857a6188c..000000000000 --- a/app/_hub/kong-inc/serverless-functions/0.3-x.md +++ /dev/null @@ -1,241 +0,0 @@ ---- -name: Serverless Functions -publisher: Kong Inc. -version: 0.3-x - -source_url: https://github.com/Kong/kong-plugin-serverless-functions - -desc: Dynamically run Lua code from Kong during the access phase -description: | - Dynamically run Lua code from Kong during the access phase. - -type: plugin -categories: - - serverless - -kong_version_compatibility: - community_edition: - compatible: - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - enterprise_edition: - compatible: - - 1.5.x - - 1.3-x - - 0.36-x - - 0.35-x - - 0.34-x - - 0.33-x - - 0.32-x - -params: - name: pre-function OR post-function - service_id: true - route_id: true - consumer_id: false - protocols: ["http", "https"] - konnect_examples: false - dbless_compatible: partially - dbless_explanation: | - The functions will be executed, but if the configured functions attempt to write to the database, the writes will fail. - config: - - name: functions - required: true - default: "[]" - value_in_examples: "[]" - description: Array of stringified Lua code to be cached and run in sequence during access phase. - ---- - -## Plugin Names - -Serverless Functions come as two separate plugins. Each one runs with a -different priority in the plugin chain. - -- `pre-function` - - Runs before other plugins run during the access phase. -- `post-function` - - Runs after other plugins in the access phase. - -## Demonstration - -### With a Database - -1. Create a Service on Kong: - - ```bash - $ curl -i -X POST http://localhost:8001/services/ \ - --data "name=plugin-testing" \ - --data "url=http://httpbin.org/headers" - - HTTP/1.1 201 Created - ... - ``` - -2. Add a Route to the Service: - - ```bash - $ curl -i -X POST http://localhost:8001/services/plugin-testing/routes \ - --data "paths[]=/test" - - HTTP/1.1 201 Created - ... - ``` - -1. Create a file named `custom-auth.lua` with the following content: - - ```lua - -- Get list of request headers - local custom_auth = kong.request.get_header("x-custom-auth") - - -- Terminate request early if the custom authentication header - -- does not exist - if not custom_auth then - return kong.response.exit(401, "Invalid Credentials") - end - - -- Remove custom authentication header from request - kong.service.request.clear_header('x-custom-auth') - ``` - -4. Ensure the file contents: - - ```bash - $ cat custom-auth.lua - ``` - -5. Apply the Lua code using the `pre-function` plugin with a cURL file upload: - - ```bash - $ curl -i -X POST http://localhost:8001/services/plugin-testing/plugins \ - -F "name=pre-function" \ - -F "config.functions=@custom-auth.lua" - - HTTP/1.1 201 Created - ... - ``` - -6. Test that the Lua code will terminate the request when no header is passed: - - ```bash - curl -i -X GET http://localhost:8000/test - - HTTP/1.1 401 Unauthorized - ... - "Invalid Credentials" - ``` - -7. Test the Lua code you just applied by making a valid request: - - ```bash - curl -i -X GET http://localhost:8000/test \ - --header "x-custom-auth: demo" - - HTTP/1.1 200 OK - ... - ``` - -### Without a Database - -1. Create the Service, Route, and associated plugin on the declarative config file: - - ``` yaml - services: - - name: plugin-testing - url: http://httpbin.org/headers - - routes: - - service: plugin-testing - paths: [ "/test" ] - - plugins: - - name: pre-function - config: - functions: | - -- Get list of request headers - local custom_auth = kong.request.get_header("x-custom-auth") - - -- Terminate request early if the custom authentication header - -- does not exist - if not custom_auth then - return kong.response.exit(401, "Invalid Credentials") - end - - -- Remove custom authentication header from request - kong.service.request.clear_header('x-custom-auth') - ``` - -2. Test that the Lua code will terminate the request when no header is passed: - - ```bash - curl -i -X GET http://localhost:8000/test - - HTTP/1.1 401 Unauthorized - ... - "Invalid Credentials" - ``` - -3. Test the Lua code you just applied by making a valid request: - - ```bash - curl -i -X GET http://localhost:8000/test \ - --header "x-custom-auth: demo" - - HTTP/1.1 200 OK - ... - ``` ----- - -This is just a small demonstration of the power these plugins grant. You were -able to dynamically inject Lua code into the plugin access phase to dynamically -terminate, or transform the request without creating a custom plugin or -reloading/redeploying Kong. - -In summary, serverless functions give you the full capabilities of a custom plugin -in the access phase without the need to redeploy or restart Kong. - - -### Notes - -#### Upvalues - -Prior to version 0.3 of the plugin, the provided Lua code would run as the -function. From version 0.3 onwards, a function can also be returned, which allows -for upvalues. - -So the older version would do this (still works with 0.3 and above): - -```lua --- this entire block is executed on each request -ngx.log(ngx.ERR, "hello world") -``` - -With this version, you can return a function to run on each request, -allowing for upvalues to keep state in between requests: - -```lua --- this runs once when Kong starts -local count = 0 - -return function() - -- this runs on each request - count = count + 1 - ngx.log(ngx.ERR, "hello world: ", count) -end -``` - -#### Minifying Lua - -Because code is sent over in a string format, it is advisable to use either -cURL file upload `@file.lua` (see demonstration) or to minify your Lua code -using a [minifier][lua-minifier]. - - -[service-url]: https://getkong.org/docs/latest/admin-api/#service-object -[lua-minifier]: https://mothereff.in/lua-minifier diff --git a/app/_hub/kong-inc/serverless-functions/1.0-x.md b/app/_hub/kong-inc/serverless-functions/1.0-x.md deleted file mode 100644 index 4ca0bf593ee7..000000000000 --- a/app/_hub/kong-inc/serverless-functions/1.0-x.md +++ /dev/null @@ -1,306 +0,0 @@ ---- -name: Serverless Functions -publisher: Kong Inc. -version: 1.0-x - -source_url: https://github.com/Kong/kong-plugin-serverless-functions - -desc: Dynamically run Lua code from Kong -description: | - Dynamically run Lua code from Kong. - -
- Warning: The pre-function and post-function serverless plugin - allows anyone who can enable the plugin to execute arbitrary code. - If your organization has security concerns about this, disable the plugin - in your kong.conf file. -
- -type: plugin -categories: - - serverless - -kong_version_compatibility: - community_edition: - compatible: - - 2.2.x - - 2.1.x - enterprise_edition: - compatible: - - 2.2.x - - 2.1.x - - 1.5.x - -params: - name: pre-function OR post-function - service_id: true - route_id: true - consumer_id: false - protocols: ["http", "https"] - konnect_examples: false - dbless_compatible: partially - dbless_explanation: | - The functions will be executed, but if the configured functions attempt to write to the database, the writes will fail. - config: - - name: functions - required: false - default: "[]" - value_in_examples: "[]" - description: "*Deprecated*; use `config.access` instead. Array of stringified Lua code to be cached and run in sequence during access phase." - - name: certificate - required: false - default: "[]" - value_in_examples: "[]" - description: "Array of stringified Lua code to be cached and run in sequence during the certificate phase. *Note*: This only runs on global plugins." - - name: rewrite - required: false - default: "[]" - value_in_examples: "[]" - description: "Array of stringified Lua code to be cached and run in sequence during the rewrite phase. *Note*: This only runs on global plugins." - - name: access - required: false - default: "[]" - value_in_examples: "[]" - description: Array of stringified Lua code to be cached and run in sequence during the access phase. - - name: header_filter - required: false - default: "[]" - value_in_examples: "[]" - description: Array of stringified Lua code to be cached and run in sequence during the header_filter phase. - - name: body_filter - required: false - default: "[]" - value_in_examples: "[]" - description: Array of stringified Lua code to be cached and run in sequence during the body_filter phase. - - name: log - required: false - default: "[]" - value_in_examples: "[]" - description: Array of stringified Lua code to be cached and run in sequence during the log phase. - ---- - -## Plugin Names - -Serverless Functions come as two separate plugins. Each one runs with a -different priority in the plugin chain. - -- `pre-function` - - Runs before other plugins run during each phase. -- `post-function` - - Runs after other plugins in each phase. - -## Demonstration - -{% navtabs %} -{% navtab With a database %} - -1. Create a Service on Kong: - - ```bash - $ curl -i -X POST http://localhost:8001/services/ \ - --data "name=plugin-testing" \ - --data "url=http://httpbin.org/headers" - - HTTP/1.1 201 Created - ... - ``` - -2. Add a Route to the Service: - - ```bash - $ curl -i -X POST http://localhost:8001/services/plugin-testing/routes \ - --data "paths[]=/test" - - HTTP/1.1 201 Created - ... - ``` - -1. Create a file named `custom-auth.lua` with the following content: - - ```lua - -- Get list of request headers - local custom_auth = kong.request.get_header("x-custom-auth") - - -- Terminate request early if our custom authentication header - -- does not exist - if not custom_auth then - return kong.response.exit(401, "Invalid Credentials") - end - - -- Remove custom authentication header from request - kong.service.request.clear_header('x-custom-auth') - ``` - -4. Ensure the file contents: - - ```bash - $ cat custom-auth.lua - ``` - -5. Apply our Lua code using the `pre-function` plugin using cURL file upload: - - ```bash - $ curl -i -X POST http://localhost:8001/services/plugin-testing/plugins \ - -F "name=pre-function" \ - -F "config.access[1]=@custom-auth.lua" \ - -F "config.access[2]=kong.log.err('Hi there Access!')" \ - -F "config.header_filter[1]=kong.log.err('Hi there Header_Filter!')" \ - -F "config.body_filter[1]=kong.log.err('Hi there Body_Filter!')" \ - -F "config.log[1]=kong.log.err('Hi there Log!')" - - HTTP/1.1 201 Created - ... - ``` - -6. Test that our Lua code will terminate the request when no header is passed: - - ```bash - curl -i -X GET http://localhost:8000/test - - HTTP/1.1 401 Unauthorized - ... - "Invalid Credentials" - ``` - In the logs, there will be the following messages: - ``` - [pre-function] Hi there Header_Filter! - [pre-function] Hi there Body_Filter! - [pre-function] Hi there Body_Filter! - [pre-function] Hi there Log! - ``` - The "Access" message is missing because the first function in that phase does - an early exit, throwing the 401. Hence the subsequent functions are not executed. - -7. Test the Lua code we just applied by making a valid request: - - ```bash - curl -i -X GET http://localhost:8000/test \ - --header "x-custom-auth: demo" - - HTTP/1.1 200 OK - ... - ``` - Now the logs will also have the "Access" message. - -{% endnavtab %} -{% navtab Without a database %} - -1. Create the Service, Route and Associated plugin on the declarative config file: - - ``` yaml - services: - - name: plugin-testing - url: http://httpbin.org/headers - - routes: - - service: plugin-testing - paths: [ "/test" ] - - plugins: - - name: pre-function - config: - access: - - |2 - -- Get list of request headers - local custom_auth = kong.request.get_header("x-custom-auth") - - -- Terminate request early if the custom authentication header - -- does not exist - if not custom_auth then - return kong.response.exit(401, "Invalid Credentials") - end - - -- Remove custom authentication header from request - kong.service.request.clear_header('x-custom-auth') - - kong.log.err('Hi there Access!') - header_filter: - - kong.log.err('Hi there Header_Filter!') - body_filter: - - kong.log.err('Hi there Body_Filter!') - log: - - kong.log.err('Hi there Log!') - ``` - -2. Test that the Lua code will terminate the request when no header is passed: - - ```bash - curl -i -X GET http://localhost:8000/test - - HTTP/1.1 401 Unauthorized - ... - "Invalid Credentials" - ``` - The following messages will be in the logs: - ``` - [pre-function] Hi there Header_Filter! - [pre-function] Hi there Body_Filter! - [pre-function] Hi there Body_Filter! - [pre-function] Hi there Log! - ``` - The "Access" message is missing because the first function in that phase does - an early exit, throwing the 401. Hence the subsequent functions are not executed. - -3. Test the Lua code we just applied by making a valid request: - - ```bash - curl -i -X GET http://localhost:8000/test \ - --header "x-custom-auth: demo" - - HTTP/1.1 200 OK - ... - ``` - Now the logs will also have the "Access" message. - -{% endnavtab %} -{% endnavtabs %} - ----- - -This is just a small demonstration of the power these plugins grant. You were -able to dynamically inject Lua code into the plugin phases to dynamically -terminate, or transform the request without creating a custom plugin or -reloading / redeploying Kong. - -In summary, serverless functions give you the full capabilities of a custom plugin -without requiring redeploying or restarting Kong. - - -### Notes - -#### Upvalues - -Prior to version 0.3 of the plugin, the provided Lua code would run as the -function. From version 0.3 onwards also a function can be returned, to allow -for upvalues. - -So the older version would do this (still works with 0.3 and above): - -```lua --- this entire block is executed on each request -ngx.log(ngx.ERR, "hello world") -``` - -With this version you can return a function to run on each request, -allowing for upvalues to keep state in between requests: - -```lua --- this runs once on the first request -local count = 0 - -return function() - -- this runs on each request - count = count + 1 - ngx.log(ngx.ERR, "hello world: ", count) -end -``` - -#### Minifying Lua - -Since we send our code over in a string format, it is advisable to use either -curl file upload `@file.lua` (see demonstration) or to minify your Lua code -using a [minifier][lua-minifier]. - - -[service-url]: https://getkong.org/docs/latest/admin-api/#service-object -[lua-minifier]: https://mothereff.in/lua-minifier diff --git a/app/_hub/kong-inc/serverless-functions/_index.md b/app/_hub/kong-inc/serverless-functions/_index.md index 2aa3fa8b92fb..d91bea25fda2 100644 --- a/app/_hub/kong-inc/serverless-functions/_index.md +++ b/app/_hub/kong-inc/serverless-functions/_index.md @@ -1,8 +1,6 @@ --- name: Serverless Functions publisher: Kong Inc. -version: 2.0-x -source_url: 'https://github.com/Kong/kong-plugin-serverless-functions' desc: Dynamically run Lua code from Kong description: | Dynamically run Lua code from Kong. @@ -15,37 +13,20 @@ description: | - `post-function` - Runs after other plugins in each phase. The `post-function` plugin can be applied to individual services, routes, or globally. -
- Warning: The pre-function and post-function serverless plugin + {:.important} + > **Warning:** The pre-function and post-function serverless plugin allows anyone who can enable the plugin to execute arbitrary code. If your organization has security concerns about this, disable the plugin - in your kong.conf file. -
+ in your `kong.conf` file. + type: plugin categories: - serverless kong_version_compatibility: community_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x + compatible: true enterprise_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x + compatible: true params: name: pre-function OR post-function examples: false @@ -64,17 +45,27 @@ params: required: false default: '[]' value_in_examples: '[]' - description: '*Deprecated*; use `config.access` instead. Array of stringified Lua code to be cached and run in sequence during access phase.' + description: | + *Deprecated*. Use `config.access` instead. + + Array of stringified Lua code to be cached and run in sequence during access phase. + maximum_version: "2.8.x" - name: certificate required: false default: '[]' value_in_examples: '[]' - description: 'Array of stringified Lua code to be cached and run in sequence during the certificate phase. *Note*: This only runs on global plugins.' + description: | + Array of stringified Lua code to be cached and run in sequence during the certificate phase. + + *Note*: This only runs on global plugins. - name: rewrite required: false default: '[]' value_in_examples: '[]' - description: 'Array of stringified Lua code to be cached and run in sequence during the rewrite phase. *Note*: This only runs on global plugins.' + description: | + Array of stringified Lua code to be cached and run in sequence during the rewrite phase. + + *Note*: This only runs on global plugins. - name: access required: false default: '[]' @@ -97,30 +88,24 @@ params: description: Array of stringified Lua code to be cached and run in sequence during the log phase. --- -## Demonstration +## Usage {% navtabs %} {% navtab With a database %} -1. Create a Service on Kong: +1. Create a service on Kong: ```bash - $ curl -i -X POST http://localhost:8001/services/ \ + curl -i -X POST http://localhost:8001/services/ \ --data "name=plugin-testing" \ --data "url=http://httpbin.org/headers" - - HTTP/1.1 201 Created - ... ``` -2. Add a Route to the Service: +2. Add a route to the service: ```bash - $ curl -i -X POST http://localhost:8001/services/plugin-testing/routes \ + curl -i -X POST http://localhost:8001/services/plugin-testing/routes \ --data "paths[]=/test" - - HTTP/1.1 201 Created - ... ``` 1. Create a file named `custom-auth.lua` with the following content: @@ -142,20 +127,23 @@ params: 4. Ensure the file contents: ```bash - $ cat custom-auth.lua + cat custom-auth.lua ``` 5. Apply our Lua code using the `pre-function` plugin using cURL file upload: ```bash - $ curl -i -X POST http://localhost:8001/services/plugin-testing/plugins \ + curl -i -X POST http://localhost:8001/services/plugin-testing/plugins \ -F "name=pre-function" \ -F "config.access[1]=@custom-auth.lua" \ -F "config.access[2]=kong.log.err('Hi there Access!')" \ -F "config.header_filter[1]=kong.log.err('Hi there Header_Filter!')" \ -F "config.body_filter[1]=kong.log.err('Hi there Body_Filter!')" \ -F "config.log[1]=kong.log.err('Hi there Log!')" + ``` + Response: + ``` HTTP/1.1 201 Created ... ``` @@ -193,7 +181,7 @@ params: {% endnavtab %} {% navtab Without a database %} -1. Create the Service, Route and Associated plugin on the declarative config file: +1. Create the service, route, and associated plugin in the declarative config file: ``` yaml services: @@ -262,8 +250,6 @@ params: {% endnavtab %} {% endnavtabs %} ----- - This is just a small demonstration of the power these plugins grant. You were able to dynamically inject Lua code into the plugin phases to dynamically terminate, or transform the request without creating a custom plugin or @@ -272,29 +258,15 @@ reloading / redeploying Kong. In summary, serverless functions give you the full capabilities of a custom plugin without requiring redeploying or restarting Kong. +## Sandboxing -### Notes - -#### Sandboxing - -Starting with version 2.0 of the plugin, the provided Lua environment is sandboxed. +The provided Lua environment is sandboxed. {% include /md/plugins-hub/sandbox.md %} -#### Upvalues - -Prior to version 0.3 of the plugin, the provided Lua code would run as the -function. Since version 0.3 functions can be returned, to allow -the use of upvalues. +## Upvalues -So the older version would do this (still works with 0.3 and above): - -```lua --- this entire block is executed on each request -ngx.log(ngx.ERR, "hello world") -``` - -With this version you can return a function to run on each request, +You can return a function to run on each request, allowing for upvalues to keep state in between requests: ```lua @@ -308,7 +280,7 @@ return function() end ``` -#### Minifying Lua +## Minifying Lua Since we send our code over in a string format, it is advisable to use either curl file upload `@file.lua` (see demonstration) or to minify your Lua code @@ -317,3 +289,21 @@ using a [minifier][lua-minifier]. [service-url]: https://getkong.org/docs/latest/admin-api/#service-object [lua-minifier]: https://mothereff.in/lua-minifier + +--- + +## Changelog + +**{{site.base_gateway}} 3.0** + +* The deprecated `config.functions` parameter has been removed from the plugin. +Use `config.access` instead. +* The pre-function plugin changed priority from `+inf` to `1000000`. + +**{{site.base_gateway}} 2.3** + +* Introduced sandboxing, which is enabled by default. +Only the Kong PDK, OpenResty `ngx` APIs, and Lua standard libraries are allowed. +To change the default setting, see the Kong [configuration property reference](/gateway/latest/reference/configuration/#untrusted_lua). + + This change was also introduced into previous releases through patch versions: 1.5.0.9, 2.1.4.3, and 2.2.1.0. diff --git a/app/_hub/kong-inc/serverless-functions/versions.yml b/app/_hub/kong-inc/serverless-functions/versions.yml index 6fd81ffd39ba..53d063d38701 100644 --- a/app/_hub/kong-inc/serverless-functions/versions.yml +++ b/app/_hub/kong-inc/serverless-functions/versions.yml @@ -1,3 +1,12 @@ -- release: 2.0-x -- release: 1.0-x -- release: 0.1-x +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 2.1.0 + 2.7.x: 2.1.0 + 2.6.x: 2.1.0 + 2.5.x: 2.1.0 + 2.4.x: 2.1.0 + 2.3.x: 2.1.0 + 2.2.x: 2.1.0 + 2.1.x: 2.1.0 diff --git a/app/_hub/kong-inc/session/1.0-x.md b/app/_hub/kong-inc/session/1.0-x.md deleted file mode 100644 index d27dc35adc9d..000000000000 --- a/app/_hub/kong-inc/session/1.0-x.md +++ /dev/null @@ -1,332 +0,0 @@ ---- -name: Session -publisher: Kong Inc. -version: 1.0-x - -desc: Support sessions for Kong Authentication Plugins. -description: | - The Kong Session Plugin can be used to manage browser sessions for APIs proxied - through the Kong API Gateway. It provides configuration and management for - session data storage, encryption, renewal, expiry, and sending browser cookies. - It is built using - lua-resty-session - -type: plugin -categories: - - authentication - -source_url: https://github.com/Kong/kong-plugin-session - -kong_version_compatibility: - community_edition: - compatible: - - 1.0.x - - 0.15.x - - enterprise_edition: - compatible: - - 0.35-x - -params: - name: session - service_id: true - route_id: true - consumer_id: false - config: - - name: secret - required: false - default: random number generated from `kong.utils.random_string` - value_in_examples: opensesame - description: - The secret that is used in keyed HMAC generation.​ - - name: cookie_name - required: false - default: '`session`' - description: The name of the cookie - - name: cookie_lifetime - required: false - default: 3600 - description: The duration (in seconds) that the session will remain open - - name: cookie_renew - required: false - default: 600 - description: The duration (in seconds) of a session remaining at which point the Plugin renews the session - - name: cookie_path - required: false - default: "/" - description: The resource in the host where the cookie is available - - name: cookie_domain - required: false - default: Set using Nginx variable host, but may be overridden - description: The domain with which the cookie is intended to be exchanged - - name: cookie_samesite - required: false - default: "Strict" - description: 'Determines whether and how a cookie may be sent with cross-site requests. "Strict": the browser will send cookies only if the request originated from the website that set the cookie. "Lax": same-site cookies are withheld on cross-domain subrequests, but will be sent when a user navigates to the URL from an external site, for example, by following a link. "off": disables the same-site attribute so that a cookie may be sent with cross-site requests. https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#SameSite_cookies' - - name: cookie_httponly - required: false - default: true - description: Applies the `HttpOnly` tag so that the cookie is sent only to a server https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#Secure_and_HttpOnly_cookies - - name: cookie_secure - required: false - default: true - description: Applies the Secure directive so that the cookie may be sent to the server only with an encrypted request over the HTTPS protocol https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#Secure_and_HttpOnly_cookies - - name: cookie_discard - required: false - default: 10 - description: The duration (in seconds) after which an old session’s TTL is updated that an old cookie is discarded. - - name: storage - required: false - default: "cookie" - description: "Determines where the session data is stored. `kong`: stores encrypted session data into Kong's current database strategy (e.g. Postgres, Cassandra); the cookie will not contain any session data. `cookie`: stores encrypted session data within the cookie itself." - - name: logout_methods - required: false - default: '[`"POST"`, `"DELETE"`]' - description: 'The methods that may be used to end sessions: POST, DELETE, GET.' - - name: logout_query_arg - required: false - default: session_logout - description: The query argument passed to logout requests. - - name: logout_post_arg - required: false - default: session_logout - description: The post argument passed to logout requests. Do not change this property. - ---- - -## Usage - -The Kong Session **Plugin** can be configured globally or per entity (e.g., Service, Route) -and is always used in conjunction with another Kong Authentication **[Plugin]**. This -**Plugin** is intended to work similarly to the [multiple authentication] setup. - -Once the Kong Session **Plugin** is enabled in conjunction with an Authentication **Plugin**, -it will run prior to credential verification. If no session is found, then the -authentication **Plugin** will run and credentials will be checked as normal. If the -credential verification is successful, then the session **Plugin** will create a new -session for usage with subsequent requests. - -When a new request comes in, and a session is present, then the Kong Session -**Plugin** will attach the `ngx.ctx` variables to let the authentication -**Plugin** know that authentication has already occured via session validation. -Since this configuration is a logical OR scenario, it is desired that anonymous -access be forbidden, then the [Request Termination] **Plugin** should be -configured on an anonymous consumer. Failure to do so will allow unauthorized -requests. For more information please see section on [multiple authentication]. - -For usage with [Key Auth] **Plugin** - -1. Create an example Service and a Route - - Issue the following cURL request to create `example-service` pointing to - mockbin.org, which will echo the request: - - ```bash - $ curl -i -X POST \ - --url http://localhost:8001/services/ \ - --data 'name=example-service' \ - --data 'url=http://mockbin.org/request' - ``` - - Add a route to the Service: - - ```bash - $ curl -i -X POST \ - --url http://localhost:8001/services/example-service/routes \ - --data 'paths[]=/sessions-test' - ``` - - The url `http://localhost:8000/sessions-test` will now echo whatever is being - requested. - -1. Configure the key-auth **Plugin** for the Service - - Issue the following cURL request to add the key-auth **Plugin** to the Service: - - ```bash - $ curl -i -X POST \ - --url http://localhost:8001/services/example-service/plugins/ \ - --data 'name=key-auth' - ``` - - Be sure to note the created **Plugin** `id` - it will be needed later. - -1. Verify that the key-auth **Plugin** is properly configured - - Issue the following cURL request to verify that the [key-auth][key-auth] - **Plugin** was properly configured on the Service: - - ```bash - $ curl -i -X GET \ - --url http://localhost:8000/sessions-test - ``` - - Since the required header or parameter `apikey` was not specified, and - anonymous access was not yet enabled, the response should be `401 Unauthorized`: - -1. Create a Consumer and an anonymous Consumer - - Every request proxied and authenticated by Kong must be associated with a - Consumer. You'll now create a Consumer named `anonymous_users` by issuing - the following request: - - ```bash - $ curl -i -X POST \ - --url http://localhost:8001/consumers/ \ - --data "username=anonymous_users" - ``` - - Be sure to note the Consumer `id` - you'll need it in a later step. - - Now create a consumer that will authenticate via sessions - ```bash - $ curl -i -X POST \ - --url http://localhost:8001/consumers/ \ - --data "username=fiona" - ``` - -1. Provision key-auth credentials for your Consumer - - ```bash - $ curl -i -X POST \ - --url http://localhost:8001/consumers/fiona/key-auth/ \ - --data 'key=open_sesame' - ``` - -1. Enable anonymous access - - You'll now re-configure the key-auth **Plugin** to permit anonymous access by - issuing the following request (**replace the uuids below by the `id` value - from previous steps**): - - ```bash - $ curl -i -X PATCH \ - --url http://localhost:8001/plugins/ \ - --data "config.anonymous=" - ``` - -1. Add the Kong Session **Plugin** to the service - - ```bash - $ curl -X POST http://localhost:8001/services/example-service/plugins \ - --data "name=session" \ - --data "config.storage=kong" \ - --data "config.cookie_secure=false" - ``` - > Note: cookie_secure is true by default, and should always be true, but is set to - false for the sake of this demo in order to avoid using HTTPS. - -1. Add the Request Termination **Plugin** - - To disable anonymous access to only allow users access via sessions or via - authentication credentials, enable the Request Termination **Plugin**. - - ```bash - $ curl -X POST http://localhost:8001/services/example-service/plugins \ - --data "name=request-termination" \ - --data "config.status_code=403" \ - --data "config.message=So long and thanks for all the fish!" \ - --data "consumer.id=" - ``` - - Anonymous requests now will return status `403`. - - ```bash - $ curl -i -X GET \ - --url http://localhost:8000/sessions-test - ``` - - Should return `403`. - -1. Verify that the session **Plugin** is properly configured - - ```bash - $ curl -i -X GET \ - --url http://localhost:8000/sessions-test?apikey=open_sesame - ``` - - The response should now have the `Set-Cookie` header. Make sure that this - cookie works. - - If cookie looks like this: - ``` - Set-Cookie: session=emjbJ3MdyDsoDUkqmemFqw..|1544654411|4QMKAE3I-jFSgmvjWApDRmZHMB8.; Path=/; SameSite=Strict; HttpOnly - ``` - - Use it like this: - - ```bash - $ curl -i -X GET \ - --url http://localhost:8000/sessions-test \ - -H "cookie:session=emjbJ3MdyDsoDUkqmemFqw..|1544654411|4QMKAE3I-jFSgmvjWApDRmZHMB8." - ``` - - This request should succeed, and `Set-Cookie` response header will not appear - until renewal period. - -1. You can also now verify cookie is attached to browser session: Navigate to - http://localhost:8000/sessions-test which should return `403` - and see the message "So long and thanks for all the fish!" -1. In same browser session, navigate to http://localhost:8000/sessions-test?apikey=open_sesame - which should return `200`, authenticated via key-auth key query param. -1. In same browser session, navigate to http://localhost:8000/sessions-test, - which will now use the session cookie that was granted by the Kong Session - **Plugin**. - -### Defaults - -By default, the Kong Session **Plugin** favors security using a `Secure`, `HTTPOnly`, -`Samesite=Strict` cookie. `cookie_domain` is automatically set using Nginx -variable host, but can be overridden. - -### Session Data Storage - -The session data can be stored in the cookie itself (encrypted) `storage=cookie`, -or inside [Kong](#kong-storage-adapter). The session data stores two context -variables: - -``` -ngx.ctx.authenticated_consumer.id -ngx.ctx.authenticated_credential.id -``` - -## Kong Storage Adapter - -The Kong Session **Plugin** extends the functionality of [lua-resty-session] with its own -session data storage adapter when `storage=kong`. This will store encrypted -session data into the current database strategy (e.g. postgres, cassandra etc.) -and the cookie will not contain any session data. Data stored in the database is -encrypted and the cookie will contain only the session id, expiration time and -HMAC signature. Sessions will use the built-in Kong DAO `ttl` mechanism which destroys -sessions after specified `cookie_lifetime` unless renewal occurs during normal -browser activity. It is recommended that the application logout via XHR request -(or something similar) to manually handle redirects. - -## Logging Out - -It is typical to provide users the ability to log out (i.e. to manually destroy) their -current session. Logging out is possible with either query params or `POST` params in -the request URL. The config's `logout_methods` allows the **Plugin** to limit logging -out based on the HTTP verb. When `logout_query_arg` is set, it will check the -presence of the URL query param specified, and likewise when `logout_post_arg` -is set it will check the presence of the specified variable in the request body. -Allowed HTTP verbs are `GET`, `DELETE`, and `POST`. When there is a session -present and the incoming request is a logout request, the Kong Session **Plugin** will -return a 200 before continuing in the **Plugin** run loop, and the request will not -continue to the upstream. - -## Known Limitations - -Due to limitations of OpenResty, the `header_filter` phase cannot connect to the -database, which poses a problem for initial retrieval of cookie (fresh session). -There is a small window of time where cookie is sent to client, but database -insert has not yet been committed, as database call is in `ngx.timer` thread. -Current workaround is to wait some interval of time (~100-500ms) after -`Set-Cookie` header is sent to client before making subsequent requests. This is -_not_ a problem during session renewal period as renew happens in `access` phase. - -[Plugin]: https://docs.konghq.com/hub/ -[lua-resty-session]: https://github.com/bungle/lua-resty-session -[multiple authentication]: https://docs.konghq.com/0.14.x/auth/#multiple-authentication -[Key Auth]: https://docs.konghq.com/hub/kong-inc/key-auth/ -[Request Termination]: https://docs.konghq.com/hub/kong-inc/request-termination/ diff --git a/app/_hub/kong-inc/session/1.2-x.md b/app/_hub/kong-inc/session/1.2-x.md deleted file mode 100644 index c8e9b1ceffee..000000000000 --- a/app/_hub/kong-inc/session/1.2-x.md +++ /dev/null @@ -1,376 +0,0 @@ ---- -name: Session -publisher: Kong Inc. -version: 2.0.0-x - -desc: Support sessions for Kong Authentication Plugins. -description: | - The Kong Session Plugin can be used to manage browser sessions for APIs proxied - through the Kong API Gateway. It provides configuration and management for - session data storage, encryption, renewal, expiry, and sending browser cookies. - It is built using - lua-resty-session - -type: plugin -categories: - - authentication - -source_url: https://github.com/Kong/kong-plugin-session - -kong_version_compatibility: - community_edition: - compatible: - - 1.2.x - -params: - name: session - service_id: true - route_id: true - consumer_id: false - config: - - name: secret - required: false - default: random number generated from `kong.utils.random_string` - value_in_examples: opensesame - description: The secret that is used in keyed HMAC generation.​ - - name: cookie_name - required: false - default: '`session`' - description: The name of the cookie - - name: cookie_lifetime - required: false - default: 3600 - description: The duration (in seconds) that the session will remain open - - name: cookie_renew - required: false - default: 600 - description: The duration (in seconds) of a session remaining at which point the Plugin renews the session - - name: cookie_path - required: false - default: '/' - description: The resource in the host where the cookie is available - - name: cookie_domain - required: false - default: Set using Nginx variable host, but may be overridden - description: The domain with which the cookie is intended to be exchanged - - name: cookie_samesite - required: false - default: 'Strict' - description: 'Determines whether and how a cookie may be sent with cross-site requests. "Strict": the browser will send cookies only if the request originated from the website that set the cookie. "Lax": same-site cookies are withheld on cross-domain subrequests, but will be sent when a user navigates to the URL from an external site, for example, by following a link. "off": disables the same-site attribute so that a cookie may be sent with cross-site requests. https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#SameSite_cookies' - - name: cookie_httponly - required: false - default: true - description: Applies the `HttpOnly` tag so that the cookie is sent only to a server https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#Secure_and_HttpOnly_cookies - - name: cookie_secure - required: false - default: true - description: Applies the Secure directive so that the cookie may be sent to the server only with an encrypted request over the HTTPS protocol https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#Secure_and_HttpOnly_cookies - - name: cookie_discard - required: false - default: 10 - description: The duration (in seconds) after which an old session’s TTL is updated that an old cookie is discarded. - - name: storage - required: false - default: 'cookie' - description: "Determines where the session data is stored. `kong`: stores encrypted session data into Kong's current database strategy (e.g. Postgres, Cassandra); the cookie will not contain any session data. `cookie`: stores encrypted session data within the cookie itself." - - name: logout_methods - required: false - default: '[`"POST"`, `"DELETE"`]' - description: 'The methods that may be used to end sessions: POST, DELETE, GET.' - - name: logout_query_arg - required: false - default: session_logout - description: The query argument passed to logout requests. - - name: logout_post_arg - required: false - default: session_logout - description: The post argument passed to logout requests. Do not change this property. ---- - -## Usage - -The Kong Session **Plugin** can be configured globally or per entity (e.g., Service, Route) -and is always used in conjunction with another Kong Authentication **[Plugin]**. This -**Plugin** is intended to work similarly to the [multiple authentication] setup. - -Once the Kong Session **Plugin** is enabled in conjunction with an Authentication **Plugin**, -it will run prior to credential verification. If no session is found, then the -authentication **Plugin** will run and credentials will be checked as normal. If the -credential verification is successful, then the session **Plugin** will create a new -session for usage with subsequent requests. - -When a new request comes in, and a session is present, then the Kong Session -**Plugin** will attach the `ngx.ctx` variables to let the authentication -**Plugin** know that authentication has already occured via session validation. -Since this configuration is a logical OR scenario, it is desired that anonymous -access be forbidden, then the [Request Termination] **Plugin** should be -configured on an anonymous consumer. Failure to do so will allow unauthorized -requests. For more information please see section on [multiple authentication]. - -### Setup With a Database - -For usage with [Key Auth] **Plugin** - -1. Create an example Service and a Route - - Issue the following cURL request to create `example-service` pointing to - mockbin.org, which will echo the request: - - ```bash - $ curl -i -X POST \ - --url http://localhost:8001/services/ \ - --data 'name=example-service' \ - --data 'url=http://mockbin.org/request' - ``` - - Add a route to the Service: - - ```bash - $ curl -i -X POST \ - --url http://localhost:8001/services/example-service/routes \ - --data 'paths[]=/sessions-test' - ``` - - The url `http://localhost:8000/sessions-test` will now echo whatever is being - requested. - -1. Configure the key-auth **Plugin** for the Service - - Issue the following cURL request to add the key-auth **Plugin** to the Service: - - ```bash - $ curl -i -X POST \ - --url http://localhost:8001/services/example-service/plugins/ \ - --data 'name=key-auth' - ``` - - Be sure to note the created **Plugin** `id` - it will be needed later. - -1. Verify that the key-auth **Plugin** is properly configured - - Issue the following cURL request to verify that the [key-auth][key-auth] - **Plugin** was properly configured on the Service: - - ```bash - $ curl -i -X GET \ - --url http://localhost:8000/sessions-test - ``` - - Since the required header or parameter `apikey` was not specified, and - anonymous access was not yet enabled, the response should be `401 Unauthorized`: - -1. Create a Consumer and an anonymous Consumer - - Every request proxied and authenticated by Kong must be associated with a - Consumer. You'll now create a Consumer named `anonymous_users` by issuing - the following request: - - ```bash - $ curl -i -X POST \ - --url http://localhost:8001/consumers/ \ - --data "username=anonymous_users" - ``` - - Be sure to note the Consumer `id` - you'll need it in a later step. - - Now create a consumer that will authenticate via sessions - - ```bash - $ curl -i -X POST \ - --url http://localhost:8001/consumers/ \ - --data "username=fiona" - ``` - -1. Provision key-auth credentials for your Consumer - - ```bash - $ curl -i -X POST \ - --url http://localhost:8001/consumers/fiona/key-auth/ \ - --data 'key=open_sesame' - ``` - -1. Enable anonymous access - - You'll now re-configure the key-auth **Plugin** to permit anonymous access by - issuing the following request (**replace the uuids below by the `id` value - from previous steps**): - - ```bash - $ curl -i -X PATCH \ - --url http://localhost:8001/plugins/ \ - --data "config.anonymous=" - ``` - -1. Add the Kong Session **Plugin** to the service - - ```bash - $ curl -X POST http://localhost:8001/services/example-service/plugins \ - --data "name=session" \ - --data "config.storage=kong" \ - --data "config.cookie_secure=false" - ``` - - > Note: cookie_secure is true by default, and should always be true, but is set to - > false for the sake of this demo in order to avoid using HTTPS. - -1. Add the Request Termination **Plugin** - - To disable anonymous access to only allow users access via sessions or via - authentication credentials, enable the Request Termination **Plugin**. - - ```bash - $ curl -X POST http://localhost:8001/services/example-service/plugins \ - --data "name=request-termination" \ - --data "config.status_code=403" \ - --data "config.message=So long and thanks for all the fish!" \ - --data "consumer.id=" - ``` - -### Setup Without a Database - -Add all these to the declarative config file: - -```yaml -services: - - name: example-service - url: http://mockbin.org/request - -routes: - - service: example-service - paths: ['/sessions-test'] - -consumers: - - username: anonymous_users - # manually set to fixed uuid in order to use it in key-auth plugin - id: 81823632-10c0-4098-a4f7-31062520c1e6 - - username: fiona - -keyauth_credentials: - - consumer: fiona - key: open_sesame - -plugins: - - name: key-auth - service: example-service - config: - # using the anonymous consumer fixed uuid (can't use the username) - anonymous: 81823632-10c0-4098-a4f7-31062520c1e6 - # cookie_secure is true by default, and should always be true, - # but is set to false for the sake of this demo in order to avoid using HTTPS. - cookie_secure: false - - name: session - config: - storage: kong - cookie_secure: false - - name: request-termination - service: example-service - consumer: anonymous_users - config: - status_code: 403 - message: 'So long and thanks for all the fish!' -``` - -### Verification - -1. Check that Anonymous requests are disabled - - ```bash - $ curl -i -X GET \ - --url http://localhost:8000/sessions-test - ``` - - Should return `403`. - -2. Verify that a user can authenticate via sessions - - ```bash - $ curl -i -X GET \ - --url http://localhost:8000/sessions-test?apikey=open_sesame - ``` - - The response should now have the `Set-Cookie` header. Make sure that this - cookie works. - - If cookie looks like this: - - ``` - Set-Cookie: session=emjbJ3MdyDsoDUkqmemFqw..|1544654411|4QMKAE3I-jFSgmvjWApDRmZHMB8.; Path=/; SameSite=Strict; HttpOnly - ``` - - Use it like this: - - ```bash - $ curl -i -X GET \ - --url http://localhost:8000/sessions-test \ - -H "cookie:session=emjbJ3MdyDsoDUkqmemFqw..|1544654411|4QMKAE3I-jFSgmvjWApDRmZHMB8." - ``` - - This request should succeed, and `Set-Cookie` response header will not appear - until renewal period. - -3. You can also now verify cookie is attached to browser session: Navigate to - http://localhost:8000/sessions-test which should return `403` - and see the message "So long and thanks for all the fish!" -4. In same browser session, navigate to http://localhost:8000/sessions-test?apikey=open_sesame - which should return `200`, authenticated via key-auth key query param. -5. In same browser session, navigate to http://localhost:8000/sessions-test, - which will now use the session cookie that was granted by the Kong Session - **Plugin**. - -### Defaults - -By default, the Kong Session **Plugin** favors security using a `Secure`, `HTTPOnly`, -`Samesite=Strict` cookie. `cookie_domain` is automatically set using Nginx -variable host, but can be overridden. - -### Session Data Storage - -The session data can be stored in the cookie itself (encrypted) `storage=cookie`, -or inside [Kong](#kong-storage-adapter). The session data stores two context -variables: - -``` -ngx.ctx.authenticated_consumer.id -ngx.ctx.authenticated_credential.id -``` - -## Kong Storage Adapter - -The Kong Session **Plugin** extends the functionality of [lua-resty-session] with its own -session data storage adapter when `storage=kong`. This will store encrypted -session data into the current database strategy (e.g. postgres, cassandra etc.) -and the cookie will not contain any session data. Data stored in the database is -encrypted and the cookie will contain only the session id, expiration time and -HMAC signature. Sessions will use the built-in Kong DAO `ttl` mechanism which destroys -sessions after specified `cookie_lifetime` unless renewal occurs during normal -browser activity. It is recommended that the application logout via XHR request -(or something similar) to manually handle redirects. - -## Logging Out - -It is typical to provide users the ability to log out (i.e. to manually destroy) their -current session. Logging out is possible with either query params or `POST` params in -the request URL. The config's `logout_methods` allows the **Plugin** to limit logging -out based on the HTTP verb. When `logout_query_arg` is set, it will check the -presence of the URL query param specified, and likewise when `logout_post_arg` -is set it will check the presence of the specified variable in the request body. -Allowed HTTP verbs are `GET`, `DELETE`, and `POST`. When there is a session -present and the incoming request is a logout request, the Kong Session **Plugin** will -return a 200 before continuing in the **Plugin** run loop, and the request will not -continue to the upstream. - -## Known Limitations - -Due to limitations of OpenResty, the `header_filter` phase cannot connect to the -database, which poses a problem for initial retrieval of cookie (fresh session). -There is a small window of time where cookie is sent to client, but database -insert has not yet been committed, as database call is in `ngx.timer` thread. -Current workaround is to wait some interval of time (~100-500ms) after -`Set-Cookie` header is sent to client before making subsequent requests. This is -_not_ a problem during session renewal period as renew happens in `access` phase. - -[plugin]: https://docs.konghq.com/hub/ -[lua-resty-session]: https://github.com/bungle/lua-resty-session -[multiple authentication]: https://docs.konghq.com/0.14.x/auth/#multiple-authentication -[key auth]: https://docs.konghq.com/hub/kong-inc/key-auth/ -[request termination]: https://docs.konghq.com/hub/kong-inc/request-termination/ diff --git a/app/_hub/kong-inc/session/2.2-x.md b/app/_hub/kong-inc/session/2.2-x.md deleted file mode 100644 index c53824641737..000000000000 --- a/app/_hub/kong-inc/session/2.2-x.md +++ /dev/null @@ -1,400 +0,0 @@ ---- -name: Session -publisher: Kong Inc. -version: 2.2.0-x - -desc: Support sessions for Kong Authentication Plugins. -description: | - The Kong Session Plugin can be used to manage browser sessions for APIs proxied - through the Kong API Gateway. It provides configuration and management for - session data storage, encryption, renewal, expiry, and sending browser cookies. - It is built using - lua-resty-session. - - For information about configuring and using the Sessions plugin with the Dev - Portal, see [Sessions in the Dev Portal](/gateway/latest/developer-portal/configuration/authentication/sessions/#configuration-to-use-the-sessions-plugin-with-the-dev-portal). - -type: plugin -categories: - - authentication - -source_url: https://github.com/Kong/kong-plugin-session - -kong_version_compatibility: - community_edition: - compatible: - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - enterprise_edition: - compatible: - - 1.5.x - - 1.3-x - - 0.36-x - - 0.35-x - -params: - name: session - service_id: true - route_id: true - consumer_id: false - config: - - name: secret - required: false - default: random number generated from `kong.utils.random_string` - value_in_examples: opensesame - description: The secret that is used in keyed HMAC generation.​ - - name: cookie_name - required: false - default: '`session`' - description: The name of the cookie - - name: cookie_lifetime - required: false - default: 3600 - description: The duration (in seconds) that the session will remain open - - name: cookie_renew - required: false - default: 600 - description: The duration (in seconds) of a session remaining at which point the Plugin renews the session - - name: cookie_path - required: false - default: '/' - description: The resource in the host where the cookie is available - - name: cookie_domain - required: false - default: Set using Nginx variable host, but may be overridden - description: The domain with which the cookie is intended to be exchanged - - name: cookie_samesite - required: false - default: 'Strict' - description: 'Determines whether and how a cookie may be sent with cross-site requests. "Strict": the browser will send cookies only if the request originated from the website that set the cookie. "Lax": same-site cookies are withheld on cross-domain subrequests, but will be sent when a user navigates to the URL from an external site, for example, by following a link. "off": disables the same-site attribute so that a cookie may be sent with cross-site requests. https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#SameSite_cookies' - - name: cookie_httponly - required: false - default: true - description: Applies the `HttpOnly` tag so that the cookie is sent only to a server https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#Secure_and_HttpOnly_cookies - - name: cookie_secure - required: false - default: true - description: Applies the Secure directive so that the cookie may be sent to the server only with an encrypted request over the HTTPS protocol https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#Secure_and_HttpOnly_cookies - - name: cookie_discard - required: false - default: 10 - description: The duration (in seconds) after which an old session’s TTL is updated that an old cookie is discarded. - - name: storage - required: false - default: 'cookie' - description: "Determines where the session data is stored. `kong`: stores encrypted session data into Kong's current database strategy (e.g. Postgres, Cassandra); the cookie will not contain any session data. `cookie`: stores encrypted session data within the cookie itself." - - name: logout_methods - required: false - default: '[`"POST"`, `"DELETE"`]' - description: 'The methods that may be used to end sessions: POST, DELETE, GET.' - - name: logout_query_arg - required: false - default: session_logout - description: The query argument passed to logout requests. - - name: logout_post_arg - required: false - default: session_logout - description: The post argument passed to logout requests. Do not change this property. ---- - -## Usage - -The Kong Session **Plugin** can be configured globally or per entity (e.g., Service, Route) -and is always used in conjunction with another Kong Authentication **[Plugin]**. This -**Plugin** is intended to work similarly to the [multiple authentication] setup. - -Once the Kong Session **Plugin** is enabled in conjunction with an Authentication **Plugin**, -it will run prior to credential verification. If no session is found, then the -authentication **Plugin** will run and credentials will be checked as normal. If the -credential verification is successful, then the session **Plugin** will create a new -session for usage with subsequent requests. - -When a new request comes in, and a session is present, then the Kong Session -**Plugin** will attach the `ngx.ctx` variables to let the authentication -**Plugin** know that authentication has already occured via session validation. -Since this configuration is a logical OR scenario, it is desired that anonymous -access be forbidden, then the [Request Termination] **Plugin** should be -configured on an anonymous consumer. Failure to do so will allow unauthorized -requests. For more information please see section on [multiple authentication]. - -### Setup With a Database - -For usage with [Key Auth] **Plugin** - -1. Create an example Service and a Route - - Issue the following cURL request to create `example-service` pointing to - mockbin.org, which will echo the request: - - ```bash - $ curl -i -X POST \ - --url http://localhost:8001/services/ \ - --data 'name=example-service' \ - --data 'url=http://mockbin.org/request' - ``` - - Add a route to the Service: - - ```bash - $ curl -i -X POST \ - --url http://localhost:8001/services/example-service/routes \ - --data 'paths[]=/sessions-test' - ``` - - The url `http://localhost:8000/sessions-test` will now echo whatever is being - requested. - -1. Configure the key-auth **Plugin** for the Service - - Issue the following cURL request to add the key-auth **Plugin** to the Service: - - ```bash - $ curl -i -X POST \ - --url http://localhost:8001/services/example-service/plugins/ \ - --data 'name=key-auth' - ``` - - Be sure to note the created **Plugin** `id` - it will be needed later. - -1. Verify that the key-auth **Plugin** is properly configured - - Issue the following cURL request to verify that the [key-auth][key-auth] - **Plugin** was properly configured on the Service: - - ```bash - $ curl -i -X GET \ - --url http://localhost:8000/sessions-test - ``` - - Since the required header or parameter `apikey` was not specified, and - anonymous access was not yet enabled, the response should be `401 Unauthorized`: - -1. Create a Consumer and an anonymous Consumer - - Every request proxied and authenticated by Kong must be associated with a - Consumer. You'll now create a Consumer named `anonymous_users` by issuing - the following request: - - ```bash - $ curl -i -X POST \ - --url http://localhost:8001/consumers/ \ - --data "username=anonymous_users" - ``` - - Be sure to note the Consumer `id` - you'll need it in a later step. - - Now create a consumer that will authenticate via sessions - - ```bash - $ curl -i -X POST \ - --url http://localhost:8001/consumers/ \ - --data "username=fiona" - ``` - -1. Provision key-auth credentials for your Consumer - - ```bash - $ curl -i -X POST \ - --url http://localhost:8001/consumers/fiona/key-auth/ \ - --data 'key=open_sesame' - ``` - -1. Enable anonymous access - - You'll now re-configure the key-auth **Plugin** to permit anonymous access by - issuing the following request (**replace the uuids below by the `id` value - from previous steps**): - - ```bash - $ curl -i -X PATCH \ - --url http://localhost:8001/plugins/ \ - --data "config.anonymous=" - ``` - -1. Add the Kong Session **Plugin** to the service - - ```bash - $ curl -X POST http://localhost:8001/services/example-service/plugins \ - --data "name=session" \ - --data "config.storage=kong" \ - --data "config.cookie_secure=false" - ``` - - > Note: cookie_secure is true by default, and should always be true, but is set to - > false for the sake of this demo in order to avoid using HTTPS. - -1. Add the Request Termination **Plugin** - - To disable anonymous access to only allow users access via sessions or via - authentication credentials, enable the Request Termination **Plugin**. - - ```bash - $ curl -X POST http://localhost:8001/services/example-service/plugins \ - --data "name=request-termination" \ - --data "config.status_code=403" \ - --data "config.message=So long and thanks for all the fish!" \ - --data "consumer.id=" - ``` - -### Setup Without a Database - -Add all these to the declarative config file: - -```yaml -services: - - name: example-service - url: http://mockbin.org/request - -routes: - - service: example-service - paths: ['/sessions-test'] - -consumers: - - username: anonymous_users - # manually set to fixed uuid in order to use it in key-auth plugin - id: 81823632-10c0-4098-a4f7-31062520c1e6 - - username: fiona - -keyauth_credentials: - - consumer: fiona - key: open_sesame - -plugins: - - name: key-auth - service: example-service - config: - # using the anonymous consumer fixed uuid (can't use the username) - anonymous: 81823632-10c0-4098-a4f7-31062520c1e6 - # cookie_secure is true by default, and should always be true, - # but is set to false for the sake of this demo in order to avoid using HTTPS. - cookie_secure: false - - name: session - config: - storage: kong - cookie_secure: false - - name: request-termination - service: example-service - consumer: anonymous_users - config: - status_code: 403 - message: 'So long and thanks for all the fish!' -``` - -### Verification - -1. Check that Anonymous requests are disabled - - ```bash - $ curl -i -X GET \ - --url http://localhost:8000/sessions-test - ``` - - Should return `403`. - -2. Verify that a user can authenticate via sessions - - ```bash - $ curl -i -X GET \ - --url http://localhost:8000/sessions-test?apikey=open_sesame - ``` - - The response should now have the `Set-Cookie` header. Make sure that this - cookie works. - - If cookie looks like this: - - ``` - Set-Cookie: session=emjbJ3MdyDsoDUkqmemFqw..|1544654411|4QMKAE3I-jFSgmvjWApDRmZHMB8.; Path=/; SameSite=Strict; HttpOnly - ``` - - Use it like this: - - ```bash - $ curl -i -X GET \ - --url http://localhost:8000/sessions-test \ - -H "cookie:session=emjbJ3MdyDsoDUkqmemFqw..|1544654411|4QMKAE3I-jFSgmvjWApDRmZHMB8." - ``` - - This request should succeed, and `Set-Cookie` response header will not appear - until renewal period. - -3. You can also now verify cookie is attached to browser session: Navigate to - http://localhost:8000/sessions-test which should return `403` - and see the message "So long and thanks for all the fish!" -4. In same browser session, navigate to http://localhost:8000/sessions-test?apikey=open_sesame - which should return `200`, authenticated via key-auth key query param. -5. In same browser session, navigate to http://localhost:8000/sessions-test, - which will now use the session cookie that was granted by the Kong Session - **Plugin**. - -### Defaults - -By default, the Kong Session **Plugin** favors security using a `Secure`, `HTTPOnly`, -`Samesite=Strict` cookie. `cookie_domain` is automatically set using Nginx -variable host, but can be overridden. - -### Session Data Storage - -The session data can be stored in the cookie itself (encrypted) `storage=cookie`, -or inside [Kong](#kong-storage-adapter). The session data stores these context -variables: - -``` -ngx.ctx.authenticated_consumer.id -ngx.ctx.authenticated_credential.id -ngx.ctx.authenticated_groups -``` - -The plugin also sets a `ngx.ctx.authenticated_session` for communication between -the `access` and `header_filter` phases in the plugin. - -### Groups - -Authenticated groups are stored on `ngx.ctx.authenticated_groups` from other -authentication plugins and the session plugin will store them in the data of -the current session. Since the session plugin runs before authentication -plugins, it will also set `authenticated_groups` associated headers. - -## Kong Storage Adapter - -The Kong Session **Plugin** extends the functionality of [lua-resty-session] with its own -session data storage adapter when `storage=kong`. This will store encrypted -session data into the current database strategy (e.g. postgres, cassandra etc.) -and the cookie will not contain any session data. Data stored in the database is -encrypted and the cookie will contain only the session id, expiration time and -HMAC signature. Sessions will use the built-in Kong DAO `ttl` mechanism which destroys -sessions after specified `cookie_lifetime` unless renewal occurs during normal -browser activity. It is recommended that the application logout via XHR request -(or something similar) to manually handle redirects. - -## Logging Out - -It is typical to provide users the ability to log out (i.e. to manually destroy) their -current session. Logging out is possible with either query params or `POST` params in -the request URL. The config's `logout_methods` allows the **Plugin** to limit logging -out based on the HTTP verb. When `logout_query_arg` is set, it will check the -presence of the URL query param specified, and likewise when `logout_post_arg` -is set it will check the presence of the specified variable in the request body. -Allowed HTTP verbs are `GET`, `DELETE`, and `POST`. When there is a session -present and the incoming request is a logout request, the Kong Session **Plugin** will -return a 200 before continuing in the **Plugin** run loop, and the request will not -continue to the upstream. - -## Known Limitations - -Due to limitations of OpenResty, the `header_filter` phase cannot connect to the -database, which poses a problem for initial retrieval of cookie (fresh session). -There is a small window of time where cookie is sent to client, but database -insert has not yet been committed, as database call is in `ngx.timer` thread. -Current workaround is to wait some interval of time (~100-500ms) after -`Set-Cookie` header is sent to client before making subsequent requests. This is -_not_ a problem during session renewal period as renew happens in `access` phase. - -[plugin]: https://docs.konghq.com/hub/ -[lua-resty-session]: https://github.com/bungle/lua-resty-session -[multiple authentication]: https://docs.konghq.com/0.14.x/auth/#multiple-authentication -[key auth]: https://docs.konghq.com/hub/kong-inc/key-auth/ -[request termination]: https://docs.konghq.com/hub/kong-inc/request-termination/ diff --git a/app/_hub/kong-inc/session/_index.md b/app/_hub/kong-inc/session/_index.md index eafddf42b3d4..a3623dee44e8 100644 --- a/app/_hub/kong-inc/session/_index.md +++ b/app/_hub/kong-inc/session/_index.md @@ -1,7 +1,6 @@ --- name: Session publisher: Kong Inc. -version: 2.4.x desc: Support sessions for Kong Authentication Plugins. description: | The Kong Session Plugin can be used to manage browser sessions for APIs proxied @@ -15,28 +14,11 @@ description: | type: plugin categories: - authentication -source_url: 'https://github.com/Kong/kong-plugin-session' kong_version_compatibility: community_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x + compatible: true enterprise_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x + compatible: true params: name: session service_id: true @@ -54,7 +36,12 @@ params: value_in_examples: opensesame datatype: string encrypted: true - description: The secret that is used in keyed HMAC generation.​ + description: | + The secret that is used in keyed HMAC generation.​ + + This field is _referenceable_, which means it can be securely stored as a + [secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) + in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). - name: cookie_name required: false default: '`session`' @@ -174,7 +161,7 @@ For usage with [Key Auth] plugin mockbin.org, which echoes the request: ```bash - $ curl -i -X POST \ + curl -i -X POST \ --url http://localhost:8001/services/ \ --data 'name=example-service' \ --data 'url=http://mockbin.org/request' @@ -183,7 +170,7 @@ For usage with [Key Auth] plugin Add a route to the Service: ```bash - $ curl -i -X POST \ + curl -i -X POST \ --url http://localhost:8001/services/example-service/routes \ --data 'paths[]=/sessions-test' ``` @@ -196,7 +183,7 @@ For usage with [Key Auth] plugin Issue the following cURL request to add the key-auth plugin to the Service: ```bash - $ curl -i -X POST \ + curl -i -X POST \ --url http://localhost:8001/services/example-service/plugins/ \ --data 'name=key-auth' ``` @@ -209,7 +196,7 @@ For usage with [Key Auth] plugin plugin is properly configured on the Service: ```bash - $ curl -i -X GET \ + curl -i -X GET \ --url http://localhost:8000/sessions-test ``` @@ -223,7 +210,7 @@ For usage with [Key Auth] plugin the following request: ```bash - $ curl -i -X POST \ + curl -i -X POST \ --url http://localhost:8001/consumers/ \ --data "username=anonymous_users" ``` @@ -233,7 +220,7 @@ For usage with [Key Auth] plugin Now create a consumer that authenticates via sessions: ```bash - $ curl -i -X POST \ + curl -i -X POST \ --url http://localhost:8001/consumers/ \ --data "username=fiona" ``` @@ -241,7 +228,7 @@ For usage with [Key Auth] plugin 1. Provision `key-auth` credentials for your Consumer ```bash - $ curl -i -X POST \ + curl -i -X POST \ --url http://localhost:8001/consumers/fiona/key-auth/ \ --data 'key=open_sesame' ``` @@ -249,11 +236,11 @@ For usage with [Key Auth] plugin 1. Enable anonymous access You can now re-configure the key-auth plugin to permit anonymous access by - issuing the following request (**replace the uuids below with the `id` value + issuing the following request (**replace the UUIDs below with the `id` value from previous steps**): ```bash - $ curl -i -X PATCH \ + curl -i -X PATCH \ --url http://localhost:8001/plugins/ \ --data "config.anonymous=" ``` @@ -261,10 +248,10 @@ For usage with [Key Auth] plugin 1. Add the Kong Session plugin to the service ```bash - $ curl -X POST http://localhost:8001/services/example-service/plugins \ - --data "name=session" \ - --data "config.storage=kong" \ - --data "config.cookie_secure=false" + curl -X POST http://localhost:8001/services/example-service/plugins \ + --data "name=session" \ + --data "config.storage=kong" \ + --data "config.cookie_secure=false" ``` > Note: cookie_secure is true by default, and should always be true, but is set to @@ -276,11 +263,11 @@ For usage with [Key Auth] plugin authentication credentials, enable the Request Termination plugin. ```bash - $ curl -X POST http://localhost:8001/services/example-service/plugins \ - --data "name=request-termination" \ - --data "config.status_code=403" \ - --data "config.message=So long and thanks for all the fish!" \ - --data "consumer.id=" + curl -X POST http://localhost:8001/services/example-service/plugins \ + --data "name=request-termination" \ + --data "config.status_code=403" \ + --data "config.message=So long and thanks for all the fish!" \ + --data "consumer.id=" ``` ### Set up Without a Database @@ -332,8 +319,8 @@ plugins: 1. Check that Anonymous requests are disabled: ```bash - $ curl -i -X GET \ - --url http://localhost:8000/sessions-test + curl -i -X GET \ + --url http://localhost:8000/sessions-test ``` Should return `403`. @@ -341,7 +328,7 @@ plugins: 2. Verify that a user can authenticate via sessions ```bash - $ curl -i -X GET \ + curl -i -X GET \ --url http://localhost:8000/sessions-test?apikey=open_sesame ``` @@ -357,9 +344,9 @@ plugins: Use it like this: ```bash - $ curl -i -X GET \ - --url http://localhost:8000/sessions-test \ - -H "cookie:session=emjbJ3MdyDsoDUkqmemFqw..|1544654411|4QMKAE3I-jFSgmvjWApDRmZHMB8." + curl -i -X GET \ + --url http://localhost:8000/sessions-test \ + -H "cookie:session=emjbJ3MdyDsoDUkqmemFqw..|1544654411|4QMKAE3I-jFSgmvjWApDRmZHMB8." ``` This request should succeed and the `Set-Cookie` response header does not appear @@ -372,7 +359,7 @@ plugins: 4. Navigate to `http://localhost:8000/sessions-test?apikey=open_sesame` - It should return `200` and authenticated via `key-auth` key query param. + It should return `200` and authenticated via `key-auth` key query parameter. 5. Navigate to `http://localhost:8000/sessions-test` @@ -410,20 +397,20 @@ plugins, it also sets `authenticated_groups` associated headers. The Session plugin extends the functionality of [lua-resty-session] with its own session data storage adapter when `storage=kong`. This stores encrypted -session data into the current database strategy and the cookie does not contain -any session data. Data stored in the database is encrypted and the cookie contains only -the session id, expiration time, and HMAC signature. Sessions use the built-in Kong -DAO `ttl` mechanism that destroys sessions after specified `cookie_lifetime` unless renewal +session data into the current database strategy and the cookie does not contain +any session data. Data stored in the database is encrypted and the cookie contains only +the session id, expiration time, and HMAC signature. Sessions use the built-in Kong +DAO `ttl` mechanism that destroys sessions after specified `cookie_lifetime` unless renewal occurs during normal browser activity. Log out the application via XHR request (or something similar) to manually handle the redirects. ## Logging Out It is typical to provide users the ability to log out (i.e., to manually destroy) their -current session. Logging out is possible with either query params or `POST` params in +current session. Logging out is possible with either query parameters or `POST` parameters in the request URL. The config's `logout_methods` allows the plugin to limit logging out based on the HTTP verb. When `logout_query_arg` is set, it checks the -presence of the URL query param specified, and likewise when `logout_post_arg` +presence of the URL query parameter specified, and likewise when `logout_post_arg` is set, it checks the presence of the specified variable in the request body. Allowed HTTP verbs are `GET`, `DELETE`, and `POST`. When there is a session present and the incoming request is a logout request, the Kong Session plugin @@ -444,7 +431,7 @@ _not_ a problem during session renewal period as renew happens in `access` phase ## Changelog -### 2.4.5 +**{{site.base_gateway}} 2.7.x** * Starting with {{site.base_gateway}} 2.7.0.0, if keyring encryption is enabled, the `config.secret` parameter value will be encrypted. diff --git a/app/_hub/kong-inc/session/versions.yml b/app/_hub/kong-inc/session/versions.yml index f56f1dd1d2f9..c4b816c503b8 100644 --- a/app/_hub/kong-inc/session/versions.yml +++ b/app/_hub/kong-inc/session/versions.yml @@ -1,4 +1,12 @@ -- release: 2.4-x -- release: 2.2-x -- release: 1.2-x -- release: 1.0-x +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 2.4.5 + 2.7.x: 2.4.5 + 2.6.x: 2.4.5 + 2.5.x: 2.4.5 + 2.4.x: 2.4.5 + 2.3.x: 2.4.5 + 2.2.x: 2.4.3 + 2.1.x: 2.4.3 diff --git a/app/_hub/kong-inc/statsd-advanced/2.2.x.md b/app/_hub/kong-inc/statsd-advanced/2.2.x.md new file mode 100644 index 000000000000..928a729e618c --- /dev/null +++ b/app/_hub/kong-inc/statsd-advanced/2.2.x.md @@ -0,0 +1,163 @@ +--- +name: StatsD Advanced +publisher: Kong Inc. +version: 2.2.x +desc: Send metrics to StatsD with more flexible options +description: | + Log [metrics](#metrics) for a Service, route + to a StatsD server. + It can also be used to log metrics on [Collectd](https://collectd.org/) + daemon by enabling its + [StatsD plugin](https://collectd.org/wiki/index.php/Plugin:StatsD). + + The StatsD Advanced plugin provides + features not available in the open-source [StatsD](/hub/kong-inc/statsd/) plugin, such as: + * Ability to choose status codes to log to metrics. + * More granular status codes per workspace. + * Ability to use TCP instead of UDP. +enterprise: true +type: plugin +categories: + - logging +kong_version_compatibility: + community_edition: + compatible: null + enterprise_edition: + compatible: + - 2.8.x + - 2.7.x + - 2.6.x + - 2.5.x + - 2.4.x + - 2.3.x + - 2.2.x + - 2.1.x + - 1.5.x + - 1.3-x + - 0.36-x +params: + name: statsd-advanced + service_id: true + route_id: true + consumer_id: true + protocols: + - http + - https + - grpc + - grpcs + - tcp + - tls + - udp + dbless_compatible: 'yes' + config: + - name: host + required: true + default: '`127.0.0.1`' + value_in_examples: 127.0.0.1 + datatype: string + description: The IP address or hostname of the StatsD server. + - name: port + required: true + default: '`8125`' + value_in_examples: 8125 + datatype: integer + description: The port of the StatsD server. + - name: metrics + required: true + default: All metrics are logged. + datatype: Array of record elements. + description: | + List of Metrics to be logged. Available values are described under [Metrics](#metrics). + - name: prefix + required: true + default: '`kong`' + datatype: string + description: String to prefix to each metric's name. + - name: hostname_in_prefix + required: true + default: '`false`' + datatype: boolean + description: Include the `hostname` in the `prefix` for each metric name. + - name: udp_packet_size + required: true + default: '`0` (not combined)' + datatype: number + description: | + Combine UDP packet up to the size configured. If zero (0), don't combine the + UDP packet. Must be a number between 0 and 65507 (inclusive). + - name: use_tcp + required: true + default: '`false`' + datatype: boolean + description: Use TCP instead of UDP. + - name: allow_status_codes + required: true + default: All responses are passed to log metrics. + value_in_examples: + - 200-205 + - 400-499 + datatype: array of string elements. + description: List of status code ranges that are allowed to be logged in metrics. + extra: | + By default, the plugin sends a packet for each metric it observes. The `udp_packet_size` option + configures the greatest datagram size the plugin can combine. It should be less than + 65507 according to UDP protocol. Please consider the MTU of the network when setting this parameter. +--- + +## Metrics + +Metric | Description | Namespace +--- | --- | --- +`request_count` | the request count | `kong.service.\.request.count` +`request_size` | the request's body size in bytes | `kong.service.\.request.size` +`response_size` | the response's body size in bytes | `kong.service.\.response.size` +`latency` | the time interval in milliseconds between the request and response | `kong.service.\.latency` +`status_count` | tracks each status code returned in a response | `kong.service.\.request.status.\.count` and `kong.\.request.status.\.total` +`unique_users` | tracks unique users who made a requests to the underlying Service/Route | `kong.service.\.user.uniques` +`request_per_user` | tracks the request count per Consumer | `kong.service.\.user.\.request.count` +`upstream_latency` | tracks the time in milliseconds it took for the final Service to process the request | `kong.service.\.upstream_latency` +`kong_latency` | tracks the internal Kong latency in milliseconds that it took to run all the Plugins | `kong.service.\.kong_latency` +`status_count_per_user` | tracks the status code for per Consumer per Service | `kong.\.user.\.request.status.\` and `kong.\.user.\.request.status.total` +`status_count_per_workspace` | the status code per Workspace | `kong.service.\.workspace.\.status.\` +`status_count_per_user_per_route` | the status code per Consumer per Route | `kong.route.\.user.\.status.\` +`shdict_usage` | the usage of shared dict, sent once every minute |`kong.node.\.shdict.\.free_space` and `kong.node.\.shdict.\.capacity` + +If a request URI doesn't match any Routes, the following metrics will be sent instead: + +Metric | Description | Namespace +--- | --- | --- +`request_count` | the request count | `kong.global.unmatched.request.count` +`request_size` | the request's body size in bytes | `kong.global.unmatched.request.size` +`response_size` | the response's body size in bytes | `kong.global.unmatched.response.size` +`latency` | the time interval between the request started and response received from the upstream server | `kong.global.unmatched.latency` +`status_count` | the status count | `kong.global.unmatched.status.\.count` +`kong_latency` | the internal Kong latency in milliseconds that it took to run all the plugins | `kong.global.unmatched.kong_latency` + +### Metric Fields + +The plugin can be configured with any combination of [Metrics](#metrics), with each entry containing the following fields: + +Field | Description | Datatype | Allowed values +--- | --- | --- --- +`name` | StatsD metrics name. Required. | String | [Metrics](#metrics) +`stat_type` | Determines what sort of event a metric represents. Required. | String | `gauge`, `timer`, `counter`, `histogram`, `meter` and `set`| +`sample_rate`
*conditional* | Sampling rate. Required. | Number | `number` +`consumer_identifier`
*conditional* | Authenticated user detail. Required. | String | One of the following options: `consumer_id`, `custom_id`, `username` +`service_identifier`
*conditional* | Service detail. Required. | String | One of the following options:`service_id`, `service_name`, `service_host`, `service_name_or_host` +`workspace_identifier`
*conditional* | Workspace detail. Required. | String | One of the following options:`workspace_id`, `workspace_name` + +### Metric Behaviors + +1. By default, all metrics get logged. +2. Metric with `stat_type` set to `counter` or `gauge` must have `sample_rate` defined as well. +3. `unique_users` metric only works with `stat_type` as `set`. +4. `status_count`, `status_count_per_user`, `status_count_per_user_per_route` and `request_per_user` work only with `stat_type` as `counter`. +5. `shdict_usage` work only with `stat_type` as `gauge`. +6. `status_count_per_user`, `request_per_user`, `unique_users` and `status_count_per_user_per_route` must have `customer_identifier` defined. +7. All metrics can optionally configure `service_identifier`; by default it's set to `service_name_or_host`. +8. `status_count_per_workspace` must have `workspace_identifier` defined. + + +## Kong Process Errors + +{% include /md/plugins-hub/kong-process-errors.md %} \ No newline at end of file diff --git a/app/_hub/kong-inc/statsd-advanced/_index.md b/app/_hub/kong-inc/statsd-advanced/_index.md index 3d48cc81d1bc..1ae374741694 100644 --- a/app/_hub/kong-inc/statsd-advanced/_index.md +++ b/app/_hub/kong-inc/statsd-advanced/_index.md @@ -1,14 +1,18 @@ --- name: StatsD Advanced publisher: Kong Inc. -version: 2.2.x +version: 3.0.x desc: Send metrics to StatsD with more flexible options description: | - Log [metrics](#metrics) for a Service or Route to a StatsD server. + Log [metrics](#metrics) for a Service, route + to a StatsD server. It can also be used to log metrics on [Collectd](https://collectd.org/) daemon by enabling its [StatsD plugin](https://collectd.org/wiki/index.php/Plugin:StatsD). + {:.important} + > Starting in Gateway version 3.0.x this plugin has been combined with the open-sourced [StatsD](/hub/kong-inc/statsd/) plugin. + The StatsD Advanced plugin provides features not available in the open-source [StatsD](/hub/kong-inc/statsd/) plugin, such as: * Ability to choose status codes to log to metrics. @@ -23,6 +27,7 @@ kong_version_compatibility: compatible: null enterprise_edition: compatible: + - 3.0.x - 2.8.x - 2.7.x - 2.6.x @@ -54,17 +59,17 @@ params: default: '`127.0.0.1`' value_in_examples: 127.0.0.1 datatype: string - description: The IP address or hostname of StatsD server to send data to. + description: The IP address or hostname of the StatsD server. - name: port required: true default: '`8125`' value_in_examples: 8125 datatype: integer - description: The port of StatsD server to send data to. + description: The port of the StatsD server. - name: metrics required: true - default: All metrics are logged - datatype: Array of record elements + default: All metrics are logged. + datatype: Array of record elements. description: | List of Metrics to be logged. Available values are described under [Metrics](#metrics). - name: prefix @@ -91,15 +96,30 @@ params: description: Use TCP instead of UDP. - name: allow_status_codes required: true - default: All responses are passed to log metrics + default: All responses are passed to log metrics. value_in_examples: - 200-205 - 400-499 - datatype: array of string elements + datatype: array of string elements. description: List of status code ranges that are allowed to be logged in metrics. + - name: consumer_identifier_default + required: true + default: 'custom_id' + datatype: string + description: The default consumer identifier for metrics. This will take effect when a metric's consumer identifier is omitted. Allowed values are `custom_id`, `consumer_id`, `username`. + - name: service_identifier_default + required: true + default: 'service_name_or_host' + datatype: string + description: The default service identifier for metrics. This will take effect when a metric's service identifier is omitted. Allowed values are `service_name_or_host`, `service_id`, `service_name`, `service_host`. + - name: workspace_identifier_default + required: true + default: 'workspace_id' + datatype: string + description: The default workspace identifier for metrics. This will take effect when a metric's workspace identifier is omitted. Allowed values are `workspace_id`, `workspace_name`. extra: | By default, the plugin sends a packet for each metric it observes. The `udp_packet_size` option - configures the greatest datagram size the plugin can combine. It should be less than + configures the greatest datagram size the plugin can combine, this should be less than 65507 according to UDP protocol. Please consider the MTU of the network when setting this parameter. --- @@ -107,30 +127,30 @@ params: Metric | Description | Namespace --- | --- | --- -`request_count` | the request count | kong.service.\.request.count -`request_size` | the request's body size in bytes | kong.service.\.request.size -`response_size` | the response's body size in bytes | kong.service.\.response.size -`latency` | the time interval in milliseconds between the request and response | kong.service.\.latency -`status_count` | tracks each status code returned in a response | kong.service.\.request.status.\.count and kong.\.request.status.\.total -`unique_users` | tracks unique users who made a requests to the underlying Service/Route | kong.service.\.user.uniques -`request_per_user` | tracks the request count per Consumer | kong.service.\.user.\.request.count -`upstream_latency` | tracks the time in milliseconds it took for the final Service to process the request | kong.service.\.upstream_latency -`kong_latency` | tracks the internal Kong latency in milliseconds that it took to run all the Plugins | kong.service.\.kong_latency -`status_count_per_user` | tracks the status code for per Consumer per Service | kong.\.user.\.request.status.\ and kong.\.user.\.request.status.total -`status_count_per_workspace` | the status code per Workspace | kong.service.\.workspace.\.status.\ -`status_count_per_user_per_route` | the status code per Consumer per Route | kong.route.\.user.\.status.\ -`shdict_usage` | the usage of shared dict, sent once every minute |kong.node.\.shdict.\.free_space and kong.node.\.shdict.\.capacity +`request_count` | The request count. | `kong.service.\.request.count` +`request_size` | The request's body size in bytes. | `kong.service.\.request.size` +`response_size` | The response's body size in bytes. | `kong.service.\.response.size` +`latency` | The time interval in milliseconds between the request and response. | `kong.service.\.latency` +`status_count` | Tracks each status code returned in a response. | `kong.service.\.request.status.\.count` and `kong.\.request.status.\.total` +`unique_users` | Tracks unique users who made a requests to the underlying service/route. | `kong.service.\.user.uniques` +`request_per_user` | Tracks the request count per consumer. | `kong.service.\.user.\.request.count` +`upstream_latency` | Tracks the time in milliseconds it took for the final Service to process the request. | `kong.service.\.upstream_latency` +`kong_latency` | Tracks the internal Kong latency that it took to run all of the plugins, in milliseconds.| `kong.service.\.kong_latency` +`status_count_per_user` | Tracks the status code per consumer per service. | `kong.\.user.\.request.status.\` and `kong.\.user.\.request.status.total` +`status_count_per_workspace` | the status code per workspace. | `kong.service.\.workspace.\.status.\` +`status_count_per_user_per_route` | the status code per consumer per Route. | `kong.route.\.user.\.status.\` +`shdict_usage` | the usage of a shared dict, sent once every minute. |`kong.node.\.shdict.\.free_space` and `kong.node.\.shdict.\.capacity` If a request URI doesn't match any Routes, the following metrics will be sent instead: Metric | Description | Namespace --- | --- | --- -`request_count` | the request count | kong.global.unmatched.request.count -`request_size` | the request's body size in bytes | kong.global.unmatched.request.size -`response_size` | the response's body size in bytes | kong.global.unmatched.response.size -`latency` | the time interval between the request started and response received from the upstream server | kong.global.unmatched.latency -`status_count` | the status count | kong.global.unmatched.status.\.count -`kong_latency` | the internal Kong latency in milliseconds that it took to run all the plugins | kong.global.unmatched.kong_latency +`request_count` | The request count. | `kong.global.unmatched.request.count` +`request_size` | The request's body size in bytes. | `kong.global.unmatched.request.size` +`response_size` | The response's body size in bytes. | `kong.global.unmatched.response.size` +`latency` | The time interval between when the request started and the response was received from the upstream server. | `kong.global.unmatched.latency` +`status_count` | The status count. | `kong.global.unmatched.status.\.count` +`kong_latency` | The internal Kong latency that it took to run all of the plugins, in milliseconds. | `kong.global.unmatched.kong_latency` ### Metric Fields @@ -138,12 +158,12 @@ The plugin can be configured with any combination of [Metrics](#metrics), with e Field | Description | Datatype | Allowed values --- | --- | --- --- -`name` | StatsD metric's name. Required. | String | [Metrics](#metrics) +`name` | StatsD metrics name. Required. | String | [Metrics](#metrics) `stat_type` | Determines what sort of event a metric represents. Required. | String | `gauge`, `timer`, `counter`, `histogram`, `meter` and `set`| `sample_rate`
*conditional* | Sampling rate. Required. | Number | `number` -`consumer_identifier`
*conditional* | Authenticated user detail. Required. | String | One of the following options: `consumer_id`, `custom_id`, `username` -`service_identifier`
*conditional* | Service detail. Required. | String | One of the following options:`service_id`, `service_name`, `service_host`, `service_name_or_host` -`workspace_identifier`
*conditional* | Workspace detail. Required. | String | One of the following options:`workspace_id`, `workspace_name` +`consumer_identifier`
*conditional* | Authenticated user detail. | String | One of the following options: `consumer_id`, `custom_id`, `username`, `null` +`service_identifier`
*conditional* | Service detail. | String | One of the following options:`service_id`, `service_name`, `service_host`, `service_name_or_host`, `null` +`workspace_identifier`
*conditional* | Workspace detail. | String | One of the following options:`workspace_id`, `workspace_name`, `null` ### Metric Behaviors diff --git a/app/_hub/kong-inc/statsd-advanced/versions.yml b/app/_hub/kong-inc/statsd-advanced/versions.yml index 1b0077a6872f..57210a1d3f49 100644 --- a/app/_hub/kong-inc/statsd-advanced/versions.yml +++ b/app/_hub/kong-inc/statsd-advanced/versions.yml @@ -1,3 +1,4 @@ +- release: 3.0.x - release: 2.2.x - release: 1.3-x - release: 0.36-x diff --git a/app/_hub/kong-inc/statsd/0.1-x.md b/app/_hub/kong-inc/statsd/0.1-x.md deleted file mode 100644 index ba20cd33da5e..000000000000 --- a/app/_hub/kong-inc/statsd/0.1-x.md +++ /dev/null @@ -1,113 +0,0 @@ ---- -name: StatsD -publisher: Kong Inc. -version: 0.1-x - -desc: Send request and response logs to StatsD -description: | - Log [metrics](#metrics) for a Service, Route (or the deprecated API entity) - to a StatsD server. - It can also be used to log metrics on [Collectd](https://collectd.org/) - daemon by enabling its [Statsd - plugin](https://collectd.org/wiki/index.php/Plugin:StatsD). - -
- Note: The functionality of this plugin as bundled - with versions of Kong prior to 0.11.0 - differs from what is documented herein. Refer to the - CHANGELOG - for details. -
- -type: plugin -categories: - - logging - -kong_version_compatibility: - community_edition: - compatible: - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - enterprise_edition: - compatible: - - 0.34-x - - 0.33-x - - 0.32-x - - 0.31-x - -params: - name: statsd - api_id: true - service_id: true - route_id: true - consumer_id: true - config: - - name: host - required: false - default: "`127.0.0.1`" - value_in_examples: 127.0.0.1 - description: The IP address or host name to send data to. - - name: port - required: false - default: "`8125`" - value_in_examples: 8125 - description: The port to send data to on the upstream server - - name: metrics - required: false - default: "All metrics
are logged" - description: List of Metrics to be logged. Available values are described under [Metrics](#metrics). - - name: prefix - required: false - default: "`kong`" - description: String to be prefixed to each metric's name. - ---- - -## Metrics - -Metrics the plugin supports logging into the StatsD server. - -Metric | description | namespace ---- | --- | --- -`request_count` | tracks the request | kong.\.request.count -`request_size` | tracks the request's body size in bytes | kong.\.request.size -`response_size` | tracks the response's body size in bytes | kong.\.response.size -`latency` | tracks the time interval in milliseconds between the request started and response received from the upstream server | kong.\.latency -`status_count` | tracks each status code returned in a response | kong.\.status.\.count and kong.\.status.\.total -`unique_users` | tracks unique users who made a requests to the underlying Service/Route (or API)| kong.\.user.uniques -`request_per_user` | tracks request/user | kong.\.user.\.count -`upstream_latency` | tracks the time it took for the final service to process the request | kong.\.upstream_latency -`kong_latency` | tracks the internal Kong latency that it took to run all the plugins | kong.\.kong_latency -`status_count_per_user` | tracks request/status/user | kong.\.user.\.status.\ and kong.\.user.\.status.total - -### Metric Fields - -Plugin can be configured with any combination of [Metrics](#metrics), with each entry containing the following fields. - -Field | description | allowed values ---- | --- | --- -`name` | StatsD metric's name | [Metrics](#metrics) -`stat_type` | determines what sort of event the metric represents | `gauge`, `timer`, `counter`, `histogram`, `meter` and `set`| -`sample_rate`
*conditional* | sampling rate | `number` -`customer_identifier`
*conditional*| authenticated user detail | `consumer_id`, `custom_id`, `username` - -### Metric Requirements - -1. By default all metrics get logged. -2. Metric with `stat_type` set to `counter` or `gauge` must have `sample_rate` defined as well. -3. `unique_users` metric only works with `stat_type` as `set`. -4. `status_count`, `status_count_per_user` and `request_per_user` work only with `stat_type` as `counter`. -5. `status_count_per_user`, `request_per_user` and `unique_users` must have `customer_identifier` defined. - - -## Kong Process Errors - -This logging plugin will only log HTTP request and response data. If you are -looking for the Kong process error file (which is the nginx error file), then -you can find it at the following path: -{[prefix](/gateway/latest/reference/configuration/#prefix)}/logs/error.log diff --git a/app/_hub/kong-inc/statsd/_index.md b/app/_hub/kong-inc/statsd/_index.md index 9f9190af1fac..89174ce26a01 100644 --- a/app/_hub/kong-inc/statsd/_index.md +++ b/app/_hub/kong-inc/statsd/_index.md @@ -1,60 +1,22 @@ --- name: StatsD publisher: Kong Inc. -version: 1.0.0 -desc: Send request and response logs to StatsD +desc: Send metrics to StatsD description: | - Log [metrics](#metrics) for a Service, Route - to a StatsD server. + Log [metrics](#metrics) for a Service or Route to a StatsD server. It can also be used to log metrics on [Collectd](https://collectd.org/) - daemon by enabling its [Statsd - plugin](https://collectd.org/wiki/index.php/Plugin:StatsD). - - This plugin is the open-source version of the [StatsD Advanced plugin](/hub/kong-inc/statsd-advanced/), which provides additional features such as: - * Ability to choose status codes to log to metrics. - * More granular status codes per workspace. - * Ability to use TCP instead of UDP. + daemon by enabling its + [StatsD plugin](https://collectd.org/wiki/index.php/Plugin:StatsD). type: plugin categories: - logging kong_version_compatibility: community_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x + compatible: true + enterprise_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x + compatible: true + params: name: statsd service_id: true @@ -76,7 +38,7 @@ params: default: '`127.0.0.1`' value_in_examples: 127.0.0.1 datatype: string - description: The IP address or host name to send data to. + description: The IP address or hostname of StatsD server to send data to. - name: port required: true default: '`8125`' @@ -87,51 +49,158 @@ params: required: true default: All metrics are logged datatype: Array of record elements - description: 'List of Metrics to be logged. Available values are described under [Metrics](#metrics).' + description: | + List of metrics to be logged. Available values are described under [Metrics](#metrics). - name: prefix required: true default: '`kong`' datatype: string description: String to prefix to each metric's name. + - name: hostname_in_prefix + required: true + default: '`false`' + datatype: boolean + description: Include the `hostname` in the `prefix` for each metric name. + minimum_version: "3.0.x" + - name: udp_packet_size + required: true + default: '`0` (not combined)' + datatype: number + description: | + Combine UDP packet up to the size configured. If zero (0), don't combine the + UDP packet. Must be a number between 0 and 65507 (inclusive). + - name: use_tcp + required: true + default: '`false`' + datatype: boolean + description: Use TCP instead of UDP. + minimum_version: "3.0.x" + - name: allow_status_codes + required: true + default: All responses are passed to log metrics + value_in_examples: + - 200-205 + - 400-499 + datatype: array of string elements + description: List of status code ranges that are allowed to be logged in metrics. + minimum_version: "3.0.x" + - name: consumer_identifier_default + required: true + default: 'custom_id' + datatype: string + description: The default consumer identifier of metrics. This takes effect when a metric's consumer identifier is omitted. Allowed values are `custom_id`, `consumer_id`, `username`. + minimum_version: "3.0.x" + - name: service_identifier_default + required: true + default: 'service_name_or_host' + datatype: string + description: The default service identifier of metrics. This takes effect when a metric's service identifier is omitted. Allowed values are `service_name_or_host`, `service_id`, `service_name`, `service_host`. + minimum_version: "3.0.x" + - name: workspace_identifier_default + required: true + default: 'workspace_id' + datatype: string + description: The default workspace identifier of metrics. This will take effect when a metric's workspace identifier is omitted. Allowed values are `workspace_id`, `workspace_name`. + minimum_version: "3.0.x" + extra: | + By default, the plugin sends a packet for each metric it observes. The `udp_packet_size` option + configures the greatest datagram size the plugin can combine. It should be less than + 65507 according to UDP protocol. Consider the MTU of the network when setting this parameter. --- ## Metrics -Metrics the plugin supports logging into the StatsD server. +{% if_plugin_version gte:3.0.x %} +Metric | Description | Namespace +--- | --- | --- +`request_count` | The number of requests. | `kong.service..request.count` +`request_size` | The request's body size in bytes. | `kong.service..request.size` +`response_size` | The response's body size in bytes. | `kong.service..response.size` +`latency` | The time interval in milliseconds between the request and response. | `kong.service..latency` +`status_count` | Tracks each status code returned in a response. | `kong.service..status.` +`unique_users` | Tracks unique users who made requests to the underlying Service or route. | `kong.service..user.uniques` +`request_per_user` | Tracks the request count per consumer. | `kong.service..user..request.count` +`upstream_latency` | Tracks the time in milliseconds it took for the final Service to process the request. | `kong.service..upstream_latency` +`kong_latency` | Tracks the internal Kong latency in milliseconds that it took to run all the plugins. | `kong.service..kong_latency` +`status_count_per_user` | Tracks the status code per consumer per service. | `kong.service..user..status.` +`status_count_per_workspace` | The status code per workspace. | `kong.service..workspace..status.` +`status_count_per_user_per_route` | The status code per consumer per route. | `kong.route..user..status.` +`shdict_usage` | The usage of shared dict, sent once every minute. | `kong.node..shdict..free_space` and `kong.node..shdict..capacity` +{% endif_plugin_version %} +{% if_plugin_version lte:2.8.x %} +Metric | Description | Namespace +--- | --- | --- +`request_count` | The number of requests. | `kong..request.count` +`request_size` | The request's body size in bytes. | `kong..request.size` +`response_size` | The response's body size in bytes. | `kong..response.size` +`latency` | The time interval in milliseconds between the request and response. | `kong..latency` +`status_count` | Tracks each status code returned in a response. | `kong..request.status..count` and `kong..request.status..total` +`unique_users` | Tracks unique users who made requests to the underlying Service or Route. | `kong..user.uniques` +`request_per_user` | Tracks the request count per Consumer. | `kong..user..request.count` +`upstream_latency` | Tracks the time in milliseconds it took for the final Service to process the request. | `kong..upstream_latency` +`kong_latency` | Tracks the internal Kong latency in milliseconds that it took to run all the plugins. | `kong..kong_latency` +`status_count_per_user` | Tracks the status code for per Consumer per Service. | `kong..user..request.status.` and `kong..user..request.status.total` +{% endif_plugin_version %} + +If a request URI doesn't match any Routes, the following metrics are sent instead: Metric | Description | Namespace --- | --- | --- -`request_count` | tracks the request | kong.\.request.count -`request_size` | tracks the request's body size in bytes | kong.\.request.size -`response_size` | tracks the response's body size in bytes | kong.\.response.size -`latency` | tracks the time interval in milliseconds between the request started and response received from the upstream server | kong.\.latency -`status_count` | tracks each status code returned in a response | kong.\.request.status.\.count and kong.\.request.status.\.total -`unique_users` | tracks unique users who made a requests to the underlying Service/Route | kong.\.user.uniques -`request_per_user` | tracks request/user | kong.\.user.\.request.count -`upstream_latency` | tracks the time it took for the final service to process the request | kong.\.upstream_latency -`kong_latency` | tracks the internal Kong latency that it took to run all the plugins | kong.\.kong_latency -`status_count_per_user` | tracks request/status/user | kong.\.user.\.request.status.\ and kong.\.user.\.request.status.total +`request_count` | The request count. | `kong.global.unmatched.request.count` +`request_size` | The request's body size in bytes. | `kong.global.unmatched.request.size` +`response_size` | The response's body size in bytes. | `kong.global.unmatched.response.size` +`latency` | The time interval between when the request started and when the response is received from the upstream server. | `kong.global.unmatched.latency` +`status_count` | The status count. | `kong.global.unmatched.status..count` +`kong_latency` | The internal Kong latency in milliseconds that it took to run all the plugins. | `kong.global.unmatched.kong_latency` ### Metric Fields The plugin can be configured with any combination of [Metrics](#metrics), with each entry containing the following fields: -Field | Description | Datatypes | Allowed values ---- | --- | --- | --- -`name` | StatsD metric's name. Required. | String | [Metrics](#metrics) -`stat_type` | Determines what sort of event the metric represents. Required. | String | `gauge`, `timer`, `counter`, `histogram`, `meter`, and `set`| -`sample_rate`
*conditional* | Sampling rate. Required. | Number | `number` -`consumer_identifier`
*conditional*| Authenticated user detail. Required. | String | One of the following options: `consumer_id`, `custom_id`, `username` +Field | Description | Datatype | Allowed values +--- | --- | --- --- +`name`
*required* | StatsD metric's name. | String | [Metrics](#metrics) +`stat_type`
*required* | Determines what sort of event a metric represents. | String | `gauge`, `timer`, `counter`, `histogram`, `meter` and `set`| +`sample_rate`
*required*
*conditional* | Sampling rate. | Number | `number` +`consumer_identifier`
*conditional* | Authenticated user detail. | String | One of the following options: `consumer_id`, `custom_id`, `username`, `null` +{% if_plugin_version gte:3.0.x %} +`service_identifier`
*conditional* | Service detail. | String | One of the following options: `service_id`, `service_name`, `service_host`, `service_name_or_host`, `null` +`workspace_identifier`
*conditional* | Workspace detail. | String | One of the following options:`workspace_id`, `workspace_name`, `null` +{% endif_plugin_version %} -### Metric Requirements +### Metric behaviors 1. By default, all metrics get logged. 2. Metric with `stat_type` set to `counter` or `gauge` must have `sample_rate` defined as well. 3. `unique_users` metric only works with `stat_type` as `set`. +{% if_plugin_version lte:2.8.x %} 4. `status_count`, `status_count_per_user` and `request_per_user` work only with `stat_type` as `counter`. 5. `status_count_per_user`, `request_per_user` and `unique_users` must have `customer_identifier` defined. +{% endif_plugin_version %} +{% if_plugin_version gte:3.0.x %} +4. `status_count`, `status_count_per_user`, `status_count_per_user_per_route` and `request_per_user` work only with `stat_type` as `counter`. +5. `shdict_usage` work only with `stat_type` as `gauge`. +6. `status_count_per_user`, `request_per_user`, `unique_users` and `status_count_per_user_per_route` must have `customer_identifier` defined. +7. All metrics can optionally configure `service_identifier`; by default it's set to `service_name_or_host`. +8. `status_count_per_workspace` must have `workspace_identifier` defined. +{% endif_plugin_version %} ## Kong Process Errors {% include /md/plugins-hub/kong-process-errors.md %} + +--- +## Changelog + +### {{site.base_gateway}} 3.0.x + +* Merged features of the StatsD Advanced plugin into the StatsD plugin. The StatsD plugin now includes the following: + * New parameters for StatsD: `hostname_in_prefix`, `udp_packet_size`, `ues_tcp`, `allow_status_codes`, `consumer_identifier_default`, `service_identifier_default`, `workspace_identifier_default`. + * New metrics: `status_count_per_workspace`, `status_count_per_user_per_route`, `shdict_usage` + * New metric fields: `service_identifier`, `workspace_identifier` + +* Breaking changes + * The metric name that is related to the service has been renamed by adding a `service.` prefix. e.g. `kong.service..request.count` + * The metric `kong..request.status..count` from metrics `status_count` and `status_count_per_user` has been renamed to `kong.service..status..count` + * The metric `*.status..total` from metrics `status_count` and `status_count_per_user` has been removed. diff --git a/app/_hub/kong-inc/statsd/versions.yml b/app/_hub/kong-inc/statsd/versions.yml index f56356207baf..2656948f543c 100644 --- a/app/_hub/kong-inc/statsd/versions.yml +++ b/app/_hub/kong-inc/statsd/versions.yml @@ -1,2 +1,12 @@ -- release: 1.0-x -- release: 0.1-x +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 2.0.1 + 2.7.x: 2.0.1 + 2.6.x: 2.0.1 + 2.5.x: 2.0.1 + 2.4.x: 2.0.1 + 2.3.x: 2.0.1 + 2.2.x: 2.0.1 + 2.1.x: 2.0.1 diff --git a/app/_hub/kong-inc/syslog/0.1-x.md b/app/_hub/kong-inc/syslog/0.1-x.md deleted file mode 100644 index bf92d225d1dc..000000000000 --- a/app/_hub/kong-inc/syslog/0.1-x.md +++ /dev/null @@ -1,186 +0,0 @@ ---- -name: Syslog -publisher: Kong Inc. -version: 0.1-x - -desc: Send request and response logs to Syslog -description: | - Log request and response data to Syslog. - -type: plugin -categories: - - logging - -kong_version_compatibility: - community_edition: - compatible: - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - enterprise_edition: - compatible: - - 0.34-x - - 0.33-x - - 0.32-x - - 0.31-x - -params: - name: syslog - api_id: true - service_id: true - route_id: true - consumer_id: true - config: - - name: successful_severity - required: false - default: "`info`" - description: An optional logging severity assigned to the all successful requests with response status code less then 400 . - - name: client_errors_severity - required: false - default: "`info`" - description: An optional logging severity assigned to the all failed requests with response status code 400 or higher but less than 500. - - name: server_errors_severity - required: false - default: "`info`" - description: An optional logging severity assigned to the all failed requests with response status code 500 or higher. - - name: log_level - required: false - default: "`info`" - description: An optional logging severity, any request with equal or higher severity will be logged to System log. - ---- - -## Log Format - -Every request will be logged to System log in [SYSLOG](https://en.wikipedia.org/wiki/Syslog) standard, with `message` component in the following format: - -```json -{ - "request": { - "method": "GET", - "uri": "/get", - "url": "http://httpbin.org:8000/get", - "size": "75", - "querystring": {}, - "headers": { - "accept": "*/*", - "host": "httpbin.org", - "user-agent": "curl/7.37.1" - }, - "tls": { - "version": "TLSv1.2", - "cipher": "ECDHE-RSA-AES256-GCM-SHA384", - "supported_client_ciphers": "ECDHE-RSA-AES256-GCM-SHA384", - "client_verify": "NONE" - } - }, - "upstream_uri": "/", - "response": { - "status": 200, - "size": "434", - "headers": { - "Content-Length": "197", - "via": "kong/0.3.0", - "Connection": "close", - "access-control-allow-credentials": "true", - "Content-Type": "application/json", - "server": "nginx", - "access-control-allow-origin": "*" - } - }, - "tries": [ - { - "state": "next", - "code": 502, - "ip": "127.0.0.1", - "port": 8000 - }, - { - "ip": "127.0.0.1", - "port": 8000 - } - ], - "authenticated_entity": { - "consumer_id": "80f74eef-31b8-45d5-c525-ae532297ea8e", - "id": "eaa330c0-4cff-47f5-c79e-b2e4f355207e" - }, - "route": { - "created_at": 1521555129, - "hosts": null, - "id": "75818c5f-202d-4b82-a553-6a46e7c9a19e", - "methods": null, - "paths": [ - "/example-path" - ], - "preserve_host": false, - "protocols": [ - "http", - "https" - ], - "regex_priority": 0, - "service": { - "id": "0590139e-7481-466c-bcdf-929adcaaf804" - }, - "strip_path": true, - "updated_at": 1521555129 - }, - "service": { - "connect_timeout": 60000, - "created_at": 1521554518, - "host": "example.com", - "id": "0590139e-7481-466c-bcdf-929adcaaf804", - "name": "myservice", - "path": "/", - "port": 80, - "protocol": "http", - "read_timeout": 60000, - "retries": 5, - "updated_at": 1521554518, - "write_timeout": 60000 - }, - "consumer": { - "username": "demo", - "created_at": 1491847011000, - "id": "35b03bfc-7a5b-4a23-a594-aa350c585fa8" - }, - "latencies": { - "proxy": 1430, - "kong": 9, - "request": 1921 - }, - "client_ip": "127.0.0.1", - "started_at": 1433209822425 -} -``` - -A few considerations on the above JSON object: - -* `request` contains properties about the request sent by the client -* `response` contains properties about the response sent to the client -* `tries` contains the list of (re)tries (successes and failures) made by the load balancer for this request -* `route` contains Kong properties about the specific Route requested -* `service` contains Kong properties about the Service associated with the requested Route -* `authenticated_entity` contains Kong properties about the authenticated credential (if an authentication plugin has been enabled) -* `consumer` contains the authenticated Consumer (if an authentication plugin has been enabled) -* `latencies` contains some data about the latencies involved: - * `proxy` is the time it took for the final service to process the request - * `kong` is the internal Kong latency that it took to run all the plugins - * `request` is the time elapsed between the first bytes were read from the client and after the last bytes were sent to the client. Useful for detecting slow clients. -* `client_ip` contains the original client IP address -* `started_at` contains the UTC timestamp of when the API transaction has started to be processed. - ----- - -## Notes - -* Make sure Syslog daemon is running on the instance and it's configured with logging level severity same as or lower than the set `config.log_level`. - -## Kong Process Errors - -This logging plugin will only log HTTP request and response data. If you are looking for the Kong process error file (which is the nginx error file), then you can find it at the following path: {[prefix](/gateway/latest/reference/configuration/#prefix)}/logs/error.log diff --git a/app/_hub/kong-inc/syslog/1.0.x.md b/app/_hub/kong-inc/syslog/1.0.x.md deleted file mode 100644 index e58ea8eae2e0..000000000000 --- a/app/_hub/kong-inc/syslog/1.0.x.md +++ /dev/null @@ -1,219 +0,0 @@ ---- -name: Syslog -publisher: Kong Inc. -version: 1.0.0 - -desc: Send request and response logs to Syslog -description: | - Log request and response data to Syslog. - -type: plugin -categories: - - logging - -kong_version_compatibility: - community_edition: - compatible: - - 2.3.x - - 2.2.x - - 2.1.x - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - enterprise_edition: - compatible: - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x - -params: - name: syslog - service_id: true - route_id: true - consumer_id: true - protocols: ["http", "https", "grpc", "grpcs", "tcp", "tls", "udp"] - dbless_compatible: yes - config: - - name: successful_severity - required: false - default: "`info`" - datatype: string - description: | - An optional logging severity assigned to all the successful requests with a response - status code less then 400. Available options: `debug`, `info`, `notice`, `warning`, `err`, `crit`, `alert`, `emerg`. - - name: client_errors_severity - required: false - default: "`info`" - datatype: string - description: | - An optional logging severity assigned to all the failed requests with a - response status code 400 or higher but less than 500. Available options: `debug`, `info`, `notice`, - `warning`, `err`, `crit`, `alert`, `emerg`. - - name: server_errors_severity - required: false - default: "`info`" - datatype: string - description: | - An optional logging severity assigned to all the failed requests with a - response status code 500 or higher. Available options: `debug`, `info`, `notice`, `warning`, `err`, `crit`, `alert`, `emerg`. - - name: log_level - required: false - default: "`info`" - datatype: string - description: | - An optional logging severity. Any request with equal or higher severity - will be logged to System log. Available options: `debug`, `info`, `notice`, `warning`, `err`, `crit`, `alert`, `emerg`. - ---- - -## Log Format - -Every request will be logged to System log in [SYSLOG](https://en.wikipedia.org/wiki/Syslog) standard, with `message` component in the following format: - -```json -{ - "request": { - "method": "GET", - "uri": "/get", - "url": "http://httpbin.org:8000/get", - "size": "75", - "querystring": {}, - "headers": { - "accept": "*/*", - "host": "httpbin.org", - "user-agent": "curl/7.37.1" - }, - "tls": { - "version": "TLSv1.2", - "cipher": "ECDHE-RSA-AES256-GCM-SHA384", - "supported_client_ciphers": "ECDHE-RSA-AES256-GCM-SHA384", - "client_verify": "NONE" - } - }, - "upstream_uri": "/", - "response": { - "status": 200, - "size": "434", - "headers": { - "Content-Length": "197", - "via": "kong/0.3.0", - "Connection": "close", - "access-control-allow-credentials": "true", - "Content-Type": "application/json", - "server": "nginx", - "access-control-allow-origin": "*" - } - }, - "tries": [ - { - "state": "next", - "code": 502, - "ip": "127.0.0.1", - "port": 8000 - }, - { - "ip": "127.0.0.1", - "port": 8000 - } - ], - "authenticated_entity": { - "consumer_id": "80f74eef-31b8-45d5-c525-ae532297ea8e", - "id": "eaa330c0-4cff-47f5-c79e-b2e4f355207e" - }, - "route": { - "created_at": 1521555129, - "hosts": null, - "id": "75818c5f-202d-4b82-a553-6a46e7c9a19e", - "methods": null, - "paths": [ - "/example-path" - ], - "preserve_host": false, - "protocols": [ - "http", - "https" - ], - "regex_priority": 0, - "service": { - "id": "0590139e-7481-466c-bcdf-929adcaaf804" - }, - "strip_path": true, - "updated_at": 1521555129 - }, - "service": { - "connect_timeout": 60000, - "created_at": 1521554518, - "host": "example.com", - "id": "0590139e-7481-466c-bcdf-929adcaaf804", - "name": "myservice", - "path": "/", - "port": 80, - "protocol": "http", - "read_timeout": 60000, - "retries": 5, - "updated_at": 1521554518, - "write_timeout": 60000 - }, - "workspaces": [ - { - "id":"b7cac81a-05dc-41f5-b6dc-b87e29b6c3a3", - "name": "default" - } - ], - "consumer": { - "username": "demo", - "created_at": 1491847011000, - "id": "35b03bfc-7a5b-4a23-a594-aa350c585fa8" - }, - "latencies": { - "proxy": 1430, - "kong": 9, - "request": 1921 - }, - "client_ip": "127.0.0.1", - "started_at": 1433209822425 -} -``` - -A few considerations on the above JSON object: - -* `request` contains properties about the request sent by the client -* `response` contains properties about the response sent to the client -* `tries` contains the list of (re)tries (successes and failures) made by the load balancer for this request -* `route` contains Kong properties about the specific Route requested -* `service` contains Kong properties about the Service associated with the requested Route -* `authenticated_entity` contains Kong properties about the authenticated credential (if an authentication plugin has been enabled) -* `workspaces` contains Kong properties of the Workspaces associated with the requested Route. **Only in Kong Gateway version >= 0.34**. -* `consumer` contains the authenticated Consumer (if an authentication plugin has been enabled) -* `latencies` contains some data about the latencies involved: - * `proxy` is the time it took for the final service to process the request - * `kong` is the internal Kong latency that it took to run all the plugins - * `request` is the time elapsed between the first bytes were read from the client and after the last bytes were sent to the client. Useful for detecting slow clients. -* `client_ip` contains the original client IP address -* `started_at` contains the UTC timestamp of when the API transaction has started to be processed. - ----- - -## Notes - -* Make sure Syslog daemon is running on the instance and it's configured with logging level severity same as or lower than the set `config.log_level`. - -## Kong Process Errors - -{% include /md/plugins-hub/kong-process-errors.md %} diff --git a/app/_hub/kong-inc/syslog/2.0.x.md b/app/_hub/kong-inc/syslog/2.0.x.md deleted file mode 100644 index 631de7aab15e..000000000000 --- a/app/_hub/kong-inc/syslog/2.0.x.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -name: Syslog -publisher: Kong Inc. -version: 2.0.x -# internal handler version 2.0.1 - -desc: Send request and response logs to Syslog -description: | - Log request and response data to Syslog. - -type: plugin -categories: - - logging - -kong_version_compatibility: - community_edition: - compatible: - - 2.3.x - - 2.2.x - - 2.1.x - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - enterprise_edition: - compatible: - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x - -params: - name: syslog - service_id: true - route_id: true - consumer_id: true - protocols: ["http", "https", "grpc", "grpcs", "tcp", "tls", "udp"] - dbless_compatible: yes - config: - - name: successful_severity - required: false - default: "`info`" - datatype: string - description: | - An optional logging severity assigned to all the successful requests with a response - status code less then 400. Available options: `debug`, `info`, `notice`, `warning`, `err`, `crit`, `alert`, `emerg`. - - name: client_errors_severity - required: false - default: "`info`" - datatype: string - description: | - An optional logging severity assigned to all the failed requests with a - response status code 400 or higher but less than 500. Available options: `debug`, `info`, `notice`, - `warning`, `err`, `crit`, `alert`, `emerg`. - - name: server_errors_severity - required: false - default: "`info`" - datatype: string - description: | - An optional logging severity assigned to all the failed requests with a - response status code 500 or higher. Available options: `debug`, `info`, `notice`, `warning`, `err`, `crit`, `alert`, `emerg`. - - name: log_level - required: false - default: "`info`" - datatype: string - description: | - An optional logging severity. Any request with equal or higher severity - will be logged to System log. Available options: `debug`, `info`, `notice`, `warning`, `err`, `crit`, `alert`, `emerg`. - ---- - -## Log format - -Every request is logged to the System log in [SYSLOG](https://en.wikipedia.org/wiki/Syslog) standard, with the -with `message` component formatted as described below. - -**Note:** Make sure the Syslog daemon is running on the instance and it's configured with the -logging level severity the same as or lower than the set `config.log_level` for this plugin. - -{% include /md/plugins-hub/log-format.md %} - -### JSON object considerations - -{% include /md/plugins-hub/json-object-log.md %} - -## Kong process errors - -{% include /md/plugins-hub/kong-process-errors.md %} diff --git a/app/_hub/kong-inc/syslog/2.1.x.md b/app/_hub/kong-inc/syslog/2.1.x.md deleted file mode 100644 index 4aeb923033a5..000000000000 --- a/app/_hub/kong-inc/syslog/2.1.x.md +++ /dev/null @@ -1,116 +0,0 @@ ---- -name: Syslog -publisher: Kong Inc. -version: 2.1.x -# internal handler version 2.1.0 - -desc: Send request and response logs to Syslog -description: | - Log request and response data to Syslog. - -type: plugin -categories: - - logging - -kong_version_compatibility: - community_edition: - compatible: - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - enterprise_edition: - compatible: - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x - -params: - name: syslog - service_id: true - route_id: true - consumer_id: true - protocols: ["http", "https", "grpc", "grpcs", "tcp", "tls", "udp"] - dbless_compatible: yes - config: - - name: successful_severity - required: false - default: "`info`" - datatype: string - description: | - An optional logging severity assigned to all the successful requests with a response - status code less then 400. Available options: `debug`, `info`, `notice`, `warning`, `err`, `crit`, `alert`, `emerg`. - - name: client_errors_severity - required: false - default: "`info`" - datatype: string - description: | - An optional logging severity assigned to all the failed requests with a - response status code 400 or higher but less than 500. Available options: `debug`, `info`, `notice`, - `warning`, `err`, `crit`, `alert`, `emerg`. - - name: server_errors_severity - required: false - default: "`info`" - datatype: string - description: | - An optional logging severity assigned to all the failed requests with a - response status code 500 or higher. Available options: `debug`, `info`, `notice`, `warning`, `err`, `crit`, `alert`, `emerg`. - - name: log_level - required: false - default: "`info`" - datatype: string - description: | - An optional logging severity. Any request with equal or higher severity - will be logged to System log. Available options: `debug`, `info`, `notice`, `warning`, `err`, `crit`, `alert`, `emerg`. - - name: custom_fields_by_lua - required: false - default: - datatype: map - description: | - A list of key-value pairs, where the key is the name of a log field and - the value is a chunk of Lua code, whose return value sets or replaces - the log field value. - ---- - -## Log format - -Every request is logged to the System log in [SYSLOG](https://en.wikipedia.org/wiki/Syslog) standard, with the -with `message` component formatted as described below. - -**Note:** Make sure the Syslog daemon is running on the instance and it's configured with the -logging level severity the same as or lower than the set `config.log_level` for this plugin. - -{% include /md/plugins-hub/log-format.md %} - -### JSON object considerations - -{% include /md/plugins-hub/json-object-log.md %} - -## Kong process errors - -{% include /md/plugins-hub/kong-process-errors.md %} - -## Custom Fields by Lua - -{% include /md/plugins-hub/log_custom_fields_by_lua.md %} diff --git a/app/_hub/kong-inc/syslog/_index.md b/app/_hub/kong-inc/syslog/_index.md index d2c86dc700df..a91fac162817 100644 --- a/app/_hub/kong-inc/syslog/_index.md +++ b/app/_hub/kong-inc/syslog/_index.md @@ -1,7 +1,6 @@ --- name: Syslog publisher: Kong Inc. -version: 2.2.x desc: Send request and response logs to Syslog description: | Log request and response data to Syslog. @@ -10,44 +9,9 @@ categories: - logging kong_version_compatibility: community_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x + compatible: true enterprise_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x + compatible: true params: name: syslog service_id: true @@ -94,6 +58,7 @@ params: An optional logging severity. Any request with equal or higher severity will be logged to System log. Available options: `debug`, `info`, `notice`, `warning`, `err`, `crit`, `alert`, `emerg`. - name: custom_fields_by_lua + minimum_version: "2.4.x" required: false default: null datatype: map @@ -102,6 +67,7 @@ params: the value is a chunk of Lua code, whose return value sets or replaces the log field value. - name: facility + minimum_version: "2.5.x" required: false default: '`user`' datatype: string @@ -130,6 +96,20 @@ logging level severity the same as or lower than the set `config.log_level` for {% include /md/plugins-hub/kong-process-errors.md %} +{% if_plugin_version gte:2.4.x %} + ## Custom Fields by Lua {% include /md/plugins-hub/log_custom_fields_by_lua.md %} + +{% endif_plugin_version %} + +--- +## Changelog + +**{{site.base_gateway}} 2.5.x** +* The plugin now includes facility configuration options, which are a way for the plugin to group error messages from different sources. + +**{{site.base_gateway}} 2.4.x** + +* Added `custom_fields_by_lua` configuration option. diff --git a/app/_hub/kong-inc/syslog/versions.yml b/app/_hub/kong-inc/syslog/versions.yml index bc466d57ec2e..bef6b22f649d 100644 --- a/app/_hub/kong-inc/syslog/versions.yml +++ b/app/_hub/kong-inc/syslog/versions.yml @@ -1,3 +1,12 @@ -- release: 2.0.x -- release: 1.0.x -- release: 0.1-x +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 2.2.0 + 2.7.x: 2.2.0 + 2.6.x: 2.2.0 + 2.5.x: 2.2.0 + 2.4.x: 2.1.0 + 2.3.x: 2.0.1 + 2.2.x: 2.0.1 + 2.1.x: 2.0.1 diff --git a/app/_hub/kong-inc/tcp-log/0.1-x.md b/app/_hub/kong-inc/tcp-log/0.1-x.md deleted file mode 100644 index c9432cf9b371..000000000000 --- a/app/_hub/kong-inc/tcp-log/0.1-x.md +++ /dev/null @@ -1,196 +0,0 @@ ---- -name: TCP Log -publisher: Kong Inc. -version: 0.1-x - -desc: Send request and response logs to a TCP server -description: | - Log request and response data to a TCP server. - -
- Note: The functionality of this plugin as bundled - with versions of Kong prior to 0.12.0 - differs from what is documented herein. Refer to the - CHANGELOG - for details. -
- -type: plugin -categories: - - logging - -kong_version_compatibility: - community_edition: - compatible: - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x - - 0.4.x - - 0.3.x - - 0.2.x - enterprise_edition: - compatible: - - 0.34-x - - 0.33-x - - 0.32-x - - 0.31-x - -params: - name: tcp-log - api_id: true - service_id: true - route_id: true - consumer_id: true - config: - - name: host - required: true - value_in_examples: 127.0.0.1 - description: The IP address or host name to send data to. - - name: port - required: true - value_in_examples: 9999 - description: The port to send data to on the upstream server - - name: timeout - required: false - default: "`10000`" - description: An optional timeout in milliseconds when sending data to the upstream server - - name: keepalive - required: false - default: "`60000`" - description: An optional value in milliseconds that defines for how long an idle connection will live before being closed - ---- - -## Log Format - -Every request will be logged separately in a JSON object, separated by a new line `\n`, with the following format: - -```json -{ - "request": { - "method": "GET", - "uri": "/get", - "url": "http://httpbin.org:8000/get", - "size": "75", - "querystring": {}, - "headers": { - "accept": "*/*", - "host": "httpbin.org", - "user-agent": "curl/7.37.1" - }, - "tls": { - "version": "TLSv1.2", - "cipher": "ECDHE-RSA-AES256-GCM-SHA384", - "supported_client_ciphers": "ECDHE-RSA-AES256-GCM-SHA384", - "client_verify": "NONE" - } - }, - "upstream_uri": "/", - "response": { - "status": 200, - "size": "434", - "headers": { - "Content-Length": "197", - "via": "kong/0.3.0", - "Connection": "close", - "access-control-allow-credentials": "true", - "Content-Type": "application/json", - "server": "nginx", - "access-control-allow-origin": "*" - } - }, - "tries": [ - { - "state": "next", - "code": 502, - "ip": "127.0.0.1", - "port": 8000 - }, - { - "ip": "127.0.0.1", - "port": 8000 - } - ], - "authenticated_entity": { - "consumer_id": "80f74eef-31b8-45d5-c525-ae532297ea8e", - "id": "eaa330c0-4cff-47f5-c79e-b2e4f355207e" - }, - "route": { - "created_at": 1521555129, - "hosts": null, - "id": "75818c5f-202d-4b82-a553-6a46e7c9a19e", - "methods": null, - "paths": [ - "/example-path" - ], - "preserve_host": false, - "protocols": [ - "http", - "https" - ], - "regex_priority": 0, - "service": { - "id": "0590139e-7481-466c-bcdf-929adcaaf804" - }, - "strip_path": true, - "updated_at": 1521555129 - }, - "service": { - "connect_timeout": 60000, - "created_at": 1521554518, - "host": "example.com", - "id": "0590139e-7481-466c-bcdf-929adcaaf804", - "name": "myservice", - "path": "/", - "port": 80, - "protocol": "http", - "read_timeout": 60000, - "retries": 5, - "updated_at": 1521554518, - "write_timeout": 60000 - }, - "consumer": { - "username": "demo", - "created_at": 1491847011000, - "id": "35b03bfc-7a5b-4a23-a594-aa350c585fa8" - }, - "latencies": { - "proxy": 1430, - "kong": 9, - "request": 1921 - }, - "client_ip": "127.0.0.1", - "started_at": 1433209822425 -} -``` - -A few considerations on the above JSON object: - -* `request` contains properties about the request sent by the client -* `response` contains properties about the response sent to the client -* `tries` contains the list of (re)tries (successes and failures) made by the load balancer for this request -* `route` contains Kong properties about the specific Route requested -* `service` contains Kong properties about the Service associated with the requested Route -* `authenticated_entity` contains Kong properties about the authenticated credential (if an authentication plugin has been enabled) -* `consumer` contains the authenticated Consumer (if an authentication plugin has been enabled) -* `latencies` contains some data about the latencies involved: - * `proxy` is the time it took for the final service to process the request - * `kong` is the internal Kong latency that it took to run all the plugins - * `request` is the time elapsed between the first bytes were read from the client and after the last bytes were sent to the client. Useful for detecting slow clients. -* `client_ip` contains the original client IP address -* `started_at` contains the UTC timestamp of when the request has started to be processed. - -Log plugins enabled on Services and Routes will contain information about the service or route. - ----- - -## Kong Process Errors - -This logging plugin will only log HTTP request and response data. If you are looking for the Kong process error file (which is the nginx error file), then you can find it at the following path: {[prefix](/gateway/latest/reference/configuration/#prefix)}/logs/error.log diff --git a/app/_hub/kong-inc/tcp-log/1.0.x.md b/app/_hub/kong-inc/tcp-log/1.0.x.md deleted file mode 100644 index b8aa7732b40f..000000000000 --- a/app/_hub/kong-inc/tcp-log/1.0.x.md +++ /dev/null @@ -1,224 +0,0 @@ ---- -name: TCP Log -publisher: Kong Inc. -version: 1.0.x - -desc: Send request and response logs to a TCP server -description: | - Log request and response data to a TCP server. - - -type: plugin -categories: - - logging - -kong_version_compatibility: - community_edition: - compatible: - - 2.3.x - - 2.2.x - - 2.1.x - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x - - 0.4.x - - 0.3.x - - 0.2.x - enterprise_edition: - compatible: - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x - -params: - name: tcp-log - service_id: true - route_id: true - consumer_id: true - protocols: ["http", "https", "grpc", "grpcs", "tcp", "tls", "udp"] - dbless_compatible: yes - config: - - name: host - required: true - value_in_examples: 127.0.0.1 - datatype: string - description: The IP address or host name to send data to. - - name: port - required: true - value_in_examples: 9999 - datatype: integer - description: The port to send data to on the upstream server. - - name: timeout - required: false - default: "`10000`" - datatype: number - description: An optional timeout in milliseconds when sending data to the upstream server. - - name: keepalive - required: false - default: "`60000`" - datatype: number - description: An optional value in milliseconds that defines how long an idle connection lives before being closed. - - name: tls - required: true - default: false - datatype: boolean - description: Indicates whether to perform a TLS handshake against the remote server. - - name: tls_sni - required: false - default: - datatype: string - description: An optional string that defines the SNI (Server Name Indication) hostname to send in the TLS handshake. - - ---- - -## Log Format - -Every request will be logged separately in a JSON object, separated by a new line `\n`, with the following format: - -```json -{ - "request": { - "method": "GET", - "uri": "/get", - "url": "http://httpbin.org:8000/get", - "size": "75", - "querystring": {}, - "headers": { - "accept": "*/*", - "host": "httpbin.org", - "user-agent": "curl/7.37.1" - }, - "tls": { - "version": "TLSv1.2", - "cipher": "ECDHE-RSA-AES256-GCM-SHA384", - "supported_client_ciphers": "ECDHE-RSA-AES256-GCM-SHA384", - "client_verify": "NONE" - } - }, - "upstream_uri": "/", - "response": { - "status": 200, - "size": "434", - "headers": { - "Content-Length": "197", - "via": "kong/0.3.0", - "Connection": "close", - "access-control-allow-credentials": "true", - "Content-Type": "application/json", - "server": "nginx", - "access-control-allow-origin": "*" - } - }, - "tries": [ - { - "state": "next", - "code": 502, - "ip": "127.0.0.1", - "port": 8000 - }, - { - "ip": "127.0.0.1", - "port": 8000 - } - ], - "authenticated_entity": { - "consumer_id": "80f74eef-31b8-45d5-c525-ae532297ea8e", - "id": "eaa330c0-4cff-47f5-c79e-b2e4f355207e" - }, - "route": { - "created_at": 1521555129, - "hosts": null, - "id": "75818c5f-202d-4b82-a553-6a46e7c9a19e", - "methods": null, - "paths": [ - "/example-path" - ], - "preserve_host": false, - "protocols": [ - "http", - "https" - ], - "regex_priority": 0, - "service": { - "id": "0590139e-7481-466c-bcdf-929adcaaf804" - }, - "strip_path": true, - "updated_at": 1521555129 - }, - "service": { - "connect_timeout": 60000, - "created_at": 1521554518, - "host": "example.com", - "id": "0590139e-7481-466c-bcdf-929adcaaf804", - "name": "myservice", - "path": "/", - "port": 80, - "protocol": "http", - "read_timeout": 60000, - "retries": 5, - "updated_at": 1521554518, - "write_timeout": 60000 - }, - "workspaces": [ - { - "id":"b7cac81a-05dc-41f5-b6dc-b87e29b6c3a3", - "name": "default" - } - ], - "consumer": { - "username": "demo", - "created_at": 1491847011000, - "id": "35b03bfc-7a5b-4a23-a594-aa350c585fa8" - }, - "latencies": { - "proxy": 1430, - "kong": 9, - "request": 1921 - }, - "client_ip": "127.0.0.1", - "started_at": 1433209822425 -} -``` - -A few considerations on the above JSON object: - -* `request` contains properties about the request sent by the client -* `response` contains properties about the response sent to the client -* `tries` contains the list of (re)tries (successes and failures) made by the load balancer for this request -* `route` contains Kong properties about the specific Route requested -* `service` contains Kong properties about the Service associated with the requested Route -* `authenticated_entity` contains Kong properties about the authenticated credential (if an authentication plugin has been enabled) -* `workspaces` contains Kong properties of the Workspaces associated with the requested Route. **Only in Kong Gateway version >= 0.34**. -* `consumer` contains the authenticated Consumer (if an authentication plugin has been enabled) -* `latencies` contains some data about the latencies involved: - * `proxy` is the time it took for the final service to process the request - * `kong` is the internal Kong latency that it took to run all the plugins - * `request` is the time elapsed between the first bytes were read from the client and after the last bytes were sent to the client. Useful for detecting slow clients. -* `client_ip` contains the original client IP address -* `started_at` contains the UTC timestamp of when the request has started to be processed. - -Log plugins enabled on Services and Routes will contain information about the service or route. - ----- - -## Kong Process Errors - -{% include /md/plugins-hub/kong-process-errors.md %} diff --git a/app/_hub/kong-inc/tcp-log/2.0.x.md b/app/_hub/kong-inc/tcp-log/2.0.x.md deleted file mode 100644 index bc782c0d5ecf..000000000000 --- a/app/_hub/kong-inc/tcp-log/2.0.x.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -name: TCP Log -publisher: Kong Inc. -version: 2.0.x -# internal handler version 2.0.1 - -desc: Send request and response logs to a TCP server -description: | - Log request and response data to a TCP server. - - -type: plugin -categories: - - logging - -kong_version_compatibility: - community_edition: - compatible: - - 2.3.x - - 2.2.x - - 2.1.x - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x - - 0.4.x - - 0.3.x - - 0.2.x - enterprise_edition: - compatible: - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x - -params: - name: tcp-log - service_id: true - route_id: true - consumer_id: true - protocols: ["http", "https", "grpc", "grpcs", "tcp", "tls", "udp"] - dbless_compatible: yes - config: - - name: host - required: true - value_in_examples: 127.0.0.1 - datatype: string - description: The IP address or host name to send data to. - - name: port - required: true - value_in_examples: 9999 - datatype: integer - description: The port to send data to on the upstream server. - - name: timeout - required: false - default: "`10000`" - datatype: number - description: An optional timeout in milliseconds when sending data to the upstream server. - - name: keepalive - required: false - default: "`60000`" - datatype: number - description: An optional value in milliseconds that defines how long an idle connection lives before being closed. - - name: tls - required: true - default: false - datatype: boolean - description: Indicates whether to perform a TLS handshake against the remote server. - - name: tls_sni - required: false - default: - datatype: string - description: An optional string that defines the SNI (Server Name Indication) hostname to send in the TLS handshake. - ---- - -## Log format - -{% include /md/plugins-hub/log-format.md %} - -### JSON object considerations - -{% include /md/plugins-hub/json-object-log.md %} - -## Kong process errors - -{% include /md/plugins-hub/kong-process-errors.md %} diff --git a/app/_hub/kong-inc/tcp-log/_index.md b/app/_hub/kong-inc/tcp-log/_index.md index dbd22098fa2c..adb69d5c9f07 100644 --- a/app/_hub/kong-inc/tcp-log/_index.md +++ b/app/_hub/kong-inc/tcp-log/_index.md @@ -1,7 +1,6 @@ --- name: TCP Log publisher: Kong Inc. -version: 2.1.x desc: Send request and response logs to a TCP server description: | Log request and response data to a TCP server. @@ -10,48 +9,9 @@ categories: - logging kong_version_compatibility: community_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x - - 0.4.x - - 0.3.x - - 0.2.x + compatible: true enterprise_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x + compatible: true params: name: tcp-log service_id: true @@ -99,6 +59,7 @@ params: datatype: string description: An optional string that defines the SNI (Server Name Indication) hostname to send in the TLS handshake. - name: custom_fields_by_lua + minimum_version: "2.4.x" required: false default: null datatype: map @@ -120,6 +81,15 @@ params: {% include /md/plugins-hub/kong-process-errors.md %} +{% if_plugin_version gte:2.4.x %} ## Custom Fields by Lua {% include /md/plugins-hub/log_custom_fields_by_lua.md %} +{% endif_plugin_version %} + +--- +## Changelog + +**{{site.base_gateway}} 2.4.x** + +* Added `custom_fields_by_lua` configuration option. diff --git a/app/_hub/kong-inc/tcp-log/versions.yml b/app/_hub/kong-inc/tcp-log/versions.yml index bc466d57ec2e..4c5a6d772c3f 100644 --- a/app/_hub/kong-inc/tcp-log/versions.yml +++ b/app/_hub/kong-inc/tcp-log/versions.yml @@ -1,3 +1,12 @@ -- release: 2.0.x -- release: 1.0.x -- release: 0.1-x +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 2.1.0 + 2.7.x: 2.1.0 + 2.6.x: 2.1.0 + 2.5.x: 2.1.0 + 2.4.x: 2.1.0 + 2.3.x: 2.0.1 + 2.2.x: 2.0.1 + 2.1.x: 2.0.1 diff --git a/app/_hub/kong-inc/tls-handshake-modifier/_index.md b/app/_hub/kong-inc/tls-handshake-modifier/_index.md new file mode 100644 index 000000000000..75d938f8891c --- /dev/null +++ b/app/_hub/kong-inc/tls-handshake-modifier/_index.md @@ -0,0 +1,69 @@ +--- +name: TLS Handshake Modifier +publisher: Kong Inc. + +desc: Requests a client to present its client certificate +description: | + The plugin requests, but does not require the client certificate. No validation + of the client certificate is performed. If a client certificate exists, + the plugin makes the certificate available to other plugins acting on this request. + + This plugin must be used in conjunction with the TLS Metadata Headers plugin. + +enterprise: true +plus: false # need to update this once we verify that this plugin is in Konnect post-3.0 update +cloud: false # need to update this once we verify that this plugin is in Konnect post-3.0 update +type: plugin +categories: + - security +kong_version_compatibility: + enterprise_edition: + compatible: + - 3.0.x +params: + name: tls-handshake-modifier + service_id: true + consumer_id: false + route_id: true + protocols: + - https + - grpcs + - tls + dbless_compatible: 'yes' + konnect_examples: false # need to update this once we verify that this plugin is in Konnect post-3.0 update + config: + - name: tls_client_certificate + required: false + default: REQUEST + datatype: string + description: | + Indicates the TLS handshake preference. The only option is `REQUEST`, which + requests the client certificate. +--- + +## Client certificate request + +Client certificates are requested in the `ssl_certificate_by_lua` phase where {{site.base_gateway}} does not +have access to `route` and `workspace` information. Due to this information gap, {{site.base_gateway}} asks for +the client certificate on every handshake if the `tls-handshake-modifier` plugin is configured on any route or service. + +In most cases, the failure of the client to present a client certificate doesn't affect subsequent +proxying if that route or service does not have the `tls-handshake-modifier` plugin applied. The exception is where +the client is a desktop browser, which prompts the end user to choose the client cert to send and +leads to user experience issues rather than proxy behavior problems. + +To improve this situation, Kong builds an in-memory map of SNIs from the configured {{site.base_gateway}} routes that should present a client +certificate. To limit client certificate requests during a handshake while ensuring the client +certificate is requested when needed, the in-memory map is dependent on all the routes in +{{site.base_gateway}} having the SNIs attribute set. When no routes have SNIs set, {{site.base_gateway}} must request +the client certificate during every TLS handshake: + +- On every request irrespective of workspace when the plugin is enabled in global workspace scope. +- On every request irrespective of workspace when the plugin is applied at the service level + and one or more of the routes *do not* have SNIs set. +- On every request irrespective of workspace when the plugin is applied at the route level + and one or more routes *do not* have SNIs set. +- On specific requests only when the plugin is applied at the route level and all routes have SNIs set. + +The result is all routes must have SNIs if you want to restrict the handshake request +for client certificates to specific requests. diff --git a/app/_hub/kong-inc/tls-handshake-modifier/versions.yml b/app/_hub/kong-inc/tls-handshake-modifier/versions.yml new file mode 100644 index 000000000000..c70068b9f9a2 --- /dev/null +++ b/app/_hub/kong-inc/tls-handshake-modifier/versions.yml @@ -0,0 +1,4 @@ +strategy: gateway + +releases: + - 3.0.x diff --git a/app/_hub/kong-inc/tls-metadata-headers/_index.md b/app/_hub/kong-inc/tls-metadata-headers/_index.md new file mode 100644 index 000000000000..c0d1f10a11fe --- /dev/null +++ b/app/_hub/kong-inc/tls-metadata-headers/_index.md @@ -0,0 +1,81 @@ +--- +name: TLS Metadata Headers +publisher: Kong Inc. + +desc: Proxies TLS client certificate metadata to upstream services via HTTP headers +description: | + The TLS Metadata Header plugin detects client certificates in requests, retrieves the TLS metadata, such as the URL encoded client certificate, and proxies this metadata via HTTP headers. + This is useful when an upstream service performs some validation for the proxied TLS client certificate. + + The plugin itself does not perform any validation on the client certificate. + + Used in conjunction with any plugin which requests a client certificate, such as the mTLS Authentication or TLS Handshake Modifier plugins. + +enterprise: true +plus: false # need to update this once we verify that this plugin is in Konnect post-3.0 update. +cloud: false # need to update this once we verify that this plugin is in Konnect post-3.0 update. +type: plugin +categories: + - security +kong_version_compatibility: + enterprise_edition: + compatible: + - 3.0.x +params: + name: tls-metadata-headers + service_id: true + consumer_id: false + route_id: true + protocols: + - https + - grpcs + - tls + dbless_compatible: 'yes' + konnect_examples: false # need to update this once we verify that this plugin is in Konnect post-3.0 update. + + config: + - name: inject_client_cert_details + required: true + default: false + datatype: boolean + value_in_examples: true + description: | + Enables TLS client certificate metadata values to be injected into HTTP headers. + - name: client_cert_header_name + required: true + default: X-Client-Cert + datatype: string + value_in_examples: X-Forwarded-Client-Cert + description: | + Define the HTTP header name used for the PEM format URL encoded client certificate. + - name: client_serial_header_name + required: true + default: X-Client-Cert-Serial + datatype: string + description: | + Define the HTTP header name used for the serial number of the client certificate. + - name: client_cert_issuer_dn_header_name + required: true + default: X-Client-Cert-Issuer-DN + datatype: string + value_in_examples: null + description: | + Define the HTTP header name used for the issuer DN of the client certificate. + - name: client_cert_subject_dn_header_name + required: true + default: X-Client-Cert-Subject-DN + datatype: string + description: | + Define the HTTP header name used for the subject DN of the client certificate. + - name: client_cert_fingerprint_header_name + required: true + default: X-Client-Cert-Fingerprint + datatype: string + description: | + Define the HTTP header name used for the SHA1 fingerprint of the client certificate. + + extra: | + + The plugin must be used in conjunction with any plugin which requests a client certificate, such as + the mTLS Authentication or TLS Handshake Modifier plugins. +--- diff --git a/app/_hub/kong-inc/tls-metadata-headers/versions.yml b/app/_hub/kong-inc/tls-metadata-headers/versions.yml new file mode 100644 index 000000000000..c70068b9f9a2 --- /dev/null +++ b/app/_hub/kong-inc/tls-metadata-headers/versions.yml @@ -0,0 +1,4 @@ +strategy: gateway + +releases: + - 3.0.x diff --git a/app/_hub/kong-inc/udp-log/0.1-x.md b/app/_hub/kong-inc/udp-log/0.1-x.md deleted file mode 100644 index 5fb876243131..000000000000 --- a/app/_hub/kong-inc/udp-log/0.1-x.md +++ /dev/null @@ -1,183 +0,0 @@ ---- -name: UDP Log -publisher: Kong Inc. -version: 0.1-x - -desc: Send request and response logs to a UDP server -description: | - Log request and response data to an UDP server. - -type: plugin -categories: - - logging - -kong_version_compatibility: - community_edition: - compatible: - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x - - 0.4.x - - 0.3.x - - 0.2.x - enterprise_edition: - compatible: - - 0.34-x - - 0.33-x - - 0.32-x - - 0.31-x - -params: - name: udp-log - api_id: true - service_id: true - route_id: true - consumer_id: true - config: - - name: host - required: true - value_in_examples: 127.0.0.1 - description: The IP address or host name to send data to. - - name: port - required: true - value_in_examples: 9999 - description: The port to send data to on the upstream server - - name: timeout - required: false - default: "`10000`" - value_in_examples: 10000 - description: An optional timeout in milliseconds when sending data to the upstream server - ---- - -## Log Format - -Every request will be logged separately in a JSON object with the following format: - -```json -{ - "request": { - "method": "GET", - "uri": "/get", - "url": "http://httpbin.org:8000/get", - "size": "75", - "querystring": {}, - "headers": { - "accept": "*/*", - "host": "httpbin.org", - "user-agent": "curl/7.37.1" - }, - "tls": { - "version": "TLSv1.2", - "cipher": "ECDHE-RSA-AES256-GCM-SHA384", - "supported_client_ciphers": "ECDHE-RSA-AES256-GCM-SHA384", - "client_verify": "NONE" - } - }, - "upstream_uri": "/", - "response": { - "status": 200, - "size": "434", - "headers": { - "Content-Length": "197", - "via": "kong/0.3.0", - "Connection": "close", - "access-control-allow-credentials": "true", - "Content-Type": "application/json", - "server": "nginx", - "access-control-allow-origin": "*" - } - }, - "tries": [ - { - "state": "next", - "code": 502, - "ip": "127.0.0.1", - "port": 8000 - }, - { - "ip": "127.0.0.1", - "port": 8000 - } - ], - "authenticated_entity": { - "consumer_id": "80f74eef-31b8-45d5-c525-ae532297ea8e", - "id": "eaa330c0-4cff-47f5-c79e-b2e4f355207e" - }, - "route": { - "created_at": 1521555129, - "hosts": null, - "id": "75818c5f-202d-4b82-a553-6a46e7c9a19e", - "methods": null, - "paths": [ - "/example-path" - ], - "preserve_host": false, - "protocols": [ - "http", - "https" - ], - "regex_priority": 0, - "service": { - "id": "0590139e-7481-466c-bcdf-929adcaaf804" - }, - "strip_path": true, - "updated_at": 1521555129 - }, - "service": { - "connect_timeout": 60000, - "created_at": 1521554518, - "host": "example.com", - "id": "0590139e-7481-466c-bcdf-929adcaaf804", - "name": "myservice", - "path": "/", - "port": 80, - "protocol": "http", - "read_timeout": 60000, - "retries": 5, - "updated_at": 1521554518, - "write_timeout": 60000 - }, - "consumer": { - "username": "demo", - "created_at": 1491847011000, - "id": "35b03bfc-7a5b-4a23-a594-aa350c585fa8" - }, - "latencies": { - "proxy": 1430, - "kong": 9, - "request": 1921 - }, - "client_ip": "127.0.0.1", - "started_at": 1433209822425 -} -``` - -A few considerations on the above JSON object: - -* `request` contains properties about the request sent by the client -* `response` contains properties about the response sent to the client -* `tries` contains the list of (re)tries (successes and failures) made by the load balancer for this request -* `route` contains Kong properties about the specific Route requested -* `service` contains Kong properties about the Service associated with the requested Route -* `authenticated_entity` contains Kong properties about the authenticated credential (if an authentication plugin has been enabled) -* `consumer` contains the authenticated Consumer (if an authentication plugin has been enabled) -* `latencies` contains some data about the latencies involved: - * `proxy` is the time it took for the final service to process the request - * `kong` is the internal Kong latency that it took to run all the plugins - * `request` is the time elapsed between the first bytes were read from the client and after the last bytes were sent to the client. Useful for detecting slow clients. -* `client_ip` contains the original client IP address -* `started_at` contains the UTC timestamp of when the request has started to be processed. - ----- - -## Kong Process Errors - -This logging plugin will only log HTTP request and response data. If you are looking for the Kong process error file (which is the nginx error file), then you can find it at the following path: {[prefix](/gateway/latest/reference/configuration/#prefix)}/logs/error.log diff --git a/app/_hub/kong-inc/udp-log/1.0.x.md b/app/_hub/kong-inc/udp-log/1.0.x.md deleted file mode 100644 index 4cd172371bf0..000000000000 --- a/app/_hub/kong-inc/udp-log/1.0.x.md +++ /dev/null @@ -1,207 +0,0 @@ ---- -name: UDP Log -publisher: Kong Inc. -version: 1.0.0 - -desc: Send request and response logs to a UDP server -description: | - Log request and response data to an UDP server. - -type: plugin -categories: - - logging - -kong_version_compatibility: - community_edition: - compatible: - - 2.3.x - - 2.2.x - - 2.1.x - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x - - 0.4.x - - 0.3.x - - 0.2.x - enterprise_edition: - compatible: - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x - -params: - name: udp-log - service_id: true - route_id: true - consumer_id: true - protocols: ["http", "https", "grpc", "grpcs", "tcp", "tls", "udp"] - dbless_compatible: yes - config: - - name: host - required: true - value_in_examples: 127.0.0.1 - datatype: string - description: The IP address or host name to send data to. - - name: port - required: true - value_in_examples: 9999 - datatype: integer - description: The port to send data to on the upstream server. - - name: timeout - required: false - default: "`10000`" - value_in_examples: 10000 - datatype: number - description: An optional timeout in milliseconds when sending data to the upstream server. - ---- - -## Log format - -Every request will be logged separately in a JSON object with the following format: - -```json -{ - "request": { - "method": "GET", - "uri": "/get", - "url": "http://httpbin.org:8000/get", - "size": "75", - "querystring": {}, - "headers": { - "accept": "*/*", - "host": "httpbin.org", - "user-agent": "curl/7.37.1" - }, - "tls": { - "version": "TLSv1.2", - "cipher": "ECDHE-RSA-AES256-GCM-SHA384", - "supported_client_ciphers": "ECDHE-RSA-AES256-GCM-SHA384", - "client_verify": "NONE" - } - - }, - "upstream_uri": "/", - "response": { - "status": 200, - "size": "434", - "headers": { - "Content-Length": "197", - "via": "kong/0.3.0", - "Connection": "close", - "access-control-allow-credentials": "true", - "Content-Type": "application/json", - "server": "nginx", - "access-control-allow-origin": "*" - } - }, - "tries": [ - { - "state": "next", - "code": 502, - "ip": "127.0.0.1", - "port": 8000 - }, - { - "ip": "127.0.0.1", - "port": 8000 - } - ], - "authenticated_entity": { - "consumer_id": "80f74eef-31b8-45d5-c525-ae532297ea8e", - "id": "eaa330c0-4cff-47f5-c79e-b2e4f355207e" - }, - "route": { - "created_at": 1521555129, - "hosts": null, - "id": "75818c5f-202d-4b82-a553-6a46e7c9a19e", - "methods": null, - "paths": [ - "/example-path" - ], - "preserve_host": false, - "protocols": [ - "http", - "https" - ], - "regex_priority": 0, - "service": { - "id": "0590139e-7481-466c-bcdf-929adcaaf804" - }, - "strip_path": true, - "updated_at": 1521555129 - }, - "service": { - "connect_timeout": 60000, - "created_at": 1521554518, - "host": "example.com", - "id": "0590139e-7481-466c-bcdf-929adcaaf804", - "name": "myservice", - "path": "/", - "port": 80, - "protocol": "http", - "read_timeout": 60000, - "retries": 5, - "updated_at": 1521554518, - "write_timeout": 60000 - }, - "workspaces": [ - { - "id":"b7cac81a-05dc-41f5-b6dc-b87e29b6c3a3", - "name": "default" - } - ], - "consumer": { - "username": "demo", - "created_at": 1491847011000, - "id": "35b03bfc-7a5b-4a23-a594-aa350c585fa8" - }, - "latencies": { - "proxy": 1430, - "kong": 9, - "request": 1921 - }, - "client_ip": "127.0.0.1", - "started_at": 1433209822425 -} -``` - -A few considerations on the above JSON object: - -* `request` contains properties about the request sent by the client -* `response` contains properties about the response sent to the client -* `tries` contains the list of (re)tries (successes and failures) made by the load balancer for this request -* `route` contains Kong properties about the specific Route requested -* `service` contains Kong properties about the Service associated with the requested Route -* `authenticated_entity` contains Kong properties about the authenticated credential (if an authentication plugin has been enabled) -* `workspaces` contains Kong properties of the Workspaces associated with the requested Route. **Only in Kong Gateway version >= 0.34**. -* `consumer` contains the authenticated Consumer (if an authentication plugin has been enabled) -* `latencies` contains some data about the latencies involved: - * `proxy` is the time it took for the final service to process the request - * `kong` is the internal Kong latency that it took to run all the plugins - * `request` is the time elapsed between the first bytes were read from the client and after the last bytes were sent to the client. Useful for detecting slow clients. -* `client_ip` contains the original client IP address -* `started_at` contains the UTC timestamp of when the request has started to be processed. - ----- - -## Kong Process Errors - -{% include /md/plugins-hub/kong-process-errors.md %} diff --git a/app/_hub/kong-inc/udp-log/2.0.x.md b/app/_hub/kong-inc/udp-log/2.0.x.md deleted file mode 100644 index fcf9bdf557c4..000000000000 --- a/app/_hub/kong-inc/udp-log/2.0.x.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -name: UDP Log -publisher: Kong Inc. -version: 2.0.x -# internal handler version 2.0.1 - -desc: Send request and response logs to a UDP server -description: | - Log request and response data to an UDP server. - -type: plugin -categories: - - logging - -kong_version_compatibility: - community_edition: - compatible: - - 2.3.x - - 2.2.x - - 2.1.x - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x - - 0.4.x - - 0.3.x - - 0.2.x - enterprise_edition: - compatible: - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x - -params: - name: udp-log - service_id: true - route_id: true - consumer_id: true - protocols: ["http", "https", "grpc", "grpcs", "tcp", "tls", "udp"] - dbless_compatible: yes - config: - - name: host - required: true - value_in_examples: 127.0.0.1 - datatype: string - description: The IP address or host name to send data to. - - name: port - required: true - value_in_examples: 9999 - datatype: integer - description: The port to send data to on the upstream server. - - name: timeout - required: false - default: "`10000`" - value_in_examples: 10000 - datatype: number - description: An optional timeout in milliseconds when sending data to the upstream server. - ---- - -## Log format - -{% include /md/plugins-hub/log-format.md %} - -### JSON object considerations - -{% include /md/plugins-hub/json-object-log.md %} - -## Kong process errors - -{% include /md/plugins-hub/kong-process-errors.md %} diff --git a/app/_hub/kong-inc/udp-log/_index.md b/app/_hub/kong-inc/udp-log/_index.md index 632a4da5d0a2..fdc012bfe0aa 100644 --- a/app/_hub/kong-inc/udp-log/_index.md +++ b/app/_hub/kong-inc/udp-log/_index.md @@ -1,7 +1,6 @@ --- name: UDP Log publisher: Kong Inc. -version: 2.1.x desc: Send request and response logs to a UDP server description: | Log request and response data to an UDP server. @@ -10,48 +9,9 @@ categories: - logging kong_version_compatibility: community_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - - 0.13.x - - 0.12.x - - 0.11.x - - 0.10.x - - 0.9.x - - 0.8.x - - 0.7.x - - 0.6.x - - 0.5.x - - 0.4.x - - 0.3.x - - 0.2.x + compatible: true enterprise_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x + compatible: true params: name: udp-log service_id: true @@ -85,6 +45,7 @@ params: datatype: number description: An optional timeout in milliseconds when sending data to the upstream server. - name: custom_fields_by_lua + minimum_version: "2.4.x" required: false default: null datatype: map @@ -106,6 +67,15 @@ params: {% include /md/plugins-hub/kong-process-errors.md %} +{% if_plugin_version gte:2.4.x %} ## Custom Fields by Lua {% include /md/plugins-hub/log_custom_fields_by_lua.md %} +{% endif_plugin_version %} + +--- +## Changelog + +**{{site.base_gateway}} 2.4.x** + +* Added `custom_fields_by_lua` configuration option. diff --git a/app/_hub/kong-inc/udp-log/versions.yml b/app/_hub/kong-inc/udp-log/versions.yml index bc466d57ec2e..4c5a6d772c3f 100644 --- a/app/_hub/kong-inc/udp-log/versions.yml +++ b/app/_hub/kong-inc/udp-log/versions.yml @@ -1,3 +1,12 @@ -- release: 2.0.x -- release: 1.0.x -- release: 0.1-x +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 2.1.0 + 2.7.x: 2.1.0 + 2.6.x: 2.1.0 + 2.5.x: 2.1.0 + 2.4.x: 2.1.0 + 2.3.x: 2.0.1 + 2.2.x: 2.0.1 + 2.1.x: 2.0.1 diff --git a/app/_hub/kong-inc/upstream-timeout/_index.md b/app/_hub/kong-inc/upstream-timeout/_index.md new file mode 100644 index 000000000000..fed50a4a1d04 --- /dev/null +++ b/app/_hub/kong-inc/upstream-timeout/_index.md @@ -0,0 +1,57 @@ +--- +name: Upstream Timeout +publisher: Kong Inc. +categories: + - traffic-control +type: plugin + +desc: Set timeouts on routes and override service-level timeouts +description: | + Use the Upstream Timeout plugin to configure route-specific timeouts. + This plugin overrides any service-level timeout settings. + +kong_version_compatibility: + enterprise_edition: + compatible: true + +cloud: true +enterprise: true +plus: false + +params: + name: upstream-timeout + service_id: false + consumer_id: false + route_id: true + protocols: + - http + - https + dbless_compatible: yes + config: + - name: connect_timeout + required: false + default: null + value_in_examples: 4000 + datatype: integer + description: | + The timeout, in milliseconds, for establishing a connection to the upstream server. + Overrides the service object [`connect_timeout`](/gateway/latest/how-kong-works/routing-traffic/#proxying-and-upstream-timeouts) setting, if the setting exists. + - name: send_timeout + required: false + default: null + value_in_examples: 5000 + datatype: integer + description: | + The timeout, in milliseconds, between two + successive write operations when sending a request to the upstream server. + Overrides the service object [`write_timeout`](/gateway/latest/how-kong-works/routing-traffic/#proxying-and-upstream-timeouts) setting, if the setting exists. + - name: read_timeout + required: false + default: null + value_in_examples: 5000 + datatype: integer + description: | + The timeout, in milliseconds, between two + successive read operations when receiving a response from the upstream server. + Overrides the service object [`read_timeout`](/gateway/latest/how-kong-works/routing-traffic/#proxying-and-upstream-timeouts) setting, if the setting exists. +--- diff --git a/app/_hub/kong-inc/upstream-timeout/versions.yml b/app/_hub/kong-inc/upstream-timeout/versions.yml new file mode 100644 index 000000000000..2df667592f0e --- /dev/null +++ b/app/_hub/kong-inc/upstream-timeout/versions.yml @@ -0,0 +1,12 @@ +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 0.1.1 + 2.7.x: 0.1.1 + 2.6.x: 0.1.1 + 2.5.x: 0.1.1 + 2.4.x: 0.1.1 + 2.3.x: 0.1.1 + 2.2.x: 0.1.1 + 2.1.x: 0.1.0 diff --git a/app/_hub/kong-inc/upstream-tls/0.35-x.md b/app/_hub/kong-inc/upstream-tls/0.35-x.md deleted file mode 100644 index c5aebad48c0c..000000000000 --- a/app/_hub/kong-inc/upstream-tls/0.35-x.md +++ /dev/null @@ -1,62 +0,0 @@ ---- - -name: Upstream TLS -publisher: Kong Inc. -version: 0.35-x - -desc: Add TLS to your Services -description: | - Enable TLS on upstream traffic by providing Kong with a list of trusted - certificates. - -enterprise: true -type: plugin -categories: - - authentication - -kong_version_compatibility: - enterprise_edition: - compatible: - - 0.35-x - -params: - name: upstream-tls - config: - - name: verify_mode - required: false - default: "`none`" - description: | - Sets the certification verification mode flags. `peer` enables client - peer validation. `none` disables client peer validation. - - name: verify_depth - required: false - default: "`4`" - description: | - Set the maximum validation chain depth - - name: trusted_certificates - required: true - default: - description: | - PEM-encoded public certificate authorities of the upstream - ---- - -Upstream TLS can be added on top of an existing Service by executing the -following request on your Kong server: - -```bash -$ curl -X POST http://kong:8001/services/1e6507e9-5c72-4dc2-9a3a-5131c4c5bea6/plugins \ - --form "name=upstream-tls" \ - --form "config.verify_mode=peer" \ - --form "config.trusted_certificates=@path_to_cert.pem" \ - --form "config.verify_depth=2" -``` - -`service`: the `id` or `name` of the Service that this plugin configuration will target. - -It can also be applied globally (for every Route, Service, or API) using the -`http://kong:8001/plugins/` endpoint. - -### Known Issues - -Only one root CA cert can be used to verify against the upstream. If you upload a pem file with multiple certs it must be the first certificate in your uploaded pem file. diff --git a/app/_hub/kong-inc/upstream-tls/_index.md b/app/_hub/kong-inc/upstream-tls/_index.md deleted file mode 100644 index cc27fce7c5d8..000000000000 --- a/app/_hub/kong-inc/upstream-tls/_index.md +++ /dev/null @@ -1,65 +0,0 @@ ---- -name: Upstream TLS -publisher: Kong Inc. -version: 0.36-x -desc: Add TLS to your Services -description: | - Enable TLS on upstream traffic by providing Kong with a list of trusted - certificates. -
-

This plugin is deprecated in Kong Gateway version 1.3, and removed in version 1.5.

-
-

Starting with Kong 1.3.0.0:

-

To configure Upstream TLS, use the NGINX directives proxy_ssl_trusted_certificate, proxy_ssl_verify, and proxy_ssl_verify_depth instead of the Upstream TLS plugin. Instructions on how to inject NGINX directives to Kong can be found here. This plugin is only functional for Kong Gateway versions 0.35 and 0.36.

-
-enterprise: true -type: plugin -kong_version_compatibility: - enterprise_edition: - compatible: - - 2.8.x - - 2.7.x - - 2.6.x - - 2.5.x - - 0.36-x - - 0.35-x -params: - name: upstream-tls - config: - - name: verify_mode - required: false - default: '`none`' - description: | - Sets the certification verification mode flags. `peer` enables client - peer validation. `none` disables client peer validation. - - name: verify_depth - required: false - default: '`4`' - description: | - Set the maximum validation chain depth - - name: trusted_certificates - required: true - default: null - description: | - PEM-encoded public certificate authorities of the upstream ---- - -In Enterprise versions 0.35 and 0.36, Upstream TLS can be added on top of an existing Service by executing the -following request on your Kong server: - -```bash -$ curl -X POST http://kong:8001/services/1e6507e9-5c72-4dc2-9a3a-5131c4c5bea6/plugins \ - --form "name=upstream-tls" \ - --form "config.verify_mode=peer" \ - --form "config.trusted_certificates=@path_to_cert.pem" \ - --form "config.verify_depth=2" -``` - -`service`: the `id` or `name` of the Service that this plugin configuration will target. - -It can also be applied globally (for every Route, Service, or API) using the -`http://kong:8001/plugins/` endpoint. - -### Known Issues - -PATCH requests to the `trust_certificates` configuration will not take affect until Kong is reloaded. This can be accomplished with the `kong reload` command. diff --git a/app/_hub/kong-inc/upstream-tls/versions.yml b/app/_hub/kong-inc/upstream-tls/versions.yml deleted file mode 100644 index bbc2a7c8db92..000000000000 --- a/app/_hub/kong-inc/upstream-tls/versions.yml +++ /dev/null @@ -1,2 +0,0 @@ -- release: 0.36-x -- release: 0.35-x diff --git a/app/_hub/kong-inc/vault-auth/0.2.2.md b/app/_hub/kong-inc/vault-auth/_0.2.2.md similarity index 100% rename from app/_hub/kong-inc/vault-auth/0.2.2.md rename to app/_hub/kong-inc/vault-auth/_0.2.2.md diff --git a/app/_hub/kong-inc/vault-auth/0.3.0.md b/app/_hub/kong-inc/vault-auth/_0.3.0.md similarity index 100% rename from app/_hub/kong-inc/vault-auth/0.3.0.md rename to app/_hub/kong-inc/vault-auth/_0.3.0.md diff --git a/app/_hub/kong-inc/vault-auth/_index.md b/app/_hub/kong-inc/vault-auth/_index.md index 9f49111812ec..11d3be5ac5d9 100644 --- a/app/_hub/kong-inc/vault-auth/_index.md +++ b/app/_hub/kong-inc/vault-auth/_index.md @@ -79,9 +79,13 @@ In order to use the plugin, you first need to create a Consumer to associate one You need to associate a credential to an existing [Consumer][consumer-object] object. To create a Consumer, you can execute the following request: ```bash -$ curl -X POST http://kong:8001/consumers/ \ - --data "username=" \ - --data "custom_id=" +curl -X POST http://kong:8001/consumers/ \ + --data "username=" \ + --data "custom_id=" +``` + +Response: +```json HTTP/1.1 201 Created { @@ -111,13 +115,13 @@ service, you must add the new consumer to an allowed group. See A Vault object represents the connection between Kong and a Vault server. It defines the connection and authentication information used to communicate with the Vault API. This allows different instances of the `vault-auth` plugin to communicate with different Vault servers, providing a flexible deployment and consumption model. Vault objects require setting a `vault_token` attribute. This attribute is _referenceable_, which means it can be securely stored as a -[secret](/gateway/latest/plan-and-deploy/security/secrets-management/getting-started) -in a vault. References must follow a [specific format](/gateway/latest/plan-and-deploy/security/secrets-management/reference-format). +[secret](/gateway/latest/kong-enterprise/security/secrets-management/getting-started) +in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/security/secrets-management/reference-format). Vault objects can be created via the following HTTP request: ```bash -$ curl -X POST http://localhost:8001/vault-auth \ +curl -X POST http://localhost:8001/vault-auth \ --header 'Content-Type: multipart/form-data' \ --form name=kong-auth \ --form mount=kong-auth \ @@ -127,7 +131,7 @@ $ curl -X POST http://localhost:8001/vault-auth \ --form vault_token= ``` -```bash +```json HTTP/1.1 201 Created { @@ -152,7 +156,11 @@ This assumes a Vault server is accessible via `127.0.0.1:8200`, and that a versi Token pairs can be managed either via the Kong Admin API, or independently via direct access with Vault. Token pairs must be associated with an existing Kong Consumer. Creating a token pair with the Kong Admin API can be done via the following request: ```bash -$ curl -X POST http://kong:8001/vault-auth/{vault}/credentials/{consumer} +curl -X POST http://kong:8001/vault-auth/{vault}/credentials/{consumer} +``` + +Response: +```json HTTP/1.1 201 Created { @@ -175,9 +183,13 @@ When the `access_token` or `secret_token` values are not provided, token values Vault objects are treated as foreign references in plugin configs, creating a seamless lifecycle relationship between Vault instances and plugins with which they're associated. `vault-auth` plugins require an association with a Vault object, which can be defined with the following HTTP request during plugin creation: ```bash -$ curl -X POST http://kong:8001/plugins \ +curl -X POST http://kong:8001/plugins \ --data name=vault-auth \ --data config.vault.id= +``` + +Response: +```json HTTP/1.1 201 Created { @@ -211,15 +223,15 @@ Where `` is the `id` of an existing Vault object. Simply make a request with the `access_token` and `secret_token` as querystring parameters: ```bash -$ curl http://kong:8000/{proxy path}?access_token=&secret_token= +curl http://kong:8000/{proxy path}?access_token=&secret_token= ``` Or in a header: ```bash -$ curl http://kong:8000/{proxy path} \ - -H 'access_token: ' \ - -H 'secret_token: ' +curl http://kong:8000/{proxy path} \ + -H 'access_token: ' \ + -H 'secret_token: ' ``` ### Deleting an Access/Secret Token Pair @@ -227,8 +239,11 @@ $ curl http://kong:8000/{proxy path} \ Existing Vault credentials can be removed from the Vault server via the following API: ```bash -$ curl -X DELETE http://kong:8001/vault-auth/{vault}/credentials/token/{access token} +curl -X DELETE http://kong:8001/vault-auth/{vault}/credentials/token/{access token} +``` +Response: +``` HTTP/1.1 204 No Content ``` @@ -258,7 +273,7 @@ Additional fields within the secret are ignored. The key must be the `access_tok `vault-auth` token pairs can be created with the Vault HTTP API or the `vault write` command: ```bash -$ vault write kong-auth/foo - < **Note**: Limits are evaluated based on the message payload length and not the +entire length of the WebSocket frame (header and payload). + +### Standalone data frames (`text` and `binary`) + +For limits of 125 bytes or less, the message length is checked after reading +and decoding the entire message into memory. + +For limits of 125 bytes or more, the message length is checked from the +frame header _before_ the entire message is read from the socket buffer, +allowing {{site.base_gateway}} to close the connection without having to read, and potentially +unmask, the entire message into memory. + +### Continuation data frames + +{{site.base_gateway}} aggregates `continuation` frames, buffering them in-memory before forwarding +them to their final destination. In addition to evaluating limits on an +individual frame basis, like singular `text` and `binary` frames, {{site.base_gateway}} +also tracks the running size of all the frames that are buffered for +aggregation. If an incoming `continuation` frame causes the total buffer size to +exceed the limit, the message is rejected, and the connection is closed. + +For example, assuming `client_max_payload = 1024`: + +``` + .------. .----. + |Client| |Kong| + '------' '----' + | | + | text(fin=false, len=500, msg=[...]) | + |>------------------------------------------->| # buffer += 500 (500) + | | + | | + | continue(fin=false, len=500, msg=[...]) | + |>------------------------------------------->| # buffer += 500 (1000) + | | + | | + | continue(fin=false, len=500, msg=[...]) | + |>------------------------------------------->| # buffer += 500 (1500) + | | # buffer >= 1024 (limit exceeded!) + | | + | close(status=1009, msg="Payload Too Large") | + |<-------------------------------------------<| + .------. .----. + |Client| |Kong| + '------' '----' +``` + +### For control frames + +All control frames (`ping`, `pong`, and `close`) have a max payload size of +`125` bytes, as per the WebSocket +[specification](https://datatracker.ietf.org/doc/html/rfc6455#section-5.5). {{site.base_gateway}} +does not enforce any limits on control frames, even when they're set to a value lower +than `125`. + + +## See also + +* [The complete WebSocket RFC](https://datatracker.ietf.org/doc/html/rfc6455) \ No newline at end of file diff --git a/app/_hub/kong-inc/websocket-size-limit/versions.yml b/app/_hub/kong-inc/websocket-size-limit/versions.yml new file mode 100644 index 000000000000..6a546b37e122 --- /dev/null +++ b/app/_hub/kong-inc/websocket-size-limit/versions.yml @@ -0,0 +1,4 @@ +strategy: gateway + +releases: + - 3.0.x \ No newline at end of file diff --git a/app/_hub/kong-inc/websocket-validator/_index.md b/app/_hub/kong-inc/websocket-validator/_index.md new file mode 100644 index 000000000000..9fa30afb48c8 --- /dev/null +++ b/app/_hub/kong-inc/websocket-validator/_index.md @@ -0,0 +1,216 @@ +--- +name: WebSocket Validator +publisher: Kong Inc. + +categories: + - traffic-control + +type: plugin + +desc: Validate WebSocket messages before they are proxied +description: | + Validate individual WebSocket messages against to a user-specified schema + before proxying them. + + Message schema can be configured by type (text or binary) and sender (client + or upstream). + + When an incoming message is invalid according to the schema, a close frame is + sent to the sender (status: `1007`) and the peer before closing the + connection. + + +kong_version_compatibility: + enterprise_edition: + compatible: + - 3.0.x + +cloud: true + +enterprise: true + +plus: true + +params: + name: websocket-validator + service_id: true + route_id: true + consumer_id: false + protocols: ["ws", "wss"] + dbless_compatible: 'yes' + config: + + - name: client.text.schema + required: semi + default: null + datatype: string + encrypted: false + value_in_examples: '''{ "type": "object" }''' + description: | + Schema used to validate client-originated text frames. The semantics of + this field depend on the validation type set by `config.client.text.type`. + + - name: client.text.type + required: semi + default: null + datatype: string + encrypted: false + value_in_examples: '''draft4''' + description: | + The corresponding validation library for `config.client.text.schema`. + Currently, only `draft4` is supported. + + + - name: client.binary.schema + required: semi + default: null + datatype: string + encrypted: false + value_in_examples: null + description: | + Schema used to validate client-originated binary frames. The semantics of + this field depend on the validation type set by `config.client.binary.type`. + + - name: client.binary.type + required: semi + default: null + datatype: string + encrypted: false + value_in_examples: null + description: | + The corresponding validation library for `config.client.binary.schema`. + Currently, only `draft4` is supported. + + + - name: upstream.text.schema + required: semi + default: null + datatype: string + encrypted: false + value_in_examples: null + description: | + Schema used to validate upstream-originated text frames. The semantics of + this field depend on the validation type set by `config.upstream.text.type`. + + - name: upstream.text.type + required: semi + default: null + datatype: string + encrypted: false + value_in_examples: null + description: | + The corresponding validation library for `config.upstream.text.schema`. + Currently, only `draft4` is supported. + + + - name: upstream.binary.schema + required: semi + default: null + datatype: string + encrypted: false + value_in_examples: null + description: | + Schema used to validate upstream-originated binary frames. The semantics of + this field depend on the validation type set by `config.upstream.binary.type`. + + - name: upstream.binary.type + required: semi + default: null + datatype: string + encrypted: false + value_in_examples: null + description: | + The corresponding validation library for `config.upstream.binary.schema`. + Currently, only `draft4` is supported. + extra: | + At least one of the following complete message validation configurations must be defined: + * `config.client.text.type` and `config.client.text.schema` + * `config.client.binary.type` and `config.client.binary.schema` + * `config.upstream.text.type` and `config.upstream.text.schema` + * `config.upstream.binary.type` and `config.upstream.binary.schema` + +--- + +## Usage + +{:.note} +> **Note**: Currently, the only supported validation type is [JSON schema +draft4](https://json-schema.org/specification-links.html#draft-4), so all +examples will use this. + +### Validate client text frames + +This example validates that client text frames: + +* Are valid JSON +* Are a JSON object (`{}`) +* Have a `name` attribute (of any type) + + +{% navtabs %} +{% navtab With a database %} + + +``` bash +curl -i -X POST http://HOSTNAME:8001/services/SERVICE/plugins \ + --data "name=websocket-validator" \ + --data "config.client.text.type=draft4" \ + --data 'config.client.text.schema={ "type": "object", "required": ["name"] }' +``` +{% endnavtab %} + +{% navtab Without a database %} + +Add the following entry to the `plugins:` section in the declarative configuration file: + +``` yaml +plugins: +- name: websocket-validator + service: SERVICE + config: + client: + text: + type: draft4 + schema: | + { + "type": "object", + "required": [ "name" ] + } +``` + +{% endnavtab %} +{% endnavtabs %} + + +Here's an example sequence for this configuration: + + +``` + .------. .----. .--------. + |Client| |Kong| |Upstream| + '------' '----' '--------' + | | | + | text(`{ "name": "Alex" }`) | | + |>----------------------------------->| | + | | | + | | text(`{ "name": "Alex" }`) | + | |>------------------------------->| + | | | + | text(`{ "name": "Kiran" }`) | | + |>----------------------------------->| | + | | | + | | text(`{ "name": "Kiran" }`) | + | |>------------------------------->| + | | | + | text(`{ "missing_name": true }`) | | + |>----------------------------------->| | + | | | + | close(status=1007) | | + |<-----------------------------------<| | + | | | + | | close() | + | |>------------------------------->| + .------. .----. .--------. + |Client| |Kong| |Upstream| + '------' '----' '--------' +``` diff --git a/app/_hub/kong-inc/websocket-validator/versions.yml b/app/_hub/kong-inc/websocket-validator/versions.yml new file mode 100644 index 000000000000..6a546b37e122 --- /dev/null +++ b/app/_hub/kong-inc/websocket-validator/versions.yml @@ -0,0 +1,4 @@ +strategy: gateway + +releases: + - 3.0.x \ No newline at end of file diff --git a/app/_hub/kong-inc/zipkin/0.1-x.md b/app/_hub/kong-inc/zipkin/0.1-x.md deleted file mode 100644 index ccd4a8ba8bfa..000000000000 --- a/app/_hub/kong-inc/zipkin/0.1-x.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -name: Zipkin -publisher: Kong Inc. -version: 0.1-x - -source_url: https://github.com/Kong/kong-plugin-zipkin - -desc: Propagate Zipkin spans and report space to a Zipkin server -description: | - Propagate Zipkin distributed tracing spans, and report spans to a Zipkin server. - -
- Note: The functionality of this plugin as bundled - with versions of Kong Gateway (OSS) prior to 0.14.1 and Kong Gateway prior to 0.34 - differs from what is documented herein. Refer to the - CHANGELOG - for details. -
- -type: plugin -categories: - - analytics-monitoring - -kong_version_compatibility: - community_edition: - compatible: - - 0.14.x - enterprise_edition: - compatible: - - 0.34-x - - 0.33-x - - 0.32-x - -params: - name: zipkin - api_id: true - service_id: true - route_id: true - consumer_id: true - konnect_examples: false - config: - - name: http_endpoint - required: true - default: "" - value_in_examples: http://your.zipkin.collector:9411/api/v2/spans - description: | - The full HTTP(S) endpoint to which Zipkin spans should be sent by Kong. - - name: sample_ratio - required: false - default: "`0.001`" - value_in_examples: 0.001 - description: | - How often to sample requests that do not contain trace ids. - Set to `0` to turn sampling off, or to `1` to sample **all** requests. - ---- - -## How it Works - -When enabled, [this plugin](https://github.com/Kong/kong-plugin-zipkin) traces requests in a way compatible with [zipkin](https://zipkin.io/). - -The code is structured around an [opentracing](http://opentracing.io/) core using the [opentracing-lua library](https://github.com/Kong/opentracing-lua) to collect timing data of a request in each of Kong's phases. -The plugin uses opentracing-lua compatible extractor, injector, and reporters to implement Zipkin's protocols. - -### Extractor and Injector - -An opentracing "extractor" collects information from an incoming request. -If no trace ID is present in the incoming request, then one is probabilistically generated based on the `sample_ratio` configuration value. - -An opentracing "injector" adds trace information to an outgoing request. Currently, the injector is only called for the request proxied by kong; it is **not** yet used for requests to the database or by other plugins (such as the [http-log plugin](/hub/kong-inc/http-log/)). - -This plugin follows Zipkin's ["B3" specification](https://github.com/openzipkin/b3-propagation/) as to which HTTP headers to use. Additionally, it supports [Jaegar](http://jaegertracing.io/)-style `uberctx-` headers for propagating [baggage](https://github.com/opentracing/specification/blob/master/specification.md#set-a-baggage-item). - - -### Reporter - -An opentracing "reporter" is how tracing data is reported to another system. -This plugin records tracing data for a given request, and sends it as a batch to a Zipkin server using [the Zipkin v2 API](https://zipkin.io/zipkin-api/#/default/post_spans). Note that zipkin version 1.31 or higher is required. - -The `http_endpoint` configuration variable must contain the full uri including scheme, host, port and path sections (i.e. your uri likely ends in `/api/v2/spans`). - - -## FAQ - -### Can I use this plugin with other tracing systems, like Jaeger? - -Probably! Jaeger accepts spans in Zipkin format - see https://www.jaegertracing.io/docs/features/#backwards-compatibility-with-zipkin for more information. diff --git a/app/_hub/kong-inc/zipkin/1.0.x.md b/app/_hub/kong-inc/zipkin/1.0.x.md deleted file mode 100644 index bcc671175a50..000000000000 --- a/app/_hub/kong-inc/zipkin/1.0.x.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -name: Zipkin -publisher: Kong Inc. -version: 1.0.0 - -source_url: https://github.com/Kong/kong-plugin-zipkin - -desc: Propagate Zipkin spans and report space to a Zipkin server -description: | - Propagate Zipkin distributed tracing spans, and report spans to a Zipkin server. - -
- Note: The functionality of this plugin as bundled - with versions of Kong Gateway (OSS) prior to 0.14.1 and Kong Gateway prior to 0.34 - differs from what is documented herein. Refer to the - CHANGELOG - for details. -
- -type: plugin -categories: - - analytics-monitoring - -kong_version_compatibility: - community_edition: - compatible: - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - enterprise_edition: - compatible: - - 1.5.x - - 1.3-x - - 0.36-x - - 0.35-x - - 0.34-x - - 0.33-x - - 0.32-x - -params: - name: zipkin - service_id: true - route_id: true - consumer_id: true - konnect_examples: false - protocols: ['http', 'https', 'tcp', 'tls', 'grpc', 'grpcs'] - dbless_compatible: yes - config: - - name: http_endpoint - required: true - default: '' - value_in_examples: http://your.zipkin.collector:9411/api/v2/spans - description: | - The full HTTP(S) endpoint to which Zipkin spans should be sent by Kong. - - name: sample_ratio - required: false - default: '`0.001`' - value_in_examples: 0.001 - description: | - How often to sample requests that do not contain trace ids. - Set to `0` to turn sampling off, or to `1` to sample **all** requests. - - name: include_credential - required: true - default: true - value_in_examples: true - description: | - Should the credential of the currently authenticated consumer be included in metadata sent to the Zipkin server? - ---- - -## How it Works - -When enabled, [this plugin](https://github.com/Kong/kong-plugin-zipkin) traces requests in a way compatible with [zipkin](https://zipkin.io/). - -The code is structured around an [opentracing](http://opentracing.io/) core using the [opentracing-lua library](https://github.com/Kong/opentracing-lua) to collect timing data of a request in each of Kong's phases. -The plugin uses opentracing-lua compatible extractor, injector, and reporters to implement Zipkin's protocols. - -### Extractor and Injector - -An opentracing "extractor" collects information from an incoming request. -If no trace ID is present in the incoming request, then one is probabilistically generated based on the `sample_ratio` configuration value. - -An opentracing "injector" adds trace information to an outgoing request. Currently, the injector is only called for the request proxied by kong; it is **not** yet used for requests to the database or by other plugins (such as the [http-log plugin](/hub/kong-inc/http-log/)). - -This plugin follows Zipkin's ["B3" specification](https://github.com/openzipkin/b3-propagation/) as to which HTTP headers to use. Additionally, it supports [Jaegar](http://jaegertracing.io/)-style `uberctx-` headers for propagating [baggage](https://github.com/opentracing/specification/blob/master/specification.md#set-a-baggage-item). - -### Reporter - -An opentracing "reporter" is how tracing data is reported to another system. -This plugin records tracing data for a given request, and sends it as a batch to a Zipkin server using [the Zipkin v2 API](https://zipkin.io/zipkin-api/#/default/post_spans). Note that zipkin version 1.31 or higher is required. - -The `http_endpoint` configuration variable must contain the full uri including scheme, host, port and path sections (i.e. your uri likely ends in `/api/v2/spans`). - -## FAQ - -### Can I use this plugin with other tracing systems, like Jaeger? - -Probably! Jaeger accepts spans in Zipkin format - see https://www.jaegertracing.io/docs/features/#backwards-compatibility-with-zipkin for more information. diff --git a/app/_hub/kong-inc/zipkin/1.1.x.md b/app/_hub/kong-inc/zipkin/1.1.x.md deleted file mode 100644 index 64b18e49be21..000000000000 --- a/app/_hub/kong-inc/zipkin/1.1.x.md +++ /dev/null @@ -1,115 +0,0 @@ ---- -name: Zipkin -publisher: Kong Inc. -version: 1.1.0 - -source_url: https://github.com/Kong/kong-plugin-zipkin - -desc: Propagate Zipkin spans and report space to a Zipkin server -description: | - Propagate Zipkin distributed tracing spans, and report spans to a Zipkin server. - -
- Note: The functionality of this plugin as bundled - with versions of Kong Gateway (OSS) prior to 0.14.1 and Kong Gateway prior to 0.34 - differs from what is documented herein. Refer to the - CHANGELOG - for details. -
- -type: plugin -categories: - - analytics-monitoring - -kong_version_compatibility: - community_edition: - compatible: - - 2.1.x - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - enterprise_edition: - compatible: - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x - - 0.35-x - - 0.34-x - - 0.33-x - - 0.32-x - -params: - name: zipkin - service_id: true - route_id: true - consumer_id: true - konnect_examples: false - protocols: ['http', 'https', 'tcp', 'tls', 'udp', 'grpc', 'grpcs'] - dbless_compatible: yes - config: - - name: http_endpoint - required: true - default: '' - value_in_examples: http://your.zipkin.collector:9411/api/v2/spans - description: | - The full HTTP(S) endpoint to which Zipkin spans should be sent by Kong. - - name: sample_ratio - required: false - default: '`0.001`' - value_in_examples: 0.001 - description: | - How often to sample requests that do not contain trace ids. - Set to `0` to turn sampling off, or to `1` to sample **all** requests. - - name: include_credential - required: true - default: true - value_in_examples: true - description: | - Should the credential of the currently authenticated consumer be included in metadata sent to the Zipkin server? - - name: traceid_byte_count - required: true - default: 16 - description: | - The length in bytes of each request's Trace ID. - - name: header_type - required: true - default: preserve - description: | - All HTTP requests going through the plugin will be tagged with a tracing HTTP request. - This property codifies what kind of tracing header the plugin expects on incoming requests. - Possible values are `b3`, `b3-single`, `w3c`, or `preserve`. The `b3` option means that - the plugin expects [Zipkin's B3 multiple headers](https://github.com/openzipkin/b3-propagation#multiple-headers) - on incoming requests, and will add them to the transmitted requests if they are missing from it. - The `b3-single` option expects or adds Zipkin's B3 single-header tracing headers. - The `w3c` option expects or adds W3C's traceparent tracing header. The `preserve` option - does not expect any format, and will transmit whatever header is recognized or present, - defaulting to `b3` if none is found. In case of mismatch between the expected and incoming - tracing headers (for example, when `header_type` is set to `b3` but a w3c-style tracing header is - found in the incoming request), then the plugin will add both kinds of tracing headers - to the request and generate a mismatch warning in the logs. - ---- - -## How it Works - -When enabled, [this plugin](https://github.com/Kong/kong-plugin-zipkin) traces requests in a way compatible with [zipkin](https://zipkin.io/). - -The code is structured around an [opentracing](http://opentracing.io/) core using the [opentracing-lua library](https://github.com/Kong/opentracing-lua) to collect timing data of a request in each of Kong's phases. -The plugin uses opentracing-lua compatible extractor, injector, and reporters to implement Zipkin's protocols. - -### Reporter - -An opentracing "reporter" is how tracing data is reported to another system. -This plugin records tracing data for a given request, and sends it as a batch to a Zipkin server using [the Zipkin v2 API](https://zipkin.io/zipkin-api/#/default/post_spans). Note that zipkin version 1.31 or higher is required. - -The `http_endpoint` configuration variable must contain the full uri including scheme, host, port and path sections (i.e. your uri likely ends in `/api/v2/spans`). - -### See also - -For more information, read the [Kong blog post](https://konghq.com/blog/tracing-with-zipkin-in-kong-2-1-0). diff --git a/app/_hub/kong-inc/zipkin/1.2.x.md b/app/_hub/kong-inc/zipkin/1.2.x.md deleted file mode 100644 index 51e852a4e277..000000000000 --- a/app/_hub/kong-inc/zipkin/1.2.x.md +++ /dev/null @@ -1,124 +0,0 @@ ---- -name: Zipkin -publisher: Kong Inc. -version: 1.2.x - -source_url: https://github.com/Kong/kong-plugin-zipkin - -desc: Propagate Zipkin spans and report space to a Zipkin server -description: | - Propagate Zipkin distributed tracing spans, and report spans to a Zipkin server. - - -type: plugin -categories: - - analytics-monitoring - -kong_version_compatibility: - community_edition: - compatible: - - 2.3.x - - 2.2.x - - 2.1.x - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - enterprise_edition: - compatible: - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x - -params: - name: zipkin - service_id: true - route_id: true - consumer_id: true - konnect_examples: false - protocols: ['http', 'https', 'tcp', 'tls', 'udp', 'grpc', 'grpcs'] - dbless_compatible: yes - config: - - name: http_endpoint - required: false - default: '' - value_in_examples: http://your.zipkin.collector:9411/api/v2/spans - description: | - The full HTTP(S) endpoint to which Zipkin spans should be sent by Kong. - If not specified, the Zipkin plugin will only act as a tracing header - generator/transmitter. - - name: sample_ratio - required: false - default: '`0.001`' - value_in_examples: 0.001 - description: | - How often to sample requests that do not contain trace ids. - Set to `0` to turn sampling off, or to `1` to sample **all** requests. - - name: include_credential - required: true - default: true - value_in_examples: true - description: | - Should the credential of the currently authenticated consumer be included in metadata sent to the Zipkin server? - - name: traceid_byte_count - required: true - default: 16 - description: | - The length in bytes of each request's Trace ID. - - name: header_type - required: true - default: preserve - description: | - All HTTP requests going through the plugin will be tagged with a tracing HTTP request. - This property codifies what kind of tracing header the plugin expects on incoming requests. - Possible values are `b3`, `b3-single`, `w3c`, or `preserve`. The `b3` option means that - the plugin expects [Zipkin's B3 multiple headers](https://github.com/openzipkin/b3-propagation#multiple-headers) - on incoming requests, and will add them to the transmitted requests if they are missing from it. - The `b3-single` option expects or adds Zipkin's B3 single-header tracing headers. - The `w3c` option expects or adds W3C's traceparent tracing header. The `preserve` option - does not expect any format, and will transmit whatever header is recognized or present, - defaulting to `b3` if none is found. In case of mismatch between the expected and incoming - tracing headers (for example, when `header_type` is set to `b3` but a w3c-style tracing header is - found in the incoming request), then the plugin will add both kinds of tracing headers - to the request and generate a mismatch warning in the logs. - - name: default_header_type - required: true - default: b3 - description: | - Allows specifying the type of header to be added to requests with no pre-existing tracing headers - and when `config.header_type` is set to `"preserve"`. - When `header_type` is set to any other value, `default_header_type` is ignored. - - name: static_tags - required: false - default: [] - value_in_examples: - description: | - The tags specified on this property will be added to the generated request traces. For example: - `[ { "name": "color", "value": "red" } ]`. - ---- - -## How it Works - -When enabled, [this plugin](https://github.com/Kong/kong-plugin-zipkin) traces requests in a way compatible with [zipkin](https://zipkin.io/). - -The code is structured around an [opentracing](http://opentracing.io/) core using the [opentracing-lua library](https://github.com/Kong/opentracing-lua) to collect timing data of a request in each of Kong's phases. -The plugin uses opentracing-lua compatible extractor, injector, and reporters to implement Zipkin's protocols. - -### Reporter - -An opentracing "reporter" is how tracing data is reported to another system. -This plugin records tracing data for a given request, and sends it as a batch to a Zipkin server using [the Zipkin v2 API](https://zipkin.io/zipkin-api/#/default/post_spans). Note that zipkin version 1.31 or higher is required. - -The `http_endpoint` configuration variable must contain the full uri including scheme, host, port and path sections (i.e. your uri likely ends in `/api/v2/spans`). - -### See also - -For more information, read the [Kong blog post](https://konghq.com/blog/tracing-with-zipkin-in-kong-2-1-0). diff --git a/app/_hub/kong-inc/zipkin/1.3.x.md b/app/_hub/kong-inc/zipkin/1.3.x.md deleted file mode 100644 index d058adb5e1eb..000000000000 --- a/app/_hub/kong-inc/zipkin/1.3.x.md +++ /dev/null @@ -1,194 +0,0 @@ ---- -name: Zipkin -publisher: Kong Inc. -version: 1.3.x - -source_url: https://github.com/Kong/kong-plugin-zipkin - -desc: Propagate Zipkin spans and report space to a Zipkin server -description: | - Propagate Zipkin distributed tracing spans, and report spans to a Zipkin server. - - -type: plugin -categories: - - analytics-monitoring - -kong_version_compatibility: - community_edition: - compatible: - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 2.0.x - - 1.5.x - - 1.4.x - - 1.3.x - - 1.2.x - - 1.1.x - - 1.0.x - - 0.14.x - enterprise_edition: - compatible: - - 2.4.x - - 2.3.x - - 2.2.x - - 2.1.x - - 1.5.x - - 1.3-x - - 0.36-x - -params: - name: zipkin - service_id: true - route_id: true - consumer_id: true - konnect_examples: false - protocols: ['http', 'https', 'tcp', 'tls', 'udp', 'grpc', 'grpcs'] - dbless_compatible: yes - config: - - name: http_endpoint - required: false - default: '' - value_in_examples: http://your.zipkin.collector:9411/api/v2/spans - datatype: string - description: | - The full HTTP(S) endpoint to which Zipkin spans should be sent by Kong. - If not specified, the Zipkin plugin will only act as a tracing header - generator/transmitter. - - name: sample_ratio - required: false - default: '`0.001`' - value_in_examples: 0.001 - datatype: number - description: | - How often to sample requests that do not contain trace ids. - Set to `0` to turn sampling off, or to `1` to sample **all** requests. The - value must be between zero (0) and one (1), inclusive. - - name: include_credential - required: true - default: true - value_in_examples: true - datatype: boolean - description: | - Should the credential of the currently authenticated consumer be included in metadata sent to the Zipkin server? - - name: traceid_byte_count - required: true - default: 16 - datatype: integer - description: | - The length in bytes of each request's Trace ID. The value can be either `8` or `16`. - - name: header_type - required: true - default: preserve - datatype: string - description: | - All HTTP requests going through the plugin will be tagged with a tracing HTTP request. - This property codifies what kind of tracing header the plugin expects on incoming requests. - Possible values are `b3`, `b3-single`, `w3c`, `preserve`, `jaeger`, or `ot`. The `b3` option means that - the plugin expects [Zipkin's B3 multiple headers](https://github.com/openzipkin/b3-propagation#multiple-headers) - on incoming requests, and will add them to the transmitted requests if they are missing from it. - The `b3-single` option expects or adds Zipkin's B3 single-header tracing headers. - The `w3c` option expects or adds W3C's traceparent tracing header. The `preserve` option - does not expect any format, and will transmit whatever header is recognized or present, - with a default of `b3` if none is found. In case of a mismatch between the expected and incoming - tracing headers (for example, when `header_type` is set to `b3` but a w3c-style tracing header is - found in the incoming request), then the plugin will add both kinds of tracing headers - to the request and generate a mismatch warning in the logs. `jaeger` will use and expect - [Jaeger-style tracing headers](https://www.jaegertracing.io/docs/1.22/client-libraries/#propagation-format) (`uber-trace-id`). - The `ot` option is for [OpenTelemetry tracing headers](https://github.com/open-telemetry/opentelemetry-java/blob/96e8523544f04c305da5382854eee06218599075/extensions/trace_propagators/src/main/java/io/opentelemetry/extensions/trace/propagation/OtTracerPropagator.java) of the form `ot-tracer-*`. - - name: default_header_type - required: true - default: b3 - datatype: string - description: | - Allows specifying the type of header to be added to requests with no pre-existing tracing headers - and when `config.header_type` is set to `"preserve"`. - When `header_type` is set to any other value, `default_header_type` is ignored. Possible values are - `b3`, `b3-single`, `w3c`, `jaeger`, or `ot`. - - name: tags_header - required: true - default: Zipkin-Tags - datatype: string - description: | - The Zipkin plugin will add extra headers to the tags associated with any HTTP - requests that come with a header named as configured by this property. The - format is `name_of_tag=value_of_tag`, separated by commas. For example: - with the default value, a request with the header - `Zipkin-Tags: fg=blue, bg=red` will generate a trace with the tag `fg` with - value `blue`, and another tag called `bg` with value `red`. - - name: static_tags - required: false - default: [] - value_in_examples: - datatype: array of string tags - description: | - The tags specified on this property will be added to the generated request traces. For example: - `[ { "name": "color", "value": "red" } ]`. - ---- - -## How it Works - -When enabled, [this plugin](https://github.com/Kong/kong-plugin-zipkin) traces requests in a way compatible with [zipkin](https://zipkin.io/). - -The code is structured around an [opentracing](http://opentracing.io/) core using the [opentracing-lua library](https://github.com/Kong/opentracing-lua) to collect timing data of a request in each of Kong's phases. -The plugin uses opentracing-lua compatible extractor, injector, and reporters to implement Zipkin's protocols. - -### Reporter - -An opentracing "reporter" is how tracing data is reported to another system. -This plugin records tracing data for a given request, and sends it as a batch to a Zipkin server using [the Zipkin v2 API](https://zipkin.io/zipkin-api/#/default/post_spans). Note that zipkin version 1.31 or higher is required. - -The `http_endpoint` configuration variable must contain the full uri including scheme, host, port and path sections (i.e. your uri likely ends in `/api/v2/spans`). - - -### Spans - -The plugin does *request sampling*. For each request which triggers the plugin, a random number between 0 and 1 is chosen. - -If the number is greater than the configured `sample_ratio`, then a trace with several spans will be generated. If `sample_ratio` is set to 1, then all requests will generate a trace (this might be very noisy). - -For each request that gets traced, the following spans are produced: - -* **Request span**: 1 per request. Encompasses the whole request in kong (kind: SERVER). - The Proxy and Balancer spans are children of this span. It contains the following logs/annotations for the rewrite phase: - - * `krs` - `kong.rewrite.start` - * `krf` - `kong.rewrite.finish` - - The Request span has the following tags: - - * `lc`: Hardcoded to `kong`. - * `kong.service`: The uuid of the service matched when processing the request, if any. - * `kong.route`: The uuid of the route matched when processing the request, if any (it can be nil on non-matched requests). - * `http.method`: The HTTP method used on the original request (only for HTTP requests). - * `http.path`: The path of the request (only for HTTP requests). - * If the plugin `tags_header` config option is set, and the request contains headers with the appropriate name and correct encoding tags, then the trace will include the tags. - * If the plugin `static_tags` config option is set, then the tags in the config option will be included in the trace. - -* **Proxy span**: 1 per request, encompassing most of Kong's internal processing of a request (kind: CLIENT). - Contains the following logs/annotations for the start/finish of the of the Kong plugin phases: - * `kas` - `kong.access.start` - * `kaf` - `kong.access.finish` - * `kbs` - `kong.body_filter.start` - * `kbf` - `kong.body_filter.finish` - * `khs` - `kong.header_filter.start` - * `khf` - `kong.header_filter.finish` - * `kps` - `kong.preread.start` (only for stream requests) - * `kpf` - `kong.preread.finish` (only for stream requests) - -* **Balancer span(s)**: 0 or more per request, each encompassing one balancer attempt (kind: CLIENT). -Contains the following tags specific to load balancing: - * `kong.balancer.try`: A number indicating the attempt (1 for the first load-balancing attempt, 2 for the second, and so on). - * `peer.ipv4` or `peer.ipv6` for the balancer IP. - * `peer.port` for the balanced port. - * `error`: Set to `true` if the balancing attempt was unsuccessful, otherwise unset. - * `http.status_code`: The HTTP status code received, in case of error. - * `kong.balancer.state`: An NGINX-specific description of the error, `next/failed` for HTTP failures, or `0` for stream failures. - Equivalent to `state_name` in OpenResty's balancer's `get_last_failure` function. - -### See also - -For more information, read the [Kong blog post](https://konghq.com/blog/tracing-with-zipkin-in-kong-2-1-0). diff --git a/app/_hub/kong-inc/zipkin/1.4.x.md b/app/_hub/kong-inc/zipkin/1.4.x.md deleted file mode 100644 index 06759fe1a713..000000000000 --- a/app/_hub/kong-inc/zipkin/1.4.x.md +++ /dev/null @@ -1,182 +0,0 @@ ---- -name: Zipkin -publisher: Kong Inc. -version: 1.4.x - -source_url: 'https://github.com/Kong/kong-plugin-zipkin' -desc: Propagate Zipkin spans and report space to a Zipkin server -description: | - Propagate Zipkin distributed tracing spans, and report spans to a Zipkin server. -type: plugin -categories: - - analytics-monitoring -kong_version_compatibility: - community_edition: - compatible: - - 2.6.x - - 2.5.x - enterprise_edition: - compatible: - - 2.6.x - - 2.5.x - - 2.4.x -params: - name: zipkin - service_id: true - route_id: true - consumer_id: true - konnect_examples: false - protocols: - - http - - https - - tcp - - tls - - udp - - grpc - - grpcs - dbless_compatible: 'yes' - config: - - name: http_endpoint - required: false - default: '' - value_in_examples: 'http://your.zipkin.collector:9411/api/v2/spans' - datatype: string - description: | - The full HTTP(S) endpoint to which Zipkin spans should be sent by Kong. - If not specified, the Zipkin plugin will only act as a tracing header - generator/transmitter. - - name: sample_ratio - required: false - default: '`0.001`' - value_in_examples: 0.001 - datatype: number - description: | - How often to sample requests that do not contain trace ids. - Set to `0` to turn sampling off, or to `1` to sample **all** requests. The - value must be between zero (0) and one (1), inclusive. - - name: include_credential - required: true - default: true - value_in_examples: true - datatype: boolean - description: | - Should the credential of the currently authenticated consumer be included in metadata sent to the Zipkin server? - - name: traceid_byte_count - required: true - default: 16 - datatype: integer - description: | - The length in bytes of each request's Trace ID. The value can be either `8` or `16`. - - name: header_type - required: true - default: preserve - datatype: string - description: | - All HTTP requests going through the plugin will be tagged with a tracing HTTP request. - This property codifies what kind of tracing header the plugin expects on incoming requests. - Possible values are `b3`, `b3-single`, `w3c`, `preserve`, `jaeger`, or `ot`. The `b3` option means that - the plugin expects [Zipkin's B3 multiple headers](https://github.com/openzipkin/b3-propagation#multiple-headers) - on incoming requests, and will add them to the transmitted requests if they are missing from it. - The `b3-single` option expects or adds Zipkin's B3 single-header tracing headers. - The `w3c` option expects or adds W3C's traceparent tracing header. The `preserve` option - does not expect any format, and will transmit whatever header is recognized or present, - with a default of `b3` if none is found. In case of a mismatch between the expected and incoming - tracing headers (for example, when `header_type` is set to `b3` but a w3c-style tracing header is - found in the incoming request), then the plugin will add both kinds of tracing headers - to the request and generate a mismatch warning in the logs. `jaeger` will use and expect - [Jaeger-style tracing headers](https://www.jaegertracing.io/docs/1.22/client-libraries/#propagation-format) (`uber-trace-id`). - The `ot` option is for [OpenTelemetry tracing headers](https://github.com/open-telemetry/opentelemetry-java/blob/96e8523544f04c305da5382854eee06218599075/extensions/trace_propagators/src/main/java/io/opentelemetry/extensions/trace/propagation/OtTracerPropagator.java) of the form `ot-tracer-*`. - - name: default_header_type - required: true - default: b3 - datatype: string - description: | - Allows specifying the type of header to be added to requests with no pre-existing tracing headers - and when `config.header_type` is set to `"preserve"`. - When `header_type` is set to any other value, `default_header_type` is ignored. Possible values are - `b3`, `b3-single`, `w3c`, `jaeger`, or `ot`. - - name: tags_header - required: true - default: Zipkin-Tags - datatype: string - description: | - The Zipkin plugin will add extra headers to the tags associated with any HTTP - requests that come with a header named as configured by this property. The - format is `name_of_tag=value_of_tag`, separated by commas. For example: - with the default value, a request with the header - `Zipkin-Tags: fg=blue, bg=red` will generate a trace with the tag `fg` with - value `blue`, and another tag called `bg` with value `red`. - - name: static_tags - required: false - default: [] - value_in_examples: null - datatype: array of string tags - description: | - The tags specified on this property will be added to the generated request traces. For example: - `[ { "name": "color", "value": "red" } ]`. ---- - -## How it Works - -When enabled, [this plugin](https://github.com/Kong/kong-plugin-zipkin) traces requests in a way compatible with [zipkin](https://zipkin.io/). - -The code is structured around an [opentracing](http://opentracing.io/) core using the [opentracing-lua library](https://github.com/Kong/opentracing-lua) to collect timing data of a request in each of Kong's phases. -The plugin uses opentracing-lua compatible extractor, injector, and reporters to implement Zipkin's protocols. - -### Reporter - -An opentracing "reporter" is how tracing data is reported to another system. -This plugin records tracing data for a given request, and sends it as a batch to a Zipkin server using [the Zipkin v2 API](https://zipkin.io/zipkin-api/#/default/post_spans). Note that zipkin version 1.31 or higher is required. - -The `http_endpoint` configuration variable must contain the full uri including scheme, host, port and path sections (i.e. your uri likely ends in `/api/v2/spans`). - -### Spans - -The plugin does *request sampling*. For each request which triggers the plugin, a random number between 0 and 1 is chosen. - -If the number is greater than the configured `sample_ratio`, then a trace with several spans will be generated. If `sample_ratio` is set to 1, then all requests will generate a trace (this might be very noisy). - -For each request that gets traced, the following spans are produced: - -* **Request span**: 1 per request. Encompasses the whole request in kong (kind: SERVER). - The Proxy and Balancer spans are children of this span. It contains the following logs/annotations for the rewrite phase: - - * `krs` - `kong.rewrite.start` - * `krf` - `kong.rewrite.finish` - - The Request span has the following tags: - - * `lc`: Hardcoded to `kong`. - * `kong.service`: The uuid of the service matched when processing the request, if any. - * `kong.service_name`: The name of the service matched when processing the request, if service exists and has a `name` attribute. - * `kong.route`: The uuid of the route matched when processing the request, if any (it can be nil on non-matched requests). - * `kong.route_name`: The name of the route matched when processing the request, if route exists and has a `name` attribute. - * `http.method`: The HTTP method used on the original request (only for HTTP requests). - * `http.path`: The path of the request (only for HTTP requests). - * If the plugin `tags_header` config option is set, and the request contains headers with the appropriate name and correct encoding tags, then the trace will include the tags. - * If the plugin `static_tags` config option is set, then the tags in the config option will be included in the trace. - -* **Proxy span**: 1 per request, encompassing most of Kong's internal processing of a request (kind: CLIENT). - Contains the following logs/annotations for the start/finish of the of the Kong plugin phases: - * `kas` - `kong.access.start` - * `kaf` - `kong.access.finish` - * `kbs` - `kong.body_filter.start` - * `kbf` - `kong.body_filter.finish` - * `khs` - `kong.header_filter.start` - * `khf` - `kong.header_filter.finish` - * `kps` - `kong.preread.start` (only for stream requests) - * `kpf` - `kong.preread.finish` (only for stream requests) - -* **Balancer span(s)**: 0 or more per request, each encompassing one balancer attempt (kind: CLIENT). -Contains the following tags specific to load balancing: - * `kong.balancer.try`: A number indicating the attempt (1 for the first load-balancing attempt, 2 for the second, and so on). - * `peer.ipv4` or `peer.ipv6` for the balancer IP. - * `peer.port` for the balanced port. - * `error`: Set to `true` if the balancing attempt was unsuccessful, otherwise unset. - * `http.status_code`: The HTTP status code received, in case of error. - * `kong.balancer.state`: An NGINX-specific description of the error, `next/failed` for HTTP failures, or `0` for stream failures. - Equivalent to `state_name` in OpenResty's balancer's `get_last_failure` function. - -### See also - -For more information, read the [Kong blog post](https://konghq.com/blog/tracing-with-zipkin-in-kong-2-1-0). diff --git a/app/_hub/kong-inc/zipkin/_index.md b/app/_hub/kong-inc/zipkin/_index.md index d042fc76c2aa..a7d2a02d525b 100644 --- a/app/_hub/kong-inc/zipkin/_index.md +++ b/app/_hub/kong-inc/zipkin/_index.md @@ -1,8 +1,6 @@ --- name: Zipkin publisher: Kong Inc. -version: 1.5.x -source_url: 'https://github.com/Kong/kong-plugin-zipkin' desc: Propagate Zipkin spans and report space to a Zipkin server description: | Propagate Zipkin distributed tracing spans, and report spans to a Zipkin server. @@ -11,13 +9,9 @@ categories: - analytics-monitoring kong_version_compatibility: community_edition: - compatible: - - 2.8.x - - 2.7.x + compatible: true enterprise_edition: - compatible: - - 2.8.x - - 2.7.x + compatible: true params: name: zipkin service_id: true @@ -35,6 +29,7 @@ params: dbless_compatible: 'yes' config: - name: local_service_name + minimum_version: "2.7.x" required: true default: kong datatype: string @@ -73,7 +68,56 @@ params: datatype: integer description: | The length in bytes of each request's Trace ID. The value can be either `8` or `16`. + + # ----- 2.3.x and earlier version of the 'header_type' parameter ----- - name: header_type + maximum_version: "2.3.x" + required: true + default: preserve + datatype: string + description: | + All HTTP requests going through the plugin are tagged with a tracing HTTP request. + This property codifies what kind of tracing header the plugin expects on incoming requests. + + Possible values: `b3`, `b3-single`, `w3c`, `preserve`, `jaeger`, `ot`, or `ignore`. + * `b3`: Expects [Zipkin's B3 multiple headers](https://github.com/openzipkin/b3-propagation#multiple-headers) + on incoming requests, and will add them to the transmitted requests if the headers are missing from those requests. + * `b3-single`: Expects or adds Zipkin's B3 single-header tracing headers. + * `w3c`: Expects or adds W3C's traceparent tracing header. + * `preserve`: Does not expect any format, and will transmit whatever header is recognized or present, + with a default of `b3` if none is found. In case of a mismatch between the expected and incoming + tracing headers (for example, when `header_type` is set to `b3` but a w3c-style tracing header is + found in the incoming request), then the plugin will add both kinds of tracing headers + to the request and generate a mismatch warning in the logs. + + # ----- 2.4.x-2.6.x version of the 'header_type' parameter ----- + - name: header_type + minimum_version: "2.4.x" + maximum_version: "2.6.x" + required: true + default: preserve + datatype: string + description: | + All HTTP requests going through the plugin are tagged with a tracing HTTP request. + This property codifies what kind of tracing header the plugin expects on incoming requests. + + Possible values: `b3`, `b3-single`, `w3c`, `preserve`, `jaeger`, `ot`, or `ignore`. + * `b3`: Expects [Zipkin's B3 multiple headers](https://github.com/openzipkin/b3-propagation#multiple-headers) + on incoming requests, and will add them to the transmitted requests if the headers are missing from those requests. + * `b3-single`: Expects or adds Zipkin's B3 single-header tracing headers. + * `w3c`: Expects or adds W3C's traceparent tracing header. + * `preserve`: Does not expect any format, and will transmit whatever header is recognized or present, + with a default of `b3` if none is found. In case of a mismatch between the expected and incoming + tracing headers (for example, when `header_type` is set to `b3` but a w3c-style tracing header is + found in the incoming request), then the plugin will add both kinds of tracing headers + to the request and generate a mismatch warning in the logs. + * `jaeger`: Expects or adds + [Jaeger-style tracing headers](https://www.jaegertracing.io/docs/1.22/client-libraries/#propagation-format) (`uber-trace-id`). + * `ot`: Expects or adds [OpenTelemetry tracing headers](https://github.com/open-telemetry/opentelemetry-java/blob/96e8523544f04c305da5382854eee06218599075/extensions/trace_propagators/src/main/java/io/opentelemetry/extensions/trace/propagation/OtTracerPropagator.java) of the form `ot-tracer-*`. + # ---------------------------------------------------------- + + - name: header_type # current version of param + minimum_version: "2.7.x" required: true default: preserve datatype: string @@ -98,6 +142,7 @@ params: Starts a new request using the `default_header_type` value, or falls back to `b3` if there is no `default_header_type` value set. - name: default_header_type + minimum_version: "2.3.x" required: true default: b3 datatype: string @@ -109,6 +154,7 @@ params: Possible values are `b3`, `b3-single`, `w3c`, `jaeger`, or `ot`. See the entry for `header_type` for value definitions. - name: tags_header + minimum_version: "2.4.x" required: true default: Zipkin-Tags datatype: string @@ -121,6 +167,7 @@ params: `Zipkin-Tags: fg=blue, bg=red` will generate a trace with the tag `fg` with value `blue`, and another tag called `bg` with value `red`. - name: static_tags + minimum_version: "2.3.x" required: false default: [] value_in_examples: null @@ -128,22 +175,60 @@ params: description: | The tags specified on this property will be added to the generated request traces. For example: `[ { "name": "color", "value": "red" } ]`. ---- + - name: http_span_name + minimum_version: "3.0.x" + required: true + default: method + value_in_examples: null + datatype: string + description: | + Specify whether to include the HTTP path in the span name. + + Options: + * `method`: Do not include the HTTP path. This is the default. + * `method_path`: Include the HTTP path. + + - name: connect_timeout + minimum_version: "3.0.x" + required: false + default: 2000 + value_in_examples: null + datatype: number + description: The timeout, in milliseconds, for establishing a connection to the Zipkin server. + - name: send_timeout + minimum_version: "3.0.x" + required: false + default: 5000 + value_in_examples: null + datatype: number + description: The timeout, in milliseconds, between two + successive write operations when sending a request to the Zipkin server. + - name: read_timeout + minimum_version: "3.0.x" + required: false + default: 5000 + value_in_examples: null + datatype: number + description: The timeout, in milliseconds, between two + successive read operations when receiving a response from the Zipkin server. + +--- ## How it Works When enabled, [this plugin](https://github.com/Kong/kong-plugin-zipkin) traces requests in a way compatible with [zipkin](https://zipkin.io/). -The code is structured around an [opentracing](http://opentracing.io/) core using the [opentracing-lua library](https://github.com/Kong/opentracing-lua) to collect timing data of a request in each of Kong's phases. -The plugin uses opentracing-lua compatible extractor, injector, and reporters to implement Zipkin's protocols. +The code is structured around an [OpenTracing](http://opentracing.io/) core using the [opentracing-lua library](https://github.com/Kong/opentracing-lua) to collect timing data of a request in each of Kong's phases. +The plugin uses `opentracing-lua` compatible extractor, injector, and reporters to implement Zipkin's protocols. ### Reporter -An opentracing "reporter" is how tracing data is reported to another system. +An OpenTracing "reporter" is how tracing data is reported to another system. This plugin records tracing data for a given request, and sends it as a batch to a Zipkin server using [the Zipkin v2 API](https://zipkin.io/zipkin-api/#/default/post_spans). Note that zipkin version 1.31 or higher is required. The `http_endpoint` configuration variable must contain the full uri including scheme, host, port and path sections (i.e. your uri likely ends in `/api/v2/spans`). +{% if_plugin_version gte:2.4.x %} ### Spans The plugin does *request sampling*. For each request which triggers the plugin, a random number between 0 and 1 is chosen. @@ -162,9 +247,11 @@ For each request that gets traced, the following spans are produced: * `lc`: Hardcoded to `kong`. * `kong.service`: The uuid of the service matched when processing the request, if any. + {% if_plugin_version gte:2.5.x %} * `kong.service_name`: The name of the service matched when processing the request, if service exists and has a `name` attribute. * `kong.route`: The uuid of the route matched when processing the request, if any (it can be nil on non-matched requests). * `kong.route_name`: The name of the route matched when processing the request, if route exists and has a `name` attribute. + {% endif_plugin_version%} * `http.method`: The HTTP method used on the original request (only for HTTP requests). * `http.path`: The path of the request (only for HTTP requests). * If the plugin `tags_header` config option is set, and the request contains headers with the appropriate name and correct encoding tags, then the trace will include the tags. @@ -191,6 +278,8 @@ Contains the following tags specific to load balancing: * `kong.balancer.state`: An NGINX-specific description of the error, `next/failed` for HTTP failures, or `0` for stream failures. Equivalent to `state_name` in OpenResty's balancer's `get_last_failure` function. +{% endif_plugin_version %} + ### See also For more information, read the [Kong blog post](https://konghq.com/blog/tracing-with-zipkin-in-kong-2-1-0). @@ -199,7 +288,29 @@ For more information, read the [Kong blog post](https://konghq.com/blog/tracing- ## Changelog -### 1.5.x +**{{site.base_gateway}} 3.0.x** + +* Added support for including the HTTP path in the span name with the +`http_span_name` configuration parameter. +[#8150](https://github.com/Kong/kong/pull/8150) +* Added support for socket connect and send/read timeouts + through the `connect_timeout`, `send_timeout`, + and `read_timeout` configuration parameters. This can help mitigate + `ngx.timer` saturation when upstream collectors are unavailable or slow. + [#8735](https://github.com/Kong/kong/pull/8735) + +**{{site.base_gateway}} 2.7.x** * Added a new parameter: `local_service_name` * Added a new `ignore` option for the `header_type` parameter + +**{{site.base_gateway}} 2.5.x** +* The plugin now includes the following tags: `kong.route`, `kong.service_name`, and `kong.route_name`. + +**{{site.base_gateway}} 2.4.x** +* Added support for OT and Jaeger style `uber-trace-id` headers. +* The plugin now allows insertion of custom tags on the Zipkin request trace. +* The plugin now allows the creation of baggage items on child spans. + +**{{site.base_gateway}} 2.3.x** +* Added the `default_header_type` and `static_tags` configuration parameters. diff --git a/app/_hub/kong-inc/zipkin/versions.yml b/app/_hub/kong-inc/zipkin/versions.yml index 139840d07629..967ef9c05387 100644 --- a/app/_hub/kong-inc/zipkin/versions.yml +++ b/app/_hub/kong-inc/zipkin/versions.yml @@ -1,7 +1,12 @@ -- release: 1.5.x -- release: 1.4.x -- release: 1.3.x -- release: 1.2.x -- release: 1.1.x -- release: 1.0.x -- release: 0.1-x +strategy: gateway +delegate_releases: true + +overrides: + 2.8.x: 1.5.0 + 2.7.x: 1.5.0 + 2.6.x: 1.4.1 + 2.5.x: 1.4.1 + 2.4.x: 1.3.0 + 2.3.x: 1.2.0 + 2.2.x: 1.1.0 + 2.1.x: 1.1.0 diff --git a/app/_hub/moesif/kong-plugin-moesif/_index.md b/app/_hub/moesif/kong-plugin-moesif/_index.md index 91023b33f4b8..0900bee200a7 100644 --- a/app/_hub/moesif/kong-plugin-moesif/_index.md +++ b/app/_hub/moesif/kong-plugin-moesif/_index.md @@ -25,7 +25,7 @@ description: | support_url: https://www.moesif.com/implementation/log-http-calls-from-kong-api-gateway?utm_medium=docs&utm_campaign=partners&utm_source=kong -source_url: https://github.com/Moesif/kong-plugin-moesif +source_code: https://github.com/Moesif/kong-plugin-moesif license_url: https://raw.githubusercontent.com/Moesif/kong-plugin-moesif/master/LICENSE diff --git a/app/_hub/okta/okta/_index.md b/app/_hub/okta/okta/_index.md index 4ce13b91186b..4d373640c01f 100644 --- a/app/_hub/okta/okta/_index.md +++ b/app/_hub/okta/okta/_index.md @@ -18,7 +18,7 @@ description: | support_url: https://github.com/tom-smith-okta/okta-api-center/issues -source_url: https://github.com/tom-smith-okta/okta-api-center/tree/master/gateways/kong +source_code: https://github.com/tom-smith-okta/okta-api-center/tree/master/gateways/kong kong_version_compatibility: community_edition: diff --git a/app/_hub/optum/kong-response-size-limiting/_index.md b/app/_hub/optum/kong-response-size-limiting/_index.md index 068884c1cd2f..9d414e2257be 100644 --- a/app/_hub/optum/kong-response-size-limiting/_index.md +++ b/app/_hub/optum/kong-response-size-limiting/_index.md @@ -15,7 +15,7 @@ categories: support_url: https://github.com/Optum/kong-response-size-limiting/issues -source_url: https://github.com/Optum/kong-response-size-limiting/ +source_code: https://github.com/Optum/kong-response-size-limiting/ license_type: Apache-2.0 diff --git a/app/_hub/optum/kong-service-virtualization/_index.md b/app/_hub/optum/kong-service-virtualization/_index.md index 0e14ff1fa498..beb7e9d4c1a4 100644 --- a/app/_hub/optum/kong-service-virtualization/_index.md +++ b/app/_hub/optum/kong-service-virtualization/_index.md @@ -14,7 +14,7 @@ description: | support_url: https://github.com/Optum/kong-service-virtualization/issues -source_url: https://github.com/Optum/kong-service-virtualization +source_code: https://github.com/Optum/kong-service-virtualization license_type: Apache-2.0 diff --git a/app/_hub/optum/kong-spec-expose/_index.md b/app/_hub/optum/kong-spec-expose/_index.md index b52a18d91469..f32e630d9173 100644 --- a/app/_hub/optum/kong-spec-expose/_index.md +++ b/app/_hub/optum/kong-spec-expose/_index.md @@ -19,7 +19,7 @@ description: | support_url: https://github.com/Optum/kong-spec-expose/issues -source_url: https://github.com/Optum/kong-spec-expose/ +source_code: https://github.com/Optum/kong-spec-expose/ license_type: Apache-2.0 diff --git a/app/_hub/optum/kong-splunk-log/_index.md b/app/_hub/optum/kong-splunk-log/_index.md index 758a708460e2..8ecfdc29e267 100644 --- a/app/_hub/optum/kong-splunk-log/_index.md +++ b/app/_hub/optum/kong-splunk-log/_index.md @@ -14,7 +14,7 @@ description: | support_url: https://github.com/Optum/kong-splunk-log/issues -source_url: https://github.com/Optum/kong-splunk-log +source_code: https://github.com/Optum/kong-splunk-log license_type: Apache-2.0 diff --git a/app/_hub/optum/kong-upstream-jwt/_index.md b/app/_hub/optum/kong-upstream-jwt/_index.md index 6e16c75400b6..b865dbd86e37 100644 --- a/app/_hub/optum/kong-upstream-jwt/_index.md +++ b/app/_hub/optum/kong-upstream-jwt/_index.md @@ -20,7 +20,7 @@ description: | support_url: https://github.com/Optum/kong-upstream-jwt/issues -source_url: https://github.com/Optum/kong-upstream-jwt/ +source_code: https://github.com/Optum/kong-upstream-jwt/ license_type: Apache-2.0 diff --git a/app/_hub/peter-evans/paseto/_index.md b/app/_hub/peter-evans/paseto/_index.md index a26c4e2b64b9..d2460d8a141b 100644 --- a/app/_hub/peter-evans/paseto/_index.md +++ b/app/_hub/peter-evans/paseto/_index.md @@ -30,7 +30,7 @@ description: | support_url: https://github.com/peter-evans/kong-plugin-paseto/issues -source_url: https://github.com/peter-evans/kong-plugin-paseto +source_code: https://github.com/peter-evans/kong-plugin-paseto license_type: MIT diff --git a/app/konnect-platform/compatibility/plugins.md b/app/_hub/plugins/compatibility/_index.md similarity index 93% rename from app/konnect-platform/compatibility/plugins.md rename to app/_hub/plugins/compatibility/_index.md index 246913aa0196..c0d8f9174d38 100644 --- a/app/konnect-platform/compatibility/plugins.md +++ b/app/_hub/plugins/compatibility/_index.md @@ -3,15 +3,13 @@ title: Plugin Compatibility no_version: true --- -## Introduction - Each [subscription tier](https://konghq.com/pricing) gives you access to a subset of plugins: * **Free tier:** Open-source Kong plugins * **Plus tier:** Open-source and Plus-specific plugins * **Enterprise tier:** All Kong plugins -### Network configuration options +## Network configuration options {{site.konnect_short_name}} can be configured in the following ways: @@ -65,23 +63,23 @@ see [{{site.ee_product_name}} for Kubernetes Deployment Options](/gateway/latest {% if plugin.free == true %} - ✅  + {% elsif plugin.free == false %} - ❌  + {% endif %} {% if plugin.plus == true %} - ✅  + {% elsif plugin.plus == false %} - ❌  + {% endif %} {% if plugin.enterprise == true %} - ✅  + {% elsif plugin.enterprise == false %} - ❌  + {% endif %} diff --git a/app/_hub/plugins/overview/_index.md b/app/_hub/plugins/overview/_index.md index 0e5e6a64410b..ec877121eac4 100644 --- a/app/_hub/plugins/overview/_index.md +++ b/app/_hub/plugins/overview/_index.md @@ -3,108 +3,4 @@ title: Plugin Overview header_title: Plugin Overview type: concept --- -## What are plugins? - -Kong is a Lua application designed to load and execute Lua or Go modules, which -we commonly refer to as _plugins_. Kong provides a set of standard Lua -plugins that get bundled with {{site.base_gateway}}. The set of plugins you -have access to depends on your installation: open-source, enterprise, or either -of these {{site.base_gateway}} options running on Kubernetes. - -Custom plugins can also be developed by the Kong Community, and are supported -and maintained by the plugin creators. If they are published on the Kong Plugin -Hub, they are called Community or Third-Party plugins. For the full explanation -of what this means, see the [Terminology](#terminology) section. - -## Why use plugins? - -Plugins provide advanced functionality and extend the use of the {{site.base_gateway}}, -which allows you to add new features to your implementation. Plugins can be configured to run in -a variety of contexts, ranging from a specific Route to all Upstreams, and can -execute actions inside Kong before or after a request has been proxied to the -upstream API, as well as on any incoming responses. - -## Plugin compatibility with deployment types - -{{site.base_gateway}} can be deployed in a variety of ways, and not all plugins -are fully compatible with each mode. See [Plugin Compatibility](/konnect-platform/compatibility/plugins) -for a comparison. - - -## Terminology -**Plugin** -: An extension to the {{site.base_gateway}}, written in Lua or Go. - -**Kong plugin** -: A plugin developed, maintained, and supported by Kong. - -**Third-party or Community plugin** -: A custom plugin developed, maintained, and supported by an external developer, -not by Kong. Kong does not test these plugins, or update their version -compatibility. If you need more information or need to have a third-party plugin -updated, contact the maintainer through the Support link in a plugin -documentation's sidebar. - -**Service** -: The Kong entity representing an external upstream API or microservice. - -**Route** -: The Kong entity representing a way to map downstream requests to upstream -services. - -**Consumer** -: An entity that makes requests for Kong to proxy. It represents either a user -or an external service. - -**Credential** -: A unique string associated with a Consumer; also referred to as an API key. - -**Upstream** -: The Kong entity that refers to your own API/service sitting behind Kong, -to which client requests are forwarded. - - -## Plugin versioning - -Each plugin has its own internal versioning scheme. These versions differ from -{{site.base_gateway}} versions. - -### Kong plugins - -For plugins developed and maintained by Kong, plugin versioning generally has -no impact on your implementation, other than to find out which versions of Kong -contain which plugin features. Kong plugins are bundled with the -{{site.base_gateway}}, so compatible plugin versions are already associated -with the correct version of Kong. - -### Third-party plugins - -Because third-party plugins are not maintained by Kong and are not bundled with -the {{site.base_gateway}}, version compatibility is a bigger concern. See each -individual plugin's page for its tested compatibility. - -If the versions on the plugin page are outdated, contact the maintainer through -the Support link in the plugin documentation's sidebar. - -## Developing custom plugins - -Kong provides an entire development environment for developing plugins, -including Lua and Go SDKs, database abstractions, migrations, and more. - -Plugins consist of modules interacting with the request/response objects or -streams via a Plugin Development Kit (or PDK) to implement arbitrary logic. -Kong provides PDKs for two languages: Lua and Go. Both of these PDKs are sets -of functions that a plugin can use to facilitate interactions between plugins -and the core (or other components) of Kong. - -To start creating your own plugins, check out the PDK documentation: -* [Plugin Development Guide](/gateway/latest/plugin-development) and the -[Plugin Development Kit reference](/gateway/latest/pdk) -* [Other Language Support](/gateway/latest/reference/external-plugins) - -## Contributing custom plugins - -If you are interested in sharing your custom plugin with other Kong users, you -must also submit plugin reference documentation to the Kong Plugin Hub. See the -[contribution guidelines](/contributing/) -for adding documentation. +{% include_cached /md/about-plugins.md %} diff --git a/app/_hub/qnap/api-transformer/_index.md b/app/_hub/qnap/api-transformer/_index.md index dee583eb04dc..75b2dfed0855 100644 --- a/app/_hub/qnap/api-transformer/_index.md +++ b/app/_hub/qnap/api-transformer/_index.md @@ -8,7 +8,7 @@ desc: Kong middleware to transform requests / responses, using Lua script. description: | This is a Kong Plugin that transforms requests and responses depending on your own business requirements. support_url: https://github.com/qnap-dev/kong-plugin-api-transformer/issues -source_url: https://github.com/qnap-dev/kong-plugin-api-transformer +source_code: https://github.com/qnap-dev/kong-plugin-api-transformer license_type: Apache-2.0 license_url: https://github.com/qnap-dev/kong-plugin-api-transformer/blob/master/LICENSE diff --git a/app/_hub/reedelk/reedelk-transformer/_index.md b/app/_hub/reedelk/reedelk-transformer/_index.md index 28cd6fd1ad5e..9907ea3e2ba1 100644 --- a/app/_hub/reedelk/reedelk-transformer/_index.md +++ b/app/_hub/reedelk/reedelk-transformer/_index.md @@ -21,7 +21,7 @@ support_url: https://github.com/codecentric/kong-plugin-reedelk-transformer/issu # (Optional) A specific URL of your own for this extension. # Defaults to the url setting in your publisher profile. -source_url: https://github.com/codecentric/kong-plugin-reedelk-transformer +source_code: https://github.com/codecentric/kong-plugin-reedelk-transformer license_type: Apache-2.0 # (Optional) For open source, use the abbreviations in parentheses at: diff --git a/app/_hub/revolution_systems/upstream-auth-basic/_index.md b/app/_hub/revolution_systems/upstream-auth-basic/_index.md index bbc0c35d3f5d..4def63a491d4 100644 --- a/app/_hub/revolution_systems/upstream-auth-basic/_index.md +++ b/app/_hub/revolution_systems/upstream-auth-basic/_index.md @@ -14,7 +14,7 @@ description: | support_url: https://github.com/revolsys/kong-plugin-upstream-auth-basic/issues -source_url: https://github.com/revolsys/kong-plugin-upstream-auth-basic +source_code: https://github.com/revolsys/kong-plugin-upstream-auth-basic license_type: Apache-2.0 diff --git a/app/_hub/salt/salt/_index.md b/app/_hub/salt/salt/_index.md index 779062ec3c4d..986b8bf473f8 100644 --- a/app/_hub/salt/salt/_index.md +++ b/app/_hub/salt/salt/_index.md @@ -19,7 +19,7 @@ description: | # (Optional) A specific URL of your own for this extension. # Defaults to the url setting in your publisher profile. -#source_url: +#source_code: # (Optional) If your extension is open source, provide a link to your code. #license_type: diff --git a/app/_hub/seifchen/kong-path-allow/_index.md b/app/_hub/seifchen/kong-path-allow/_index.md index bb4b90d1821f..127412fcb0bb 100644 --- a/app/_hub/seifchen/kong-path-allow/_index.md +++ b/app/_hub/seifchen/kong-path-allow/_index.md @@ -14,7 +14,7 @@ description: | support_url: https://github.com/seifchen/kong-path-allow/issues -source_url: https://github.com/seifchen/kong-path-allow +source_code: https://github.com/seifchen/kong-path-allow license_type: Apache-2.0 diff --git a/app/_hub/signal_sciences/signal-sciences/_index.md b/app/_hub/signal_sciences/signal-sciences/_index.md index d1824e057357..87a7e11f8ed3 100644 --- a/app/_hub/signal_sciences/signal-sciences/_index.md +++ b/app/_hub/signal_sciences/signal-sciences/_index.md @@ -38,7 +38,7 @@ description: | support_url: https://docs.signalsciences.net/ -#source_url: +#source_code: # (Optional) If your extension is open source, provide a link to your code. #license_type: diff --git a/app/_hub/signalfx/signalfx/_index.md b/app/_hub/signalfx/signalfx/_index.md index 24d0d1fc6eb1..1b2279c31ede 100644 --- a/app/_hub/signalfx/signalfx/_index.md +++ b/app/_hub/signalfx/signalfx/_index.md @@ -12,7 +12,7 @@ description: | support_url: https://support.signalfx.com/hc/en-us -source_url: https://github.com/signalfx/kong-plugin-signalfx +source_code: https://github.com/signalfx/kong-plugin-signalfx license_type: Apache-2.0 diff --git a/app/_hub/stone-payments/kong-plugin-template-transformer/_index.md b/app/_hub/stone-payments/kong-plugin-template-transformer/_index.md index ed77ef1ac3d6..ec0519ccd665 100644 --- a/app/_hub/stone-payments/kong-plugin-template-transformer/_index.md +++ b/app/_hub/stone-payments/kong-plugin-template-transformer/_index.md @@ -8,7 +8,7 @@ desc: Kong middleware to transform requests / responses, using pre-configured te description: | This is Kong plugins that accepts requests and response templates to completely transform requests and responses with Lua templates. support_url: https://github.com/stone-payments/kong-plugin-template-transformer/issues -source_url: https://github.com/stone-payments/kong-plugin-template-transformer +source_code: https://github.com/stone-payments/kong-plugin-template-transformer license_type: Apache-2.0 license_url: https://github.com/stone-payments/kong-plugin-template-transformer/blob/master/LICENSE diff --git a/app/_hub/stone-payments/kong-plugin-url-rewrite/_index.md b/app/_hub/stone-payments/kong-plugin-url-rewrite/_index.md index 597e771d56d8..1265ca5d2c41 100644 --- a/app/_hub/stone-payments/kong-plugin-url-rewrite/_index.md +++ b/app/_hub/stone-payments/kong-plugin-url-rewrite/_index.md @@ -8,7 +8,7 @@ desc: Kong middleware to completely rewrite the URL of a route. description: | When using Kong, you can create routes that proxy to an upstream. The problem lies when the upstream has an url that is not very friendly to your clients, or restful, or even pretty. When you add a Route in Kong, you have a somewhat limited url rewrite capability. This plugin simply throws away the url set in Kong route and uses the url set in it's configuration to proxy to the upstream. This gives you full freedom as to how to write your url's in Kong and inner services as well. support_url: https://github.com/stone-payments/kong-plugin-url-rewrite/issues -source_url: https://github.com/stone-payments/kong-plugin-url-rewrite +source_code: https://github.com/stone-payments/kong-plugin-url-rewrite license_type: Apache-2.0 license_url: https://github.com/stone-payments/kong-plugin-url-rewrite/blob/master/LICENSE diff --git a/app/_hub/tomkerkhove/microsoft_azure/_index.md b/app/_hub/tomkerkhove/microsoft_azure/_index.md index 157fc02e323d..145bdf41f216 100644 --- a/app/_hub/tomkerkhove/microsoft_azure/_index.md +++ b/app/_hub/tomkerkhove/microsoft_azure/_index.md @@ -24,7 +24,7 @@ description: #| support_url: https://github.com/tomkerkhove/kong-deployment-on-azure/issues # Defaults to the url setting in your publisher profile. -source_url: https://github.com/tomkerkhove/kong-deployment-on-azure +source_code: https://github.com/tomkerkhove/kong-deployment-on-azure # (Optional) If your extension is open source, provide a link to your code. #license_type: diff --git a/app/_hub/tomkerkhove/microsoft_azure_container_instances/_index.md b/app/_hub/tomkerkhove/microsoft_azure_container_instances/_index.md index 1845e315d413..4a9cf0117cfa 100644 --- a/app/_hub/tomkerkhove/microsoft_azure_container_instances/_index.md +++ b/app/_hub/tomkerkhove/microsoft_azure_container_instances/_index.md @@ -25,7 +25,7 @@ description: | support_url: https://github.com/tomkerkhove/kong-deployment-on-azure/issues # Defaults to the url setting in your publisher profile. -source_url: https://github.com/tomkerkhove/kong-deployment-on-azure +source_code: https://github.com/tomkerkhove/kong-deployment-on-azure # (Optional) If your extension is open source, provide a link to your code. #license_type: diff --git a/app/_hub/wallarm/wallarm/_index.md b/app/_hub/wallarm/wallarm/_index.md index c391dcb84155..09f855af48fb 100644 --- a/app/_hub/wallarm/wallarm/_index.md +++ b/app/_hub/wallarm/wallarm/_index.md @@ -28,7 +28,7 @@ description: | # (Optional) A specific URL of your own for this extension. # Defaults to the url setting in your publisher profile. -#source_url: +#source_code: # (Optional) If your extension is open source, provide a link to your code. #license_type: diff --git a/app/_hub/yesinteractive/kong-jwt2header/_index.md b/app/_hub/yesinteractive/kong-jwt2header/_index.md index d2f5e83c944c..e3ccedf5d4ad 100644 --- a/app/_hub/yesinteractive/kong-jwt2header/_index.md +++ b/app/_hub/yesinteractive/kong-jwt2header/_index.md @@ -24,7 +24,7 @@ description: | support_url: https://github.com/yesinteractive/kong-jwt2header/issues -source_url: https://github.com/yesinteractive/kong-jwt2header +source_code: https://github.com/yesinteractive/kong-jwt2header license_type: MIT diff --git a/app/_hub/yesinteractive/kong-log-google/_index.md b/app/_hub/yesinteractive/kong-log-google/_index.md index 08f36c2b4a51..fc0ca9099382 100644 --- a/app/_hub/yesinteractive/kong-log-google/_index.md +++ b/app/_hub/yesinteractive/kong-log-google/_index.md @@ -19,7 +19,7 @@ description: This plugin logs your Kong gateway transactions to Google Analytics support_url: https://github.com/yesinteractive/kong-log-google/issues -source_url: https://github.com/yesinteractive/kong-log-google +source_code: https://github.com/yesinteractive/kong-log-google license_type: MIT diff --git a/app/_hub/yesinteractive/kongmap/_index.md b/app/_hub/yesinteractive/kongmap/_index.md index 08942f7d4a19..a3acf52594a5 100644 --- a/app/_hub/yesinteractive/kongmap/_index.md +++ b/app/_hub/yesinteractive/kongmap/_index.md @@ -14,7 +14,7 @@ description: | support_url: https://github.com/yesinteractive/kong-map/issues -source_url: https://github.com/yesinteractive/kong-map +source_code: https://github.com/yesinteractive/kong-map license_type: AGPL-3.0 diff --git a/app/_includes/breadcrumbs.html b/app/_includes/breadcrumbs.html index f68cbd8b0bd8..760ffd7de5ba 100644 --- a/app/_includes/breadcrumbs.html +++ b/app/_includes/breadcrumbs.html @@ -1,57 +1,85 @@ +{% assign crumbs = include.url | split : '/' %} + +{% assign version = include.kong_version %} +{% if include.is_latest %} + {% assign version = "latest" %} +{% endif %} + +{% assign offset = 3 %} +{% if include.no_version == true %} + {% assign offset = 2 %} +{% endif %} + +{% if include.edition == 'enterprise' %} + {% capture product_url %}/enterprise/{% unless include.no_version == true %}{{version}}/{% endunless %}{% endcapture %} + {% capture product_title %}{{site.ee_product_name}}{% endcapture %} +{% elsif include.edition == 'konnect' %} + {% capture product_url %}/konnect/{% endcapture %} + {% capture product_title %}{{site.konnect_saas}}{% endcapture %} +{% elsif include.edition == 'mesh' %} + {% capture product_url %}/mesh/{% unless include.no_version == true %}{{version}}/{% endunless %}{% endcapture %} + {% capture product_title %}{{site.mesh_product_name}}{% endcapture %} +{% elsif include.edition == 'deck' %} + {% capture product_url %}/deck/{% endcapture %} + {% capture product_title %}decK{% endcapture %} +{% elsif include.edition == 'kubernetes-ingress-controller' %} + {% capture product_url %}/kubernetes-ingress-controller/{{version}}/{% endcapture %} + {% capture product_title %}{{site.kic_product_name}}{% endcapture %} +{% elsif include.edition == 'gateway-oss' %} + {% capture product_url %}/gateway-oss/{{version}}/{% endcapture %} + {% capture product_title %}{{ site.ce_product_name }}{% endcapture %} +{% elsif include.edition == 'gateway' %} + {% capture product_url %}/gateway/{{version}}/{% endcapture %} + {% capture product_title %}{{ site.base_gateway }}{% endcapture %} +{% elsif include.edition == 'getting-started-guide' %} + {% capture product_url %}/getting-started-guide/{{version}}/overview{% endcapture %} + {% capture product_title %}Get Started with Kong Gateway{% endcapture %} +{% elsif include.edition == 'contributing' %} + {% capture product_url %}/contributing/{% endcapture %} + {% capture product_title %}Style guide and contribution guidelines{% endcapture %} +{% endif %} + +
\ No newline at end of file diff --git a/app/_includes/docs-sidebar.html b/app/_includes/docs-sidebar.html index 31e4c288e6f7..273f0d45e459 100644 --- a/app/_includes/docs-sidebar.html +++ b/app/_includes/docs-sidebar.html @@ -15,7 +15,6 @@ {% if include.edition == 'enterprise' %}{{site.ee_product_name}} {% elsif include.edition == 'konnect' %}{{site.konnect_saas}} - {% elsif include.edition == 'konnect-platform' %}{{site.konnect_product_name}} Platform {% elsif include.edition == 'mesh' %}{{site.mesh_product_name}} {% elsif include.edition == 'deck' %}decK {% elsif include.edition == 'kubernetes-ingress-controller' %}{{site.kic_product_name}} @@ -54,10 +53,6 @@ Kuma
- -
@@ -104,20 +99,20 @@ {% if include.edition == 'gateway' %}
  • - Older Enterprise versions (0.31-2.5) + Older Enterprise versions (2.1-2.5)
  • - Older OSS versions (0.13-2.5) + Older OSS versions (2.0-2.5)
  • {% endif %} - {% if include.edition == 'gateway-oss' or include.edition == 'gateway' %} + {% if include.edition == 'gateway-oss' or include.edition == 'gateway' or include.edition == 'enterprise' %}
  • - - Archive (pre-0.13) + + Archive (pre-2.0)
  • {% endif %} diff --git a/app/_includes/feature-table.html b/app/_includes/feature-table.html new file mode 100644 index 000000000000..e7f04e8be3f2 --- /dev/null +++ b/app/_includes/feature-table.html @@ -0,0 +1,61 @@ +{% assign keys = '' | split: '' %} + + + + + + {% for c in include.config.columns %} + {% assign key = c.key | split: ' ' %} + {% assign keys = keys | concat: key %} + + {% endfor %} + + + + {% for f in include.config.features %} + + + + + + {% for i in f.items %} + + + {% for k in keys %} + {% assign k_text = k | append: "_text" %} + + {% endfor %} + + {% endfor %} + {% endfor %} + +
    + {{ c.name }} + {% if c.image %} + {{ c.name }} + {% else %} + {{ c.name }} + {% endif %} + {% if c.cta_link %} + {{ c.cta }} + {% endif %} +
    + {{ f.name }} +
    + {% if i.url %} + {{ i.name }} + {% else %} + {{ i.name }} + {% endif %} + {% if i.tooltip %} + {% info_tooltip %} + {{ i.tooltip }} + {% endinfo_tooltip %} + {% endif %} + + {% if i[k_text] %} + {{ i[k_text] }} + {% else %} + + {% endif %} +
    diff --git a/app/_includes/hub-examples.html b/app/_includes/hub-examples.html index 87b7b5d948aa..bd1e8b150cdd 100644 --- a/app/_includes/hub-examples.html +++ b/app/_includes/hub-examples.html @@ -30,8 +30,11 @@ for field in include.params.config %}{% if_plugin_version gte:field.minimum_version lte:field.maximum_version %}{% if field.value_in_examples != nil %}{% if field.value_in_examples.first %}{% - for value in field.value_in_examples %} \ - --data{% if field.urlencode_in_examples %}-urlencode{% endif %} {% if field.value_in_examples contains "'" %}'config.{{ field.name }}={{ value | replace: "'", "" }}'{% else %}"config.{{ field.name }}={{ value }}"{% endif %}{% + for value in field.value_in_examples %} \{% + if field.datatype == "map" %}{% assign mapValues = value | split: ":" %} + --data{% if field.urlencode_in_examples %}-urlencode{% endif %} {% if field.value_in_examples contains "'" %}'config.{{ field.name }}.{{ mapValues[0] }}={{ mapValues[1] | replace: "'", "" }}'{% else %}"config.{{ field.name }}.{{ mapValues[0] }}={{ mapValues[1] }}"{% endif %}{% + else %} + --data{% if field.urlencode_in_examples %}-urlencode{% endif %} {% if field.value_in_examples contains "'" %}'config.{{ field.name }}={{ value | replace: "'", "" }}'{% else %}"config.{{ field.name }}={{ value }}"{% endif %}{% endif %}{% endfor %}{% else %} \ --data{% if field.urlencode_in_examples %}-urlencode{% endif %} {% if field.value_in_examples contains "'" %}'config.{{ field.name }}={{ field.value_in_examples | replace: "'", "" }}'{% else %}"config.{{ field.name }}={{ field.value_in_examples }}"{% endif %}{% @@ -218,7 +221,7 @@ if page.enterprise == true or page.plus == true %}
    Note: If the plugin is greyed out, then it is not available - for your product tier. See {{site.base_gateway}} tiers. + for your product tier. See {{site.base_gateway}} tiers.
    {% endif %} 5. If the option is available, select **Scoped**. 6. Add the service name and ID to the **Service** field if it @@ -251,8 +254,8 @@ Make the following request: ```bash -$ curl -X POST http://localhost:8001/routes/ROUTE_NAME|ROUTE_ID/plugins \ - --data "name={{include.params.name}}" {{ config_required_fields }} +curl -X POST http://localhost:8001/routes/ROUTE_NAME|ROUTE_ID/plugins \ + --data "name={{include.params.name}}" {{ config_required_fields }} ``` Replace `ROUTE_NAME|ROUTE_ID` with the `id` or `name` of the route that this plugin configuration will target. @@ -356,7 +359,7 @@ if page.enterprise == true or page.plus == true %}
    Note: If the plugin is greyed out, then it is not available - for your product tier. See {{site.base_gateway}} tiers. + for your product tier. See {{site.base_gateway}} tiers.
    {% endif %} 5. If the option is available, select **Scoped**. 6. Add the route ID if it is not already prefilled.{% unless @@ -388,8 +391,8 @@ Make the following request: ```bash -$ curl -X POST http://localhost:8001/consumers/CONSUMER_NAME|CONSUMER_ID/plugins \ - --data "name={{include.params.name}}" {{ config_required_fields }} +curl -X POST http://localhost:8001/consumers/CONSUMER_NAME|CONSUMER_ID/plugins \ + --data "name={{include.params.name}}" {{ config_required_fields }} ``` Replace `CONSUMER_NAME|CONSUMER_ID` with the `id` or `name` of the consumer that this plugin configuration will target. @@ -470,7 +473,7 @@ if page.enterprise == true or page.plus == true %}
    Note: If the plugin is greyed out, then it is not available - for your product tier. See {{site.base_gateway}} tiers. + for your product tier. See {{site.base_gateway}} tiers.
    {% endif %} 5. If the option is available, select **Scoped**. 6. Add the consumer ID if it is not already prefilled.{% unless @@ -507,8 +510,8 @@ Make the following request: ```bash -$ curl -X POST http://localhost:8001/plugins/ \ - --data "name={{include.params.name}}" {{ config_required_fields }} +curl -X POST http://localhost:8001/plugins/ \ + --data "name={{include.params.name}}" {{ config_required_fields }} ``` {% endnavtab %} @@ -560,7 +563,7 @@ if page.enterprise == true or page.plus == true %}
    Note: If the plugin is greyed out, then it is not available - for your product tier. See {{site.base_gateway}} tiers. + for your product tier. See {{site.base_gateway}} tiers.
    {% endif %} 4. If the option is available, set the plugin scope to **Global**.{% unless config_required_fields_gui == empty %} diff --git a/app/_includes/md/2.6.x/ee-kong-user.md b/app/_includes/md/2.6.x/ee-kong-user.md index df6f202e5203..adecbc58dd3a 100644 --- a/app/_includes/md/2.6.x/ee-kong-user.md +++ b/app/_includes/md/2.6.x/ee-kong-user.md @@ -6,4 +6,4 @@ Amazon Linux 2, CentOS, Ubuntu, and RHEL --> run as `kong` by default. If this is not the desired behavior, you can switch the NGINX master process to run on the built-in `kong` user or to a custom non-root user before starting {{site.base_gateway}}. For more information, see -[Running Kong as a Non-Root User](/gateway/{{include.kong_version}}/plan-and-deploy/kong-user). +[Running Kong as a Non-Root User](/gateway/{{include.kong_version}}/production/running-kong/kong-user). diff --git a/app/_includes/md/about-plugins.md b/app/_includes/md/about-plugins.md new file mode 100644 index 000000000000..5fc852ed8afe --- /dev/null +++ b/app/_includes/md/about-plugins.md @@ -0,0 +1,110 @@ + +## What are plugins? + +{{site.base_gateway}} is a Lua application designed to load and execute Lua or Go modules, which +we commonly refer to as _plugins_. Kong provides a set of standard Lua +plugins that get bundled with {{site.base_gateway}}. The set of plugins you +have access to depends on your installation: open-source, enterprise, or either +of these {{site.base_gateway}} options running on Kubernetes. + +Custom plugins can also be developed by the Kong Community and are supported +and maintained by the plugin creators. If they are published on the Kong Plugin +Hub, they are called Community or Third-Party plugins. + +## Why use plugins? + +Plugins provide advanced functionality and extend the use of the {{site.base_gateway}}, +which allows you to add new features to your implementation. Plugins can be configured to run in +a variety of contexts, ranging from a specific route to all upstreams, and can +execute actions inside Kong before or after a request has been proxied to the +upstream API, as well as on any incoming responses. + +## Plugin compatibility with deployment types + +{{site.base_gateway}} can be deployed in a variety of ways, and not all plugins +are fully compatible with each mode. See [Plugin Compatibility](/konnect/compatibility#plugin-compatibility) +for a comparison. + + +## Terminology +**Plugin** +: An extension to the {{site.base_gateway}}, written in Lua or Go. + +**Kong plugin** +: A plugin developed, maintained, and supported by Kong. + +**Third-party or Community plugin** +: A custom plugin developed, maintained, and supported by an external developer, +not by Kong. Kong does not test these plugins, or update their version +compatibility. If you need more information or need to have a third-party plugin +updated, contact the maintainer by clicking [Report an issue](https://github.com/Kong/docs.konghq.com/issues) in the plugin +documentation's sidebar. + +**Service** +: The Kong entity representing an external upstream API or microservice. + +**Route** +: The Kong entity representing a way to map downstream requests to upstream +services. + +**Consumer** +: An entity that makes requests for Kong to proxy. It represents either a user +or an external service. + +**Credential** +: The API key. A unique string associated with a consumer. + +**Upstream** +: The Kong entity that refers to your own API/service sitting behind Kong, +to which client requests are forwarded. + + +## Plugin versioning + +Each plugin has its own internal versioning scheme. These versions differ from +{{site.base_gateway}} versions. + +### Kong plugins + +For plugins developed and maintained by Kong, plugin versioning generally has +no impact on your implementation, other than to find out which versions of Kong +contain which plugin features. Kong plugins are bundled with the +{{site.base_gateway}}, so compatible plugin versions are already associated +with the correct version of Kong. + +### Third-party plugins + +Because third-party plugins are not maintained by Kong and are not bundled with +the {{site.base_gateway}}, version compatibility is a bigger concern. See each +individual plugin's page for its tested compatibility. + +If the versions on the plugin page are outdated, contact the maintainer through +the Support link in the plugin documentation's sidebar. + +## Developing custom plugins + +Kong provides an entire development environment for developing plugins, +including Lua and Go SDKs, database abstractions, migrations, and more. + +Plugins consist of modules interacting with the request/response objects or +streams via a Plugin Development Kit (or PDK) to implement arbitrary logic. +Kong provides PDKs for two languages: Lua and Go. Both of these PDKs are sets +of functions that a plugin can use to facilitate interactions between plugins +and the core (or other components) of Kong. + +To start creating your own plugins, check out the PDK documentation: +* [Plugin Development Guide](/gateway/latest/plugin-development/) +* [Plugin Development Kit reference](/gateway/latest/plugin-development/pdk/) +* [Other Language Support](/gateway/latest/plugin-development/pluginserver/go/) + +## Contributing custom plugins + +If you are interested in sharing your custom plugin with other Kong users, you +must also submit plugin reference documentation to the Kong Plugin Hub. See the +[contribution guidelines](/contributing/) +for adding documentation. + +## Other key concepts + +* For more information about available plugins, see the [Plugin Hub](/hub/). +* [Stages of software availability](/gateway/latest/stability/) \ No newline at end of file diff --git a/app/_includes/md/admin-listen.md b/app/_includes/md/admin-listen.md index 97117a740182..2e356dba8fdb 100644 --- a/app/_includes/md/admin-listen.md +++ b/app/_includes/md/admin-listen.md @@ -3,11 +3,18 @@ > **Important:** The settings below are intended for non-production use **only**, as they override the default `admin_listen` setting to listen for requests from any source. **Do not** use these settings in environments directly exposed to the internet. > >
    - > If you need to expose the `admin_listen` port to the internet in a production environment, [secure it with authentication](/gateway/latest/admin-api/secure-admin-api/). + > If you need to expose the `admin_listen` port to the internet in a production environment, + > {% if_version lte:2.8.x + %}[secure it with authentication](/gateway/{{include.kong_version}}/admin-api/secure-admin-api).{% endif_version %}{% if_version gte:3.0.x + %}[secure it with authentication](/gateway/{{include.kong_version}}/production/running-kong/secure-admin-api).{% endif_version %} + {% endif %} {% if include.desc == "short" %} {:.important} - > **Important**: If you need to expose the `admin_listen` port to the internet in a production environment, [secure it with authentication](/gateway/latest/admin-api/secure-admin-api/). + > **Important**: If you need to expose the `admin_listen` port to the internet in a production environment, + > {% if_version lte:2.8.x + %}[secure it with authentication](/gateway/{{include.kong_version}}/admin-api/secure-admin-api).{% endif_version %}{% if_version gte:3.0.x + %}[secure it with authentication](/gateway/{{include.kong_version}}/production/running-kong/secure-admin-api).{% endif_version %} {% endif %} diff --git a/app/_includes/md/availability-stages.md b/app/_includes/md/availability-stages.md new file mode 100644 index 000000000000..286f6b1cb783 --- /dev/null +++ b/app/_includes/md/availability-stages.md @@ -0,0 +1,29 @@ + +## Tech preview +A feature that is in tech preview might have limited to no documentation, no support, and is not guaranteed to be made available as GA in the future. Some products or projects may also call this stage *alpha*. + +**A tech preview feature or version should not be deployed in a production environment**. + +Tech preview features are experimental. Interfaces for features in tech preview could change in backwards-incompatible ways. Do not count on the feature becoming a formal product, and expect it to change heavily if it does. + +## Beta +A beta designation in Kong software means the functionality of a feature or release version is of high quality and can be deployed in a non-production environment. + +**A beta feature or version should not be deployed in a production environment**. + +Note the following when using a beta feature or version: +* Beta customers are encouraged to engage Kong Support to report issues encountered in beta testing. Support requests should be filed with normal priority, but contractual SLA’s will not be applicable for beta features. +* Support is not available for data recovery, rollback, or other tasks when using a beta feature or version. +* User documentation might not be available, complete, or reflect entire functionality. + +A beta feature or version is made available to the general public for usability testing and to gain feedback about the feature or version before releasing it as a production-ready, stable feature or version. + +## General availability +General availability, or GA, means that the software is released publicly and +is supported according to Kong's [support and maintenance policy](https://konghq.com/wp-content/uploads/2021/04/Kong-Support-and-Maintenance-Policy-16-April-2021.pdf). Generally available features usually have official documentation (as needed) and interfaces are stable. + +If feature documentation doesn't have a tech preview, alpha, or beta label, then the feature is generally available. + +You can deploy GA features to production environments. + +Interfaces are guaranteed to follow a [semantic versioning](https://semver.org/) model for any changes. diff --git a/app/_includes/md/ce-kong-user.md b/app/_includes/md/ce-kong-user.md index b7009547bbd7..79b561ecbd63 100644 --- a/app/_includes/md/ce-kong-user.md +++ b/app/_includes/md/ce-kong-user.md @@ -5,4 +5,4 @@ as `root` and the worker processes as `kong` by default. If this is not the desired behavior, you can switch the Nginx master process to run on the built-in `kong` user or to a custom non-root user before starting Kong. For more - information, see [Running Kong as a Non-Root User](/gateway/latest/plan-and-deploy/kong-user). + information, see [Running Kong as a Non-Root User](/gateway/latest/production/running-kong/kong-user). diff --git a/app/_includes/md/deb.md b/app/_includes/md/deb.md index 3760b76cd5e9..5413593e5ea0 100644 --- a/app/_includes/md/deb.md +++ b/app/_includes/md/deb.md @@ -7,7 +7,9 @@ You can install Kong by downloading an installation package or using our apt rep {% if include.distribution == "ubuntu" %} + {% if_version lte:2.8.x %} - [Xenial]({{ site.links.download }}/gateway-2.x-ubuntu-xenial/pool/all/k/kong/kong_{{site.data.kong_latest.version}}_amd64.deb) + {% endif_version %} - [Bionic]({{ site.links.download }}/gateway-2.x-ubuntu-bionic/pool/all/k/kong/kong_{{site.data.kong_latest.version}}_amd64.deb) - [Focal]({{ site.links.download }}/gateway-2.x-ubuntu-focal/pool/all/k/kong/kong_{{site.data.kong_latest.version}}_amd64.deb) @@ -15,7 +17,9 @@ You can install Kong by downloading an installation package or using our apt rep {% if include.distribution == "debian" %} + {% if_version lte:2.8.x %} - [8 Jessie]({{ site.links.download }}/gateway-2.x-debian-jessie/pool/all/k/kong/kong_{{site.data.kong_latest.version}}_amd64.deb) + {% endif_version %} - [9 Stretch]({{ site.links.download }}/gateway-2.x-debian-stretch/pool/all/k/kong/kong_{{site.data.kong_latest.version}}_amd64.deb) - [10 Buster]({{ site.links.download }}/gateway-2.x-debian-buster/pool/all/k/kong/kong_{{site.data.kong_latest.version}}_amd64.deb) - [11 Bullseye]({{ site.links.download }}/gateway-2.x-debian-bullseye/pool/all/k/kong/kong_{{site.data.kong_latest.version}}_amd64.deb) @@ -37,7 +41,7 @@ $ sudo dpkg -i kong.{{site.data.kong_latest.version}}.amd64.deb To install from the command line ```bash -$ echo "deb [trusted=yes] {{ site.links.download }}/gateway-2.x-{{ include.distribution }}-$(lsb_release -sc)/ default all" | sudo tee /etc/apt/sources.list.d/kong.list +$ echo "deb [trusted=yes] {{ site.links.download }}/gateway-2.x-{{ include.distribution }}-$(lsb_release -sc)/ default all" | sudo tee /etc/apt/sources.list.d/kong.list $ sudo apt-get update $ sudo apt install -y kong ``` @@ -45,4 +49,4 @@ $ sudo apt install -y kong {% endnavtab %} {% endnavtabs %} -{% include_cached /md/installation.md kong_version=page.kong_version %} \ No newline at end of file +{% include_cached /md/installation.md kong_version=page.kong_version %} diff --git a/app/_includes/md/enterprise/deploy-license.md b/app/_includes/md/enterprise/deploy-license.md index 6b27281c46b1..e1b8512532ce 100644 --- a/app/_includes/md/enterprise/deploy-license.md +++ b/app/_includes/md/enterprise/deploy-license.md @@ -68,7 +68,7 @@ Result: ``` For more detail and options, see the -[Admin API `licenses` endpoint reference](/gateway/latest/admin-api/licenses/examples/). +[Admin API `licenses` endpoint reference](/gateway/latest/licenses/examples). {% endnavtab %} {% navtab Filesystem %} @@ -121,10 +121,19 @@ substituting your own license key. 1. Include the license as part of the `docker run` command when starting a {{site.base_gateway}} container: + {% if_version lte:2.8.x %} {:.note} > **Note:** This is only a snippet. For a full working example, see the instructions to [Install Kong Gateway on Docker](/gateway/{{page.kong_version}}/install-and-run/docker). + {% endif_version %} + {% if_version gte:3.0.x %} + {:.note} + > **Note:** This is only a snippet. For a full working example, see the instructions to + [Install Kong Gateway on Docker](/gateway/{{page.kong_version}}/install/docker). + + {% endif_version %} + ```bash docker run -d --name kong-gateway \ --network=kong-net \ @@ -142,13 +151,22 @@ on each node manually. Include the license as part of the `docker run` command when starting a {{site.base_gateway}} container. Mount the path to the file on your -local filesystem to a directory in the Docker container, making the file visible +local filesystem to a directory in the Docker container, making the file visible from the container: +{% if_version lte:2.8.x %} {:.note} > **Note:** This is only a snippet. For a full working example, see the instructions to [Install Kong Gateway on Docker](/gateway/{{page.kong_version}}/install-and-run/docker). +{% endif_version %} +{% if_version gte:3.0.x %} +{:.note} +> **Note:** This is only a snippet. For a full working example, see the instructions to +[Install Kong Gateway on Docker](/gateway/{{page.kong_version}}/install/docker). + +{% endif_version %} + ```bash docker run -d --name kong-gateway \ --network=kong-net \ diff --git a/app/_includes/md/enterprise/turn-on-rbac.md b/app/_includes/md/enterprise/turn-on-rbac.md index f21507e8d156..b39ae5697136 100644 --- a/app/_includes/md/enterprise/turn-on-rbac.md +++ b/app/_includes/md/enterprise/turn-on-rbac.md @@ -5,25 +5,36 @@ To enable RBAC, you will need the initial KONG_PASSWORD that was used when you f {% navtabs %} {% navtab UNIX-based system or Windows %} 1. Modify configuration settings below in your `kong.conf` file. Navigate to the file at `/etc/kong/kong.conf`: -
    cd /etc/kong/
    + ```sh + cd /etc/kong/ + ``` 2. Copy the `kong.conf.default` file so you know you have a working copy to fall back to. -
    cp kong.conf.default kong.conf
    + ```sh + cp kong.conf.default kong.conf + ``` 3. Now, edit the following settings in `kong.conf`: -
    echo >> “enforce_rbac = on” >> /etc/kong/kong.conf
    echo >> “admin_gui_auth = basic-auth” >> /etc/kong.conf
    echo >> “admin_gui_session_conf = {"secret":"secret","storage":"kong","cookie_secure":false}”
    + ``` + echo >> “enforce_rbac = on” >> /etc/kong/kong.conf + echo >> “admin_gui_auth = basic-auth” >> /etc/kong.conf + echo >> “admin_gui_session_conf = {"secret":"secret","storage":"kong","cookie_secure":false}” + ``` - This will turn on RBAC, tell {{site.base_gateway}} to use basic authentication (username/password), and tell the Sessions Plugin how to create a session cookie. + This turns on RBAC, tells {{site.base_gateway}} to use basic authentication (username/password), and tells the Sessions plugin how to create a session cookie. The cookie is used for all subsequent requests to authenticate the user until it expires. The session has a limited duration and renews at a configurable interval, which helps prevent an attacker from obtaining and using a stale cookie after the session has ended. 4. Restart {{site.base_gateway}} and point to the new config file: -
    kong restart -c /etc/kong/kong.conf
    + ``` + kong restart -c /etc/kong/kong.conf + ``` {% endnavtab %} {% navtab Docker %} If you have a Docker installation, run the following command to set the needed environment variables and reload the gateway's configuration. -**Note:** make sure to replace `` with the ID of your container. +{:.note} +> **Note:** Make sure to replace `{KONG-CONTAINER-ID}` with the ID of your container. ```bash echo "KONG_ENFORCE_RBAC=on @@ -32,11 +43,17 @@ KONG_ADMIN_GUI_SESSION_CONF='{\"secret\":\"secret\",\"storage\":\"kong\",\"cooki kong reload exit" | docker exec -i {KONG_CONTAINER_ID} /bin/sh ``` -This will turn on RBAC, tell {{site.base_gateway}} to use basic authentication (username/password), and tell the Sessions Plugin how to create a session cookie. +This turns RBAC on, tells {{site.base_gateway}} to use basic authentication (username/password), and tells the Sessions plugin how to create a session cookie. The cookie is used for all subsequent requests to authenticate the user, until it expires. The session has a limited duration and renews at a configurable interval, which helps prevent an attacker from obtaining and using a stale cookie after the session has ended. {% endnavtab %} {% endnavtabs %} -Outside of this guide, you will likely want to modify these settings differently, depending on your installation. You can read more about these settings here: [Basic Auth for Kong Manager](/gateway/latest/configure/auth/kong-manager/basic/). +{% if_version lte:2.8.x %} +Outside of this guide, you will likely want to modify these settings differently, depending on your installation. You can read more about these settings here: [Basic Auth for Kong Manager](/gateway/latest/kong-manager/auth/basic/). +{% endif_version %} + +{% if_version gte:3.0.x %} +Outside of this guide, you will likely want to modify these settings differently, depending on your installation. You can read more about these settings here: [Basic Auth for Kong Manager](/gateway/{{page.kong_version}}/kong-manager/auth/basic/). +{% endif_version %} diff --git a/app/_includes/md/gateway/deployment-options.md b/app/_includes/md/gateway/deployment-options.md index f00e83d5682f..4ef301dcdc27 100644 --- a/app/_includes/md/gateway/deployment-options.md +++ b/app/_includes/md/gateway/deployment-options.md @@ -1,4 +1,9 @@ The installation instructions explain how to deploy {{site.base_gateway}} in its entirety on a single node -- with or without a database. +{% if_version lte:2.8.x %} The instructions are the same for setting up a Control Plane instance in Hybrid mode. After you set up the Control Plane, you set up additional Gateway instances for the Data Planes. See [Hybrid Mode Setup](/gateway/{{include.kong_version}}/plan-and-deploy/hybrid-mode/hybrid-mode-setup) for details. +{% endif_version %} +{% if_version gte:3.0.x %} +The instructions are the same for setting up a Control Plane instance in Hybrid mode. After you set up the Control Plane, you set up additional Gateway instances for the Data Planes. See [Hybrid Mode Setup](/gateway/{{include.kong_version}}/production/deployment-topologies/hybrid-mode/setup) for details. +{% endif_version %} diff --git a/app/_includes/md/gateway/ldap-service-directory-mapping.md b/app/_includes/md/gateway/ldap-service-directory-mapping.md new file mode 100644 index 000000000000..760499d1fb36 --- /dev/null +++ b/app/_includes/md/gateway/ldap-service-directory-mapping.md @@ -0,0 +1,22 @@ + + +When using only RBAC Token authorization, Service Directory Mapping to Kong Roles does not take effect. If you need to use CLI access with your Service Directory mapping, you can use the same authentication mechanism that Kong Manager uses to secure browser sessions. + +#### Authenticate User Session + +Retrieve a secure cookie session with the authorized LDAP user credentials: + +```sh +$ curl -c /tmp/cookie http://localhost:8001/auth \ +-H 'Kong-Admin-User: ' \ +--user : +``` + +Now the cookie is stored at `/tmp/cookie` and can be read for future requests: + +```sh +$ curl -c /tmp/cookie -b /tmp/cookie http://localhost:8001/consumers \ +-H 'Kong-Admin-User: ' +``` + +Because Kong Manager is a browser application, if any HTTP responses see the `Set-Cookie` header, then it will automatically attach it to future requests. This is why it is helpful to utilize [cURL's cookie engine](https://ec.haxx.se/http/http-cookies) or [HTTPie sessions](https://httpie.org/docs/0.9.7#sessions). If storing the session is not desired, then the `Set-Cookie` header value can be copied directly from the `/auth` response and used with subsequent requests. diff --git a/app/_includes/md/gateway/root-user-note.md b/app/_includes/md/gateway/root-user-note.md index 307ed459249b..b2a9c04343cc 100644 --- a/app/_includes/md/gateway/root-user-note.md +++ b/app/_includes/md/gateway/root-user-note.md @@ -1,13 +1,23 @@ - +{% if_version lte:2.8.x %} {:.note} > **Note:** When you start {{site.base_gateway}}, the NGINX master process runs as `root`, and the worker processes run as `kong` by default. If this is not the desired behavior, you can switch the NGINX master process to run on the built-in `kong` user or to a custom non-root user before starting {{site.base_gateway}}. For more information, see [Running Kong as a Non-Root User](/gateway/{{include.kong_version}}/plan-and-deploy/kong-user). + +{% endif_version %} +{% if_version gte:3.0.x %} +> **Note:** When you start {{site.base_gateway}}, the NGINX master process runs as `root`, and the worker processes +run as `kong` by default. If this is not the desired behavior, you can switch the NGINX master process +to run on the built-in `kong` user or to a custom non-root user before starting {{site.base_gateway}}. +For more information, see +[Running Kong as a Non-Root User](/gateway/{{include.kong_version}}/production/running-kong/kong-user). +{% endif_version %} diff --git a/app/_includes/md/gateway/setup.md b/app/_includes/md/gateway/setup.md index 5b5bf65c7beb..6db4a6e7dbd9 100644 --- a/app/_includes/md/gateway/setup.md +++ b/app/_includes/md/gateway/setup.md @@ -184,13 +184,20 @@ $ scp license.json /etc/kong/license.json {% endnavtab %} {% endnavtabs %} -### Enable and configure Kong Manager +### Enable Kong Manager {:.badge .free} +{% if_version gte:3.0.x %} + If you're running {{site.base_gateway}} with a database (either in traditional or hybrid mode), you can enable {{site.base_gateway}}'s graphical user interface (GUI), Kong Manager. +See the [Kong Manager setup guide](/gateway/{{page.kong_version}}/kong-manager/enable) for more information. + +{% endif_version %} +{% if_version lte:2.8.x %} + 1. Update the `admin_gui_url` property in the `kong.conf` configuration file to the DNS, or IP address, of your system. For example: @@ -203,7 +210,7 @@ or hybrid mode), you can enable {{site.base_gateway}}'s graphical user interface 2. Update the Admin API setting in the `kong.conf` file to listen on the needed network interfaces on the OS host. A setting of `0.0.0.0:8001` will listen on port `8001` on all available network interfaces. - {% include_cached /md/admin-listen.md desc='long' %} + {% include_cached /md/admin-listen.md kong_version=page.kong_version desc='long' %} Example configuration: @@ -225,11 +232,14 @@ or hybrid mode), you can enable {{site.base_gateway}}'s graphical user interface 5. Access Kong Manager on port `8002`. +{% endif_version %} + ### Enable Dev Portal {:.badge .enterprise} If you're running {{site.base_gateway}} with a database (either in traditional -or hybrid mode), you can enable the [Dev Portal](/gateway/{{page.kong_version}}/developer-portal/). +or hybrid mode), you can enable the {% if_version lte:2.8.x %}[Dev Portal](/gateway/{{page.kong_version}}/developer-portal/).{% endif_version %}{% if_version gte:3.0.x + %}[Dev Portal](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/){% endif_version %} 1. Enable the Dev Portal in the `kong.conf` file by setting the `portal` property to `on` and the `portal_gui_host` property to the DNS or IP address of the system. @@ -264,10 +274,12 @@ or hybrid mode), you can enable the [Dev Portal](/gateway/{{page.kong_version}}/ ## Troubleshooting and support {:.badge .enterprise} +{% if_version gte:3.0.x %} + For troubleshooting license issues, see: -* [Deployment options for licenses](/gateway/{{page.kong_version}}/plan-and-deploy/licenses/deploy-license/) +* [Deployment options for licenses](/gateway/{{page.kong_version}}/licenses/deploy) * [`/licenses` API reference](/gateway/{{page.kong_version}}/admin-api/licenses/reference/) -* [`/licenses` API examples](/gateway/{{page.kong_version}}/admin-api/licenses/examples/) +* [`/licenses` API examples](/gateway/{{page.kong_version}}/licenses/examples) If you did not receive an `HTTP/1.1 200 OK` message or need assistance completing your setup, reach out to your Kong Support contact or go to the @@ -276,5 +288,25 @@ your setup, reach out to your Kong Support contact or go to the ## Next steps Check out {{site.base_gateway}}'s series of -[Getting Started](/gateway/{{include.kong_version}}/get-started/comprehensive) guides to get the most +[Getting Started](/gateway/{{include.kong_version}}/get-started/) guides to get the most out of {{site.base_gateway}}. + +{% endif_version %} +{% if_version lte:2.8.x %} + +For troubleshooting license issues, see: +* [Deployment options for licenses](/gateway/{{page.kong_version}}/plan-and-deploy/licenses/deploy-license) +* [`/licenses` API reference](/gateway/{{page.kong_version}}/admin-api/licenses/reference/) +* [`/licenses` API examples](/gateway/{{page.kong_version}}/admin-api/licenses/examples) + +If you did not receive an `HTTP/1.1 200 OK` message or need assistance completing +your setup, reach out to your Kong Support contact or go to the +[Support Portal](https://support.konghq.com/support/s/). + +## Next steps + +Check out {{site.base_gateway}}'s series of +[Getting Started](/gateway/{{include.kong_version}}/get-started/comprehensive/) guides to get the most +out of {{site.base_gateway}}. + +{% endif_version %} diff --git a/app/_includes/md/installation.md b/app/_includes/md/installation.md index 6a2b88b94fab..073243d75928 100644 --- a/app/_includes/md/installation.md +++ b/app/_includes/md/installation.md @@ -57,7 +57,7 @@ to `off` and the `declarative_config` option to the path of your `kong.yml` file as `root` and the worker processes as `kong` by default. If this is not the desired behavior, you can switch the NGINX master process to run on the built-in `kong` user or to a custom non-root user before starting Kong. For more -information, see [Running Kong as a Non-Root User](/gateway/{{include.kong_version}}/plan-and-deploy/kong-user). +information, see [Running Kong as a Non-Root User](/gateway/{{include.kong_version}}/production/running-kong/kong-user). 1. Start {{site.base_gateway}}: ```bash diff --git a/app/_includes/md/plugins-hub/upstream-headers.md b/app/_includes/md/plugins-hub/upstream-headers.md new file mode 100644 index 000000000000..e4bb8c143243 --- /dev/null +++ b/app/_includes/md/plugins-hub/upstream-headers.md @@ -0,0 +1,20 @@ +When a client has been authenticated, the plugin appends some headers to +the request before proxying it to the upstream service, so that you +can identify the consumer in your code: + +* `X-Consumer-ID`: The ID of the consumer in Kong. +* `X-Consumer-Custom-ID`: The `custom_id` of the consumer (if set). +* `X-Consumer-Username`: The `username` of the consumer (if set). +* `X-Credential-Identifier`: The identifier of the credential (only if the consumer is not the `anonymous` consumer). +* `X-Anonymous-Consumer`: Is set to `true` if authentication fails, and the `anonymous` consumer is set instead. + +You can use this information on your side to implement additional logic. +You can use the `X-Consumer-ID` value to query the Kong Admin API and retrieve +more information about the consumer. + +{% if_plugin_version lte:2.8.x %} + +{:.important} +> **Important**: `X-Credential-Username` was deprecated in favor of `X-Credential-Identifier` in Kong 2.1. + +{% endif_plugin_version %} diff --git a/app/konnect-platform/support-policy.md b/app/_includes/md/support-policy.md similarity index 94% rename from app/konnect-platform/support-policy.md rename to app/_includes/md/support-policy.md index 25596d0094bb..2f1e4b49d352 100644 --- a/app/konnect-platform/support-policy.md +++ b/app/_includes/md/support-policy.md @@ -1,11 +1,3 @@ ---- -title: Version Support Policy -no_version: true -badge: enterprise -content-type: reference ---- - -The support for {{site.ee_product_name}} and {{site.mesh_product_name}} software versions is explained in this topic. ## Types of releases Kong primarily follows [semantic versioning](https://semver.org/) (SemVer) with its products. That is, products typically follow a pattern of `{MAJOR_VERSION}.{MINOR_VERSION}.{PATCH_VERSION}`. {{site.ee_product_name}} additionally has one more decimal point on the right which identifies a sub-patch based on the Kong Community Gateway. For the purposes of this support document: @@ -35,7 +27,7 @@ After the product hits the end of the support period, Kong will provide limited ## Bug fix guidelines Unfortunately, all software is susceptible to bugs. Kong seeks to remedy bugs through a structured protocol as follows: -* Serious security vulnerabilities are treated with the utmost priority. See [here](/gateway/latest/plan-and-deploy/security/kong-security-update-process/) for our security vulnerability reporting and remedy process, including how to report a vulnerability. +* Serious security vulnerabilities are treated with the utmost priority. See [here](/gateway/latest/production/security-update-process/) for our security vulnerability reporting and remedy process, including how to report a vulnerability. * Bugs which result in production outages of {{site.ee_product_name}} or effective non-operation (such as catastrophic performance degradation) will be remedied through high priority bug fixes and provided in patch releases to the Latest Major/Minor Version Release of all currently supported Major Versions of the software and optionally ported to other versions at Kong’s discretion based on the severity and impact of the bug. diff --git a/app/_includes/nav-v2.html b/app/_includes/nav-v2.html index 05c7c1637a6b..21aae7e17c47 100644 --- a/app/_includes/nav-v2.html +++ b/app/_includes/nav-v2.html @@ -70,10 +70,6 @@ Kuma
    - -
    diff --git a/app/_layouts/docs-v2.html b/app/_layouts/docs-v2.html index 9289fbec5684..4fec65ade709 100644 --- a/app/_layouts/docs-v2.html +++ b/app/_layouts/docs-v2.html @@ -70,7 +70,7 @@
    {% endunless %} {% unless page.no_breadcrumbs %} - {% include_cached breadcrumbs.html edition=page.edition no_version=page.no_version has_version=page.has_version kong_version=page.kong_version url=page.url dir=page.dir%} + {% include_cached breadcrumbs.html is_latest=page.is_latest edition=page.edition no_version=page.no_version has_version=page.has_version kong_version=page.kong_version url=page.url dir=page.dir%} {% endunless %}
    {% if page.edition == 'gateway-oss' or page.edition == 'enterprise' or page.edition == 'getting-started-guide' %} @@ -106,12 +106,12 @@

    {{page.subtitle | flatify }}

    {% if page.alpha %}
    - This feature is released as a tech preview (alpha-quality) and should not be deployed in a production environment. + This feature is released as a tech preview (alpha-quality) and should not be deployed in a production environment.
    {% endif %} {% if page.beta %}
    - This feature is released as beta and should not be deployed in a production environment. + This feature is released as beta and should not be deployed in a production environment.
    {% endif %} @@ -124,9 +124,26 @@

    {{page.subtitle | flatify }}

    current {{site.konnect_short_name}} documentation. {% endif %} - {{ content }} + {% if page.book %} +
    +
    + {% if page.book.previous %} + + {% endif %} + {% if page.book.next %} + + {% endif %} +
    + {% endif %} + diff --git a/app/_layouts/extension.html b/app/_layouts/extension.html index ee2787928570..717f334f1793 100644 --- a/app/_layouts/extension.html +++ b/app/_layouts/extension.html @@ -77,7 +77,7 @@ {% endif %} {% for field in page.params.config %} - {% if_plugin_version gte:field.minimum_version %} + {% if_plugin_version gte:field.minimum_version lte:field.maximum_version %} {% if field.group %}

    {{ field.group | markdownify | strip_html }} {% if field.description %}
    {{ field.description | markdownify | strip_html }}{% endif %}
    Form ParameterDescription @@ -165,12 +165,12 @@ {% endif %} {% if page.alpha %}
    - This plugin is released as a (alpha-quality) and should not be deployed in a production environment. + This plugin is released as a (alpha-quality) and should not be deployed in a production environment.
    {% endif %} {% if page.beta %}
    - This plugin is released as and should not be deployed in a production environment. + This plugin is released as and should not be deployed in a production environment.
    {% endif %} @@ -333,7 +333,7 @@

    Privacy Policy

    DB-less compatible? - {% if page.params.dbless_compatible == "yes" or page.params.dbless_compatible == true %}Yes{% endif %}{% + {% if page.params.dbless_compatible == "yes" or page.params.dbless_compatible == true %}Yes{% endif %}{% if page.params.dbless_compatible == "no" or page.params.dbless_compatible == false %}No{% endif %}{% if page.params.dbless_compatible == "partially" %}Partially{% endif %} @@ -369,14 +369,14 @@

    Privacy Policy

    {{ support_dom | truncate: 15 }} {% endif %} - {% if page.source_url or page.license_type %} + {% if page.source_code or page.license_type %} Source
      - {% if page.source_url %} + {% if page.source_code %}
    • - Code + Code
    • {% endif %} {% if page.license_type %} diff --git a/app/_plugins/filters/breadcrumb_title_filter.rb b/app/_plugins/filters/breadcrumb_title_filter.rb new file mode 100644 index 000000000000..7f3abd310fbf --- /dev/null +++ b/app/_plugins/filters/breadcrumb_title_filter.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +require 'yaml' +module Jekyll + module BreadcrumbTitleFilter + def initialize(ctx) + super(ctx) + @mapping = YAML.load_file("#{__dir__}/../../breadcrumb_titles.yml") + end + + def breadcrumb_title(input) + parts = input.split('/') + parts[2] = 'VERSION' + input = "#{parts.join('/')}/" + @mapping[input] + end + end +end + +Liquid::Template.register_filter(Jekyll::BreadcrumbTitleFilter) diff --git a/app/_plugins/filters/titleize_filter.rb b/app/_plugins/filters/titleize_filter.rb new file mode 100644 index 000000000000..f88ace3e5feb --- /dev/null +++ b/app/_plugins/filters/titleize_filter.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require 'active_support/core_ext/string/inflections' # If not using Rails + +ActiveSupport::Inflector.inflections do |inflect| + inflect.acronym 'API' + inflect.acronym 'mTLS' + inflect.acronym 'PDK' + inflect.acronym 'OIDC' + inflect.acronym 'OSS' + inflect.acronym 'kubectl' + inflect.acronym 'OpenShift' + inflect.acronym 'systemd' + inflect.acronym 'StatsD' + inflect.acronym 'GraphQL' + inflect.acronym 'DB' +end + +module Jekyll + module TitleizeFilter + def titleize(input) + input.titleize + end + end +end + +Liquid::Template.register_filter(Jekyll::TitleizeFilter) diff --git a/app/_plugins/generators/alias_generator.rb b/app/_plugins/generators/alias_generator.rb index e7a60f71beb7..f46b7543a103 100644 --- a/app/_plugins/generators/alias_generator.rb +++ b/app/_plugins/generators/alias_generator.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true +require 'yaml' # Alias Generator for Posts using Netlify _redirects # # Generates redirect pages for posts with aliases set in the YAML Front Matter. @@ -30,13 +31,18 @@ module Jekyll class AliasGenerator < Generator priority :lowest - def generate(site) # rubocop:disable Metrics/AbcSize + def generate(site) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength @redirects = [] + # Generate redirect_to from frontmatter redirects site.pages.each do |page| generate_aliases(page.destination('').gsub(/index\.(html|htm)$/, ''), page) end + # Generate redirects from moved_urls + moved_pages = YAML.load_file("#{__dir__}/../../moved_urls.yml") + generate_moved_aliases(moved_pages) + # Read existing _redirects file existing = "#{File.read("#{__dir__}/../../_redirects")}\n" @@ -47,6 +53,14 @@ def generate(site) # rubocop:disable Metrics/AbcSize site.pages << page end + def generate_moved_aliases(moved_pages) + moved_pages.each do |k, v| + k = k.sub('/VERSION/', '/latest/') + v = v.sub('/VERSION/', '/latest/') + @redirects.push("#{k}\t#{v}") + end + end + def generate_aliases(_destination_path, page) # rubocop:disable Metrics/MethodLength aliases = page.data['alias'] alias_paths ||= [] diff --git a/app/_plugins/generators/book.rb b/app/_plugins/generators/book.rb index b1ee28b3b04f..3c0534da32cc 100644 --- a/app/_plugins/generators/book.rb +++ b/app/_plugins/generators/book.rb @@ -22,9 +22,9 @@ def generate(site) # rubocop:disable Metrics/PerceivedComplexity, Metrics/Cyclom 'chapters' => {} } - page.data['book']['previous'] = pages[idx - 1].url if idx.positive? + page.data['book']['previous'] = pages[idx - 1] if idx.positive? - page.data['book']['next'] = pages[idx + 1].url if idx < pages.size - 1 + page.data['book']['next'] = pages[idx + 1] if idx < pages.size - 1 # Add all existing pages links to this page pages.each do |p| diff --git a/app/_plugins/generators/canonical_url_generator.rb b/app/_plugins/generators/canonical_url_generator.rb index 9293bda780b5..f6431ebec79f 100644 --- a/app/_plugins/generators/canonical_url_generator.rb +++ b/app/_plugins/generators/canonical_url_generator.rb @@ -159,6 +159,8 @@ def set_canonical_and_noindex(site, all_pages) # rubocop:disable Metrics/AbcSize def resolve_moved_url(url) resolved_url = nil loop do + raise "Circular reference for #{url}" if url == @moved_pages[url] + url = @moved_pages[url] break unless url diff --git a/app/_plugins/generators/plugin_single_source_generator.rb b/app/_plugins/generators/plugin_single_source_generator.rb index e4e70ddf6ea8..11dabb7ec792 100644 --- a/app/_plugins/generators/plugin_single_source_generator.rb +++ b/app/_plugins/generators/plugin_single_source_generator.rb @@ -135,6 +135,9 @@ def initialize(site, version, author, plugin_name, source_file, source_path, per @data['version'] = version if set_version @data['is_latest'] = permalink_name == 'index' + @data['canonical_url'] = "/hub/#{author}/#{plugin_name}/" unless @data['is_latest'] + @data['seo_noindex'] = true unless @data['is_latest'] + # We need to set the path so that some of the conditionals in templates # continue to work. @data['path'] = "_hub/#{author}/#{plugin_name}/#{permalink_name}.md" diff --git a/app/_plugins/generators/single_source_generator.rb b/app/_plugins/generators/single_source_generator.rb index f9d04dee64ee..6281bf3bd951 100644 --- a/app/_plugins/generators/single_source_generator.rb +++ b/app/_plugins/generators/single_source_generator.rb @@ -15,6 +15,10 @@ def generate(site) # rubocop:disable Metrics/AbcSize # Assume that the whole file should be treated as generated assume_generated = data['assume_generated'].nil? ? true : data['assume_generated'] version = version_for_release(data['product'], data['release']) + + # If there is an 'unlisted' section, add that in to 'items' to be rendered + data['items'] = data['items'] + data['unlisted'] if data['unlisted'] + create_pages(data['items'], site, data['product'], data['release'], version, assume_generated, f) end end @@ -61,7 +65,7 @@ def create_pages(data, site, product, release, version, assume_generated, nav) # end class SingleSourcePage < Jekyll::Page - def initialize(site, src, dest, product, release, version, nav) # rubocop:disable Lint/MissingSuper, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/AbcSize, Metrics/ParameterLists + def initialize(site, src, dest, product, release, version, nav) # rubocop:disable Lint/MissingSuper, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/AbcSize, Metrics/ParameterLists, Metrics/PerceivedComplexity # Configure variables that Jekyll depends on @site = site @@ -90,7 +94,15 @@ def initialize(site, src, dest, product, release, version, nav) # rubocop:disabl # Read the source file, either `.md or /index.md` file = "src/#{src}.md" - file = "src/#{src}/index.md" unless File.exist?(file) + if File.exist?(file) + is_dir_index = false + else + file = "src/#{src}/index.md" + raise "Could not find a source file at 'src/#{src}.md' or #{file}" unless File.exist?(file) + + is_dir_index = true + end + content = File.read(file) # Load content + frontmatter from the file @@ -104,6 +116,7 @@ def initialize(site, src, dest, product, release, version, nav) # rubocop:disabl # Make it clear that this content comes from a generated file @data['path'] = "GENERATED:nav=#{nav}:src=#{src}:#{@dir}" + @data['is_dir_index'] = is_dir_index # Set the current release and concrete version @data['release'] = release diff --git a/app/_plugins/generators/versions.rb b/app/_plugins/generators/versions.rb index b9b90abd0782..fde765c9f77e 100644 --- a/app/_plugins/generators/versions.rb +++ b/app/_plugins/generators/versions.rb @@ -1,3 +1,4 @@ +# Language: Ruby, Level: Level 3 # frozen_string_literal: true module Jekyll @@ -29,10 +30,6 @@ def generate(site) # rubocop:disable Metrics/PerceivedComplexity, Metrics/Method elem['edition'] && elem['edition'] == 'konnect' end - konnect_platform_versions = site.data['kong_versions'].select do |elem| - elem['edition'] && elem['edition'] == 'konnect-platform' - end - kic_versions = site.data['kong_versions'].select do |elem| elem['edition'] && elem['edition'] == 'kubernetes-ingress-controller' end @@ -51,7 +48,6 @@ def generate(site) # rubocop:disable Metrics/PerceivedComplexity, Metrics/Method site.data['kong_versions_deck'] = deck_versions site.data['kong_versions_mesh'] = mesh_versions site.data['kong_versions_konnect'] = konnect_versions - site.data['kong_versions_konnect_platform'] = konnect_platform_versions site.data['kong_versions_kic'] = kic_versions site.data['kong_versions_contributing'] = contributing_versions site.data['kong_versions_gateway'] = gateway_versions @@ -97,7 +93,6 @@ def generate(site) # rubocop:disable Metrics/PerceivedComplexity, Metrics/Method deck contributing konnect - konnect-platform kubernetes-ingress-controller gateway gateway-oss @@ -131,12 +126,6 @@ def generate(site) # rubocop:disable Metrics/PerceivedComplexity, Metrics/Method page.data['kong_versions'] = konnect_versions page.data['nav_items'] = site.data['docs_nav_konnect'] create_aliases(page, '/konnect', 1, parts, 'release') - when 'konnect-platform' - page.data['edition'] = parts[0] - page.data['kong_version'] = parts[1] - page.data['kong_versions'] = konnect_platform_versions - page.data['nav_items'] = site.data['docs_nav_konnect_platform'] - create_aliases(page, '/konnect-platform', 1, parts, 'release') when 'kubernetes-ingress-controller' page.data['edition'] = parts[0] page.data['kong_version'] = parts[1] diff --git a/app/_redirects b/app/_redirects index 1061206718ac..3f177b3645a9 100644 --- a/app/_redirects +++ b/app/_redirects @@ -1,6 +1,15 @@ +# DEPRECATED OS +/gateway/3.0.x/install-and-run/centos /gateway/latest/install-and-run/os-support +/gateway/latest/install-and-run/centos /gateway/latest/install-and-run/os-support + # FREE TRIALS, GENERAL LICENSING /free-trial/guide/ https://konghq.com/install /konnect-platform/plans/ https://konghq.com/pricing/ +/konnect-platform/get-started/ /konnect/getting-started/ +/konnect-platform/compatibility/plugins/ /hub/plugins/compatibility/ +/konnect-platform/key-concepts/ /konnect/availability-stages/ +/konnect-platform/support-policy/ /gateway/latest/support-policy/ +/konnect-platform/ /konnect/ # DECK /deck/overview/ /deck/ @@ -87,7 +96,6 @@ # PLUGINS /hub/api-fortress/api-fortress-http-log/ /hub/ /hub/api-fortress/api-fortress-http-log/* /hub/ -/hub/plugins/compatibility /konnect-platform/compatibility/plugins /enterprise/latest/plugins/statsd-advanced/ /hub/kong-inc/statsd-advanced/ /hub/kong-inc/basic-auth/1.0-x.html /hub/kong-inc/basic-auth/2.1-x.html /hub/kong-inc/basic-authentication/ /hub/kong-inc/basic-auth/ @@ -97,7 +105,7 @@ /hub/kong-inc/ldap-authentication-advanced /hub/kong-inc/ldap-auth-advanced/ /hub/kong-inc/ldap-authentication /hub/kong-inc/ldap-auth/ /hub/kong-inc/proxy-cache/0.35-x.html /hub/kong-inc/proxy-cache/ -/hub/kong-inc/upstream-tls/0.36-x.html /hub/ +/hub/kong-inc/upstream-tls/* /hub/ /hub/rate-limiting-advanced /hub/kong-inc/rate-limiting-advanced/ /kong-inc/rate-limiting/ /hub/kong-inc/rate-limiting/ /latest/pdk/kong.service.request/ /gateway/latest/pdk/kong.service.request/ @@ -122,7 +130,104 @@ /enterprise/2.6.x/plugins/* /gateway/2.6.x/configuration/auth/:splat /enterprise/2.7.x/plugins/* /gateway/2.7.x/configuration/auth/:splat /enterprise/latest/plugins/* /gateway/latest/configuration/auth/:splat - +/hub/kong-inc/kubernetes-sidecar-injector /mesh/ +/hub/kong-inc/ee-openid-connect-rp/ /hub/kong-inc/openid-connect/ + +/hub/kong-inc/acl/0.* /hub/kong-inc/acl/ +/hub/kong-inc/acme/0.* /hub/kong-inc/acme/ +/hub/kong-inc/application-registration/1.* /hub/kong-inc/application-registration/ +/hub/kong-inc/aws-lambda/0.* /hub/kong-inc/aws-lambda/ +/hub/kong-inc/aws-lambda/1.* /hub/kong-inc/aws-lambda/ +/hub/kong-inc/aws-lambda/3.4.x.html /hub/kong-inc/aws-lambda/ +/hub/kong-inc/aws-lambda/3.5.x.html /hub/kong-inc/aws-lambda/ +/hub/kong-inc/azure-functions/0.* /hub/kong-inc/azure-functions/ +/hub/kong-inc/basic-auth/0.* /hub/kong-inc/basic-auth/ +/hub/kong-inc/basic-auth/2.1-x.html /hub/kong-inc/basic-auth/ +/hub/kong-inc/bot-detection/0.* /hub/kong-inc/bot-detection/ +/hub/kong-inc/canary/0.* /hub/kong-inc/canary/ +/hub/kong-inc/correlation-id/0.* /hub/kong-inc/correlation-id/ +/hub/kong-inc/correlation-id/1.* /hub/kong-inc/correlation-id/ +/hub/kong-inc/cors/0.* /hub/kong-inc/cors/ +/hub/kong-inc/datadog/0.* /hub/kong-inc/datadog/ +/hub/kong-inc/datadog/1.* /hub/kong-inc/datadog/ +/hub/kong-inc/datadog/3.1.x.html /hub/kong-inc/datadog/ +/hub/kong-inc/exit-transformer/1.* /hub/kong-inc/exit-transformer/ +/hub/kong-inc/file-log/0.* /hub/kong-inc/file-log/ +/hub/kong-inc/file-log/1.* /hub/kong-inc/file-log/ +/hub/kong-inc/forward-proxy/0.* /hub/kong-inc/forward-proxy/ +/hub/kong-inc/forward-proxy/1.* /hub/kong-inc/forward-proxy/ +/hub/kong-inc/graphql-rate-limiting-advanced/0.* /hub/kong-inc/graphql-rate-limiting-advanced/ +/hub/kong-inc/grpc-gateway/0.* /hub/kong-inc/grpc-gateway/ +/hub/kong-inc/grpc-web/0.* /hub/kong-inc/grpc-web/ +/hub/kong-inc/hmac-auth/0.* /hub/kong-inc/hmac-auth +/hub/kong-inc/hmac-auth/2.1-x.html /hub/kong-inc/hmac-auth +/hub/kong-inc/hmac-auth/2.4-x.html /hub/kong-inc/hmac-auth +/hub/kong-inc/http-log/0.* /hub/kong-inc/http-log/ +/hub/kong-inc/http-log/1.* /hub/kong-inc/http-log/ +/hub/kong-inc/ip-restriction/0.* /hub/kong-inc/ip-restriction/ +/hub/kong-inc/ip-restriction/1.* /hub/kong-inc/ip-restriction/ +/hub/kong-inc/jwt/0.* /hub/kong-inc/jwt/ +/hub/kong-inc/jwt/2.1-x.html /hub/kong-inc/jwt/ +/hub/kong-inc/jwt-signer/0.* /hub/kong-inc/jwt-signer/ +/hub/kong-inc/jwt-signer/1.* /hub/kong-inc/jwt-signer/ +/hub/kong-inc/kafka-log/0.* /hub/kong-inc/kafka-log/ +/hub/kong-inc/kafka-upstream/0.* /hub/kong-inc/kafka-upstream/ +/hub/kong-inc/key-auth/0.* /hub/kong-inc/key-auth/ +/hub/kong-inc/key-auth-enc/1.* /hub/kong-inc/key-auth-enc/ +/hub/kong-inc/ldap-auth/0.* /hub/kong-inc/ldap-auth/ +/hub/kong-inc/ldap-auth/2.1-x.html /hub/kong-inc/ldap-auth/ +/hub/kong-inc/ldap-auth-advanced/0.* /hub/kong-inc/ldap-auth-advanced/ +/hub/kong-inc/ldap-auth-advanced/1.* /hub/kong-inc/ldap-auth-advanced/ +/hub/kong-inc/loggly/0.* /hub/kong-inc/loggly/ +/hub/kong-inc/loggly/1.* /hub/kong-inc/loggly/ +/hub/kong-inc/mocking/0.* /hub/kong-inc/mocking/ +/hub/kong-inc/mtls-auth/0.* /hub/kong-inc/mtls-auth/ +/hub/kong-inc/mtls-auth/1.* /hub/kong-inc/mtls-auth/ +/hub/kong-inc/oauth2/0.* /hub/kong-inc/oauth2/ +/hub/kong-inc/oauth2/1.* /hub/kong-inc/oauth2/ +/hub/kong-inc/oauth2-introspection/0.* /hub/kong-inc/oauth2-introspection/ +/hub/kong-inc/opa/0.* /hub/kong-inc/opa/ +/hub/kong-inc/openid-connect/0.* /hub/kong-inc/openid-connect/ +/hub/kong-inc/openid-connect/1.* /hub/kong-inc/openid-connect/ +/hub/kong-inc/openwhisk/0.1-x.html /hub/kong-inc/openwhisk/ +/hub/kong-inc/prometheus/0.* /hub/kong-inc/prometheus/ +/hub/kong-inc/prometheus/1.* /hub/kong-inc/prometheus/ +/hub/kong-inc/proxy-cache/0.* /hub/kong-inc/proxy-cache/ +/hub/kong-inc/proxy-cache-advanced/0.* /hub/kong-inc/proxy-cache-advanced/ +/hub/kong-inc/rate-limiting/0.* /hub/kong-inc/rate-limiting/ +/hub/kong-inc/rate-limiting/1.* /hub/kong-inc/rate-limiting/ +/hub/kong-inc/rate-limiting/2.1-x.html /hub/kong-inc/rate-limiting/ +/hub/kong-inc/rate-limiting-advanced/0.* /hub/kong-inc/rate-limiting-advanced/ +/hub/kong-inc/rate-limiting-advanced/1.* /hub/kong-inc/rate-limiting-advanced/ +/hub/kong-inc/request-size-limiting/0.* /hub/kong-inc/request-size-limiting/ +/hub/kong-inc/request-size-limiting/1.* /hub/kong-inc/request-size-limiting/ +/hub/kong-inc/request-termination/0.* /hub/kong-inc/request-termination/ +/hub/kong-inc/request-termination/1.* /hub/kong-inc/request-termination/ +/hub/kong-inc/request-transformer/0.* /hub/kong-inc/request-transformer +/hub/kong-inc/request-transformer/1.* /hub/kong-inc/request-transformer +/hub/kong-inc/request-transformer-advanced/0.* /hub/kong-inc/request-transformer-advanced/ +/hub/kong-inc/request-transformer-advanced/1.* /hub/kong-inc/request-transformer-advanced/ +/hub/kong-inc/request-validator/0.* /hub/kong-inc/request-validator/ +/hub/kong-inc/response-ratelimiting/1.* /hub/kong-inc/response-ratelimiting/ +/hub/kong-inc/response-transformer/0.* /hub/kong-inc/response-transformer/ +/hub/kong-inc/response-transformer/1.* /hub/kong-inc/response-transformer/ +/hub/kong-inc/response-transformer-advanced/0.* /hub/kong-inc/response-transformer-advanced/ +/hub/kong-inc/response-transformer-advanced/1.* /hub/kong-inc/response-transformer-advanced/ +/hub/kong-inc/route-by-header/0.* /hub/kong-inc/route-by-header/ +/hub/kong-inc/serverless-functions/0.* /hub/kong-inc/serverless-functions +/hub/kong-inc/serverless-functions/1.* /hub/kong-inc/serverless-functions +/hub/kong-inc/session/0.* /hub/kong-inc/session/ +/hub/kong-inc/session/1.* /hub/kong-inc/session/ +/hub/kong-inc/session/2.2-x.html /hub/kong-inc/session/ +/hub/kong-inc/statsd/0.* /hub/kong-inc/statsd/ +/hub/kong-inc/syslog/0.* /hub/kong-inc/syslog +/hub/kong-inc/syslog/1.* /hub/kong-inc/syslog +/hub/kong-inc/tcp-log/0.* /hub/kong-inc/tcp-log/ +/hub/kong-inc/tcp-log/1.* /hub/kong-inc/tcp-log/ +/hub/kong-inc/udp-log/0.* /hub/kong-inc/udp-log/ +/hub/kong-inc/udp-log/1.* /hub/kong-inc/udp-log/ +/hub/kong-inc/vault-auth/0.* /hub/kong-inc/udp-log/ +/hub/kong-inc/zipkin/1.* /hub/kong-inc/zipkin/ # KONNECT @@ -665,12 +770,12 @@ # GENERAL REDIRECTS TO /GATEWAY/ /enterprise/changelog /gateway/changelog -/enterprise/2.6.x/introduction/key-concepts /konnect-platform/key-concepts -/enterprise/2.7.x/introduction/key-concepts /konnect-platform/key-concepts -/enterprise/latest/introduction/key-concepts /konnect-platform/key-concepts -/enterprise/2.6.x/introduction/support-policy /konnect-platform/support-policy -/enterprise/2.7.x/introduction/support-policy /konnect-platform/support-policy -/enterprise/latest/introduction/support-policy /konnect-platform/support-policy +/enterprise/2.6.x/introduction/key-concepts /gateway/latest/availability-stages/ +/enterprise/2.7.x/introduction/key-concepts /gateway/latest/availability-stages/ +/enterprise/latest/introduction/key-concepts /gateway/latest/availability-stages/ +/enterprise/2.6.x/introduction/support-policy /gateway/latest/support-policy/ +/enterprise/2.7.x/introduction/support-policy /gateway/latest/support-policy/ +/enterprise/latest/introduction/support-policy /gateway/latest/support-policy/ /latest/* / /latest / /2.6.x/* /gateway/2.6.x/ @@ -690,3 +795,16 @@ /introduction / /enterprise/ /gateway/ /gateway-oss/ /gateway/ + + + +# 3.0 + +/gateway/2.8.x/install-and-run/ /gateway/latest/install-and-run/os-support +/gateway/2.8.x/install-and-run/centos/ /gateway/latest/install-and-run/os-support +/gateway/2.8.x/get-started/quickstart/ /gateway/latest/get-started/ +/gateway/2.8.x/get-started/quickstart/configuring-a-service/ /gateway/latest/get-started/services-and-routes/ +/gateway/2.8.x/get-started/quickstart/configuring-a-grpc-service/ /gateway/latest/get-started/ratelimiting/ +/gateway/2.8.x/get-started/quickstart/enabling-plugins/ /gateway/latest/key-concepts/plugins/ +/gateway/2.8.x/get-started/quickstart/adding-consumers/ /gateway/latest/get-started/key-authentication +/gateway/2.8.x/admin-api/rbac/examples/ /gateway/latest/admin-api/rbac/reference/ \ No newline at end of file diff --git a/app/api/vitals.yaml b/app/api/vitals.yaml new file mode 100644 index 000000000000..2cbcf24c9dfb --- /dev/null +++ b/app/api/vitals.yaml @@ -0,0 +1,847 @@ +swagger: '2.0' +info: + description: Vitals API + version: 2.4.0 + title: Vitals API +basePath: / +tags: + - name: health + description: Stats about the health of a Kong cluster + - name: traffic + description: Stats about traffic routed through Kong +schemes: + - http +paths: + /vitals: + get: + tags: + - vitals + summary: Get information about stats collected + description: '' + operationId: getVitalsInfo + produces: + - application/json + responses: + '200': + description: successful operation + schema: + $ref: '#/definitions/VitalsInfo' + /vitals/cluster: + get: + tags: + - health + summary: Get health stats for this Kong cluster + description: '' + operationId: getClusterStats + produces: + - application/json + parameters: + - name: interval + in: query + description: Granularity of the time series (days, minutes or seconds) + required: true + type: string + - name: start_ts + in: query + description: Requested start of the time series, in Unix epoch format (seconds) + required: false + type: string + - name: end_ts + in: query + description: Requested end of the time series, in Unix epoch format (seconds) + required: false + type: string + responses: + '200': + description: successful operation + schema: + $ref: '#/definitions/ClusterVitalsTimeSeriesWithMetadata' + '400': + description: Invalid query params + /vitals/cluster/status_codes: + get: + deprecated: true + tags: + - traffic + summary: Get the status code classes returned across the cluster + description: This operation is deprecated. Use /status_code_classes. + operationId: getClusterStatusCodeStats + produces: + - application/json + parameters: + - name: interval + in: query + description: Granularity of the time series (days, minutes or seconds) + required: true + type: string + - name: start_ts + in: query + description: Requested start of the time series, in Unix epoch format (seconds) + required: false + type: string + - name: end_ts + in: query + description: Requested end of the time series, in Unix epoch format (seconds) + required: false + type: string + responses: + '200': + description: successful operation + schema: + $ref: '#/definitions/ClusterVitalsStatusCodesWithMetadata' + '400': + description: Invalid query params + /vitals/nodes: + get: + tags: + - health + summary: Get health stats for all nodes + description: '' + operationId: getAllNodeStats + produces: + - application/json + parameters: + - name: interval + in: query + description: Granularity of the time series (days, minutes or seconds) + required: true + type: string + - name: start_ts + in: query + description: Requested start of the time series, in Unix epoch format (seconds) + required: false + type: string + - name: end_ts + in: query + description: Requested end of the time series, in Unix epoch format (seconds) + required: false + type: string + responses: + '200': + description: successful operation + schema: + $ref: '#/definitions/NodeVitalsTimeSeriesWithMetadata' + '400': + description: Invalid query params + '/vitals/nodes/{node_id}': + get: + tags: + - health + summary: Get stats for a specific node by UUID + description: '' + operationId: getNodeStatsByID + produces: + - application/json + parameters: + - name: node_id + type: string + in: path + description: Node to retrieve stats for + required: true + - name: interval + in: query + description: Granularity of the time series (days, minutes or seconds) + required: true + type: string + - name: start_ts + in: query + description: Requested start of the time series, in Unix epoch format (seconds) + required: false + type: string + - name: end_ts + in: query + description: Requested end of the time series, in Unix epoch format (seconds) + required: false + type: string + responses: + '200': + description: successful operation + schema: + $ref: '#/definitions/NodeVitalsTimeSeriesWithMetadata' + '400': + description: Invalid query params + '404': + description: Unable to find requested node + '/{workspace_name}/vitals/consumers/{consumer_id}/cluster': + get: + tags: + - traffic + deprecated: true + summary: Get count of requests for the given consumer across entire cluster + description: This operation is deprecated. Use /vitals/status_codes/by_consumer_and_route + operationId: getConsumerClusterStats + produces: + - application/json + parameters: + - name: workspace_name + type: string + in: path + description: Workspace containing the requested consumer. + required: true + - name: consumer_id + type: string + in: path + description: Consumer to retrieve stats for + required: true + - name: interval + type: string + in: query + description: Granularity of the time series (days, minutes or seconds) + required: true + - name: start_ts + in: query + description: Requested start of the time series, in Unix epoch format (seconds) + required: false + type: string + - name: end_ts + in: query + description: Requested end of the time series, in Unix epoch format (seconds) + required: false + type: string + responses: + '200': + description: successful operation + schema: + $ref: '#/definitions/ClusterConsumersTimeSeriesWithMetadata' + '400': + description: Invalid query params + '404': + description: Unable to find requested consumer + /{workspace_name}/vitals/status_code_classes: + get: + tags: + - traffic + summary: Get status code classes for a cluster or workspace. + description: '' + operationId: getStatusCodeClassesByWorkspace + produces: + - application/json + parameters: + - name: workspace_name + type: string + in: path + description: >- + Optional parameter. If provided, returns status code classes for the + workspace; otherwise, returns them for the cluster + required: true + - name: interval + type: string + in: query + description: Granularity of the time series (days, minutes or seconds) + required: true + - name: start_ts + in: query + description: Requested start of the time series, in Unix epoch format (seconds) + required: false + type: string + - name: end_ts + in: query + description: Requested end of the time series, in Unix epoch format (seconds) + required: false + type: string + responses: + '200': + description: successful operation + schema: + $ref: '#/definitions/StatusCodesByEntityMetadata' + '400': + description: Invalid query params + '404': + description: Unable to find requested consumer + /{workspace_name}/vitals/status_codes/by_service: + get: + tags: + - traffic + summary: Get a time series of status codes returned by a given service + description: '' + operationId: getStatusCodesByService + produces: + - application/json + parameters: + - name: service_id + type: string + in: query + description: Service to retrieve status codes for + required: true + - name: interval + type: string + in: query + description: Granularity of the time series (days, minutes or seconds) + required: true + - name: start_ts + in: query + description: Requested start of the time series, in Unix epoch format (seconds) + required: true + type: string + - name: end_ts + in: query + description: Requested end of the time series, in Unix epoch format (seconds) + required: true + type: string + - name: workspace_name + type: string + in: path + description: Workspace containing the requested service. + required: true + responses: + '200': + description: successful operation + schema: + $ref: '#/definitions/StatusCodesByEntityTimeSeriesWithMetadata' + '400': + description: Invalid query params + '404': + description: Unable to find requested service + /{workspace_name}/vitals/status_codes/by_route: + get: + tags: + - traffic + summary: Get cluster-wide count of status for a given route + description: '' + operationId: getStatusCodesByRoute + produces: + - application/json + parameters: + - name: route_id + type: string + in: query + description: Route to retrieve status codes for + required: true + - name: interval + type: string + in: query + description: Granularity of the time series (days, minutes or seconds) + required: true + - name: start_ts + in: query + description: Requested start of the time series, in Unix epoch format (seconds) + required: true + type: string + - name: end_ts + in: query + description: Requested end of the time series, in Unix epoch format (seconds) + required: true + type: string + - name: workspace_name + type: string + in: path + description: Workspace containing the requested route. + required: true + responses: + '200': + description: successful operation + schema: + $ref: '#/definitions/StatusCodesByEntityTimeSeriesWithMetadata' + '400': + description: Invalid query params + '404': + description: Unable to find requested route + /{workspace_name}/vitals/status_codes/by_consumer: + get: + tags: + - traffic + summary: Get cluster-wide count of status for a given consumer + description: '' + operationId: getStatusCodesByRoute + produces: + - application/json + parameters: + - name: consumer_id + type: string + in: query + description: Route to retrieve status codes for + required: true + - name: interval + type: string + in: query + description: Granularity of the time series (days, minutes or seconds) + required: true + - name: start_ts + in: query + description: Requested start of the time series, in Unix epoch format (seconds) + required: true + type: string + - name: end_ts + in: query + description: Requested end of the time series, in Unix epoch format (seconds) + required: true + type: string + - name: workspace_name + type: string + in: path + description: Workspace containing the requested consumer. + required: true + responses: + '200': + description: successful operation + schema: + $ref: '#/definitions/StatusCodesByEntityTimeSeriesWithMetadata' + '400': + description: Invalid query params + '404': + description: Unable to find requested route + '/{workspace_name}/vitals/status_codes/by_consumer_and_route': + get: + tags: + - traffic + summary: >- + Get status codes for all the routes called by the given consumer in the + given timeframe + description: '' + operationId: getStatusCodesByConsumerAndRoute + produces: + - application/json + parameters: + - name: consumer_id + type: string + in: query + description: Consumer to retrieve status codes for + required: true + - name: interval + type: string + in: query + description: Granularity of the time series (days, minutes or seconds) + required: true + - name: start_ts + in: query + description: Requested start of the time series, in Unix epoch format (seconds) + required: false + type: string + - name: end_ts + in: query + description: Requested end of the time series, in Unix epoch format (seconds) + required: false + type: string + - name: workspace_name + type: string + in: path + description: Workspace containing the requested consumer and route. + required: true + responses: + '200': + description: successful operation + schema: + $ref: '#/definitions/StatusCodesByEntityTimeSeriesWithMetadata' + '400': + description: Invalid query params + '404': + description: Unable to find requested consumer +definitions: + ClusterVitalsMetadata: + properties: + level: + type: string + example: cluster + enum: + - cluster + - node + workspace_id: + type: string + description: UUID of workspace this time series is for + interval: + type: string + example: seconds + enum: + - seconds + - minutes + - days + interval_width: + type: number + example: 60 + earliest_ts: + type: integer + example: 1514508300 + latest_ts: + type: integer + example: 1514508480 + stat_labels: + type: array + items: + type: string + example: + - cache_datastore_hits_total + - cache_datastore_misses_total + - latency_proxy_request_min_ms + - latency_proxy_request_max_ms + - latency_upstream_min_ms + - latency_upstream_max_ms + - requests_proxy_total + - latency_proxy_request_avg_ms + - latency_upstream_avg_ms + StatusCodesByEntityMetadata: + properties: + entity_type: + type: string + example: service|route + entity_id: + type: string + example: + level: + type: string + example: cluster + enum: + - cluster + workspace_id: + type: string + description: UUID of the workspace this time series is for + interval: + type: string + example: seconds + enum: + - seconds + - minutes + - days + interval_width: + type: number + example: 60 + earliest_ts: + type: integer + example: 1514508300 + latest_ts: + type: integer + example: 1514508480 + stat_labels: + type: array + items: + type: string + example: + - status_codes_service|route_total + StatusCodesByEntityTimeSeriesWithMetadata: + type: object + properties: + meta: + $ref: '#/definitions/StatusCodesByEntityMetadata' + stats: + $ref: '#/definitions/StatusCodesByEntityStats' + ClusterVitalsStatusCodesMetadata: + properties: + level: + type: string + example: cluster + enum: + - cluster + interval: + type: string + example: seconds + enum: + - seconds + - minutes + - days + interval_width: + type: number + example: 60 + earliest_ts: + type: integer + example: 1514508300 + latest_ts: + type: integer + example: 1514508480 + stat_labels: + type: array + items: + type: string + example: + - status_code_classes_total + ClusterVitalsStats: + properties: + cluster: + type: object + properties: + : + type: array + items: + type: integer + description: >- + List of stat values collected at "timestamp_n", in same order as + "meta.stat_labels" + example: + - 999 + - 130 + - 0 + - 35 + - 142 + - 528 + - 1146 + - 110 + - 156 + StatusCodesByEntityStats: + properties: + cluster: + type: object + description: Vitals status codes data available at the cluster level + properties: + : + type: object + properties: + : + type: integer + description: >- + The total count of a particular status code for the time + period + example: 1824 + ClusterVitalsStatusCodesStats: + properties: + cluster: + type: object + description: Vitals status codes data available at the cluster level + properties: + : + type: object + properties: + : + type: integer + description: >- + The total count of a particular status code class for the time + period + example: 1824 + ClusterVitalsTimeSeriesWithMetadata: + type: object + properties: + meta: + $ref: '#/definitions/ClusterVitalsMetadata' + stats: + $ref: '#/definitions/ClusterVitalsStats' + ClusterVitalsStatusCodesWithMetadata: + type: object + properties: + meta: + $ref: '#/definitions/ClusterVitalsStatusCodesMetadata' + stats: + $ref: '#/definitions/ClusterVitalsStatusCodesStats' + ClusterConsumersMetadata: + properties: + level: + type: string + example: cluster + enum: + - cluster + - node + interval: + type: string + example: seconds + enum: + - seconds + - minutes + - days + interval_width: + type: number + example: 60 + earliest_ts: + type: integer + example: 1514508300 + latest_ts: + type: integer + example: 1514508480 + stat_labels: + type: array + items: + type: string + example: + - requests_consumer_total + ClusterConsumersStats: + properties: + cluster: + type: object + properties: + : + type: integer + description: >- + List of stat values collected at "timestamp_n", in same order as + "meta.stat_labels" + example: 47 + ClusterConsumersTimeSeriesWithMetadata: + type: object + properties: + meta: + $ref: '#/definitions/ClusterConsumersMetadata' + stats: + $ref: '#/definitions/ClusterConsumersStats' + NodeVitalsMetadata: + properties: + level: + type: string + example: node + enum: + - cluster + - node + workspace_id: + type: string + description: UUID of the workspace this time series is for + interval: + type: string + example: seconds + enum: + - seconds + - minutes + - days + interval_width: + type: number + example: 60 + earliest_ts: + type: integer + example: 1514508300 + latest_ts: + type: integer + example: 1514508480 + stat_labels: + type: array + items: + type: string + example: + - cache_datastore_hits_total + - cache_datastore_misses_total + - latency_proxy_request_min_ms + - latency_proxy_request_max_ms + - latency_upstream_min_ms + - latency_upstream_max_ms + - requests_proxy_total + - latency_proxy_request_avg_ms + - latency_upstream_avg_ms + nodes: + type: object + description: >- + table of node ids that contributed to this time series. This element + is not included on cluster-level requests. + properties: + : + type: object + description: The id of a node included in this time series. + properties: + hostname: + type: string + description: The name of the host where this node runs + NodeVitalsStats: + properties: + : + type: object + description: >- + The node this time series is for, or "cluster" if it's a cluster-level + time series. + properties: + : + type: array + items: + type: integer + description: >- + List of stat values collected at "timestamp_n", in same order as + "meta.stat_labels" + example: + - 999 + - 130 + - 0 + - 35 + - 142 + - 528 + - 1146 + - 110 + - 156 + NodeVitalsTimeSeriesWithMetadata: + type: object + properties: + meta: + $ref: '#/definitions/NodeVitalsMetadata' + stats: + $ref: '#/definitions/NodeVitalsStats' + VitalsInfo: + type: object + example: + stats: + cache_datastore_hits_total: + levels: + cluster: + intervals: + days: + retention_period_seconds: 63072000 + minutes: + retention_period_seconds: 90000 + seconds: + retention_period_seconds: 3600 + nodes: + intervals: + days: + retention_period_seconds: 63072000 + minutes: + retention_period_seconds: 90000 + seconds: + retention_period_seconds: 3600 + properties: + stats: + type: object + properties: + : + type: object + properties: + levels: + type: object + description: >- + Vitals data is tracked and aggregated at different levels (per + cluster, per node) + properties: + cluster: + type: object + description: Vitals data available at the cluster level + properties: + intervals: + type: object + description: >- + Vitals data is available at different intervals + (seconds, minutes, days) + properties: + days: + type: object + properties: + retention_period_seconds: + type: integer + description: >- + Configured retention period (in seconds) for + the days interval + minutes: + type: object + properties: + retention_period_seconds: + type: integer + description: >- + Configured retention period (in seconds) for + the minutes interval + seconds: + type: object + properties: + retention_period_seconds: + type: integer + description: >- + Configured retention period (in seconds) for + the seconds interval + nodes: + type: object + description: Vitals data available at the node level + properties: + intervals: + type: object + description: >- + Vitals data is available at different intervals + (seconds, minutes, days) + properties: + days: + type: object + properties: + retention_period_seconds: + type: integer + description: >- + Configured retention period (in seconds) for + the days interval + minutes: + type: object + properties: + retention_period_seconds: + type: integer + description: >- + Configured retention period (in seconds) for + the minutes interval + seconds: + type: object + properties: + retention_period_seconds: + type: integer + description: >- + Configured retention period (in seconds) for + the seconds interval diff --git a/app/breadcrumb_titles.yml b/app/breadcrumb_titles.yml new file mode 100644 index 000000000000..94964a6dd409 --- /dev/null +++ b/app/breadcrumb_titles.yml @@ -0,0 +1,5 @@ +/gateway/VERSION/production/: Production Deployment +/gateway/VERSION/kong-manager/auth/: Authentication and Authorization +/gateway/VERSION/kong-manager/auth/oidc/: OpenID Connect +/gateway/VERSION/kong-plugins/authentication/oidc/: OpenID Connect +/gateway/VERSION/kong-enterprise/analytics/: Vitals \ No newline at end of file diff --git a/app/contributing/terms.md b/app/contributing/terms.md deleted file mode 100644 index 0334dc0c06bb..000000000000 --- a/app/contributing/terms.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -title: Common terms in the docs -no_version: true ---- - -> WORK IN PROGRESS - -## General terms - -### Control plane - -#### Data plane -(data plane proxy, data plane instance, data plane node) - -#### Service -(Service object vs service) - -Service package, version, implementation - -#### Route -(Route object vs route) - -#### Upstream -(Upstream object vs upstream service) - -#### Runtime - -#### DB-less mode vs database-backed - -#### Hybrid mode - - -## Product and component names - -* Kong Konnect platform (Konnect) -* Konnect SaaS -* Kong Mesh (Mesh, service mesh) -* Kong for Kubernetes; Kong on Kubernetes Enterprise -* Kubernetes Ingress Controller/Kong Ingress Controller (KIC) -* decK -* Kong Gateway (gateway, API gateway) -* Kong Gateway (OSS) -* Insomnia -* Kuma -* Dev Portal (developer portal) -* Vitals diff --git a/app/contributing/variables.md b/app/contributing/variables.md index 9ebe847a5f30..a33d4c94c986 100644 --- a/app/contributing/variables.md +++ b/app/contributing/variables.md @@ -3,24 +3,24 @@ title: Using Variables no_version: true --- -Use variable in content text, links, and in codeblocks. +Use variable in content text, links, and in code blocks. Do not use in: * Page front matter: This is an important note for plugins in particular, as much of the page content is generated out of a plugin’s front matter. -* Auto-generated docs (eg Admin API). +* Auto-generated docs (for example, Admin API). * Page titles or headings. ## Product names For specific product name definitions and when to use what, see [word choice and naming](/contributing/word-choice). - + Variable | Output | Definition ---------|--------|----------- {% raw %}`{{site.base_gateway}}`{% endraw %} | {{site.base_gateway}} | The Kong API Gateway. Use this in most situations, including:

      • When talking about a feature that is available for both open-source and Enterprise
      • When referring to the Enterprise image used in any mode, with a license or without. {% raw %}`{{site.ee_product_name}}`{% endraw %} | {{site.ee_product_name}} | (Legacy variable, do not use) The whole self-managed Enterprise Gateway package, including modules and peripherals, eg Kong Manager, Dev Portal, Vitals, etc. {% raw %}`{{site.ce_product_name}}`{% endraw %} | {{site.ce_product_name}} | Kong's open-source API gateway. Use when referring to something that's _only_ available in open-source. -{% raw %}`{{site.konnect_product_name}}`{% endraw %}| {{site.konnect_product_name}} | The full name of the Kong Konnect platform, both cloud and self-managed. +{% raw %}`{{site.konnect_product_name}}`{% endraw %}| {{site.konnect_product_name}} | The full name of Kong Konnect. {% raw %}`{{site.konnect_short_name}}`{% endraw %} | {{site.konnect_short_name}} | The short name of the SaaS Konnect control plane. {% raw %}`{{site.konnect_saas}}`{% endraw %} | {{site.konnect_saas}} | The full name of the SaaS Konnect control plane. {% raw %}`{{site.company_name}}`{% endraw %} | {{site.company_name}} | The name of the company.

      Sometimes "Kong" is used to refer to Kong Gateway. For branding reasons, we should avoid using this term to refer to Kong Gateway going forward, however, user communities will continue to use this term as shorthand. @@ -33,6 +33,8 @@ Variable | Output | Definition {% raw %}`{{site.links.download}}`{% endraw %} | https://download.konghq.com | Kong's product download site. {% raw %}`{{site.links.web}}`{% endraw %} | https://docs.konghq.com | Kong Docs website. + + ## Update or add variables The product name variables are defined in the site config file, `jekyll.yml`. @@ -42,6 +44,7 @@ If you need to update the variable text, add, or remove a variable, edit For a new variable, use the following syntax: `:` + + + diff --git a/app/enterprise/2.1.x/plugin-development/access-the-datastore.md b/app/enterprise/2.1.x/plugin-development/access-the-datastore.md index f783a00d90a5..e50e794b71ef 100644 --- a/app/enterprise/2.1.x/plugin-development/access-the-datastore.md +++ b/app/enterprise/2.1.x/plugin-development/access-the-datastore.md @@ -68,8 +68,4 @@ local inserted_plugin, err = kong.db.plugins:insert({ For a real-life example of the DAO being used in a plugin, see the [Key-Auth plugin source code](https://github.com/Kong/kong/blob/master/kong/plugins/key-auth/handler.lua). ---- - -Next: [Storing Custom Entities ›]({{page.book.next}}) - [Plugin Development Kit]: /enterprise/{{page.kong_version}}/pdk diff --git a/app/enterprise/2.1.x/plugin-development/admin-api.md b/app/enterprise/2.1.x/plugin-development/admin-api.md index b60861663d9e..fc82f44d1d95 100644 --- a/app/enterprise/2.1.x/plugin-development/admin-api.md +++ b/app/enterprise/2.1.x/plugin-development/admin-api.md @@ -167,8 +167,4 @@ three functions: - The `PUT` function populates `self.args.post.consumer` before calling the `endpoints`-provided `put_entity_endpoint` function. ---- - -Next: [Write tests for your plugin]({{page.book.next}}) - [Admin API]: /enterprise/{{page.kong_version}}/admin-api/ diff --git a/app/enterprise/2.1.x/plugin-development/custom-entities.md b/app/enterprise/2.1.x/plugin-development/custom-entities.md index 0d806af89906..aa0236a1ec96 100644 --- a/app/enterprise/2.1.x/plugin-development/custom-entities.md +++ b/app/enterprise/2.1.x/plugin-development/custom-entities.md @@ -11,7 +11,7 @@ its configuration in the database. In that case, Kong provides you with an abstraction on top of its primary datastores which allows you to store custom entities. -As explained in the [previous chapter]({{page.book.previous}}), Kong interacts +As explained in the [previous chapter]({{page.book.previous.url}}), Kong interacts with the model layer through classes we refer to as "DAOs", and available on a singleton often referred to as the "DAO Factory". This chapter will explain how to to provide an abstraction for your own entities. @@ -188,7 +188,7 @@ for one that works with Cassandra too. enforce it for Cassandra, but for Postgres you must set this constraint in the migrations. -To see a real-life example, give a look at the [Key-Auth plugin migrations](https://github.com/Kong/kong/tree/{{page.kong_version}}/kong/plugins/key-auth/migrations). +To see a real-life example, give a look at the [Key-Auth plugin migrations](https://github.com/Kong/kong/tree/master/kong/plugins/key-auth/migrations). --- @@ -635,11 +635,7 @@ When a custom entity is required on every request/response it is good practice to cache it in-memory by leveraging the in-memory cache API provided by Kong. The next chapter will focus on caching custom entities, and invalidating them -when they change in the datastore: [Caching custom entities]({{page.book.next}}). - ---- - -Next: [Caching custom entities ›]({{page.book.next}}) +when they change in the datastore: [Caching custom entities]({{page.book.next.url}}). [Admin API]: /enterprise/{{page.kong_version}}/admin-api/ [Plugin Development Kit]: /enterprise/{{page.kong_version}}/pdk diff --git a/app/enterprise/2.1.x/plugin-development/custom-logic.md b/app/enterprise/2.1.x/plugin-development/custom-logic.md index 03d2c4d1e590..acf73c73dd51 100644 --- a/app/enterprise/2.1.x/plugin-development/custom-logic.md +++ b/app/enterprise/2.1.x/plugin-development/custom-logic.md @@ -54,7 +54,7 @@ All of those functions, except `init_worker`, take one parameter which is given by Kong upon its invocation: the configuration of your plugin. This parameter is a Lua table, and contains values defined by your users, according to your plugin's schema (described in the `schema.lua` module). More on plugins schemas -in the [next chapter]({{page.book.next}}). +in the [next chapter]({{page.book.next.url}}). [HTTP Module]: https://github.com/openresty/lua-nginx-module [Stream Module]: https://github.com/openresty/stream-lua-nginx-module @@ -320,9 +320,5 @@ syslog | 4 request-termination | 2 post-function | -1000 ---- - -Next: [Plugin configuration ›]({{page.book.next}}) - [lua-nginx-module]: https://github.com/openresty/lua-nginx-module [pdk]: /enterprise/{{page.kong_version}}/pdk diff --git a/app/enterprise/2.1.x/plugin-development/entities-cache.md b/app/enterprise/2.1.x/plugin-development/entities-cache.md index 677e9227597e..bbde12b37844 100644 --- a/app/enterprise/2.1.x/plugin-development/entities-cache.md +++ b/app/enterprise/2.1.x/plugin-development/entities-cache.md @@ -7,7 +7,7 @@ chapter: 7 ## Introduction Your plugin may need to frequently access custom entities (explained in the -[previous chapter]({{page.book.previous}})) on every request and/or response. +[previous chapter]({{page.book.previous.url}})) on every request and/or response. Usually, loading them once and caching them in-memory dramatically improves the performance while making sure the datastore is not stressed with an increased load. @@ -339,11 +339,7 @@ Kong to setup their APIs and plugins. It is likely that they also need to be able to interact with the custom entities you implemented for your plugin (for example, creating and deleting API keys). The way you would do this is by extending the Admin API, which we will detail in the next chapter: -[Extending the Admin API]({{page.book.next}}). - ---- - -Next: [Extending the Admin API ›]({{page.book.next}}) +[Extending the Admin API]({{page.book.next.url}}). [Admin API]: /enterprise/{{page.kong_version}}/admin-api/ [Plugin Development Kit]: /enterprise/{{page.kong_version}}/pdk diff --git a/app/enterprise/2.1.x/plugin-development/file-structure.md b/app/enterprise/2.1.x/plugin-development/file-structure.md index 240f31bd261e..d3b864dca871 100644 --- a/app/enterprise/2.1.x/plugin-development/file-structure.md +++ b/app/enterprise/2.1.x/plugin-development/file-structure.md @@ -111,10 +111,6 @@ master each one of them. The [Key-Auth plugin] is an example of plugin with this file structure. See [its source code] for more details. ---- - -Next: [Write custom logic ›]({{page.book.next}}) - [api.lua]: {{page.book.chapters.admin-api}} [daos.lua]: {{page.book.chapters.custom-entities}} [handler.lua]: {{page.book.chapters.custom-logic}} diff --git a/app/enterprise/2.1.x/plugin-development/index.md b/app/enterprise/2.1.x/plugin-development/index.md index 2dfd5555482b..fa0f04a1b515 100644 --- a/app/enterprise/2.1.x/plugin-development/index.md +++ b/app/enterprise/2.1.x/plugin-development/index.md @@ -29,9 +29,5 @@ This guide will explore in detail the structure of plugins, what they can extend, and how to distribute and install them. For a complete reference of the PDK, see the [Plugin Development Kit] reference. ---- - -Next: [File structure of a plugin ›]({{page.book.next}}) - [lua-nginx-module]: https://github.com/openresty/lua-nginx-module [Plugin Development Kit]: /enterprise/{{page.kong_version}}/pdk diff --git a/app/enterprise/2.1.x/plugin-development/plugin-configuration.md b/app/enterprise/2.1.x/plugin-development/plugin-configuration.md index 18ac7acac0b0..12c03ab4629d 100644 --- a/app/enterprise/2.1.x/plugin-development/plugin-configuration.md +++ b/app/enterprise/2.1.x/plugin-development/plugin-configuration.md @@ -411,10 +411,6 @@ return CustomHandler You can also see a real-world example of schema in [the Key-Auth plugin source code]. ---- - -Next: [Accessing the Datastore ›]({{page.book.next}}) - [Admin API]: /enterprise/{{page.kong_version}}/admin-api [Plugin Development Kit]: /enterprise/{{page.kong_version}}/pdk [the Key-Auth plugin source code]: https://github.com/Kong/kong/blob/master/kong/plugins/key-auth/schema.lua diff --git a/app/enterprise/2.1.x/plugin-development/tests.md b/app/enterprise/2.1.x/plugin-development/tests.md index 65de6ede1f3f..229282ed4727 100644 --- a/app/enterprise/2.1.x/plugin-development/tests.md +++ b/app/enterprise/2.1.x/plugin-development/tests.md @@ -14,7 +14,7 @@ might also want to write integration tests. Again, Kong has your back. ## Write integration tests The preferred testing framework for Kong is -[busted](http://olivinelabs.com/busted/) running with the +[busted](https://github.com/lunarmodules/busted/) running with the [resty-cli](https://github.com/openresty/resty-cli) interpreter, though you are free to use another one if you wish. In the Kong repository, the busted executable can be found at `bin/busted`. @@ -102,6 +102,3 @@ and Admin API on port 9001. If you want to see a real-world example, give a look at the [Key-Auth plugin specs](https://github.com/Kong/kong/tree/master/spec/03-plugins/09-key-auth) ---- - -Next: [Distribute your plugin ›]({{page.book.next}}) diff --git a/app/enterprise/2.2.x/plugin-development/access-the-datastore.md b/app/enterprise/2.2.x/plugin-development/access-the-datastore.md index f783a00d90a5..e50e794b71ef 100644 --- a/app/enterprise/2.2.x/plugin-development/access-the-datastore.md +++ b/app/enterprise/2.2.x/plugin-development/access-the-datastore.md @@ -68,8 +68,4 @@ local inserted_plugin, err = kong.db.plugins:insert({ For a real-life example of the DAO being used in a plugin, see the [Key-Auth plugin source code](https://github.com/Kong/kong/blob/master/kong/plugins/key-auth/handler.lua). ---- - -Next: [Storing Custom Entities ›]({{page.book.next}}) - [Plugin Development Kit]: /enterprise/{{page.kong_version}}/pdk diff --git a/app/enterprise/2.2.x/plugin-development/admin-api.md b/app/enterprise/2.2.x/plugin-development/admin-api.md index b60861663d9e..fc82f44d1d95 100644 --- a/app/enterprise/2.2.x/plugin-development/admin-api.md +++ b/app/enterprise/2.2.x/plugin-development/admin-api.md @@ -167,8 +167,4 @@ three functions: - The `PUT` function populates `self.args.post.consumer` before calling the `endpoints`-provided `put_entity_endpoint` function. ---- - -Next: [Write tests for your plugin]({{page.book.next}}) - [Admin API]: /enterprise/{{page.kong_version}}/admin-api/ diff --git a/app/enterprise/2.2.x/plugin-development/custom-entities.md b/app/enterprise/2.2.x/plugin-development/custom-entities.md index 0d806af89906..aa0236a1ec96 100644 --- a/app/enterprise/2.2.x/plugin-development/custom-entities.md +++ b/app/enterprise/2.2.x/plugin-development/custom-entities.md @@ -11,7 +11,7 @@ its configuration in the database. In that case, Kong provides you with an abstraction on top of its primary datastores which allows you to store custom entities. -As explained in the [previous chapter]({{page.book.previous}}), Kong interacts +As explained in the [previous chapter]({{page.book.previous.url}}), Kong interacts with the model layer through classes we refer to as "DAOs", and available on a singleton often referred to as the "DAO Factory". This chapter will explain how to to provide an abstraction for your own entities. @@ -188,7 +188,7 @@ for one that works with Cassandra too. enforce it for Cassandra, but for Postgres you must set this constraint in the migrations. -To see a real-life example, give a look at the [Key-Auth plugin migrations](https://github.com/Kong/kong/tree/{{page.kong_version}}/kong/plugins/key-auth/migrations). +To see a real-life example, give a look at the [Key-Auth plugin migrations](https://github.com/Kong/kong/tree/master/kong/plugins/key-auth/migrations). --- @@ -635,11 +635,7 @@ When a custom entity is required on every request/response it is good practice to cache it in-memory by leveraging the in-memory cache API provided by Kong. The next chapter will focus on caching custom entities, and invalidating them -when they change in the datastore: [Caching custom entities]({{page.book.next}}). - ---- - -Next: [Caching custom entities ›]({{page.book.next}}) +when they change in the datastore: [Caching custom entities]({{page.book.next.url}}). [Admin API]: /enterprise/{{page.kong_version}}/admin-api/ [Plugin Development Kit]: /enterprise/{{page.kong_version}}/pdk diff --git a/app/enterprise/2.2.x/plugin-development/custom-logic.md b/app/enterprise/2.2.x/plugin-development/custom-logic.md index 03d2c4d1e590..acf73c73dd51 100644 --- a/app/enterprise/2.2.x/plugin-development/custom-logic.md +++ b/app/enterprise/2.2.x/plugin-development/custom-logic.md @@ -54,7 +54,7 @@ All of those functions, except `init_worker`, take one parameter which is given by Kong upon its invocation: the configuration of your plugin. This parameter is a Lua table, and contains values defined by your users, according to your plugin's schema (described in the `schema.lua` module). More on plugins schemas -in the [next chapter]({{page.book.next}}). +in the [next chapter]({{page.book.next.url}}). [HTTP Module]: https://github.com/openresty/lua-nginx-module [Stream Module]: https://github.com/openresty/stream-lua-nginx-module @@ -320,9 +320,5 @@ syslog | 4 request-termination | 2 post-function | -1000 ---- - -Next: [Plugin configuration ›]({{page.book.next}}) - [lua-nginx-module]: https://github.com/openresty/lua-nginx-module [pdk]: /enterprise/{{page.kong_version}}/pdk diff --git a/app/enterprise/2.2.x/plugin-development/entities-cache.md b/app/enterprise/2.2.x/plugin-development/entities-cache.md index 677e9227597e..bbde12b37844 100644 --- a/app/enterprise/2.2.x/plugin-development/entities-cache.md +++ b/app/enterprise/2.2.x/plugin-development/entities-cache.md @@ -7,7 +7,7 @@ chapter: 7 ## Introduction Your plugin may need to frequently access custom entities (explained in the -[previous chapter]({{page.book.previous}})) on every request and/or response. +[previous chapter]({{page.book.previous.url}})) on every request and/or response. Usually, loading them once and caching them in-memory dramatically improves the performance while making sure the datastore is not stressed with an increased load. @@ -339,11 +339,7 @@ Kong to setup their APIs and plugins. It is likely that they also need to be able to interact with the custom entities you implemented for your plugin (for example, creating and deleting API keys). The way you would do this is by extending the Admin API, which we will detail in the next chapter: -[Extending the Admin API]({{page.book.next}}). - ---- - -Next: [Extending the Admin API ›]({{page.book.next}}) +[Extending the Admin API]({{page.book.next.url}}). [Admin API]: /enterprise/{{page.kong_version}}/admin-api/ [Plugin Development Kit]: /enterprise/{{page.kong_version}}/pdk diff --git a/app/enterprise/2.2.x/plugin-development/file-structure.md b/app/enterprise/2.2.x/plugin-development/file-structure.md index 240f31bd261e..d3b864dca871 100644 --- a/app/enterprise/2.2.x/plugin-development/file-structure.md +++ b/app/enterprise/2.2.x/plugin-development/file-structure.md @@ -111,10 +111,6 @@ master each one of them. The [Key-Auth plugin] is an example of plugin with this file structure. See [its source code] for more details. ---- - -Next: [Write custom logic ›]({{page.book.next}}) - [api.lua]: {{page.book.chapters.admin-api}} [daos.lua]: {{page.book.chapters.custom-entities}} [handler.lua]: {{page.book.chapters.custom-logic}} diff --git a/app/enterprise/2.2.x/plugin-development/index.md b/app/enterprise/2.2.x/plugin-development/index.md index 2dfd5555482b..fa0f04a1b515 100644 --- a/app/enterprise/2.2.x/plugin-development/index.md +++ b/app/enterprise/2.2.x/plugin-development/index.md @@ -29,9 +29,5 @@ This guide will explore in detail the structure of plugins, what they can extend, and how to distribute and install them. For a complete reference of the PDK, see the [Plugin Development Kit] reference. ---- - -Next: [File structure of a plugin ›]({{page.book.next}}) - [lua-nginx-module]: https://github.com/openresty/lua-nginx-module [Plugin Development Kit]: /enterprise/{{page.kong_version}}/pdk diff --git a/app/enterprise/2.2.x/plugin-development/plugin-configuration.md b/app/enterprise/2.2.x/plugin-development/plugin-configuration.md index 18ac7acac0b0..12c03ab4629d 100644 --- a/app/enterprise/2.2.x/plugin-development/plugin-configuration.md +++ b/app/enterprise/2.2.x/plugin-development/plugin-configuration.md @@ -411,10 +411,6 @@ return CustomHandler You can also see a real-world example of schema in [the Key-Auth plugin source code]. ---- - -Next: [Accessing the Datastore ›]({{page.book.next}}) - [Admin API]: /enterprise/{{page.kong_version}}/admin-api [Plugin Development Kit]: /enterprise/{{page.kong_version}}/pdk [the Key-Auth plugin source code]: https://github.com/Kong/kong/blob/master/kong/plugins/key-auth/schema.lua diff --git a/app/enterprise/2.2.x/plugin-development/tests.md b/app/enterprise/2.2.x/plugin-development/tests.md index 65de6ede1f3f..229282ed4727 100644 --- a/app/enterprise/2.2.x/plugin-development/tests.md +++ b/app/enterprise/2.2.x/plugin-development/tests.md @@ -14,7 +14,7 @@ might also want to write integration tests. Again, Kong has your back. ## Write integration tests The preferred testing framework for Kong is -[busted](http://olivinelabs.com/busted/) running with the +[busted](https://github.com/lunarmodules/busted/) running with the [resty-cli](https://github.com/openresty/resty-cli) interpreter, though you are free to use another one if you wish. In the Kong repository, the busted executable can be found at `bin/busted`. @@ -102,6 +102,3 @@ and Admin API on port 9001. If you want to see a real-world example, give a look at the [Key-Auth plugin specs](https://github.com/Kong/kong/tree/master/spec/03-plugins/09-key-auth) ---- - -Next: [Distribute your plugin ›]({{page.book.next}}) diff --git a/app/enterprise/2.3.x/plugin-development/access-the-datastore.md b/app/enterprise/2.3.x/plugin-development/access-the-datastore.md index f783a00d90a5..e50e794b71ef 100644 --- a/app/enterprise/2.3.x/plugin-development/access-the-datastore.md +++ b/app/enterprise/2.3.x/plugin-development/access-the-datastore.md @@ -68,8 +68,4 @@ local inserted_plugin, err = kong.db.plugins:insert({ For a real-life example of the DAO being used in a plugin, see the [Key-Auth plugin source code](https://github.com/Kong/kong/blob/master/kong/plugins/key-auth/handler.lua). ---- - -Next: [Storing Custom Entities ›]({{page.book.next}}) - [Plugin Development Kit]: /enterprise/{{page.kong_version}}/pdk diff --git a/app/enterprise/2.3.x/plugin-development/admin-api.md b/app/enterprise/2.3.x/plugin-development/admin-api.md index b60861663d9e..fc82f44d1d95 100644 --- a/app/enterprise/2.3.x/plugin-development/admin-api.md +++ b/app/enterprise/2.3.x/plugin-development/admin-api.md @@ -167,8 +167,4 @@ three functions: - The `PUT` function populates `self.args.post.consumer` before calling the `endpoints`-provided `put_entity_endpoint` function. ---- - -Next: [Write tests for your plugin]({{page.book.next}}) - [Admin API]: /enterprise/{{page.kong_version}}/admin-api/ diff --git a/app/enterprise/2.3.x/plugin-development/custom-entities.md b/app/enterprise/2.3.x/plugin-development/custom-entities.md index d33b1851dc11..b69de5187c71 100644 --- a/app/enterprise/2.3.x/plugin-development/custom-entities.md +++ b/app/enterprise/2.3.x/plugin-development/custom-entities.md @@ -11,7 +11,7 @@ its configuration in the database. In that case, Kong provides you with an abstraction on top of its primary datastores which allows you to store custom entities. -As explained in the [previous chapter]({{page.book.previous}}), Kong interacts +As explained in the [previous chapter]({{page.book.previous.url}}), Kong interacts with the model layer through classes we refer to as "DAOs", and available on a singleton often referred to as the "DAO Factory". This chapter will explain how to to provide an abstraction for your own entities. @@ -188,7 +188,7 @@ for one that works with Cassandra too. enforce it for Cassandra, but for Postgres you must set this constraint in the migrations. -To see a real-life example, give a look at the [Key-Auth plugin migrations](https://github.com/Kong/kong/tree/{{page.kong_version}}/kong/plugins/key-auth/migrations). +To see a real-life example, give a look at the [Key-Auth plugin migrations](https://github.com/Kong/kong/tree/master/kong/plugins/key-auth/migrations). --- @@ -635,11 +635,7 @@ When a custom entity is required on every request/response it is good practice to cache it in-memory by leveraging the in-memory cache API provided by Kong. The next chapter will focus on caching custom entities, and invalidating them -when they change in the datastore: [Caching custom entities]({{page.book.next}}). - ---- - -Next: [Caching custom entities ›]({{page.book.next}}) +when they change in the datastore: [Caching custom entities]({{page.book.next.url}}). [Admin API]: /enterprise/{{page.kong_version}}/admin-api/ [Plugin Development Kit]: /enterprise/{{page.kong_version}}/pdk diff --git a/app/enterprise/2.3.x/plugin-development/custom-logic.md b/app/enterprise/2.3.x/plugin-development/custom-logic.md index 03d2c4d1e590..acf73c73dd51 100644 --- a/app/enterprise/2.3.x/plugin-development/custom-logic.md +++ b/app/enterprise/2.3.x/plugin-development/custom-logic.md @@ -54,7 +54,7 @@ All of those functions, except `init_worker`, take one parameter which is given by Kong upon its invocation: the configuration of your plugin. This parameter is a Lua table, and contains values defined by your users, according to your plugin's schema (described in the `schema.lua` module). More on plugins schemas -in the [next chapter]({{page.book.next}}). +in the [next chapter]({{page.book.next.url}}). [HTTP Module]: https://github.com/openresty/lua-nginx-module [Stream Module]: https://github.com/openresty/stream-lua-nginx-module @@ -320,9 +320,5 @@ syslog | 4 request-termination | 2 post-function | -1000 ---- - -Next: [Plugin configuration ›]({{page.book.next}}) - [lua-nginx-module]: https://github.com/openresty/lua-nginx-module [pdk]: /enterprise/{{page.kong_version}}/pdk diff --git a/app/enterprise/2.3.x/plugin-development/entities-cache.md b/app/enterprise/2.3.x/plugin-development/entities-cache.md index 677e9227597e..bbde12b37844 100644 --- a/app/enterprise/2.3.x/plugin-development/entities-cache.md +++ b/app/enterprise/2.3.x/plugin-development/entities-cache.md @@ -7,7 +7,7 @@ chapter: 7 ## Introduction Your plugin may need to frequently access custom entities (explained in the -[previous chapter]({{page.book.previous}})) on every request and/or response. +[previous chapter]({{page.book.previous.url}})) on every request and/or response. Usually, loading them once and caching them in-memory dramatically improves the performance while making sure the datastore is not stressed with an increased load. @@ -339,11 +339,7 @@ Kong to setup their APIs and plugins. It is likely that they also need to be able to interact with the custom entities you implemented for your plugin (for example, creating and deleting API keys). The way you would do this is by extending the Admin API, which we will detail in the next chapter: -[Extending the Admin API]({{page.book.next}}). - ---- - -Next: [Extending the Admin API ›]({{page.book.next}}) +[Extending the Admin API]({{page.book.next.url}}). [Admin API]: /enterprise/{{page.kong_version}}/admin-api/ [Plugin Development Kit]: /enterprise/{{page.kong_version}}/pdk diff --git a/app/enterprise/2.3.x/plugin-development/file-structure.md b/app/enterprise/2.3.x/plugin-development/file-structure.md index 240f31bd261e..d3b864dca871 100644 --- a/app/enterprise/2.3.x/plugin-development/file-structure.md +++ b/app/enterprise/2.3.x/plugin-development/file-structure.md @@ -111,10 +111,6 @@ master each one of them. The [Key-Auth plugin] is an example of plugin with this file structure. See [its source code] for more details. ---- - -Next: [Write custom logic ›]({{page.book.next}}) - [api.lua]: {{page.book.chapters.admin-api}} [daos.lua]: {{page.book.chapters.custom-entities}} [handler.lua]: {{page.book.chapters.custom-logic}} diff --git a/app/enterprise/2.3.x/plugin-development/index.md b/app/enterprise/2.3.x/plugin-development/index.md index 2dfd5555482b..fa0f04a1b515 100644 --- a/app/enterprise/2.3.x/plugin-development/index.md +++ b/app/enterprise/2.3.x/plugin-development/index.md @@ -29,9 +29,5 @@ This guide will explore in detail the structure of plugins, what they can extend, and how to distribute and install them. For a complete reference of the PDK, see the [Plugin Development Kit] reference. ---- - -Next: [File structure of a plugin ›]({{page.book.next}}) - [lua-nginx-module]: https://github.com/openresty/lua-nginx-module [Plugin Development Kit]: /enterprise/{{page.kong_version}}/pdk diff --git a/app/enterprise/2.3.x/plugin-development/plugin-configuration.md b/app/enterprise/2.3.x/plugin-development/plugin-configuration.md index 18ac7acac0b0..12c03ab4629d 100644 --- a/app/enterprise/2.3.x/plugin-development/plugin-configuration.md +++ b/app/enterprise/2.3.x/plugin-development/plugin-configuration.md @@ -411,10 +411,6 @@ return CustomHandler You can also see a real-world example of schema in [the Key-Auth plugin source code]. ---- - -Next: [Accessing the Datastore ›]({{page.book.next}}) - [Admin API]: /enterprise/{{page.kong_version}}/admin-api [Plugin Development Kit]: /enterprise/{{page.kong_version}}/pdk [the Key-Auth plugin source code]: https://github.com/Kong/kong/blob/master/kong/plugins/key-auth/schema.lua diff --git a/app/enterprise/2.3.x/plugin-development/tests.md b/app/enterprise/2.3.x/plugin-development/tests.md index 65de6ede1f3f..229282ed4727 100644 --- a/app/enterprise/2.3.x/plugin-development/tests.md +++ b/app/enterprise/2.3.x/plugin-development/tests.md @@ -14,7 +14,7 @@ might also want to write integration tests. Again, Kong has your back. ## Write integration tests The preferred testing framework for Kong is -[busted](http://olivinelabs.com/busted/) running with the +[busted](https://github.com/lunarmodules/busted/) running with the [resty-cli](https://github.com/openresty/resty-cli) interpreter, though you are free to use another one if you wish. In the Kong repository, the busted executable can be found at `bin/busted`. @@ -102,6 +102,3 @@ and Admin API on port 9001. If you want to see a real-world example, give a look at the [Key-Auth plugin specs](https://github.com/Kong/kong/tree/master/spec/03-plugins/09-key-auth) ---- - -Next: [Distribute your plugin ›]({{page.book.next}}) diff --git a/app/enterprise/2.4.x/plugin-development/access-the-datastore.md b/app/enterprise/2.4.x/plugin-development/access-the-datastore.md index f783a00d90a5..e50e794b71ef 100644 --- a/app/enterprise/2.4.x/plugin-development/access-the-datastore.md +++ b/app/enterprise/2.4.x/plugin-development/access-the-datastore.md @@ -68,8 +68,4 @@ local inserted_plugin, err = kong.db.plugins:insert({ For a real-life example of the DAO being used in a plugin, see the [Key-Auth plugin source code](https://github.com/Kong/kong/blob/master/kong/plugins/key-auth/handler.lua). ---- - -Next: [Storing Custom Entities ›]({{page.book.next}}) - [Plugin Development Kit]: /enterprise/{{page.kong_version}}/pdk diff --git a/app/enterprise/2.4.x/plugin-development/admin-api.md b/app/enterprise/2.4.x/plugin-development/admin-api.md index b60861663d9e..fc82f44d1d95 100644 --- a/app/enterprise/2.4.x/plugin-development/admin-api.md +++ b/app/enterprise/2.4.x/plugin-development/admin-api.md @@ -167,8 +167,4 @@ three functions: - The `PUT` function populates `self.args.post.consumer` before calling the `endpoints`-provided `put_entity_endpoint` function. ---- - -Next: [Write tests for your plugin]({{page.book.next}}) - [Admin API]: /enterprise/{{page.kong_version}}/admin-api/ diff --git a/app/enterprise/2.4.x/plugin-development/custom-entities.md b/app/enterprise/2.4.x/plugin-development/custom-entities.md index d33b1851dc11..b69de5187c71 100644 --- a/app/enterprise/2.4.x/plugin-development/custom-entities.md +++ b/app/enterprise/2.4.x/plugin-development/custom-entities.md @@ -11,7 +11,7 @@ its configuration in the database. In that case, Kong provides you with an abstraction on top of its primary datastores which allows you to store custom entities. -As explained in the [previous chapter]({{page.book.previous}}), Kong interacts +As explained in the [previous chapter]({{page.book.previous.url}}), Kong interacts with the model layer through classes we refer to as "DAOs", and available on a singleton often referred to as the "DAO Factory". This chapter will explain how to to provide an abstraction for your own entities. @@ -188,7 +188,7 @@ for one that works with Cassandra too. enforce it for Cassandra, but for Postgres you must set this constraint in the migrations. -To see a real-life example, give a look at the [Key-Auth plugin migrations](https://github.com/Kong/kong/tree/{{page.kong_version}}/kong/plugins/key-auth/migrations). +To see a real-life example, give a look at the [Key-Auth plugin migrations](https://github.com/Kong/kong/tree/master/kong/plugins/key-auth/migrations). --- @@ -635,11 +635,7 @@ When a custom entity is required on every request/response it is good practice to cache it in-memory by leveraging the in-memory cache API provided by Kong. The next chapter will focus on caching custom entities, and invalidating them -when they change in the datastore: [Caching custom entities]({{page.book.next}}). - ---- - -Next: [Caching custom entities ›]({{page.book.next}}) +when they change in the datastore: [Caching custom entities]({{page.book.next.url}}). [Admin API]: /enterprise/{{page.kong_version}}/admin-api/ [Plugin Development Kit]: /enterprise/{{page.kong_version}}/pdk diff --git a/app/enterprise/2.4.x/plugin-development/custom-logic.md b/app/enterprise/2.4.x/plugin-development/custom-logic.md index 4354bf35293c..6ca3c4f99753 100644 --- a/app/enterprise/2.4.x/plugin-development/custom-logic.md +++ b/app/enterprise/2.4.x/plugin-development/custom-logic.md @@ -65,7 +65,7 @@ All of those functions, except `init_worker`, take one parameter that is given by {{site.ee_product_name}} upon its invocation: the configuration of your plugin. This parameter is a Lua table, and contains values defined by your users, according to your plugin's schema (described in the `schema.lua` module). More on plugin schemas -in the [next chapter]({{page.book.next}}). +in the [next chapter]({{page.book.next.url}}). Note that UDP streams don't have real connections. {{site.ee_product_name}} considers all packets with the same origin and destination host and port as a single @@ -325,9 +325,5 @@ request-termination | 2 correlation-id | 1 post-function | -1000 ---- - -Next: [Plugin configuration ›]({{page.book.next}}) - [lua-nginx-module]: https://github.com/openresty/lua-nginx-module [pdk]: /enterprise/{{page.kong_version}}/pdk diff --git a/app/enterprise/2.4.x/plugin-development/entities-cache.md b/app/enterprise/2.4.x/plugin-development/entities-cache.md index 677e9227597e..bbde12b37844 100644 --- a/app/enterprise/2.4.x/plugin-development/entities-cache.md +++ b/app/enterprise/2.4.x/plugin-development/entities-cache.md @@ -7,7 +7,7 @@ chapter: 7 ## Introduction Your plugin may need to frequently access custom entities (explained in the -[previous chapter]({{page.book.previous}})) on every request and/or response. +[previous chapter]({{page.book.previous.url}})) on every request and/or response. Usually, loading them once and caching them in-memory dramatically improves the performance while making sure the datastore is not stressed with an increased load. @@ -339,11 +339,7 @@ Kong to setup their APIs and plugins. It is likely that they also need to be able to interact with the custom entities you implemented for your plugin (for example, creating and deleting API keys). The way you would do this is by extending the Admin API, which we will detail in the next chapter: -[Extending the Admin API]({{page.book.next}}). - ---- - -Next: [Extending the Admin API ›]({{page.book.next}}) +[Extending the Admin API]({{page.book.next.url}}). [Admin API]: /enterprise/{{page.kong_version}}/admin-api/ [Plugin Development Kit]: /enterprise/{{page.kong_version}}/pdk diff --git a/app/enterprise/2.4.x/plugin-development/file-structure.md b/app/enterprise/2.4.x/plugin-development/file-structure.md index 240f31bd261e..d3b864dca871 100644 --- a/app/enterprise/2.4.x/plugin-development/file-structure.md +++ b/app/enterprise/2.4.x/plugin-development/file-structure.md @@ -111,10 +111,6 @@ master each one of them. The [Key-Auth plugin] is an example of plugin with this file structure. See [its source code] for more details. ---- - -Next: [Write custom logic ›]({{page.book.next}}) - [api.lua]: {{page.book.chapters.admin-api}} [daos.lua]: {{page.book.chapters.custom-entities}} [handler.lua]: {{page.book.chapters.custom-logic}} diff --git a/app/enterprise/2.4.x/plugin-development/index.md b/app/enterprise/2.4.x/plugin-development/index.md index 2dfd5555482b..fa0f04a1b515 100644 --- a/app/enterprise/2.4.x/plugin-development/index.md +++ b/app/enterprise/2.4.x/plugin-development/index.md @@ -29,9 +29,5 @@ This guide will explore in detail the structure of plugins, what they can extend, and how to distribute and install them. For a complete reference of the PDK, see the [Plugin Development Kit] reference. ---- - -Next: [File structure of a plugin ›]({{page.book.next}}) - [lua-nginx-module]: https://github.com/openresty/lua-nginx-module [Plugin Development Kit]: /enterprise/{{page.kong_version}}/pdk diff --git a/app/enterprise/2.4.x/plugin-development/plugin-configuration.md b/app/enterprise/2.4.x/plugin-development/plugin-configuration.md index 18ac7acac0b0..12c03ab4629d 100644 --- a/app/enterprise/2.4.x/plugin-development/plugin-configuration.md +++ b/app/enterprise/2.4.x/plugin-development/plugin-configuration.md @@ -411,10 +411,6 @@ return CustomHandler You can also see a real-world example of schema in [the Key-Auth plugin source code]. ---- - -Next: [Accessing the Datastore ›]({{page.book.next}}) - [Admin API]: /enterprise/{{page.kong_version}}/admin-api [Plugin Development Kit]: /enterprise/{{page.kong_version}}/pdk [the Key-Auth plugin source code]: https://github.com/Kong/kong/blob/master/kong/plugins/key-auth/schema.lua diff --git a/app/enterprise/2.4.x/plugin-development/tests.md b/app/enterprise/2.4.x/plugin-development/tests.md index 65de6ede1f3f..229282ed4727 100644 --- a/app/enterprise/2.4.x/plugin-development/tests.md +++ b/app/enterprise/2.4.x/plugin-development/tests.md @@ -14,7 +14,7 @@ might also want to write integration tests. Again, Kong has your back. ## Write integration tests The preferred testing framework for Kong is -[busted](http://olivinelabs.com/busted/) running with the +[busted](https://github.com/lunarmodules/busted/) running with the [resty-cli](https://github.com/openresty/resty-cli) interpreter, though you are free to use another one if you wish. In the Kong repository, the busted executable can be found at `bin/busted`. @@ -102,6 +102,3 @@ and Admin API on port 9001. If you want to see a real-world example, give a look at the [Key-Auth plugin specs](https://github.com/Kong/kong/tree/master/spec/03-plugins/09-key-auth) ---- - -Next: [Distribute your plugin ›]({{page.book.next}}) diff --git a/app/enterprise/2.5.x/plugin-development/access-the-datastore.md b/app/enterprise/2.5.x/plugin-development/access-the-datastore.md index f783a00d90a5..e50e794b71ef 100644 --- a/app/enterprise/2.5.x/plugin-development/access-the-datastore.md +++ b/app/enterprise/2.5.x/plugin-development/access-the-datastore.md @@ -68,8 +68,4 @@ local inserted_plugin, err = kong.db.plugins:insert({ For a real-life example of the DAO being used in a plugin, see the [Key-Auth plugin source code](https://github.com/Kong/kong/blob/master/kong/plugins/key-auth/handler.lua). ---- - -Next: [Storing Custom Entities ›]({{page.book.next}}) - [Plugin Development Kit]: /enterprise/{{page.kong_version}}/pdk diff --git a/app/enterprise/2.5.x/plugin-development/admin-api.md b/app/enterprise/2.5.x/plugin-development/admin-api.md index 899614372e04..bc86a3b25b44 100644 --- a/app/enterprise/2.5.x/plugin-development/admin-api.md +++ b/app/enterprise/2.5.x/plugin-development/admin-api.md @@ -230,8 +230,4 @@ return { This code will make all requests to the `/services` endpoint return a `404 not found` response. ---- - -Next: [Write tests for your plugin]({{page.book.next}}) - [Admin API]: /enterprise/{{page.kong_version}}/admin-api/ diff --git a/app/enterprise/2.5.x/plugin-development/custom-entities.md b/app/enterprise/2.5.x/plugin-development/custom-entities.md index d33b1851dc11..b69de5187c71 100644 --- a/app/enterprise/2.5.x/plugin-development/custom-entities.md +++ b/app/enterprise/2.5.x/plugin-development/custom-entities.md @@ -11,7 +11,7 @@ its configuration in the database. In that case, Kong provides you with an abstraction on top of its primary datastores which allows you to store custom entities. -As explained in the [previous chapter]({{page.book.previous}}), Kong interacts +As explained in the [previous chapter]({{page.book.previous.url}}), Kong interacts with the model layer through classes we refer to as "DAOs", and available on a singleton often referred to as the "DAO Factory". This chapter will explain how to to provide an abstraction for your own entities. @@ -188,7 +188,7 @@ for one that works with Cassandra too. enforce it for Cassandra, but for Postgres you must set this constraint in the migrations. -To see a real-life example, give a look at the [Key-Auth plugin migrations](https://github.com/Kong/kong/tree/{{page.kong_version}}/kong/plugins/key-auth/migrations). +To see a real-life example, give a look at the [Key-Auth plugin migrations](https://github.com/Kong/kong/tree/master/kong/plugins/key-auth/migrations). --- @@ -635,11 +635,7 @@ When a custom entity is required on every request/response it is good practice to cache it in-memory by leveraging the in-memory cache API provided by Kong. The next chapter will focus on caching custom entities, and invalidating them -when they change in the datastore: [Caching custom entities]({{page.book.next}}). - ---- - -Next: [Caching custom entities ›]({{page.book.next}}) +when they change in the datastore: [Caching custom entities]({{page.book.next.url}}). [Admin API]: /enterprise/{{page.kong_version}}/admin-api/ [Plugin Development Kit]: /enterprise/{{page.kong_version}}/pdk diff --git a/app/enterprise/2.5.x/plugin-development/custom-logic.md b/app/enterprise/2.5.x/plugin-development/custom-logic.md index 9030d747ed2a..530b26234991 100644 --- a/app/enterprise/2.5.x/plugin-development/custom-logic.md +++ b/app/enterprise/2.5.x/plugin-development/custom-logic.md @@ -65,7 +65,7 @@ All of those functions, except `init_worker`, take one parameter that is given by {{site.ee_product_name}} upon its invocation: the configuration of your plugin. This parameter is a Lua table, and contains values defined by your users, according to your plugin's schema (described in the `schema.lua` module). More on plugin schemas -in the [next chapter]({{page.book.next}}). +in the [next chapter]({{page.book.next.url}}). Note that UDP streams don't have real connections. {{site.ee_product_name}} considers all packets with the same origin and destination host and port as a single @@ -323,9 +323,5 @@ request-termination | 2 correlation-id | 1 post-function | -1000 ---- - -Next: [Plugin configuration ›]({{page.book.next}}) - [lua-nginx-module]: https://github.com/openresty/lua-nginx-module [pdk]: /enterprise/{{page.kong_version}}/pdk diff --git a/app/enterprise/2.5.x/plugin-development/entities-cache.md b/app/enterprise/2.5.x/plugin-development/entities-cache.md index 677e9227597e..bbde12b37844 100644 --- a/app/enterprise/2.5.x/plugin-development/entities-cache.md +++ b/app/enterprise/2.5.x/plugin-development/entities-cache.md @@ -7,7 +7,7 @@ chapter: 7 ## Introduction Your plugin may need to frequently access custom entities (explained in the -[previous chapter]({{page.book.previous}})) on every request and/or response. +[previous chapter]({{page.book.previous.url}})) on every request and/or response. Usually, loading them once and caching them in-memory dramatically improves the performance while making sure the datastore is not stressed with an increased load. @@ -339,11 +339,7 @@ Kong to setup their APIs and plugins. It is likely that they also need to be able to interact with the custom entities you implemented for your plugin (for example, creating and deleting API keys). The way you would do this is by extending the Admin API, which we will detail in the next chapter: -[Extending the Admin API]({{page.book.next}}). - ---- - -Next: [Extending the Admin API ›]({{page.book.next}}) +[Extending the Admin API]({{page.book.next.url}}). [Admin API]: /enterprise/{{page.kong_version}}/admin-api/ [Plugin Development Kit]: /enterprise/{{page.kong_version}}/pdk diff --git a/app/enterprise/2.5.x/plugin-development/file-structure.md b/app/enterprise/2.5.x/plugin-development/file-structure.md index 240f31bd261e..d3b864dca871 100644 --- a/app/enterprise/2.5.x/plugin-development/file-structure.md +++ b/app/enterprise/2.5.x/plugin-development/file-structure.md @@ -111,10 +111,6 @@ master each one of them. The [Key-Auth plugin] is an example of plugin with this file structure. See [its source code] for more details. ---- - -Next: [Write custom logic ›]({{page.book.next}}) - [api.lua]: {{page.book.chapters.admin-api}} [daos.lua]: {{page.book.chapters.custom-entities}} [handler.lua]: {{page.book.chapters.custom-logic}} diff --git a/app/enterprise/2.5.x/plugin-development/index.md b/app/enterprise/2.5.x/plugin-development/index.md index 2dfd5555482b..fa0f04a1b515 100644 --- a/app/enterprise/2.5.x/plugin-development/index.md +++ b/app/enterprise/2.5.x/plugin-development/index.md @@ -29,9 +29,5 @@ This guide will explore in detail the structure of plugins, what they can extend, and how to distribute and install them. For a complete reference of the PDK, see the [Plugin Development Kit] reference. ---- - -Next: [File structure of a plugin ›]({{page.book.next}}) - [lua-nginx-module]: https://github.com/openresty/lua-nginx-module [Plugin Development Kit]: /enterprise/{{page.kong_version}}/pdk diff --git a/app/enterprise/2.5.x/plugin-development/plugin-configuration.md b/app/enterprise/2.5.x/plugin-development/plugin-configuration.md index 18ac7acac0b0..12c03ab4629d 100644 --- a/app/enterprise/2.5.x/plugin-development/plugin-configuration.md +++ b/app/enterprise/2.5.x/plugin-development/plugin-configuration.md @@ -411,10 +411,6 @@ return CustomHandler You can also see a real-world example of schema in [the Key-Auth plugin source code]. ---- - -Next: [Accessing the Datastore ›]({{page.book.next}}) - [Admin API]: /enterprise/{{page.kong_version}}/admin-api [Plugin Development Kit]: /enterprise/{{page.kong_version}}/pdk [the Key-Auth plugin source code]: https://github.com/Kong/kong/blob/master/kong/plugins/key-auth/schema.lua diff --git a/app/enterprise/2.5.x/plugin-development/tests.md b/app/enterprise/2.5.x/plugin-development/tests.md index 65de6ede1f3f..229282ed4727 100644 --- a/app/enterprise/2.5.x/plugin-development/tests.md +++ b/app/enterprise/2.5.x/plugin-development/tests.md @@ -14,7 +14,7 @@ might also want to write integration tests. Again, Kong has your back. ## Write integration tests The preferred testing framework for Kong is -[busted](http://olivinelabs.com/busted/) running with the +[busted](https://github.com/lunarmodules/busted/) running with the [resty-cli](https://github.com/openresty/resty-cli) interpreter, though you are free to use another one if you wish. In the Kong repository, the busted executable can be found at `bin/busted`. @@ -102,6 +102,3 @@ and Admin API on port 9001. If you want to see a real-world example, give a look at the [Key-Auth plugin specs](https://github.com/Kong/kong/tree/master/spec/03-plugins/09-key-auth) ---- - -Next: [Distribute your plugin ›]({{page.book.next}}) diff --git a/app/gateway-oss/2.0.x/plugin-development/access-the-datastore.md b/app/gateway-oss/2.0.x/plugin-development/access-the-datastore.md index 63fab7c8aa5c..6d9c161d886b 100644 --- a/app/gateway-oss/2.0.x/plugin-development/access-the-datastore.md +++ b/app/gateway-oss/2.0.x/plugin-development/access-the-datastore.md @@ -68,8 +68,4 @@ local inserted_plugin, err = kong.db.plugins:insert({ For a real-life example of the DAO being used in a plugin, see the [Key-Auth plugin source code](https://github.com/Kong/kong/blob/master/kong/plugins/key-auth/handler.lua). ---- - -Next: [Storing Custom Entities ›]({{page.book.next}}) - [Plugin Development Kit]: /{{page.kong_version}}/pdk diff --git a/app/gateway-oss/2.0.x/plugin-development/admin-api.md b/app/gateway-oss/2.0.x/plugin-development/admin-api.md index 58184b86690f..781e69858b94 100644 --- a/app/gateway-oss/2.0.x/plugin-development/admin-api.md +++ b/app/gateway-oss/2.0.x/plugin-development/admin-api.md @@ -95,10 +95,8 @@ return { ``` This code will create two Admin API endpoints in `/consumers/:consumers/key-auth`, to -obtain (`GET`) and create (`POST`) credentials associated to a given consumer. On this example -the functions are provided by the `kong.api.endpoints` library. If you want to see a more -complete example, with custom code in functions, see -[the `api.lua` file from the key-auth plugin](https://github.com/Kong/kong/blob/master/kong/plugins/key-auth/api.lua). +obtain (`GET`) and create (`POST`) credentials associated to a given consumer. In this example, +the functions are provided by the `kong.api.endpoints` library. The `endpoints` module currently contains the default implementation for the most usual CRUD operations used in Kong. This module provides you with helpers for any insert, retrieve, @@ -167,8 +165,4 @@ three functions: - The `PUT` function populates `self.args.post.consumer` before calling the `endpoints`-provided `put_entity_endpoint` function. ---- - -Next: [Write tests for your plugin]({{page.book.next}}) - [Admin API]: /{{page.kong_version}}/admin-api/ diff --git a/app/gateway-oss/2.0.x/plugin-development/custom-entities.md b/app/gateway-oss/2.0.x/plugin-development/custom-entities.md index 73391bee63d9..189f5c36ff1d 100644 --- a/app/gateway-oss/2.0.x/plugin-development/custom-entities.md +++ b/app/gateway-oss/2.0.x/plugin-development/custom-entities.md @@ -11,7 +11,7 @@ its configuration in the database. In that case, Kong provides you with an abstraction on top of its primary datastores which allows you to store custom entities. -As explained in the [previous chapter]({{page.book.previous}}), Kong interacts +As explained in the [previous chapter]({{page.book.previous.url}}), Kong interacts with the model layer through classes we refer to as "DAOs", and available on a singleton often referred to as the "DAO Factory". This chapter will explain how to to provide an abstraction for your own entities. @@ -188,7 +188,7 @@ for one that works with Cassandra too. enforce it for Cassandra, but for Postgres you must set this constraint in the migrations. -To see a real-life example, give a look at the [Key-Auth plugin migrations](https://github.com/Kong/kong/tree/{{page.kong_version}}/kong/plugins/key-auth/migrations). +To see a real-life example, give a look at the [Key-Auth plugin migrations](https://github.com/Kong/kong/tree/master/kong/plugins/key-auth/migrations). --- @@ -670,11 +670,7 @@ When a custom entity is required on every request/response it is good practice to cache it in-memory by leveraging the in-memory cache API provided by Kong. The next chapter will focus on caching custom entities, and invalidating them -when they change in the datastore: [Caching custom entities]({{page.book.next}}). - ---- - -Next: [Caching custom entities ›]({{page.book.next}}) +when they change in the datastore: [Caching custom entities]({{page.book.next.url}}). [Admin API]: /{{page.kong_version}}/admin-api/ [Plugin Development Kit]: /{{page.kong_version}}/pdk diff --git a/app/gateway-oss/2.0.x/plugin-development/custom-logic.md b/app/gateway-oss/2.0.x/plugin-development/custom-logic.md index 5e1e573be08e..299ef49a88b6 100644 --- a/app/gateway-oss/2.0.x/plugin-development/custom-logic.md +++ b/app/gateway-oss/2.0.x/plugin-development/custom-logic.md @@ -54,7 +54,7 @@ All of those functions, except `init_worker`, take one parameter which is given by Kong upon its invocation: the configuration of your plugin. This parameter is a Lua table, and contains values defined by your users, according to your plugin's schema (described in the `schema.lua` module). More on plugins schemas -in the [next chapter]({{page.book.next}}). +in the [next chapter]({{page.book.next.url}}). [HTTP Module]: https://github.com/openresty/lua-nginx-module [Stream Module]: https://github.com/openresty/stream-lua-nginx-module @@ -295,9 +295,5 @@ request-termination | 2 correlation-id | 1 post-function | -1000 ---- - -Next: [Plugin configuration ›]({{page.book.next}}) - [lua-nginx-module]: https://github.com/openresty/lua-nginx-module [pdk]: /{{page.kong_version}}/pdk diff --git a/app/gateway-oss/2.0.x/plugin-development/entities-cache.md b/app/gateway-oss/2.0.x/plugin-development/entities-cache.md index 50eb5cd3eb15..b80202be0509 100644 --- a/app/gateway-oss/2.0.x/plugin-development/entities-cache.md +++ b/app/gateway-oss/2.0.x/plugin-development/entities-cache.md @@ -7,7 +7,7 @@ chapter: 7 ## Introduction Your plugin may need to frequently access custom entities (explained in the -[previous chapter]({{page.book.previous}})) on every request and/or response. +[previous chapter]({{page.book.previous.url}})) on every request and/or response. Usually, loading them once and caching them in-memory dramatically improves the performance while making sure the datastore is not stressed with an increased load. @@ -341,11 +341,7 @@ Kong to setup their APIs and plugins. It is likely that they also need to be able to interact with the custom entities you implemented for your plugin (for example, creating and deleting API keys). The way you would do this is by extending the Admin API, which we will detail in the next chapter: -[Extending the Admin API]({{page.book.next}}). - ---- - -Next: [Extending the Admin API ›]({{page.book.next}}) +[Extending the Admin API]({{page.book.next.url}}). [Admin API]: /{{page.kong_version}}/admin-api/ [Plugin Development Kit]: /{{page.kong_version}}/pdk diff --git a/app/gateway-oss/2.0.x/plugin-development/file-structure.md b/app/gateway-oss/2.0.x/plugin-development/file-structure.md index 84f8599232c7..16afad6f8895 100644 --- a/app/gateway-oss/2.0.x/plugin-development/file-structure.md +++ b/app/gateway-oss/2.0.x/plugin-development/file-structure.md @@ -111,10 +111,6 @@ master each one of them. The [Key-Auth plugin] is an example of plugin with this file structure. See [its source code] for more details. ---- - -Next: [Write custom logic ›]({{page.book.next}}) - [api.lua]: {{page.book.chapters.admin-api}} [daos.lua]: {{page.book.chapters.custom-entities}} [handler.lua]: {{page.book.chapters.custom-logic}} diff --git a/app/gateway-oss/2.0.x/plugin-development/index.md b/app/gateway-oss/2.0.x/plugin-development/index.md index a317d734fffd..100b861fba72 100644 --- a/app/gateway-oss/2.0.x/plugin-development/index.md +++ b/app/gateway-oss/2.0.x/plugin-development/index.md @@ -29,9 +29,5 @@ This guide will explore in detail the structure of plugins, what they can extend, and how to distribute and install them. For a complete reference of the PDK, see the [Plugin Development Kit] reference. ---- - -Next: [File structure of a plugin ›]({{page.book.next}}) - [lua-nginx-module]: https://github.com/openresty/lua-nginx-module [Plugin Development Kit]: /{{page.kong_version}}/pdk diff --git a/app/gateway-oss/2.0.x/plugin-development/plugin-configuration.md b/app/gateway-oss/2.0.x/plugin-development/plugin-configuration.md index b206ffcb3519..ba67b748992d 100644 --- a/app/gateway-oss/2.0.x/plugin-development/plugin-configuration.md +++ b/app/gateway-oss/2.0.x/plugin-development/plugin-configuration.md @@ -400,10 +400,6 @@ return CustomHandler You can also see a real-world example of schema in [the Key-Auth plugin source code]. ---- - -Next: [Accessing the Datastore ›]({{page.book.next}}) - [Admin API]: /{{page.kong_version}}/admin-api [Plugin Development Kit]: /{{page.kong_version}}/pdk [the Key-Auth plugin source code]: https://github.com/Kong/kong/blob/master/kong/plugins/key-auth/schema.lua diff --git a/app/gateway-oss/2.0.x/plugin-development/tests.md b/app/gateway-oss/2.0.x/plugin-development/tests.md index c94392339c74..833786cca388 100644 --- a/app/gateway-oss/2.0.x/plugin-development/tests.md +++ b/app/gateway-oss/2.0.x/plugin-development/tests.md @@ -15,7 +15,7 @@ might also want to write integration tests. Again, Kong has your back. ## Write integration tests The preferred testing framework for Kong is -[busted](http://olivinelabs.com/busted/) running with the +[busted](https://github.com/lunarmodules/busted/) running with the [resty-cli](https://github.com/openresty/resty-cli) interpreter, though you are free to use another one if you wish. In the Kong repository, the busted executable can be found at `bin/busted`. @@ -103,6 +103,3 @@ and Admin API on port 9001. If you want to see a real-world example, give a look at the [Key-Auth plugin specs](https://github.com/Kong/kong/tree/master/spec/03-plugins/09-key-auth) ---- - -Next: [Distribute your plugin ›]({{page.book.next}}) diff --git a/app/gateway-oss/2.1.x/plugin-development/access-the-datastore.md b/app/gateway-oss/2.1.x/plugin-development/access-the-datastore.md index 63fab7c8aa5c..6d9c161d886b 100644 --- a/app/gateway-oss/2.1.x/plugin-development/access-the-datastore.md +++ b/app/gateway-oss/2.1.x/plugin-development/access-the-datastore.md @@ -68,8 +68,4 @@ local inserted_plugin, err = kong.db.plugins:insert({ For a real-life example of the DAO being used in a plugin, see the [Key-Auth plugin source code](https://github.com/Kong/kong/blob/master/kong/plugins/key-auth/handler.lua). ---- - -Next: [Storing Custom Entities ›]({{page.book.next}}) - [Plugin Development Kit]: /{{page.kong_version}}/pdk diff --git a/app/gateway-oss/2.1.x/plugin-development/admin-api.md b/app/gateway-oss/2.1.x/plugin-development/admin-api.md index 58184b86690f..781e69858b94 100644 --- a/app/gateway-oss/2.1.x/plugin-development/admin-api.md +++ b/app/gateway-oss/2.1.x/plugin-development/admin-api.md @@ -95,10 +95,8 @@ return { ``` This code will create two Admin API endpoints in `/consumers/:consumers/key-auth`, to -obtain (`GET`) and create (`POST`) credentials associated to a given consumer. On this example -the functions are provided by the `kong.api.endpoints` library. If you want to see a more -complete example, with custom code in functions, see -[the `api.lua` file from the key-auth plugin](https://github.com/Kong/kong/blob/master/kong/plugins/key-auth/api.lua). +obtain (`GET`) and create (`POST`) credentials associated to a given consumer. In this example, +the functions are provided by the `kong.api.endpoints` library. The `endpoints` module currently contains the default implementation for the most usual CRUD operations used in Kong. This module provides you with helpers for any insert, retrieve, @@ -167,8 +165,4 @@ three functions: - The `PUT` function populates `self.args.post.consumer` before calling the `endpoints`-provided `put_entity_endpoint` function. ---- - -Next: [Write tests for your plugin]({{page.book.next}}) - [Admin API]: /{{page.kong_version}}/admin-api/ diff --git a/app/gateway-oss/2.1.x/plugin-development/custom-entities.md b/app/gateway-oss/2.1.x/plugin-development/custom-entities.md index 73391bee63d9..189f5c36ff1d 100644 --- a/app/gateway-oss/2.1.x/plugin-development/custom-entities.md +++ b/app/gateway-oss/2.1.x/plugin-development/custom-entities.md @@ -11,7 +11,7 @@ its configuration in the database. In that case, Kong provides you with an abstraction on top of its primary datastores which allows you to store custom entities. -As explained in the [previous chapter]({{page.book.previous}}), Kong interacts +As explained in the [previous chapter]({{page.book.previous.url}}), Kong interacts with the model layer through classes we refer to as "DAOs", and available on a singleton often referred to as the "DAO Factory". This chapter will explain how to to provide an abstraction for your own entities. @@ -188,7 +188,7 @@ for one that works with Cassandra too. enforce it for Cassandra, but for Postgres you must set this constraint in the migrations. -To see a real-life example, give a look at the [Key-Auth plugin migrations](https://github.com/Kong/kong/tree/{{page.kong_version}}/kong/plugins/key-auth/migrations). +To see a real-life example, give a look at the [Key-Auth plugin migrations](https://github.com/Kong/kong/tree/master/kong/plugins/key-auth/migrations). --- @@ -670,11 +670,7 @@ When a custom entity is required on every request/response it is good practice to cache it in-memory by leveraging the in-memory cache API provided by Kong. The next chapter will focus on caching custom entities, and invalidating them -when they change in the datastore: [Caching custom entities]({{page.book.next}}). - ---- - -Next: [Caching custom entities ›]({{page.book.next}}) +when they change in the datastore: [Caching custom entities]({{page.book.next.url}}). [Admin API]: /{{page.kong_version}}/admin-api/ [Plugin Development Kit]: /{{page.kong_version}}/pdk diff --git a/app/gateway-oss/2.1.x/plugin-development/custom-logic.md b/app/gateway-oss/2.1.x/plugin-development/custom-logic.md index 5e1e573be08e..299ef49a88b6 100644 --- a/app/gateway-oss/2.1.x/plugin-development/custom-logic.md +++ b/app/gateway-oss/2.1.x/plugin-development/custom-logic.md @@ -54,7 +54,7 @@ All of those functions, except `init_worker`, take one parameter which is given by Kong upon its invocation: the configuration of your plugin. This parameter is a Lua table, and contains values defined by your users, according to your plugin's schema (described in the `schema.lua` module). More on plugins schemas -in the [next chapter]({{page.book.next}}). +in the [next chapter]({{page.book.next.url}}). [HTTP Module]: https://github.com/openresty/lua-nginx-module [Stream Module]: https://github.com/openresty/stream-lua-nginx-module @@ -295,9 +295,5 @@ request-termination | 2 correlation-id | 1 post-function | -1000 ---- - -Next: [Plugin configuration ›]({{page.book.next}}) - [lua-nginx-module]: https://github.com/openresty/lua-nginx-module [pdk]: /{{page.kong_version}}/pdk diff --git a/app/gateway-oss/2.1.x/plugin-development/entities-cache.md b/app/gateway-oss/2.1.x/plugin-development/entities-cache.md index 50eb5cd3eb15..b80202be0509 100644 --- a/app/gateway-oss/2.1.x/plugin-development/entities-cache.md +++ b/app/gateway-oss/2.1.x/plugin-development/entities-cache.md @@ -7,7 +7,7 @@ chapter: 7 ## Introduction Your plugin may need to frequently access custom entities (explained in the -[previous chapter]({{page.book.previous}})) on every request and/or response. +[previous chapter]({{page.book.previous.url}})) on every request and/or response. Usually, loading them once and caching them in-memory dramatically improves the performance while making sure the datastore is not stressed with an increased load. @@ -341,11 +341,7 @@ Kong to setup their APIs and plugins. It is likely that they also need to be able to interact with the custom entities you implemented for your plugin (for example, creating and deleting API keys). The way you would do this is by extending the Admin API, which we will detail in the next chapter: -[Extending the Admin API]({{page.book.next}}). - ---- - -Next: [Extending the Admin API ›]({{page.book.next}}) +[Extending the Admin API]({{page.book.next.url}}). [Admin API]: /{{page.kong_version}}/admin-api/ [Plugin Development Kit]: /{{page.kong_version}}/pdk diff --git a/app/gateway-oss/2.1.x/plugin-development/file-structure.md b/app/gateway-oss/2.1.x/plugin-development/file-structure.md index 84f8599232c7..16afad6f8895 100644 --- a/app/gateway-oss/2.1.x/plugin-development/file-structure.md +++ b/app/gateway-oss/2.1.x/plugin-development/file-structure.md @@ -111,10 +111,6 @@ master each one of them. The [Key-Auth plugin] is an example of plugin with this file structure. See [its source code] for more details. ---- - -Next: [Write custom logic ›]({{page.book.next}}) - [api.lua]: {{page.book.chapters.admin-api}} [daos.lua]: {{page.book.chapters.custom-entities}} [handler.lua]: {{page.book.chapters.custom-logic}} diff --git a/app/gateway-oss/2.1.x/plugin-development/index.md b/app/gateway-oss/2.1.x/plugin-development/index.md index a317d734fffd..100b861fba72 100644 --- a/app/gateway-oss/2.1.x/plugin-development/index.md +++ b/app/gateway-oss/2.1.x/plugin-development/index.md @@ -29,9 +29,5 @@ This guide will explore in detail the structure of plugins, what they can extend, and how to distribute and install them. For a complete reference of the PDK, see the [Plugin Development Kit] reference. ---- - -Next: [File structure of a plugin ›]({{page.book.next}}) - [lua-nginx-module]: https://github.com/openresty/lua-nginx-module [Plugin Development Kit]: /{{page.kong_version}}/pdk diff --git a/app/gateway-oss/2.1.x/plugin-development/plugin-configuration.md b/app/gateway-oss/2.1.x/plugin-development/plugin-configuration.md index b206ffcb3519..ba67b748992d 100644 --- a/app/gateway-oss/2.1.x/plugin-development/plugin-configuration.md +++ b/app/gateway-oss/2.1.x/plugin-development/plugin-configuration.md @@ -400,10 +400,6 @@ return CustomHandler You can also see a real-world example of schema in [the Key-Auth plugin source code]. ---- - -Next: [Accessing the Datastore ›]({{page.book.next}}) - [Admin API]: /{{page.kong_version}}/admin-api [Plugin Development Kit]: /{{page.kong_version}}/pdk [the Key-Auth plugin source code]: https://github.com/Kong/kong/blob/master/kong/plugins/key-auth/schema.lua diff --git a/app/gateway-oss/2.1.x/plugin-development/tests.md b/app/gateway-oss/2.1.x/plugin-development/tests.md index c94392339c74..833786cca388 100644 --- a/app/gateway-oss/2.1.x/plugin-development/tests.md +++ b/app/gateway-oss/2.1.x/plugin-development/tests.md @@ -15,7 +15,7 @@ might also want to write integration tests. Again, Kong has your back. ## Write integration tests The preferred testing framework for Kong is -[busted](http://olivinelabs.com/busted/) running with the +[busted](https://github.com/lunarmodules/busted/) running with the [resty-cli](https://github.com/openresty/resty-cli) interpreter, though you are free to use another one if you wish. In the Kong repository, the busted executable can be found at `bin/busted`. @@ -103,6 +103,3 @@ and Admin API on port 9001. If you want to see a real-world example, give a look at the [Key-Auth plugin specs](https://github.com/Kong/kong/tree/master/spec/03-plugins/09-key-auth) ---- - -Next: [Distribute your plugin ›]({{page.book.next}}) diff --git a/app/gateway-oss/2.2.x/plugin-development/access-the-datastore.md b/app/gateway-oss/2.2.x/plugin-development/access-the-datastore.md index 63fab7c8aa5c..6d9c161d886b 100644 --- a/app/gateway-oss/2.2.x/plugin-development/access-the-datastore.md +++ b/app/gateway-oss/2.2.x/plugin-development/access-the-datastore.md @@ -68,8 +68,4 @@ local inserted_plugin, err = kong.db.plugins:insert({ For a real-life example of the DAO being used in a plugin, see the [Key-Auth plugin source code](https://github.com/Kong/kong/blob/master/kong/plugins/key-auth/handler.lua). ---- - -Next: [Storing Custom Entities ›]({{page.book.next}}) - [Plugin Development Kit]: /{{page.kong_version}}/pdk diff --git a/app/gateway-oss/2.2.x/plugin-development/admin-api.md b/app/gateway-oss/2.2.x/plugin-development/admin-api.md index 951393ac2e8d..171e47d52476 100644 --- a/app/gateway-oss/2.2.x/plugin-development/admin-api.md +++ b/app/gateway-oss/2.2.x/plugin-development/admin-api.md @@ -11,7 +11,7 @@ chapter: 8
      Note: The Admin API extensions are available only - for HTTP plugins, not Stream plugins. + for HTTP plugins, not Stream plugins.
      ## Introduction @@ -100,10 +100,8 @@ return { ``` This code will create two Admin API endpoints in `/consumers/:consumers/key-auth`, to -obtain (`GET`) and create (`POST`) credentials associated to a given consumer. On this example -the functions are provided by the `kong.api.endpoints` library. If you want to see a more -complete example, with custom code in functions, see -[the `api.lua` file from the key-auth plugin](https://github.com/Kong/kong/blob/master/kong/plugins/key-auth/api.lua). +obtain (`GET`) and create (`POST`) credentials associated to a given consumer. In this example, +the functions are provided by the `kong.api.endpoints` library. The `endpoints` module currently contains the default implementation for the most usual CRUD operations used in Kong. This module provides you with helpers for any insert, retrieve, @@ -172,8 +170,4 @@ three functions: - The `PUT` function populates `self.args.post.consumer` before calling the `endpoints`-provided `put_entity_endpoint` function. ---- - -Next: [Write tests for your plugin]({{page.book.next}}) - [Admin API]: /{{page.kong_version}}/admin-api/ diff --git a/app/gateway-oss/2.2.x/plugin-development/custom-entities.md b/app/gateway-oss/2.2.x/plugin-development/custom-entities.md index 73391bee63d9..189f5c36ff1d 100644 --- a/app/gateway-oss/2.2.x/plugin-development/custom-entities.md +++ b/app/gateway-oss/2.2.x/plugin-development/custom-entities.md @@ -11,7 +11,7 @@ its configuration in the database. In that case, Kong provides you with an abstraction on top of its primary datastores which allows you to store custom entities. -As explained in the [previous chapter]({{page.book.previous}}), Kong interacts +As explained in the [previous chapter]({{page.book.previous.url}}), Kong interacts with the model layer through classes we refer to as "DAOs", and available on a singleton often referred to as the "DAO Factory". This chapter will explain how to to provide an abstraction for your own entities. @@ -188,7 +188,7 @@ for one that works with Cassandra too. enforce it for Cassandra, but for Postgres you must set this constraint in the migrations. -To see a real-life example, give a look at the [Key-Auth plugin migrations](https://github.com/Kong/kong/tree/{{page.kong_version}}/kong/plugins/key-auth/migrations). +To see a real-life example, give a look at the [Key-Auth plugin migrations](https://github.com/Kong/kong/tree/master/kong/plugins/key-auth/migrations). --- @@ -670,11 +670,7 @@ When a custom entity is required on every request/response it is good practice to cache it in-memory by leveraging the in-memory cache API provided by Kong. The next chapter will focus on caching custom entities, and invalidating them -when they change in the datastore: [Caching custom entities]({{page.book.next}}). - ---- - -Next: [Caching custom entities ›]({{page.book.next}}) +when they change in the datastore: [Caching custom entities]({{page.book.next.url}}). [Admin API]: /{{page.kong_version}}/admin-api/ [Plugin Development Kit]: /{{page.kong_version}}/pdk diff --git a/app/gateway-oss/2.2.x/plugin-development/custom-logic.md b/app/gateway-oss/2.2.x/plugin-development/custom-logic.md index a33c57f2ac7e..869475c1fde6 100644 --- a/app/gateway-oss/2.2.x/plugin-development/custom-logic.md +++ b/app/gateway-oss/2.2.x/plugin-development/custom-logic.md @@ -61,7 +61,7 @@ All of those functions, except `init_worker`, take one parameter which is given by Kong upon its invocation: the configuration of your plugin. This parameter is a Lua table, and contains values defined by your users, according to your plugin's schema (described in the `schema.lua` module). More on plugins schemas -in the [next chapter]({{page.book.next}}). +in the [next chapter]({{page.book.next.url}}). Note that UDP streams don't have real connections. Kong will consider all packets with the same origin and destination host and port as a single @@ -308,9 +308,5 @@ request-termination | 2 correlation-id | 1 post-function | -1000 ---- - -Next: [Plugin configuration ›]({{page.book.next}}) - [lua-nginx-module]: https://github.com/openresty/lua-nginx-module [pdk]: /{{page.kong_version}}/pdk diff --git a/app/gateway-oss/2.2.x/plugin-development/entities-cache.md b/app/gateway-oss/2.2.x/plugin-development/entities-cache.md index 50eb5cd3eb15..b80202be0509 100644 --- a/app/gateway-oss/2.2.x/plugin-development/entities-cache.md +++ b/app/gateway-oss/2.2.x/plugin-development/entities-cache.md @@ -7,7 +7,7 @@ chapter: 7 ## Introduction Your plugin may need to frequently access custom entities (explained in the -[previous chapter]({{page.book.previous}})) on every request and/or response. +[previous chapter]({{page.book.previous.url}})) on every request and/or response. Usually, loading them once and caching them in-memory dramatically improves the performance while making sure the datastore is not stressed with an increased load. @@ -341,11 +341,7 @@ Kong to setup their APIs and plugins. It is likely that they also need to be able to interact with the custom entities you implemented for your plugin (for example, creating and deleting API keys). The way you would do this is by extending the Admin API, which we will detail in the next chapter: -[Extending the Admin API]({{page.book.next}}). - ---- - -Next: [Extending the Admin API ›]({{page.book.next}}) +[Extending the Admin API]({{page.book.next.url}}). [Admin API]: /{{page.kong_version}}/admin-api/ [Plugin Development Kit]: /{{page.kong_version}}/pdk diff --git a/app/gateway-oss/2.2.x/plugin-development/file-structure.md b/app/gateway-oss/2.2.x/plugin-development/file-structure.md index 84f8599232c7..16afad6f8895 100644 --- a/app/gateway-oss/2.2.x/plugin-development/file-structure.md +++ b/app/gateway-oss/2.2.x/plugin-development/file-structure.md @@ -111,10 +111,6 @@ master each one of them. The [Key-Auth plugin] is an example of plugin with this file structure. See [its source code] for more details. ---- - -Next: [Write custom logic ›]({{page.book.next}}) - [api.lua]: {{page.book.chapters.admin-api}} [daos.lua]: {{page.book.chapters.custom-entities}} [handler.lua]: {{page.book.chapters.custom-logic}} diff --git a/app/gateway-oss/2.2.x/plugin-development/index.md b/app/gateway-oss/2.2.x/plugin-development/index.md index a317d734fffd..100b861fba72 100644 --- a/app/gateway-oss/2.2.x/plugin-development/index.md +++ b/app/gateway-oss/2.2.x/plugin-development/index.md @@ -29,9 +29,5 @@ This guide will explore in detail the structure of plugins, what they can extend, and how to distribute and install them. For a complete reference of the PDK, see the [Plugin Development Kit] reference. ---- - -Next: [File structure of a plugin ›]({{page.book.next}}) - [lua-nginx-module]: https://github.com/openresty/lua-nginx-module [Plugin Development Kit]: /{{page.kong_version}}/pdk diff --git a/app/gateway-oss/2.2.x/plugin-development/plugin-configuration.md b/app/gateway-oss/2.2.x/plugin-development/plugin-configuration.md index b206ffcb3519..ba67b748992d 100644 --- a/app/gateway-oss/2.2.x/plugin-development/plugin-configuration.md +++ b/app/gateway-oss/2.2.x/plugin-development/plugin-configuration.md @@ -400,10 +400,6 @@ return CustomHandler You can also see a real-world example of schema in [the Key-Auth plugin source code]. ---- - -Next: [Accessing the Datastore ›]({{page.book.next}}) - [Admin API]: /{{page.kong_version}}/admin-api [Plugin Development Kit]: /{{page.kong_version}}/pdk [the Key-Auth plugin source code]: https://github.com/Kong/kong/blob/master/kong/plugins/key-auth/schema.lua diff --git a/app/gateway-oss/2.2.x/plugin-development/tests.md b/app/gateway-oss/2.2.x/plugin-development/tests.md index c94392339c74..833786cca388 100644 --- a/app/gateway-oss/2.2.x/plugin-development/tests.md +++ b/app/gateway-oss/2.2.x/plugin-development/tests.md @@ -15,7 +15,7 @@ might also want to write integration tests. Again, Kong has your back. ## Write integration tests The preferred testing framework for Kong is -[busted](http://olivinelabs.com/busted/) running with the +[busted](https://github.com/lunarmodules/busted/) running with the [resty-cli](https://github.com/openresty/resty-cli) interpreter, though you are free to use another one if you wish. In the Kong repository, the busted executable can be found at `bin/busted`. @@ -103,6 +103,3 @@ and Admin API on port 9001. If you want to see a real-world example, give a look at the [Key-Auth plugin specs](https://github.com/Kong/kong/tree/master/spec/03-plugins/09-key-auth) ---- - -Next: [Distribute your plugin ›]({{page.book.next}}) diff --git a/app/gateway-oss/2.3.x/plugin-development/access-the-datastore.md b/app/gateway-oss/2.3.x/plugin-development/access-the-datastore.md index 63fab7c8aa5c..6d9c161d886b 100644 --- a/app/gateway-oss/2.3.x/plugin-development/access-the-datastore.md +++ b/app/gateway-oss/2.3.x/plugin-development/access-the-datastore.md @@ -68,8 +68,4 @@ local inserted_plugin, err = kong.db.plugins:insert({ For a real-life example of the DAO being used in a plugin, see the [Key-Auth plugin source code](https://github.com/Kong/kong/blob/master/kong/plugins/key-auth/handler.lua). ---- - -Next: [Storing Custom Entities ›]({{page.book.next}}) - [Plugin Development Kit]: /{{page.kong_version}}/pdk diff --git a/app/gateway-oss/2.3.x/plugin-development/admin-api.md b/app/gateway-oss/2.3.x/plugin-development/admin-api.md index 951393ac2e8d..171e47d52476 100644 --- a/app/gateway-oss/2.3.x/plugin-development/admin-api.md +++ b/app/gateway-oss/2.3.x/plugin-development/admin-api.md @@ -11,7 +11,7 @@ chapter: 8
      Note: The Admin API extensions are available only - for HTTP plugins, not Stream plugins. + for HTTP plugins, not Stream plugins.
      ## Introduction @@ -100,10 +100,8 @@ return { ``` This code will create two Admin API endpoints in `/consumers/:consumers/key-auth`, to -obtain (`GET`) and create (`POST`) credentials associated to a given consumer. On this example -the functions are provided by the `kong.api.endpoints` library. If you want to see a more -complete example, with custom code in functions, see -[the `api.lua` file from the key-auth plugin](https://github.com/Kong/kong/blob/master/kong/plugins/key-auth/api.lua). +obtain (`GET`) and create (`POST`) credentials associated to a given consumer. In this example, +the functions are provided by the `kong.api.endpoints` library. The `endpoints` module currently contains the default implementation for the most usual CRUD operations used in Kong. This module provides you with helpers for any insert, retrieve, @@ -172,8 +170,4 @@ three functions: - The `PUT` function populates `self.args.post.consumer` before calling the `endpoints`-provided `put_entity_endpoint` function. ---- - -Next: [Write tests for your plugin]({{page.book.next}}) - [Admin API]: /{{page.kong_version}}/admin-api/ diff --git a/app/gateway-oss/2.3.x/plugin-development/custom-entities.md b/app/gateway-oss/2.3.x/plugin-development/custom-entities.md index fbb2b082ddbf..ba076ccf316c 100644 --- a/app/gateway-oss/2.3.x/plugin-development/custom-entities.md +++ b/app/gateway-oss/2.3.x/plugin-development/custom-entities.md @@ -11,7 +11,7 @@ its configuration in the database. In that case, Kong provides you with an abstraction on top of its primary datastores which allows you to store custom entities. -As explained in the [previous chapter]({{page.book.previous}}), Kong interacts +As explained in the [previous chapter]({{page.book.previous.url}}), Kong interacts with the model layer through classes we refer to as "DAOs", and available on a singleton often referred to as the "DAO Factory". This chapter will explain how to to provide an abstraction for your own entities. @@ -188,7 +188,7 @@ for one that works with Cassandra too. enforce it for Cassandra, but for Postgres you must set this constraint in the migrations. -To see a real-life example, give a look at the [Key-Auth plugin migrations](https://github.com/Kong/kong/tree/{{page.kong_version}}/kong/plugins/key-auth/migrations). +To see a real-life example, give a look at the [Key-Auth plugin migrations](https://github.com/Kong/kong/tree/master/kong/plugins/key-auth/migrations). --- @@ -670,11 +670,7 @@ When a custom entity is required on every request/response it is good practice to cache it in-memory by leveraging the in-memory cache API provided by Kong. The next chapter will focus on caching custom entities, and invalidating them -when they change in the datastore: [Caching custom entities]({{page.book.next}}). - ---- - -Next: [Caching custom entities ›]({{page.book.next}}) +when they change in the datastore: [Caching custom entities]({{page.book.next.url}}). [Admin API]: /{{page.kong_version}}/admin-api/ [Plugin Development Kit]: /{{page.kong_version}}/pdk diff --git a/app/gateway-oss/2.3.x/plugin-development/custom-logic.md b/app/gateway-oss/2.3.x/plugin-development/custom-logic.md index a33c57f2ac7e..869475c1fde6 100644 --- a/app/gateway-oss/2.3.x/plugin-development/custom-logic.md +++ b/app/gateway-oss/2.3.x/plugin-development/custom-logic.md @@ -61,7 +61,7 @@ All of those functions, except `init_worker`, take one parameter which is given by Kong upon its invocation: the configuration of your plugin. This parameter is a Lua table, and contains values defined by your users, according to your plugin's schema (described in the `schema.lua` module). More on plugins schemas -in the [next chapter]({{page.book.next}}). +in the [next chapter]({{page.book.next.url}}). Note that UDP streams don't have real connections. Kong will consider all packets with the same origin and destination host and port as a single @@ -308,9 +308,5 @@ request-termination | 2 correlation-id | 1 post-function | -1000 ---- - -Next: [Plugin configuration ›]({{page.book.next}}) - [lua-nginx-module]: https://github.com/openresty/lua-nginx-module [pdk]: /{{page.kong_version}}/pdk diff --git a/app/gateway-oss/2.3.x/plugin-development/entities-cache.md b/app/gateway-oss/2.3.x/plugin-development/entities-cache.md index 50eb5cd3eb15..b80202be0509 100644 --- a/app/gateway-oss/2.3.x/plugin-development/entities-cache.md +++ b/app/gateway-oss/2.3.x/plugin-development/entities-cache.md @@ -7,7 +7,7 @@ chapter: 7 ## Introduction Your plugin may need to frequently access custom entities (explained in the -[previous chapter]({{page.book.previous}})) on every request and/or response. +[previous chapter]({{page.book.previous.url}})) on every request and/or response. Usually, loading them once and caching them in-memory dramatically improves the performance while making sure the datastore is not stressed with an increased load. @@ -341,11 +341,7 @@ Kong to setup their APIs and plugins. It is likely that they also need to be able to interact with the custom entities you implemented for your plugin (for example, creating and deleting API keys). The way you would do this is by extending the Admin API, which we will detail in the next chapter: -[Extending the Admin API]({{page.book.next}}). - ---- - -Next: [Extending the Admin API ›]({{page.book.next}}) +[Extending the Admin API]({{page.book.next.url}}). [Admin API]: /{{page.kong_version}}/admin-api/ [Plugin Development Kit]: /{{page.kong_version}}/pdk diff --git a/app/gateway-oss/2.3.x/plugin-development/file-structure.md b/app/gateway-oss/2.3.x/plugin-development/file-structure.md index 84f8599232c7..16afad6f8895 100644 --- a/app/gateway-oss/2.3.x/plugin-development/file-structure.md +++ b/app/gateway-oss/2.3.x/plugin-development/file-structure.md @@ -111,10 +111,6 @@ master each one of them. The [Key-Auth plugin] is an example of plugin with this file structure. See [its source code] for more details. ---- - -Next: [Write custom logic ›]({{page.book.next}}) - [api.lua]: {{page.book.chapters.admin-api}} [daos.lua]: {{page.book.chapters.custom-entities}} [handler.lua]: {{page.book.chapters.custom-logic}} diff --git a/app/gateway-oss/2.3.x/plugin-development/index.md b/app/gateway-oss/2.3.x/plugin-development/index.md index a317d734fffd..100b861fba72 100644 --- a/app/gateway-oss/2.3.x/plugin-development/index.md +++ b/app/gateway-oss/2.3.x/plugin-development/index.md @@ -29,9 +29,5 @@ This guide will explore in detail the structure of plugins, what they can extend, and how to distribute and install them. For a complete reference of the PDK, see the [Plugin Development Kit] reference. ---- - -Next: [File structure of a plugin ›]({{page.book.next}}) - [lua-nginx-module]: https://github.com/openresty/lua-nginx-module [Plugin Development Kit]: /{{page.kong_version}}/pdk diff --git a/app/gateway-oss/2.3.x/plugin-development/plugin-configuration.md b/app/gateway-oss/2.3.x/plugin-development/plugin-configuration.md index b206ffcb3519..ba67b748992d 100644 --- a/app/gateway-oss/2.3.x/plugin-development/plugin-configuration.md +++ b/app/gateway-oss/2.3.x/plugin-development/plugin-configuration.md @@ -400,10 +400,6 @@ return CustomHandler You can also see a real-world example of schema in [the Key-Auth plugin source code]. ---- - -Next: [Accessing the Datastore ›]({{page.book.next}}) - [Admin API]: /{{page.kong_version}}/admin-api [Plugin Development Kit]: /{{page.kong_version}}/pdk [the Key-Auth plugin source code]: https://github.com/Kong/kong/blob/master/kong/plugins/key-auth/schema.lua diff --git a/app/gateway-oss/2.3.x/plugin-development/tests.md b/app/gateway-oss/2.3.x/plugin-development/tests.md index c94392339c74..833786cca388 100644 --- a/app/gateway-oss/2.3.x/plugin-development/tests.md +++ b/app/gateway-oss/2.3.x/plugin-development/tests.md @@ -15,7 +15,7 @@ might also want to write integration tests. Again, Kong has your back. ## Write integration tests The preferred testing framework for Kong is -[busted](http://olivinelabs.com/busted/) running with the +[busted](https://github.com/lunarmodules/busted/) running with the [resty-cli](https://github.com/openresty/resty-cli) interpreter, though you are free to use another one if you wish. In the Kong repository, the busted executable can be found at `bin/busted`. @@ -103,6 +103,3 @@ and Admin API on port 9001. If you want to see a real-world example, give a look at the [Key-Auth plugin specs](https://github.com/Kong/kong/tree/master/spec/03-plugins/09-key-auth) ---- - -Next: [Distribute your plugin ›]({{page.book.next}}) diff --git a/app/gateway-oss/2.4.x/plugin-development/access-the-datastore.md b/app/gateway-oss/2.4.x/plugin-development/access-the-datastore.md index e64bdb1292a3..04207c5a5da3 100644 --- a/app/gateway-oss/2.4.x/plugin-development/access-the-datastore.md +++ b/app/gateway-oss/2.4.x/plugin-development/access-the-datastore.md @@ -68,8 +68,4 @@ local inserted_plugin, err = kong.db.plugins:insert({ For a real-life example of the DAO being used in a plugin, see the [Key-Auth plugin source code](https://github.com/Kong/kong/blob/master/kong/plugins/key-auth/handler.lua). ---- - -Next: [Storing Custom Entities ›]({{page.book.next}}) - [Plugin Development Kit]: /gateway-oss/{{page.kong_version}}/pdk diff --git a/app/gateway-oss/2.4.x/plugin-development/admin-api.md b/app/gateway-oss/2.4.x/plugin-development/admin-api.md index ef8d94c46f43..bd59b52bef2c 100644 --- a/app/gateway-oss/2.4.x/plugin-development/admin-api.md +++ b/app/gateway-oss/2.4.x/plugin-development/admin-api.md @@ -11,7 +11,7 @@ chapter: 8
      Note: The Admin API extensions are available only - for HTTP plugins, not Stream plugins. + for HTTP plugins, not Stream plugins.
      ## Introduction @@ -100,10 +100,8 @@ return { ``` This code will create two Admin API endpoints in `/consumers/:consumers/key-auth`, to -obtain (`GET`) and create (`POST`) credentials associated to a given consumer. On this example -the functions are provided by the `kong.api.endpoints` library. If you want to see a more -complete example, with custom code in functions, see -[the `api.lua` file from the key-auth plugin](https://github.com/Kong/kong/blob/master/kong/plugins/key-auth/api.lua). +obtain (`GET`) and create (`POST`) credentials associated to a given consumer. In this example, +the functions are provided by the `kong.api.endpoints` library. The `endpoints` module currently contains the default implementation for the most usual CRUD operations used in Kong. This module provides you with helpers for any insert, retrieve, @@ -172,8 +170,4 @@ three functions: - The `PUT` function populates `self.args.post.consumer` before calling the `endpoints`-provided `put_entity_endpoint` function. ---- - -Next: [Write tests for your plugin]({{page.book.next}}) - [Admin API]: /gateway-oss/{{page.kong_version}}/admin-api/ diff --git a/app/gateway-oss/2.4.x/plugin-development/custom-entities.md b/app/gateway-oss/2.4.x/plugin-development/custom-entities.md index a26b761e17d3..f97c9617b5ed 100644 --- a/app/gateway-oss/2.4.x/plugin-development/custom-entities.md +++ b/app/gateway-oss/2.4.x/plugin-development/custom-entities.md @@ -11,7 +11,7 @@ its configuration in the database. In that case, Kong provides you with an abstraction on top of its primary datastores which allows you to store custom entities. -As explained in the [previous chapter]({{page.book.previous}}), Kong interacts +As explained in the [previous chapter]({{page.book.previous.url}}), Kong interacts with the model layer through classes we refer to as "DAOs", and available on a singleton often referred to as the "DAO Factory". This chapter will explain how to to provide an abstraction for your own entities. @@ -188,7 +188,7 @@ for one that works with Cassandra too. enforce it for Cassandra, but for Postgres you must set this constraint in the migrations. -To see a real-life example, give a look at the [Key-Auth plugin migrations](https://github.com/Kong/kong/tree/{{page.kong_version}}/kong/plugins/key-auth/migrations). +To see a real-life example, give a look at the [Key-Auth plugin migrations](https://github.com/Kong/kong/tree/master/kong/plugins/key-auth/migrations). --- @@ -670,11 +670,7 @@ When a custom entity is required on every request/response it is good practice to cache it in-memory by leveraging the in-memory cache API provided by Kong. The next chapter will focus on caching custom entities, and invalidating them -when they change in the datastore: [Caching custom entities]({{page.book.next}}). - ---- - -Next: [Caching custom entities ›]({{page.book.next}}) +when they change in the datastore: [Caching custom entities]({{page.book.next.url}}). [Admin API]: /gateway-oss/{{page.kong_version}}/admin-api/ [Plugin Development Kit]: /gateway-oss/{{page.kong_version}}/pdk diff --git a/app/gateway-oss/2.4.x/plugin-development/custom-logic.md b/app/gateway-oss/2.4.x/plugin-development/custom-logic.md index c229ce2c2611..6e1613721f17 100644 --- a/app/gateway-oss/2.4.x/plugin-development/custom-logic.md +++ b/app/gateway-oss/2.4.x/plugin-development/custom-logic.md @@ -65,7 +65,7 @@ All of those functions, except `init_worker`, take one parameter which is given by {{site.ce_product_name}} upon its invocation: the configuration of your Plugin. This parameter is a Lua table, and contains values defined by your users, according to your Plugin's schema (described in the `schema.lua` module). More on Plugins schemas -in the [next chapter]({{page.book.next}}). +in the [next chapter]({{page.book.next.url}}). Note that UDP streams don't have real connections. {{site.ce_product_name}} will consider all packets with the same origin and destination host and port as a single @@ -292,9 +292,5 @@ request-termination | 2 correlation-id | 1 post-function | -1000 ---- - -Next: [Plugin configuration ›]({{page.book.next}}) - [lua-nginx-module]: https://github.com/openresty/lua-nginx-module [pdk]: /gateway-oss/{{page.kong_version}}/pdk diff --git a/app/gateway-oss/2.4.x/plugin-development/entities-cache.md b/app/gateway-oss/2.4.x/plugin-development/entities-cache.md index 361722dc029a..853e08d06469 100644 --- a/app/gateway-oss/2.4.x/plugin-development/entities-cache.md +++ b/app/gateway-oss/2.4.x/plugin-development/entities-cache.md @@ -7,7 +7,7 @@ chapter: 7 ## Introduction Your plugin may need to frequently access custom entities (explained in the -[previous chapter]({{page.book.previous}})) on every request and/or response. +[previous chapter]({{page.book.previous.url}})) on every request and/or response. Usually, loading them once and caching them in-memory dramatically improves the performance while making sure the datastore is not stressed with an increased load. @@ -341,11 +341,7 @@ Kong to setup their APIs and plugins. It is likely that they also need to be able to interact with the custom entities you implemented for your plugin (for example, creating and deleting API keys). The way you would do this is by extending the Admin API, which we will detail in the next chapter: -[Extending the Admin API]({{page.book.next}}). - ---- - -Next: [Extending the Admin API ›]({{page.book.next}}) +[Extending the Admin API]({{page.book.next.url}}). [Admin API]: /gateway-oss/{{page.kong_version}}/admin-api/ [Plugin Development Kit]: /gateway-oss/{{page.kong_version}}/pdk diff --git a/app/gateway-oss/2.4.x/plugin-development/file-structure.md b/app/gateway-oss/2.4.x/plugin-development/file-structure.md index 7949c82f5744..d5f2fa06ca21 100644 --- a/app/gateway-oss/2.4.x/plugin-development/file-structure.md +++ b/app/gateway-oss/2.4.x/plugin-development/file-structure.md @@ -111,10 +111,6 @@ master each one of them. The [Key-Auth plugin] is an example of plugin with this file structure. See [its source code] for more details. ---- - -Next: [Write custom logic ›]({{page.book.next}}) - [api.lua]: {{page.book.chapters.admin-api}} [daos.lua]: {{page.book.chapters.custom-entities}} [handler.lua]: {{page.book.chapters.custom-logic}} diff --git a/app/gateway-oss/2.4.x/plugin-development/index.md b/app/gateway-oss/2.4.x/plugin-development/index.md index 8c16bec9205b..0b6fa320d1ee 100644 --- a/app/gateway-oss/2.4.x/plugin-development/index.md +++ b/app/gateway-oss/2.4.x/plugin-development/index.md @@ -29,9 +29,5 @@ This guide will explore in detail the structure of plugins, what they can extend, and how to distribute and install them. For a complete reference of the PDK, see the [Plugin Development Kit] reference. ---- - -Next: [File structure of a plugin ›]({{page.book.next}}) - [lua-nginx-module]: https://github.com/openresty/lua-nginx-module [Plugin Development Kit]: /gateway-oss/{{page.kong_version}}/pdk diff --git a/app/gateway-oss/2.4.x/plugin-development/plugin-configuration.md b/app/gateway-oss/2.4.x/plugin-development/plugin-configuration.md index 29ec0c82ba47..25d50c2377c3 100644 --- a/app/gateway-oss/2.4.x/plugin-development/plugin-configuration.md +++ b/app/gateway-oss/2.4.x/plugin-development/plugin-configuration.md @@ -400,10 +400,6 @@ return CustomHandler You can also see a real-world example of schema in [the Key-Auth plugin source code]. ---- - -Next: [Accessing the Datastore ›]({{page.book.next}}) - [Admin API]: /gateway-oss/{{page.kong_version}}/admin-api [Plugin Development Kit]: /gateway-oss/{{page.kong_version}}/pdk [the Key-Auth plugin source code]: https://github.com/Kong/kong/blob/master/kong/plugins/key-auth/schema.lua diff --git a/app/gateway-oss/2.4.x/plugin-development/tests.md b/app/gateway-oss/2.4.x/plugin-development/tests.md index c94392339c74..833786cca388 100644 --- a/app/gateway-oss/2.4.x/plugin-development/tests.md +++ b/app/gateway-oss/2.4.x/plugin-development/tests.md @@ -15,7 +15,7 @@ might also want to write integration tests. Again, Kong has your back. ## Write integration tests The preferred testing framework for Kong is -[busted](http://olivinelabs.com/busted/) running with the +[busted](https://github.com/lunarmodules/busted/) running with the [resty-cli](https://github.com/openresty/resty-cli) interpreter, though you are free to use another one if you wish. In the Kong repository, the busted executable can be found at `bin/busted`. @@ -103,6 +103,3 @@ and Admin API on port 9001. If you want to see a real-world example, give a look at the [Key-Auth plugin specs](https://github.com/Kong/kong/tree/master/spec/03-plugins/09-key-auth) ---- - -Next: [Distribute your plugin ›]({{page.book.next}}) diff --git a/app/gateway-oss/2.5.x/plugin-development/access-the-datastore.md b/app/gateway-oss/2.5.x/plugin-development/access-the-datastore.md index e64bdb1292a3..04207c5a5da3 100644 --- a/app/gateway-oss/2.5.x/plugin-development/access-the-datastore.md +++ b/app/gateway-oss/2.5.x/plugin-development/access-the-datastore.md @@ -68,8 +68,4 @@ local inserted_plugin, err = kong.db.plugins:insert({ For a real-life example of the DAO being used in a plugin, see the [Key-Auth plugin source code](https://github.com/Kong/kong/blob/master/kong/plugins/key-auth/handler.lua). ---- - -Next: [Storing Custom Entities ›]({{page.book.next}}) - [Plugin Development Kit]: /gateway-oss/{{page.kong_version}}/pdk diff --git a/app/gateway-oss/2.5.x/plugin-development/admin-api.md b/app/gateway-oss/2.5.x/plugin-development/admin-api.md index ef8d94c46f43..bd59b52bef2c 100644 --- a/app/gateway-oss/2.5.x/plugin-development/admin-api.md +++ b/app/gateway-oss/2.5.x/plugin-development/admin-api.md @@ -11,7 +11,7 @@ chapter: 8
      Note: The Admin API extensions are available only - for HTTP plugins, not Stream plugins. + for HTTP plugins, not Stream plugins.
      ## Introduction @@ -100,10 +100,8 @@ return { ``` This code will create two Admin API endpoints in `/consumers/:consumers/key-auth`, to -obtain (`GET`) and create (`POST`) credentials associated to a given consumer. On this example -the functions are provided by the `kong.api.endpoints` library. If you want to see a more -complete example, with custom code in functions, see -[the `api.lua` file from the key-auth plugin](https://github.com/Kong/kong/blob/master/kong/plugins/key-auth/api.lua). +obtain (`GET`) and create (`POST`) credentials associated to a given consumer. In this example, +the functions are provided by the `kong.api.endpoints` library. The `endpoints` module currently contains the default implementation for the most usual CRUD operations used in Kong. This module provides you with helpers for any insert, retrieve, @@ -172,8 +170,4 @@ three functions: - The `PUT` function populates `self.args.post.consumer` before calling the `endpoints`-provided `put_entity_endpoint` function. ---- - -Next: [Write tests for your plugin]({{page.book.next}}) - [Admin API]: /gateway-oss/{{page.kong_version}}/admin-api/ diff --git a/app/gateway-oss/2.5.x/plugin-development/custom-entities.md b/app/gateway-oss/2.5.x/plugin-development/custom-entities.md index a26b761e17d3..f97c9617b5ed 100644 --- a/app/gateway-oss/2.5.x/plugin-development/custom-entities.md +++ b/app/gateway-oss/2.5.x/plugin-development/custom-entities.md @@ -11,7 +11,7 @@ its configuration in the database. In that case, Kong provides you with an abstraction on top of its primary datastores which allows you to store custom entities. -As explained in the [previous chapter]({{page.book.previous}}), Kong interacts +As explained in the [previous chapter]({{page.book.previous.url}}), Kong interacts with the model layer through classes we refer to as "DAOs", and available on a singleton often referred to as the "DAO Factory". This chapter will explain how to to provide an abstraction for your own entities. @@ -188,7 +188,7 @@ for one that works with Cassandra too. enforce it for Cassandra, but for Postgres you must set this constraint in the migrations. -To see a real-life example, give a look at the [Key-Auth plugin migrations](https://github.com/Kong/kong/tree/{{page.kong_version}}/kong/plugins/key-auth/migrations). +To see a real-life example, give a look at the [Key-Auth plugin migrations](https://github.com/Kong/kong/tree/master/kong/plugins/key-auth/migrations). --- @@ -670,11 +670,7 @@ When a custom entity is required on every request/response it is good practice to cache it in-memory by leveraging the in-memory cache API provided by Kong. The next chapter will focus on caching custom entities, and invalidating them -when they change in the datastore: [Caching custom entities]({{page.book.next}}). - ---- - -Next: [Caching custom entities ›]({{page.book.next}}) +when they change in the datastore: [Caching custom entities]({{page.book.next.url}}). [Admin API]: /gateway-oss/{{page.kong_version}}/admin-api/ [Plugin Development Kit]: /gateway-oss/{{page.kong_version}}/pdk diff --git a/app/gateway-oss/2.5.x/plugin-development/custom-logic.md b/app/gateway-oss/2.5.x/plugin-development/custom-logic.md index c229ce2c2611..6e1613721f17 100644 --- a/app/gateway-oss/2.5.x/plugin-development/custom-logic.md +++ b/app/gateway-oss/2.5.x/plugin-development/custom-logic.md @@ -65,7 +65,7 @@ All of those functions, except `init_worker`, take one parameter which is given by {{site.ce_product_name}} upon its invocation: the configuration of your Plugin. This parameter is a Lua table, and contains values defined by your users, according to your Plugin's schema (described in the `schema.lua` module). More on Plugins schemas -in the [next chapter]({{page.book.next}}). +in the [next chapter]({{page.book.next.url}}). Note that UDP streams don't have real connections. {{site.ce_product_name}} will consider all packets with the same origin and destination host and port as a single @@ -292,9 +292,5 @@ request-termination | 2 correlation-id | 1 post-function | -1000 ---- - -Next: [Plugin configuration ›]({{page.book.next}}) - [lua-nginx-module]: https://github.com/openresty/lua-nginx-module [pdk]: /gateway-oss/{{page.kong_version}}/pdk diff --git a/app/gateway-oss/2.5.x/plugin-development/entities-cache.md b/app/gateway-oss/2.5.x/plugin-development/entities-cache.md index 361722dc029a..853e08d06469 100644 --- a/app/gateway-oss/2.5.x/plugin-development/entities-cache.md +++ b/app/gateway-oss/2.5.x/plugin-development/entities-cache.md @@ -7,7 +7,7 @@ chapter: 7 ## Introduction Your plugin may need to frequently access custom entities (explained in the -[previous chapter]({{page.book.previous}})) on every request and/or response. +[previous chapter]({{page.book.previous.url}})) on every request and/or response. Usually, loading them once and caching them in-memory dramatically improves the performance while making sure the datastore is not stressed with an increased load. @@ -341,11 +341,7 @@ Kong to setup their APIs and plugins. It is likely that they also need to be able to interact with the custom entities you implemented for your plugin (for example, creating and deleting API keys). The way you would do this is by extending the Admin API, which we will detail in the next chapter: -[Extending the Admin API]({{page.book.next}}). - ---- - -Next: [Extending the Admin API ›]({{page.book.next}}) +[Extending the Admin API]({{page.book.next.url}}). [Admin API]: /gateway-oss/{{page.kong_version}}/admin-api/ [Plugin Development Kit]: /gateway-oss/{{page.kong_version}}/pdk diff --git a/app/gateway-oss/2.5.x/plugin-development/file-structure.md b/app/gateway-oss/2.5.x/plugin-development/file-structure.md index 7949c82f5744..d5f2fa06ca21 100644 --- a/app/gateway-oss/2.5.x/plugin-development/file-structure.md +++ b/app/gateway-oss/2.5.x/plugin-development/file-structure.md @@ -111,10 +111,6 @@ master each one of them. The [Key-Auth plugin] is an example of plugin with this file structure. See [its source code] for more details. ---- - -Next: [Write custom logic ›]({{page.book.next}}) - [api.lua]: {{page.book.chapters.admin-api}} [daos.lua]: {{page.book.chapters.custom-entities}} [handler.lua]: {{page.book.chapters.custom-logic}} diff --git a/app/gateway-oss/2.5.x/plugin-development/index.md b/app/gateway-oss/2.5.x/plugin-development/index.md index 8c16bec9205b..0b6fa320d1ee 100644 --- a/app/gateway-oss/2.5.x/plugin-development/index.md +++ b/app/gateway-oss/2.5.x/plugin-development/index.md @@ -29,9 +29,5 @@ This guide will explore in detail the structure of plugins, what they can extend, and how to distribute and install them. For a complete reference of the PDK, see the [Plugin Development Kit] reference. ---- - -Next: [File structure of a plugin ›]({{page.book.next}}) - [lua-nginx-module]: https://github.com/openresty/lua-nginx-module [Plugin Development Kit]: /gateway-oss/{{page.kong_version}}/pdk diff --git a/app/gateway-oss/2.5.x/plugin-development/plugin-configuration.md b/app/gateway-oss/2.5.x/plugin-development/plugin-configuration.md index 29ec0c82ba47..25d50c2377c3 100644 --- a/app/gateway-oss/2.5.x/plugin-development/plugin-configuration.md +++ b/app/gateway-oss/2.5.x/plugin-development/plugin-configuration.md @@ -400,10 +400,6 @@ return CustomHandler You can also see a real-world example of schema in [the Key-Auth plugin source code]. ---- - -Next: [Accessing the Datastore ›]({{page.book.next}}) - [Admin API]: /gateway-oss/{{page.kong_version}}/admin-api [Plugin Development Kit]: /gateway-oss/{{page.kong_version}}/pdk [the Key-Auth plugin source code]: https://github.com/Kong/kong/blob/master/kong/plugins/key-auth/schema.lua diff --git a/app/gateway-oss/2.5.x/plugin-development/tests.md b/app/gateway-oss/2.5.x/plugin-development/tests.md index c94392339c74..833786cca388 100644 --- a/app/gateway-oss/2.5.x/plugin-development/tests.md +++ b/app/gateway-oss/2.5.x/plugin-development/tests.md @@ -15,7 +15,7 @@ might also want to write integration tests. Again, Kong has your back. ## Write integration tests The preferred testing framework for Kong is -[busted](http://olivinelabs.com/busted/) running with the +[busted](https://github.com/lunarmodules/busted/) running with the [resty-cli](https://github.com/openresty/resty-cli) interpreter, though you are free to use another one if you wish. In the Kong repository, the busted executable can be found at `bin/busted`. @@ -103,6 +103,3 @@ and Admin API on port 9001. If you want to see a real-world example, give a look at the [Key-Auth plugin specs](https://github.com/Kong/kong/tree/master/spec/03-plugins/09-key-auth) ---- - -Next: [Distribute your plugin ›]({{page.book.next}}) diff --git a/app/_data/docs_nav_ce_0.13.x.yml b/app/gateway-oss/docs_nav_ce_0.13.x.yml similarity index 100% rename from app/_data/docs_nav_ce_0.13.x.yml rename to app/gateway-oss/docs_nav_ce_0.13.x.yml diff --git a/app/_data/docs_nav_ce_0.14.x.yml b/app/gateway-oss/docs_nav_ce_0.14.x.yml similarity index 100% rename from app/_data/docs_nav_ce_0.14.x.yml rename to app/gateway-oss/docs_nav_ce_0.14.x.yml diff --git a/app/_data/docs_nav_ce_1.0.x.yml b/app/gateway-oss/docs_nav_ce_1.0.x.yml similarity index 100% rename from app/_data/docs_nav_ce_1.0.x.yml rename to app/gateway-oss/docs_nav_ce_1.0.x.yml diff --git a/app/_data/docs_nav_ce_1.1.x.yml b/app/gateway-oss/docs_nav_ce_1.1.x.yml similarity index 100% rename from app/_data/docs_nav_ce_1.1.x.yml rename to app/gateway-oss/docs_nav_ce_1.1.x.yml diff --git a/app/_data/docs_nav_ce_1.2.x.yml b/app/gateway-oss/docs_nav_ce_1.2.x.yml similarity index 100% rename from app/_data/docs_nav_ce_1.2.x.yml rename to app/gateway-oss/docs_nav_ce_1.2.x.yml diff --git a/app/_data/docs_nav_ce_1.3.x.yml b/app/gateway-oss/docs_nav_ce_1.3.x.yml similarity index 100% rename from app/_data/docs_nav_ce_1.3.x.yml rename to app/gateway-oss/docs_nav_ce_1.3.x.yml diff --git a/app/_data/docs_nav_ce_1.4.x.yml b/app/gateway-oss/docs_nav_ce_1.4.x.yml similarity index 100% rename from app/_data/docs_nav_ce_1.4.x.yml rename to app/gateway-oss/docs_nav_ce_1.4.x.yml diff --git a/app/_data/docs_nav_ce_1.5.x.yml b/app/gateway-oss/docs_nav_ce_1.5.x.yml similarity index 100% rename from app/_data/docs_nav_ce_1.5.x.yml rename to app/gateway-oss/docs_nav_ce_1.5.x.yml diff --git a/app/_data/docs_nav_ee_0.31-x.yml b/app/gateway-oss/docs_nav_ee_0.31-x.yml similarity index 100% rename from app/_data/docs_nav_ee_0.31-x.yml rename to app/gateway-oss/docs_nav_ee_0.31-x.yml diff --git a/app/_data/docs_nav_ee_0.32-x.yml b/app/gateway-oss/docs_nav_ee_0.32-x.yml similarity index 100% rename from app/_data/docs_nav_ee_0.32-x.yml rename to app/gateway-oss/docs_nav_ee_0.32-x.yml diff --git a/app/_data/docs_nav_ee_0.33-x.yml b/app/gateway-oss/docs_nav_ee_0.33-x.yml similarity index 100% rename from app/_data/docs_nav_ee_0.33-x.yml rename to app/gateway-oss/docs_nav_ee_0.33-x.yml diff --git a/app/_data/docs_nav_ee_0.34-x.yml b/app/gateway-oss/docs_nav_ee_0.34-x.yml similarity index 100% rename from app/_data/docs_nav_ee_0.34-x.yml rename to app/gateway-oss/docs_nav_ee_0.34-x.yml diff --git a/app/_data/docs_nav_ee_0.35-x.yml b/app/gateway-oss/docs_nav_ee_0.35-x.yml similarity index 100% rename from app/_data/docs_nav_ee_0.35-x.yml rename to app/gateway-oss/docs_nav_ee_0.35-x.yml diff --git a/app/_data/docs_nav_ee_0.36-x.yml b/app/gateway-oss/docs_nav_ee_0.36-x.yml similarity index 100% rename from app/_data/docs_nav_ee_0.36-x.yml rename to app/gateway-oss/docs_nav_ee_0.36-x.yml diff --git a/app/_data/docs_nav_ee_1.3-x.yml b/app/gateway-oss/docs_nav_ee_1.3-x.yml similarity index 100% rename from app/_data/docs_nav_ee_1.3-x.yml rename to app/gateway-oss/docs_nav_ee_1.3-x.yml diff --git a/app/_data/docs_nav_ee_1.5.x.yml b/app/gateway-oss/docs_nav_ee_1.5.x.yml similarity index 100% rename from app/_data/docs_nav_ee_1.5.x.yml rename to app/gateway-oss/docs_nav_ee_1.5.x.yml diff --git a/app/gateway/2.6.x/configure/auth/kong-manager/networking.md b/app/gateway/2.6.x/configure/auth/kong-manager/networking.md index edf58415304f..d52f26184465 100644 --- a/app/gateway/2.6.x/configure/auth/kong-manager/networking.md +++ b/app/gateway/2.6.x/configure/auth/kong-manager/networking.md @@ -28,7 +28,7 @@ Common configurations to enable are 8444 on localhost. Change [`admin_listen`] if necessary, or set [`admin_api_uri`]. -{% include_cached /md/admin-listen.md desc='short' %} +{% include_cached /md/admin-listen.md kong_version=page.kong_version desc='short' %} * Securing Kong Manager and serving it from a dedicated node diff --git a/app/gateway/2.6.x/configure/auth/oidc-cognito.md b/app/gateway/2.6.x/configure/auth/oidc-cognito.md index b2d68fbc8ac9..4fd7b48bf8b9 100644 --- a/app/gateway/2.6.x/configure/auth/oidc-cognito.md +++ b/app/gateway/2.6.x/configure/auth/oidc-cognito.md @@ -12,28 +12,16 @@ In this configuration, we use User Pools. 1. Log in to AWS Console. 1. Navigate to the Amazon Cognito Service. - - 1. Click on **Manage User Pools**. - - 1. Click the **Create a user pool** button on the right-hand side. - - 1. Enter a pool name; we use “test-pool” for this example. - - 1. Click **Step Through Settings**. - - 1. Select **Email address or phone number**, and under that, select **Allow email addresses**. Select the following standard attributes as required: email, family name, given name. - - 1. Click **Next step**. 1. Accept the defaults for **Password settings**, then click **Next step**. 1. Accept the defaults for **MFA and verifications**, then click **Next step**. @@ -43,54 +31,32 @@ In this configuration, we use User Pools. 1. We can create an application definition later. Keep things simple for now and click **Next step**. 1. We don’t have any need for Triggers or customized Sign Up/Sign In behavior for this example. Scroll down and click **Save Changes**. - - 1. Click **Create pool**. Wait a moment for the success message. 1. Make a note of the **Pool ID**. You will need this when configuring the application later. - - ## Application Definition You need to add an OAuth2 application definition to the User Pool we just created. 1. Go to the App clients screen in the AWS Cognito management screen for the User Pool we just created. - - 1. Click “Add an app client”. - - -1. Enter an App client name. This demo is using “kong-api” - - +1. Enter an App client name. This demo is using “kong-api”. 1. Enter a Refresh token expiration (in days). We will use the default of 30 days. 1. Do not select “Generate client secret”. This example will use a public client. - - 1. Do not select any other checkboxes. - - 1. Click the “Set attribute read and write permissions” button. - - 1. Let’s make this simple and only give the user read and write access to the required attributes. So, uncheck everything except the email, given name, and family name fields. - - -1. Click “Create app client” - - +1. Click “Create app client”. 1. Click “Show Details”. - - 1. Take note of the App client ID. We will need that later. 1. Go to the App integration -> App client settings screen. 1. Click the “Cognito User Pool” checkbox under Enabled Identity Providers. @@ -103,21 +69,13 @@ You need to add an OAuth2 application definition to the User Pool we just create Note that AWS Cognito doesn’t support HTTP callback URLs. This field should include the API and Dev Portal URLs that you want to secure using AWS Cognito. - - 1. Click the “Authorization code grant” checkbox under Allowed OAuth Flows. - - - 1. Click the checkboxes next to email, OpenID, aws.cognito.signin.user.admin, and profile. 1. Click the “Save changes” button. 1. Click on the domain name tab. 1. Add a sub-domain name. 1. Click the Check Availability button. 1. As long as it reports “This domain is available”, the name you have chosen will work. - - - 1. Click the “Save changes” button. Now that you have created an Amazon Cognito User Pool and Application Definition, we can configure the OpenID Connect plugin in Kong. We can then test integration between Dev Portal and Amazon Cognito. @@ -155,7 +113,7 @@ You can verify the confirmed user from the Cognito page under “General setting ## Dev Portal Integration -{% include_cached /md/admin-listen.md desc='long' %} +{% include_cached /md/admin-listen.md kong_version=page.kong_version desc='long' %} Since AWS Cognito only supports the HTTPS protocol, when you start {{site.base_gateway}}, ensure that HTTPS protocol for Dev Portal is enabled. For example: diff --git a/app/gateway/2.6.x/configure/network.md b/app/gateway/2.6.x/configure/network.md index 303331d80693..25f7e7253cff 100644 --- a/app/gateway/2.6.x/configure/network.md +++ b/app/gateway/2.6.x/configure/network.md @@ -34,7 +34,7 @@ it from unauthorized access. * `8001` provides Kong's **Admin API** that you can use to operate Kong with HTTP. See [admin_listen]. -{% include_cached /md/admin-listen.md desc='short' %} +{% include_cached /md/admin-listen.md kong_version=page.kong_version desc='short' %} * `8444` provides the same Kong **Admin API** but using HTTPS. See [admin_listen] and the `ssl` suffix. diff --git a/app/gateway/2.6.x/install-and-run/docker.md b/app/gateway/2.6.x/install-and-run/docker.md index 3c576773e14c..3997aa7cae13 100644 --- a/app/gateway/2.6.x/install-and-run/docker.md +++ b/app/gateway/2.6.x/install-and-run/docker.md @@ -126,7 +126,7 @@ kong:{{page.kong_versions[page.version-index].ce-version}}-alpine kong migration ### Start Kong Gateway -{% include_cached /md/admin-listen.md desc='long' %} +{% include_cached /md/admin-listen.md kong_version=page.kong_version desc='long' %} 1. Run the following command to start a container with {{site.base_gateway}}: {% capture start_container %} @@ -295,7 +295,7 @@ backed up by a Redis cluster). ### Start Kong Gateway in DB-less mode -{% include_cached /md/admin-listen.md desc='long' %} +{% include_cached /md/admin-listen.md kong_version=page.kong_version desc='long' %} 1. From the same directory where you just created the `kong.yml` file, run the following command to start a container with {{site.base_gateway}}: diff --git a/app/gateway/2.6.x/plan-and-deploy/security/start-kong-securely.md b/app/gateway/2.6.x/plan-and-deploy/security/start-kong-securely.md index a8394b34422e..2d109f046fb6 100644 --- a/app/gateway/2.6.x/plan-and-deploy/security/start-kong-securely.md +++ b/app/gateway/2.6.x/plan-and-deploy/security/start-kong-securely.md @@ -32,7 +32,7 @@ of authentication. For a simple configuration to use for the subsequent Getting Started guides: -{% include_cached /md/admin-listen.md desc='long' %} +{% include_cached /md/admin-listen.md kong_version=page.kong_version desc='long' %} ``` enforce_rbac = on diff --git a/app/gateway/2.6.x/plugin-development/access-the-datastore.md b/app/gateway/2.6.x/plugin-development/access-the-datastore.md index ddf7cd377b82..81bc93bb2c82 100644 --- a/app/gateway/2.6.x/plugin-development/access-the-datastore.md +++ b/app/gateway/2.6.x/plugin-development/access-the-datastore.md @@ -64,8 +64,4 @@ local inserted_plugin, err = kong.db.plugins:insert({ For a real-life example of the DAO being used in a plugin, see the [Key-Auth plugin source code](https://github.com/Kong/kong/blob/master/kong/plugins/key-auth/handler.lua). ---- - -Next: [Storing Custom Entities ›]({{page.book.next}}) - [Plugin Development Kit]: /gateway/{{page.kong_version}}/pdk diff --git a/app/gateway/2.6.x/plugin-development/admin-api.md b/app/gateway/2.6.x/plugin-development/admin-api.md index 936be35074a7..00a2ff967723 100644 --- a/app/gateway/2.6.x/plugin-development/admin-api.md +++ b/app/gateway/2.6.x/plugin-development/admin-api.md @@ -95,10 +95,8 @@ return { ``` This code will create two Admin API endpoints in `/consumers/:consumers/key-auth`, to -obtain (`GET`) and create (`POST`) credentials associated to a given consumer. On this example -the functions are provided by the `kong.api.endpoints` library. If you want to see a more -complete example, with custom code in functions, see -[the `api.lua` file from the key-auth plugin](https://github.com/Kong/kong/blob/master/kong/plugins/key-auth/api.lua). +obtain (`GET`) and create (`POST`) credentials associated to a given consumer. In this example, +the functions are provided by the `kong.api.endpoints` library. The `endpoints` module currently contains the default implementation for the most usual CRUD operations used in Kong. This module provides you with helpers for any insert, retrieve, @@ -167,8 +165,4 @@ three functions: - The `PUT` function populates `self.args.post.consumer` before calling the `endpoints`-provided `put_entity_endpoint` function. ---- - -Next: [Write tests for your plugin]({{page.book.next}}) - [Admin API]: /gateway/{{page.kong_version}}/admin-api/ diff --git a/app/gateway/2.6.x/plugin-development/custom-entities.md b/app/gateway/2.6.x/plugin-development/custom-entities.md index 6929cff267b0..b04d63c762ef 100644 --- a/app/gateway/2.6.x/plugin-development/custom-entities.md +++ b/app/gateway/2.6.x/plugin-development/custom-entities.md @@ -9,7 +9,7 @@ its configuration in the database. In that case, Kong provides you with an abstraction on top of its primary datastores which allows you to store custom entities. -As explained in the [previous chapter]({{page.book.previous}}), Kong interacts +As explained in the [previous chapter]({{page.book.previous.url}}), Kong interacts with the model layer through classes we refer to as "DAOs", and available on a singleton often referred to as the "DAO Factory". This chapter will explain how to to provide an abstraction for your own entities. @@ -664,11 +664,7 @@ When a custom entity is required on every request/response it is good practice to cache it in-memory by leveraging the in-memory cache API provided by Kong. The next chapter will focus on caching custom entities, and invalidating them -when they change in the datastore: [Caching custom entities]({{page.book.next}}). - ---- - -Next: [Caching custom entities ›]({{page.book.next}}) +when they change in the datastore: [Caching custom entities]({{page.book.next.url}}). [Admin API]: /gateway/{{page.kong_version}}/admin-api/ [Plugin Development Kit]: /gateway/{{page.kong_version}}/pdk diff --git a/app/gateway/2.6.x/plugin-development/custom-logic.md b/app/gateway/2.6.x/plugin-development/custom-logic.md index 4d6ffd6ee5df..0c96854dcacd 100644 --- a/app/gateway/2.6.x/plugin-development/custom-logic.md +++ b/app/gateway/2.6.x/plugin-development/custom-logic.md @@ -61,7 +61,7 @@ All of those functions, except `init_worker`, take one parameter which is given by {{site.base_gateway}} upon its invocation: the configuration of your plugin. This parameter is a Lua table, and contains values defined by your users, according to your plugin's schema (described in the `schema.lua` module). More on plugins schemas -in the [next chapter]({{page.book.next}}). +in the [next chapter]({{page.book.next.url}}). Note that UDP streams don't have real connections. {{site.base_gateway}} will consider all packets with the same origin and destination host and port as a single @@ -374,9 +374,5 @@ post-function | -1000 {% endnavtab %} {% endnavtabs %} ---- - -Next: [Plugin configuration ›]({{page.book.next}}) - [lua-nginx-module]: https://github.com/openresty/lua-nginx-module [pdk]: /gateway/{{page.kong_version}}/pdk diff --git a/app/gateway/2.6.x/plugin-development/entities-cache.md b/app/gateway/2.6.x/plugin-development/entities-cache.md index 5b8889400d56..d6cfa0e6e265 100644 --- a/app/gateway/2.6.x/plugin-development/entities-cache.md +++ b/app/gateway/2.6.x/plugin-development/entities-cache.md @@ -5,7 +5,7 @@ chapter: 7 --- Your plugin may need to frequently access custom entities (explained in the -[previous chapter]({{page.book.previous}})) on every request and/or response. +[previous chapter]({{page.book.previous.url}})) on every request and/or response. Usually, loading them once and caching them in-memory dramatically improves the performance while making sure the datastore is not stressed with an increased load. @@ -338,11 +338,7 @@ Kong to setup their APIs and plugins. It is likely that they also need to be able to interact with the custom entities you implemented for your plugin (for example, creating and deleting API keys). The way you would do this is by extending the Admin API, which we will detail in the next chapter: -[Extending the Admin API]({{page.book.next}}). - ---- - -Next: [Extending the Admin API ›]({{page.book.next}}) +[Extending the Admin API]({{page.book.next.url}}). [Admin API]: /gateway/{{page.kong_version}}/admin-api/ [Plugin Development Kit]: /gateway/{{page.kong_version}}/pdk diff --git a/app/gateway/2.6.x/plugin-development/file-structure.md b/app/gateway/2.6.x/plugin-development/file-structure.md index 2271be481020..bbcbcf15c355 100644 --- a/app/gateway/2.6.x/plugin-development/file-structure.md +++ b/app/gateway/2.6.x/plugin-development/file-structure.md @@ -106,10 +106,6 @@ master each one of them. The [Key-Auth plugin] is an example of plugin with this file structure. See [its source code] for more details. ---- - -Next: [Write custom logic ›]({{page.book.next}}) - [api.lua]: {{page.book.chapters.admin-api}} [daos.lua]: {{page.book.chapters.custom-entities}} [handler.lua]: {{page.book.chapters.custom-logic}} diff --git a/app/gateway/2.6.x/plugin-development/index.md b/app/gateway/2.6.x/plugin-development/index.md index cef99548ecbf..8c88afdb5336 100644 --- a/app/gateway/2.6.x/plugin-development/index.md +++ b/app/gateway/2.6.x/plugin-development/index.md @@ -27,9 +27,5 @@ This guide will explore in detail the structure of plugins, what they can extend, and how to distribute and install them. For a complete reference of the PDK, see the [Plugin Development Kit] reference. ---- - -Next: [File structure of a plugin ›]({{page.book.next}}) - [lua-nginx-module]: https://github.com/openresty/lua-nginx-module [Plugin Development Kit]: /gateway/{{page.kong_version}}/pdk diff --git a/app/gateway/2.6.x/plugin-development/plugin-configuration.md b/app/gateway/2.6.x/plugin-development/plugin-configuration.md index c588855d40ad..ea947969a9e6 100644 --- a/app/gateway/2.6.x/plugin-development/plugin-configuration.md +++ b/app/gateway/2.6.x/plugin-development/plugin-configuration.md @@ -397,10 +397,6 @@ return CustomHandler You can also see a real-world example of schema in [the Key-Auth plugin source code]. ---- - -Next: [Accessing the Datastore ›]({{page.book.next}}) - [Admin API]: /gateway/{{page.kong_version}}/admin-api [Plugin Development Kit]: /gateway/{{page.kong_version}}/pdk [the Key-Auth plugin source code]: https://github.com/Kong/kong/blob/master/kong/plugins/key-auth/schema.lua diff --git a/app/gateway/2.6.x/plugin-development/tests.md b/app/gateway/2.6.x/plugin-development/tests.md index f4c3bef3f22d..f08a48f09134 100644 --- a/app/gateway/2.6.x/plugin-development/tests.md +++ b/app/gateway/2.6.x/plugin-development/tests.md @@ -12,7 +12,7 @@ might also want to write integration tests. Again, Kong has your back. ## Write integration tests The preferred testing framework for Kong is -[busted](http://olivinelabs.com/busted/) running with the +[busted](https://github.com/lunarmodules/busted/) running with the [resty-cli](https://github.com/openresty/resty-cli) interpreter, though you are free to use a different one. In the Kong repository, the busted executable can be found at `bin/busted`. @@ -100,6 +100,3 @@ and Admin API on port 9001. For a real-world example, see the [Key-Auth plugin specs](https://github.com/Kong/kong/tree/master/spec/03-plugins/09-key-auth). ---- - -Next: [Distribute your plugin ›]({{page.book.next}}) diff --git a/app/gateway/2.6.x/reference/proxy.md b/app/gateway/2.6.x/reference/proxy.md index 5a279e79eaca..bd2a9f01ea40 100644 --- a/app/gateway/2.6.x/reference/proxy.md +++ b/app/gateway/2.6.x/reference/proxy.md @@ -14,7 +14,7 @@ properties: - `admin_listen`, which also defines a list of addresses and ports, but those should be restricted to only be accessed by administrators, as they expose Kong's configuration capabilities: the **Admin API** (`8001` by default). -{% include_cached /md/admin-listen.md desc='short' %} +{% include_cached /md/admin-listen.md kong_version=page.kong_version desc='short' %} - `stream_listen`, which is similar to `proxy_listen` but for Layer 4 (TCP, TLS) generic proxy. This is turned off by default. diff --git a/app/gateway/2.6.x/vitals/vitals-influx-strategy.md b/app/gateway/2.6.x/vitals/vitals-influx-strategy.md index 243441d18eb7..d4541d7669c5 100644 --- a/app/gateway/2.6.x/vitals/vitals-influx-strategy.md +++ b/app/gateway/2.6.x/vitals/vitals-influx-strategy.md @@ -79,7 +79,7 @@ with each other. 1. Start the gateway with Kong Manager: -{% include_cached /md/admin-listen.md desc='long' %} +{% include_cached /md/admin-listen.md kong_version=page.kong_version desc='long' %}
      docker run -d --name kong-ee --network=kong-ee-net \
             -e "KONG_DATABASE=postgres" \
      diff --git a/app/gateway/2.7.x/configure/auth/kong-manager/networking.md b/app/gateway/2.7.x/configure/auth/kong-manager/networking.md
      index edf58415304f..d52f26184465 100644
      --- a/app/gateway/2.7.x/configure/auth/kong-manager/networking.md
      +++ b/app/gateway/2.7.x/configure/auth/kong-manager/networking.md
      @@ -28,7 +28,7 @@ Common configurations to enable are
         8444 on localhost. Change [`admin_listen`] if necessary, or set
         [`admin_api_uri`].
       
      -{% include_cached /md/admin-listen.md desc='short' %}
      +{% include_cached /md/admin-listen.md kong_version=page.kong_version desc='short' %}
       
       * Securing Kong Manager and serving it from a dedicated node
       
      diff --git a/app/gateway/2.7.x/configure/auth/oidc-cognito.md b/app/gateway/2.7.x/configure/auth/oidc-cognito.md
      index b2d68fbc8ac9..4fd7b48bf8b9 100644
      --- a/app/gateway/2.7.x/configure/auth/oidc-cognito.md
      +++ b/app/gateway/2.7.x/configure/auth/oidc-cognito.md
      @@ -12,28 +12,16 @@ In this configuration, we use User Pools.
       1. Log in to AWS Console.
       1. Navigate to the Amazon Cognito Service.
       
      -    
      -
       1. Click on **Manage User Pools**.
       
      -    
      -
       1. Click the **Create a user pool** button on the right-hand side.
       
      -    
      -
       1. Enter a pool name; we use “test-pool” for this example.
       
      -    
      -
       1. Click **Step Through Settings**.
       
      -    
      -
       1. Select **Email address or phone number**, and under that, select **Allow email addresses**. Select the following standard attributes as required: email, family name, given name.
       
      -    
      -
       1. Click **Next step**.
       1. Accept the defaults for **Password settings**, then click **Next step**.
       1. Accept the defaults for **MFA and verifications**, then click **Next step**.
      @@ -43,54 +31,32 @@ In this configuration, we use User Pools.
       1. We can create an application definition later. Keep things simple for now and click **Next step**.
       1. We don’t have any need for Triggers or customized Sign Up/Sign In behavior for this example. Scroll down and click **Save Changes**.
       
      -    
      -
       1. Click **Create pool**. Wait a moment for the success message.
       1. Make a note of the **Pool ID**. You will need this when configuring the application later.
       
      -    
      -
       ## Application Definition
       
       You need to add an OAuth2 application definition to the User Pool we just created.
       
       1. Go to the App clients screen in the AWS Cognito management screen for the User Pool we just created.
       
      -    
      -
       1. Click “Add an app client”.
       
      -    
      -
      -1. Enter an App client name. This demo is using “kong-api”
      -
      -    
      +1. Enter an App client name. This demo is using “kong-api”.
       
       1. Enter a Refresh token expiration (in days). We will use the default of 30 days.
       1. Do not select “Generate client secret”. This example will use a public client.
       
      -    
      -
       1. Do not select any other checkboxes.
       
      -    
      -
       1. Click the “Set attribute read and write permissions” button.
       
      -    
      -
       1. Let’s make this simple and only give the user read and write access to the required attributes. So, uncheck everything except the email, given name, and family name fields.
       
      -    
      -
      -1. Click “Create app client”
      -
      -    
      +1. Click “Create app client”.
       
       1. Click “Show Details”.
       
      -    
      -
       1. Take note of the App client ID. We will need that later.
       1. Go to the App integration -> App client settings screen.
       1. Click the “Cognito User Pool” checkbox under Enabled Identity Providers.
      @@ -103,21 +69,13 @@ You need to add an OAuth2 application definition to the User Pool we just create
           Note that AWS Cognito doesn’t support HTTP callback URLs. This field should
           include the API and Dev Portal URLs that you want to secure using AWS Cognito.
       
      -    
      -
       1. Click the “Authorization code grant” checkbox under Allowed OAuth Flows.
      -
      -    
      -
       1. Click the checkboxes next to email, OpenID, aws.cognito.signin.user.admin, and profile.
       1. Click the “Save changes” button.
       1. Click on the domain name tab.
       1. Add a sub-domain name.
       1. Click the Check Availability button.
       1. As long as it reports “This domain is available”, the name you have chosen will work.
      -
      -    
      -
       1. Click the “Save changes” button.
       
       Now that you have created an Amazon Cognito User Pool and Application Definition, we can configure the OpenID Connect plugin in Kong. We can then test integration between Dev Portal and Amazon Cognito.
      @@ -155,7 +113,7 @@ You can verify the confirmed user from the Cognito page under “General setting
       
       ## Dev Portal Integration
       
      -{% include_cached /md/admin-listen.md desc='long' %}
      +{% include_cached /md/admin-listen.md kong_version=page.kong_version desc='long' %}
       
       Since AWS Cognito only supports the HTTPS protocol, when you start {{site.base_gateway}}, ensure that HTTPS protocol for Dev Portal is enabled. For example:
       
      diff --git a/app/gateway/2.7.x/configure/network.md b/app/gateway/2.7.x/configure/network.md
      index 303331d80693..25f7e7253cff 100644
      --- a/app/gateway/2.7.x/configure/network.md
      +++ b/app/gateway/2.7.x/configure/network.md
      @@ -34,7 +34,7 @@ it from unauthorized access.
       
       * `8001` provides Kong's **Admin API** that you can use to operate Kong with HTTP. See [admin_listen].
       
      -{% include_cached /md/admin-listen.md desc='short' %}
      +{% include_cached /md/admin-listen.md kong_version=page.kong_version desc='short' %}
       
       * `8444` provides the same Kong **Admin API** but using HTTPS. See [admin_listen] and the `ssl` suffix.
       
      diff --git a/app/gateway/2.7.x/install-and-run/docker.md b/app/gateway/2.7.x/install-and-run/docker.md
      index e0f7f0d6e35a..a5c954cb568c 100644
      --- a/app/gateway/2.7.x/install-and-run/docker.md
      +++ b/app/gateway/2.7.x/install-and-run/docker.md
      @@ -128,7 +128,7 @@ kong:{{page.kong_versions[page.version-index].ce-version}}-alpine kong migration
       
       ### Start Kong Gateway
       
      -{% include_cached /md/admin-listen.md desc='long' %}
      +{% include_cached /md/admin-listen.md kong_version=page.kong_version desc='long' %}
       
       1. Run the following command to start a container with {{site.base_gateway}}:
       {% capture start_container %}
      @@ -297,7 +297,7 @@ backed up by a Redis cluster).
       
       ### Start Kong Gateway in DB-less mode
       
      -{% include_cached /md/admin-listen.md desc='long' %}
      +{% include_cached /md/admin-listen.md kong_version=page.kong_version desc='long' %}
       
       1. From the same directory where you just created the `kong.yml` file,
       run the following command to start a container with {{site.base_gateway}}:
      diff --git a/app/gateway/2.7.x/plan-and-deploy/security/start-kong-securely.md b/app/gateway/2.7.x/plan-and-deploy/security/start-kong-securely.md
      index a8394b34422e..2d109f046fb6 100644
      --- a/app/gateway/2.7.x/plan-and-deploy/security/start-kong-securely.md
      +++ b/app/gateway/2.7.x/plan-and-deploy/security/start-kong-securely.md
      @@ -32,7 +32,7 @@ of authentication.
       For a simple configuration to use for the subsequent Getting
       Started guides:
       
      -{% include_cached /md/admin-listen.md desc='long' %}
      +{% include_cached /md/admin-listen.md kong_version=page.kong_version desc='long' %}
       
       ```
       enforce_rbac = on
      diff --git a/app/gateway/2.7.x/plugin-development/access-the-datastore.md b/app/gateway/2.7.x/plugin-development/access-the-datastore.md
      index 93a6afb213b2..218ffaeeb99e 100644
      --- a/app/gateway/2.7.x/plugin-development/access-the-datastore.md
      +++ b/app/gateway/2.7.x/plugin-development/access-the-datastore.md
      @@ -66,8 +66,4 @@ local inserted_plugin, err = kong.db.plugins:insert({
       For a real-life example of the DAO being used in a plugin, see the
       [Key-Auth plugin source code](https://github.com/Kong/kong/blob/master/kong/plugins/key-auth/handler.lua).
       
      ----
      -
      -Next: [Storing Custom Entities ›]({{page.book.next}})
      -
       [Plugin Development Kit]: /gateway/{{page.kong_version}}/pdk
      diff --git a/app/gateway/2.7.x/plugin-development/admin-api.md b/app/gateway/2.7.x/plugin-development/admin-api.md
      index 936be35074a7..00a2ff967723 100644
      --- a/app/gateway/2.7.x/plugin-development/admin-api.md
      +++ b/app/gateway/2.7.x/plugin-development/admin-api.md
      @@ -95,10 +95,8 @@ return {
       ```
       
       This code will create two Admin API endpoints in `/consumers/:consumers/key-auth`, to
      -obtain (`GET`) and create (`POST`) credentials associated to a given consumer. On this example
      -the functions are provided by the `kong.api.endpoints` library. If you want to see a more
      -complete example, with custom code in functions, see
      -[the `api.lua` file from the key-auth plugin](https://github.com/Kong/kong/blob/master/kong/plugins/key-auth/api.lua).
      +obtain (`GET`) and create (`POST`) credentials associated to a given consumer. In this example,
      +the functions are provided by the `kong.api.endpoints` library.
       
       The `endpoints` module currently contains the default implementation for the most usual CRUD
       operations used in Kong. This module provides you with helpers for any insert, retrieve,
      @@ -167,8 +165,4 @@ three functions:
       - The `PUT` function populates `self.args.post.consumer` before calling the `endpoints`-provided
         `put_entity_endpoint` function.
       
      ----
      -
      -Next: [Write tests for your plugin]({{page.book.next}})
      -
       [Admin API]: /gateway/{{page.kong_version}}/admin-api/
      diff --git a/app/gateway/2.7.x/plugin-development/custom-entities.md b/app/gateway/2.7.x/plugin-development/custom-entities.md
      index 18c408acfa98..6fcdf98a7e9a 100644
      --- a/app/gateway/2.7.x/plugin-development/custom-entities.md
      +++ b/app/gateway/2.7.x/plugin-development/custom-entities.md
      @@ -9,7 +9,7 @@ its configuration in the database. In that case, Kong provides you with
       an abstraction on top of its primary datastores which allows you to store
       custom entities.
       
      -As explained in the [previous chapter]({{page.book.previous}}), Kong interacts
      +As explained in the [previous chapter]({{page.book.previous.url}}), Kong interacts
       with the model layer through classes we refer to as "DAOs", and available on a
       singleton often referred to as the "DAO Factory". This chapter will explain how
       to to provide an abstraction for your own entities.
      @@ -671,11 +671,7 @@ When a custom entity is required on every request/response it is good practice
       to cache it in-memory by leveraging the in-memory cache API provided by Kong.
       
       The next chapter will focus on caching custom entities, and invalidating them
      -when they change in the datastore: [Caching custom entities]({{page.book.next}}).
      -
      ----
      -
      -Next: [Caching custom entities ›]({{page.book.next}})
      +when they change in the datastore: [Caching custom entities]({{page.book.next.url}}).
       
       [Admin API]: /gateway/{{page.kong_version}}/admin-api/
       [Plugin Development Kit]: /gateway/{{page.kong_version}}/pdk
      diff --git a/app/gateway/2.7.x/plugin-development/custom-logic.md b/app/gateway/2.7.x/plugin-development/custom-logic.md
      index 2792da895f51..0c84362d6f3e 100644
      --- a/app/gateway/2.7.x/plugin-development/custom-logic.md
      +++ b/app/gateway/2.7.x/plugin-development/custom-logic.md
      @@ -61,7 +61,7 @@ All of those functions, except `init_worker`, take one parameter which is given
       by {{site.base_gateway}} upon its invocation: the configuration of your plugin. This parameter
       is a Lua table, and contains values defined by your users, according to your
       plugin's schema (described in the `schema.lua` module). More on plugins schemas
      -in the [next chapter]({{page.book.next}}).
      +in the [next chapter]({{page.book.next.url}}).
       
       Note that UDP streams don't have real connections.  {{site.base_gateway}} will consider all
       packets with the same origin and destination host and port as a single
      @@ -399,9 +399,5 @@ post-function               | -1000
       
       {% endnavtab %}
       {% endnavtabs %}
      ----
      -
      -Next: [Plugin configuration ›]({{page.book.next}})
      -
       [lua-nginx-module]: https://github.com/openresty/lua-nginx-module
       [pdk]: /gateway/{{page.kong_version}}/pdk
      diff --git a/app/gateway/2.7.x/plugin-development/entities-cache.md b/app/gateway/2.7.x/plugin-development/entities-cache.md
      index 5b8889400d56..d6cfa0e6e265 100644
      --- a/app/gateway/2.7.x/plugin-development/entities-cache.md
      +++ b/app/gateway/2.7.x/plugin-development/entities-cache.md
      @@ -5,7 +5,7 @@ chapter: 7
       ---
       
       Your plugin may need to frequently access custom entities (explained in the
      -[previous chapter]({{page.book.previous}})) on every request and/or response.
      +[previous chapter]({{page.book.previous.url}})) on every request and/or response.
       Usually, loading them once and caching them in-memory dramatically improves
       the performance while making sure the datastore is not stressed with an
       increased load.
      @@ -338,11 +338,7 @@ Kong to setup their APIs and plugins. It is likely that they also need to be
       able to interact with the custom entities you implemented for your plugin (for
       example, creating and deleting API keys). The way you would do this is by
       extending the Admin API, which we will detail in the next chapter:
      -[Extending the Admin API]({{page.book.next}}).
      -
      ----
      -
      -Next: [Extending the Admin API ›]({{page.book.next}})
      +[Extending the Admin API]({{page.book.next.url}}).
       
       [Admin API]: /gateway/{{page.kong_version}}/admin-api/
       [Plugin Development Kit]: /gateway/{{page.kong_version}}/pdk
      diff --git a/app/gateway/2.7.x/plugin-development/file-structure.md b/app/gateway/2.7.x/plugin-development/file-structure.md
      index 2271be481020..bbcbcf15c355 100644
      --- a/app/gateway/2.7.x/plugin-development/file-structure.md
      +++ b/app/gateway/2.7.x/plugin-development/file-structure.md
      @@ -106,10 +106,6 @@ master each one of them.
       The [Key-Auth plugin] is an example of plugin with this file structure.
       See [its source code] for more details.
       
      ----
      -
      -Next: [Write custom logic ›]({{page.book.next}})
      -
       [api.lua]: {{page.book.chapters.admin-api}}
       [daos.lua]: {{page.book.chapters.custom-entities}}
       [handler.lua]: {{page.book.chapters.custom-logic}}
      diff --git a/app/gateway/2.7.x/plugin-development/index.md b/app/gateway/2.7.x/plugin-development/index.md
      index cef99548ecbf..8c88afdb5336 100644
      --- a/app/gateway/2.7.x/plugin-development/index.md
      +++ b/app/gateway/2.7.x/plugin-development/index.md
      @@ -27,9 +27,5 @@ This guide will explore in detail the structure of plugins, what they can
       extend, and how to distribute and install them. For a complete reference of the
       PDK, see the [Plugin Development Kit] reference.
       
      ----
      -
      -Next: [File structure of a plugin ›]({{page.book.next}})
      -
       [lua-nginx-module]: https://github.com/openresty/lua-nginx-module
       [Plugin Development Kit]: /gateway/{{page.kong_version}}/pdk
      diff --git a/app/gateway/2.7.x/plugin-development/plugin-configuration.md b/app/gateway/2.7.x/plugin-development/plugin-configuration.md
      index c588855d40ad..ea947969a9e6 100644
      --- a/app/gateway/2.7.x/plugin-development/plugin-configuration.md
      +++ b/app/gateway/2.7.x/plugin-development/plugin-configuration.md
      @@ -397,10 +397,6 @@ return CustomHandler
       
       You can also see a real-world example of schema in [the Key-Auth plugin source code].
       
      ----
      -
      -Next: [Accessing the Datastore ›]({{page.book.next}})
      -
       [Admin API]: /gateway/{{page.kong_version}}/admin-api
       [Plugin Development Kit]: /gateway/{{page.kong_version}}/pdk
       [the Key-Auth plugin source code]: https://github.com/Kong/kong/blob/master/kong/plugins/key-auth/schema.lua
      diff --git a/app/gateway/2.7.x/plugin-development/tests.md b/app/gateway/2.7.x/plugin-development/tests.md
      index f4c3bef3f22d..f08a48f09134 100644
      --- a/app/gateway/2.7.x/plugin-development/tests.md
      +++ b/app/gateway/2.7.x/plugin-development/tests.md
      @@ -12,7 +12,7 @@ might also want to write integration tests. Again, Kong has your back.
       ## Write integration tests
       
       The preferred testing framework for Kong is
      -[busted](http://olivinelabs.com/busted/) running with the
      +[busted](https://github.com/lunarmodules/busted/) running with the
       [resty-cli](https://github.com/openresty/resty-cli) interpreter, though you are
       free to use a different one. In the Kong repository, the busted
       executable can be found at `bin/busted`.
      @@ -100,6 +100,3 @@ and Admin API on port 9001.
       For a real-world example, see the
       [Key-Auth plugin specs](https://github.com/Kong/kong/tree/master/spec/03-plugins/09-key-auth).
       
      ----
      -
      -Next: [Distribute your plugin ›]({{page.book.next}})
      diff --git a/app/gateway/2.7.x/reference/proxy.md b/app/gateway/2.7.x/reference/proxy.md
      index 84a0ea96fd7c..1beb13aeab55 100644
      --- a/app/gateway/2.7.x/reference/proxy.md
      +++ b/app/gateway/2.7.x/reference/proxy.md
      @@ -14,7 +14,7 @@ properties:
       - `admin_listen`, which also defines a list of addresses and ports, but those
         should be restricted to only be accessed by administrators, as they expose
         Kong's configuration capabilities: the **Admin API** (`8001` by default).
      -{% include_cached /md/admin-listen.md desc='short' %}
      +{% include_cached /md/admin-listen.md kong_version=page.kong_version desc='short' %}
       - `stream_listen`, which is similar to `proxy_listen` but for Layer 4 (TCP, TLS)
         generic proxy. This is turned off by default.
       
      diff --git a/app/gateway/2.7.x/vitals/vitals-influx-strategy.md b/app/gateway/2.7.x/vitals/vitals-influx-strategy.md
      index 727deed6fc54..4f43c3e006bd 100644
      --- a/app/gateway/2.7.x/vitals/vitals-influx-strategy.md
      +++ b/app/gateway/2.7.x/vitals/vitals-influx-strategy.md
      @@ -78,7 +78,7 @@ with each other.
       
       1. Start the gateway with Kong Manager:
       
      -{% include_cached /md/admin-listen.md desc='long' %}
      +{% include_cached /md/admin-listen.md kong_version=page.kong_version desc='long' %}
       
           
      docker run -d --name kong-ee --network=kong-ee-net \
             -e "KONG_DATABASE=postgres" \
      diff --git a/app/gateway/2.8.x/availability-stages.md b/app/gateway/2.8.x/availability-stages.md
      new file mode 100644
      index 000000000000..29c582eadfcc
      --- /dev/null
      +++ b/app/gateway/2.8.x/availability-stages.md
      @@ -0,0 +1,6 @@
      +---
      +title: Stages of software availability
      +content-type: reference
      +---
      +
      +{% include_cached /md/availability-stages.md %}
      diff --git a/app/gateway/2.8.x/configure/auth/kong-manager/networking.md b/app/gateway/2.8.x/configure/auth/kong-manager/networking.md
      index edf58415304f..d52f26184465 100644
      --- a/app/gateway/2.8.x/configure/auth/kong-manager/networking.md
      +++ b/app/gateway/2.8.x/configure/auth/kong-manager/networking.md
      @@ -28,7 +28,7 @@ Common configurations to enable are
         8444 on localhost. Change [`admin_listen`] if necessary, or set
         [`admin_api_uri`].
       
      -{% include_cached /md/admin-listen.md desc='short' %}
      +{% include_cached /md/admin-listen.md kong_version=page.kong_version desc='short' %}
       
       * Securing Kong Manager and serving it from a dedicated node
       
      diff --git a/app/gateway/2.8.x/configure/auth/oidc-cognito.md b/app/gateway/2.8.x/configure/auth/oidc-cognito.md
      index b2d68fbc8ac9..4fd7b48bf8b9 100644
      --- a/app/gateway/2.8.x/configure/auth/oidc-cognito.md
      +++ b/app/gateway/2.8.x/configure/auth/oidc-cognito.md
      @@ -12,28 +12,16 @@ In this configuration, we use User Pools.
       1. Log in to AWS Console.
       1. Navigate to the Amazon Cognito Service.
       
      -    
      -
       1. Click on **Manage User Pools**.
       
      -    
      -
       1. Click the **Create a user pool** button on the right-hand side.
       
      -    
      -
       1. Enter a pool name; we use “test-pool” for this example.
       
      -    
      -
       1. Click **Step Through Settings**.
       
      -    
      -
       1. Select **Email address or phone number**, and under that, select **Allow email addresses**. Select the following standard attributes as required: email, family name, given name.
       
      -    
      -
       1. Click **Next step**.
       1. Accept the defaults for **Password settings**, then click **Next step**.
       1. Accept the defaults for **MFA and verifications**, then click **Next step**.
      @@ -43,54 +31,32 @@ In this configuration, we use User Pools.
       1. We can create an application definition later. Keep things simple for now and click **Next step**.
       1. We don’t have any need for Triggers or customized Sign Up/Sign In behavior for this example. Scroll down and click **Save Changes**.
       
      -    
      -
       1. Click **Create pool**. Wait a moment for the success message.
       1. Make a note of the **Pool ID**. You will need this when configuring the application later.
       
      -    
      -
       ## Application Definition
       
       You need to add an OAuth2 application definition to the User Pool we just created.
       
       1. Go to the App clients screen in the AWS Cognito management screen for the User Pool we just created.
       
      -    
      -
       1. Click “Add an app client”.
       
      -    
      -
      -1. Enter an App client name. This demo is using “kong-api”
      -
      -    
      +1. Enter an App client name. This demo is using “kong-api”.
       
       1. Enter a Refresh token expiration (in days). We will use the default of 30 days.
       1. Do not select “Generate client secret”. This example will use a public client.
       
      -    
      -
       1. Do not select any other checkboxes.
       
      -    
      -
       1. Click the “Set attribute read and write permissions” button.
       
      -    
      -
       1. Let’s make this simple and only give the user read and write access to the required attributes. So, uncheck everything except the email, given name, and family name fields.
       
      -    
      -
      -1. Click “Create app client”
      -
      -    
      +1. Click “Create app client”.
       
       1. Click “Show Details”.
       
      -    
      -
       1. Take note of the App client ID. We will need that later.
       1. Go to the App integration -> App client settings screen.
       1. Click the “Cognito User Pool” checkbox under Enabled Identity Providers.
      @@ -103,21 +69,13 @@ You need to add an OAuth2 application definition to the User Pool we just create
           Note that AWS Cognito doesn’t support HTTP callback URLs. This field should
           include the API and Dev Portal URLs that you want to secure using AWS Cognito.
       
      -    
      -
       1. Click the “Authorization code grant” checkbox under Allowed OAuth Flows.
      -
      -    
      -
       1. Click the checkboxes next to email, OpenID, aws.cognito.signin.user.admin, and profile.
       1. Click the “Save changes” button.
       1. Click on the domain name tab.
       1. Add a sub-domain name.
       1. Click the Check Availability button.
       1. As long as it reports “This domain is available”, the name you have chosen will work.
      -
      -    
      -
       1. Click the “Save changes” button.
       
       Now that you have created an Amazon Cognito User Pool and Application Definition, we can configure the OpenID Connect plugin in Kong. We can then test integration between Dev Portal and Amazon Cognito.
      @@ -155,7 +113,7 @@ You can verify the confirmed user from the Cognito page under “General setting
       
       ## Dev Portal Integration
       
      -{% include_cached /md/admin-listen.md desc='long' %}
      +{% include_cached /md/admin-listen.md kong_version=page.kong_version desc='long' %}
       
       Since AWS Cognito only supports the HTTPS protocol, when you start {{site.base_gateway}}, ensure that HTTPS protocol for Dev Portal is enabled. For example:
       
      diff --git a/app/gateway/2.8.x/configure/network.md b/app/gateway/2.8.x/configure/network.md
      index 303331d80693..25f7e7253cff 100644
      --- a/app/gateway/2.8.x/configure/network.md
      +++ b/app/gateway/2.8.x/configure/network.md
      @@ -34,7 +34,7 @@ it from unauthorized access.
       
       * `8001` provides Kong's **Admin API** that you can use to operate Kong with HTTP. See [admin_listen].
       
      -{% include_cached /md/admin-listen.md desc='short' %}
      +{% include_cached /md/admin-listen.md kong_version=page.kong_version desc='short' %}
       
       * `8444` provides the same Kong **Admin API** but using HTTPS. See [admin_listen] and the `ssl` suffix.
       
      diff --git a/app/gateway/2.8.x/index.md b/app/gateway/2.8.x/index.md
      index 715ae77ad81f..45ac34604006 100644
      --- a/app/gateway/2.8.x/index.md
      +++ b/app/gateway/2.8.x/index.md
      @@ -174,4 +174,4 @@ Kong primarily follows a [semantic versioning](https://semver.org/) (SemVer)
       model for its products.
       
       For the latest version support information for {{site.ee_product_name}} and
      -{{site.mesh_product_name}}, see our [version support policy](/konnect-platform/support-policy).
      +{{site.mesh_product_name}}, see our [version support policy](/gateway/{{page.kong_version}}/support-policy).
      diff --git a/app/gateway/2.8.x/install-and-run/debian.md b/app/gateway/2.8.x/install-and-run/debian.md
      index a878d979f71c..cb88972702e2 100644
      --- a/app/gateway/2.8.x/install-and-run/debian.md
      +++ b/app/gateway/2.8.x/install-and-run/debian.md
      @@ -95,6 +95,17 @@ apt install -y kong={{page.kong_versions[page.version-index].ce-version}}
       
       {{ install_from_repo | indent | replace: " ", "" }}
       
      +{% navtabs_ee %}
      +{% navtab Kong Gateway %}
      +{:.note .no-icon}
      +> Once {{ site.base_gateway }} is installed, you may want to run `sudo apt-mark hold kong-enterprise-edition`. This will prevent an accidental upgrade to a new version.
      +{% endnavtab %}
      +{% navtab Kong Gateway (OSS) %}
      +{:.note .no-icon}
      +> Once {{ site.base_gateway }} is installed, you may want to run `sudo apt-mark hold kong`. This will prevent an accidental upgrade to a new version.
      +{% endnavtab %}
      +{% endnavtabs_ee %}
      +
       {% endnavtab %}
       {% endnavtabs %}
       
      diff --git a/app/gateway/2.8.x/install-and-run/docker.md b/app/gateway/2.8.x/install-and-run/docker.md
      index ee00eb88aa44..5090d3ae8016 100644
      --- a/app/gateway/2.8.x/install-and-run/docker.md
      +++ b/app/gateway/2.8.x/install-and-run/docker.md
      @@ -118,7 +118,7 @@ kong:{{page.kong_versions[page.version-index].ce-version}}-alpine kong migration
       
       ### Start Kong Gateway
       
      -{% include_cached /md/admin-listen.md desc='long' %}
      +{% include_cached /md/admin-listen.md kong_version=page.kong_version desc='long' %}
       
       1. (Optional) If you have an Enterprise license for {{site.base_gateway}},
       export the license key to a variable:
      @@ -305,7 +305,7 @@ backed up by a Redis cluster).
       
       ### Start Kong Gateway in DB-less mode
       
      -{% include_cached /md/admin-listen.md desc='long' %}
      +{% include_cached /md/admin-listen.md kong_version=page.kong_version desc='long' %}
       
       1. (Optional) If you have an Enterprise license for {{site.base_gateway}},
       export the license key to a variable:
      diff --git a/app/gateway/2.8.x/install-and-run/helm-quickstart-enterprise.md b/app/gateway/2.8.x/install-and-run/helm-quickstart-enterprise.md
      new file mode 100644
      index 000000000000..ada26d7abc86
      --- /dev/null
      +++ b/app/gateway/2.8.x/install-and-run/helm-quickstart-enterprise.md
      @@ -0,0 +1,428 @@
      +---
      +title: Install with Kong Gateway using Helm
      +toc: true
      +content-type: how-to
      +---
      +
      +
      +This guide will show you how to install {{site.base_gateway}} on Kubernetes with Helm. Two options are provided for deploying a local development environment using [Docker Desktop Kubernetes](https://docs.docker.com/desktop/kubernetes/) and [Kind Kubernetes](https://kind.sigs.k8s.io/). You can also follow this guide using an existing cloud hosted Kubernetes cluster. 
      +
      +
      +{% navtabs %}
      +{% navtab Docker Desktop Kubernetes %}
      +## Docker Desktop
      +
      +Docker Desktop Kubernetes is a tool for running a local Kubernetes cluster using Docker. These instructions will guide you through deploying {{site.base_gateway}} to a local Docker Desktop Kubernetes cluster.
      +
      +## Dependencies
      +
      +- [`Helm 3`](https://helm.sh/)
      +- [`kubectl`](https://kubernetes.io/docs/tasks/tools/) v1.19 or later
      +- [Docker Desktop Kubernetes](https://docs.docker.com/desktop/kubernetes/)
      +
      +{:.note}
      +> Kong services will be published to localhost at the domain name `https://kong.127-0-0-1.nip.io`. The [nip.io](https://nip.io) service is used to automatically resolve this domain to the localhost address. 
      +
      +## Configure Kubectl
      +
      +Set your kubeconfig context and verify with the following command:
      +
      +    kubectl config use-context docker-desktop && kubectl cluster-info
      +
      +
      +{% endnavtab %}
      +{% navtab Kind Kubernetes %}
      +
      +## Kind Kubernetes
      +
      +Kind or "Kubernetes-in-Docker", is a tool for running local Kubernetes clusters in Docker containers. These instructions will guide you through deploying {{site.base_gateway}} to a local Kind Kubernetes cluster.
      +
      +
      +## Dependencies
      +
      +- [`Helm 3`](https://helm.sh/)
      +- [`kubectl`](https://kubernetes.io/docs/tasks/tools/) v1.19 or later
      +- [KinD](https://kind.sigs.k8s.io/)
      +
      +{:.note}
      +> Kong services will be published to localhost at the domain name `https://kong.127-0-0-1.nip.io`. The [nip.io](https://nip.io) service is used to automatically resolve this domain to the localhost address. 
      +
      +## Create Kubernetes Cluster
      +
      +A Kind config file is required to build a local cluster listening locally on ports `80` and `443`. Starting from the `bash` command, and ending with the `EOF"` line, highlight and copy this text block, then paste it into your terminal.
      +
      +    bash -c "cat < /tmp/kind-config.yaml && kind create cluster --config /tmp/kind-config.yaml
      +    apiVersion: kind.x-k8s.io/v1alpha4
      +    kind: Cluster
      +    name: kong
      +    networking:
      +      apiServerAddress: "0.0.0.0"
      +      apiServerPort: 16443
      +    nodes:
      +      - role: control-plane
      +        extraPortMappings:
      +        - listenAddress: "0.0.0.0"
      +          protocol: TCP
      +          hostPort: 80
      +          containerPort: 80
      +        - listenAddress: "0.0.0.0"
      +          protocol: TCP
      +          hostPort: 443
      +          containerPort: 443
      +    EOF"
      +
      +Set your kubeconfig context and verify with the following commands.
      +
      +    kubectl config use-context kind-kong && kubectl cluster-info
      +
      +{% endnavtab %}
      +{% navtab Kubernetes in the Cloud%}
      +
      +## Kubernetes in the cloud
      +
      +These instructions will guide you through deploying {{site.base_gateway}} to a cloud hosted Kubernetes cluster you have already built. Please ensure your local system and your Kubernetes cluster meet the dependency criteria listed below before continuing.
      +
      +{:.note}
      +> Please note that it is recommended to first try the Docker Desktop or Kind Kubernetes local deploys before proceeding to build on a cloud hosted kubernetes cluster.
      +
      +## Dependencies
      +
      +- [`Helm 3`](https://helm.sh/)
      +- [`kubectl`](https://kubernetes.io/docs/tasks/tools/) v1.19 or later
      +- Domain Name
      +- DNS configured with your DNS Provider
      +- Public Cloud hosted Kubernetes cluster
      +- [Cloud load balancer support](https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/)
      +
      +## Configure Kubectl
      +
      +Verify your kubeconfig context is set correctly with the following command.
      +
      +    kubectl cluster-info
      +
      +## Prepare the Helm chart 
      +
      +To inject your custom domain name into the Helm values file configure the {{site.base_gateway}} deployment with:
      +
      +1. `curl` the example values.yaml file.
      +
      +       curl -o ~/quickstart.yaml -L https://bit.ly/KongGatewayHelmValuesAIO
      +
      +2. Replace `example.com` with your preferred domain name and export as a variable.
      +
      +       export BASE_DOMAIN="example.com"
      +
      +3. Replace the `127-0-0-1.nip.io` base domain in the values file with your preferred domain name.
      +
      +       sed -i "s/127-0-0-1\.nip\.io/$BASE_DOMAIN/g" ~/quickstart.yaml
      +
      +{% endnavtab %}
      +{% endnavtabs %}
      +
      +## Create {{site.base_gateway}} secrets
      +
      +Configuring {{site.base_gateway}} requires a namespace and configuration secrets. The secrets contain Kong's enterprise license, admin password, session configurations, and PostgreSQL connection details.
      +
      +1. Create the Kong namespace for {{site.base_gateway}}:
      +
      +       kubectl create namespace kong
      +
      +2. Create Kong config and credential variables:
      +
      +       kubectl create secret generic kong-config-secret -n kong \
      +           --from-literal=portal_session_conf='{"storage":"kong","secret":"super_secret_salt_string","cookie_name":"portal_session","cookie_samesite":"off","cookie_secure":false}' \
      +           --from-literal=admin_gui_session_conf='{"storage":"kong","secret":"super_secret_salt_string","cookie_name":"admin_session","cookie_samesite":"off","cookie_secure":false}' \
      +           --from-literal=pg_host="enterprise-postgresql.kong.svc.cluster.local" \
      +           --from-literal=kong_admin_password=kong \
      +           --from-literal=password=kong
      +
      +4. Create a Kong Enterprise license secret:
      +
      +{% navtabs %}
      +{% navtab Kong Enterprise Free Mode%}
      +
      +    kubectl create secret generic kong-enterprise-license --from-literal=license="'{}'" -n kong --dry-run=client -o yaml | kubectl apply -f -
      +
      +{% endnavtab %}
      +{% navtab Kong Enterprise licensed Mode%}
      +
      +   >This command must be run in the directory that contains your `license.json` file.
      +
      +    kubectl create secret generic kong-enterprise-license --from-file=license=license.json -n kong --dry-run=client -o yaml | kubectl apply -f -
      +
      +{% endnavtab %}
      +{% endnavtabs %}
      +
      +{:.note}
      +> Kong can run in two license modes, Enterprise Licensed, or Enterprise Free. If you would like to run all enterprise features, please contact your account manager to request a `license.json` file.
      +
      +## Install Cert Manager
      +
      +Cert Manager provides automation for generating SSL certificates. {{site.base_gateway}} uses Cert Manager to provide the required certificates.
      +
      +
      +
      +Install Cert Manager and create a basic [SelfSigned](https://cert-manager.io/docs/configuration/selfsigned/) certificate issuer:
      +
      +1. Add the Jetstack Cert Manager Helm repository:
      +
      +       helm repo add jetstack https://charts.jetstack.io ; helm repo update
      +
      +2. Install Cert Manager:
      +
      +       helm upgrade --install cert-manager jetstack/cert-manager \
      +           --set installCRDs=true --namespace cert-manager --create-namespace
      +
      +3. Create a SelfSigned certificate issuer:
      +
      +       bash -c "cat < You will receive a "Your Connection is not Private" warning message due to using selfsigned certs. If you are using Chrome there may not be an "Accept risk and continue" option, to continue type `thisisunsafe` while the tab is in focus to continue.
      +
      +5. If running {{site.base_gateway}} in Licensed Mode, use the Super Admin username with the password set in the secret `kong-config-secret` created earlier: `kong_admin`:`kong`
      +
      +{% endnavtab %}
      +{% navtab Kind Kubernetes %}
      +
      +Once all dependencies are installed and ready, deploy {{site.base_gateway}} to your cluster:
      +
      +1. Add the Kong Helm repo:
      +
      +       helm repo add kong https://charts.konghq.com ; helm repo update
      +
      +2. Install Kong:
      +
      +       helm install quickstart kong/kong --namespace kong --values https://bit.ly/KongGatewayHelmValuesAIO
      +
      +3. Wait for all pods to be in the `Running` state:
      +
      +       kubectl get po --namespace kong -w
      +
      +4. Once all the pods are running, open Kong Manager in your browser at its ingress host domain, for example: [https://kong.127-0-0-1.nip.io](https://kong.127-0-0-1.nip.io). Or open it with the following command:
      +
      +       open "https://$(kubectl get ingress --namespace kong quickstart-kong-manager -o jsonpath='{.spec.tls[0].hosts[0]}')"
      +
      +    {:.important}
      +    > You will receive a "Your Connection is not Private" warning message due to using selfsigned certs. If you are using Chrome there may not be an "Accept risk and continue" option, to continue type `thisisunsafe` while the tab is in focus to continue.
      +
      +5. If running {{site.base_gateway}} in Licensed Mode, use the Super Admin username with the password set in the secret `kong-config-secret` created earlier: `kong_admin`:`kong`
      +
      +{% endnavtab %}
      +{% navtab Kubernetes in the Cloud%}
      +
      +Once all dependencies are installed and ready, deploy {{site.base_gateway}} to your cluster:
      +
      +1. Add the Kong Helm repo:
      +
      +       helm repo add kong https://charts.konghq.com ; helm repo update
      +
      +2. Install Kong:
      +
      +       helm install quickstart kong/kong --namespace kong --values ~/quickstart.yaml
      +
      +3. Wait for all pods to be in the `Running` state:
      +
      +       kubectl get po --namespace kong -w
      +
      +4. Once all pods are running, find the cloud load balancer of your {{site.base_gateway}} data plane:
      +
      +       kubectl get svc --namespace kong quickstart-kong-proxy -w
      +
      +5. Using your DNS Provider, configure a DNS entry to point to the load balancer shown by the last step. A wildcard DNS record is recommended for development environments.
      +
      +6. Open Kong Manager with the kong subdomain on your domain. For example: `https://kong.example.com`, or open it with the following command:
      +
      +       open "https://$(kubectl get ingress --namespace kong quickstart-kong-manager -o jsonpath='{.spec.tls[0].hosts[0]}')"
      +
      +    {:.important}
      +    > You will receive a "Your Connection is not Private" warning message due to using selfsigned certs. If you are using Chrome there may not be an "Accept risk and continue" option, to continue type `thisisunsafe` while the tab is in focus to continue.
      +
      +7. If running {{site.base_gateway}} in Licensed Mode, use the Super Admin username with the password set in the secret `kong-config-secret` created earlier: `kong_admin`:`kong`
      +
      +{% endnavtab %}
      +{% endnavtabs %}
      +
      +## Use {{site.base_gateway}}
      +
      +{{site.base_gateway}} is now be serving the Kong Manager WebGUI and the Kong Admin API.
      +
      +For local deployments, Kong Manager is locally accessible at `https://kong.127-0-0-1.nip.io`. The [nip.io](https://nip.io) service resolves this domain to localhost also known as `127.0.0.1`.
      +
      +You can configure Kong via the Admin API with [decK](https://docs.konghq.com/deck/latest/), [Insomnia](https://docs.insomnia.rest/insomnia/get-started), HTTPie, or cURL, at `https://kong.127-0-0-1.nip.io/api`:
      +
      +{% navtabs codeblock %}
      +{% navtab cURL %}
      +
      +    curl --silent --insecure -X GET https://kong.127-0-0-1.nip.io/api -H 'kong-admin-token:kong'
      +
      +{% endnavtab %}
      +{% navtab HTTPie %}
      +
      +    http --verify=no get https://kong.127-0-0-1.nip.io/api kong-admin-token:kong
      +
      +{% endnavtab %}
      +{% endnavtabs %}
      +
      +## Teardown 
      +
      +{% navtabs %}
      +{% navtab Docker Desktop Kubernetes %}
      +
      +To remove {{site.base_gateway}} from your system, follow these instructions:
      +
      +1. Remove Kong
      +
      +       helm uninstall --namespace kong quickstart
      +
      +2. Delete Kong secrets 
      +
      +       kubectl delete secrets -nkong kong-enterprise-license
      +       kubectl delete secrets -nkong kong-config-secret
      +
      +3. Remove Kong database PVC
      +
      +       kubectl delete pvc -n kong data-quickstart-postgresql-0
      +
      +4. Remove Kong Helm chart repository
      +  
      +       helm repo remove kong
      +
      +5. Remove cert-manager
      +  
      +       helm uninstall --namespace cert-manager cert-manager
      +
      +6. Remove jetstack cert-manager Helm repository
      +
      +       helm repo remove jetstack
      +
      +{% endnavtab %}
      +{% navtab Kind Kubernetes %}
      +
      +To remove {{site.base_gateway}} from your system, follow these instructions:
      +
      +1. Remove Kong
      +
      +       helm uninstall --namespace kong quickstart
      +
      +2. Delete Kong secrets
      +
      +       kubectl delete secrets -nkong kong-enterprise-license
      +       kubectl delete secrets -nkong kong-config-secret
      +
      +3. Remove Kong database PVC
      +
      +       kubectl delete pvc -n kong data-quickstart-postgresql-0
      +
      +4. Remove Kong Helm chart repository
      +  
      +       helm repo remove kong
      +
      +5. Remove cert-manager
      +  
      +       helm uninstall --namespace cert-manager cert-manager
      +
      +6. Remove jetstack cert-manager Helm repository
      +
      +       helm repo remove jetstack
      +
      +7. Destroy the Kind cluster
      +  
      +       kind delete cluster --name=kong
      +       rm /tmp/kind-config.yaml 
      +
      +{% endnavtab %}
      +{% navtab Kubernetes in the Cloud%}
      +
      +To remove {{site.base_gateway}} from your system, follow these instructions:
      +
      +1. Remove Kong
      +
      +       helm uninstall --namespace kong quickstart
      +
      +2. Delete Kong secrets
      +
      +       kubectl delete secrets -nkong kong-enterprise-license
      +       kubectl delete secrets -nkong kong-config-secret
      +
      +3. Remove Kong database PVC
      +
      +       kubectl delete pvc -n kong data-quickstart-postgresql-0
      +
      +4. Remove Kong Helm chart repository
      +  
      +       helm repo remove kong
      +
      +5. Remove cert-manager
      +  
      +       helm uninstall --namespace cert-manager cert-manager
      +
      +6. Remove jetstack cert-manager Helm Repository
      +
      +       helm repo remove jetstack
      +
      +{% endnavtab %}
      +{% endnavtabs %}
      +
      +## Next Steps
      +
      +See the [Kong Ingress Controller docs](/kubernetes-ingress-controller/) for  how-to guides, reference guides, and more.
      diff --git a/app/gateway/2.8.x/install-and-run/ubuntu.md b/app/gateway/2.8.x/install-and-run/ubuntu.md
      index 97e20f52168e..f3f4a4263867 100644
      --- a/app/gateway/2.8.x/install-and-run/ubuntu.md
      +++ b/app/gateway/2.8.x/install-and-run/ubuntu.md
      @@ -14,10 +14,10 @@ Kong is licensed under an
       
       ## Download and install
       
      -You can install {{site.base_gateway}} by downloading an installation package or using our APT repository. We currently package Kong Gateway for Ubuntu Bionic, Focal, and Xenial. 
      +You can install {{site.base_gateway}} by downloading an installation package or using our APT repository. We currently package {{ site.base_gateway }} for Ubuntu Bionic, Focal, and Xenial.
       
       {:.note .no-icon}
      -> We currently package Kong Gateway for Ubuntu Bionic, Focal and Xenial.
      +> We currently package {{ site.base_gateway }} for Ubuntu Bionic, Focal and Xenial.
       > If you are using a different release, replace `$(lsb_release -sc)` with `xenial` in the commands below.
       > 

      > To check your release name run `lsb_release -sc`. @@ -90,17 +90,31 @@ Install the APT repository from the command line. ```bash sudo apt install -y kong-enterprise-edition={{page.kong_versions[page.version-index].ee-version}} ``` + {% endnavtab %} {% navtab Kong Gateway (OSS) %} ```bash -apt install -y kong={{page.kong_versions[page.version-index].ce-version}} +sudo apt install -y kong={{page.kong_versions[page.version-index].ce-version}} ``` + + {% endnavtab %} {% endnavtabs_ee %} {% endcapture %} {{ install_from_repo | indent | replace: " ", "" }} +{% navtabs_ee %} +{% navtab Kong Gateway %} +{:.note .no-icon} +> Once {{ site.base_gateway }} is installed, you may want to run `sudo apt-mark hold kong-enterprise-edition`. This will prevent an accidental upgrade to a new version. +{% endnavtab %} +{% navtab Kong Gateway (OSS) %} +{:.note .no-icon} +> Once {{ site.base_gateway }} is installed, you may want to run `sudo apt-mark hold kong`. This will prevent an accidental upgrade to a new version. +{% endnavtab %} +{% endnavtabs_ee %} + {% endnavtab %} {% endnavtabs %} diff --git a/app/gateway/2.8.x/plan-and-deploy/security/secrets-management/backends/aws-sm.md b/app/gateway/2.8.x/plan-and-deploy/security/secrets-management/backends/aws-sm.md index 7a60ccf8d08e..5b6291d9723c 100644 --- a/app/gateway/2.8.x/plan-and-deploy/security/secrets-management/backends/aws-sm.md +++ b/app/gateway/2.8.x/plan-and-deploy/security/secrets-management/backends/aws-sm.md @@ -96,8 +96,8 @@ environment variable. You can create multiple entities, which lets you have secrets in different regions: ```bash -http -f PUT :8001/vaults/aws-eu-central-vault name=aws config.region="eu-central-1" -http -f PUT :8001/vaults/aws-us-west-vault name=aws config.region="us-west-1" +curl -X PUT http://HOSTNAME:8001/vaults/aws-eu-central-vault -d name=aws -d config.region="eu-central-1" +curl -X PUT http://HOSTNAME:8001/vaults/aws-us-west-vault -d name=aws -d config.region="us-west-1" ``` This lets you source secrets from different regions: diff --git a/app/gateway/2.8.x/plan-and-deploy/security/secrets-management/getting-started.md b/app/gateway/2.8.x/plan-and-deploy/security/secrets-management/getting-started.md index b9f60691b75e..4110a7737d4c 100644 --- a/app/gateway/2.8.x/plan-and-deploy/security/secrets-management/getting-started.md +++ b/app/gateway/2.8.x/plan-and-deploy/security/secrets-management/getting-started.md @@ -2,20 +2,23 @@ title: Get Started with Secrets Management --- -Secrets are generally confidential values that should not appear in plain text in the application. There are several products that help you -store, retrieve, and rotate these secrets securely. {{site.base_gateway}} offers a mechanism to set up references to these secrets which makes your {{site.base_gateway}} -installation more secure. +This feature is currently in beta state and isn't fully supported. APIs are subject to change. + + +Secrets are generally confidential values that should not appear in plain text in the application. +There are several products that help you store, retrieve, and rotate these secrets securely. +{{site.base_gateway}} offers a mechanism to set up references to these secrets which makes your {{site.base_gateway}} installation more secure. ## Getting started {:.note} > When running {{site.base_gateway}} in hybrid or DB-less mode, secrets management is only supported in {{site.base_gateway}} 2.8.1.3 or later. -The following example uses the most basic form of secrets management: storing secrets in environment variables. In this example, you will replace a plaintext password to your Postgres database with a reference to an environment variable. +The following example uses the most basic form of secrets management: storing secrets in environment variables. In this example, you will replace a plaintext password to your PostgreSQL database with a reference to an environment variable. You can also store secrets in a secure vault backend. For a list of supported vault backend implementations, see the [Backends Overview](/gateway/{{page.kong_version}}/plan-and-deploy/security/secrets-management/backends). -In this example we'll replace our plaintext password to our Postgres database with a reference. To do so, please define your environment variable and assign a secret value to it. +In this example we'll replace our plaintext password to our PostgreSQL database with a reference. To do so, please define your environment variable and assign a secret value to it. ### Define a reference diff --git a/app/gateway/2.8.x/plan-and-deploy/security/start-kong-securely.md b/app/gateway/2.8.x/plan-and-deploy/security/start-kong-securely.md index a8394b34422e..2d109f046fb6 100644 --- a/app/gateway/2.8.x/plan-and-deploy/security/start-kong-securely.md +++ b/app/gateway/2.8.x/plan-and-deploy/security/start-kong-securely.md @@ -32,7 +32,7 @@ of authentication. For a simple configuration to use for the subsequent Getting Started guides: -{% include_cached /md/admin-listen.md desc='long' %} +{% include_cached /md/admin-listen.md kong_version=page.kong_version desc='long' %} ``` enforce_rbac = on diff --git a/app/gateway/2.8.x/plugin-development/access-the-datastore.md b/app/gateway/2.8.x/plugin-development/access-the-datastore.md index 93a6afb213b2..218ffaeeb99e 100644 --- a/app/gateway/2.8.x/plugin-development/access-the-datastore.md +++ b/app/gateway/2.8.x/plugin-development/access-the-datastore.md @@ -66,8 +66,4 @@ local inserted_plugin, err = kong.db.plugins:insert({ For a real-life example of the DAO being used in a plugin, see the [Key-Auth plugin source code](https://github.com/Kong/kong/blob/master/kong/plugins/key-auth/handler.lua). ---- - -Next: [Storing Custom Entities ›]({{page.book.next}}) - [Plugin Development Kit]: /gateway/{{page.kong_version}}/pdk diff --git a/app/gateway/2.8.x/plugin-development/admin-api.md b/app/gateway/2.8.x/plugin-development/admin-api.md index c90957657a64..8609796034b5 100644 --- a/app/gateway/2.8.x/plugin-development/admin-api.md +++ b/app/gateway/2.8.x/plugin-development/admin-api.md @@ -165,8 +165,4 @@ three functions: - The `PUT` function populates `self.args.post.consumer` before calling the `endpoints`-provided `put_entity_endpoint` function. ---- - -Next: [Write tests for your plugin]({{page.book.next}}) - [Admin API]: /gateway/{{page.kong_version}}/admin-api/ diff --git a/app/gateway/2.8.x/plugin-development/custom-entities.md b/app/gateway/2.8.x/plugin-development/custom-entities.md index 7496ed880b85..fed0cab986b8 100644 --- a/app/gateway/2.8.x/plugin-development/custom-entities.md +++ b/app/gateway/2.8.x/plugin-development/custom-entities.md @@ -9,7 +9,7 @@ its configuration in the database. In that case, Kong provides you with an abstraction on top of its primary data stores, which allows you to store custom entities. -As explained in the [previous chapter]({{page.book.previous}}), Kong interacts +As explained in the [previous chapter]({{page.book.previous.url}}), Kong interacts with the model layer through classes we refer to as "DAOs", and available on a singleton often referred to as the "DAO Factory". This chapter will explain how to provide an abstraction for your own entities. @@ -671,11 +671,7 @@ When a custom entity is required on every request/response it is good practice to cache it in-memory by leveraging the in-memory cache API provided by Kong. The next chapter will focus on caching custom entities, and invalidating them -when they change in the data store: [Caching custom entities]({{page.book.next}}). - ---- - -Next: [Caching custom entities ›]({{page.book.next}}) +when they change in the data store: [Caching custom entities]({{page.book.next.url}}). [Admin API]: /gateway/{{page.kong_version}}/admin-api/ [Plugin Development Kit]: /gateway/{{page.kong_version}}/pdk diff --git a/app/gateway/2.8.x/plugin-development/custom-logic.md b/app/gateway/2.8.x/plugin-development/custom-logic.md index 2792da895f51..0c84362d6f3e 100644 --- a/app/gateway/2.8.x/plugin-development/custom-logic.md +++ b/app/gateway/2.8.x/plugin-development/custom-logic.md @@ -61,7 +61,7 @@ All of those functions, except `init_worker`, take one parameter which is given by {{site.base_gateway}} upon its invocation: the configuration of your plugin. This parameter is a Lua table, and contains values defined by your users, according to your plugin's schema (described in the `schema.lua` module). More on plugins schemas -in the [next chapter]({{page.book.next}}). +in the [next chapter]({{page.book.next.url}}). Note that UDP streams don't have real connections. {{site.base_gateway}} will consider all packets with the same origin and destination host and port as a single @@ -399,9 +399,5 @@ post-function | -1000 {% endnavtab %} {% endnavtabs %} ---- - -Next: [Plugin configuration ›]({{page.book.next}}) - [lua-nginx-module]: https://github.com/openresty/lua-nginx-module [pdk]: /gateway/{{page.kong_version}}/pdk diff --git a/app/gateway/2.8.x/plugin-development/entities-cache.md b/app/gateway/2.8.x/plugin-development/entities-cache.md index 000e20f2ef28..b74df67e7e37 100644 --- a/app/gateway/2.8.x/plugin-development/entities-cache.md +++ b/app/gateway/2.8.x/plugin-development/entities-cache.md @@ -5,7 +5,7 @@ chapter: 7 --- Your plugin may need to frequently access custom entities (explained in the -[previous chapter]({{page.book.previous}})) on every request and/or response. +[previous chapter]({{page.book.previous.url}})) on every request and/or response. Usually, loading them once and caching them in-memory dramatically improves the performance while making sure the data store is not stressed with an increased load. @@ -338,11 +338,7 @@ Kong to setup their APIs and plugins. It is likely that they also need to be able to interact with the custom entities you implemented for your plugin (for example, creating and deleting API keys). The way you would do this is by extending the Admin API, which we will detail in the next chapter: -[Extending the Admin API]({{page.book.next}}). - ---- - -Next: [Extending the Admin API ›]({{page.book.next}}) +[Extending the Admin API]({{page.book.next.url}}). [Admin API]: /gateway/{{page.kong_version}}/admin-api/ [Plugin Development Kit]: /gateway/{{page.kong_version}}/pdk diff --git a/app/gateway/2.8.x/plugin-development/file-structure.md b/app/gateway/2.8.x/plugin-development/file-structure.md index 2271be481020..bbcbcf15c355 100644 --- a/app/gateway/2.8.x/plugin-development/file-structure.md +++ b/app/gateway/2.8.x/plugin-development/file-structure.md @@ -106,10 +106,6 @@ master each one of them. The [Key-Auth plugin] is an example of plugin with this file structure. See [its source code] for more details. ---- - -Next: [Write custom logic ›]({{page.book.next}}) - [api.lua]: {{page.book.chapters.admin-api}} [daos.lua]: {{page.book.chapters.custom-entities}} [handler.lua]: {{page.book.chapters.custom-logic}} diff --git a/app/gateway/2.8.x/plugin-development/index.md b/app/gateway/2.8.x/plugin-development/index.md index cef99548ecbf..8c88afdb5336 100644 --- a/app/gateway/2.8.x/plugin-development/index.md +++ b/app/gateway/2.8.x/plugin-development/index.md @@ -27,9 +27,5 @@ This guide will explore in detail the structure of plugins, what they can extend, and how to distribute and install them. For a complete reference of the PDK, see the [Plugin Development Kit] reference. ---- - -Next: [File structure of a plugin ›]({{page.book.next}}) - [lua-nginx-module]: https://github.com/openresty/lua-nginx-module [Plugin Development Kit]: /gateway/{{page.kong_version}}/pdk diff --git a/app/gateway/2.8.x/plugin-development/plugin-configuration.md b/app/gateway/2.8.x/plugin-development/plugin-configuration.md index c588855d40ad..ea947969a9e6 100644 --- a/app/gateway/2.8.x/plugin-development/plugin-configuration.md +++ b/app/gateway/2.8.x/plugin-development/plugin-configuration.md @@ -397,10 +397,6 @@ return CustomHandler You can also see a real-world example of schema in [the Key-Auth plugin source code]. ---- - -Next: [Accessing the Datastore ›]({{page.book.next}}) - [Admin API]: /gateway/{{page.kong_version}}/admin-api [Plugin Development Kit]: /gateway/{{page.kong_version}}/pdk [the Key-Auth plugin source code]: https://github.com/Kong/kong/blob/master/kong/plugins/key-auth/schema.lua diff --git a/app/gateway/2.8.x/plugin-development/tests.md b/app/gateway/2.8.x/plugin-development/tests.md index f4c3bef3f22d..f08a48f09134 100644 --- a/app/gateway/2.8.x/plugin-development/tests.md +++ b/app/gateway/2.8.x/plugin-development/tests.md @@ -12,7 +12,7 @@ might also want to write integration tests. Again, Kong has your back. ## Write integration tests The preferred testing framework for Kong is -[busted](http://olivinelabs.com/busted/) running with the +[busted](https://github.com/lunarmodules/busted/) running with the [resty-cli](https://github.com/openresty/resty-cli) interpreter, though you are free to use a different one. In the Kong repository, the busted executable can be found at `bin/busted`. @@ -100,6 +100,3 @@ and Admin API on port 9001. For a real-world example, see the [Key-Auth plugin specs](https://github.com/Kong/kong/tree/master/spec/03-plugins/09-key-auth). ---- - -Next: [Distribute your plugin ›]({{page.book.next}}) diff --git a/app/gateway/2.8.x/reference/db-less-and-declarative-config.md b/app/gateway/2.8.x/reference/db-less-and-declarative-config.md index f624068b8c9d..b9e4935ed25b 100644 --- a/app/gateway/2.8.x/reference/db-less-and-declarative-config.md +++ b/app/gateway/2.8.x/reference/db-less-and-declarative-config.md @@ -6,11 +6,11 @@ title: DB-less and Declarative Configuration {% include_cached /md/enterprise/cassandra-deprecation.md %} -Traditionally, {{ site.base_gateway }} Gateway has always required a database, to store its configured entities such as Routes, +Traditionally, {{site.base_gateway}} has always required a database, to store its configured entities such as Routes, Services and Plugins. Kong uses its configuration file, `kong.conf`, to -specify the use of Postgres and Cassandra and its various settings. +specify the use of PostgreSQL and Cassandra and its various settings. -{{ site.base_gateway }} can be run without a database using only in-memory storage for entities. We call this DB-less mode. When running {{ site.base_gateway }} DB-less, the configuration of entities is done in a second configuration file, in YAML or JSON, using declarative configuration. +{{site.base_gateway}} can be run without a database using only in-memory storage for entities. We call this DB-less mode. When running {{site.base_gateway}} DB-less, the configuration of entities is done in a second configuration file, in YAML or JSON, using declarative configuration. The combination of DB-less mode and declarative configuration has a number of benefits: @@ -49,7 +49,7 @@ file loaded into Kong is the configured state of the system. ## Set up Kong in DB-less mode -To use {{ site.base_gateway }} in DB-less mode, set the `database` directive of `kong.conf` to `off`. As usual, you can do this by editing `kong.conf` and setting +To use {{site.base_gateway}} in DB-less mode, set the `database` directive of `kong.conf` to `off`. As usual, you can do this by editing `kong.conf` and setting `database=off` or via environment variables. You can then start Kong as usual: @@ -89,7 +89,7 @@ Server: kong/2.1.0 } ``` -{{ site.base_gateway }} is running, but no declarative configuration was loaded yet. This +{{site.base_gateway}} is running, but no declarative configuration was loaded yet. This means that the configuration of this node is empty. There are no Routes, Services or entities of any kind. @@ -138,7 +138,7 @@ by default. You can experiment by uncommenting the examples ## Declarative configuration format -The {{ site.base_gateway }} declarative configuration format consists of lists of +The {{site.base_gateway}} declarative configuration format consists of lists of entities and their attributes. This is a small yet complete example that illustrates a number of features: @@ -238,13 +238,13 @@ http :8001/config config=@kong.yml The `/config` endpoint replaces the entire set of entities in memory with the ones specified in the given file. -Or another way you can start Kong in DB-less mode is with a +Or another way you can start Kong in DB-less mode is with a declarative configuration in a string using the `KONG_DECLARATIVE_CONFIG_STRING` -environment variable. +environment variable. ``` -export KONG_DATABASE=off -export KONG_DECLARATIVE_CONFIG_STRING='{"_format_version":"1.1", "services":[{"host":"mockbin.com","port":443,"protocol":"https", "routes":[{"paths":["/"]}]}],"plugins":[{"name":"rate-limiting", "config":{"policy":"local","limit_by":"ip","minute":3}}]}' +export KONG_DATABASE=off +export KONG_DECLARATIVE_CONFIG_STRING='{"_format_version":"1.1", "services":[{"host":"mockbin.com","port":443,"protocol":"https", "routes":[{"paths":["/"]}]}],"plugins":[{"name":"rate-limiting", "config":{"policy":"local","limit_by":"ip","minute":3}}]}' kong start ``` @@ -288,4 +288,4 @@ Not all Kong plugins are compatible with DB-less mode since some of them by design require a central database coordination or dynamic creation of entities. -For current plugin compatibility, see [Plugin compatibility](/konnect-platform/compatibility/plugins/). \ No newline at end of file +For current plugin compatibility, see [Plugin compatibility](/hub/plugins/compatibility). diff --git a/app/gateway/2.8.x/reference/proxy.md b/app/gateway/2.8.x/reference/proxy.md index 3ceccf88e57f..beb7b73e08ba 100644 --- a/app/gateway/2.8.x/reference/proxy.md +++ b/app/gateway/2.8.x/reference/proxy.md @@ -14,7 +14,7 @@ properties: - `admin_listen`, which also defines a list of addresses and ports, but those should be restricted to only be accessed by administrators, as they expose Kong's configuration capabilities: the **Admin API** (`8001` by default). -{% include_cached /md/admin-listen.md desc='short' %} +{% include_cached /md/admin-listen.md kong_version=page.kong_version desc='short' %} - `stream_listen`, which is similar to `proxy_listen` but for Layer 4 (TCP, TLS) generic proxy. This is turned off by default. diff --git a/app/gateway/2.8.x/support-policy.md b/app/gateway/2.8.x/support-policy.md new file mode 100644 index 000000000000..d78a855bd08d --- /dev/null +++ b/app/gateway/2.8.x/support-policy.md @@ -0,0 +1,42 @@ +--- +title: Version Support Policy +badge: enterprise +content-type: reference +--- + +The support for {{site.ee_product_name}} software versions is explained in this topic. + +{% include_cached /md/support-policy.md %} + +## Version support for {{site.base_gateway}} (Enterprise) + +| Version | Released Date | End of Full Support | End of Sunset Support | +|:--------:|:-------------:|:-------------------:|:---------------------:| +| 2.8.x.x | 2022-03-02 | 2023-08-24 | 2024-08-24 | +| 2.7.x.x | 2021-12-16 | 2022-08-24 | 2023-08-24 | +| 2.6.x.x | 2021-10-14 | 2022-08-24 | 2023-08-24 | +| 2.5.x.x | 2021-08-03 | 2022-08-24 | 2023-08-24 | +| 2.4.x.x | 2021-05-18 | 2022-08-24 | 2023-08-24 | +| 2.3.x.x | 2021-02-11 | 2022-08-24 | 2023-08-24 | +| 2.2.x.x | 2020-11-17 | 2022-08-24 | 2023-08-24 | +| 2.1.x.x | 2020-08-25 | 2022-08-24 | 2023-08-24 | +| 1.5.x.x | 2020-04-10 | 2021-04-09 | 2022-04-09 | +| 1.3.x.x | 2019-11-05 | 2020-11-04 | 2021-11-04 | +| 0.36 | 2019-08-05 | 2020-08-04 | 2021-08-04 | +| 0.35 | 2019-05-16 | 2020-05-15 | 2020-11-15 | +| 0.34 | 2018-11-19 | 2019-11-18 | 2020-11-18 | +| 0.33 | 2018-07-11 | 2019-06-10 | 2020-06-10 | +| 0.32 | 2018-05-22 | 2019-05-21 | 2020-05-21 | +| 0.31 | 2018-03-13 | 2019-03-12 | 2020-03-12 | +| 0.30 | 2018-01-22 | 2019-01-21 | 2020-01-21 | + +> *Table 1: Version Support for {{site.ee_product_name}}* + +## Additional terms +- The above is a summary only and is qualified by Kong’s [Support and Maintenance Policy](https://konghq.com/supportandmaintenancepolicy). +- The above applies to Kong standard software builds only. + +## See also + +* [Version support policy for {{site.mesh_product_name}}](/mesh/latest/support-policy) +* [Version support policy for {{site.kic_product_name}}](/kubernetes-ingress-controller/latest/support-policy) diff --git a/app/gateway/2.8.x/vitals/vitals-influx-strategy.md b/app/gateway/2.8.x/vitals/vitals-influx-strategy.md index 727deed6fc54..4f43c3e006bd 100644 --- a/app/gateway/2.8.x/vitals/vitals-influx-strategy.md +++ b/app/gateway/2.8.x/vitals/vitals-influx-strategy.md @@ -78,7 +78,7 @@ with each other. 1. Start the gateway with Kong Manager: -{% include_cached /md/admin-listen.md desc='long' %} +{% include_cached /md/admin-listen.md kong_version=page.kong_version desc='long' %}
      docker run -d --name kong-ee --network=kong-ee-net \
             -e "KONG_DATABASE=postgres" \
      diff --git a/app/gateway/changelog.md b/app/gateway/changelog.md
      index 33bcf486afeb..c1f5eaf2b899 100644
      --- a/app/gateway/changelog.md
      +++ b/app/gateway/changelog.md
      @@ -2,16 +2,826 @@
       title: Kong Gateway Changelog
       no_version: true
       ---
      -
       
       
      -## 2.8.1.4
      -**Release Date**  2022/08/23
      +## 3.0.0.0
      +**Release Date** 2022/09/09
      +
      +{:.important}
      +> **Important**: Kong Gateway 3.0.0.0 is a major release and contains breaking changes.
      +Review the [breaking changes and deprecations](#breaking-changes-and-deprecations) and the [known limitations](#known-limitations) before attempting to [upgrade](/gateway/latest/upgrade/).
      +
      +### Features
      +
      +#### Enterprise
      +
      +* Kong Gateway now supports [dynamic plugin ordering](/gateway/3.0.x/kong-enterprise/plugin-ordering).
      +You can change a plugin's static priority by specifing the order in which plugins run.
      +This lets you run plugins such as `rate-limiting` before authentication plugins.
      +
      +* Kong Gateway now includes WebSocket validation functionality. Websockets are a type of persistent connection that works on top of HTTP.
      +
      +  Previously, Kong Gateway 2.x supported limited WebSocket connections, where plugins only ran during the initial connection phase instead of for each frame.
      +  Now, Kong Gateway provides more control over WebSocket traffic by implementing plugins that target WebSocket frames.
      +
      +  This release includes:
      +  * [Service](/gateway/3.0.x/admin-api/#service-object) and [route](/gateway/3.0.x/admin-api/#route-object) support for `ws` and `wss` protocols
      +  * Two new plugins: [WebSocket Size Limit](/hub/kong-inc/websocket-size-limit/) and [WebSocket Validator](/hub/kong-inc/websocket-validator/)
      +  * WebSocket plugin development capabilities (**Beta feature**)
      +    * PDK modules: [kong.websocket.client](/gateway/3.0.x/plugin-development/pdk/kong.websocket.client) and [kong.websocket.upstream](/gateway/3.0.x/plugin-development/pdk/kong.websocket.upstream)
      +    * [New plugin handlers](/gateway/3.0.x/plugin-development/custom-logic/#websocket-plugin-development)
      +
      +  Learn how to develop WebSocket plugins with our [plugin development guide](/gateway/3.0.x/plugin-development/custom-logic/#websocket-plugin-development).
      +
      +* In this release, Kong Manager ships a with a refactored design and improved user experience.
      +
      +  Notable changes:
      +  * Reworked workspace dashboards, both for specific workspaces and at the multi-workspace level.
      +  * License metrics now appear at the top of overview pages.
      +  * Restructured the layout and navigation to make workspace selection a secondary concern.
      +  * Grayed out portal buttons when you don't have permissions.
      +  * Added license level to phone home metrics.
      +  * Added more tooltips.
      +
      +* [Secrets management](/gateway/{{page.kong_version}}/kong-enterprise/secrets-management/) is now generally available.
      +  * Added GCP integration support for the secrets manager. GCP is now available as a vault backend.
      +  * The `/vaults-beta` entity has been deprecated and replaced with the `/vaults` entity.
      +  [#8871](https://github.com/Kong/kong/pull/8871)
      +  [#9217](https://github.com/Kong/kong/pull/9217)
      +
      +* Kong Gateway now provides slim and UBI images.
      +Slim images are docker containers built with a minimal set of installed packages to run Kong Gateway.
      +From 3.0 onward, Kong Docker images will only contain software required to run the Gateway.
      +This ensures that false positive vulnerabilities don't get flagged during security scanning.
      +
      +    If you want to retain or add other dependencies, you can [build custom Kong Docker images](/gateway/3.0.x/install/docker/build-custom-images).
      +
      +* The base OS for our convenience docker tags (for example, `latest`, `3.0.0.0`, `3.0`) has switched from Alpine to Debian.
      +
      +* Added key recovery for keyring encryption.
      +This exposes a new endpoint for the Admin API, [`/keyring/recover`](/gateway/3.0.x/admin-api/db-encryption/#recover-keyring-from-database), and requires [`keyring_recovery_public_key`](/gateway/3.0.x/reference/configuration/#keyring_recovery_public_key) to be set in `kong.conf`.
      +
      +* You can now encrypt declarative configuration files on data planes in DB-less and hybrid modes using [AES-256-GCM](https://www.rfc-editor.org/rfc/rfc5288.html) or [chacha20-poly1305](https://www.rfc-editor.org/rfc/rfc7539.html) encryption algorithms.
      +
      +    Set your desired encryption mode with the [`declarative_config_encryption_mode`](/gateway/3.0.x/reference/configuration/#declarative_config_encryption_mode) configuration parameter.
      +
      +#### Core
      +
      +* This release introduces a new router implementation: `atc-router`.
      +This router is written in Rust, a powerful routing language that can handle complex routing requirements.
      +The new router can be used in traditional-compatible mode, or use the new expression-based language.
      +
      +  With the new router, we have:
      +  * Reduced router rebuild time when changing Kong’s configuration
      +  * Increased runtime performance when routing requests
      +  * Reduced P99 latency from 1.5s to 0.1s with 10,000 routes
      +
      +  Learn more about the router:
      +  * [Configure routes using expressions](/gateway/3.0.x/key-concepts/routes/expressions)
      +  * [Router operator reference](/gateway/3.0.x/reference/router-operators)
      +
      +  [#8938](https://github.com/Kong/kong/pull/8938)
      +* Implemented delayed response in stream mode.
      +  [#6878](https://github.com/Kong/kong/pull/6878)
      +* Added `cache_key` on target entity for uniqueness detection.
      +  [#8179](https://github.com/Kong/kong/pull/8179)
      +* Introduced the tracing API, which is compatible with OpenTelemetry API specs, and
      +  adds built-in instrumentations.
      +
      +  The tracing API is intended to be used with a external exporter plugin.
      +  Built-in instrumentation types and sampling rate are configurable through the
      +  [`opentelemetry_tracing`](/gateway/3.0.x/reference/configuration/#opentelemetry_tracing) and [`opentelemetry_tracing_sampling_rate`](/gateway/3.0.x/reference/configuration/#opentelemetry_tracing_sampling_rate) options.
      +  [#8724](https://github.com/Kong/kong/pull/8724)
      +* Added `path`, `uri_capture`, and `query_arg` options to upstream `hash_on`
      +  for load balancing.
      +  [#8701](https://github.com/Kong/kong/pull/8701)
      +* Introduced Unix domain socket-based `lua-resty-events` to
      +  replace shared memory-based `lua-resty-worker-events`.
      +  [#8890](https://github.com/Kong/kong/pull/8890)
      +* Introduced the `table_name` field for entities.
      +  This field lets you specify a table name.
      +  Previously, the name was deduced by the entity `name` attribute.
      +  [#9182](https://github.com/Kong/kong/pull/9182)
      +* Added `headers` on active health checks for upstreams.
      +  [#8255](https://github.com/Kong/kong/pull/8255)
      +* Target entities using hostnames were resolved when they were not needed. Now
      +  when a target is removed or updated, the DNS record associated with it is
      +  removed from the list of hostnames to be resolved.
      +  [#8497](https://github.com/Kong/kong/pull/8497) [9265](https://github.com/Kong/kong/pull/9265)
      +* Improved error handling and debugging info in the DNS code.
      +  [#8902](https://github.com/Kong/kong/pull/8902)
      +* Kong Gateway will now attempt to recover from an unclean shutdown by detecting and
      +  removing dangling Unix sockets in the prefix directory.
      +  [#9254](https://github.com/Kong/kong/pull/9254)
      +* A new CLI command, `kong migrations status`, generates the migration status in a JSON file.
      +* Removed the warning for `AAAA` being experimental with `dns_order`.
      +
      +#### Performance
      +
      +- Kong Gateway does not register unnecessary event handlers on hybrid mode control plane
      +  nodes anymore. [#8452](https://github.com/Kong/kong/pull/8452).
      +- Use the new timer library to improve performance,
      +  except for the plugin server.
      +  [#8912](https://github.com/Kong/kong/pull/8912)
      +- Increased the use of caching for DNS queries by activating `additional_section` by default.
      +  [#8895](https://github.com/Kong/kong/pull/8895)
      +- `pdk.request.get_header` has been changed to a faster implementation.
      +  It doesn't fetch all headers every time it's called.
      +  [#8716](https://github.com/Kong/kong/pull/8716)
      +- Conditional rebuilding of the router, plugins iterator, and balancer on data planes.
      +  [#8519](https://github.com/Kong/kong/pull/8519),
      +  [#8671](https://github.com/Kong/kong/pull/8671)
      +- Made configuration loading code more cooperative by yielding.
      +  [#8888](https://github.com/Kong/kong/pull/8888)
      +- Use the LuaJIT encoder instead of JSON to serialize values faster in LMDB.
      +  [#8942](https://github.com/Kong/kong/pull/8942)
      +- Made inflating and JSON decoding non-concurrent, which avoids blocking and makes data plane reloads faster.
      +  [#8959](https://github.com/Kong/kong/pull/8959)
      +- Stopped duplication of some events.
      +  [#9082](https://github.com/Kong/kong/pull/9082)
      +- Improved performance of configuration hash calculation by using `string.buffer` and `tablepool`.
      +  [#9073](https://github.com/Kong/kong/pull/9073)
      +- Reduced cache usage in DB-less mode by not using the Kong cache for routes and services in LMDB.
      +  [#8972](https://github.com/Kong/kong/pull/8972)
      +
      +#### Admin API
      +
      +- Added a new `/timers` Admin API endpoint to get timer statistics and worker info.
      +  [#8912](https://github.com/Kong/kong/pull/8912)
      +  [#8999](https://github.com/Kong/kong/pull/8999)
      +- The `/` endpoint now includes plugin priority.
      +  [#8821](https://github.com/Kong/kong/pull/8821)
      +
      +#### Hybrid Mode
      +
      +- Added wRPC protocol support. Configuration synchronization now happens over wRPC.
      +  wRPC is an RPC protocol that encodes with ProtoBuf and transports
      +  with WebSocket.
      +  [#8357](https://github.com/Kong/kong/pull/8357)
      +  - To keep compatibility with earlier versions,
      +    added support for the control plane to fall back to the previous protocol to
      +    support older data planes.
      +    [#8834](https://github.com/Kong/kong/pull/8834)
      +  - Added support to negotiate services supported with wRPC protocol.
      +    We will support more services in the future.
      +    [#8926](https://github.com/Kong/kong/pull/8926)
      +- Declarative configuration exports now happen inside a transaction in PostgreSQL.
      +  [#8586](https://github.com/Kong/kong/pull/8586)
      +
      +#### Plugins
      +
      +* Starting with version 3.0, all bundled plugin versions are the same as the
      +Kong Gateway version.
      +[#8772](https://github.com/Kong/kong/pull/8772)
      +
      +    [Plugin documentation](/hub/) now refers to the Kong Gateway version instead of
      +    the individual plugin version.
      +
      +* **New plugins**:
      +  * [OpenTelemetry](/hub/kong-inc/opentelemetry) (`opentelemetry`)
      +
      +    Export tracing instrumentations to any OTLP/HTTP compatible backend.
      +    `opentelemetry_tracing` configuration must be enabled to collect
      +    the core tracing spans of Kong Gateway.
      +    [#8826](https://github.com/Kong/kong/pull/8826)
      +
      +  * [TLS Handshake Modifier](/hub/kong-inc/tls-handshake-modifier/) (`tls-handshake-modifier`)
      +
      +    Make certificates available to other plugins acting on the same request.  
      +
      +  * [TLS Metadata Headers](/hub/kong-inc/tls-metadata-headers/) (`tls-metadata-headers`)
      +
      +    Proxy TLS client certificate metadata to upstream services via HTTP headers.
      +
      +  * [WebSocket Size Limit](/hub/kong-inc/websocket-size-limit/) (`websocket-size-limit`)
      +
      +    Allows operators to specify a maximum size for incoming WebSocket messages.
      +
      +  * [WebSocket Validator](/hub/kong-inc/websocket-validator/) (`websocket-validator`)
      +
      +    Validate individual WebSocket messages against a user-specified schema
      +    before proxying them.
      +
      +* [ACME](/hub/kong-inc/ACME/) (`acme`)
      +  * Added the `allow_any_domain` field. It defaults to false and if set to true, the gateway will
      +  ignore the `domains` field.
      +  [#9047](https://github.com/Kong/kong/pull/9047)
      +
      +* [AWS Lambda](/hub/kong-inc/aws-lambda) (`aws-lambda`)
      +  * Added support for cross-account invocation through
      +  the `aws_assume_role_arn` and
      +  `aws_role_session_name` configuration parameters.
      +  [#8900](https://github.com/Kong/kong/pull/8900)
      +  * The plugin now accepts string type `statusCode` as a valid return when
      +    working in proxy integration mode.
      +    [#8765](https://github.com/Kong/kong/pull/8765)
      +  * The plugin now separates AWS credential cache by the IAM role ARN.
      +    [#8907](https://github.com/Kong/kong/pull/8907)
      +
      +* Collector (`collector`)
      +  * The deprecated Collector plugin has been removed.
      +
      +* [DeGraphQL](/hub/kong-inc/degraphql) (`degraphql`)
      +  * The GraphQL server path is now configurable with the `graphql_server_path` configuration parameter.
      +
      +* [Kafka Upstream](/hub/kong-inc/kafka-upstream/) (`kafka-upstream`) and
      +[Kafka Log](/hub/kong-inc/kafka-log) (`kafka-log`)
      +  * Added support for the `SCRAM-SHA-512` authentication mechanism.
      +
      +* [LDAP Authentication Advanced](/hub/kong-inc/ldap-auth-advanced) (`ldap-auth-advanced`)
      +  * This plugin now allows authorization based on group membership.
      +  The new configuration parameter, `groups_required`, is an array of string
      +  elements that indicates the groups that users must belong to for the request
      +  to be authorized.
      +  * The character `.` is now allowed in group attributes.
      +  * The character `:` is now allowed in the password field.
      +
      +* [mTLS Authentication](/hub/kong-inc/mtls-auth) (`mtls-auth`)
      +  * Introduced certificate revocation list (CRL) and OCSP server support with the
      +  following parameters: `http_proxy_host`, `http_proxy_port`, `https_proxy_host`,
      +  and `https_proxy_port`.
      +
      +* [OPA](/hub/kong-inc/opa/) (`opa`)
      +  * New configuration parameter `include_body_in_opa_input`: When enabled, include the raw body as a string in the OPA input at `input.request.http.body` and the body size at `input.request.http.body_size`.
      +
      +  * New configuration parameter `include_parsed_json_body_in_opa_input`: When enabled and content-type is `application/json`, the parsed JSON will be added to the OPA input at `input.request.http.parsed_body`.
      +
      +* [Prometheus](/hub/kong-inc/prometheus/) (`prometheus`)
      +  * High cardinality metrics are now disabled by default.
      +  * Decreased performance penalty to proxy traffic when collecting metrics.
      +  * The following metric names were adjusted to add units to standardize where possible:
      +    * `http_status` to `http_requests_total`.
      +    * `latency` to `kong_request_latency_ms` (HTTP), `kong_upstream_latency_ms`, `kong_kong_latency_ms`, and `session_duration_ms` (stream).
      +
      +        Kong latency and upstream latency can operate at orders of different magnitudes. Separate these buckets to reduce memory overhead.
      +
      +    * `kong_bandwidth` to `kong_bandwidth_bytes`.
      +    * `nginx_http_current_connections` and `nginx_stream_current_connections` were merged into to `nginx_hconnections_total` (or `nginx_current_connections`?)
      +    *  `request_count` and `consumer_status` were merged into http_requests_total.
      +
      +        If the `per_consumer` config is set to `false`, the `consumer` label will be empty. If the `per_consumer` config is `true`, the `consumer` label will be filled.
      +  * Removed the following metric: `http_consumer_status`
      +  * New metrics:
      +    * `session_duration_ms`: monitoring stream connections.
      +    * `node_info`: Single gauge set to 1 that outputs the node's ID and Kong Gateway version.
      +
      +  * `http_requests_total` has a new label, `source`. It can be set to `exit`, `error`, or `service`.
      +  * All memory metrics have a new label: `node_id`.
      +  * Updated the Grafana dashboard that comes packaged with Kong
      +
      +* [StatsD](/hub/kong-inc/statsd) (`statsd`)
      +  * **Newly open-sourced plugin capabilities**: All capabilities of the [StatsD Advanced](/hub/kong-inc/statsd-advanced/) plugin are now bundled in the [StatsD](https://docs.konghq.com/hub/kong-inc/statsd) plugin.
      +    [#9046](https://github.com/Kong/kong/pull/9046)
      +
      +* [Zipkin](/hub/kong-inc/zipkin) (`zipkin`)
      +  * Added support for including the HTTP path in the span name with the
      +  `http_span_name` configuration parameter.
      +  [#8150](https://github.com/Kong/kong/pull/8150)
      +  * Added support for socket connect and send/read timeouts
      +    through the `connect_timeout`, `send_timeout`,
      +    and `read_timeout` configuration parameters. This can help mitigate
      +    `ngx.timer` saturation when upstream collectors are unavailable or slow.
      +    [#8735](https://github.com/Kong/kong/pull/8735)
      +
      +#### Configuration
      +
      +* You can now configure `openresty_path` to allow
      +  developers and operators to specify the OpenResty installation to use when
      +  running Kong Gateway, instead of using the system-installed OpenResty.
      +  [#8412](https://github.com/Kong/kong/pull/8412)
      +* Added `ipv6only` to listen options `admin_listen`, `proxy_listen`, and `stream_listen`.
      +  [#9225](https://github.com/Kong/kong/pull/9225)
      +* Added `so_keepalive` to listen options `admin_listen`, `proxy_listen`, and `stream_listen`.
      +  [#9225](https://github.com/Kong/kong/pull/9225)
      +* Add LMDB DB-less configuration persistence and removed the JSON-based
      +  configuration cache for faster startup time.
      +  [#8670](https://github.com/Kong/kong/pull/8670)
      +* `nginx_events_worker_connections=auto` now has a lower bound of 1024.
      +  [#9276](https://github.com/Kong/kong/pull/9276)
      +* `nginx_main_worker_rlimit_nofile=auto` now has a lower bound of 1024.
      +  [#9276](https://github.com/Kong/kong/pull/9276)
      +
      +#### PDK
      +
      +* Added new PDK function: `kong.request.get_start_time()`.
      +  This function returns the request start time, in Unix epoch milliseconds.
      +  [#8688](https://github.com/Kong/kong/pull/8688)
      +* The function `kong.db.*.cache_key()` now falls back to `.id` if nothing from `cache_key` is found.
      +  [#8553](https://github.com/Kong/kong/pull/8553)
      +
      +### Known limitations
      +
      +* Kong Manager does not currently support the following features:
      +  * Secrets management
      +  * Plugin ordering
      +  * Expression-based routing
      +
      +* Blue-green migration from 2.8.x (and below) to 3.0.x is not supported.
      +  * This is a known issue planned to be fixed in the next 2.8 release. If this is a requirement for upgrading,
      +  Kong operators should upgrade to that version before beginning a upgrade to 3.0.0.0.
      +  * See [Upgrade Kong Gateway](/gateway/latest/upgrade/) for more details.
      +
      +* OpenTracing: There is an issue with `nginx-opentracing` in this release, so it is not
      +  recommended to upgrade yet if you are an OpenTracing user. This will be
      +  rectified in an upcoming patch/minor release.
      +
      +### Breaking changes and deprecations
      +
      +#### Deployment
      +
      +* Deprecated and stopped producing Amazon Linux 1 containers and packages.
      +Amazon Linux 1 [reached end-of-life on December 31, 2020](https://aws.amazon.com/blogs/aws/update-on-amazon-linux-ami-end-of-life).
      +  [Kong/docs.konghq.com #3966](https://github.com/Kong/docs.konghq.com/pull/3966)
      +* Deprecated and stopped producing Debian 8 (Jessie) containers and packages.
      +Debian 8 [reached end-of-life in June 30, 2020](https://www.debian.org/News/2020/20200709).
      +  [Kong/kong-build-tools #448](https://github.com/Kong/kong-build-tools/pull/448)
      +  [Kong/kong-distributions #766](https://github.com/Kong/kong-distributions/pull/766)
      +
      +#### Core
      +
      +* As of 3.0, Kong Gateway's schema library's `process_auto_fields` function will not make deep
      +  copies of data that is passed to it when the given context is `select`. This was
      +  done to avoid excessive deep copying of tables where we believe the data most of
      +  the time comes from a driver like `pgmoon` or `lmdb`.
      +
      +  If a custom plugin relied on `process_auto_fields` not overriding the given table, it must make its own copy
      +  before passing it to the function now.
      +  [#8796](https://github.com/Kong/kong/pull/8796)
      +* The deprecated `shorthands` field in Kong plugin or DAO schemas was removed in favor
      +  of the typed `shorthand_fields`. If your custom schemas still use `shorthands`, you
      +  need to update them to use `shorthand_fields`.
      +  [#8815](https://github.com/Kong/kong/pull/8815)
      +* The support for `legacy = true/false` attribute was removed from Kong schemas and
      +  Kong field schemas.
      +  [#8958](https://github.com/Kong/kong/pull/8958)
      +* The deprecated alias of `Kong.serve_admin_api` was removed. If your custom Nginx
      +  templates still use it, change it to `Kong.admin_content`.
      +  [#8815](https://github.com/Kong/kong/pull/8815)
      +* The Kong singletons module `kong.singletons` was removed in favor of the PDK `kong.*`.
      +  [#8874](https://github.com/Kong/kong/pull/8874)
      +* The data plane configuration cache was removed.
      +  Configuration persistence is now done automatically with LMDB.
      +  [#8704](https://github.com/Kong/kong/pull/8704)
      +* `ngx.ctx.balancer_address` was removed in favor of `ngx.ctx.balancer_data`.
      +  [#9043](https://github.com/Kong/kong/pull/9043)
      +* The normalization rules for `route.path` have changed. Kong Gateway now stores the unnormalized path, but
      +  the regex path always pattern-matches with the normalized URI. Previously, Kong Gateway replaced percent-encoding
      +  in the regex path pattern to ensure different forms of URI matches.
      +  That is no longer supported. Except for the reserved characters defined in
      +  [rfc3986](https://datatracker.ietf.org/doc/html/rfc3986#section-2.2),
      +  write all other characters without percent-encoding.
      +  [#9024](https://github.com/Kong/kong/pull/9024)
      +* Kong Gateway no longer uses a heuristic to guess whether a `route.path` is a regex pattern. From 3.0 onward,
      +  all regex paths must start with the `"~"` prefix, and all paths that don't start with `"~"` will be considered plain text.
      +  The migration process should automatically convert the regex paths when upgrading from 2.x to 3.0.
      +  [#9027](https://github.com/Kong/kong/pull/9027)
      +* Bumped the version number (`_format_version`) of declarative configuration to `3.0` for changes on `route.path`.
      +  Declarative configurations using older versions are upgraded to `3.0` during migrations.
      +
      +    {:.important}
      +    > **Do not sync (`deck sync`) declarative configuration files from 2.8 or earlier to 3.0.**
      +    Old configuration files will overwrite the configuration and create compatibility issues.
      +    To grab the updated configuration, `deck dump` the 3.0 file after migrations are completed.
      +
      +  [#9078](https://github.com/Kong/kong/pull/9078)
      +* Tags may now contain space characters.
      +  [#9143](https://github.com/Kong/kong/pull/9143)
      +* Support for the `nginx-opentracing` module is deprecated as of `3.0` and will
      +  be removed from Kong in `4.0` (see the [Known Limitations](#known-limitations) section for additional
      +  information).
      +
      +#### Admin API
      +
      +* The Admin API endpoint `/vitals/reports` has been removed.
      +* `POST` requests on `/targets` endpoints are no longer able to update
      +  existing entities. They are only able to create new ones.
      +  [#8596](https://github.com/Kong/kong/pull/8596),
      +  [#8798](https://github.com/Kong/kong/pull/8798). If you have scripts that use
      +  `POST` requests to modify `/targets`, change them to `PUT`
      +  requests to the appropriate endpoints before updating to {{site.base_gateway}} 3.0.
      +* Insert and update operations on duplicated targets return a `409` error.
      +  [#8179](https://github.com/Kong/kong/pull/8179),
      +  [#8768](https://github.com/Kong/kong/pull/8768)
      +* The list of reported plugins available on the server now returns a table of
      +  metadata per plugin instead of a boolean `true`.
      +  [#8810](https://github.com/Kong/kong/pull/8810)
      +
      +#### PDK
      +
      +* The `kong.request.get_path()` PDK function now performs path normalization
      +  on the string that is returned to the caller. The raw, non-normalized version
      +  of the request path can be fetched via `kong.request.get_raw_path()`.
      +  [#8823](https://github.com/Kong/kong/pull/8823)
      +* `pdk.response.set_header()`, `pdk.response.set_headers()`, `pdk.response.exit()` now ignore and emit warnings for manually set `Transfer-Encoding` headers.
      +  [#8698](https://github.com/Kong/kong/pull/8698)
      +* The PDK is no longer versioned.
      +  [#8585](https://github.com/Kong/kong/pull/8585)
      +* The JavaScript PDK now returns `Uint8Array` for `kong.request.getRawBody`,
      +  `kong.response.getRawBody`, and `kong.service.response.getRawBody`.
      +  The Python PDK returns `bytes` for `kong.request.get_raw_body`,
      +  `kong.response.get_raw_body`, and `kong.service.response.get_raw_body`.
      +  Previously, these functions returned strings.
      +  [#8623](https://github.com/Kong/kong/pull/8623)
      +* The `go_pluginserver_exe` and `go_plugins_dir` directives are no longer supported.
      + [#8552](https://github.com/Kong/kong/pull/8552). If you are using
      + [Go plugin server](https://github.com/Kong/go-pluginserver), migrate your plugins to use the
      + [Go PDK](https://github.com/Kong/go-pdk) before upgrading.
      +
      +#### Plugins
      +
      +* DAOs in plugins must be listed in an array, so that their loading order is explicit. Loading them in a
      +  hash-like table is no longer supported.
      +  [#8988](https://github.com/Kong/kong/pull/8988)
      +* Plugins MUST now have a valid `PRIORITY` (integer) and `VERSION` ("x.y.z" format)
      +  field in their `handler.lua` file, otherwise the plugin will fail to load.
      +  [#8836](https://github.com/Kong/kong/pull/8836)
      +* The old `kong.plugins.log-serializers.basic` library was removed in favor of the PDK
      +  function `kong.log.serialize`. Upgrade your plugins to use the PDK.
      +  [#8815](https://github.com/Kong/kong/pull/8815)
      +* The support for deprecated legacy plugin schemas was removed. If your custom plugins
      +  still use the old (`0.x era`) schemas, you are now forced to upgrade them.
      +  [#8815](https://github.com/Kong/kong/pull/8815)
      +* Updated the priority for some plugins.
      +
      +    This is important for those who run custom plugins as it may affect the sequence in which your plugins are executed.
      +    This does not change the order of execution for plugins in a standard Kong Gateway installation.
      +
      +    Old and new plugin priority values:
      +    - `acme` changed from `1007` to `1705`
      +    - `basic-auth` changed from `1001` to `1100`
      +    - `hmac-auth` changed from `1000` to `1030`
      +    - `jwt` changed from `1005` to `1450`
      +    - `key-auth` changed from `1003` to `1250`
      +    - `ldap-auth` changed from `1002` to `1200`
      +    - `oauth2` changed from `1004` to `1400`
      +    - `rate-limiting` changed from `901` to `910`
      +    - `pre-function` changed from `+inf` to `1000000`.
      +
      +* Kong plugins no longer support `CREDENTIAL_USERNAME` (`X-Credential-Username`).
      +  Use the constant `CREDENTIAL_IDENTIFIER` (`X-Credential-Identifier`) when
      +  setting the upstream headers for a credential.
      +  [#8815](https://github.com/Kong/kong/pull/8815)
      +
      +* [ACL](/hub/kong-inc/acl/) (`acl`), [Bot Detection](/hub/kong-inc/bot-detection) (`bot-detection`), and [IP Restriction](/hub/kong-inc/ip-restriction/) (`ip-restriction`)
      +  * Removed the deprecated `blacklist` and `whitelist` configuration parameters.
      +   [#8560](https://github.com/Kong/kong/pull/8560)
      +
      +* [ACME](/hub/kong-inc/ACME/) (`acme`)
      +  * The default value of the `auth_method` configuration parameter is now `token`.
      +
      +* [AWS Lambda](/hub/kong-inc/aws-lambda/) (`aws-lambda`)
      +  * The AWS region is now required. You can set it through the plugin configuration with the  `aws_region` field parameter, or with environment variables.
      +  * The plugin now allows `host` and `aws_region` fields to be set at the same time, and always applies the SigV4 signature.
      +  [#8082](https://github.com/Kong/kong/pull/8082)
      +
      +* [HTTP Log](/hub/kong-inc/http-log/) (`http-log`)
      +  * The `headers` field now only takes a single string per header name,
      +  where it previously took an array of values.
      +  [#6992](https://github.com/Kong/kong/pull/6992)
      +
      +* [JWT](/hub/kong-inc/jwt/) (`jwt`)
      +  * The authenticated JWT is no longer put into the nginx
      +    context (`ngx.ctx.authenticated_jwt_token`). Custom plugins which depend on that
      +    value being set under that name must be updated to use Kong's shared context
      +    instead (`kong.ctx.shared.authenticated_jwt_token`) before upgrading to 3.0.
      +
      +* [Prometheus](/hub/kong-inc/prometheus/) (`prometheus`)
      +  * High cardinality metrics are now disabled by default.
      +  * Decreased performance penalty to proxy traffic when collecting metrics.
      +  * The following metric names were adjusted to add units to standardize where possible:
      +    * `http_status` to `http_requests_total`.
      +    * `latency` to `kong_request_latency_ms` (HTTP), `kong_upstream_latency_ms`, `kong_kong_latency_ms`, and `session_duration_ms` (stream).
      +
      +        Kong latency and upstream latency can operate at orders of different magnitudes. Separate these buckets to reduce memory overhead.
      +
      +    * `kong_bandwidth` to `kong_bandwidth_bytes`.
      +    * `nginx_http_current_connections` and `nginx_stream_current_connections` were merged into to `nginx_connections_total`.
      +    *  `request_count` and `consumer_status` were merged into `http_requests_total`.
      +
      +        If the `per_consumer` config is set to `false`, the `consumer` label will be empty. If the `per_consumer` config is `true`, the `consumer` label will be filled.
      +  * Removed the following metric: `http_consumer_status`
      +  * New metrics:
      +    * `session_duration_ms`: monitoring stream connections.
      +    * `node_info`: Single gauge set to 1 that outputs the node's ID and Kong Gateway version.
      +
      +  * `http_requests_total` has a new label, `source`. It can be set to `exit`, `error`, or `service`.
      +  * All memory metrics have a new label: `node_id`.
      +  * Updated the Grafana dashboard that comes packaged with Kong
      +[#8712](https://github.com/Kong/kong/pull/8712)
      +  * The plugin doesn't export status codes, latencies, bandwidth and upstream
      +  health check metrics by default. They can still be turned on manually by setting `status_code_metrics`,
      +  `lantency_metrics`, `bandwidth_metrics` and `upstream_health_metrics` respectively.
      +  [#9028](https://github.com/Kong/kong/pull/9028)
      +
      +* [Serverless Functions](/hub/kong-inc/serverless-functions/) (`post-function` or `pre-function`)
      +  * Removed the deprecated `config.functions` configuration parameter from the Serverless Functions plugins' schemas.
      +    Use the `config.access` phase instead.
      +  [#8559](https://github.com/Kong/kong/pull/8559)
      +
      +* [StatsD](/hub/kong-inc/statsd/) (`statsd`):
      +  * Any metric name that is related to a service now has a `service.` prefix: `kong.service..request.count`.
      +    * The metric `kong..request.status.` has been renamed to `kong.service..status.`.
      +    * The metric `kong..user..request.status.` has been renamed to `kong.service..user..status.`.
      +  * The metric `*.status..total` from metrics `status_count` and `status_count_per_user` has been removed.
      +
      +  [#9046](https://github.com/Kong/kong/pull/9046)
      +
      +* [Rate Limiting](/hub/kong-inc/rate-limiting/) (`rate-limiting`), [Rate Limiting Advanced](/hub/kong-inc/rate-limiting-advanced/) (`rate-limiting-advanced`), and [Response Rate Limiting](/hub/kong-inc/response-ratelimiting/) (`response-ratelimiting`):
      +  * The default policy is now local for all deployment modes.
      +  [#9344](https://github.com/Kong/kong/pull/9344)
      +
      +* **Deprecated**: [StatsD Advanced](/hub/kong-inc/statsd-advanced/) (`statsd-advanced`):
      +  * The StatsD Advanced plugin has been deprecated and will be removed in 4.0.
      +  All capabilities are now available in the [StatsD](/hub/kong-inc/statsd/) plugin.
      +
      +* [Proxy Cache](/hub/kong-inc/proxy-cache/) (`proxy-cache`), [Proxy Cache Advanced](/hub/kong-inc/proxy-cache-advanced/) (`proxy-cache-advanced`), and [GraphQL Proxy Cache Advanced](/hub/kong-inc/graphql-proxy-cache-advanced/) (`graphql-proxy-cache-advanced`)
      +  * These plugins don't store response data in `ngx.ctx.proxy_cache_hit` anymore.
      +    Logging plugins that need the response data must now read it from `kong.ctx.shared.proxy_cache_hit`.
      +    [#8607](https://github.com/Kong/kong/pull/8607)
      +
      +
      +
      +#### Configuration
      +
      +* The Kong constant `CREDENTIAL_USERNAME` with the value of `X-Credential-Username` has been
      +  removed.
      +  [#8815](https://github.com/Kong/kong/pull/8815)
      +* The default value of `lua_ssl_trusted_certificate` has changed to `system`
      +  [#8602](https://github.com/Kong/kong/pull/8602) to automatically load the trusted CA list from the system CA store.
      +* It is no longer possible to use a `.lua` format to import a declarative configuration file from the `kong`
      +  CLI tool. Only JSON and YAML formats are supported. If your update procedure with Kong Gateway involves
      +  executing `kong config db_import config.lua`, convert the `config.lua` file into a `config.json` or `config.yml` file
      +  before upgrading.
      +  [#8898](https://github.com/Kong/kong/pull/8898)
      +* The data plane config cache mechanism and its related configuration options
      +(`data_plane_config_cache_mode` and `data_plane_config_cache_path`) have been removed in favor of LMDB.
      +
      +#### Migrations
      +
      +* The migration helper library (mostly used for Cassandra migrations) is no longer supplied with Kong Gateway.
      +  [#8781](https://github.com/Kong/kong/pull/8781)
      +* PostgreSQL migrations can now have an `up_f` part like Cassandra
      +  migrations, designating a function to call. The `up_f` part is
      +  invoked after the `up` part has been executed against the database
      +  for both PostgreSQL and Cassandra.
       
       ### Fixes
       
       #### Enterprise
       
      +* Fixed an issue with keyring encryption, where the control plane would crash if any errors occurred
      +during the initialization of the [keyring module](/gateway/latest/kong-enterprise/db-encryption/).
      +
      +* Fixed an issue where the keyring module was not decrypting keys after a soft reload.
      +
      +* Fixed pagination issues:
      +  * Fixed a consumer pagination issue.
      +  * Fixed an issue that appeared when loading the second page while iterating over a foreign key field using the DAO.
      +    [#9255](https://github.com/Kong/kong/pull/9255)
      +
      +* Fixed service route update failures that occurred after restarting a control plane.
      +
      +* **Vitals**:
      +  * Disabled `phone_home` for `anonymous_reports` on the data plane.
      +  * The Kong Gateway version information is now sent in the telemetry request query parameter.
      +
      +* **Kong Manager**:
      +  * Fixed the workspace dashboard's loading state.
      +    Previously, a dashboard with no request data and an existing service would still prompt users to add a service.
      +  * Fixed an issue where Kong Manager allowed selection of metrics not supported by the Datadog plugin.
      +  * Fixed the values accepted for upstream configuration in Kong Manager.
      +  Previously, fields that were supposed to accept decimals would only accept whole numbers.
      +  * Fixed an issue where you couldn't save or update `pre-function` plugin configuration when the updated value contained a comma (`,`).
      +  * The service name field on the Service Contracts page now correctly shows the service display name.
      +  Previously, it showed the service ID.
      +  * Fixed an issue where, after updating the CA certificate, the page wouldn't return to the certificate view.
      +  * Fixed an issue where the port was missing from the service URL on the service overview page.
      +  * Fixed an issue where switching between workspace dashboard pages would not update the Dev Portal URL.
      +  * Fixed issues with plugins:
      +    * The Exit Transformer plugin can now load Lua functions added through Kong Manager.
      +    * The CORS plugin now treats regexes properly for the `config.origins` field.
      +    * The Datadog plugin now accepts an array for the `tags` field. Previously, it was incorrectly expecting a string.
      +
      +  * Fixed an `HTTP 500` error that occurred when sorting routes by the **Hosts** column, then clicking **Next** on a paginated listing.
      +  * Fixed an issue that prevented developer role assignments from displaying in Kong Manager.
      +    When viewing a role under the Permissions tab in the Dev Portal section, the list of developers wouldn't update when a new developer was added.
      +    Kong Manager was constructing the wrong URL when retrieving Dev Portal assignees.
      +  * Fixed an issue where admins couldn't switch workspaces if they didn't have an roles in the default workspace.
      +  * Fixed a display issue with Dev Portal settings in Kong Manager.
      +  * Improved the error that appeared when trying to view admin roles without permissions for the resource.
      +    Instead of displaying `404 workspace not found`, the error now informs the user that they don't have access to view roles.
      +
      +* Fixed an issue where the data plane would reload and lose its license after an Nginx reload.
      +* Fixed issues in dependencies:
      +
      +  * `kong-gql`: Fixed variable definitions to handle non-nullable/list-type variables correctly.
      +  * `lua-resty-openssl-aux-module`: Fixed an issue with getting `SSL_CTX` from a request.
      +
      +#### Core
      +
      +* The schema validator now correctly converts `null` from declarative
      +  configurations to `nil`.
      +  [#8483](https://github.com/Kong/kong/pull/8483)
      +* Kong now reschedules router and plugin iterator timers only after finishing the previous
      +  execution, avoiding unnecessary concurrent executions.
      +  [#8567](https://github.com/Kong/kong/pull/8567)
      +* External plugins now handle returned JSON with null member correctly.
      +  [#8611](https://github.com/Kong/kong/pull/8611)
      +* Fixed an issue where the address of an environment variable could change but the code didn't
      +  check that it was fixed after init.
      +  [#8581](https://github.com/Kong/kong/pull/8581)
      +* Fixed an issue where the Go plugin server instance would not be updated after
      +  a restart.
      +  [#8547](https://github.com/Kong/kong/pull/8547)
      +* Fixed an issue on trying to reschedule the DNS resolving timer when Kong was
      +  being reloaded.
      +  [#8702](https://github.com/Kong/kong/pull/8702)
      +* The private stream API has been rewritten to allow for larger message payloads.
      +  [#8641](https://github.com/Kong/kong/pull/8641)
      +* Fixed an issue that the client certificate sent to the upstream was not updated when using the `PATCH` method.
      +  [#8934](https://github.com/Kong/kong/pull/8934)
      +* Fixed an issue where the control plane and wRPC module interaction would cause Kong to crash when calling `export_deflated_reconfigure_payload` without a `pcall`.
      +  [#8668](https://github.com/Kong/kong/pull/8668)
      +* Moved all `.proto` files to `/usr/local/kong/include` and ordered by priority.
      +  [#8914](https://github.com/Kong/kong/pull/8914)
      +* Fixed an issue that caused unexpected 404 errors when creating or updating configs with invalid options.
      +  [#8831](https://github.com/Kong/kong/pull/8831)
      +* Fixed an issue that caused crashes when calling some PDK APIs.
      +  [#8604](https://github.com/Kong/kong/pull/8604)
      +* Fixed an issue that caused crashes when go PDK calls returned arrays.
      +  [#8891](https://github.com/Kong/kong/pull/8891)
      +* Plugin servers now shutdown gracefully when Kong exits.
      +  [#8923](https://github.com/Kong/kong/pull/8923)
      +* CLI now prompts with `[y/n]` instead of `[Y/n]`, as it does not take `y` as default.
      +  [#9114](https://github.com/Kong/kong/pull/9114)
      +* Improved the error message that appears when Kong can't connect to Cassandra on init.
      +  [#8847](https://github.com/Kong/kong/pull/8847)
      +* Fixed an issue where the Vault subschema wasn't loaded in the `off` strategy.
      +  [#9174](https://github.com/Kong/kong/pull/9174)
      +* The schema now runs select transformations before `process_auto_fields`.
      +  [#9049](https://github.com/Kong/kong/pull/9049)
      +* Fixed an issue where {{site.base_gateway}} would use too many timers to keep track of upstreams when `worker_consistency = eventual`.
      +  [#8694](https://github.com/Kong/kong/pull/8694),
      +  [#8858](https://github.com/Kong/kong/pull/8858)
      +* Fixed an issue where it wasn't possible to set target status using only a hostname for targets set only by their hostname.
      +  [#8797](https://github.com/Kong/kong/pull/8797)
      +* Fixed an issue where cache entries of some entities were not being properly invalidated after a cascade delete.
      +  [#9261](https://github.com/Kong/kong/pull/9261)
      +* Running `kong start` when {{site.base_gateway}} is already running no longer overwrites
      +  the existing `.kong_env` file [#9254](https://github.com/Kong/kong/pull/9254)
      +
      +
      +#### Admin API
      +
      +* The Admin API now supports `HTTP/2` when requesting `/status`.
      +  [#8690](https://github.com/Kong/kong/pull/8690)
      +* Fixed an issue where the Admin API didn't display `Allow` and `Access-Control-Allow-Methods` headers with `OPTIONS` requests.
      +
      +#### Plugins
      +
      +* Plugins with colliding priorities have now deterministic sorting based on their name.
      +  [#8957](https://github.com/Kong/kong/pull/8957)
      +
      +* External plugins: Kong Gateway now handles logging better when a plugin instance loses the `instances_id` in an event handler.
      +  [#8652](https://github.com/Kong/kong/pull/8652)
      +
      +* [ACME](/hub/kong-inc/ACME/) (`acme`)
      +  * The default value of the `auth_method` configuration parameter is now set to `token`.
      +  [#8565](https://github.com/Kong/kong/pull/8565)
      +  * Added a cache for `domains_matcher`.
      +  [#9048](https://github.com/Kong/kong/pull/9048)
      +
      +* [HTTP Log](/hub/kong-inc/http-log) (`http-log`)
      +  * Log output is now restricted to the workspace the plugin is running in. Previously,
      +  the plugin could log requests from outside of its workspace.
      +
      +* [AWS Lambda](/hub/kong-inc/aws-lambda/) (`aws-lambda`)
      +  * Removed the deprecated `proxy_scheme` field from the plugin's schema.
      +    [#8566](https://github.com/Kong/kong/pull/8566)
      +  * Changed the path from `request_uri` to `upstream_uri` to fix an issue where the URI could not follow a rule defined by the Request Transformer plugin.
      +    [#9058](https://github.com/Kong/kong/pull/9058) [#9129](https://github.com/Kong/kong/pull/9129)
      +
      +* [Forward Proxy](/hub/kong-inc/forward-proxy/) (`forward-proxy`)
      +  * Fixed a proxy authentication error caused by incorrect base64 encoding.
      +  * Use lowercase when overwriting the Nginx request host header.
      +  * The plugin now allows multi-value response headers.
      +
      +* [gRPC Gateway](/hub/kong-inc/grpc-gateway/) (`grpc-gateway`)
      +  * Fixed the handling of boolean fields from URI arguments.
      +    [#9180](https://github.com/Kong/kong/pull/9180)
      +
      +* [HMAC Authentication](/hub/kong-inc/hmac-auth/) (`hmac-auth`)
      +  * Removed deprecated signature format using `ngx.var.uri`.
      +    [#8558](https://github.com/Kong/kong/pull/8558)
      +
      +* [LDAP Authentication](/hub/kong-inc/ldap-auth) (`ldap-auth`)
      +  * Refactored ASN.1 parser using OpenSSL API through FFI.
      +    [#8663](https://github.com/Kong/kong/pull/8663)
      +
      +* [LDAP Authentication Advanced](/hub/kong-inc/ldap-auth-advanced) (`ldap-auth-advanced`)
      +  * Fixed an issue where Kong Manager LDAP authentication failed when `base_dn` was the domain root.
      +
      +* [Mocking](/hub/kong-inc/mocking) (`mocking`)
      +  * Fixed an issue where `204` responses were not handled correctly and you would see the following error:
      +`"No examples exist in API specification for this resource"`.
      +  * `204` response specs now support empty content elements.
      +
      +* [OpenID Connect](/hub/kong-inc/openid-connect/) (`openid-connect`)
      +openid-connect
      +  * Fixed an issue with `kong_oauth2` consumer mapping.
      +
      +* [Rate Limiting](/hub/kong-inc/rate-limiting) (`rate-limiting`) and [Response Rate Limiting](/hub/kong-inc/response-ratelimiting) (`response-ratelimiting`)
      +  * Fixed a PostgreSQL deadlock issue that occurred when the `cluster` policy was used with two or more metrics (for example, `second` and `day`.)
      +    [#8968](https://github.com/Kong/kong/pull/8968)
      +
      +* [Rate Limiting Advanced](/hub/kong-inc/rate-limiting-advanced/) (`rate-limiting-advanced`)
      +  * Fixed error handling when calling `get_window` and added more buffer on the window reserve.
      +  * Fixed error handling for plugin strategy configuration when in hybrid or DB-less mode and strategy is set to `cluster`.
      +
      +* [Serverless Functions](/hub/kong-inc/serverless-functions/) (`serverless-functions`)
      +  * Fixed a problem that could cause a crash.
      +  [#9269](https://github.com/Kong/kong/pull/9269)
      +
      +* [Syslog](/hub/kong-inc/syslog/) (`syslog`)
      +  * The `conf.facility` default value is now set to `user`.
      +    [#8564](https://github.com/Kong/kong/pull/8564)
      +
      +* [Zipkin](/hub/kong-inc/zipkin) (`zipkin`)
      +  * Fixed the balancer spans' duration to include the connection time
      +  from Nginx to the upstream.
      +    [#8848](https://github.com/Kong/kong/pull/8848)
      +  * Corrected the calculation of the header filter start time.
      +    [#9230](https://github.com/Kong/kong/pull/9230)
      +  * Made the plugin compatible with the latest [Jaeger header spec](https://www.jaegertracing.io/docs/1.29/client-libraries/#tracespan-identity), which makes `parent_id` optional.
      +  [#8352](https://github.com/Kong/kong/pull/8352)
      +
      +#### Clustering
      +
      +* The cluster listener now uses the value of `admin_error_log` for its log file
      +  instead of `proxy_error_log`.
      +  [#8583](https://github.com/Kong/kong/pull/8583)
      +* Fixed a typo in some business logic that checks the Kong role before setting a
      +  value in cache at startup. [#9060](https://github.com/Kong/kong/pull/9060)
      +* Fixed an issue in hybrid mode where, if a service was set to `enabled: false` and that service had a route with an enabled plugin, any new data planes would receive empty configuration.
      +  [#8816](https://github.com/Kong/kong/pull/8816)
      +* Localized `config_version` to avoid a race condition from the new yielding config loading code.
      +  [#8188](https://github.com/Kong/kong/pull/8818)
      +
      +#### PDK
      +
      +* `kong.response.get_source()` now returns an error instead of an exit when plugin throws a
      +  runtime exception in the access phase.
      +  [#8599](https://github.com/Kong/kong/pull/8599)
      +* `kong.tools.uri.normalize()` now escapes reserved and unreserved characters more accurately.
      +  [#8140](https://github.com/Kong/kong/pull/8140)
      +
      +
      +* RFC3987 validation on route paths was removed, allowing operators to create a route with an invalid path
      +  URI like `/something|` which can not match any incoming request. This validation will be added back in a future release.
      +
      +### Dependencies
      +
      +* Bumped `openresty` from 1.19.9.1 to 1.21.4.1
      +  [#8850](https://github.com/Kong/kong/pull/8850)
      +* Bumped `pgmoon` from 1.13.0 to 1.15.0
      +  [#8908](https://github.com/Kong/kong/pull/8908)
      +  [#8429](https://github.com/Kong/kong/pull/8429)
      +* Bumped `openssl` from 1.1.1n to 1.1.1q
      +  [#9074](https://github.com/Kong/kong/pull/9074)
      +  [#8544](https://github.com/Kong/kong/pull/8544)
      +  [#8752](https://github.com/Kong/kong/pull/8752)
      +  [#8994](https://github.com/Kong/kong/pull/8994)
      +* Bumped `resty.openssl` from 0.8.8 to 0.8.10
      +  [#8592](https://github.com/Kong/kong/pull/8592)
      +  [#8753](https://github.com/Kong/kong/pull/8753)
      +  [#9023](https://github.com/Kong/kong/pull/9023)
      +* Bumped `inspect` from 3.1.2 to 3.1.3
      +  [#8589](https://github.com/Kong/kong/pull/8589)
      +* Bumped `resty.acme` from 0.7.2 to 0.8.1
      +  [#8680](https://github.com/Kong/kong/pull/8680)
      +  [#9165](https://github.com/Kong/kong/pull/9165)
      +* Bumped `luarocks` from 3.8.0 to 3.9.1
      +  [#8700](https://github.com/Kong/kong/pull/8700)
      +  [#9204](https://github.com/Kong/kong/pull/9204)
      +* Bumped `luasec` from 1.0.2 to 1.2.0
      +  [#8754](https://github.com/Kong/kong/pull/8754)
      +  [#8754](https://github.com/Kong/kong/pull/9205)
      +* Bumped `resty.healthcheck` from 1.5.0 to 1.6.1
      +  [#8755](https://github.com/Kong/kong/pull/8755)
      +  [#9018](https://github.com/Kong/kong/pull/9018)
      +  [#9150](https://github.com/Kong/kong/pull/9150)
      +* Bumped `resty.cassandra` from 1.5.1 to 1.5.2
      +  [#8845](https://github.com/Kong/kong/pull/8845)
      +* Bumped `penlight` from 1.12.0 to 1.13.1
      +  [#9206](https://github.com/Kong/kong/pull/9206)
      +* Bumped `lua-resty-mlcach`e from 2.5.0 to 2.6.0
      +  [#9287](https://github.com/Kong/kong/pull/9287)
      +* Bumped `lodash` for Dev Portal from 4.17.11 to 4.17.21
      +* Bumped `lodash` for Kong Manager from 4.17.15 to 4.17.21
      +
      +## 2.8.1.4
      +**Release Date**  2022/08/23
      +
       * Fixed vulnerabilities [CVE-2022-37434](https://nvd.nist.gov/vuln/detail/CVE-2022-37434) and [CVE-2022-24975](https://nvd.nist.gov/vuln/detail/CVE-2022-24975).
       
       * When using secrets management in free mode, only the [environment variable](/gateway/2.8.x/plan-and-deploy/security/secrets-management/backends/env) backend is available. AWS, GCP, and HashiCorp vault backends require an Enterprise license.
      @@ -123,6 +933,33 @@ Kong Manager was constructing the wrong URL when retrieving Dev Portal assignees
       `"No examples exist in API specification for this resource"`.
         * `204` response specs now support empty content elements.
       
      +### Deprecated
      +
      +* **Amazon Linux 1**: Support for running Kong Gateway on Amazon Linux 1 is now deprecated, as the
      +[Amazon Linux (1) AMI has ended standard support as of December 31, 2020](https://aws.amazon.com/blogs/aws/update-on-amazon-linux-ami-end-of-life).
      +Starting with Kong Gateway 3.0.0.0, Kong is not building new Amazon Linux 1
      +images or packages, and Kong will not test package installation on Amazon Linux 1.
      +
      +    If you need to install Kong Gateway on Amazon Linux 1, see the documentation for
      +    [previous versions](/gateway/2.8.x/install-and-run/amazon-linux/).
      +
      +* **Debian 8**: Support for running Kong Gateway on Debian 8 ("Jessie") is now deprecated, as
      +[Debian 8 ("Jessie") has reached End of Life (EOL)](https://www.debian.org/News/2020/20200709).
      +Starting with Kong Gateway 3.0.0.0, Kong is not building new Debian 8
      +("Jessie") images or packages, and Kong will not test package installation on
      +Debian 8 ("Jessie").
      +
      +    If you need to install Kong Gateway on Debian 8 ("Jessie"), see the documentation for
      +    [previous versions](/gateway/2.8.x/install-and-run/debian/).
      +
      +* **Ubuntu 16.04**: Support for running Kong Gateway on Ubuntu 16.04 ("Xenial") is now deprecated,
      +as [Standard Support for Ubuntu 16.04 has ended as of April, 2021](https://wiki.ubuntu.com/Releases).
      +Starting with Kong Gateway 3.0.0.0, Kong is not building new Ubuntu 16.04
      +images or packages, and Kong will not test package installation on Ubuntu 16.04.
      +
      +    If you need to install Kong Gateway on Ubuntu 16.04, see the documentation for
      +    [previous versions](/gateway/2.8.x/install-and-run/ubuntu/).
      +
       ## 2.8.1.1
       **Release Date** 2022/05/27
       
      @@ -373,7 +1210,7 @@ making your environment more secure.
         and `session_redis_password` configuration fields are now marked as
         referenceable, which means they can be securely stored as
         [secrets](/gateway/latest/plan-and-deploy/security/secrets-management/getting-started)
      -  in a vault. References must follow a [specific format](/gateway/latest/plan-and-deploy/security/secrets-management/reference-format).
      +  in a vault. References must follow a [specific format](/gateway/{{page.kong_version}}/kong-enterprise/security/secrets-management/reference-format).
       
       * [Forward Proxy Advanced](/hub/kong-inc/forward-proxy/) (`forward-proxy`)
       
      @@ -387,7 +1224,7 @@ making your environment more secure.
         * The `auth_password` and `auth_username` configuration fields are now marked as
         referenceable, which means they can be securely stored as
         [secrets](/gateway/latest/plan-and-deploy/security/secrets-management/getting-started)
      -  in a vault. References must follow a [specific format](/gateway/latest/plan-and-deploy/security/secrets-management/reference-format).
      +  in a vault. References must follow a [specific format](/gateway/{{page.kong_version}}/kong-enterprise/security/secrets-management/reference-format).
       
       * [Kafka Upstream](/hub/kong-inc/kafka-upstream/) (`kafka-upstream`) and [Kafka Log](/hub/kong-inc/kafka-log) (`kafka-log`)
       
      @@ -397,21 +1234,21 @@ making your environment more secure.
         * **Beta feature:** The `authentication.user` and `authentication.password` configuration fields are now marked as
         referenceable, which means they can be securely stored as
         [secrets](/gateway/latest/plan-and-deploy/security/secrets-management/getting-started)
      -  in a vault. References must follow a [specific format](/gateway/latest/plan-and-deploy/security/secrets-management/reference-format).
      +  in a vault. References must follow a [specific format](/gateway/{{page.kong_version}}/kong-enterprise/security/secrets-management/reference-format).
       
       * [LDAP Authentication Advanced](/hub/kong-inc/ldap-auth-advanced) (`ldap-auth-advanced`)
       
         * **Beta feature:** The `ldap_password` and `bind_dn` configuration fields are now marked as
         referenceable, which means they can be securely stored as
         [secrets](/gateway/latest/plan-and-deploy/security/secrets-management/getting-started)
      -  in a vault. References must follow a [specific format](/gateway/latest/plan-and-deploy/security/secrets-management/reference-format).
      +  in a vault. References must follow a [specific format](/gateway/{{page.kong_version}}/kong-enterprise/security/secrets-management/reference-format).
       
       * [Vault Authentication](/hub/kong-inc/vault-auth/) (`vault-auth`)
       
         * **Beta feature:** The `vaults.vault_token` form field is now marked as
         referenceable, which means it can be securely stored as a
      -  [secret](/gateway/latest/plan-and-deploy/security/secrets-management/getting-started)
      -  in a vault. References must follow a [specific format](/gateway/latest/plan-and-deploy/security/secrets-management/reference-format).
      +  [secret](/gateway/{{page.kong_version}}/kong-enterprise/security/secrets-management/getting-started)
      +  in a vault. References must follow a [specific format](/gateway/{{page.kong_version}}/kong-enterprise/security/secrets-management/reference-format).
       
       * [GraphQL Rate Limiting Advanced](/hub/kong-inc/graphql-rate-limiting-advanced/) (`graphql-rate-limiting-advanced`)
       
      @@ -422,7 +1259,7 @@ making your environment more secure.
         * **Beta feature:** The `redis.username`, `redis.password`, `redis.sentinel_username`, and `redis.sentinel_password`
         configuration fields are now marked as referenceable, which means they can be securely stored as
         [secrets](/gateway/latest/plan-and-deploy/security/secrets-management/getting-started)
      -  in a vault. References must follow a [specific format](/gateway/latest/plan-and-deploy/security/secrets-management/reference-format).
      +  in a vault. References must follow a [specific format](/gateway/{{page.kong_version}}/kong-enterprise/security/secrets-management/reference-format).
       
       * [Rate Limiting](/hub/kong-inc/rate-limiting/) (`rate-limiting`)
       
      @@ -434,7 +1271,7 @@ making your environment more secure.
         * **Beta feature:** The `redis.username`, `redis.password`, `redis.sentinel_username`, and `redis.sentinel_password`
         configuration fields are now marked as referenceable, which means they can be securely stored as
         [secrets](/gateway/latest/plan-and-deploy/security/secrets-management/getting-started)
      -  in a vault. References must follow a [specific format](/gateway/latest/plan-and-deploy/security/secrets-management/reference-format).
      +  in a vault. References must follow a [specific format](/gateway/{{page.kong_version}}/kong-enterprise/security/secrets-management/reference-format).
       
       * [Response Rate Limiting](/hub/kong-inc/response-ratelimiting/) (`response-ratelimiting`)
         * Added Redis ACL support (Redis v6.0.0+ and Redis Sentinel v6.2.0+).
      @@ -455,7 +1292,7 @@ making your environment more secure.
         * **Beta feature:**  The `redis.password`, `redis.sentinel_username`, and `redis.sentinel_password`
         configuration fields are now marked as referenceable, which means they can be
         securely stored as [secrets](/gateway/latest/plan-and-deploy/security/secrets-management/getting-started)
      -  in a vault. References must follow a [specific format](/gateway/latest/plan-and-deploy/security/secrets-management/reference-format).
      +  in a vault. References must follow a [specific format](/gateway/{{page.kong_version}}/kong-enterprise/security/secrets-management/reference-format).
       
       * [jq](/hub/kong-inc/jq/) (`jq`)
         * Use response buffering from the PDK.
      diff --git a/app/konnect-platform/guides.md b/app/konnect-platform/guides.md
      deleted file mode 100644
      index fe847969b6cf..000000000000
      --- a/app/konnect-platform/guides.md
      +++ /dev/null
      @@ -1,23 +0,0 @@
      ----
      -title: Get Started with the Konnect Platform
      -no_version: true
      ----
      -
      -{{site.konnect_product_name}} is a versatile platform. To get started, choose
      -your deployment type:
      -
      -* **{{site.konnect_saas}} deployment**: Let Kong host the control plane
      -and you only need to provide the data plane node. Spin up a simple
      -{{site.base_gateway}} runtime with Docker, create a service, and implement it
      -in minutes. See the
      -[{{site.konnect_saas}} quickstart guide](/konnect/getting-started/) to get
      -started.
      -
      -* **Self-managed deployment**:
      -Install {{site.base_gateway}}, then use the {{site.base_gateway}} guide for a
      -detailed walkthrough of foundational API gateway concepts, features, and
      -capabilities.
      -    * For a traditional deployment, see the [Kong gateway installation guides](/gateway/latest/install-and-run).
      -    * For a hybrid mode deployment, use the [hybrid mode post-installation instructions](/gateway/latest/plan-and-deploy/hybrid-mode/hybrid-mode-setup).
      -    * Once everything is installed, check out the
      -    [self-managed getting started guide](/gateway/latest/get-started/comprehensive).
      diff --git a/app/konnect-platform/index.md b/app/konnect-platform/index.md
      deleted file mode 100644
      index 579bcf7f6ef9..000000000000
      --- a/app/konnect-platform/index.md
      +++ /dev/null
      @@ -1,122 +0,0 @@
      ----
      -title: Kong Konnect
      -subtitle: The full-stack connectivity platform for cloud-native applications
      -no_version: true
      ----
      -
      -## End-to-end Service Connectivity Platform  
      -We live in a connected world. Every application we use, whether within or outside
      -of work, is built on top of dozens, sometimes hundreds of **services** that
      -enable our digital, connected experiences. For example, think of an application
      -that allows you to control your garden sprinklers. While it may seem
      -simple on the surface, underlying that application are likely a dozen or so
      -services as illustrated below.
      -
      -![{{site.konnect_product_name}} Overview](/assets/images/docs/konnect/konnect-overview.png)
      -
      -In the diagram above, each of the red circles represents a
      -**connectivity end-point**. At each of these points, **connectivity logic** is
      -required. Connectivity logic addresses concerns such as ensuring that incoming
      -requests are authenticated, authorized, rate-limited, and logged, or that, as
      -a new version of a service is introduced, requests from incompatible older
      -versions of the service’s consumers are routed to the older version.
      -
      -Most organizations build and manage their connectivity logic from scratch many
      -times over across each team, application, and service. This Do-It-Yourself
      -approach is unfortunately not only inefficient, but it also leads to
      -significantly lowered reliability, speed, and insight across the connected
      -experiences that form the touchpoints (web apps, mobile apps, APIs) of the
      -modern organization’s interactions with its customers, partners, and employees.
      -
      -As a Service Connectivity Platform (SCP), {{site.konnect_short_name}} enables
      -*reliability*, *speed*, and *insight* by providing common, out-of-the-box
      -connectivity logic, executed through **connectivity runtimes** and managed
      -through **functionality modules** across points of connectivity within your
      -applications.
      -
      -### Reliability
      -If connectivity logic fails — for example, a piece of logic that
      -authenticates incoming requests — there could be serious security and
      -availability consequences. {{site.konnect_short_name}} provides rock-solid,
      -pre-validated, and tested connectivity logic that can be applied to connectivity
      -endpoints and executed through highly reliable connectivity runtimes,
      -minimizing the risks of service failures and security vulnerabilities.
      -
      -The components of {{site.konnect_short_name}} that enable this reliability
      -are defined in the following table:
      -
      -| {{site.konnect_short_name}} Component {:width=20%:} | Description |
      -|---------------------------------------|-------------|
      -| [{{site.base_gateway}}](/gateway/)  | High-performance connectivity runtime for executing edge connectivity logic. |
      -| [Kong Ingress Controller](/kubernetes-ingress-controller/) | High-performance connectivity runtime for executing inter-app connectivity logic within a Kubernetes environment. |
      -| [{{site.mesh_product_name}}](/mesh/)  | High-performance connectivity runtime for executing in-app connectivity logic. {{site.mesh_product_name}} is built on the Kuma service mesh open-source project. |
      -| [Kong Plugins](/hub)                        | Secure, tested, and reliable connectivity logic for all connectivity needs applied through the {{site.base_gateway}} and Kong Ingress Controller runtimes. Many plugins are built and supported by {{site.company_name}}, and a wide array of plugins are also built and maintained by the Kong community. |
      -| [Runtime Manager](/konnect/runtime-manager)
      (Cloud only) | Functionality module that enables provisioning instances of {{site.konnect_short_name}}’s supported runtimes. Runtime Manager provides a unified view of all of these runtimes and their current status.

      **Note:** Currently, the only supported runtime type in the Runtime Manager is a {{site.base_gateway}} data plane. | - -### Speed -{{site.konnect_short_name}} provides increased velocity of service development -and faster connectivity runtime performance. - -#### Service Development Velocity -The connectivity logic that comes out of the box with -{{site.konnect_short_name}} allows developers to focus on business logic and -not need to rewrite a piece of connectivity logic every time. In turn, this -leads to faster development. {{site.konnect_short_name}} enables developers to -rapidly search for and discover existing services, which they can reuse to -accelerate the development of their applications. - -The components of {{site.konnect_short_name}} that enable service development -velocity are defined in the following table: - -| {{site.konnect_short_name}} Component {:width=20%:} | Description | -|------------------------------|-------------| -| [Insomnia](https://support.insomnia.rest/) | API debugging, design, and testing tool for developers. Allows developers to rapidly explore and consume existing services of different protocols (spawning REST, GraphQL, and gRPC), design services using a spec-based approach, and write and build a suite of tests while collaborating with other developers.

      Using Insomnia, you can generate {{site.base_gateway}} and Kong Ingress Controller runtime configurations directly from their API specs. Developers can rapidly map their API designs to connectivity logic that exposes those designs within a connectivity runtime. | -| Dev Portal

      [Cloud docs](/konnect/dev-portal)
      [Self-managed docs](/gateway/latest/developer-portal) | Functionality module that enables the formal publishing of API docs to an API catalogue through which developers (typically external to an application team) can discover and formally register to use the API. | -| [ServiceHub](/konnect/servicehub)
      (Cloud only) | Functionality module that enables the cataloging of all services into a single system of record. This catalog represents the single source of truth for your organization’s service inventory and their dependencies. By leveraging ServiceHub, application developers can search, discover, and consume existing services to accelerate their time-to-market, while enabling a more consistent end-user experience across the organization’s applications. | - -#### Connectivity Runtime Performance -Any unnecessary latency incurred in the execution of connectivity logic is -compounded across each of the dozens to hundreds of connectivity endpoints -underlying modern applications. All of {{site.konnect_short_name}}’s -out-of-the-box high performance connectivity logic and connectivity runtimes are -optimized to minimize this latency. - -### Insight -Connectivity endpoints provide sources of insight across three different dimensions: - -* At the service level: for example, how many versions of Service A are there -and what does each version's interface look like? -* At the application level: for example, what is the overall uptime of the -Device App? -* At the business level: for example, which device types use our applications -the most? - -{{site.konnect_short_name}} captures this insight and provides tools that make -it easily accessible to any stakeholders. The components of -{{site.konnect_short_name}} that enable service development velocity are -defined in the following table: - -| {{site.konnect_short_name}} Component {:width=20%:} | Description | -|---------------------------------------|-------------| -| Vitals

      [Cloud docs](/konnect/vitals)
      [Self-managed docs](/gateway/latest/vitals/) | Functionality module that enables the capture and generation of service usage and health monitoring data. This module's capabilities can be enhanced with {{site.konnect_short_name}} plugins that enable monitoring metrics to be streamed to third-party analytics providers such as Datadog and Prometheus. | -| [ServiceHub](/konnect/servicehub)
      (Cloud only) | Functionality module that enables the cataloging all of all services into a single system of record that represents the single source of truth of your organization’s service inventory and their dependencies. By leveraging ServiceHub, enterprise architects can attain a better understanding of the organization’s inventory of services, in terms of the level of reuse, usage, and operational health of services across different teams and environments. | - -#### Cloud-native Service Lifecycle -As the number of connectivity endpoints and runtimes increases, the automation -of their lifecycles becomes more critical, as automation allows for a high -velocity of change in a reliable manner. {{site.konnect_short_name}} is designed -from the ground up to enable this level of automation across both legacy -environments and more modern, containerized infrastructure. It provides all -capabilities through CLIs, declarative configuration interfaces, and -well-defined APIs. - -The components of {{site.konnect_short_name}} that enable this cloud-native -lifecycle are as follows: - -| {{site.konnect_short_name}} Component {:width=20%:}| Description | -|------------------------------|-------------| -| [decK](/deck) | decK is a tool that allows for the management of {{site.base_gateway}}’s configuration in a declarative fashion. It can sync configuration to a running cluster, diff configuration to detect any drift or manual changes, and back up {{site.base_gateway}}'s configuration. It also can manage the configuration in a distributed way using tags, helping you split configuration across various teams. | -| [Kong Ingress Controller CRDs](/kubernetes-ingress-controller/latest/concepts/custom-resources) | The Kong Ingress Controller runtime’s lifecycle can be managed entirely through Kubernetes CRD manifests, which can be applied through the Kubernetes `kubectl` command line. | -| [{{site.base_gateway}}’s Admin API](/gateway/latest/admin-api) | The {{site.base_gateway}} runtime provides an internal REST-based Admin API. Requests to the Admin API can be sent from any node in the cluster, and {{site.konnect_short_name}} will keep the configuration consistent across all nodes. | -| [Inso command line](https://support.insomnia.rest/collection/105-inso-cli) | Inso is a CLI for Insomnia that exposes Insomnia’s application functionality to be invoked via a terminal or within a CI/CD pipeline for automation of API debugging, testing, and configuration generation. | -| [{{site.konnect_saas}} Admin API](/konnect/reference/konnect-api) | {{site.konnect_short_name}} provides a REST-based Cloud API that exposes all of the functionality of its Cloud web interfaces. | diff --git a/app/konnect-platform/key-concepts.md b/app/konnect-platform/key-concepts.md deleted file mode 100644 index f178e56d4254..000000000000 --- a/app/konnect-platform/key-concepts.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: Key Concepts and Terminology -no_version: true ---- - -Kong uses common terms for entities and processes that have a specific meaning in context. This topic provides a conceptual overview of terms, and how they apply to Kong’s use cases. - -## Stages of software availability - -### Tech preview -A feature that is in tech preview might have limited to no documentation, is not guaranteed to be made available as GA in the future, and should not be deployed to production environments. - -### Beta -A Beta designation in Kong software means the functionality of a feature or release version is of high quality and can be deployed in a non-production environment. Note the following when using a Beta feature or version: - -* **A Beta feature or version should not be deployed in a production environment.** -* Beta customers are encouraged to engage Kong Support to report issues encountered in Beta testing. Support requests should be filed with normal priority, but contractual SLA’s will not be applicable for Beta features. -* Support is not available for data recovery, rollback, or other tasks when using a Beta feature or version. -* User documentation might not be available, complete, or reflect entire functionality. - -A Beta feature or version is made available to the general public for usability testing and to gain feedback about the feature or version before releasing it as a production-ready, stable feature or version. - -### General availability -General availability, or GA, means that the software is released publically and -is supported according to Kong's [support and maintenance policy](https://konghq.com/wp-content/uploads/2021/04/Kong-Support-and-Maintenance-Policy-16-April-2021.pdf). diff --git a/app/konnect/availability-stages.md b/app/konnect/availability-stages.md new file mode 100644 index 000000000000..235cee833b1a --- /dev/null +++ b/app/konnect/availability-stages.md @@ -0,0 +1,7 @@ +--- +title: Stages of software availability +content-type: reference +no_version: true +--- + +{% include_cached /md/availability-stages.md %} diff --git a/app/konnect/compatibility.md b/app/konnect/compatibility.md index e1358ece0425..2e6b7932e80b 100644 --- a/app/konnect/compatibility.md +++ b/app/konnect/compatibility.md @@ -23,3 +23,103 @@ data plane. | {{site.ee_product_name}} 2.6.x | | 2.6.0.0 | {{site.ee_product_name}} 2.5.x | | 2.5.0.1 | {{site.ee_product_name}} 2.4.x or earlier | | -- + + +## Plugin Compatibility + +Each [subscription tier](https://konghq.com/pricing) gives you +access to a subset of plugins: +* **Free tier:** Open-source Kong plugins +* **Plus tier:** Open-source and Plus-specific plugins +* **Enterprise tier:** All Kong plugins + +### Network configuration options + +{{site.konnect_short_name}} can be configured in the following ways: + +* **Kong-hosted cloud**: Hybrid deployment. Nodes are split into control plane and +data plane roles. Kong provides and hosts the control plane and a database with +{{site.konnect_saas}}, and you provide the data plane nodes (no databases required). + +* **Self-managed**: Use any hosting service of your choice or host on-premises, +with any of the following network configurations: + * **Classic:** Every node is connected to a database. Refers to a classic + deployment on any platform, including Kubernetes. + * **DB-less:** Deployed without a database (available in {{site.ce_product_name}} + 1.1 and {{site.ee_product_name}} 2.4 onward). Admin API is read-only, + except for the `/config` endpoint. Refers to a DB-less deployment on any + platform, including Kubernetes. + * **Hybrid mode:** Nodes are split into control plane and data plane roles. + The control plane coordinates configuration and propagates it to data plane + nodes, so only control plane nodes require a database + (available in {{site.ce_product_name}} 2.0 and {{site.ee_product_name}} 2.1 onward). + + +For the differences between deployment types when running on Kubernetes, +see [{{site.ee_product_name}} for Kubernetes Deployment Options](/gateway/latest/plan-and-deploy/kubernetes-deployment-options/). + +## Plugin tiers and supported network configurations + + +{% assign categories = site.data.tables.plugin_index %} + +{% for category in categories %} +

      + {{ category.name }} +

      + + + + + + + + + + + + {% for plugin in category.plugins %} + + + + + + + + + {% endfor %} + +
      PluginFreePlusEnterpriseSupported network configurationNotes
      + {{ plugin.name }} + + {% if plugin.free == true %} + ✅  + {% elsif plugin.free == false %} + ❌  + {% endif %} + + {% if plugin.plus == true %} + ✅  + {% elsif plugin.plus == false %} + ❌  + {% endif %} + + {% if plugin.enterprise == true %} + ✅  + {% elsif plugin.enterprise == false %} + ❌  + {% endif %} + + {{ plugin.network_config_opts }} + + {{ plugin.notes }} +
      + +{% endfor %} + +### Deployment + +[Deployment plugins](/hub) are not bundled with any version of Konnect, and are +simply tools to help you deploy Kong Gateway in various environments. diff --git a/app/konnect/servicehub/plugins.md b/app/konnect/servicehub/plugins.md index aafe32bcc81f..2d12a9394f31 100644 --- a/app/konnect/servicehub/plugins.md +++ b/app/konnect/servicehub/plugins.md @@ -49,7 +49,7 @@ The following plugins are not available with {{site.konnect_saas}}: * GraphQL Rate Limiting Advanced * Key Authentication Encrypted -See the [plugin compatibility chart](/konnect-platform/compatibility/plugins) +See the [plugin compatibility chart](/hub/plugins/compatibility) for a full comparison of plans and network configurations that each plugin supports. diff --git a/app/mesh/1.4.x/index.md b/app/mesh/1.4.x/index.md index 3222c0f1c15f..b13a646ef8db 100644 --- a/app/mesh/1.4.x/index.md +++ b/app/mesh/1.4.x/index.md @@ -22,7 +22,7 @@ both Kubernetes and VMs on any cloud. Built on top of CNCF's {{site.mesh_product_name}} extends Kuma and Envoy with enterprise features and support, while providing native integration with -[{{site.ee_product_name}}](https://konghq.com/products/kong-enterprise) for a +[{{site.ee_product_name}}](https://konghq.com/products/api-gateway-platform) for a full-stack connectivity platform for all of your services and APIs, across every cloud and environment. @@ -68,8 +68,8 @@ for both edge and internal API traffic.
      Two different applications - "Banking" and "Trading" - run in their - own meshes "A" and "B" across different datacenters. In this example, - Kong Gateway is being used both for edge communication, and for internal + own meshes "A" and "B" across different data centers. In this example, + {{site.base_gateway}} is being used both for edge communication, and for internal communication between meshes. @@ -129,7 +129,7 @@ hybrid Kubernetes/VMs:
      {{site.mesh_product_name}} can support multiple zones (like a Kubernetes - cluster, VPC, datacenter, etc.) together in the same distributed deployment. + cluster, VPC, data center, etc.) together in the same distributed deployment. Then, you can create multiple isolated virtual meshes with the same control plane in order to support every team and application in the organization. @@ -142,5 +142,5 @@ standalone and multi-zone deployment modes in the Kuma documentation. Kong primarily follows a [semantic versioning](https://semver.org/) (SemVer) model for its products. -For the latest version support information for {{site.ee_product_name}} and -{{site.mesh_product_name}}, see our [version support policy](/konnect-platform/support-policy). +For the latest version support information for +{{site.mesh_product_name}}, see our [version support policy](/mesh/latest/support-policy). diff --git a/app/mesh/1.5.x/index.md b/app/mesh/1.5.x/index.md index 7a57da95a4ca..b13a646ef8db 100644 --- a/app/mesh/1.5.x/index.md +++ b/app/mesh/1.5.x/index.md @@ -22,7 +22,7 @@ both Kubernetes and VMs on any cloud. Built on top of CNCF's {{site.mesh_product_name}} extends Kuma and Envoy with enterprise features and support, while providing native integration with -[{{site.ee_product_name}}](https://konghq.com/products/kong-enterprise) for a +[{{site.ee_product_name}}](https://konghq.com/products/api-gateway-platform) for a full-stack connectivity platform for all of your services and APIs, across every cloud and environment. @@ -68,8 +68,8 @@ for both edge and internal API traffic.
      Two different applications - "Banking" and "Trading" - run in their - own meshes "A" and "B" across different datacenters. In this example, - Kong Gateway is being used both for edge communication, and for internal + own meshes "A" and "B" across different data centers. In this example, + {{site.base_gateway}} is being used both for edge communication, and for internal communication between meshes. @@ -129,7 +129,7 @@ hybrid Kubernetes/VMs:
      {{site.mesh_product_name}} can support multiple zones (like a Kubernetes - cluster, VPC, datacenter, etc.) together in the same distributed deployment. + cluster, VPC, data center, etc.) together in the same distributed deployment. Then, you can create multiple isolated virtual meshes with the same control plane in order to support every team and application in the organization. @@ -137,3 +137,10 @@ hybrid Kubernetes/VMs:
      [Learn more](https://kuma.io/docs/latest/introduction/deployments/) about the standalone and multi-zone deployment modes in the Kuma documentation. + +## Support policy +Kong primarily follows a [semantic versioning](https://semver.org/) (SemVer) +model for its products. + +For the latest version support information for +{{site.mesh_product_name}}, see our [version support policy](/mesh/latest/support-policy). diff --git a/app/mesh/1.6.x/index.md b/app/mesh/1.6.x/index.md index e8f5d59f1d7e..44058b46979f 100644 --- a/app/mesh/1.6.x/index.md +++ b/app/mesh/1.6.x/index.md @@ -22,7 +22,7 @@ both Kubernetes and VMs on any cloud. Built on top of CNCF's {{site.mesh_product_name}} extends Kuma and Envoy with enterprise features and support, while providing native integration with -[{{site.ee_product_name}}](https://konghq.com/products/kong-enterprise) for a +[{{site.ee_product_name}}](https://konghq.com/products/api-gateway-platform) for a full-stack connectivity platform for all of your services and APIs, across every cloud and environment. @@ -68,8 +68,8 @@ for both edge and internal API traffic.
      Two different applications - "Banking" and "Trading" - run in their - own meshes "A" and "B" across different datacenters. In this example, - Kong Gateway is being used both for edge communication and for internal + own meshes "A" and "B" across different data centers. In this example, + {{site.base_gateway}} is being used both for edge communication and for internal communication between meshes. @@ -129,7 +129,7 @@ hybrid Kubernetes/VMs:
      {{site.mesh_product_name}} can support multiple zones (like a Kubernetes - cluster, VPC, datacenter, etc.) together in the same distributed deployment. + cluster, VPC, data center, etc.) together in the same distributed deployment. Then, you can create multiple isolated virtual meshes with the same control plane in order to support every team and application in the organization. @@ -137,3 +137,10 @@ hybrid Kubernetes/VMs:
      [Learn more](https://kuma.io/docs/latest/introduction/deployments/) about the standalone and multi-zone deployment modes in the Kuma documentation. + +## Support policy +Kong primarily follows a [semantic versioning](https://semver.org/) (SemVer) +model for its products. + +For the latest version support information for +{{site.mesh_product_name}}, see our [version support policy](/mesh/latest/support-policy). diff --git a/app/moved_urls.yml b/app/moved_urls.yml index 42c160948b3b..904601348f7b 100644 --- a/app/moved_urls.yml +++ b/app/moved_urls.yml @@ -1,2 +1,155 @@ --- /gateway-oss/VERSION/configuration/: "/gateway/VERSION/reference/configuration/" +/gateway/VERSION/get-started/configure-services-and-routes/: "/gateway/VERSION/get-started/services-and-routes/" +/gateway/VERSION/install-and-run/: "/gateway/VERSION/install/" +/gateway/VERSION/install-and-run/kubernetes/: "/gateway/VERSION/install/kubernetes/kubectl/" +/gateway/VERSION/install-and-run/helm/: "/gateway/VERSION/install/kubernetes/helm-quickstart/" +/gateway/VERSION/install-and-run/openshift/: "/gateway/VERSION/install/kubernetes/openshift/" +/gateway/VERSION/install-and-run/helm-quickstart-enterprise/: "/gateway/VERSION/install/kubernetes/helm-quickstart/" +/gateway/VERSION/install-and-run/docker/: "/gateway/VERSION/install/docker/" +/gateway/VERSION/install-and-run/amazon-linux/: "/gateway/VERSION/install/linux/amazon-linux/" +/gateway/VERSION/install-and-run/macos/: "/gateway/VERSION/install/macos/" +/gateway/VERSION/install-and-run/debian/: "/gateway/VERSION/install/linux/debian/" +/gateway/VERSION/install-and-run/rhel/: "/gateway/VERSION/install/linux/rhel/" +/gateway/VERSION/install-and-run/ubuntu/: "/gateway/VERSION/install/linux/ubuntu/" +/gateway/VERSION/install-and-run/centos/: "/gateway/VERSION/install/linux/os-support/" +/gateway/VERSION/install-and-run/migrate-ce-to-ke/: "/gateway/VERSION/migrate-ce-to-ke/" +/gateway/VERSION/install-and-run/upgrade-enterprise/: "/gateway/VERSION/upgrade/" +/gateway/VERSION/install-and-run/upgrade-oss/: "/gateway/VERSION/upgrade/" +/gateway/VERSION/get-started/quickstart/: "/gateway/VERSION/get-started/" +/gateway/VERSION/get-started/quickstart/configuring-a-service/: "/gateway/VERSION/get-started/services-and-routes/" +/gateway/VERSION/get-started/quickstart/configuring-a-grpc-service/: "/gateway/VERSION/kong-plugins/configuring-a-grpc-service/" +/gateway/VERSION/get-started/quickstart/enabling-plugins/: "/gateway/VERSION/get-started/rate-limiting/" +/gateway/VERSION/get-started/quickstart/adding-consumers/: "/gateway/VERSION/get-started/key-authentication/" +/gateway/VERSION/get-started/comprehensive/prepare/: "/gateway/VERSION/get-started/" +/gateway/VERSION/get-started/comprehensive/expose-services/: "/gateway/VERSION/get-started/services-and-routes/" +/gateway/VERSION/get-started/comprehensive/protect-services/: "/gateway/VERSION/get-started/rate-limiting/" +/gateway/VERSION/get-started/comprehensive/improve-performance/: "/gateway/VERSION/get-started/proxy-caching/" +/gateway/VERSION/get-started/comprehensive/secure-services/: "/gateway/VERSION/get-started/secure-services/" +/gateway/VERSION/get-started/comprehensive/load-balancing/: "/gateway/VERSION/get-started/load-balancing/" +/gateway/VERSION/get-started/comprehensive/manage-teams/: "/gateway/VERSION/kong-manager/auth/workspaces-and-teams/" +/gateway/VERSION/get-started/comprehensive/dev-portal/: "/gateway/VERSION/kong-enterprise/dev-portal/publish-spec/" +/gateway/VERSION/plan-and-deploy/kong-user/: "/gateway/VERSION/production/running-kong/kong-user/" +/gateway/VERSION/plan-and-deploy/sizing-guidelines/: "/gateway/VERSION/production/sizing-guidelines/" +/gateway/VERSION/plan-and-deploy/hybrid-mode/: "/gateway/VERSION/production/deployment-topologies/hybrid-mode/" +/gateway/VERSION/plan-and-deploy/hybrid-mode/hybrid-mode-setup/: "/gateway/VERSION/production/deployment-topologies/hybrid-mode/setup/" +/gateway/VERSION/plan-and-deploy/kubernetes-deployment-options/: "/gateway/VERSION/install/kubernetes/deployment-options/" +/gateway/VERSION/plan-and-deploy/systemd/: "/gateway/VERSION/production/running-kong/systemd/" +/gateway/VERSION/plan-and-deploy/performance-testing-framework/: "/gateway/VERSION/reference/performance-testing-framework/" +/gateway/VERSION/plan-and-deploy/dns-considerations/: "/gateway/VERSION/production/networking/dns-considerations/" +/gateway/VERSION/plan-and-deploy/default-ports/: "/gateway/VERSION/production/networking/default-ports/" +/gateway/VERSION/plan-and-deploy/licenses/: "/gateway/VERSION/licenses/" +/gateway/VERSION/plan-and-deploy/licenses/access-license/: "/gateway/VERSION/licenses/download/" +/gateway/VERSION/plan-and-deploy/licenses/deploy-license/: "/gateway/VERSION/licenses/deploy/" +/gateway/VERSION/plan-and-deploy/licenses/report/: "/gateway/VERSION/licenses/report/" +/gateway/VERSION/plan-and-deploy/security/start-kong-securely/: "/gateway/VERSION/production/access-control/start-securely/" +/gateway/VERSION/plan-and-deploy/security/db-encryption/: "/gateway/VERSION/kong-enterprise/db-encryption/" +/gateway/VERSION/plan-and-deploy/security/kong-security-update-process/: "/gateway/VERSION/production/security-update-process/" +/gateway/VERSION/plan-and-deploy/security/secrets-management/: "/gateway/VERSION/kong-enterprise/secrets-management/" +/gateway/VERSION/plan-and-deploy/security/secrets-management/getting-started/: "/gateway/VERSION/kong-enterprise/secrets-management/getting-started/" +/gateway/VERSION/plan-and-deploy/security/secrets-management/advanced-usage/: "/gateway/VERSION/kong-enterprise/secrets-management/advanced-usage/" +/gateway/VERSION/plan-and-deploy/security/secrets-management/backends/: "/gateway/VERSION/kong-enterprise/secrets-management/backends/" +/gateway/VERSION/plan-and-deploy/security/secrets-management/backends/env/: "/gateway/VERSION/kong-enterprise/secrets-management/backends/env/" +/gateway/VERSION/plan-and-deploy/security/secrets-management/backends/aws-sm/: "/gateway/VERSION/kong-enterprise/secrets-management/backends/aws-sm/" +/gateway/VERSION/plan-and-deploy/security/secrets-management/backends/gcp-sm/: "/gateway/VERSION/kong-enterprise/secrets-management/backends/gcp-sm/" +/gateway/VERSION/plan-and-deploy/security/secrets-management/backends/hashicorp-vault/: "/gateway/VERSION/kong-enterprise/secrets-management/backends/hashicorp-vault/" +/gateway/VERSION/plan-and-deploy/security/secrets-management/reference-format/: "/gateway/VERSION/kong-enterprise/secrets-management/reference-format/" +/gateway/VERSION/configure/auth/: "/gateway/VERSION/kong-plugins/authentication/reference/" +/gateway/VERSION/configure/auth/oidc-use-case/: "/gateway/VERSION/kong-plugins/authentication/oidc/" +/gateway/VERSION/configure/auth/oidc-curity/: "/gateway/VERSION/kong-plugins/authentication/oidc/curity/" +/gateway/VERSION/configure/auth/oidc-azuread/: "/gateway/VERSION/kong-plugins/authentication/oidc/azure-ad/" +/gateway/VERSION/configure/auth/oidc-google/: "/gateway/VERSION/kong-plugins/authentication/oidc/google/" +/gateway/VERSION/configure/auth/oidc-okta/: "/gateway/VERSION/kong-plugins/authentication/oidc/okta/" +/gateway/VERSION/configure/auth/oidc-auth0/: "/gateway/VERSION/kong-plugins/authentication/oidc/auth0/" +/gateway/VERSION/configure/auth/oidc-cognito/: "/gateway/VERSION/kong-plugins/authentication/oidc/cognito/" +/gateway/VERSION/configure/auth/allowing-multiple-authentication-methods/: "/gateway/VERSION/kong-plugins/authentication/allowing-multiple-authentication-methods/" +/gateway/VERSION/configure/auth/kong-manager/: "/gateway/VERSION/kong-manager/auth/" +/gateway/VERSION/configure/auth/kong-manager/super-admin/: "/gateway/VERSION/kong-manager/auth/super-admin/" +/gateway/VERSION/configure/auth/kong-manager/networking/: "/gateway/VERSION/kong-manager/networking/" +/gateway/VERSION/configure/auth/kong-manager/email/: "/gateway/VERSION/kong-manager/configuring-to-send-email/" +/gateway/VERSION/configure/auth/kong-manager/reset-password/: "/gateway/VERSION/kong-manager/auth/reset-password/" +/gateway/VERSION/configure/auth/kong-manager/workspaces/: "/gateway/VERSION/kong-manager/workspaces/" +/gateway/VERSION/configure/auth/kong-manager/basic/: "/gateway/VERSION/kong-manager/auth/basic/" +/gateway/VERSION/configure/auth/kong-manager/ldap/: "/gateway/VERSION/kong-manager/auth/ldap/configure/" +/gateway/VERSION/configure/auth/kong-manager/oidc-mapping/: "/gateway/VERSION/kong-manager/auth/oidc/mapping/" +/gateway/VERSION/configure/auth/kong-manager/sessions/: "/gateway/VERSION/kong-manager/auth/sessions/" +/gateway/VERSION/configure/auth/rbac/: "/gateway/VERSION/kong-manager/auth/rbac/" +/gateway/VERSION/configure/auth/rbac/add-role/: "/gateway/VERSION/kong-manager/auth/rbac/add-role/" +/gateway/VERSION/configure/auth/rbac/add-user/: "/gateway/VERSION/kong-manager/auth/rbac/add-user/" +/gateway/VERSION/configure/auth/rbac/add-admin/: "/gateway/VERSION/kong-manager/auth/rbac/add-admin/" +/gateway/VERSION/configure/auth/service-directory-mapping/: "/gateway/VERSION/kong-manager/auth/ldap/service-directory-mapping/" +/gateway/VERSION/configure/grpc/: "/gateway/VERSION/kong-plugins/grpc/" +/gateway/VERSION/configure/graphql-quickstart/: "/gateway/VERSION/kong-plugins/graphql/" +/gateway/VERSION/configure/logging/: "/gateway/VERSION/production/logging/" +/gateway/VERSION/configure/network/: "/gateway/VERSION/production/networking/firewall/" +/gateway/VERSION/developer-portal/: "/gateway/VERSION/kong-enterprise/dev-portal/" +/gateway/VERSION/developer-portal/enable-dev-portal/: "/gateway/VERSION/kong-enterprise/dev-portal/enable/" +/gateway/VERSION/developer-portal/structure-and-file-types/: "/gateway/VERSION/kong-enterprise/dev-portal/structure-and-file-types/" +/gateway/VERSION/developer-portal/working-with-templates/: "/gateway/VERSION/kong-enterprise/dev-portal/working-with-templates/" +/gateway/VERSION/developer-portal/using-the-editor/: "/gateway/VERSION/kong-enterprise/dev-portal/using-the-editor/" +/gateway/VERSION/developer-portal/configuration/authentication/basic-auth/: "/gateway/VERSION/kong-enterprise/dev-portal/authentication/basic-auth/" +/gateway/VERSION/developer-portal/configuration/authentication/key-auth/: "/gateway/VERSION/kong-enterprise/dev-portal/authentication/key-auth/" +/gateway/VERSION/developer-portal/configuration/authentication/oidc/: "/gateway/VERSION/kong-enterprise/dev-portal/authentication/oidc/" +/gateway/VERSION/developer-portal/configuration/authentication/sessions/: "/gateway/VERSION/kong-enterprise/dev-portal/authentication/sessions/" +/gateway/VERSION/developer-portal/configuration/authentication/adding-registration-fields/: "/gateway/VERSION/kong-enterprise/dev-portal/authentication/adding-registration-fields/" +/gateway/VERSION/developer-portal/configuration/smtp/: "/gateway/VERSION/kong-enterprise/dev-portal/smtp/" +/gateway/VERSION/developer-portal/configuration/workspaces/: "/gateway/VERSION/kong-enterprise/dev-portal/workspaces/" +/gateway/VERSION/developer-portal/administration/managing-developers/: "/gateway/VERSION/kong-enterprise/dev-portal/authentication/managing-developers/" +/gateway/VERSION/developer-portal/administration/developer-permissions/: "/gateway/VERSION/kong-enterprise/dev-portal/authentication/developer-permissions/" +/gateway/VERSION/developer-portal/administration/application-registration/auth-provider-strategy/: "/gateway/VERSION/kong-enterprise/dev-portal/applications/auth-provider-strategy/" +/gateway/VERSION/developer-portal/administration/application-registration/enable-application-registration/: "/gateway/VERSION/kong-enterprise/dev-portal/applications/enable-application-registration/" +/gateway/VERSION/developer-portal/administration/application-registration/enable-key-auth-plugin/: "/gateway/VERSION/kong-enterprise/dev-portal/applications/enable-key-auth-plugin/" +/gateway/VERSION/developer-portal/administration/application-registration/3rd-party-oauth/: "/gateway/VERSION/kong-enterprise/dev-portal/authentication/3rd-party-oauth/" +/gateway/VERSION/developer-portal/administration/application-registration/okta-config/: "/gateway/VERSION/kong-enterprise/dev-portal/authentication/okta-config/" +/gateway/VERSION/developer-portal/administration/application-registration/azure-oidc-config/: "/gateway/VERSION/kong-enterprise/dev-portal/authentication/azure-oidc-config/" +/gateway/VERSION/developer-portal/administration/application-registration/managing-applications/: "/gateway/VERSION/kong-enterprise/dev-portal/applications/managing-applications/" +/gateway/VERSION/developer-portal/theme-customization/easy-theme-editing/: "/gateway/VERSION/kong-enterprise/dev-portal/customize/theme-editing/" +/gateway/VERSION/developer-portal/theme-customization/migrating-templates/: "/gateway/VERSION/kong-enterprise/dev-portal/customize/migrating-templates/" +/gateway/VERSION/developer-portal/theme-customization/markdown-extended/: "/gateway/VERSION/kong-enterprise/dev-portal/customize/markdown-extended/" +/gateway/VERSION/developer-portal/theme-customization/emails/: "/gateway/VERSION/kong-enterprise/dev-portal/customize/emails/" +/gateway/VERSION/developer-portal/theme-customization/adding-javascript-assets/: "/gateway/VERSION/kong-enterprise/dev-portal/customize/adding-javascript-assets/" +/gateway/VERSION/developer-portal/theme-customization/single-page-app/: "/gateway/VERSION/kong-enterprise/dev-portal/customize/single-page-app/" +/gateway/VERSION/developer-portal/theme-customization/alternate-openapi-renderer/: "/gateway/VERSION/kong-enterprise/dev-portal/customize/alternate-openapi-renderer/" +/gateway/VERSION/developer-portal/helpers/cli/: "/gateway/VERSION/kong-enterprise/dev-portal/cli/" +/gateway/VERSION/vitals/: "/gateway/VERSION/kong-enterprise/analytics/" +/gateway/VERSION/vitals/vitals-metrics/: "/gateway/VERSION/kong-enterprise/analytics/metrics/" +/gateway/VERSION/vitals/vitals-reports/: "/gateway/VERSION/kong-enterprise/analytics/reports/" +/gateway/VERSION/vitals/vitals-influx-strategy/: "/gateway/VERSION/kong-enterprise/analytics/influx-strategy/" +/gateway/VERSION/vitals/vitals-prometheus-strategy/: "/gateway/VERSION/kong-enterprise/analytics/prometheus-strategy/" +/gateway/VERSION/vitals/vitals-estimates/: "/gateway/VERSION/kong-enterprise/analytics/estimates/" +/gateway/VERSION/admin-api/licenses/examples/: "/gateway/VERSION/licenses/examples/" +/gateway/VERSION/admin-api/workspaces/examples/: "/gateway/VERSION/kong-enterprise/workspaces/" +/gateway/VERSION/admin-api/rbac/examples/: "/gateway/VERSION/production/access-control/enable-rbac/" +/gateway/VERSION/admin-api/admins/examples/: "/gateway/VERSION/production/access-control/register-admin-api/" +/gateway/VERSION/admin-api/consumer-groups/examples/: "/gateway/VERSION/kong-enterprise/consumer-groups/" +/gateway/VERSION/admin-api/event-hooks/examples/: "/gateway/VERSION/kong-enterprise/event-hooks/" +/gateway/VERSION/admin-api/audit-log/: "/gateway/VERSION/kong-enterprise/audit-log/" +/gateway/VERSION/admin-api/db-encryption/: "/gateway/VERSION/kong-enterprise/db-encryption/" +/gateway/VERSION/admin-api/secure-admin-api/: "/gateway/VERSION/production/running-kong/secure-admin-api/" +/gateway/VERSION/reference/db-less-and-declarative-config/: "/gateway/VERSION/production/deployment-topologies/db-less-and-declarative-config/" +/gateway/VERSION/reference/loadbalancing/: "/gateway/VERSION/how-kong-works/load-balancing/" +/gateway/VERSION/reference/proxy/: "/gateway/VERSION/how-kong-works/routing-traffic/" +/gateway/VERSION/reference/rate-limiting/: "/gateway/VERSION/kong-plugins/rate-limiting/algorithms/rate-limiting/" +/gateway/VERSION/reference/health-checks-circuit-breakers/: "/gateway/VERSION/how-kong-works/health-checks/" +/gateway/VERSION/reference/clustering/: "/gateway/VERSION/production/clustering/" +/gateway/VERSION/pdk/: "/gateway/VERSION/plugin-development/pdk/" +/gateway/VERSION/pdk/kong.client/: "/gateway/VERSION/plugin-development/pdk/kong.client/" +/gateway/VERSION/pdk/kong.client.tls/: "/gateway/VERSION/plugin-development/pdk/kong.client.tls/" +/gateway/VERSION/availability-stages/: "/gateway/VERSION/stability/" +/gateway/VERSION/pdk/kong.cluster/: "/gateway/VERSION/plugin-development/pdk/kong.cluster/" +/gateway/VERSION/pdk/kong.ctx/: "/gateway/VERSION/plugin-development/pdk/kong.ctx/" +/gateway/VERSION/pdk/kong.ip/: "/gateway/VERSION/plugin-development/pdk/kong.ip/" +/gateway/VERSION/pdk/kong.log/: "/gateway/VERSION/plugin-development/pdk/kong.log/" +/gateway/VERSION/pdk/kong.nginx/: "/gateway/VERSION/plugin-development/pdk/kong.nginx/" +/gateway/VERSION/pdk/kong.node/: "/gateway/VERSION/plugin-development/pdk/kong.node/" +/gateway/VERSION/pdk/kong.request/: "/gateway/VERSION/plugin-development/pdk/kong.request/" +/gateway/VERSION/pdk/kong.response/: "/gateway/VERSION/plugin-development/pdk/kong.response/" +/gateway/VERSION/pdk/kong.router/: "/gateway/VERSION/plugin-development/pdk/kong.router/" +/gateway/VERSION/pdk/kong.service/: "/gateway/VERSION/plugin-development/pdk/kong.service/" +/gateway/VERSION/pdk/kong.service.request/: "/gateway/VERSION/plugin-development/pdk/kong.service.request/" +/gateway/VERSION/pdk/kong.service.response/: "/gateway/VERSION/plugin-development/pdk/kong.service.response/" +/gateway/VERSION/pdk/kong.table/: "/gateway/VERSION/plugin-development/pdk/kong.table/" +/gateway/VERSION/pdk/kong.vault/: "/gateway/VERSION/plugin-development/pdk/kong.vault/" +/gateway/VERSION/plugin-development/plugin-configuration/: "/gateway/VERSION/plugin-development/configuration/" +/gateway/VERSION/reference/external-plugins/: "/gateway/VERSION/plugin-development/pluginserver/go/" +/gateway/VERSION/get-started/secure-services/: "/gateway/VERSION/get-started/key-authentication/" diff --git a/app/enterprise/0.31-x/admin-gui.md b/archive/enterprise/0.31-x/admin-gui.md similarity index 100% rename from app/enterprise/0.31-x/admin-gui.md rename to archive/enterprise/0.31-x/admin-gui.md diff --git a/app/enterprise/0.31-x/allowing-multiple-authentication-methods.md b/archive/enterprise/0.31-x/allowing-multiple-authentication-methods.md similarity index 100% rename from app/enterprise/0.31-x/allowing-multiple-authentication-methods.md rename to archive/enterprise/0.31-x/allowing-multiple-authentication-methods.md diff --git a/app/enterprise/0.31-x/developer-portal/authentication.md b/archive/enterprise/0.31-x/developer-portal/authentication.md similarity index 100% rename from app/enterprise/0.31-x/developer-portal/authentication.md rename to archive/enterprise/0.31-x/developer-portal/authentication.md diff --git a/app/enterprise/0.31-x/developer-portal/customization.md b/archive/enterprise/0.31-x/developer-portal/customization.md similarity index 100% rename from app/enterprise/0.31-x/developer-portal/customization.md rename to archive/enterprise/0.31-x/developer-portal/customization.md diff --git a/app/enterprise/0.31-x/developer-portal/faq.md b/archive/enterprise/0.31-x/developer-portal/faq.md similarity index 100% rename from app/enterprise/0.31-x/developer-portal/faq.md rename to archive/enterprise/0.31-x/developer-portal/faq.md diff --git a/app/enterprise/0.31-x/developer-portal/getting-started.md b/archive/enterprise/0.31-x/developer-portal/getting-started.md similarity index 100% rename from app/enterprise/0.31-x/developer-portal/getting-started.md rename to archive/enterprise/0.31-x/developer-portal/getting-started.md diff --git a/app/enterprise/0.31-x/developer-portal/introduction.md b/archive/enterprise/0.31-x/developer-portal/introduction.md similarity index 100% rename from app/enterprise/0.31-x/developer-portal/introduction.md rename to archive/enterprise/0.31-x/developer-portal/introduction.md diff --git a/app/enterprise/0.31-x/developer-portal/known-limitations.md b/archive/enterprise/0.31-x/developer-portal/known-limitations.md similarity index 100% rename from app/enterprise/0.31-x/developer-portal/known-limitations.md rename to archive/enterprise/0.31-x/developer-portal/known-limitations.md diff --git a/app/enterprise/0.31-x/developer-portal/understanding.md b/archive/enterprise/0.31-x/developer-portal/understanding.md similarity index 100% rename from app/enterprise/0.31-x/developer-portal/understanding.md rename to archive/enterprise/0.31-x/developer-portal/understanding.md diff --git a/app/enterprise/0.31-x/edition-versioning.md b/archive/enterprise/0.31-x/edition-versioning.md similarity index 100% rename from app/enterprise/0.31-x/edition-versioning.md rename to archive/enterprise/0.31-x/edition-versioning.md diff --git a/app/enterprise/0.31-x/getting-started/accessing-your-license.md b/archive/enterprise/0.31-x/getting-started/accessing-your-license.md similarity index 100% rename from app/enterprise/0.31-x/getting-started/accessing-your-license.md rename to archive/enterprise/0.31-x/getting-started/accessing-your-license.md diff --git a/app/enterprise/0.31-x/getting-started/adding-consumers.md b/archive/enterprise/0.31-x/getting-started/adding-consumers.md similarity index 100% rename from app/enterprise/0.31-x/getting-started/adding-consumers.md rename to archive/enterprise/0.31-x/getting-started/adding-consumers.md diff --git a/app/enterprise/0.31-x/getting-started/adding-your-api.md b/archive/enterprise/0.31-x/getting-started/adding-your-api.md similarity index 100% rename from app/enterprise/0.31-x/getting-started/adding-your-api.md rename to archive/enterprise/0.31-x/getting-started/adding-your-api.md diff --git a/app/enterprise/0.31-x/getting-started/enabling-plugins.md b/archive/enterprise/0.31-x/getting-started/enabling-plugins.md similarity index 100% rename from app/enterprise/0.31-x/getting-started/enabling-plugins.md rename to archive/enterprise/0.31-x/getting-started/enabling-plugins.md diff --git a/app/enterprise/0.31-x/getting-started/introduction.md b/archive/enterprise/0.31-x/getting-started/introduction.md similarity index 100% rename from app/enterprise/0.31-x/getting-started/introduction.md rename to archive/enterprise/0.31-x/getting-started/introduction.md diff --git a/app/enterprise/0.31-x/getting-started/licensing.md b/archive/enterprise/0.31-x/getting-started/licensing.md similarity index 100% rename from app/enterprise/0.31-x/getting-started/licensing.md rename to archive/enterprise/0.31-x/getting-started/licensing.md diff --git a/app/enterprise/0.31-x/getting-started/quickstart.md b/archive/enterprise/0.31-x/getting-started/quickstart.md similarity index 100% rename from app/enterprise/0.31-x/getting-started/quickstart.md rename to archive/enterprise/0.31-x/getting-started/quickstart.md diff --git a/app/enterprise/0.31-x/index.md b/archive/enterprise/0.31-x/index.md similarity index 100% rename from app/enterprise/0.31-x/index.md rename to archive/enterprise/0.31-x/index.md diff --git a/app/enterprise/0.31-x/installation/amazon-linux.md b/archive/enterprise/0.31-x/installation/amazon-linux.md similarity index 100% rename from app/enterprise/0.31-x/installation/amazon-linux.md rename to archive/enterprise/0.31-x/installation/amazon-linux.md diff --git a/app/enterprise/0.31-x/installation/centos.md b/archive/enterprise/0.31-x/installation/centos.md similarity index 100% rename from app/enterprise/0.31-x/installation/centos.md rename to archive/enterprise/0.31-x/installation/centos.md diff --git a/app/enterprise/0.31-x/installation/docker.md b/archive/enterprise/0.31-x/installation/docker.md similarity index 100% rename from app/enterprise/0.31-x/installation/docker.md rename to archive/enterprise/0.31-x/installation/docker.md diff --git a/app/enterprise/0.31-x/installation/ubuntu.md b/archive/enterprise/0.31-x/installation/ubuntu.md similarity index 100% rename from app/enterprise/0.31-x/installation/ubuntu.md rename to archive/enterprise/0.31-x/installation/ubuntu.md diff --git a/app/enterprise/0.31-x/kong-architecture-overview.md b/archive/enterprise/0.31-x/kong-architecture-overview.md similarity index 100% rename from app/enterprise/0.31-x/kong-architecture-overview.md rename to archive/enterprise/0.31-x/kong-architecture-overview.md diff --git a/app/enterprise/0.31-x/kong-architecture-patterns.md b/archive/enterprise/0.31-x/kong-architecture-patterns.md similarity index 100% rename from app/enterprise/0.31-x/kong-architecture-patterns.md rename to archive/enterprise/0.31-x/kong-architecture-patterns.md diff --git a/app/enterprise/0.31-x/kong-implementation-checklist.md b/archive/enterprise/0.31-x/kong-implementation-checklist.md similarity index 100% rename from app/enterprise/0.31-x/kong-implementation-checklist.md rename to archive/enterprise/0.31-x/kong-implementation-checklist.md diff --git a/app/enterprise/0.31-x/oidc-auth0.md b/archive/enterprise/0.31-x/oidc-auth0.md similarity index 100% rename from app/enterprise/0.31-x/oidc-auth0.md rename to archive/enterprise/0.31-x/oidc-auth0.md diff --git a/app/enterprise/0.31-x/oidc-google.md b/archive/enterprise/0.31-x/oidc-google.md similarity index 100% rename from app/enterprise/0.31-x/oidc-google.md rename to archive/enterprise/0.31-x/oidc-google.md diff --git a/app/enterprise/0.31-x/plugins/canary-release.md b/archive/enterprise/0.31-x/plugins/canary-release.md similarity index 100% rename from app/enterprise/0.31-x/plugins/canary-release.md rename to archive/enterprise/0.31-x/plugins/canary-release.md diff --git a/app/enterprise/0.31-x/plugins/forward-proxy.md b/archive/enterprise/0.31-x/plugins/forward-proxy.md similarity index 100% rename from app/enterprise/0.31-x/plugins/forward-proxy.md rename to archive/enterprise/0.31-x/plugins/forward-proxy.md diff --git a/app/enterprise/0.31-x/plugins/http-proxy-caching.md b/archive/enterprise/0.31-x/plugins/http-proxy-caching.md similarity index 100% rename from app/enterprise/0.31-x/plugins/http-proxy-caching.md rename to archive/enterprise/0.31-x/plugins/http-proxy-caching.md diff --git a/app/enterprise/0.31-x/plugins/oauth2-introspection.md b/archive/enterprise/0.31-x/plugins/oauth2-introspection.md similarity index 100% rename from app/enterprise/0.31-x/plugins/oauth2-introspection.md rename to archive/enterprise/0.31-x/plugins/oauth2-introspection.md diff --git a/app/enterprise/0.31-x/plugins/openid-connect.md b/archive/enterprise/0.31-x/plugins/openid-connect.md similarity index 100% rename from app/enterprise/0.31-x/plugins/openid-connect.md rename to archive/enterprise/0.31-x/plugins/openid-connect.md diff --git a/app/enterprise/0.31-x/plugins/rate-limiting.md b/archive/enterprise/0.31-x/plugins/rate-limiting.md similarity index 100% rename from app/enterprise/0.31-x/plugins/rate-limiting.md rename to archive/enterprise/0.31-x/plugins/rate-limiting.md diff --git a/app/enterprise/0.31-x/plugins/rbac-api.md b/archive/enterprise/0.31-x/plugins/rbac-api.md similarity index 100% rename from app/enterprise/0.31-x/plugins/rbac-api.md rename to archive/enterprise/0.31-x/plugins/rbac-api.md diff --git a/app/enterprise/0.31-x/plugins/request-transformer.md b/archive/enterprise/0.31-x/plugins/request-transformer.md similarity index 100% rename from app/enterprise/0.31-x/plugins/request-transformer.md rename to archive/enterprise/0.31-x/plugins/request-transformer.md diff --git a/app/enterprise/0.31-x/postgresql-redhat.md b/archive/enterprise/0.31-x/postgresql-redhat.md similarity index 100% rename from app/enterprise/0.31-x/postgresql-redhat.md rename to archive/enterprise/0.31-x/postgresql-redhat.md diff --git a/app/enterprise/0.31-x/rate-limiting.md b/archive/enterprise/0.31-x/rate-limiting.md similarity index 100% rename from app/enterprise/0.31-x/rate-limiting.md rename to archive/enterprise/0.31-x/rate-limiting.md diff --git a/app/enterprise/0.31-x/setting-up-admin-api-rbac.md b/archive/enterprise/0.31-x/setting-up-admin-api-rbac.md similarity index 100% rename from app/enterprise/0.31-x/setting-up-admin-api-rbac.md rename to archive/enterprise/0.31-x/setting-up-admin-api-rbac.md diff --git a/app/enterprise/0.31-x/vitals.md b/archive/enterprise/0.31-x/vitals.md similarity index 100% rename from app/enterprise/0.31-x/vitals.md rename to archive/enterprise/0.31-x/vitals.md diff --git a/app/enterprise/0.31-x/vitalsSpec_v0.31.yaml b/archive/enterprise/0.31-x/vitalsSpec_v0.31.yaml similarity index 100% rename from app/enterprise/0.31-x/vitalsSpec_v0.31.yaml rename to archive/enterprise/0.31-x/vitalsSpec_v0.31.yaml diff --git a/app/enterprise/0.32-x/admin-gui.md b/archive/enterprise/0.32-x/admin-gui.md similarity index 100% rename from app/enterprise/0.32-x/admin-gui.md rename to archive/enterprise/0.32-x/admin-gui.md diff --git a/app/enterprise/0.32-x/allowing-multiple-authentication-methods.md b/archive/enterprise/0.32-x/allowing-multiple-authentication-methods.md similarity index 100% rename from app/enterprise/0.32-x/allowing-multiple-authentication-methods.md rename to archive/enterprise/0.32-x/allowing-multiple-authentication-methods.md diff --git a/app/enterprise/0.32-x/developer-portal/configuration/authentication.md b/archive/enterprise/0.32-x/developer-portal/configuration/authentication.md similarity index 100% rename from app/enterprise/0.32-x/developer-portal/configuration/authentication.md rename to archive/enterprise/0.32-x/developer-portal/configuration/authentication.md diff --git a/app/enterprise/0.32-x/developer-portal/configuration/getting-started.md b/archive/enterprise/0.32-x/developer-portal/configuration/getting-started.md similarity index 100% rename from app/enterprise/0.32-x/developer-portal/configuration/getting-started.md rename to archive/enterprise/0.32-x/developer-portal/configuration/getting-started.md diff --git a/app/enterprise/0.32-x/developer-portal/configuration/networking.md b/archive/enterprise/0.32-x/developer-portal/configuration/networking.md similarity index 100% rename from app/enterprise/0.32-x/developer-portal/configuration/networking.md rename to archive/enterprise/0.32-x/developer-portal/configuration/networking.md diff --git a/app/enterprise/0.32-x/developer-portal/configuration/property-reference.md b/archive/enterprise/0.32-x/developer-portal/configuration/property-reference.md similarity index 100% rename from app/enterprise/0.32-x/developer-portal/configuration/property-reference.md rename to archive/enterprise/0.32-x/developer-portal/configuration/property-reference.md diff --git a/app/enterprise/0.32-x/developer-portal/customization.md b/archive/enterprise/0.32-x/developer-portal/customization.md similarity index 100% rename from app/enterprise/0.32-x/developer-portal/customization.md rename to archive/enterprise/0.32-x/developer-portal/customization.md diff --git a/app/enterprise/0.32-x/developer-portal/developer-access.md b/archive/enterprise/0.32-x/developer-portal/developer-access.md similarity index 100% rename from app/enterprise/0.32-x/developer-portal/developer-access.md rename to archive/enterprise/0.32-x/developer-portal/developer-access.md diff --git a/app/enterprise/0.32-x/developer-portal/faq.md b/archive/enterprise/0.32-x/developer-portal/faq.md similarity index 100% rename from app/enterprise/0.32-x/developer-portal/faq.md rename to archive/enterprise/0.32-x/developer-portal/faq.md diff --git a/app/enterprise/0.32-x/developer-portal/file-management.md b/archive/enterprise/0.32-x/developer-portal/file-management.md similarity index 100% rename from app/enterprise/0.32-x/developer-portal/file-management.md rename to archive/enterprise/0.32-x/developer-portal/file-management.md diff --git a/app/enterprise/0.32-x/developer-portal/glossary.md b/archive/enterprise/0.32-x/developer-portal/glossary.md similarity index 100% rename from app/enterprise/0.32-x/developer-portal/glossary.md rename to archive/enterprise/0.32-x/developer-portal/glossary.md diff --git a/app/enterprise/0.32-x/developer-portal/managing-developers.md b/archive/enterprise/0.32-x/developer-portal/managing-developers.md similarity index 100% rename from app/enterprise/0.32-x/developer-portal/managing-developers.md rename to archive/enterprise/0.32-x/developer-portal/managing-developers.md diff --git a/app/enterprise/0.32-x/developer-portal/overview.md b/archive/enterprise/0.32-x/developer-portal/overview.md similarity index 100% rename from app/enterprise/0.32-x/developer-portal/overview.md rename to archive/enterprise/0.32-x/developer-portal/overview.md diff --git a/app/enterprise/0.32-x/edition-versioning.md b/archive/enterprise/0.32-x/edition-versioning.md similarity index 100% rename from app/enterprise/0.32-x/edition-versioning.md rename to archive/enterprise/0.32-x/edition-versioning.md diff --git a/app/enterprise/0.32-x/getting-started/accessing-your-license.md b/archive/enterprise/0.32-x/getting-started/accessing-your-license.md similarity index 100% rename from app/enterprise/0.32-x/getting-started/accessing-your-license.md rename to archive/enterprise/0.32-x/getting-started/accessing-your-license.md diff --git a/app/enterprise/0.32-x/getting-started/adding-consumers.md b/archive/enterprise/0.32-x/getting-started/adding-consumers.md similarity index 100% rename from app/enterprise/0.32-x/getting-started/adding-consumers.md rename to archive/enterprise/0.32-x/getting-started/adding-consumers.md diff --git a/app/enterprise/0.32-x/getting-started/adding-your-api.md b/archive/enterprise/0.32-x/getting-started/adding-your-api.md similarity index 100% rename from app/enterprise/0.32-x/getting-started/adding-your-api.md rename to archive/enterprise/0.32-x/getting-started/adding-your-api.md diff --git a/app/enterprise/0.32-x/getting-started/enabling-plugins.md b/archive/enterprise/0.32-x/getting-started/enabling-plugins.md similarity index 100% rename from app/enterprise/0.32-x/getting-started/enabling-plugins.md rename to archive/enterprise/0.32-x/getting-started/enabling-plugins.md diff --git a/app/enterprise/0.32-x/getting-started/introduction.md b/archive/enterprise/0.32-x/getting-started/introduction.md similarity index 100% rename from app/enterprise/0.32-x/getting-started/introduction.md rename to archive/enterprise/0.32-x/getting-started/introduction.md diff --git a/app/enterprise/0.32-x/getting-started/licensing.md b/archive/enterprise/0.32-x/getting-started/licensing.md similarity index 100% rename from app/enterprise/0.32-x/getting-started/licensing.md rename to archive/enterprise/0.32-x/getting-started/licensing.md diff --git a/app/enterprise/0.32-x/getting-started/quickstart.md b/archive/enterprise/0.32-x/getting-started/quickstart.md similarity index 100% rename from app/enterprise/0.32-x/getting-started/quickstart.md rename to archive/enterprise/0.32-x/getting-started/quickstart.md diff --git a/app/enterprise/0.32-x/index.md b/archive/enterprise/0.32-x/index.md similarity index 100% rename from app/enterprise/0.32-x/index.md rename to archive/enterprise/0.32-x/index.md diff --git a/app/enterprise/0.32-x/installation/amazon-linux.md b/archive/enterprise/0.32-x/installation/amazon-linux.md similarity index 100% rename from app/enterprise/0.32-x/installation/amazon-linux.md rename to archive/enterprise/0.32-x/installation/amazon-linux.md diff --git a/app/enterprise/0.32-x/installation/centos.md b/archive/enterprise/0.32-x/installation/centos.md similarity index 100% rename from app/enterprise/0.32-x/installation/centos.md rename to archive/enterprise/0.32-x/installation/centos.md diff --git a/app/enterprise/0.32-x/installation/docker.md b/archive/enterprise/0.32-x/installation/docker.md similarity index 100% rename from app/enterprise/0.32-x/installation/docker.md rename to archive/enterprise/0.32-x/installation/docker.md diff --git a/app/enterprise/0.32-x/installation/ubuntu.md b/archive/enterprise/0.32-x/installation/ubuntu.md similarity index 100% rename from app/enterprise/0.32-x/installation/ubuntu.md rename to archive/enterprise/0.32-x/installation/ubuntu.md diff --git a/app/enterprise/0.32-x/kong-architecture-overview.md b/archive/enterprise/0.32-x/kong-architecture-overview.md similarity index 100% rename from app/enterprise/0.32-x/kong-architecture-overview.md rename to archive/enterprise/0.32-x/kong-architecture-overview.md diff --git a/app/enterprise/0.32-x/kong-architecture-patterns.md b/archive/enterprise/0.32-x/kong-architecture-patterns.md similarity index 100% rename from app/enterprise/0.32-x/kong-architecture-patterns.md rename to archive/enterprise/0.32-x/kong-architecture-patterns.md diff --git a/app/enterprise/0.32-x/kong-implementation-checklist.md b/archive/enterprise/0.32-x/kong-implementation-checklist.md similarity index 100% rename from app/enterprise/0.32-x/kong-implementation-checklist.md rename to archive/enterprise/0.32-x/kong-implementation-checklist.md diff --git a/app/enterprise/0.32-x/oidc-auth0.md b/archive/enterprise/0.32-x/oidc-auth0.md similarity index 100% rename from app/enterprise/0.32-x/oidc-auth0.md rename to archive/enterprise/0.32-x/oidc-auth0.md diff --git a/app/enterprise/0.32-x/oidc-google.md b/archive/enterprise/0.32-x/oidc-google.md similarity index 100% rename from app/enterprise/0.32-x/oidc-google.md rename to archive/enterprise/0.32-x/oidc-google.md diff --git a/app/enterprise/0.32-x/plugins/canary-release.md b/archive/enterprise/0.32-x/plugins/canary-release.md similarity index 100% rename from app/enterprise/0.32-x/plugins/canary-release.md rename to archive/enterprise/0.32-x/plugins/canary-release.md diff --git a/app/enterprise/0.32-x/plugins/forward-proxy.md b/archive/enterprise/0.32-x/plugins/forward-proxy.md similarity index 100% rename from app/enterprise/0.32-x/plugins/forward-proxy.md rename to archive/enterprise/0.32-x/plugins/forward-proxy.md diff --git a/app/enterprise/0.32-x/plugins/http-proxy-caching.md b/archive/enterprise/0.32-x/plugins/http-proxy-caching.md similarity index 100% rename from app/enterprise/0.32-x/plugins/http-proxy-caching.md rename to archive/enterprise/0.32-x/plugins/http-proxy-caching.md diff --git a/app/enterprise/0.32-x/plugins/oauth2-introspection.md b/archive/enterprise/0.32-x/plugins/oauth2-introspection.md similarity index 100% rename from app/enterprise/0.32-x/plugins/oauth2-introspection.md rename to archive/enterprise/0.32-x/plugins/oauth2-introspection.md diff --git a/app/enterprise/0.32-x/plugins/openid-connect.md b/archive/enterprise/0.32-x/plugins/openid-connect.md similarity index 100% rename from app/enterprise/0.32-x/plugins/openid-connect.md rename to archive/enterprise/0.32-x/plugins/openid-connect.md diff --git a/app/enterprise/0.32-x/plugins/rate-limiting-advanced.md b/archive/enterprise/0.32-x/plugins/rate-limiting-advanced.md similarity index 100% rename from app/enterprise/0.32-x/plugins/rate-limiting-advanced.md rename to archive/enterprise/0.32-x/plugins/rate-limiting-advanced.md diff --git a/app/enterprise/0.32-x/plugins/rbac-api.md b/archive/enterprise/0.32-x/plugins/rbac-api.md similarity index 100% rename from app/enterprise/0.32-x/plugins/rbac-api.md rename to archive/enterprise/0.32-x/plugins/rbac-api.md diff --git a/app/enterprise/0.32-x/plugins/request-transformer.md b/archive/enterprise/0.32-x/plugins/request-transformer.md similarity index 100% rename from app/enterprise/0.32-x/plugins/request-transformer.md rename to archive/enterprise/0.32-x/plugins/request-transformer.md diff --git a/app/enterprise/0.32-x/postgresql-redhat.md b/archive/enterprise/0.32-x/postgresql-redhat.md similarity index 100% rename from app/enterprise/0.32-x/postgresql-redhat.md rename to archive/enterprise/0.32-x/postgresql-redhat.md diff --git a/app/enterprise/0.32-x/rate-limiting.md b/archive/enterprise/0.32-x/rate-limiting.md similarity index 100% rename from app/enterprise/0.32-x/rate-limiting.md rename to archive/enterprise/0.32-x/rate-limiting.md diff --git a/app/enterprise/0.32-x/setting-up-admin-api-rbac.md b/archive/enterprise/0.32-x/setting-up-admin-api-rbac.md similarity index 100% rename from app/enterprise/0.32-x/setting-up-admin-api-rbac.md rename to archive/enterprise/0.32-x/setting-up-admin-api-rbac.md diff --git a/app/enterprise/0.32-x/upgrades-migrations.md b/archive/enterprise/0.32-x/upgrades-migrations.md similarity index 100% rename from app/enterprise/0.32-x/upgrades-migrations.md rename to archive/enterprise/0.32-x/upgrades-migrations.md diff --git a/app/enterprise/0.32-x/vitals.md b/archive/enterprise/0.32-x/vitals.md similarity index 100% rename from app/enterprise/0.32-x/vitals.md rename to archive/enterprise/0.32-x/vitals.md diff --git a/app/enterprise/0.32-x/vitalsSpec_v0.32.yaml b/archive/enterprise/0.32-x/vitalsSpec_v0.32.yaml similarity index 100% rename from app/enterprise/0.32-x/vitalsSpec_v0.32.yaml rename to archive/enterprise/0.32-x/vitalsSpec_v0.32.yaml diff --git a/app/enterprise/0.33-x/admin-gui/configuration/authentication.md b/archive/enterprise/0.33-x/admin-gui/configuration/authentication.md similarity index 100% rename from app/enterprise/0.33-x/admin-gui/configuration/authentication.md rename to archive/enterprise/0.33-x/admin-gui/configuration/authentication.md diff --git a/app/enterprise/0.33-x/admin-gui/configuration/getting-started.md b/archive/enterprise/0.33-x/admin-gui/configuration/getting-started.md similarity index 100% rename from app/enterprise/0.33-x/admin-gui/configuration/getting-started.md rename to archive/enterprise/0.33-x/admin-gui/configuration/getting-started.md diff --git a/app/enterprise/0.33-x/admin-gui/configuration/managing-admins.md b/archive/enterprise/0.33-x/admin-gui/configuration/managing-admins.md similarity index 100% rename from app/enterprise/0.33-x/admin-gui/configuration/managing-admins.md rename to archive/enterprise/0.33-x/admin-gui/configuration/managing-admins.md diff --git a/app/enterprise/0.33-x/admin-gui/configuration/networking.md b/archive/enterprise/0.33-x/admin-gui/configuration/networking.md similarity index 100% rename from app/enterprise/0.33-x/admin-gui/configuration/networking.md rename to archive/enterprise/0.33-x/admin-gui/configuration/networking.md diff --git a/app/enterprise/0.33-x/admin-gui/configuration/property-reference.md b/archive/enterprise/0.33-x/admin-gui/configuration/property-reference.md similarity index 100% rename from app/enterprise/0.33-x/admin-gui/configuration/property-reference.md rename to archive/enterprise/0.33-x/admin-gui/configuration/property-reference.md diff --git a/app/enterprise/0.33-x/admin-gui/overview.md b/archive/enterprise/0.33-x/admin-gui/overview.md similarity index 100% rename from app/enterprise/0.33-x/admin-gui/overview.md rename to archive/enterprise/0.33-x/admin-gui/overview.md diff --git a/app/enterprise/0.33-x/allowing-multiple-authentication-methods.md b/archive/enterprise/0.33-x/allowing-multiple-authentication-methods.md similarity index 100% rename from app/enterprise/0.33-x/allowing-multiple-authentication-methods.md rename to archive/enterprise/0.33-x/allowing-multiple-authentication-methods.md diff --git a/app/enterprise/0.33-x/deployment-guide.md b/archive/enterprise/0.33-x/deployment-guide.md similarity index 100% rename from app/enterprise/0.33-x/deployment-guide.md rename to archive/enterprise/0.33-x/deployment-guide.md diff --git a/app/enterprise/0.33-x/developer-portal/best-practices.md b/archive/enterprise/0.33-x/developer-portal/best-practices.md similarity index 100% rename from app/enterprise/0.33-x/developer-portal/best-practices.md rename to archive/enterprise/0.33-x/developer-portal/best-practices.md diff --git a/app/enterprise/0.33-x/developer-portal/configuration/authentication.md b/archive/enterprise/0.33-x/developer-portal/configuration/authentication.md similarity index 100% rename from app/enterprise/0.33-x/developer-portal/configuration/authentication.md rename to archive/enterprise/0.33-x/developer-portal/configuration/authentication.md diff --git a/app/enterprise/0.33-x/developer-portal/configuration/getting-started.md b/archive/enterprise/0.33-x/developer-portal/configuration/getting-started.md similarity index 100% rename from app/enterprise/0.33-x/developer-portal/configuration/getting-started.md rename to archive/enterprise/0.33-x/developer-portal/configuration/getting-started.md diff --git a/app/enterprise/0.33-x/developer-portal/configuration/networking.md b/archive/enterprise/0.33-x/developer-portal/configuration/networking.md similarity index 100% rename from app/enterprise/0.33-x/developer-portal/configuration/networking.md rename to archive/enterprise/0.33-x/developer-portal/configuration/networking.md diff --git a/app/enterprise/0.33-x/developer-portal/configuration/property-reference.md b/archive/enterprise/0.33-x/developer-portal/configuration/property-reference.md similarity index 100% rename from app/enterprise/0.33-x/developer-portal/configuration/property-reference.md rename to archive/enterprise/0.33-x/developer-portal/configuration/property-reference.md diff --git a/app/enterprise/0.33-x/developer-portal/customization.md b/archive/enterprise/0.33-x/developer-portal/customization.md similarity index 100% rename from app/enterprise/0.33-x/developer-portal/customization.md rename to archive/enterprise/0.33-x/developer-portal/customization.md diff --git a/app/enterprise/0.33-x/developer-portal/developer-access.md b/archive/enterprise/0.33-x/developer-portal/developer-access.md similarity index 100% rename from app/enterprise/0.33-x/developer-portal/developer-access.md rename to archive/enterprise/0.33-x/developer-portal/developer-access.md diff --git a/app/enterprise/0.33-x/developer-portal/faq.md b/archive/enterprise/0.33-x/developer-portal/faq.md similarity index 100% rename from app/enterprise/0.33-x/developer-portal/faq.md rename to archive/enterprise/0.33-x/developer-portal/faq.md diff --git a/app/enterprise/0.33-x/developer-portal/file-management.md b/archive/enterprise/0.33-x/developer-portal/file-management.md similarity index 100% rename from app/enterprise/0.33-x/developer-portal/file-management.md rename to archive/enterprise/0.33-x/developer-portal/file-management.md diff --git a/app/enterprise/0.33-x/developer-portal/glossary.md b/archive/enterprise/0.33-x/developer-portal/glossary.md similarity index 100% rename from app/enterprise/0.33-x/developer-portal/glossary.md rename to archive/enterprise/0.33-x/developer-portal/glossary.md diff --git a/app/enterprise/0.33-x/developer-portal/managing-developers.md b/archive/enterprise/0.33-x/developer-portal/managing-developers.md similarity index 100% rename from app/enterprise/0.33-x/developer-portal/managing-developers.md rename to archive/enterprise/0.33-x/developer-portal/managing-developers.md diff --git a/app/enterprise/0.33-x/developer-portal/overview.md b/archive/enterprise/0.33-x/developer-portal/overview.md similarity index 100% rename from app/enterprise/0.33-x/developer-portal/overview.md rename to archive/enterprise/0.33-x/developer-portal/overview.md diff --git a/app/enterprise/0.33-x/edition-versioning.md b/archive/enterprise/0.33-x/edition-versioning.md similarity index 100% rename from app/enterprise/0.33-x/edition-versioning.md rename to archive/enterprise/0.33-x/edition-versioning.md diff --git a/app/enterprise/0.33-x/getting-started/accessing-your-license.md b/archive/enterprise/0.33-x/getting-started/accessing-your-license.md similarity index 100% rename from app/enterprise/0.33-x/getting-started/accessing-your-license.md rename to archive/enterprise/0.33-x/getting-started/accessing-your-license.md diff --git a/app/enterprise/0.33-x/getting-started/adding-consumers.md b/archive/enterprise/0.33-x/getting-started/adding-consumers.md similarity index 100% rename from app/enterprise/0.33-x/getting-started/adding-consumers.md rename to archive/enterprise/0.33-x/getting-started/adding-consumers.md diff --git a/app/enterprise/0.33-x/getting-started/adding-your-api.md b/archive/enterprise/0.33-x/getting-started/adding-your-api.md similarity index 100% rename from app/enterprise/0.33-x/getting-started/adding-your-api.md rename to archive/enterprise/0.33-x/getting-started/adding-your-api.md diff --git a/app/enterprise/0.33-x/getting-started/configuring-a-service.md b/archive/enterprise/0.33-x/getting-started/configuring-a-service.md similarity index 100% rename from app/enterprise/0.33-x/getting-started/configuring-a-service.md rename to archive/enterprise/0.33-x/getting-started/configuring-a-service.md diff --git a/app/enterprise/0.33-x/getting-started/enabling-plugins.md b/archive/enterprise/0.33-x/getting-started/enabling-plugins.md similarity index 100% rename from app/enterprise/0.33-x/getting-started/enabling-plugins.md rename to archive/enterprise/0.33-x/getting-started/enabling-plugins.md diff --git a/app/enterprise/0.33-x/getting-started/introduction.md b/archive/enterprise/0.33-x/getting-started/introduction.md similarity index 100% rename from app/enterprise/0.33-x/getting-started/introduction.md rename to archive/enterprise/0.33-x/getting-started/introduction.md diff --git a/app/enterprise/0.33-x/getting-started/licensing.md b/archive/enterprise/0.33-x/getting-started/licensing.md similarity index 100% rename from app/enterprise/0.33-x/getting-started/licensing.md rename to archive/enterprise/0.33-x/getting-started/licensing.md diff --git a/app/enterprise/0.33-x/getting-started/quickstart.md b/archive/enterprise/0.33-x/getting-started/quickstart.md similarity index 100% rename from app/enterprise/0.33-x/getting-started/quickstart.md rename to archive/enterprise/0.33-x/getting-started/quickstart.md diff --git a/app/enterprise/0.33-x/index.md b/archive/enterprise/0.33-x/index.md similarity index 100% rename from app/enterprise/0.33-x/index.md rename to archive/enterprise/0.33-x/index.md diff --git a/app/enterprise/0.33-x/installation/amazon-linux.md b/archive/enterprise/0.33-x/installation/amazon-linux.md similarity index 100% rename from app/enterprise/0.33-x/installation/amazon-linux.md rename to archive/enterprise/0.33-x/installation/amazon-linux.md diff --git a/app/enterprise/0.33-x/installation/centos.md b/archive/enterprise/0.33-x/installation/centos.md similarity index 100% rename from app/enterprise/0.33-x/installation/centos.md rename to archive/enterprise/0.33-x/installation/centos.md diff --git a/app/enterprise/0.33-x/installation/docker.md b/archive/enterprise/0.33-x/installation/docker.md similarity index 100% rename from app/enterprise/0.33-x/installation/docker.md rename to archive/enterprise/0.33-x/installation/docker.md diff --git a/app/enterprise/0.33-x/kong-architecture-overview.md b/archive/enterprise/0.33-x/kong-architecture-overview.md similarity index 100% rename from app/enterprise/0.33-x/kong-architecture-overview.md rename to archive/enterprise/0.33-x/kong-architecture-overview.md diff --git a/app/enterprise/0.33-x/kong-architecture-patterns.md b/archive/enterprise/0.33-x/kong-architecture-patterns.md similarity index 100% rename from app/enterprise/0.33-x/kong-architecture-patterns.md rename to archive/enterprise/0.33-x/kong-architecture-patterns.md diff --git a/app/enterprise/0.33-x/oidc-auth0.md b/archive/enterprise/0.33-x/oidc-auth0.md similarity index 100% rename from app/enterprise/0.33-x/oidc-auth0.md rename to archive/enterprise/0.33-x/oidc-auth0.md diff --git a/app/enterprise/0.33-x/oidc-google.md b/archive/enterprise/0.33-x/oidc-google.md similarity index 100% rename from app/enterprise/0.33-x/oidc-google.md rename to archive/enterprise/0.33-x/oidc-google.md diff --git a/app/enterprise/0.33-x/plugins/canary-release.md b/archive/enterprise/0.33-x/plugins/canary-release.md similarity index 100% rename from app/enterprise/0.33-x/plugins/canary-release.md rename to archive/enterprise/0.33-x/plugins/canary-release.md diff --git a/app/enterprise/0.33-x/plugins/forward-proxy.md b/archive/enterprise/0.33-x/plugins/forward-proxy.md similarity index 100% rename from app/enterprise/0.33-x/plugins/forward-proxy.md rename to archive/enterprise/0.33-x/plugins/forward-proxy.md diff --git a/app/enterprise/0.33-x/plugins/http-proxy-caching.md b/archive/enterprise/0.33-x/plugins/http-proxy-caching.md similarity index 100% rename from app/enterprise/0.33-x/plugins/http-proxy-caching.md rename to archive/enterprise/0.33-x/plugins/http-proxy-caching.md diff --git a/app/enterprise/0.33-x/plugins/ldap-authentication-advanced.md b/archive/enterprise/0.33-x/plugins/ldap-authentication-advanced.md similarity index 100% rename from app/enterprise/0.33-x/plugins/ldap-authentication-advanced.md rename to archive/enterprise/0.33-x/plugins/ldap-authentication-advanced.md diff --git a/app/enterprise/0.33-x/plugins/oauth2-introspection.md b/archive/enterprise/0.33-x/plugins/oauth2-introspection.md similarity index 100% rename from app/enterprise/0.33-x/plugins/oauth2-introspection.md rename to archive/enterprise/0.33-x/plugins/oauth2-introspection.md diff --git a/app/enterprise/0.33-x/plugins/openid-connect.md b/archive/enterprise/0.33-x/plugins/openid-connect.md similarity index 100% rename from app/enterprise/0.33-x/plugins/openid-connect.md rename to archive/enterprise/0.33-x/plugins/openid-connect.md diff --git a/app/enterprise/0.33-x/plugins/rate-limiting-advanced.md b/archive/enterprise/0.33-x/plugins/rate-limiting-advanced.md similarity index 100% rename from app/enterprise/0.33-x/plugins/rate-limiting-advanced.md rename to archive/enterprise/0.33-x/plugins/rate-limiting-advanced.md diff --git a/app/enterprise/0.33-x/plugins/request-transformer.md b/archive/enterprise/0.33-x/plugins/request-transformer.md similarity index 100% rename from app/enterprise/0.33-x/plugins/request-transformer.md rename to archive/enterprise/0.33-x/plugins/request-transformer.md diff --git a/app/enterprise/0.33-x/plugins/statsd-advanced.md b/archive/enterprise/0.33-x/plugins/statsd-advanced.md similarity index 100% rename from app/enterprise/0.33-x/plugins/statsd-advanced.md rename to archive/enterprise/0.33-x/plugins/statsd-advanced.md diff --git a/app/enterprise/0.33-x/postgresql-redhat.md b/archive/enterprise/0.33-x/postgresql-redhat.md similarity index 100% rename from app/enterprise/0.33-x/postgresql-redhat.md rename to archive/enterprise/0.33-x/postgresql-redhat.md diff --git a/app/enterprise/0.33-x/rate-limiting.md b/archive/enterprise/0.33-x/rate-limiting.md similarity index 100% rename from app/enterprise/0.33-x/rate-limiting.md rename to archive/enterprise/0.33-x/rate-limiting.md diff --git a/app/enterprise/0.33-x/rbac/admin-api.md b/archive/enterprise/0.33-x/rbac/admin-api.md similarity index 100% rename from app/enterprise/0.33-x/rbac/admin-api.md rename to archive/enterprise/0.33-x/rbac/admin-api.md diff --git a/app/enterprise/0.33-x/rbac/examples.md b/archive/enterprise/0.33-x/rbac/examples.md similarity index 100% rename from app/enterprise/0.33-x/rbac/examples.md rename to archive/enterprise/0.33-x/rbac/examples.md diff --git a/app/enterprise/0.33-x/rbac/overview.md b/archive/enterprise/0.33-x/rbac/overview.md similarity index 100% rename from app/enterprise/0.33-x/rbac/overview.md rename to archive/enterprise/0.33-x/rbac/overview.md diff --git a/app/enterprise/0.33-x/upgrades-migrations.md b/archive/enterprise/0.33-x/upgrades-migrations.md similarity index 100% rename from app/enterprise/0.33-x/upgrades-migrations.md rename to archive/enterprise/0.33-x/upgrades-migrations.md diff --git a/app/enterprise/0.33-x/vitals.md b/archive/enterprise/0.33-x/vitals.md similarity index 100% rename from app/enterprise/0.33-x/vitals.md rename to archive/enterprise/0.33-x/vitals.md diff --git a/app/enterprise/0.33-x/vitalsSpec.yaml b/archive/enterprise/0.33-x/vitalsSpec.yaml similarity index 100% rename from app/enterprise/0.33-x/vitalsSpec.yaml rename to archive/enterprise/0.33-x/vitalsSpec.yaml diff --git a/app/enterprise/0.33-x/workspaces/admin-api.md b/archive/enterprise/0.33-x/workspaces/admin-api.md similarity index 100% rename from app/enterprise/0.33-x/workspaces/admin-api.md rename to archive/enterprise/0.33-x/workspaces/admin-api.md diff --git a/app/enterprise/0.33-x/workspaces/examples.md b/archive/enterprise/0.33-x/workspaces/examples.md similarity index 100% rename from app/enterprise/0.33-x/workspaces/examples.md rename to archive/enterprise/0.33-x/workspaces/examples.md diff --git a/app/enterprise/0.33-x/workspaces/overview.md b/archive/enterprise/0.33-x/workspaces/overview.md similarity index 100% rename from app/enterprise/0.33-x/workspaces/overview.md rename to archive/enterprise/0.33-x/workspaces/overview.md diff --git a/app/enterprise/0.34-x/admin-api-audit-log.md b/archive/enterprise/0.34-x/admin-api-audit-log.md similarity index 100% rename from app/enterprise/0.34-x/admin-api-audit-log.md rename to archive/enterprise/0.34-x/admin-api-audit-log.md diff --git a/app/enterprise/0.34-x/admin-api.md b/archive/enterprise/0.34-x/admin-api.md similarity index 100% rename from app/enterprise/0.34-x/admin-api.md rename to archive/enterprise/0.34-x/admin-api.md diff --git a/app/enterprise/0.34-x/allowing-multiple-authentication-methods.md b/archive/enterprise/0.34-x/allowing-multiple-authentication-methods.md similarity index 100% rename from app/enterprise/0.34-x/allowing-multiple-authentication-methods.md rename to archive/enterprise/0.34-x/allowing-multiple-authentication-methods.md diff --git a/app/enterprise/0.34-x/auth.md b/archive/enterprise/0.34-x/auth.md similarity index 100% rename from app/enterprise/0.34-x/auth.md rename to archive/enterprise/0.34-x/auth.md diff --git a/app/enterprise/0.34-x/cli.md b/archive/enterprise/0.34-x/cli.md similarity index 100% rename from app/enterprise/0.34-x/cli.md rename to archive/enterprise/0.34-x/cli.md diff --git a/app/enterprise/0.34-x/clustering.md b/archive/enterprise/0.34-x/clustering.md similarity index 100% rename from app/enterprise/0.34-x/clustering.md rename to archive/enterprise/0.34-x/clustering.md diff --git a/app/enterprise/0.34-x/configuration.md b/archive/enterprise/0.34-x/configuration.md similarity index 100% rename from app/enterprise/0.34-x/configuration.md rename to archive/enterprise/0.34-x/configuration.md diff --git a/app/enterprise/0.34-x/deployment-guide.md b/archive/enterprise/0.34-x/deployment-guide.md similarity index 100% rename from app/enterprise/0.34-x/deployment-guide.md rename to archive/enterprise/0.34-x/deployment-guide.md diff --git a/app/enterprise/0.34-x/developer-portal/configuration/authentication.md b/archive/enterprise/0.34-x/developer-portal/configuration/authentication.md similarity index 100% rename from app/enterprise/0.34-x/developer-portal/configuration/authentication.md rename to archive/enterprise/0.34-x/developer-portal/configuration/authentication.md diff --git a/app/enterprise/0.34-x/developer-portal/configuration/getting-started.md b/archive/enterprise/0.34-x/developer-portal/configuration/getting-started.md similarity index 100% rename from app/enterprise/0.34-x/developer-portal/configuration/getting-started.md rename to archive/enterprise/0.34-x/developer-portal/configuration/getting-started.md diff --git a/app/enterprise/0.34-x/developer-portal/configuration/networking.md b/archive/enterprise/0.34-x/developer-portal/configuration/networking.md similarity index 100% rename from app/enterprise/0.34-x/developer-portal/configuration/networking.md rename to archive/enterprise/0.34-x/developer-portal/configuration/networking.md diff --git a/app/enterprise/0.34-x/developer-portal/configuration/smtp.md b/archive/enterprise/0.34-x/developer-portal/configuration/smtp.md similarity index 100% rename from app/enterprise/0.34-x/developer-portal/configuration/smtp.md rename to archive/enterprise/0.34-x/developer-portal/configuration/smtp.md diff --git a/app/enterprise/0.34-x/developer-portal/configuration/workspaces.md b/archive/enterprise/0.34-x/developer-portal/configuration/workspaces.md similarity index 100% rename from app/enterprise/0.34-x/developer-portal/configuration/workspaces.md rename to archive/enterprise/0.34-x/developer-portal/configuration/workspaces.md diff --git a/app/enterprise/0.34-x/developer-portal/customization.md b/archive/enterprise/0.34-x/developer-portal/customization.md similarity index 100% rename from app/enterprise/0.34-x/developer-portal/customization.md rename to archive/enterprise/0.34-x/developer-portal/customization.md diff --git a/app/enterprise/0.34-x/developer-portal/customization/customization.md b/archive/enterprise/0.34-x/developer-portal/customization/customization.md similarity index 100% rename from app/enterprise/0.34-x/developer-portal/customization/customization.md rename to archive/enterprise/0.34-x/developer-portal/customization/customization.md diff --git a/app/enterprise/0.34-x/developer-portal/customization/smart-components.md b/archive/enterprise/0.34-x/developer-portal/customization/smart-components.md similarity index 100% rename from app/enterprise/0.34-x/developer-portal/customization/smart-components.md rename to archive/enterprise/0.34-x/developer-portal/customization/smart-components.md diff --git a/app/enterprise/0.34-x/developer-portal/developers/developer-access.md b/archive/enterprise/0.34-x/developer-portal/developers/developer-access.md similarity index 100% rename from app/enterprise/0.34-x/developer-portal/developers/developer-access.md rename to archive/enterprise/0.34-x/developer-portal/developers/developer-access.md diff --git a/app/enterprise/0.34-x/developer-portal/faq.md b/archive/enterprise/0.34-x/developer-portal/faq.md similarity index 100% rename from app/enterprise/0.34-x/developer-portal/faq.md rename to archive/enterprise/0.34-x/developer-portal/faq.md diff --git a/app/enterprise/0.34-x/developer-portal/glossary.md b/archive/enterprise/0.34-x/developer-portal/glossary.md similarity index 100% rename from app/enterprise/0.34-x/developer-portal/glossary.md rename to archive/enterprise/0.34-x/developer-portal/glossary.md diff --git a/app/enterprise/0.34-x/developer-portal/introduction.md b/archive/enterprise/0.34-x/developer-portal/introduction.md similarity index 100% rename from app/enterprise/0.34-x/developer-portal/introduction.md rename to archive/enterprise/0.34-x/developer-portal/introduction.md diff --git a/app/enterprise/0.34-x/developer-portal/management/developers.md b/archive/enterprise/0.34-x/developer-portal/management/developers.md similarity index 100% rename from app/enterprise/0.34-x/developer-portal/management/developers.md rename to archive/enterprise/0.34-x/developer-portal/management/developers.md diff --git a/app/enterprise/0.34-x/developer-portal/management/file-management.md b/archive/enterprise/0.34-x/developer-portal/management/file-management.md similarity index 100% rename from app/enterprise/0.34-x/developer-portal/management/file-management.md rename to archive/enterprise/0.34-x/developer-portal/management/file-management.md diff --git a/app/enterprise/0.34-x/edition-versioning.md b/archive/enterprise/0.34-x/edition-versioning.md similarity index 100% rename from app/enterprise/0.34-x/edition-versioning.md rename to archive/enterprise/0.34-x/edition-versioning.md diff --git a/app/enterprise/0.34-x/getting-started/accessing-your-license.md b/archive/enterprise/0.34-x/getting-started/accessing-your-license.md similarity index 100% rename from app/enterprise/0.34-x/getting-started/accessing-your-license.md rename to archive/enterprise/0.34-x/getting-started/accessing-your-license.md diff --git a/app/enterprise/0.34-x/getting-started/adding-consumers.md b/archive/enterprise/0.34-x/getting-started/adding-consumers.md similarity index 100% rename from app/enterprise/0.34-x/getting-started/adding-consumers.md rename to archive/enterprise/0.34-x/getting-started/adding-consumers.md diff --git a/app/enterprise/0.34-x/getting-started/adding-your-api.md b/archive/enterprise/0.34-x/getting-started/adding-your-api.md similarity index 100% rename from app/enterprise/0.34-x/getting-started/adding-your-api.md rename to archive/enterprise/0.34-x/getting-started/adding-your-api.md diff --git a/app/enterprise/0.34-x/getting-started/configuring-a-service.md b/archive/enterprise/0.34-x/getting-started/configuring-a-service.md similarity index 100% rename from app/enterprise/0.34-x/getting-started/configuring-a-service.md rename to archive/enterprise/0.34-x/getting-started/configuring-a-service.md diff --git a/app/enterprise/0.34-x/getting-started/enabling-plugins.md b/archive/enterprise/0.34-x/getting-started/enabling-plugins.md similarity index 100% rename from app/enterprise/0.34-x/getting-started/enabling-plugins.md rename to archive/enterprise/0.34-x/getting-started/enabling-plugins.md diff --git a/app/enterprise/0.34-x/getting-started/introduction.md b/archive/enterprise/0.34-x/getting-started/introduction.md similarity index 100% rename from app/enterprise/0.34-x/getting-started/introduction.md rename to archive/enterprise/0.34-x/getting-started/introduction.md diff --git a/app/enterprise/0.34-x/getting-started/licensing.md b/archive/enterprise/0.34-x/getting-started/licensing.md similarity index 100% rename from app/enterprise/0.34-x/getting-started/licensing.md rename to archive/enterprise/0.34-x/getting-started/licensing.md diff --git a/app/enterprise/0.34-x/getting-started/quickstart.md b/archive/enterprise/0.34-x/getting-started/quickstart.md similarity index 100% rename from app/enterprise/0.34-x/getting-started/quickstart.md rename to archive/enterprise/0.34-x/getting-started/quickstart.md diff --git a/app/enterprise/0.34-x/health-checks-circuit-breakers.md b/archive/enterprise/0.34-x/health-checks-circuit-breakers.md similarity index 100% rename from app/enterprise/0.34-x/health-checks-circuit-breakers.md rename to archive/enterprise/0.34-x/health-checks-circuit-breakers.md diff --git a/app/enterprise/0.34-x/index.md b/archive/enterprise/0.34-x/index.md similarity index 100% rename from app/enterprise/0.34-x/index.md rename to archive/enterprise/0.34-x/index.md diff --git a/app/enterprise/0.34-x/installation/amazon-linux.md b/archive/enterprise/0.34-x/installation/amazon-linux.md similarity index 100% rename from app/enterprise/0.34-x/installation/amazon-linux.md rename to archive/enterprise/0.34-x/installation/amazon-linux.md diff --git a/app/enterprise/0.34-x/installation/centos.md b/archive/enterprise/0.34-x/installation/centos.md similarity index 100% rename from app/enterprise/0.34-x/installation/centos.md rename to archive/enterprise/0.34-x/installation/centos.md diff --git a/app/enterprise/0.34-x/installation/docker.md b/archive/enterprise/0.34-x/installation/docker.md similarity index 100% rename from app/enterprise/0.34-x/installation/docker.md rename to archive/enterprise/0.34-x/installation/docker.md diff --git a/app/enterprise/0.34-x/kong-architecture-overview.md b/archive/enterprise/0.34-x/kong-architecture-overview.md similarity index 100% rename from app/enterprise/0.34-x/kong-architecture-overview.md rename to archive/enterprise/0.34-x/kong-architecture-overview.md diff --git a/app/enterprise/0.34-x/kong-architecture-patterns.md b/archive/enterprise/0.34-x/kong-architecture-patterns.md similarity index 100% rename from app/enterprise/0.34-x/kong-architecture-patterns.md rename to archive/enterprise/0.34-x/kong-architecture-patterns.md diff --git a/app/enterprise/0.34-x/kong-aws.md b/archive/enterprise/0.34-x/kong-aws.md similarity index 100% rename from app/enterprise/0.34-x/kong-aws.md rename to archive/enterprise/0.34-x/kong-aws.md diff --git a/app/enterprise/0.34-x/kong-manager/configuration/authentication.md b/archive/enterprise/0.34-x/kong-manager/configuration/authentication.md similarity index 100% rename from app/enterprise/0.34-x/kong-manager/configuration/authentication.md rename to archive/enterprise/0.34-x/kong-manager/configuration/authentication.md diff --git a/app/enterprise/0.34-x/kong-manager/configuration/getting-started.md b/archive/enterprise/0.34-x/kong-manager/configuration/getting-started.md similarity index 100% rename from app/enterprise/0.34-x/kong-manager/configuration/getting-started.md rename to archive/enterprise/0.34-x/kong-manager/configuration/getting-started.md diff --git a/app/enterprise/0.34-x/kong-manager/configuration/networking.md b/archive/enterprise/0.34-x/kong-manager/configuration/networking.md similarity index 100% rename from app/enterprise/0.34-x/kong-manager/configuration/networking.md rename to archive/enterprise/0.34-x/kong-manager/configuration/networking.md diff --git a/app/enterprise/0.34-x/kong-manager/organization-management/managing-admins.md b/archive/enterprise/0.34-x/kong-manager/organization-management/managing-admins.md similarity index 100% rename from app/enterprise/0.34-x/kong-manager/organization-management/managing-admins.md rename to archive/enterprise/0.34-x/kong-manager/organization-management/managing-admins.md diff --git a/app/enterprise/0.34-x/kong-manager/organization-management/rbac-and-perms.md b/archive/enterprise/0.34-x/kong-manager/organization-management/rbac-and-perms.md similarity index 100% rename from app/enterprise/0.34-x/kong-manager/organization-management/rbac-and-perms.md rename to archive/enterprise/0.34-x/kong-manager/organization-management/rbac-and-perms.md diff --git a/app/enterprise/0.34-x/kong-manager/organization-management/workspaces.md b/archive/enterprise/0.34-x/kong-manager/organization-management/workspaces.md similarity index 100% rename from app/enterprise/0.34-x/kong-manager/organization-management/workspaces.md rename to archive/enterprise/0.34-x/kong-manager/organization-management/workspaces.md diff --git a/app/enterprise/0.34-x/kong-manager/overview.md b/archive/enterprise/0.34-x/kong-manager/overview.md similarity index 100% rename from app/enterprise/0.34-x/kong-manager/overview.md rename to archive/enterprise/0.34-x/kong-manager/overview.md diff --git a/app/enterprise/0.34-x/kong-manager/vitals.md b/archive/enterprise/0.34-x/kong-manager/vitals.md similarity index 100% rename from app/enterprise/0.34-x/kong-manager/vitals.md rename to archive/enterprise/0.34-x/kong-manager/vitals.md diff --git a/app/enterprise/0.34-x/loadbalancing.md b/archive/enterprise/0.34-x/loadbalancing.md similarity index 100% rename from app/enterprise/0.34-x/loadbalancing.md rename to archive/enterprise/0.34-x/loadbalancing.md diff --git a/app/enterprise/0.34-x/network.md b/archive/enterprise/0.34-x/network.md similarity index 100% rename from app/enterprise/0.34-x/network.md rename to archive/enterprise/0.34-x/network.md diff --git a/app/enterprise/0.34-x/oidc-auth0.md b/archive/enterprise/0.34-x/oidc-auth0.md similarity index 100% rename from app/enterprise/0.34-x/oidc-auth0.md rename to archive/enterprise/0.34-x/oidc-auth0.md diff --git a/app/enterprise/0.34-x/oidc-google.md b/archive/enterprise/0.34-x/oidc-google.md similarity index 100% rename from app/enterprise/0.34-x/oidc-google.md rename to archive/enterprise/0.34-x/oidc-google.md diff --git a/app/enterprise/0.34-x/plugin-development/access-the-datastore.md b/archive/enterprise/0.34-x/plugin-development/access-the-datastore.md similarity index 100% rename from app/enterprise/0.34-x/plugin-development/access-the-datastore.md rename to archive/enterprise/0.34-x/plugin-development/access-the-datastore.md diff --git a/app/enterprise/0.34-x/plugin-development/admin-api.md b/archive/enterprise/0.34-x/plugin-development/admin-api.md similarity index 100% rename from app/enterprise/0.34-x/plugin-development/admin-api.md rename to archive/enterprise/0.34-x/plugin-development/admin-api.md diff --git a/app/enterprise/0.34-x/plugin-development/custom-entities.md b/archive/enterprise/0.34-x/plugin-development/custom-entities.md similarity index 100% rename from app/enterprise/0.34-x/plugin-development/custom-entities.md rename to archive/enterprise/0.34-x/plugin-development/custom-entities.md diff --git a/app/enterprise/0.34-x/plugin-development/custom-logic.md b/archive/enterprise/0.34-x/plugin-development/custom-logic.md similarity index 100% rename from app/enterprise/0.34-x/plugin-development/custom-logic.md rename to archive/enterprise/0.34-x/plugin-development/custom-logic.md diff --git a/app/enterprise/0.34-x/plugin-development/distribution.md b/archive/enterprise/0.34-x/plugin-development/distribution.md similarity index 100% rename from app/enterprise/0.34-x/plugin-development/distribution.md rename to archive/enterprise/0.34-x/plugin-development/distribution.md diff --git a/app/enterprise/0.34-x/plugin-development/entities-cache.md b/archive/enterprise/0.34-x/plugin-development/entities-cache.md similarity index 100% rename from app/enterprise/0.34-x/plugin-development/entities-cache.md rename to archive/enterprise/0.34-x/plugin-development/entities-cache.md diff --git a/app/enterprise/0.34-x/plugin-development/file-structure.md b/archive/enterprise/0.34-x/plugin-development/file-structure.md similarity index 100% rename from app/enterprise/0.34-x/plugin-development/file-structure.md rename to archive/enterprise/0.34-x/plugin-development/file-structure.md diff --git a/app/enterprise/0.34-x/plugin-development/index.md b/archive/enterprise/0.34-x/plugin-development/index.md similarity index 100% rename from app/enterprise/0.34-x/plugin-development/index.md rename to archive/enterprise/0.34-x/plugin-development/index.md diff --git a/app/enterprise/0.34-x/plugin-development/plugin-configuration.md b/archive/enterprise/0.34-x/plugin-development/plugin-configuration.md similarity index 100% rename from app/enterprise/0.34-x/plugin-development/plugin-configuration.md rename to archive/enterprise/0.34-x/plugin-development/plugin-configuration.md diff --git a/app/enterprise/0.34-x/plugin-development/tests.md b/archive/enterprise/0.34-x/plugin-development/tests.md similarity index 100% rename from app/enterprise/0.34-x/plugin-development/tests.md rename to archive/enterprise/0.34-x/plugin-development/tests.md diff --git a/app/enterprise/0.34-x/plugins/canary-release.md b/archive/enterprise/0.34-x/plugins/canary-release.md similarity index 100% rename from app/enterprise/0.34-x/plugins/canary-release.md rename to archive/enterprise/0.34-x/plugins/canary-release.md diff --git a/app/enterprise/0.34-x/plugins/forward-proxy.md b/archive/enterprise/0.34-x/plugins/forward-proxy.md similarity index 100% rename from app/enterprise/0.34-x/plugins/forward-proxy.md rename to archive/enterprise/0.34-x/plugins/forward-proxy.md diff --git a/app/enterprise/0.34-x/plugins/http-proxy-caching.md b/archive/enterprise/0.34-x/plugins/http-proxy-caching.md similarity index 100% rename from app/enterprise/0.34-x/plugins/http-proxy-caching.md rename to archive/enterprise/0.34-x/plugins/http-proxy-caching.md diff --git a/app/enterprise/0.34-x/plugins/ldap-authentication-advanced.md b/archive/enterprise/0.34-x/plugins/ldap-authentication-advanced.md similarity index 100% rename from app/enterprise/0.34-x/plugins/ldap-authentication-advanced.md rename to archive/enterprise/0.34-x/plugins/ldap-authentication-advanced.md diff --git a/app/enterprise/0.34-x/plugins/oauth2-introspection.md b/archive/enterprise/0.34-x/plugins/oauth2-introspection.md similarity index 100% rename from app/enterprise/0.34-x/plugins/oauth2-introspection.md rename to archive/enterprise/0.34-x/plugins/oauth2-introspection.md diff --git a/app/enterprise/0.34-x/plugins/openid-connect.md b/archive/enterprise/0.34-x/plugins/openid-connect.md similarity index 100% rename from app/enterprise/0.34-x/plugins/openid-connect.md rename to archive/enterprise/0.34-x/plugins/openid-connect.md diff --git a/app/enterprise/0.34-x/plugins/rate-limiting-advanced.md b/archive/enterprise/0.34-x/plugins/rate-limiting-advanced.md similarity index 100% rename from app/enterprise/0.34-x/plugins/rate-limiting-advanced.md rename to archive/enterprise/0.34-x/plugins/rate-limiting-advanced.md diff --git a/app/enterprise/0.34-x/plugins/request-transformer.md b/archive/enterprise/0.34-x/plugins/request-transformer.md similarity index 100% rename from app/enterprise/0.34-x/plugins/request-transformer.md rename to archive/enterprise/0.34-x/plugins/request-transformer.md diff --git a/app/enterprise/0.34-x/plugins/statsd-advanced.md b/archive/enterprise/0.34-x/plugins/statsd-advanced.md similarity index 100% rename from app/enterprise/0.34-x/plugins/statsd-advanced.md rename to archive/enterprise/0.34-x/plugins/statsd-advanced.md diff --git a/app/enterprise/0.34-x/plugins/statsd.rules.yaml b/archive/enterprise/0.34-x/plugins/statsd.rules.yaml similarity index 100% rename from app/enterprise/0.34-x/plugins/statsd.rules.yaml rename to archive/enterprise/0.34-x/plugins/statsd.rules.yaml diff --git a/app/enterprise/0.34-x/postgresql-redhat.md b/archive/enterprise/0.34-x/postgresql-redhat.md similarity index 100% rename from app/enterprise/0.34-x/postgresql-redhat.md rename to archive/enterprise/0.34-x/postgresql-redhat.md diff --git a/app/enterprise/0.34-x/property-reference.md b/archive/enterprise/0.34-x/property-reference.md similarity index 100% rename from app/enterprise/0.34-x/property-reference.md rename to archive/enterprise/0.34-x/property-reference.md diff --git a/app/enterprise/0.34-x/proxy.md b/archive/enterprise/0.34-x/proxy.md similarity index 100% rename from app/enterprise/0.34-x/proxy.md rename to archive/enterprise/0.34-x/proxy.md diff --git a/app/enterprise/0.34-x/rate-limiting.md b/archive/enterprise/0.34-x/rate-limiting.md similarity index 100% rename from app/enterprise/0.34-x/rate-limiting.md rename to archive/enterprise/0.34-x/rate-limiting.md diff --git a/app/enterprise/0.34-x/rbac/admin-api.md b/archive/enterprise/0.34-x/rbac/admin-api.md similarity index 100% rename from app/enterprise/0.34-x/rbac/admin-api.md rename to archive/enterprise/0.34-x/rbac/admin-api.md diff --git a/app/enterprise/0.34-x/rbac/examples.md b/archive/enterprise/0.34-x/rbac/examples.md similarity index 100% rename from app/enterprise/0.34-x/rbac/examples.md rename to archive/enterprise/0.34-x/rbac/examples.md diff --git a/app/enterprise/0.34-x/rbac/overview.md b/archive/enterprise/0.34-x/rbac/overview.md similarity index 100% rename from app/enterprise/0.34-x/rbac/overview.md rename to archive/enterprise/0.34-x/rbac/overview.md diff --git a/app/enterprise/0.34-x/secure-admin-api.md b/archive/enterprise/0.34-x/secure-admin-api.md similarity index 100% rename from app/enterprise/0.34-x/secure-admin-api.md rename to archive/enterprise/0.34-x/secure-admin-api.md diff --git a/app/enterprise/0.34-x/upgrades-migrations.md b/archive/enterprise/0.34-x/upgrades-migrations.md similarity index 100% rename from app/enterprise/0.34-x/upgrades-migrations.md rename to archive/enterprise/0.34-x/upgrades-migrations.md diff --git a/app/enterprise/0.34-x/vitals-influx-strategy.md b/archive/enterprise/0.34-x/vitals-influx-strategy.md similarity index 100% rename from app/enterprise/0.34-x/vitals-influx-strategy.md rename to archive/enterprise/0.34-x/vitals-influx-strategy.md diff --git a/app/enterprise/0.34-x/vitals-prometheus-strategy.md b/archive/enterprise/0.34-x/vitals-prometheus-strategy.md similarity index 100% rename from app/enterprise/0.34-x/vitals-prometheus-strategy.md rename to archive/enterprise/0.34-x/vitals-prometheus-strategy.md diff --git a/app/enterprise/0.34-x/vitals.md b/archive/enterprise/0.34-x/vitals.md similarity index 100% rename from app/enterprise/0.34-x/vitals.md rename to archive/enterprise/0.34-x/vitals.md diff --git a/app/enterprise/0.34-x/vitalsSpec.yaml b/archive/enterprise/0.34-x/vitalsSpec.yaml similarity index 100% rename from app/enterprise/0.34-x/vitalsSpec.yaml rename to archive/enterprise/0.34-x/vitalsSpec.yaml diff --git a/app/enterprise/0.34-x/workspaces/admin-api.md b/archive/enterprise/0.34-x/workspaces/admin-api.md similarity index 100% rename from app/enterprise/0.34-x/workspaces/admin-api.md rename to archive/enterprise/0.34-x/workspaces/admin-api.md diff --git a/app/enterprise/0.34-x/workspaces/examples.md b/archive/enterprise/0.34-x/workspaces/examples.md similarity index 100% rename from app/enterprise/0.34-x/workspaces/examples.md rename to archive/enterprise/0.34-x/workspaces/examples.md diff --git a/app/enterprise/0.34-x/workspaces/overview.md b/archive/enterprise/0.34-x/workspaces/overview.md similarity index 100% rename from app/enterprise/0.34-x/workspaces/overview.md rename to archive/enterprise/0.34-x/workspaces/overview.md diff --git a/app/enterprise/0.35-x/admin-api/admins/examples.md b/archive/enterprise/0.35-x/admin-api/admins/examples.md similarity index 100% rename from app/enterprise/0.35-x/admin-api/admins/examples.md rename to archive/enterprise/0.35-x/admin-api/admins/examples.md diff --git a/app/enterprise/0.35-x/admin-api/admins/index.md b/archive/enterprise/0.35-x/admin-api/admins/index.md similarity index 100% rename from app/enterprise/0.35-x/admin-api/admins/index.md rename to archive/enterprise/0.35-x/admin-api/admins/index.md diff --git a/app/enterprise/0.35-x/admin-api/admins/reference.md b/archive/enterprise/0.35-x/admin-api/admins/reference.md similarity index 100% rename from app/enterprise/0.35-x/admin-api/admins/reference.md rename to archive/enterprise/0.35-x/admin-api/admins/reference.md diff --git a/app/enterprise/0.35-x/admin-api/audit-log.md b/archive/enterprise/0.35-x/admin-api/audit-log.md similarity index 100% rename from app/enterprise/0.35-x/admin-api/audit-log.md rename to archive/enterprise/0.35-x/admin-api/audit-log.md diff --git a/app/enterprise/0.35-x/admin-api/index.md b/archive/enterprise/0.35-x/admin-api/index.md similarity index 100% rename from app/enterprise/0.35-x/admin-api/index.md rename to archive/enterprise/0.35-x/admin-api/index.md diff --git a/app/enterprise/0.35-x/admin-api/rbac/examples.md b/archive/enterprise/0.35-x/admin-api/rbac/examples.md similarity index 100% rename from app/enterprise/0.35-x/admin-api/rbac/examples.md rename to archive/enterprise/0.35-x/admin-api/rbac/examples.md diff --git a/app/enterprise/0.35-x/admin-api/rbac/reference.md b/archive/enterprise/0.35-x/admin-api/rbac/reference.md similarity index 100% rename from app/enterprise/0.35-x/admin-api/rbac/reference.md rename to archive/enterprise/0.35-x/admin-api/rbac/reference.md diff --git a/app/enterprise/0.35-x/admin-api/vitals/index.md b/archive/enterprise/0.35-x/admin-api/vitals/index.md similarity index 100% rename from app/enterprise/0.35-x/admin-api/vitals/index.md rename to archive/enterprise/0.35-x/admin-api/vitals/index.md diff --git a/app/enterprise/0.35-x/admin-api/vitals/vitals-influx-strategy.md b/archive/enterprise/0.35-x/admin-api/vitals/vitals-influx-strategy.md similarity index 100% rename from app/enterprise/0.35-x/admin-api/vitals/vitals-influx-strategy.md rename to archive/enterprise/0.35-x/admin-api/vitals/vitals-influx-strategy.md diff --git a/app/enterprise/0.35-x/admin-api/vitals/vitals-prometheus-strategy.md b/archive/enterprise/0.35-x/admin-api/vitals/vitals-prometheus-strategy.md similarity index 100% rename from app/enterprise/0.35-x/admin-api/vitals/vitals-prometheus-strategy.md rename to archive/enterprise/0.35-x/admin-api/vitals/vitals-prometheus-strategy.md diff --git a/app/enterprise/0.35-x/admin-api/vitals/vitalsSpec.yaml b/archive/enterprise/0.35-x/admin-api/vitals/vitalsSpec.yaml similarity index 100% rename from app/enterprise/0.35-x/admin-api/vitals/vitalsSpec.yaml rename to archive/enterprise/0.35-x/admin-api/vitals/vitalsSpec.yaml diff --git a/app/enterprise/0.35-x/admin-api/workspaces/examples.md b/archive/enterprise/0.35-x/admin-api/workspaces/examples.md similarity index 100% rename from app/enterprise/0.35-x/admin-api/workspaces/examples.md rename to archive/enterprise/0.35-x/admin-api/workspaces/examples.md diff --git a/app/enterprise/0.35-x/admin-api/workspaces/reference.md b/archive/enterprise/0.35-x/admin-api/workspaces/reference.md similarity index 100% rename from app/enterprise/0.35-x/admin-api/workspaces/reference.md rename to archive/enterprise/0.35-x/admin-api/workspaces/reference.md diff --git a/app/enterprise/0.35-x/auth.md b/archive/enterprise/0.35-x/auth.md similarity index 100% rename from app/enterprise/0.35-x/auth.md rename to archive/enterprise/0.35-x/auth.md diff --git a/app/enterprise/0.35-x/cli.md b/archive/enterprise/0.35-x/cli.md similarity index 100% rename from app/enterprise/0.35-x/cli.md rename to archive/enterprise/0.35-x/cli.md diff --git a/app/enterprise/0.35-x/clustering.md b/archive/enterprise/0.35-x/clustering.md similarity index 100% rename from app/enterprise/0.35-x/clustering.md rename to archive/enterprise/0.35-x/clustering.md diff --git a/app/enterprise/0.35-x/deployment/access-license.md b/archive/enterprise/0.35-x/deployment/access-license.md similarity index 100% rename from app/enterprise/0.35-x/deployment/access-license.md rename to archive/enterprise/0.35-x/deployment/access-license.md diff --git a/app/enterprise/0.35-x/deployment/installation/amazon-linux.md b/archive/enterprise/0.35-x/deployment/installation/amazon-linux.md similarity index 100% rename from app/enterprise/0.35-x/deployment/installation/amazon-linux.md rename to archive/enterprise/0.35-x/deployment/installation/amazon-linux.md diff --git a/app/enterprise/0.35-x/deployment/installation/centos.md b/archive/enterprise/0.35-x/deployment/installation/centos.md similarity index 100% rename from app/enterprise/0.35-x/deployment/installation/centos.md rename to archive/enterprise/0.35-x/deployment/installation/centos.md diff --git a/app/enterprise/0.35-x/deployment/installation/docker.md b/archive/enterprise/0.35-x/deployment/installation/docker.md similarity index 100% rename from app/enterprise/0.35-x/deployment/installation/docker.md rename to archive/enterprise/0.35-x/deployment/installation/docker.md diff --git a/app/enterprise/0.35-x/deployment/installation/overview.md b/archive/enterprise/0.35-x/deployment/installation/overview.md similarity index 100% rename from app/enterprise/0.35-x/deployment/installation/overview.md rename to archive/enterprise/0.35-x/deployment/installation/overview.md diff --git a/app/enterprise/0.35-x/deployment/installation/ubuntu.md b/archive/enterprise/0.35-x/deployment/installation/ubuntu.md similarity index 100% rename from app/enterprise/0.35-x/deployment/installation/ubuntu.md rename to archive/enterprise/0.35-x/deployment/installation/ubuntu.md diff --git a/app/enterprise/0.35-x/deployment/licensing.md b/archive/enterprise/0.35-x/deployment/licensing.md similarity index 100% rename from app/enterprise/0.35-x/deployment/licensing.md rename to archive/enterprise/0.35-x/deployment/licensing.md diff --git a/app/enterprise/0.35-x/deployment/migrate-apis-cli.md b/archive/enterprise/0.35-x/deployment/migrate-apis-cli.md similarity index 100% rename from app/enterprise/0.35-x/deployment/migrate-apis-cli.md rename to archive/enterprise/0.35-x/deployment/migrate-apis-cli.md diff --git a/app/enterprise/0.35-x/deployment/migrations.md b/archive/enterprise/0.35-x/deployment/migrations.md similarity index 100% rename from app/enterprise/0.35-x/deployment/migrations.md rename to archive/enterprise/0.35-x/deployment/migrations.md diff --git a/app/enterprise/0.35-x/developer-portal/administration/developer-access.md b/archive/enterprise/0.35-x/developer-portal/administration/developer-access.md similarity index 100% rename from app/enterprise/0.35-x/developer-portal/administration/developer-access.md rename to archive/enterprise/0.35-x/developer-portal/administration/developer-access.md diff --git a/app/enterprise/0.35-x/developer-portal/administration/managing-developers.md b/archive/enterprise/0.35-x/developer-portal/administration/managing-developers.md similarity index 100% rename from app/enterprise/0.35-x/developer-portal/administration/managing-developers.md rename to archive/enterprise/0.35-x/developer-portal/administration/managing-developers.md diff --git a/app/enterprise/0.35-x/developer-portal/best-practices.md b/archive/enterprise/0.35-x/developer-portal/best-practices.md similarity index 100% rename from app/enterprise/0.35-x/developer-portal/best-practices.md rename to archive/enterprise/0.35-x/developer-portal/best-practices.md diff --git a/app/enterprise/0.35-x/developer-portal/configuration/authentication/adding-registration-fields.md b/archive/enterprise/0.35-x/developer-portal/configuration/authentication/adding-registration-fields.md similarity index 100% rename from app/enterprise/0.35-x/developer-portal/configuration/authentication/adding-registration-fields.md rename to archive/enterprise/0.35-x/developer-portal/configuration/authentication/adding-registration-fields.md diff --git a/app/enterprise/0.35-x/developer-portal/configuration/authentication/basic-auth.md b/archive/enterprise/0.35-x/developer-portal/configuration/authentication/basic-auth.md similarity index 100% rename from app/enterprise/0.35-x/developer-portal/configuration/authentication/basic-auth.md rename to archive/enterprise/0.35-x/developer-portal/configuration/authentication/basic-auth.md diff --git a/app/enterprise/0.35-x/developer-portal/configuration/authentication/disabling-auth.md b/archive/enterprise/0.35-x/developer-portal/configuration/authentication/disabling-auth.md similarity index 100% rename from app/enterprise/0.35-x/developer-portal/configuration/authentication/disabling-auth.md rename to archive/enterprise/0.35-x/developer-portal/configuration/authentication/disabling-auth.md diff --git a/app/enterprise/0.35-x/developer-portal/configuration/authentication/index.md b/archive/enterprise/0.35-x/developer-portal/configuration/authentication/index.md similarity index 100% rename from app/enterprise/0.35-x/developer-portal/configuration/authentication/index.md rename to archive/enterprise/0.35-x/developer-portal/configuration/authentication/index.md diff --git a/app/enterprise/0.35-x/developer-portal/configuration/authentication/key-auth.md b/archive/enterprise/0.35-x/developer-portal/configuration/authentication/key-auth.md similarity index 100% rename from app/enterprise/0.35-x/developer-portal/configuration/authentication/key-auth.md rename to archive/enterprise/0.35-x/developer-portal/configuration/authentication/key-auth.md diff --git a/app/enterprise/0.35-x/developer-portal/configuration/authentication/oidc.md b/archive/enterprise/0.35-x/developer-portal/configuration/authentication/oidc.md similarity index 100% rename from app/enterprise/0.35-x/developer-portal/configuration/authentication/oidc.md rename to archive/enterprise/0.35-x/developer-portal/configuration/authentication/oidc.md diff --git a/app/enterprise/0.35-x/developer-portal/configuration/authentication/sessions.md b/archive/enterprise/0.35-x/developer-portal/configuration/authentication/sessions.md similarity index 100% rename from app/enterprise/0.35-x/developer-portal/configuration/authentication/sessions.md rename to archive/enterprise/0.35-x/developer-portal/configuration/authentication/sessions.md diff --git a/app/enterprise/0.35-x/developer-portal/configuration/authentication/understanding-page-routing.md b/archive/enterprise/0.35-x/developer-portal/configuration/authentication/understanding-page-routing.md similarity index 100% rename from app/enterprise/0.35-x/developer-portal/configuration/authentication/understanding-page-routing.md rename to archive/enterprise/0.35-x/developer-portal/configuration/authentication/understanding-page-routing.md diff --git a/app/enterprise/0.35-x/developer-portal/configuration/index.md b/archive/enterprise/0.35-x/developer-portal/configuration/index.md similarity index 100% rename from app/enterprise/0.35-x/developer-portal/configuration/index.md rename to archive/enterprise/0.35-x/developer-portal/configuration/index.md diff --git a/app/enterprise/0.35-x/developer-portal/configuration/smtp.md b/archive/enterprise/0.35-x/developer-portal/configuration/smtp.md similarity index 100% rename from app/enterprise/0.35-x/developer-portal/configuration/smtp.md rename to archive/enterprise/0.35-x/developer-portal/configuration/smtp.md diff --git a/app/enterprise/0.35-x/developer-portal/configuration/workspaces.md b/archive/enterprise/0.35-x/developer-portal/configuration/workspaces.md similarity index 100% rename from app/enterprise/0.35-x/developer-portal/configuration/workspaces.md rename to archive/enterprise/0.35-x/developer-portal/configuration/workspaces.md diff --git a/app/enterprise/0.35-x/developer-portal/content-management/file-management.md b/archive/enterprise/0.35-x/developer-portal/content-management/file-management.md similarity index 100% rename from app/enterprise/0.35-x/developer-portal/content-management/file-management.md rename to archive/enterprise/0.35-x/developer-portal/content-management/file-management.md diff --git a/app/enterprise/0.35-x/developer-portal/content-management/index.md b/archive/enterprise/0.35-x/developer-portal/content-management/index.md similarity index 100% rename from app/enterprise/0.35-x/developer-portal/content-management/index.md rename to archive/enterprise/0.35-x/developer-portal/content-management/index.md diff --git a/app/enterprise/0.35-x/developer-portal/content-management/serving-assets/aws-cloudfront.md b/archive/enterprise/0.35-x/developer-portal/content-management/serving-assets/aws-cloudfront.md similarity index 100% rename from app/enterprise/0.35-x/developer-portal/content-management/serving-assets/aws-cloudfront.md rename to archive/enterprise/0.35-x/developer-portal/content-management/serving-assets/aws-cloudfront.md diff --git a/app/enterprise/0.35-x/developer-portal/content-management/serving-assets/google-cloud.md b/archive/enterprise/0.35-x/developer-portal/content-management/serving-assets/google-cloud.md similarity index 100% rename from app/enterprise/0.35-x/developer-portal/content-management/serving-assets/google-cloud.md rename to archive/enterprise/0.35-x/developer-portal/content-management/serving-assets/google-cloud.md diff --git a/app/enterprise/0.35-x/developer-portal/content-management/serving-assets/index.md b/archive/enterprise/0.35-x/developer-portal/content-management/serving-assets/index.md similarity index 100% rename from app/enterprise/0.35-x/developer-portal/content-management/serving-assets/index.md rename to archive/enterprise/0.35-x/developer-portal/content-management/serving-assets/index.md diff --git a/app/enterprise/0.35-x/developer-portal/faq.md b/archive/enterprise/0.35-x/developer-portal/faq.md similarity index 100% rename from app/enterprise/0.35-x/developer-portal/faq.md rename to archive/enterprise/0.35-x/developer-portal/faq.md diff --git a/app/enterprise/0.35-x/developer-portal/introduction.md b/archive/enterprise/0.35-x/developer-portal/introduction.md similarity index 100% rename from app/enterprise/0.35-x/developer-portal/introduction.md rename to archive/enterprise/0.35-x/developer-portal/introduction.md diff --git a/app/enterprise/0.35-x/developer-portal/networking.md b/archive/enterprise/0.35-x/developer-portal/networking.md similarity index 100% rename from app/enterprise/0.35-x/developer-portal/networking.md rename to archive/enterprise/0.35-x/developer-portal/networking.md diff --git a/app/enterprise/0.35-x/developer-portal/quickstart.md b/archive/enterprise/0.35-x/developer-portal/quickstart.md similarity index 100% rename from app/enterprise/0.35-x/developer-portal/quickstart.md rename to archive/enterprise/0.35-x/developer-portal/quickstart.md diff --git a/app/enterprise/0.35-x/developer-portal/theme-customization/customizing-dev-portal.md b/archive/enterprise/0.35-x/developer-portal/theme-customization/customizing-dev-portal.md similarity index 100% rename from app/enterprise/0.35-x/developer-portal/theme-customization/customizing-dev-portal.md rename to archive/enterprise/0.35-x/developer-portal/theme-customization/customizing-dev-portal.md diff --git a/app/enterprise/0.35-x/getting-started/add-admin.md b/archive/enterprise/0.35-x/getting-started/add-admin.md similarity index 100% rename from app/enterprise/0.35-x/getting-started/add-admin.md rename to archive/enterprise/0.35-x/getting-started/add-admin.md diff --git a/app/enterprise/0.35-x/getting-started/add-consumer.md b/archive/enterprise/0.35-x/getting-started/add-consumer.md similarity index 100% rename from app/enterprise/0.35-x/getting-started/add-consumer.md rename to archive/enterprise/0.35-x/getting-started/add-consumer.md diff --git a/app/enterprise/0.35-x/getting-started/add-role.md b/archive/enterprise/0.35-x/getting-started/add-role.md similarity index 100% rename from app/enterprise/0.35-x/getting-started/add-role.md rename to archive/enterprise/0.35-x/getting-started/add-role.md diff --git a/app/enterprise/0.35-x/getting-started/add-service.md b/archive/enterprise/0.35-x/getting-started/add-service.md similarity index 100% rename from app/enterprise/0.35-x/getting-started/add-service.md rename to archive/enterprise/0.35-x/getting-started/add-service.md diff --git a/app/enterprise/0.35-x/getting-started/add-workspace.md b/archive/enterprise/0.35-x/getting-started/add-workspace.md similarity index 100% rename from app/enterprise/0.35-x/getting-started/add-workspace.md rename to archive/enterprise/0.35-x/getting-started/add-workspace.md diff --git a/app/enterprise/0.35-x/getting-started/enable-dev-portal.md b/archive/enterprise/0.35-x/getting-started/enable-dev-portal.md similarity index 100% rename from app/enterprise/0.35-x/getting-started/enable-dev-portal.md rename to archive/enterprise/0.35-x/getting-started/enable-dev-portal.md diff --git a/app/enterprise/0.35-x/getting-started/enable-plugin.md b/archive/enterprise/0.35-x/getting-started/enable-plugin.md similarity index 100% rename from app/enterprise/0.35-x/getting-started/enable-plugin.md rename to archive/enterprise/0.35-x/getting-started/enable-plugin.md diff --git a/app/enterprise/0.35-x/getting-started/index.md b/archive/enterprise/0.35-x/getting-started/index.md similarity index 100% rename from app/enterprise/0.35-x/getting-started/index.md rename to archive/enterprise/0.35-x/getting-started/index.md diff --git a/app/enterprise/0.35-x/getting-started/start-kong.md b/archive/enterprise/0.35-x/getting-started/start-kong.md similarity index 100% rename from app/enterprise/0.35-x/getting-started/start-kong.md rename to archive/enterprise/0.35-x/getting-started/start-kong.md diff --git a/app/enterprise/0.35-x/health-checks-circuit-breakers.md b/archive/enterprise/0.35-x/health-checks-circuit-breakers.md similarity index 100% rename from app/enterprise/0.35-x/health-checks-circuit-breakers.md rename to archive/enterprise/0.35-x/health-checks-circuit-breakers.md diff --git a/app/enterprise/0.35-x/index.md b/archive/enterprise/0.35-x/index.md similarity index 100% rename from app/enterprise/0.35-x/index.md rename to archive/enterprise/0.35-x/index.md diff --git a/app/enterprise/0.35-x/kong-manager/administration/admins/admins.md b/archive/enterprise/0.35-x/kong-manager/administration/admins/admins.md similarity index 100% rename from app/enterprise/0.35-x/kong-manager/administration/admins/admins.md rename to archive/enterprise/0.35-x/kong-manager/administration/admins/admins.md diff --git a/app/enterprise/0.35-x/kong-manager/administration/admins/invite.md b/archive/enterprise/0.35-x/kong-manager/administration/admins/invite.md similarity index 100% rename from app/enterprise/0.35-x/kong-manager/administration/admins/invite.md rename to archive/enterprise/0.35-x/kong-manager/administration/admins/invite.md diff --git a/app/enterprise/0.35-x/kong-manager/administration/rbac/new-role.md b/archive/enterprise/0.35-x/kong-manager/administration/rbac/new-role.md similarity index 100% rename from app/enterprise/0.35-x/kong-manager/administration/rbac/new-role.md rename to archive/enterprise/0.35-x/kong-manager/administration/rbac/new-role.md diff --git a/app/enterprise/0.35-x/kong-manager/administration/rbac/rbac.md b/archive/enterprise/0.35-x/kong-manager/administration/rbac/rbac.md similarity index 100% rename from app/enterprise/0.35-x/kong-manager/administration/rbac/rbac.md rename to archive/enterprise/0.35-x/kong-manager/administration/rbac/rbac.md diff --git a/app/enterprise/0.35-x/kong-manager/administration/workspaces/create-workspace.md b/archive/enterprise/0.35-x/kong-manager/administration/workspaces/create-workspace.md similarity index 100% rename from app/enterprise/0.35-x/kong-manager/administration/workspaces/create-workspace.md rename to archive/enterprise/0.35-x/kong-manager/administration/workspaces/create-workspace.md diff --git a/app/enterprise/0.35-x/kong-manager/administration/workspaces/update-workspace.md b/archive/enterprise/0.35-x/kong-manager/administration/workspaces/update-workspace.md similarity index 100% rename from app/enterprise/0.35-x/kong-manager/administration/workspaces/update-workspace.md rename to archive/enterprise/0.35-x/kong-manager/administration/workspaces/update-workspace.md diff --git a/app/enterprise/0.35-x/kong-manager/administration/workspaces/workspaces.md b/archive/enterprise/0.35-x/kong-manager/administration/workspaces/workspaces.md similarity index 100% rename from app/enterprise/0.35-x/kong-manager/administration/workspaces/workspaces.md rename to archive/enterprise/0.35-x/kong-manager/administration/workspaces/workspaces.md diff --git a/app/enterprise/0.35-x/kong-manager/authentication/basic.md b/archive/enterprise/0.35-x/kong-manager/authentication/basic.md similarity index 100% rename from app/enterprise/0.35-x/kong-manager/authentication/basic.md rename to archive/enterprise/0.35-x/kong-manager/authentication/basic.md diff --git a/app/enterprise/0.35-x/kong-manager/authentication/ldap.md b/archive/enterprise/0.35-x/kong-manager/authentication/ldap.md similarity index 100% rename from app/enterprise/0.35-x/kong-manager/authentication/ldap.md rename to archive/enterprise/0.35-x/kong-manager/authentication/ldap.md diff --git a/app/enterprise/0.35-x/kong-manager/authentication/oidc.md b/archive/enterprise/0.35-x/kong-manager/authentication/oidc.md similarity index 100% rename from app/enterprise/0.35-x/kong-manager/authentication/oidc.md rename to archive/enterprise/0.35-x/kong-manager/authentication/oidc.md diff --git a/app/enterprise/0.35-x/kong-manager/authentication/sessions.md b/archive/enterprise/0.35-x/kong-manager/authentication/sessions.md similarity index 100% rename from app/enterprise/0.35-x/kong-manager/authentication/sessions.md rename to archive/enterprise/0.35-x/kong-manager/authentication/sessions.md diff --git a/app/enterprise/0.35-x/kong-manager/authentication/super-admin.md b/archive/enterprise/0.35-x/kong-manager/authentication/super-admin.md similarity index 100% rename from app/enterprise/0.35-x/kong-manager/authentication/super-admin.md rename to archive/enterprise/0.35-x/kong-manager/authentication/super-admin.md diff --git a/app/enterprise/0.35-x/kong-manager/best-practices.md b/archive/enterprise/0.35-x/kong-manager/best-practices.md similarity index 100% rename from app/enterprise/0.35-x/kong-manager/best-practices.md rename to archive/enterprise/0.35-x/kong-manager/best-practices.md diff --git a/app/enterprise/0.35-x/kong-manager/faq.md b/archive/enterprise/0.35-x/kong-manager/faq.md similarity index 100% rename from app/enterprise/0.35-x/kong-manager/faq.md rename to archive/enterprise/0.35-x/kong-manager/faq.md diff --git a/app/enterprise/0.35-x/kong-manager/networking/configuration.md b/archive/enterprise/0.35-x/kong-manager/networking/configuration.md similarity index 100% rename from app/enterprise/0.35-x/kong-manager/networking/configuration.md rename to archive/enterprise/0.35-x/kong-manager/networking/configuration.md diff --git a/app/enterprise/0.35-x/kong-manager/networking/email.md b/archive/enterprise/0.35-x/kong-manager/networking/email.md similarity index 100% rename from app/enterprise/0.35-x/kong-manager/networking/email.md rename to archive/enterprise/0.35-x/kong-manager/networking/email.md diff --git a/app/enterprise/0.35-x/kong-manager/overview.md b/archive/enterprise/0.35-x/kong-manager/overview.md similarity index 100% rename from app/enterprise/0.35-x/kong-manager/overview.md rename to archive/enterprise/0.35-x/kong-manager/overview.md diff --git a/app/enterprise/0.35-x/kong-manager/reset-password.md b/archive/enterprise/0.35-x/kong-manager/reset-password.md similarity index 100% rename from app/enterprise/0.35-x/kong-manager/reset-password.md rename to archive/enterprise/0.35-x/kong-manager/reset-password.md diff --git a/app/enterprise/0.35-x/kong-manager/security.md b/archive/enterprise/0.35-x/kong-manager/security.md similarity index 100% rename from app/enterprise/0.35-x/kong-manager/security.md rename to archive/enterprise/0.35-x/kong-manager/security.md diff --git a/app/enterprise/0.35-x/kong-manager/vitals.md b/archive/enterprise/0.35-x/kong-manager/vitals.md similarity index 100% rename from app/enterprise/0.35-x/kong-manager/vitals.md rename to archive/enterprise/0.35-x/kong-manager/vitals.md diff --git a/app/enterprise/0.35-x/loadbalancing.md b/archive/enterprise/0.35-x/loadbalancing.md similarity index 100% rename from app/enterprise/0.35-x/loadbalancing.md rename to archive/enterprise/0.35-x/loadbalancing.md diff --git a/app/enterprise/0.35-x/logging.md b/archive/enterprise/0.35-x/logging.md similarity index 100% rename from app/enterprise/0.35-x/logging.md rename to archive/enterprise/0.35-x/logging.md diff --git a/app/enterprise/0.35-x/network.md b/archive/enterprise/0.35-x/network.md similarity index 100% rename from app/enterprise/0.35-x/network.md rename to archive/enterprise/0.35-x/network.md diff --git a/app/enterprise/0.35-x/pdk/index.md b/archive/enterprise/0.35-x/pdk/index.md similarity index 100% rename from app/enterprise/0.35-x/pdk/index.md rename to archive/enterprise/0.35-x/pdk/index.md diff --git a/app/enterprise/0.35-x/pdk/kong.client.md b/archive/enterprise/0.35-x/pdk/kong.client.md similarity index 100% rename from app/enterprise/0.35-x/pdk/kong.client.md rename to archive/enterprise/0.35-x/pdk/kong.client.md diff --git a/app/enterprise/0.35-x/pdk/kong.ctx.md b/archive/enterprise/0.35-x/pdk/kong.ctx.md similarity index 100% rename from app/enterprise/0.35-x/pdk/kong.ctx.md rename to archive/enterprise/0.35-x/pdk/kong.ctx.md diff --git a/app/enterprise/0.35-x/pdk/kong.ip.md b/archive/enterprise/0.35-x/pdk/kong.ip.md similarity index 100% rename from app/enterprise/0.35-x/pdk/kong.ip.md rename to archive/enterprise/0.35-x/pdk/kong.ip.md diff --git a/app/enterprise/0.35-x/pdk/kong.log.md b/archive/enterprise/0.35-x/pdk/kong.log.md similarity index 100% rename from app/enterprise/0.35-x/pdk/kong.log.md rename to archive/enterprise/0.35-x/pdk/kong.log.md diff --git a/app/enterprise/0.35-x/pdk/kong.node.md b/archive/enterprise/0.35-x/pdk/kong.node.md similarity index 100% rename from app/enterprise/0.35-x/pdk/kong.node.md rename to archive/enterprise/0.35-x/pdk/kong.node.md diff --git a/app/enterprise/0.35-x/pdk/kong.request.md b/archive/enterprise/0.35-x/pdk/kong.request.md similarity index 100% rename from app/enterprise/0.35-x/pdk/kong.request.md rename to archive/enterprise/0.35-x/pdk/kong.request.md diff --git a/app/enterprise/0.35-x/pdk/kong.response.md b/archive/enterprise/0.35-x/pdk/kong.response.md similarity index 100% rename from app/enterprise/0.35-x/pdk/kong.response.md rename to archive/enterprise/0.35-x/pdk/kong.response.md diff --git a/app/enterprise/0.35-x/pdk/kong.router.md b/archive/enterprise/0.35-x/pdk/kong.router.md similarity index 100% rename from app/enterprise/0.35-x/pdk/kong.router.md rename to archive/enterprise/0.35-x/pdk/kong.router.md diff --git a/app/enterprise/0.35-x/pdk/kong.service.md b/archive/enterprise/0.35-x/pdk/kong.service.md similarity index 100% rename from app/enterprise/0.35-x/pdk/kong.service.md rename to archive/enterprise/0.35-x/pdk/kong.service.md diff --git a/app/enterprise/0.35-x/pdk/kong.service.request.md b/archive/enterprise/0.35-x/pdk/kong.service.request.md similarity index 100% rename from app/enterprise/0.35-x/pdk/kong.service.request.md rename to archive/enterprise/0.35-x/pdk/kong.service.request.md diff --git a/app/enterprise/0.35-x/pdk/kong.service.response.md b/archive/enterprise/0.35-x/pdk/kong.service.response.md similarity index 100% rename from app/enterprise/0.35-x/pdk/kong.service.response.md rename to archive/enterprise/0.35-x/pdk/kong.service.response.md diff --git a/app/enterprise/0.35-x/pdk/kong.table.md b/archive/enterprise/0.35-x/pdk/kong.table.md similarity index 100% rename from app/enterprise/0.35-x/pdk/kong.table.md rename to archive/enterprise/0.35-x/pdk/kong.table.md diff --git a/app/enterprise/0.35-x/plugin-development/access-the-datastore.md b/archive/enterprise/0.35-x/plugin-development/access-the-datastore.md similarity index 100% rename from app/enterprise/0.35-x/plugin-development/access-the-datastore.md rename to archive/enterprise/0.35-x/plugin-development/access-the-datastore.md diff --git a/app/enterprise/0.35-x/plugin-development/admin-api.md b/archive/enterprise/0.35-x/plugin-development/admin-api.md similarity index 100% rename from app/enterprise/0.35-x/plugin-development/admin-api.md rename to archive/enterprise/0.35-x/plugin-development/admin-api.md diff --git a/app/enterprise/0.35-x/plugin-development/custom-entities.md b/archive/enterprise/0.35-x/plugin-development/custom-entities.md similarity index 100% rename from app/enterprise/0.35-x/plugin-development/custom-entities.md rename to archive/enterprise/0.35-x/plugin-development/custom-entities.md diff --git a/app/enterprise/0.35-x/plugin-development/custom-logic.md b/archive/enterprise/0.35-x/plugin-development/custom-logic.md similarity index 100% rename from app/enterprise/0.35-x/plugin-development/custom-logic.md rename to archive/enterprise/0.35-x/plugin-development/custom-logic.md diff --git a/app/enterprise/0.35-x/plugin-development/distribution.md b/archive/enterprise/0.35-x/plugin-development/distribution.md similarity index 100% rename from app/enterprise/0.35-x/plugin-development/distribution.md rename to archive/enterprise/0.35-x/plugin-development/distribution.md diff --git a/app/enterprise/0.35-x/plugin-development/entities-cache.md b/archive/enterprise/0.35-x/plugin-development/entities-cache.md similarity index 100% rename from app/enterprise/0.35-x/plugin-development/entities-cache.md rename to archive/enterprise/0.35-x/plugin-development/entities-cache.md diff --git a/app/enterprise/0.35-x/plugin-development/file-structure.md b/archive/enterprise/0.35-x/plugin-development/file-structure.md similarity index 100% rename from app/enterprise/0.35-x/plugin-development/file-structure.md rename to archive/enterprise/0.35-x/plugin-development/file-structure.md diff --git a/app/enterprise/0.35-x/plugin-development/index.md b/archive/enterprise/0.35-x/plugin-development/index.md similarity index 100% rename from app/enterprise/0.35-x/plugin-development/index.md rename to archive/enterprise/0.35-x/plugin-development/index.md diff --git a/app/enterprise/0.35-x/plugin-development/plugin-configuration.md b/archive/enterprise/0.35-x/plugin-development/plugin-configuration.md similarity index 100% rename from app/enterprise/0.35-x/plugin-development/plugin-configuration.md rename to archive/enterprise/0.35-x/plugin-development/plugin-configuration.md diff --git a/app/enterprise/0.35-x/plugin-development/tests.md b/archive/enterprise/0.35-x/plugin-development/tests.md similarity index 100% rename from app/enterprise/0.35-x/plugin-development/tests.md rename to archive/enterprise/0.35-x/plugin-development/tests.md diff --git a/app/enterprise/0.35-x/plugins/allowing-multiple-authentication-methods.md b/archive/enterprise/0.35-x/plugins/allowing-multiple-authentication-methods.md similarity index 100% rename from app/enterprise/0.35-x/plugins/allowing-multiple-authentication-methods.md rename to archive/enterprise/0.35-x/plugins/allowing-multiple-authentication-methods.md diff --git a/app/enterprise/0.35-x/plugins/canary-release.md b/archive/enterprise/0.35-x/plugins/canary-release.md similarity index 100% rename from app/enterprise/0.35-x/plugins/canary-release.md rename to archive/enterprise/0.35-x/plugins/canary-release.md diff --git a/app/enterprise/0.35-x/plugins/forward-proxy.md b/archive/enterprise/0.35-x/plugins/forward-proxy.md similarity index 100% rename from app/enterprise/0.35-x/plugins/forward-proxy.md rename to archive/enterprise/0.35-x/plugins/forward-proxy.md diff --git a/app/enterprise/0.35-x/plugins/http-proxy-caching.md b/archive/enterprise/0.35-x/plugins/http-proxy-caching.md similarity index 100% rename from app/enterprise/0.35-x/plugins/http-proxy-caching.md rename to archive/enterprise/0.35-x/plugins/http-proxy-caching.md diff --git a/app/enterprise/0.35-x/plugins/index.md b/archive/enterprise/0.35-x/plugins/index.md similarity index 100% rename from app/enterprise/0.35-x/plugins/index.md rename to archive/enterprise/0.35-x/plugins/index.md diff --git a/app/enterprise/0.35-x/plugins/jwt-signer.md b/archive/enterprise/0.35-x/plugins/jwt-signer.md similarity index 100% rename from app/enterprise/0.35-x/plugins/jwt-signer.md rename to archive/enterprise/0.35-x/plugins/jwt-signer.md diff --git a/app/enterprise/0.35-x/plugins/ldap-authentication-advanced.md b/archive/enterprise/0.35-x/plugins/ldap-authentication-advanced.md similarity index 100% rename from app/enterprise/0.35-x/plugins/ldap-authentication-advanced.md rename to archive/enterprise/0.35-x/plugins/ldap-authentication-advanced.md diff --git a/app/enterprise/0.35-x/plugins/oauth2-introspection.md b/archive/enterprise/0.35-x/plugins/oauth2-introspection.md similarity index 100% rename from app/enterprise/0.35-x/plugins/oauth2-introspection.md rename to archive/enterprise/0.35-x/plugins/oauth2-introspection.md diff --git a/app/enterprise/0.35-x/plugins/oidc-auth0.md b/archive/enterprise/0.35-x/plugins/oidc-auth0.md similarity index 100% rename from app/enterprise/0.35-x/plugins/oidc-auth0.md rename to archive/enterprise/0.35-x/plugins/oidc-auth0.md diff --git a/app/enterprise/0.35-x/plugins/oidc-azuread.md b/archive/enterprise/0.35-x/plugins/oidc-azuread.md similarity index 100% rename from app/enterprise/0.35-x/plugins/oidc-azuread.md rename to archive/enterprise/0.35-x/plugins/oidc-azuread.md diff --git a/app/enterprise/0.35-x/plugins/oidc-google.md b/archive/enterprise/0.35-x/plugins/oidc-google.md similarity index 100% rename from app/enterprise/0.35-x/plugins/oidc-google.md rename to archive/enterprise/0.35-x/plugins/oidc-google.md diff --git a/app/enterprise/0.35-x/plugins/oidc-okta.md b/archive/enterprise/0.35-x/plugins/oidc-okta.md similarity index 100% rename from app/enterprise/0.35-x/plugins/oidc-okta.md rename to archive/enterprise/0.35-x/plugins/oidc-okta.md diff --git a/app/enterprise/0.35-x/plugins/openid-connect.md b/archive/enterprise/0.35-x/plugins/openid-connect.md similarity index 100% rename from app/enterprise/0.35-x/plugins/openid-connect.md rename to archive/enterprise/0.35-x/plugins/openid-connect.md diff --git a/app/enterprise/0.35-x/plugins/rate-limiting-advanced.md b/archive/enterprise/0.35-x/plugins/rate-limiting-advanced.md similarity index 100% rename from app/enterprise/0.35-x/plugins/rate-limiting-advanced.md rename to archive/enterprise/0.35-x/plugins/rate-limiting-advanced.md diff --git a/app/enterprise/0.35-x/plugins/request-transformer.md b/archive/enterprise/0.35-x/plugins/request-transformer.md similarity index 100% rename from app/enterprise/0.35-x/plugins/request-transformer.md rename to archive/enterprise/0.35-x/plugins/request-transformer.md diff --git a/app/enterprise/0.35-x/plugins/request-validator.md b/archive/enterprise/0.35-x/plugins/request-validator.md similarity index 100% rename from app/enterprise/0.35-x/plugins/request-validator.md rename to archive/enterprise/0.35-x/plugins/request-validator.md diff --git a/app/enterprise/0.35-x/plugins/route-by-header.md b/archive/enterprise/0.35-x/plugins/route-by-header.md similarity index 100% rename from app/enterprise/0.35-x/plugins/route-by-header.md rename to archive/enterprise/0.35-x/plugins/route-by-header.md diff --git a/app/enterprise/0.35-x/plugins/route-by-headers.md b/archive/enterprise/0.35-x/plugins/route-by-headers.md similarity index 100% rename from app/enterprise/0.35-x/plugins/route-by-headers.md rename to archive/enterprise/0.35-x/plugins/route-by-headers.md diff --git a/app/enterprise/0.35-x/plugins/session.md b/archive/enterprise/0.35-x/plugins/session.md similarity index 100% rename from app/enterprise/0.35-x/plugins/session.md rename to archive/enterprise/0.35-x/plugins/session.md diff --git a/app/enterprise/0.35-x/plugins/statsd-advanced.md b/archive/enterprise/0.35-x/plugins/statsd-advanced.md similarity index 100% rename from app/enterprise/0.35-x/plugins/statsd-advanced.md rename to archive/enterprise/0.35-x/plugins/statsd-advanced.md diff --git a/app/enterprise/0.35-x/plugins/statsd.rules.yaml b/archive/enterprise/0.35-x/plugins/statsd.rules.yaml similarity index 100% rename from app/enterprise/0.35-x/plugins/statsd.rules.yaml rename to archive/enterprise/0.35-x/plugins/statsd.rules.yaml diff --git a/app/enterprise/0.35-x/plugins/upstream-tls.md b/archive/enterprise/0.35-x/plugins/upstream-tls.md similarity index 100% rename from app/enterprise/0.35-x/plugins/upstream-tls.md rename to archive/enterprise/0.35-x/plugins/upstream-tls.md diff --git a/app/enterprise/0.35-x/plugins/vault-auth.md b/archive/enterprise/0.35-x/plugins/vault-auth.md similarity index 100% rename from app/enterprise/0.35-x/plugins/vault-auth.md rename to archive/enterprise/0.35-x/plugins/vault-auth.md diff --git a/app/enterprise/0.35-x/property-reference.md b/archive/enterprise/0.35-x/property-reference.md similarity index 100% rename from app/enterprise/0.35-x/property-reference.md rename to archive/enterprise/0.35-x/property-reference.md diff --git a/app/enterprise/0.35-x/proxy.md b/archive/enterprise/0.35-x/proxy.md similarity index 100% rename from app/enterprise/0.35-x/proxy.md rename to archive/enterprise/0.35-x/proxy.md diff --git a/app/enterprise/0.35-x/secure-admin-api.md b/archive/enterprise/0.35-x/secure-admin-api.md similarity index 100% rename from app/enterprise/0.35-x/secure-admin-api.md rename to archive/enterprise/0.35-x/secure-admin-api.md diff --git a/app/enterprise/0.36-x/admin-api/admins/examples.md b/archive/enterprise/0.36-x/admin-api/admins/examples.md similarity index 100% rename from app/enterprise/0.36-x/admin-api/admins/examples.md rename to archive/enterprise/0.36-x/admin-api/admins/examples.md diff --git a/app/enterprise/0.36-x/admin-api/admins/reference.md b/archive/enterprise/0.36-x/admin-api/admins/reference.md similarity index 100% rename from app/enterprise/0.36-x/admin-api/admins/reference.md rename to archive/enterprise/0.36-x/admin-api/admins/reference.md diff --git a/app/enterprise/0.36-x/admin-api/audit-log.md b/archive/enterprise/0.36-x/admin-api/audit-log.md similarity index 100% rename from app/enterprise/0.36-x/admin-api/audit-log.md rename to archive/enterprise/0.36-x/admin-api/audit-log.md diff --git a/app/enterprise/0.36-x/admin-api/index.md b/archive/enterprise/0.36-x/admin-api/index.md similarity index 100% rename from app/enterprise/0.36-x/admin-api/index.md rename to archive/enterprise/0.36-x/admin-api/index.md diff --git a/app/enterprise/0.36-x/admin-api/rbac/examples.md b/archive/enterprise/0.36-x/admin-api/rbac/examples.md similarity index 100% rename from app/enterprise/0.36-x/admin-api/rbac/examples.md rename to archive/enterprise/0.36-x/admin-api/rbac/examples.md diff --git a/app/enterprise/0.36-x/admin-api/rbac/reference.md b/archive/enterprise/0.36-x/admin-api/rbac/reference.md similarity index 100% rename from app/enterprise/0.36-x/admin-api/rbac/reference.md rename to archive/enterprise/0.36-x/admin-api/rbac/reference.md diff --git a/app/enterprise/0.36-x/admin-api/vitals/index.md b/archive/enterprise/0.36-x/admin-api/vitals/index.md similarity index 100% rename from app/enterprise/0.36-x/admin-api/vitals/index.md rename to archive/enterprise/0.36-x/admin-api/vitals/index.md diff --git a/app/enterprise/0.36-x/admin-api/vitals/vitals-influx-strategy.md b/archive/enterprise/0.36-x/admin-api/vitals/vitals-influx-strategy.md similarity index 100% rename from app/enterprise/0.36-x/admin-api/vitals/vitals-influx-strategy.md rename to archive/enterprise/0.36-x/admin-api/vitals/vitals-influx-strategy.md diff --git a/app/enterprise/0.36-x/admin-api/vitals/vitals-prometheus-strategy.md b/archive/enterprise/0.36-x/admin-api/vitals/vitals-prometheus-strategy.md similarity index 100% rename from app/enterprise/0.36-x/admin-api/vitals/vitals-prometheus-strategy.md rename to archive/enterprise/0.36-x/admin-api/vitals/vitals-prometheus-strategy.md diff --git a/app/enterprise/0.36-x/admin-api/vitals/vitalsSpec.yaml b/archive/enterprise/0.36-x/admin-api/vitals/vitalsSpec.yaml similarity index 100% rename from app/enterprise/0.36-x/admin-api/vitals/vitalsSpec.yaml rename to archive/enterprise/0.36-x/admin-api/vitals/vitalsSpec.yaml diff --git a/app/enterprise/0.36-x/admin-api/workspaces/examples.md b/archive/enterprise/0.36-x/admin-api/workspaces/examples.md similarity index 100% rename from app/enterprise/0.36-x/admin-api/workspaces/examples.md rename to archive/enterprise/0.36-x/admin-api/workspaces/examples.md diff --git a/app/enterprise/0.36-x/admin-api/workspaces/reference.md b/archive/enterprise/0.36-x/admin-api/workspaces/reference.md similarity index 100% rename from app/enterprise/0.36-x/admin-api/workspaces/reference.md rename to archive/enterprise/0.36-x/admin-api/workspaces/reference.md diff --git a/app/enterprise/0.36-x/auth.md b/archive/enterprise/0.36-x/auth.md similarity index 100% rename from app/enterprise/0.36-x/auth.md rename to archive/enterprise/0.36-x/auth.md diff --git a/app/enterprise/0.36-x/cli.md b/archive/enterprise/0.36-x/cli.md similarity index 100% rename from app/enterprise/0.36-x/cli.md rename to archive/enterprise/0.36-x/cli.md diff --git a/app/enterprise/0.36-x/clustering.md b/archive/enterprise/0.36-x/clustering.md similarity index 100% rename from app/enterprise/0.36-x/clustering.md rename to archive/enterprise/0.36-x/clustering.md diff --git a/app/enterprise/0.36-x/deployment/access-license.md b/archive/enterprise/0.36-x/deployment/access-license.md similarity index 100% rename from app/enterprise/0.36-x/deployment/access-license.md rename to archive/enterprise/0.36-x/deployment/access-license.md diff --git a/app/enterprise/0.36-x/deployment/installation/amazon-linux.md b/archive/enterprise/0.36-x/deployment/installation/amazon-linux.md similarity index 100% rename from app/enterprise/0.36-x/deployment/installation/amazon-linux.md rename to archive/enterprise/0.36-x/deployment/installation/amazon-linux.md diff --git a/app/enterprise/0.36-x/deployment/installation/centos.md b/archive/enterprise/0.36-x/deployment/installation/centos.md similarity index 100% rename from app/enterprise/0.36-x/deployment/installation/centos.md rename to archive/enterprise/0.36-x/deployment/installation/centos.md diff --git a/app/enterprise/0.36-x/deployment/installation/docker.md b/archive/enterprise/0.36-x/deployment/installation/docker.md similarity index 100% rename from app/enterprise/0.36-x/deployment/installation/docker.md rename to archive/enterprise/0.36-x/deployment/installation/docker.md diff --git a/app/enterprise/0.36-x/deployment/installation/free-trial.md b/archive/enterprise/0.36-x/deployment/installation/free-trial.md similarity index 100% rename from app/enterprise/0.36-x/deployment/installation/free-trial.md rename to archive/enterprise/0.36-x/deployment/installation/free-trial.md diff --git a/app/enterprise/0.36-x/deployment/installation/overview.md b/archive/enterprise/0.36-x/deployment/installation/overview.md similarity index 100% rename from app/enterprise/0.36-x/deployment/installation/overview.md rename to archive/enterprise/0.36-x/deployment/installation/overview.md diff --git a/app/enterprise/0.36-x/deployment/installation/ubuntu.md b/archive/enterprise/0.36-x/deployment/installation/ubuntu.md similarity index 100% rename from app/enterprise/0.36-x/deployment/installation/ubuntu.md rename to archive/enterprise/0.36-x/deployment/installation/ubuntu.md diff --git a/app/enterprise/0.36-x/deployment/licensing.md b/archive/enterprise/0.36-x/deployment/licensing.md similarity index 100% rename from app/enterprise/0.36-x/deployment/licensing.md rename to archive/enterprise/0.36-x/deployment/licensing.md diff --git a/app/enterprise/0.36-x/deployment/migrations.md b/archive/enterprise/0.36-x/deployment/migrations.md similarity index 100% rename from app/enterprise/0.36-x/deployment/migrations.md rename to archive/enterprise/0.36-x/deployment/migrations.md diff --git a/app/enterprise/0.36-x/developer-portal/administration/developer-access.md b/archive/enterprise/0.36-x/developer-portal/administration/developer-access.md similarity index 100% rename from app/enterprise/0.36-x/developer-portal/administration/developer-access.md rename to archive/enterprise/0.36-x/developer-portal/administration/developer-access.md diff --git a/app/enterprise/0.36-x/developer-portal/administration/managing-developers.md b/archive/enterprise/0.36-x/developer-portal/administration/managing-developers.md similarity index 100% rename from app/enterprise/0.36-x/developer-portal/administration/managing-developers.md rename to archive/enterprise/0.36-x/developer-portal/administration/managing-developers.md diff --git a/app/enterprise/0.36-x/developer-portal/best-practices.md b/archive/enterprise/0.36-x/developer-portal/best-practices.md similarity index 100% rename from app/enterprise/0.36-x/developer-portal/best-practices.md rename to archive/enterprise/0.36-x/developer-portal/best-practices.md diff --git a/app/enterprise/0.36-x/developer-portal/configuration/authentication/adding-registration-fields.md b/archive/enterprise/0.36-x/developer-portal/configuration/authentication/adding-registration-fields.md similarity index 100% rename from app/enterprise/0.36-x/developer-portal/configuration/authentication/adding-registration-fields.md rename to archive/enterprise/0.36-x/developer-portal/configuration/authentication/adding-registration-fields.md diff --git a/app/enterprise/0.36-x/developer-portal/configuration/authentication/basic-auth.md b/archive/enterprise/0.36-x/developer-portal/configuration/authentication/basic-auth.md similarity index 100% rename from app/enterprise/0.36-x/developer-portal/configuration/authentication/basic-auth.md rename to archive/enterprise/0.36-x/developer-portal/configuration/authentication/basic-auth.md diff --git a/app/enterprise/0.36-x/developer-portal/configuration/authentication/disabling-auth.md b/archive/enterprise/0.36-x/developer-portal/configuration/authentication/disabling-auth.md similarity index 100% rename from app/enterprise/0.36-x/developer-portal/configuration/authentication/disabling-auth.md rename to archive/enterprise/0.36-x/developer-portal/configuration/authentication/disabling-auth.md diff --git a/app/enterprise/0.36-x/developer-portal/configuration/authentication/index.md b/archive/enterprise/0.36-x/developer-portal/configuration/authentication/index.md similarity index 100% rename from app/enterprise/0.36-x/developer-portal/configuration/authentication/index.md rename to archive/enterprise/0.36-x/developer-portal/configuration/authentication/index.md diff --git a/app/enterprise/0.36-x/developer-portal/configuration/authentication/key-auth.md b/archive/enterprise/0.36-x/developer-portal/configuration/authentication/key-auth.md similarity index 100% rename from app/enterprise/0.36-x/developer-portal/configuration/authentication/key-auth.md rename to archive/enterprise/0.36-x/developer-portal/configuration/authentication/key-auth.md diff --git a/app/enterprise/0.36-x/developer-portal/configuration/authentication/oidc.md b/archive/enterprise/0.36-x/developer-portal/configuration/authentication/oidc.md similarity index 100% rename from app/enterprise/0.36-x/developer-portal/configuration/authentication/oidc.md rename to archive/enterprise/0.36-x/developer-portal/configuration/authentication/oidc.md diff --git a/app/enterprise/0.36-x/developer-portal/configuration/authentication/sessions.md b/archive/enterprise/0.36-x/developer-portal/configuration/authentication/sessions.md similarity index 100% rename from app/enterprise/0.36-x/developer-portal/configuration/authentication/sessions.md rename to archive/enterprise/0.36-x/developer-portal/configuration/authentication/sessions.md diff --git a/app/enterprise/0.36-x/developer-portal/configuration/authentication/understanding-page-routing.md b/archive/enterprise/0.36-x/developer-portal/configuration/authentication/understanding-page-routing.md similarity index 100% rename from app/enterprise/0.36-x/developer-portal/configuration/authentication/understanding-page-routing.md rename to archive/enterprise/0.36-x/developer-portal/configuration/authentication/understanding-page-routing.md diff --git a/app/enterprise/0.36-x/developer-portal/configuration/index.md b/archive/enterprise/0.36-x/developer-portal/configuration/index.md similarity index 100% rename from app/enterprise/0.36-x/developer-portal/configuration/index.md rename to archive/enterprise/0.36-x/developer-portal/configuration/index.md diff --git a/app/enterprise/0.36-x/developer-portal/configuration/smtp.md b/archive/enterprise/0.36-x/developer-portal/configuration/smtp.md similarity index 100% rename from app/enterprise/0.36-x/developer-portal/configuration/smtp.md rename to archive/enterprise/0.36-x/developer-portal/configuration/smtp.md diff --git a/app/enterprise/0.36-x/developer-portal/configuration/workspaces.md b/archive/enterprise/0.36-x/developer-portal/configuration/workspaces.md similarity index 100% rename from app/enterprise/0.36-x/developer-portal/configuration/workspaces.md rename to archive/enterprise/0.36-x/developer-portal/configuration/workspaces.md diff --git a/app/enterprise/0.36-x/developer-portal/content-management/file-management.md b/archive/enterprise/0.36-x/developer-portal/content-management/file-management.md similarity index 100% rename from app/enterprise/0.36-x/developer-portal/content-management/file-management.md rename to archive/enterprise/0.36-x/developer-portal/content-management/file-management.md diff --git a/app/enterprise/0.36-x/developer-portal/content-management/index.md b/archive/enterprise/0.36-x/developer-portal/content-management/index.md similarity index 100% rename from app/enterprise/0.36-x/developer-portal/content-management/index.md rename to archive/enterprise/0.36-x/developer-portal/content-management/index.md diff --git a/app/enterprise/0.36-x/developer-portal/content-management/serving-assets/aws-cloudfront.md b/archive/enterprise/0.36-x/developer-portal/content-management/serving-assets/aws-cloudfront.md similarity index 100% rename from app/enterprise/0.36-x/developer-portal/content-management/serving-assets/aws-cloudfront.md rename to archive/enterprise/0.36-x/developer-portal/content-management/serving-assets/aws-cloudfront.md diff --git a/app/enterprise/0.36-x/developer-portal/content-management/serving-assets/google-cloud.md b/archive/enterprise/0.36-x/developer-portal/content-management/serving-assets/google-cloud.md similarity index 100% rename from app/enterprise/0.36-x/developer-portal/content-management/serving-assets/google-cloud.md rename to archive/enterprise/0.36-x/developer-portal/content-management/serving-assets/google-cloud.md diff --git a/app/enterprise/0.36-x/developer-portal/content-management/serving-assets/index.md b/archive/enterprise/0.36-x/developer-portal/content-management/serving-assets/index.md similarity index 100% rename from app/enterprise/0.36-x/developer-portal/content-management/serving-assets/index.md rename to archive/enterprise/0.36-x/developer-portal/content-management/serving-assets/index.md diff --git a/app/enterprise/0.36-x/developer-portal/faq.md b/archive/enterprise/0.36-x/developer-portal/faq.md similarity index 100% rename from app/enterprise/0.36-x/developer-portal/faq.md rename to archive/enterprise/0.36-x/developer-portal/faq.md diff --git a/app/enterprise/0.36-x/developer-portal/introduction.md b/archive/enterprise/0.36-x/developer-portal/introduction.md similarity index 100% rename from app/enterprise/0.36-x/developer-portal/introduction.md rename to archive/enterprise/0.36-x/developer-portal/introduction.md diff --git a/app/enterprise/0.36-x/developer-portal/networking.md b/archive/enterprise/0.36-x/developer-portal/networking.md similarity index 100% rename from app/enterprise/0.36-x/developer-portal/networking.md rename to archive/enterprise/0.36-x/developer-portal/networking.md diff --git a/app/enterprise/0.36-x/developer-portal/quickstart.md b/archive/enterprise/0.36-x/developer-portal/quickstart.md similarity index 100% rename from app/enterprise/0.36-x/developer-portal/quickstart.md rename to archive/enterprise/0.36-x/developer-portal/quickstart.md diff --git a/app/enterprise/0.36-x/developer-portal/theme-customization/customizing-dev-portal.md b/archive/enterprise/0.36-x/developer-portal/theme-customization/customizing-dev-portal.md similarity index 100% rename from app/enterprise/0.36-x/developer-portal/theme-customization/customizing-dev-portal.md rename to archive/enterprise/0.36-x/developer-portal/theme-customization/customizing-dev-portal.md diff --git a/app/enterprise/0.36-x/getting-started/add-admin.md b/archive/enterprise/0.36-x/getting-started/add-admin.md similarity index 100% rename from app/enterprise/0.36-x/getting-started/add-admin.md rename to archive/enterprise/0.36-x/getting-started/add-admin.md diff --git a/app/enterprise/0.36-x/getting-started/add-consumer.md b/archive/enterprise/0.36-x/getting-started/add-consumer.md similarity index 100% rename from app/enterprise/0.36-x/getting-started/add-consumer.md rename to archive/enterprise/0.36-x/getting-started/add-consumer.md diff --git a/app/enterprise/0.36-x/getting-started/add-role.md b/archive/enterprise/0.36-x/getting-started/add-role.md similarity index 100% rename from app/enterprise/0.36-x/getting-started/add-role.md rename to archive/enterprise/0.36-x/getting-started/add-role.md diff --git a/app/enterprise/0.36-x/getting-started/add-service.md b/archive/enterprise/0.36-x/getting-started/add-service.md similarity index 100% rename from app/enterprise/0.36-x/getting-started/add-service.md rename to archive/enterprise/0.36-x/getting-started/add-service.md diff --git a/app/enterprise/0.36-x/getting-started/add-workspace.md b/archive/enterprise/0.36-x/getting-started/add-workspace.md similarity index 100% rename from app/enterprise/0.36-x/getting-started/add-workspace.md rename to archive/enterprise/0.36-x/getting-started/add-workspace.md diff --git a/app/enterprise/0.36-x/getting-started/enable-dev-portal.md b/archive/enterprise/0.36-x/getting-started/enable-dev-portal.md similarity index 100% rename from app/enterprise/0.36-x/getting-started/enable-dev-portal.md rename to archive/enterprise/0.36-x/getting-started/enable-dev-portal.md diff --git a/app/enterprise/0.36-x/getting-started/enable-plugin.md b/archive/enterprise/0.36-x/getting-started/enable-plugin.md similarity index 100% rename from app/enterprise/0.36-x/getting-started/enable-plugin.md rename to archive/enterprise/0.36-x/getting-started/enable-plugin.md diff --git a/app/enterprise/0.36-x/getting-started/index.md b/archive/enterprise/0.36-x/getting-started/index.md similarity index 100% rename from app/enterprise/0.36-x/getting-started/index.md rename to archive/enterprise/0.36-x/getting-started/index.md diff --git a/app/enterprise/0.36-x/getting-started/start-kong.md b/archive/enterprise/0.36-x/getting-started/start-kong.md similarity index 100% rename from app/enterprise/0.36-x/getting-started/start-kong.md rename to archive/enterprise/0.36-x/getting-started/start-kong.md diff --git a/app/enterprise/0.36-x/health-checks-circuit-breakers.md b/archive/enterprise/0.36-x/health-checks-circuit-breakers.md similarity index 100% rename from app/enterprise/0.36-x/health-checks-circuit-breakers.md rename to archive/enterprise/0.36-x/health-checks-circuit-breakers.md diff --git a/app/enterprise/0.36-x/index.md b/archive/enterprise/0.36-x/index.md similarity index 100% rename from app/enterprise/0.36-x/index.md rename to archive/enterprise/0.36-x/index.md diff --git a/app/enterprise/0.36-x/kong-manager/administration/admins/admins.md b/archive/enterprise/0.36-x/kong-manager/administration/admins/admins.md similarity index 100% rename from app/enterprise/0.36-x/kong-manager/administration/admins/admins.md rename to archive/enterprise/0.36-x/kong-manager/administration/admins/admins.md diff --git a/app/enterprise/0.36-x/kong-manager/administration/admins/invite.md b/archive/enterprise/0.36-x/kong-manager/administration/admins/invite.md similarity index 100% rename from app/enterprise/0.36-x/kong-manager/administration/admins/invite.md rename to archive/enterprise/0.36-x/kong-manager/administration/admins/invite.md diff --git a/app/enterprise/0.36-x/kong-manager/administration/rbac/new-role.md b/archive/enterprise/0.36-x/kong-manager/administration/rbac/new-role.md similarity index 100% rename from app/enterprise/0.36-x/kong-manager/administration/rbac/new-role.md rename to archive/enterprise/0.36-x/kong-manager/administration/rbac/new-role.md diff --git a/app/enterprise/0.36-x/kong-manager/administration/rbac/rbac.md b/archive/enterprise/0.36-x/kong-manager/administration/rbac/rbac.md similarity index 100% rename from app/enterprise/0.36-x/kong-manager/administration/rbac/rbac.md rename to archive/enterprise/0.36-x/kong-manager/administration/rbac/rbac.md diff --git a/app/enterprise/0.36-x/kong-manager/administration/workspaces/create-workspace.md b/archive/enterprise/0.36-x/kong-manager/administration/workspaces/create-workspace.md similarity index 100% rename from app/enterprise/0.36-x/kong-manager/administration/workspaces/create-workspace.md rename to archive/enterprise/0.36-x/kong-manager/administration/workspaces/create-workspace.md diff --git a/app/enterprise/0.36-x/kong-manager/administration/workspaces/update-workspace.md b/archive/enterprise/0.36-x/kong-manager/administration/workspaces/update-workspace.md similarity index 100% rename from app/enterprise/0.36-x/kong-manager/administration/workspaces/update-workspace.md rename to archive/enterprise/0.36-x/kong-manager/administration/workspaces/update-workspace.md diff --git a/app/enterprise/0.36-x/kong-manager/administration/workspaces/workspaces.md b/archive/enterprise/0.36-x/kong-manager/administration/workspaces/workspaces.md similarity index 100% rename from app/enterprise/0.36-x/kong-manager/administration/workspaces/workspaces.md rename to archive/enterprise/0.36-x/kong-manager/administration/workspaces/workspaces.md diff --git a/app/enterprise/0.36-x/kong-manager/authentication/basic.md b/archive/enterprise/0.36-x/kong-manager/authentication/basic.md similarity index 100% rename from app/enterprise/0.36-x/kong-manager/authentication/basic.md rename to archive/enterprise/0.36-x/kong-manager/authentication/basic.md diff --git a/app/enterprise/0.36-x/kong-manager/authentication/ldap.md b/archive/enterprise/0.36-x/kong-manager/authentication/ldap.md similarity index 100% rename from app/enterprise/0.36-x/kong-manager/authentication/ldap.md rename to archive/enterprise/0.36-x/kong-manager/authentication/ldap.md diff --git a/app/enterprise/0.36-x/kong-manager/authentication/oidc.md b/archive/enterprise/0.36-x/kong-manager/authentication/oidc.md similarity index 100% rename from app/enterprise/0.36-x/kong-manager/authentication/oidc.md rename to archive/enterprise/0.36-x/kong-manager/authentication/oidc.md diff --git a/app/enterprise/0.36-x/kong-manager/authentication/sessions.md b/archive/enterprise/0.36-x/kong-manager/authentication/sessions.md similarity index 100% rename from app/enterprise/0.36-x/kong-manager/authentication/sessions.md rename to archive/enterprise/0.36-x/kong-manager/authentication/sessions.md diff --git a/app/enterprise/0.36-x/kong-manager/authentication/super-admin.md b/archive/enterprise/0.36-x/kong-manager/authentication/super-admin.md similarity index 100% rename from app/enterprise/0.36-x/kong-manager/authentication/super-admin.md rename to archive/enterprise/0.36-x/kong-manager/authentication/super-admin.md diff --git a/app/enterprise/0.36-x/kong-manager/best-practices.md b/archive/enterprise/0.36-x/kong-manager/best-practices.md similarity index 100% rename from app/enterprise/0.36-x/kong-manager/best-practices.md rename to archive/enterprise/0.36-x/kong-manager/best-practices.md diff --git a/app/enterprise/0.36-x/kong-manager/faq.md b/archive/enterprise/0.36-x/kong-manager/faq.md similarity index 100% rename from app/enterprise/0.36-x/kong-manager/faq.md rename to archive/enterprise/0.36-x/kong-manager/faq.md diff --git a/app/enterprise/0.36-x/kong-manager/networking/configuration.md b/archive/enterprise/0.36-x/kong-manager/networking/configuration.md similarity index 100% rename from app/enterprise/0.36-x/kong-manager/networking/configuration.md rename to archive/enterprise/0.36-x/kong-manager/networking/configuration.md diff --git a/app/enterprise/0.36-x/kong-manager/networking/email.md b/archive/enterprise/0.36-x/kong-manager/networking/email.md similarity index 100% rename from app/enterprise/0.36-x/kong-manager/networking/email.md rename to archive/enterprise/0.36-x/kong-manager/networking/email.md diff --git a/app/enterprise/0.36-x/kong-manager/overview.md b/archive/enterprise/0.36-x/kong-manager/overview.md similarity index 100% rename from app/enterprise/0.36-x/kong-manager/overview.md rename to archive/enterprise/0.36-x/kong-manager/overview.md diff --git a/app/enterprise/0.36-x/kong-manager/reset-password.md b/archive/enterprise/0.36-x/kong-manager/reset-password.md similarity index 100% rename from app/enterprise/0.36-x/kong-manager/reset-password.md rename to archive/enterprise/0.36-x/kong-manager/reset-password.md diff --git a/app/enterprise/0.36-x/kong-manager/security.md b/archive/enterprise/0.36-x/kong-manager/security.md similarity index 100% rename from app/enterprise/0.36-x/kong-manager/security.md rename to archive/enterprise/0.36-x/kong-manager/security.md diff --git a/app/enterprise/0.36-x/kong-manager/vitals.md b/archive/enterprise/0.36-x/kong-manager/vitals.md similarity index 100% rename from app/enterprise/0.36-x/kong-manager/vitals.md rename to archive/enterprise/0.36-x/kong-manager/vitals.md diff --git a/app/enterprise/0.36-x/loadbalancing.md b/archive/enterprise/0.36-x/loadbalancing.md similarity index 100% rename from app/enterprise/0.36-x/loadbalancing.md rename to archive/enterprise/0.36-x/loadbalancing.md diff --git a/app/enterprise/0.36-x/logging.md b/archive/enterprise/0.36-x/logging.md similarity index 100% rename from app/enterprise/0.36-x/logging.md rename to archive/enterprise/0.36-x/logging.md diff --git a/app/enterprise/0.36-x/network.md b/archive/enterprise/0.36-x/network.md similarity index 100% rename from app/enterprise/0.36-x/network.md rename to archive/enterprise/0.36-x/network.md diff --git a/app/enterprise/0.36-x/oasconfig.md b/archive/enterprise/0.36-x/oasconfig.md similarity index 100% rename from app/enterprise/0.36-x/oasconfig.md rename to archive/enterprise/0.36-x/oasconfig.md diff --git a/app/enterprise/0.36-x/pdk/index.md b/archive/enterprise/0.36-x/pdk/index.md similarity index 100% rename from app/enterprise/0.36-x/pdk/index.md rename to archive/enterprise/0.36-x/pdk/index.md diff --git a/app/enterprise/0.36-x/pdk/kong.client.md b/archive/enterprise/0.36-x/pdk/kong.client.md similarity index 100% rename from app/enterprise/0.36-x/pdk/kong.client.md rename to archive/enterprise/0.36-x/pdk/kong.client.md diff --git a/app/enterprise/0.36-x/pdk/kong.ctx.md b/archive/enterprise/0.36-x/pdk/kong.ctx.md similarity index 100% rename from app/enterprise/0.36-x/pdk/kong.ctx.md rename to archive/enterprise/0.36-x/pdk/kong.ctx.md diff --git a/app/enterprise/0.36-x/pdk/kong.ip.md b/archive/enterprise/0.36-x/pdk/kong.ip.md similarity index 100% rename from app/enterprise/0.36-x/pdk/kong.ip.md rename to archive/enterprise/0.36-x/pdk/kong.ip.md diff --git a/app/enterprise/0.36-x/pdk/kong.log.md b/archive/enterprise/0.36-x/pdk/kong.log.md similarity index 100% rename from app/enterprise/0.36-x/pdk/kong.log.md rename to archive/enterprise/0.36-x/pdk/kong.log.md diff --git a/app/enterprise/0.36-x/pdk/kong.node.md b/archive/enterprise/0.36-x/pdk/kong.node.md similarity index 100% rename from app/enterprise/0.36-x/pdk/kong.node.md rename to archive/enterprise/0.36-x/pdk/kong.node.md diff --git a/app/enterprise/0.36-x/pdk/kong.request.md b/archive/enterprise/0.36-x/pdk/kong.request.md similarity index 100% rename from app/enterprise/0.36-x/pdk/kong.request.md rename to archive/enterprise/0.36-x/pdk/kong.request.md diff --git a/app/enterprise/0.36-x/pdk/kong.response.md b/archive/enterprise/0.36-x/pdk/kong.response.md similarity index 100% rename from app/enterprise/0.36-x/pdk/kong.response.md rename to archive/enterprise/0.36-x/pdk/kong.response.md diff --git a/app/enterprise/0.36-x/pdk/kong.router.md b/archive/enterprise/0.36-x/pdk/kong.router.md similarity index 100% rename from app/enterprise/0.36-x/pdk/kong.router.md rename to archive/enterprise/0.36-x/pdk/kong.router.md diff --git a/app/enterprise/0.36-x/pdk/kong.service.md b/archive/enterprise/0.36-x/pdk/kong.service.md similarity index 100% rename from app/enterprise/0.36-x/pdk/kong.service.md rename to archive/enterprise/0.36-x/pdk/kong.service.md diff --git a/app/enterprise/0.36-x/pdk/kong.service.request.md b/archive/enterprise/0.36-x/pdk/kong.service.request.md similarity index 100% rename from app/enterprise/0.36-x/pdk/kong.service.request.md rename to archive/enterprise/0.36-x/pdk/kong.service.request.md diff --git a/app/enterprise/0.36-x/pdk/kong.service.response.md b/archive/enterprise/0.36-x/pdk/kong.service.response.md similarity index 100% rename from app/enterprise/0.36-x/pdk/kong.service.response.md rename to archive/enterprise/0.36-x/pdk/kong.service.response.md diff --git a/app/enterprise/0.36-x/pdk/kong.table.md b/archive/enterprise/0.36-x/pdk/kong.table.md similarity index 100% rename from app/enterprise/0.36-x/pdk/kong.table.md rename to archive/enterprise/0.36-x/pdk/kong.table.md diff --git a/app/enterprise/0.36-x/plugin-development/access-the-datastore.md b/archive/enterprise/0.36-x/plugin-development/access-the-datastore.md similarity index 100% rename from app/enterprise/0.36-x/plugin-development/access-the-datastore.md rename to archive/enterprise/0.36-x/plugin-development/access-the-datastore.md diff --git a/app/enterprise/0.36-x/plugin-development/admin-api.md b/archive/enterprise/0.36-x/plugin-development/admin-api.md similarity index 100% rename from app/enterprise/0.36-x/plugin-development/admin-api.md rename to archive/enterprise/0.36-x/plugin-development/admin-api.md diff --git a/app/enterprise/0.36-x/plugin-development/custom-entities.md b/archive/enterprise/0.36-x/plugin-development/custom-entities.md similarity index 100% rename from app/enterprise/0.36-x/plugin-development/custom-entities.md rename to archive/enterprise/0.36-x/plugin-development/custom-entities.md diff --git a/app/enterprise/0.36-x/plugin-development/custom-logic.md b/archive/enterprise/0.36-x/plugin-development/custom-logic.md similarity index 100% rename from app/enterprise/0.36-x/plugin-development/custom-logic.md rename to archive/enterprise/0.36-x/plugin-development/custom-logic.md diff --git a/app/enterprise/0.36-x/plugin-development/distribution.md b/archive/enterprise/0.36-x/plugin-development/distribution.md similarity index 100% rename from app/enterprise/0.36-x/plugin-development/distribution.md rename to archive/enterprise/0.36-x/plugin-development/distribution.md diff --git a/app/enterprise/0.36-x/plugin-development/entities-cache.md b/archive/enterprise/0.36-x/plugin-development/entities-cache.md similarity index 100% rename from app/enterprise/0.36-x/plugin-development/entities-cache.md rename to archive/enterprise/0.36-x/plugin-development/entities-cache.md diff --git a/app/enterprise/0.36-x/plugin-development/file-structure.md b/archive/enterprise/0.36-x/plugin-development/file-structure.md similarity index 100% rename from app/enterprise/0.36-x/plugin-development/file-structure.md rename to archive/enterprise/0.36-x/plugin-development/file-structure.md diff --git a/app/enterprise/0.36-x/plugin-development/index.md b/archive/enterprise/0.36-x/plugin-development/index.md similarity index 100% rename from app/enterprise/0.36-x/plugin-development/index.md rename to archive/enterprise/0.36-x/plugin-development/index.md diff --git a/app/enterprise/0.36-x/plugin-development/plugin-configuration.md b/archive/enterprise/0.36-x/plugin-development/plugin-configuration.md similarity index 100% rename from app/enterprise/0.36-x/plugin-development/plugin-configuration.md rename to archive/enterprise/0.36-x/plugin-development/plugin-configuration.md diff --git a/app/enterprise/0.36-x/plugin-development/tests.md b/archive/enterprise/0.36-x/plugin-development/tests.md similarity index 100% rename from app/enterprise/0.36-x/plugin-development/tests.md rename to archive/enterprise/0.36-x/plugin-development/tests.md diff --git a/app/enterprise/0.36-x/plugins/allowing-multiple-authentication-methods.md b/archive/enterprise/0.36-x/plugins/allowing-multiple-authentication-methods.md similarity index 100% rename from app/enterprise/0.36-x/plugins/allowing-multiple-authentication-methods.md rename to archive/enterprise/0.36-x/plugins/allowing-multiple-authentication-methods.md diff --git a/app/enterprise/0.36-x/plugins/canary-release.md b/archive/enterprise/0.36-x/plugins/canary-release.md similarity index 100% rename from app/enterprise/0.36-x/plugins/canary-release.md rename to archive/enterprise/0.36-x/plugins/canary-release.md diff --git a/app/enterprise/0.36-x/plugins/forward-proxy.md b/archive/enterprise/0.36-x/plugins/forward-proxy.md similarity index 100% rename from app/enterprise/0.36-x/plugins/forward-proxy.md rename to archive/enterprise/0.36-x/plugins/forward-proxy.md diff --git a/app/enterprise/0.36-x/plugins/http-proxy-caching.md b/archive/enterprise/0.36-x/plugins/http-proxy-caching.md similarity index 100% rename from app/enterprise/0.36-x/plugins/http-proxy-caching.md rename to archive/enterprise/0.36-x/plugins/http-proxy-caching.md diff --git a/app/enterprise/0.36-x/plugins/index.md b/archive/enterprise/0.36-x/plugins/index.md similarity index 100% rename from app/enterprise/0.36-x/plugins/index.md rename to archive/enterprise/0.36-x/plugins/index.md diff --git a/app/enterprise/0.36-x/plugins/jwt-signer.md b/archive/enterprise/0.36-x/plugins/jwt-signer.md similarity index 100% rename from app/enterprise/0.36-x/plugins/jwt-signer.md rename to archive/enterprise/0.36-x/plugins/jwt-signer.md diff --git a/app/enterprise/0.36-x/plugins/ldap-authentication-advanced.md b/archive/enterprise/0.36-x/plugins/ldap-authentication-advanced.md similarity index 100% rename from app/enterprise/0.36-x/plugins/ldap-authentication-advanced.md rename to archive/enterprise/0.36-x/plugins/ldap-authentication-advanced.md diff --git a/app/enterprise/0.36-x/plugins/oauth2-introspection.md b/archive/enterprise/0.36-x/plugins/oauth2-introspection.md similarity index 100% rename from app/enterprise/0.36-x/plugins/oauth2-introspection.md rename to archive/enterprise/0.36-x/plugins/oauth2-introspection.md diff --git a/app/enterprise/0.36-x/plugins/oidc-auth0.md b/archive/enterprise/0.36-x/plugins/oidc-auth0.md similarity index 100% rename from app/enterprise/0.36-x/plugins/oidc-auth0.md rename to archive/enterprise/0.36-x/plugins/oidc-auth0.md diff --git a/app/enterprise/0.36-x/plugins/oidc-azuread.md b/archive/enterprise/0.36-x/plugins/oidc-azuread.md similarity index 100% rename from app/enterprise/0.36-x/plugins/oidc-azuread.md rename to archive/enterprise/0.36-x/plugins/oidc-azuread.md diff --git a/app/enterprise/0.36-x/plugins/oidc-google.md b/archive/enterprise/0.36-x/plugins/oidc-google.md similarity index 100% rename from app/enterprise/0.36-x/plugins/oidc-google.md rename to archive/enterprise/0.36-x/plugins/oidc-google.md diff --git a/app/enterprise/0.36-x/plugins/oidc-okta.md b/archive/enterprise/0.36-x/plugins/oidc-okta.md similarity index 100% rename from app/enterprise/0.36-x/plugins/oidc-okta.md rename to archive/enterprise/0.36-x/plugins/oidc-okta.md diff --git a/app/enterprise/0.36-x/plugins/openid-connect.md b/archive/enterprise/0.36-x/plugins/openid-connect.md similarity index 100% rename from app/enterprise/0.36-x/plugins/openid-connect.md rename to archive/enterprise/0.36-x/plugins/openid-connect.md diff --git a/app/enterprise/0.36-x/plugins/rate-limiting-advanced.md b/archive/enterprise/0.36-x/plugins/rate-limiting-advanced.md similarity index 100% rename from app/enterprise/0.36-x/plugins/rate-limiting-advanced.md rename to archive/enterprise/0.36-x/plugins/rate-limiting-advanced.md diff --git a/app/enterprise/0.36-x/plugins/request-transformer.md b/archive/enterprise/0.36-x/plugins/request-transformer.md similarity index 100% rename from app/enterprise/0.36-x/plugins/request-transformer.md rename to archive/enterprise/0.36-x/plugins/request-transformer.md diff --git a/app/enterprise/0.36-x/plugins/request-validator.md b/archive/enterprise/0.36-x/plugins/request-validator.md similarity index 100% rename from app/enterprise/0.36-x/plugins/request-validator.md rename to archive/enterprise/0.36-x/plugins/request-validator.md diff --git a/app/enterprise/0.36-x/plugins/route-by-header.md b/archive/enterprise/0.36-x/plugins/route-by-header.md similarity index 100% rename from app/enterprise/0.36-x/plugins/route-by-header.md rename to archive/enterprise/0.36-x/plugins/route-by-header.md diff --git a/app/enterprise/0.36-x/plugins/route-by-headers.md b/archive/enterprise/0.36-x/plugins/route-by-headers.md similarity index 100% rename from app/enterprise/0.36-x/plugins/route-by-headers.md rename to archive/enterprise/0.36-x/plugins/route-by-headers.md diff --git a/app/enterprise/0.36-x/plugins/session.md b/archive/enterprise/0.36-x/plugins/session.md similarity index 100% rename from app/enterprise/0.36-x/plugins/session.md rename to archive/enterprise/0.36-x/plugins/session.md diff --git a/app/enterprise/0.36-x/plugins/statsd-advanced.md b/archive/enterprise/0.36-x/plugins/statsd-advanced.md similarity index 100% rename from app/enterprise/0.36-x/plugins/statsd-advanced.md rename to archive/enterprise/0.36-x/plugins/statsd-advanced.md diff --git a/app/enterprise/0.36-x/plugins/statsd.rules.yaml b/archive/enterprise/0.36-x/plugins/statsd.rules.yaml similarity index 100% rename from app/enterprise/0.36-x/plugins/statsd.rules.yaml rename to archive/enterprise/0.36-x/plugins/statsd.rules.yaml diff --git a/app/enterprise/0.36-x/plugins/upstream-tls.md b/archive/enterprise/0.36-x/plugins/upstream-tls.md similarity index 100% rename from app/enterprise/0.36-x/plugins/upstream-tls.md rename to archive/enterprise/0.36-x/plugins/upstream-tls.md diff --git a/app/enterprise/0.36-x/plugins/vault-auth.md b/archive/enterprise/0.36-x/plugins/vault-auth.md similarity index 100% rename from app/enterprise/0.36-x/plugins/vault-auth.md rename to archive/enterprise/0.36-x/plugins/vault-auth.md diff --git a/app/enterprise/0.36-x/property-reference.md b/archive/enterprise/0.36-x/property-reference.md similarity index 100% rename from app/enterprise/0.36-x/property-reference.md rename to archive/enterprise/0.36-x/property-reference.md diff --git a/app/enterprise/0.36-x/proxy.md b/archive/enterprise/0.36-x/proxy.md similarity index 100% rename from app/enterprise/0.36-x/proxy.md rename to archive/enterprise/0.36-x/proxy.md diff --git a/app/enterprise/0.36-x/secure-admin-api.md b/archive/enterprise/0.36-x/secure-admin-api.md similarity index 100% rename from app/enterprise/0.36-x/secure-admin-api.md rename to archive/enterprise/0.36-x/secure-admin-api.md diff --git a/app/enterprise/1.3-x/admin-api/admins/examples.md b/archive/enterprise/1.3-x/admin-api/admins/examples.md similarity index 100% rename from app/enterprise/1.3-x/admin-api/admins/examples.md rename to archive/enterprise/1.3-x/admin-api/admins/examples.md diff --git a/app/enterprise/1.3-x/admin-api/admins/reference.md b/archive/enterprise/1.3-x/admin-api/admins/reference.md similarity index 100% rename from app/enterprise/1.3-x/admin-api/admins/reference.md rename to archive/enterprise/1.3-x/admin-api/admins/reference.md diff --git a/app/enterprise/1.3-x/admin-api/audit-log.md b/archive/enterprise/1.3-x/admin-api/audit-log.md similarity index 100% rename from app/enterprise/1.3-x/admin-api/audit-log.md rename to archive/enterprise/1.3-x/admin-api/audit-log.md diff --git a/app/enterprise/1.3-x/admin-api/db-encryption.md b/archive/enterprise/1.3-x/admin-api/db-encryption.md similarity index 100% rename from app/enterprise/1.3-x/admin-api/db-encryption.md rename to archive/enterprise/1.3-x/admin-api/db-encryption.md diff --git a/app/enterprise/1.3-x/admin-api/index.md b/archive/enterprise/1.3-x/admin-api/index.md similarity index 100% rename from app/enterprise/1.3-x/admin-api/index.md rename to archive/enterprise/1.3-x/admin-api/index.md diff --git a/app/enterprise/1.3-x/admin-api/rbac/examples.md b/archive/enterprise/1.3-x/admin-api/rbac/examples.md similarity index 100% rename from app/enterprise/1.3-x/admin-api/rbac/examples.md rename to archive/enterprise/1.3-x/admin-api/rbac/examples.md diff --git a/app/enterprise/1.3-x/admin-api/rbac/reference.md b/archive/enterprise/1.3-x/admin-api/rbac/reference.md similarity index 100% rename from app/enterprise/1.3-x/admin-api/rbac/reference.md rename to archive/enterprise/1.3-x/admin-api/rbac/reference.md diff --git a/app/enterprise/1.3-x/admin-api/vitals/index.md b/archive/enterprise/1.3-x/admin-api/vitals/index.md similarity index 100% rename from app/enterprise/1.3-x/admin-api/vitals/index.md rename to archive/enterprise/1.3-x/admin-api/vitals/index.md diff --git a/app/enterprise/1.3-x/admin-api/vitals/vitals-influx-strategy.md b/archive/enterprise/1.3-x/admin-api/vitals/vitals-influx-strategy.md similarity index 100% rename from app/enterprise/1.3-x/admin-api/vitals/vitals-influx-strategy.md rename to archive/enterprise/1.3-x/admin-api/vitals/vitals-influx-strategy.md diff --git a/app/enterprise/1.3-x/admin-api/vitals/vitals-prometheus-strategy.md b/archive/enterprise/1.3-x/admin-api/vitals/vitals-prometheus-strategy.md similarity index 100% rename from app/enterprise/1.3-x/admin-api/vitals/vitals-prometheus-strategy.md rename to archive/enterprise/1.3-x/admin-api/vitals/vitals-prometheus-strategy.md diff --git a/app/enterprise/1.3-x/admin-api/vitals/vitalsSpec.yaml b/archive/enterprise/1.3-x/admin-api/vitals/vitalsSpec.yaml similarity index 100% rename from app/enterprise/1.3-x/admin-api/vitals/vitalsSpec.yaml rename to archive/enterprise/1.3-x/admin-api/vitals/vitalsSpec.yaml diff --git a/app/enterprise/1.3-x/admin-api/workspaces/examples.md b/archive/enterprise/1.3-x/admin-api/workspaces/examples.md similarity index 100% rename from app/enterprise/1.3-x/admin-api/workspaces/examples.md rename to archive/enterprise/1.3-x/admin-api/workspaces/examples.md diff --git a/app/enterprise/1.3-x/admin-api/workspaces/reference.md b/archive/enterprise/1.3-x/admin-api/workspaces/reference.md similarity index 100% rename from app/enterprise/1.3-x/admin-api/workspaces/reference.md rename to archive/enterprise/1.3-x/admin-api/workspaces/reference.md diff --git a/app/enterprise/1.3-x/auth.md b/archive/enterprise/1.3-x/auth.md similarity index 100% rename from app/enterprise/1.3-x/auth.md rename to archive/enterprise/1.3-x/auth.md diff --git a/app/enterprise/1.3-x/cli.md b/archive/enterprise/1.3-x/cli.md similarity index 100% rename from app/enterprise/1.3-x/cli.md rename to archive/enterprise/1.3-x/cli.md diff --git a/app/enterprise/1.3-x/clustering.md b/archive/enterprise/1.3-x/clustering.md similarity index 100% rename from app/enterprise/1.3-x/clustering.md rename to archive/enterprise/1.3-x/clustering.md diff --git a/app/enterprise/1.3-x/compatibility.md b/archive/enterprise/1.3-x/compatibility.md similarity index 100% rename from app/enterprise/1.3-x/compatibility.md rename to archive/enterprise/1.3-x/compatibility.md diff --git a/app/enterprise/1.3-x/db-encryption.md b/archive/enterprise/1.3-x/db-encryption.md similarity index 100% rename from app/enterprise/1.3-x/db-encryption.md rename to archive/enterprise/1.3-x/db-encryption.md diff --git a/app/enterprise/1.3-x/deployment/access-license.md b/archive/enterprise/1.3-x/deployment/access-license.md similarity index 100% rename from app/enterprise/1.3-x/deployment/access-license.md rename to archive/enterprise/1.3-x/deployment/access-license.md diff --git a/app/enterprise/1.3-x/deployment/installation/amazon-linux-2.md b/archive/enterprise/1.3-x/deployment/installation/amazon-linux-2.md similarity index 100% rename from app/enterprise/1.3-x/deployment/installation/amazon-linux-2.md rename to archive/enterprise/1.3-x/deployment/installation/amazon-linux-2.md diff --git a/app/enterprise/1.3-x/deployment/installation/amazon-linux.md b/archive/enterprise/1.3-x/deployment/installation/amazon-linux.md similarity index 100% rename from app/enterprise/1.3-x/deployment/installation/amazon-linux.md rename to archive/enterprise/1.3-x/deployment/installation/amazon-linux.md diff --git a/app/enterprise/1.3-x/deployment/installation/centos.md b/archive/enterprise/1.3-x/deployment/installation/centos.md similarity index 100% rename from app/enterprise/1.3-x/deployment/installation/centos.md rename to archive/enterprise/1.3-x/deployment/installation/centos.md diff --git a/app/enterprise/1.3-x/deployment/installation/docker.md b/archive/enterprise/1.3-x/deployment/installation/docker.md similarity index 100% rename from app/enterprise/1.3-x/deployment/installation/docker.md rename to archive/enterprise/1.3-x/deployment/installation/docker.md diff --git a/app/enterprise/1.3-x/deployment/installation/index.md b/archive/enterprise/1.3-x/deployment/installation/index.md similarity index 100% rename from app/enterprise/1.3-x/deployment/installation/index.md rename to archive/enterprise/1.3-x/deployment/installation/index.md diff --git a/app/enterprise/1.3-x/deployment/installation/overview.md b/archive/enterprise/1.3-x/deployment/installation/overview.md similarity index 100% rename from app/enterprise/1.3-x/deployment/installation/overview.md rename to archive/enterprise/1.3-x/deployment/installation/overview.md diff --git a/app/enterprise/1.3-x/deployment/installation/rhel.md b/archive/enterprise/1.3-x/deployment/installation/rhel.md similarity index 100% rename from app/enterprise/1.3-x/deployment/installation/rhel.md rename to archive/enterprise/1.3-x/deployment/installation/rhel.md diff --git a/app/enterprise/1.3-x/deployment/installation/ubuntu.md b/archive/enterprise/1.3-x/deployment/installation/ubuntu.md similarity index 100% rename from app/enterprise/1.3-x/deployment/installation/ubuntu.md rename to archive/enterprise/1.3-x/deployment/installation/ubuntu.md diff --git a/app/enterprise/1.3-x/deployment/licenses/report.md b/archive/enterprise/1.3-x/deployment/licenses/report.md similarity index 100% rename from app/enterprise/1.3-x/deployment/licenses/report.md rename to archive/enterprise/1.3-x/deployment/licenses/report.md diff --git a/app/enterprise/1.3-x/deployment/licensing.md b/archive/enterprise/1.3-x/deployment/licensing.md similarity index 100% rename from app/enterprise/1.3-x/deployment/licensing.md rename to archive/enterprise/1.3-x/deployment/licensing.md diff --git a/app/enterprise/1.3-x/deployment/migrations.md b/archive/enterprise/1.3-x/deployment/migrations.md similarity index 100% rename from app/enterprise/1.3-x/deployment/migrations.md rename to archive/enterprise/1.3-x/deployment/migrations.md diff --git a/app/enterprise/1.3-x/developer-portal/administration/developer-permissions.md b/archive/enterprise/1.3-x/developer-portal/administration/developer-permissions.md similarity index 100% rename from app/enterprise/1.3-x/developer-portal/administration/developer-permissions.md rename to archive/enterprise/1.3-x/developer-portal/administration/developer-permissions.md diff --git a/app/enterprise/1.3-x/developer-portal/administration/index.md b/archive/enterprise/1.3-x/developer-portal/administration/index.md similarity index 100% rename from app/enterprise/1.3-x/developer-portal/administration/index.md rename to archive/enterprise/1.3-x/developer-portal/administration/index.md diff --git a/app/enterprise/1.3-x/developer-portal/administration/managing-developers.md b/archive/enterprise/1.3-x/developer-portal/administration/managing-developers.md similarity index 100% rename from app/enterprise/1.3-x/developer-portal/administration/managing-developers.md rename to archive/enterprise/1.3-x/developer-portal/administration/managing-developers.md diff --git a/app/enterprise/1.3-x/developer-portal/configuration/authentication/adding-registration-fields.md b/archive/enterprise/1.3-x/developer-portal/configuration/authentication/adding-registration-fields.md similarity index 100% rename from app/enterprise/1.3-x/developer-portal/configuration/authentication/adding-registration-fields.md rename to archive/enterprise/1.3-x/developer-portal/configuration/authentication/adding-registration-fields.md diff --git a/app/enterprise/1.3-x/developer-portal/configuration/authentication/basic-auth.md b/archive/enterprise/1.3-x/developer-portal/configuration/authentication/basic-auth.md similarity index 100% rename from app/enterprise/1.3-x/developer-portal/configuration/authentication/basic-auth.md rename to archive/enterprise/1.3-x/developer-portal/configuration/authentication/basic-auth.md diff --git a/app/enterprise/1.3-x/developer-portal/configuration/authentication/index.md b/archive/enterprise/1.3-x/developer-portal/configuration/authentication/index.md similarity index 100% rename from app/enterprise/1.3-x/developer-portal/configuration/authentication/index.md rename to archive/enterprise/1.3-x/developer-portal/configuration/authentication/index.md diff --git a/app/enterprise/1.3-x/developer-portal/configuration/authentication/key-auth.md b/archive/enterprise/1.3-x/developer-portal/configuration/authentication/key-auth.md similarity index 100% rename from app/enterprise/1.3-x/developer-portal/configuration/authentication/key-auth.md rename to archive/enterprise/1.3-x/developer-portal/configuration/authentication/key-auth.md diff --git a/app/enterprise/1.3-x/developer-portal/configuration/authentication/oidc.md b/archive/enterprise/1.3-x/developer-portal/configuration/authentication/oidc.md similarity index 100% rename from app/enterprise/1.3-x/developer-portal/configuration/authentication/oidc.md rename to archive/enterprise/1.3-x/developer-portal/configuration/authentication/oidc.md diff --git a/app/enterprise/1.3-x/developer-portal/configuration/authentication/sessions.md b/archive/enterprise/1.3-x/developer-portal/configuration/authentication/sessions.md similarity index 100% rename from app/enterprise/1.3-x/developer-portal/configuration/authentication/sessions.md rename to archive/enterprise/1.3-x/developer-portal/configuration/authentication/sessions.md diff --git a/app/enterprise/1.3-x/developer-portal/configuration/index.md b/archive/enterprise/1.3-x/developer-portal/configuration/index.md similarity index 100% rename from app/enterprise/1.3-x/developer-portal/configuration/index.md rename to archive/enterprise/1.3-x/developer-portal/configuration/index.md diff --git a/app/enterprise/1.3-x/developer-portal/configuration/smtp.md b/archive/enterprise/1.3-x/developer-portal/configuration/smtp.md similarity index 100% rename from app/enterprise/1.3-x/developer-portal/configuration/smtp.md rename to archive/enterprise/1.3-x/developer-portal/configuration/smtp.md diff --git a/app/enterprise/1.3-x/developer-portal/configuration/workspaces.md b/archive/enterprise/1.3-x/developer-portal/configuration/workspaces.md similarity index 100% rename from app/enterprise/1.3-x/developer-portal/configuration/workspaces.md rename to archive/enterprise/1.3-x/developer-portal/configuration/workspaces.md diff --git a/app/enterprise/1.3-x/developer-portal/files-api.md b/archive/enterprise/1.3-x/developer-portal/files-api.md similarity index 100% rename from app/enterprise/1.3-x/developer-portal/files-api.md rename to archive/enterprise/1.3-x/developer-portal/files-api.md diff --git a/app/enterprise/1.3-x/developer-portal/helpers/cli.md b/archive/enterprise/1.3-x/developer-portal/helpers/cli.md similarity index 100% rename from app/enterprise/1.3-x/developer-portal/helpers/cli.md rename to archive/enterprise/1.3-x/developer-portal/helpers/cli.md diff --git a/app/enterprise/1.3-x/developer-portal/index.md b/archive/enterprise/1.3-x/developer-portal/index.md similarity index 100% rename from app/enterprise/1.3-x/developer-portal/index.md rename to archive/enterprise/1.3-x/developer-portal/index.md diff --git a/app/enterprise/1.3-x/developer-portal/introduction.md b/archive/enterprise/1.3-x/developer-portal/introduction.md similarity index 100% rename from app/enterprise/1.3-x/developer-portal/introduction.md rename to archive/enterprise/1.3-x/developer-portal/introduction.md diff --git a/app/enterprise/1.3-x/developer-portal/legacy-migration.md b/archive/enterprise/1.3-x/developer-portal/legacy-migration.md similarity index 100% rename from app/enterprise/1.3-x/developer-portal/legacy-migration.md rename to archive/enterprise/1.3-x/developer-portal/legacy-migration.md diff --git a/app/enterprise/1.3-x/developer-portal/overview.md b/archive/enterprise/1.3-x/developer-portal/overview.md similarity index 100% rename from app/enterprise/1.3-x/developer-portal/overview.md rename to archive/enterprise/1.3-x/developer-portal/overview.md diff --git a/app/enterprise/1.3-x/developer-portal/structure-and-file-types.md b/archive/enterprise/1.3-x/developer-portal/structure-and-file-types.md similarity index 100% rename from app/enterprise/1.3-x/developer-portal/structure-and-file-types.md rename to archive/enterprise/1.3-x/developer-portal/structure-and-file-types.md diff --git a/app/enterprise/1.3-x/developer-portal/theme-customization/adding-javascript-assets.md b/archive/enterprise/1.3-x/developer-portal/theme-customization/adding-javascript-assets.md similarity index 100% rename from app/enterprise/1.3-x/developer-portal/theme-customization/adding-javascript-assets.md rename to archive/enterprise/1.3-x/developer-portal/theme-customization/adding-javascript-assets.md diff --git a/app/enterprise/1.3-x/developer-portal/theme-customization/easy-theme-editing.md b/archive/enterprise/1.3-x/developer-portal/theme-customization/easy-theme-editing.md similarity index 100% rename from app/enterprise/1.3-x/developer-portal/theme-customization/easy-theme-editing.md rename to archive/enterprise/1.3-x/developer-portal/theme-customization/easy-theme-editing.md diff --git a/app/enterprise/1.3-x/developer-portal/theme-customization/emails.md b/archive/enterprise/1.3-x/developer-portal/theme-customization/emails.md similarity index 100% rename from app/enterprise/1.3-x/developer-portal/theme-customization/emails.md rename to archive/enterprise/1.3-x/developer-portal/theme-customization/emails.md diff --git a/app/enterprise/1.3-x/developer-portal/theme-customization/single-page-app.md b/archive/enterprise/1.3-x/developer-portal/theme-customization/single-page-app.md similarity index 100% rename from app/enterprise/1.3-x/developer-portal/theme-customization/single-page-app.md rename to archive/enterprise/1.3-x/developer-portal/theme-customization/single-page-app.md diff --git a/app/enterprise/1.3-x/developer-portal/using-the-editor.md b/archive/enterprise/1.3-x/developer-portal/using-the-editor.md similarity index 100% rename from app/enterprise/1.3-x/developer-portal/using-the-editor.md rename to archive/enterprise/1.3-x/developer-portal/using-the-editor.md diff --git a/app/enterprise/1.3-x/developer-portal/working-with-templates.md b/archive/enterprise/1.3-x/developer-portal/working-with-templates.md similarity index 100% rename from app/enterprise/1.3-x/developer-portal/working-with-templates.md rename to archive/enterprise/1.3-x/developer-portal/working-with-templates.md diff --git a/app/enterprise/1.3-x/getting-started/add-admin.md b/archive/enterprise/1.3-x/getting-started/add-admin.md similarity index 100% rename from app/enterprise/1.3-x/getting-started/add-admin.md rename to archive/enterprise/1.3-x/getting-started/add-admin.md diff --git a/app/enterprise/1.3-x/getting-started/add-consumer.md b/archive/enterprise/1.3-x/getting-started/add-consumer.md similarity index 100% rename from app/enterprise/1.3-x/getting-started/add-consumer.md rename to archive/enterprise/1.3-x/getting-started/add-consumer.md diff --git a/app/enterprise/1.3-x/getting-started/add-role.md b/archive/enterprise/1.3-x/getting-started/add-role.md similarity index 100% rename from app/enterprise/1.3-x/getting-started/add-role.md rename to archive/enterprise/1.3-x/getting-started/add-role.md diff --git a/app/enterprise/1.3-x/getting-started/add-service.md b/archive/enterprise/1.3-x/getting-started/add-service.md similarity index 100% rename from app/enterprise/1.3-x/getting-started/add-service.md rename to archive/enterprise/1.3-x/getting-started/add-service.md diff --git a/app/enterprise/1.3-x/getting-started/add-workspace.md b/archive/enterprise/1.3-x/getting-started/add-workspace.md similarity index 100% rename from app/enterprise/1.3-x/getting-started/add-workspace.md rename to archive/enterprise/1.3-x/getting-started/add-workspace.md diff --git a/app/enterprise/1.3-x/getting-started/configuring-a-grpc-service.md b/archive/enterprise/1.3-x/getting-started/configuring-a-grpc-service.md similarity index 100% rename from app/enterprise/1.3-x/getting-started/configuring-a-grpc-service.md rename to archive/enterprise/1.3-x/getting-started/configuring-a-grpc-service.md diff --git a/app/enterprise/1.3-x/getting-started/enable-dev-portal.md b/archive/enterprise/1.3-x/getting-started/enable-dev-portal.md similarity index 100% rename from app/enterprise/1.3-x/getting-started/enable-dev-portal.md rename to archive/enterprise/1.3-x/getting-started/enable-dev-portal.md diff --git a/app/enterprise/1.3-x/getting-started/enable-plugin.md b/archive/enterprise/1.3-x/getting-started/enable-plugin.md similarity index 100% rename from app/enterprise/1.3-x/getting-started/enable-plugin.md rename to archive/enterprise/1.3-x/getting-started/enable-plugin.md diff --git a/app/enterprise/1.3-x/getting-started/index.md b/archive/enterprise/1.3-x/getting-started/index.md similarity index 100% rename from app/enterprise/1.3-x/getting-started/index.md rename to archive/enterprise/1.3-x/getting-started/index.md diff --git a/app/enterprise/1.3-x/getting-started/key-concepts.md b/archive/enterprise/1.3-x/getting-started/key-concepts.md similarity index 100% rename from app/enterprise/1.3-x/getting-started/key-concepts.md rename to archive/enterprise/1.3-x/getting-started/key-concepts.md diff --git a/app/enterprise/1.3-x/getting-started/start-kong.md b/archive/enterprise/1.3-x/getting-started/start-kong.md similarity index 100% rename from app/enterprise/1.3-x/getting-started/start-kong.md rename to archive/enterprise/1.3-x/getting-started/start-kong.md diff --git a/app/enterprise/1.3-x/health-checks-circuit-breakers.md b/archive/enterprise/1.3-x/health-checks-circuit-breakers.md similarity index 100% rename from app/enterprise/1.3-x/health-checks-circuit-breakers.md rename to archive/enterprise/1.3-x/health-checks-circuit-breakers.md diff --git a/app/enterprise/1.3-x/index.md b/archive/enterprise/1.3-x/index.md similarity index 100% rename from app/enterprise/1.3-x/index.md rename to archive/enterprise/1.3-x/index.md diff --git a/app/enterprise/1.3-x/kong-cloud.md b/archive/enterprise/1.3-x/kong-cloud.md similarity index 100% rename from app/enterprise/1.3-x/kong-cloud.md rename to archive/enterprise/1.3-x/kong-cloud.md diff --git a/app/enterprise/1.3-x/kong-for-kubernetes/changelog.md b/archive/enterprise/1.3-x/kong-for-kubernetes/changelog.md similarity index 100% rename from app/enterprise/1.3-x/kong-for-kubernetes/changelog.md rename to archive/enterprise/1.3-x/kong-for-kubernetes/changelog.md diff --git a/app/enterprise/1.3-x/kong-for-kubernetes/index.md b/archive/enterprise/1.3-x/kong-for-kubernetes/index.md similarity index 100% rename from app/enterprise/1.3-x/kong-for-kubernetes/index.md rename to archive/enterprise/1.3-x/kong-for-kubernetes/index.md diff --git a/app/enterprise/1.3-x/kong-for-kubernetes/install.md b/archive/enterprise/1.3-x/kong-for-kubernetes/install.md similarity index 100% rename from app/enterprise/1.3-x/kong-for-kubernetes/install.md rename to archive/enterprise/1.3-x/kong-for-kubernetes/install.md diff --git a/app/enterprise/1.3-x/kong-for-kubernetes/using-kong-for-kubernetes.md b/archive/enterprise/1.3-x/kong-for-kubernetes/using-kong-for-kubernetes.md similarity index 100% rename from app/enterprise/1.3-x/kong-for-kubernetes/using-kong-for-kubernetes.md rename to archive/enterprise/1.3-x/kong-for-kubernetes/using-kong-for-kubernetes.md diff --git a/app/enterprise/1.3-x/kong-manager/administration/admins/invite.md b/archive/enterprise/1.3-x/kong-manager/administration/admins/invite.md similarity index 100% rename from app/enterprise/1.3-x/kong-manager/administration/admins/invite.md rename to archive/enterprise/1.3-x/kong-manager/administration/admins/invite.md diff --git a/app/enterprise/1.3-x/kong-manager/administration/rbac/add-user.md b/archive/enterprise/1.3-x/kong-manager/administration/rbac/add-user.md similarity index 100% rename from app/enterprise/1.3-x/kong-manager/administration/rbac/add-user.md rename to archive/enterprise/1.3-x/kong-manager/administration/rbac/add-user.md diff --git a/app/enterprise/1.3-x/kong-manager/administration/rbac/index.md b/archive/enterprise/1.3-x/kong-manager/administration/rbac/index.md similarity index 100% rename from app/enterprise/1.3-x/kong-manager/administration/rbac/index.md rename to archive/enterprise/1.3-x/kong-manager/administration/rbac/index.md diff --git a/app/enterprise/1.3-x/kong-manager/administration/rbac/new-role.md b/archive/enterprise/1.3-x/kong-manager/administration/rbac/new-role.md similarity index 100% rename from app/enterprise/1.3-x/kong-manager/administration/rbac/new-role.md rename to archive/enterprise/1.3-x/kong-manager/administration/rbac/new-role.md diff --git a/app/enterprise/1.3-x/kong-manager/administration/rbac/rbac.md b/archive/enterprise/1.3-x/kong-manager/administration/rbac/rbac.md similarity index 100% rename from app/enterprise/1.3-x/kong-manager/administration/rbac/rbac.md rename to archive/enterprise/1.3-x/kong-manager/administration/rbac/rbac.md diff --git a/app/enterprise/1.3-x/kong-manager/administration/workspaces/create-workspace.md b/archive/enterprise/1.3-x/kong-manager/administration/workspaces/create-workspace.md similarity index 100% rename from app/enterprise/1.3-x/kong-manager/administration/workspaces/create-workspace.md rename to archive/enterprise/1.3-x/kong-manager/administration/workspaces/create-workspace.md diff --git a/app/enterprise/1.3-x/kong-manager/administration/workspaces/update-workspace.md b/archive/enterprise/1.3-x/kong-manager/administration/workspaces/update-workspace.md similarity index 100% rename from app/enterprise/1.3-x/kong-manager/administration/workspaces/update-workspace.md rename to archive/enterprise/1.3-x/kong-manager/administration/workspaces/update-workspace.md diff --git a/app/enterprise/1.3-x/kong-manager/administration/workspaces/workspaces.md b/archive/enterprise/1.3-x/kong-manager/administration/workspaces/workspaces.md similarity index 100% rename from app/enterprise/1.3-x/kong-manager/administration/workspaces/workspaces.md rename to archive/enterprise/1.3-x/kong-manager/administration/workspaces/workspaces.md diff --git a/app/enterprise/1.3-x/kong-manager/authentication/basic.md b/archive/enterprise/1.3-x/kong-manager/authentication/basic.md similarity index 100% rename from app/enterprise/1.3-x/kong-manager/authentication/basic.md rename to archive/enterprise/1.3-x/kong-manager/authentication/basic.md diff --git a/app/enterprise/1.3-x/kong-manager/authentication/ldap.md b/archive/enterprise/1.3-x/kong-manager/authentication/ldap.md similarity index 100% rename from app/enterprise/1.3-x/kong-manager/authentication/ldap.md rename to archive/enterprise/1.3-x/kong-manager/authentication/ldap.md diff --git a/app/enterprise/1.3-x/kong-manager/authentication/oidc.md b/archive/enterprise/1.3-x/kong-manager/authentication/oidc.md similarity index 100% rename from app/enterprise/1.3-x/kong-manager/authentication/oidc.md rename to archive/enterprise/1.3-x/kong-manager/authentication/oidc.md diff --git a/app/enterprise/1.3-x/kong-manager/authentication/sessions.md b/archive/enterprise/1.3-x/kong-manager/authentication/sessions.md similarity index 100% rename from app/enterprise/1.3-x/kong-manager/authentication/sessions.md rename to archive/enterprise/1.3-x/kong-manager/authentication/sessions.md diff --git a/app/enterprise/1.3-x/kong-manager/authentication/super-admin.md b/archive/enterprise/1.3-x/kong-manager/authentication/super-admin.md similarity index 100% rename from app/enterprise/1.3-x/kong-manager/authentication/super-admin.md rename to archive/enterprise/1.3-x/kong-manager/authentication/super-admin.md diff --git a/app/enterprise/1.3-x/kong-manager/best-practices.md b/archive/enterprise/1.3-x/kong-manager/best-practices.md similarity index 100% rename from app/enterprise/1.3-x/kong-manager/best-practices.md rename to archive/enterprise/1.3-x/kong-manager/best-practices.md diff --git a/app/enterprise/1.3-x/kong-manager/faq.md b/archive/enterprise/1.3-x/kong-manager/faq.md similarity index 100% rename from app/enterprise/1.3-x/kong-manager/faq.md rename to archive/enterprise/1.3-x/kong-manager/faq.md diff --git a/app/enterprise/1.3-x/kong-manager/networking/configuration.md b/archive/enterprise/1.3-x/kong-manager/networking/configuration.md similarity index 100% rename from app/enterprise/1.3-x/kong-manager/networking/configuration.md rename to archive/enterprise/1.3-x/kong-manager/networking/configuration.md diff --git a/app/enterprise/1.3-x/kong-manager/networking/email.md b/archive/enterprise/1.3-x/kong-manager/networking/email.md similarity index 100% rename from app/enterprise/1.3-x/kong-manager/networking/email.md rename to archive/enterprise/1.3-x/kong-manager/networking/email.md diff --git a/app/enterprise/1.3-x/kong-manager/overview.md b/archive/enterprise/1.3-x/kong-manager/overview.md similarity index 100% rename from app/enterprise/1.3-x/kong-manager/overview.md rename to archive/enterprise/1.3-x/kong-manager/overview.md diff --git a/app/enterprise/1.3-x/kong-manager/reset-password.md b/archive/enterprise/1.3-x/kong-manager/reset-password.md similarity index 100% rename from app/enterprise/1.3-x/kong-manager/reset-password.md rename to archive/enterprise/1.3-x/kong-manager/reset-password.md diff --git a/app/enterprise/1.3-x/kong-manager/security.md b/archive/enterprise/1.3-x/kong-manager/security.md similarity index 100% rename from app/enterprise/1.3-x/kong-manager/security.md rename to archive/enterprise/1.3-x/kong-manager/security.md diff --git a/app/enterprise/1.3-x/kong-manager/service-directory-mapping.md b/archive/enterprise/1.3-x/kong-manager/service-directory-mapping.md similarity index 100% rename from app/enterprise/1.3-x/kong-manager/service-directory-mapping.md rename to archive/enterprise/1.3-x/kong-manager/service-directory-mapping.md diff --git a/app/enterprise/1.3-x/kong-manager/vitals.md b/archive/enterprise/1.3-x/kong-manager/vitals.md similarity index 100% rename from app/enterprise/1.3-x/kong-manager/vitals.md rename to archive/enterprise/1.3-x/kong-manager/vitals.md diff --git a/app/enterprise/1.3-x/loadbalancing.md b/archive/enterprise/1.3-x/loadbalancing.md similarity index 100% rename from app/enterprise/1.3-x/loadbalancing.md rename to archive/enterprise/1.3-x/loadbalancing.md diff --git a/app/enterprise/1.3-x/logging.md b/archive/enterprise/1.3-x/logging.md similarity index 100% rename from app/enterprise/1.3-x/logging.md rename to archive/enterprise/1.3-x/logging.md diff --git a/app/enterprise/1.3-x/network.md b/archive/enterprise/1.3-x/network.md similarity index 100% rename from app/enterprise/1.3-x/network.md rename to archive/enterprise/1.3-x/network.md diff --git a/app/enterprise/1.3-x/pdk/index.md b/archive/enterprise/1.3-x/pdk/index.md similarity index 100% rename from app/enterprise/1.3-x/pdk/index.md rename to archive/enterprise/1.3-x/pdk/index.md diff --git a/app/enterprise/1.3-x/pdk/kong.client.md b/archive/enterprise/1.3-x/pdk/kong.client.md similarity index 100% rename from app/enterprise/1.3-x/pdk/kong.client.md rename to archive/enterprise/1.3-x/pdk/kong.client.md diff --git a/app/enterprise/1.3-x/pdk/kong.ctx.md b/archive/enterprise/1.3-x/pdk/kong.ctx.md similarity index 100% rename from app/enterprise/1.3-x/pdk/kong.ctx.md rename to archive/enterprise/1.3-x/pdk/kong.ctx.md diff --git a/app/enterprise/1.3-x/pdk/kong.ip.md b/archive/enterprise/1.3-x/pdk/kong.ip.md similarity index 100% rename from app/enterprise/1.3-x/pdk/kong.ip.md rename to archive/enterprise/1.3-x/pdk/kong.ip.md diff --git a/app/enterprise/1.3-x/pdk/kong.log.md b/archive/enterprise/1.3-x/pdk/kong.log.md similarity index 100% rename from app/enterprise/1.3-x/pdk/kong.log.md rename to archive/enterprise/1.3-x/pdk/kong.log.md diff --git a/app/enterprise/1.3-x/pdk/kong.node.md b/archive/enterprise/1.3-x/pdk/kong.node.md similarity index 100% rename from app/enterprise/1.3-x/pdk/kong.node.md rename to archive/enterprise/1.3-x/pdk/kong.node.md diff --git a/app/enterprise/1.3-x/pdk/kong.request.md b/archive/enterprise/1.3-x/pdk/kong.request.md similarity index 100% rename from app/enterprise/1.3-x/pdk/kong.request.md rename to archive/enterprise/1.3-x/pdk/kong.request.md diff --git a/app/enterprise/1.3-x/pdk/kong.response.md b/archive/enterprise/1.3-x/pdk/kong.response.md similarity index 100% rename from app/enterprise/1.3-x/pdk/kong.response.md rename to archive/enterprise/1.3-x/pdk/kong.response.md diff --git a/app/enterprise/1.3-x/pdk/kong.router.md b/archive/enterprise/1.3-x/pdk/kong.router.md similarity index 100% rename from app/enterprise/1.3-x/pdk/kong.router.md rename to archive/enterprise/1.3-x/pdk/kong.router.md diff --git a/app/enterprise/1.3-x/pdk/kong.service.md b/archive/enterprise/1.3-x/pdk/kong.service.md similarity index 100% rename from app/enterprise/1.3-x/pdk/kong.service.md rename to archive/enterprise/1.3-x/pdk/kong.service.md diff --git a/app/enterprise/1.3-x/pdk/kong.service.request.md b/archive/enterprise/1.3-x/pdk/kong.service.request.md similarity index 100% rename from app/enterprise/1.3-x/pdk/kong.service.request.md rename to archive/enterprise/1.3-x/pdk/kong.service.request.md diff --git a/app/enterprise/1.3-x/pdk/kong.service.response.md b/archive/enterprise/1.3-x/pdk/kong.service.response.md similarity index 100% rename from app/enterprise/1.3-x/pdk/kong.service.response.md rename to archive/enterprise/1.3-x/pdk/kong.service.response.md diff --git a/app/enterprise/1.3-x/pdk/kong.table.md b/archive/enterprise/1.3-x/pdk/kong.table.md similarity index 100% rename from app/enterprise/1.3-x/pdk/kong.table.md rename to archive/enterprise/1.3-x/pdk/kong.table.md diff --git a/app/enterprise/1.3-x/plugin-development/access-the-datastore.md b/archive/enterprise/1.3-x/plugin-development/access-the-datastore.md similarity index 100% rename from app/enterprise/1.3-x/plugin-development/access-the-datastore.md rename to archive/enterprise/1.3-x/plugin-development/access-the-datastore.md diff --git a/app/enterprise/1.3-x/plugin-development/admin-api.md b/archive/enterprise/1.3-x/plugin-development/admin-api.md similarity index 100% rename from app/enterprise/1.3-x/plugin-development/admin-api.md rename to archive/enterprise/1.3-x/plugin-development/admin-api.md diff --git a/app/enterprise/1.3-x/plugin-development/custom-entities.md b/archive/enterprise/1.3-x/plugin-development/custom-entities.md similarity index 100% rename from app/enterprise/1.3-x/plugin-development/custom-entities.md rename to archive/enterprise/1.3-x/plugin-development/custom-entities.md diff --git a/app/enterprise/1.3-x/plugin-development/custom-logic.md b/archive/enterprise/1.3-x/plugin-development/custom-logic.md similarity index 100% rename from app/enterprise/1.3-x/plugin-development/custom-logic.md rename to archive/enterprise/1.3-x/plugin-development/custom-logic.md diff --git a/app/enterprise/1.3-x/plugin-development/distribution.md b/archive/enterprise/1.3-x/plugin-development/distribution.md similarity index 100% rename from app/enterprise/1.3-x/plugin-development/distribution.md rename to archive/enterprise/1.3-x/plugin-development/distribution.md diff --git a/app/enterprise/1.3-x/plugin-development/entities-cache.md b/archive/enterprise/1.3-x/plugin-development/entities-cache.md similarity index 100% rename from app/enterprise/1.3-x/plugin-development/entities-cache.md rename to archive/enterprise/1.3-x/plugin-development/entities-cache.md diff --git a/app/enterprise/1.3-x/plugin-development/file-structure.md b/archive/enterprise/1.3-x/plugin-development/file-structure.md similarity index 100% rename from app/enterprise/1.3-x/plugin-development/file-structure.md rename to archive/enterprise/1.3-x/plugin-development/file-structure.md diff --git a/app/enterprise/1.3-x/plugin-development/index.md b/archive/enterprise/1.3-x/plugin-development/index.md similarity index 100% rename from app/enterprise/1.3-x/plugin-development/index.md rename to archive/enterprise/1.3-x/plugin-development/index.md diff --git a/app/enterprise/1.3-x/plugin-development/plugin-configuration.md b/archive/enterprise/1.3-x/plugin-development/plugin-configuration.md similarity index 100% rename from app/enterprise/1.3-x/plugin-development/plugin-configuration.md rename to archive/enterprise/1.3-x/plugin-development/plugin-configuration.md diff --git a/app/enterprise/1.3-x/plugin-development/tests.md b/archive/enterprise/1.3-x/plugin-development/tests.md similarity index 100% rename from app/enterprise/1.3-x/plugin-development/tests.md rename to archive/enterprise/1.3-x/plugin-development/tests.md diff --git a/app/enterprise/1.3-x/plugins/allowing-multiple-authentication-methods.md b/archive/enterprise/1.3-x/plugins/allowing-multiple-authentication-methods.md similarity index 100% rename from app/enterprise/1.3-x/plugins/allowing-multiple-authentication-methods.md rename to archive/enterprise/1.3-x/plugins/allowing-multiple-authentication-methods.md diff --git a/app/enterprise/1.3-x/plugins/canary-release.md b/archive/enterprise/1.3-x/plugins/canary-release.md similarity index 100% rename from app/enterprise/1.3-x/plugins/canary-release.md rename to archive/enterprise/1.3-x/plugins/canary-release.md diff --git a/app/enterprise/1.3-x/plugins/degraphql.md b/archive/enterprise/1.3-x/plugins/degraphql.md similarity index 100% rename from app/enterprise/1.3-x/plugins/degraphql.md rename to archive/enterprise/1.3-x/plugins/degraphql.md diff --git a/app/enterprise/1.3-x/plugins/exit-transformer.md b/archive/enterprise/1.3-x/plugins/exit-transformer.md similarity index 100% rename from app/enterprise/1.3-x/plugins/exit-transformer.md rename to archive/enterprise/1.3-x/plugins/exit-transformer.md diff --git a/app/enterprise/1.3-x/plugins/forward-proxy.md b/archive/enterprise/1.3-x/plugins/forward-proxy.md similarity index 100% rename from app/enterprise/1.3-x/plugins/forward-proxy.md rename to archive/enterprise/1.3-x/plugins/forward-proxy.md diff --git a/app/enterprise/1.3-x/plugins/graphql-proxy-cache-advanced.md b/archive/enterprise/1.3-x/plugins/graphql-proxy-cache-advanced.md similarity index 100% rename from app/enterprise/1.3-x/plugins/graphql-proxy-cache-advanced.md rename to archive/enterprise/1.3-x/plugins/graphql-proxy-cache-advanced.md diff --git a/app/enterprise/1.3-x/plugins/graphql-quickstart.md b/archive/enterprise/1.3-x/plugins/graphql-quickstart.md similarity index 100% rename from app/enterprise/1.3-x/plugins/graphql-quickstart.md rename to archive/enterprise/1.3-x/plugins/graphql-quickstart.md diff --git a/app/enterprise/1.3-x/plugins/graphql-rate-limiting-advanced.md b/archive/enterprise/1.3-x/plugins/graphql-rate-limiting-advanced.md similarity index 100% rename from app/enterprise/1.3-x/plugins/graphql-rate-limiting-advanced.md rename to archive/enterprise/1.3-x/plugins/graphql-rate-limiting-advanced.md diff --git a/app/enterprise/1.3-x/plugins/http-proxy-caching.md b/archive/enterprise/1.3-x/plugins/http-proxy-caching.md similarity index 100% rename from app/enterprise/1.3-x/plugins/http-proxy-caching.md rename to archive/enterprise/1.3-x/plugins/http-proxy-caching.md diff --git a/app/enterprise/1.3-x/plugins/index.md b/archive/enterprise/1.3-x/plugins/index.md similarity index 100% rename from app/enterprise/1.3-x/plugins/index.md rename to archive/enterprise/1.3-x/plugins/index.md diff --git a/app/enterprise/1.3-x/plugins/jwt-signer.md b/archive/enterprise/1.3-x/plugins/jwt-signer.md similarity index 100% rename from app/enterprise/1.3-x/plugins/jwt-signer.md rename to archive/enterprise/1.3-x/plugins/jwt-signer.md diff --git a/app/enterprise/1.3-x/plugins/kafka-log.md b/archive/enterprise/1.3-x/plugins/kafka-log.md similarity index 100% rename from app/enterprise/1.3-x/plugins/kafka-log.md rename to archive/enterprise/1.3-x/plugins/kafka-log.md diff --git a/app/enterprise/1.3-x/plugins/kafka-upstream.md b/archive/enterprise/1.3-x/plugins/kafka-upstream.md similarity index 100% rename from app/enterprise/1.3-x/plugins/kafka-upstream.md rename to archive/enterprise/1.3-x/plugins/kafka-upstream.md diff --git a/app/enterprise/1.3-x/plugins/key-auth-enc.md b/archive/enterprise/1.3-x/plugins/key-auth-enc.md similarity index 100% rename from app/enterprise/1.3-x/plugins/key-auth-enc.md rename to archive/enterprise/1.3-x/plugins/key-auth-enc.md diff --git a/app/enterprise/1.3-x/plugins/ldap-authentication-advanced.md b/archive/enterprise/1.3-x/plugins/ldap-authentication-advanced.md similarity index 100% rename from app/enterprise/1.3-x/plugins/ldap-authentication-advanced.md rename to archive/enterprise/1.3-x/plugins/ldap-authentication-advanced.md diff --git a/app/enterprise/1.3-x/plugins/oauth2-introspection.md b/archive/enterprise/1.3-x/plugins/oauth2-introspection.md similarity index 100% rename from app/enterprise/1.3-x/plugins/oauth2-introspection.md rename to archive/enterprise/1.3-x/plugins/oauth2-introspection.md diff --git a/app/enterprise/1.3-x/plugins/oidc-auth0.md b/archive/enterprise/1.3-x/plugins/oidc-auth0.md similarity index 100% rename from app/enterprise/1.3-x/plugins/oidc-auth0.md rename to archive/enterprise/1.3-x/plugins/oidc-auth0.md diff --git a/app/enterprise/1.3-x/plugins/oidc-azuread.md b/archive/enterprise/1.3-x/plugins/oidc-azuread.md similarity index 100% rename from app/enterprise/1.3-x/plugins/oidc-azuread.md rename to archive/enterprise/1.3-x/plugins/oidc-azuread.md diff --git a/app/enterprise/1.3-x/plugins/oidc-cognito.md b/archive/enterprise/1.3-x/plugins/oidc-cognito.md similarity index 100% rename from app/enterprise/1.3-x/plugins/oidc-cognito.md rename to archive/enterprise/1.3-x/plugins/oidc-cognito.md diff --git a/app/enterprise/1.3-x/plugins/oidc-google.md b/archive/enterprise/1.3-x/plugins/oidc-google.md similarity index 100% rename from app/enterprise/1.3-x/plugins/oidc-google.md rename to archive/enterprise/1.3-x/plugins/oidc-google.md diff --git a/app/enterprise/1.3-x/plugins/oidc-okta.md b/archive/enterprise/1.3-x/plugins/oidc-okta.md similarity index 100% rename from app/enterprise/1.3-x/plugins/oidc-okta.md rename to archive/enterprise/1.3-x/plugins/oidc-okta.md diff --git a/app/enterprise/1.3-x/plugins/oidc-use-case.md b/archive/enterprise/1.3-x/plugins/oidc-use-case.md similarity index 100% rename from app/enterprise/1.3-x/plugins/oidc-use-case.md rename to archive/enterprise/1.3-x/plugins/oidc-use-case.md diff --git a/app/enterprise/1.3-x/plugins/openid-connect.md b/archive/enterprise/1.3-x/plugins/openid-connect.md similarity index 100% rename from app/enterprise/1.3-x/plugins/openid-connect.md rename to archive/enterprise/1.3-x/plugins/openid-connect.md diff --git a/app/enterprise/1.3-x/plugins/proxy-cache-advanced.md b/archive/enterprise/1.3-x/plugins/proxy-cache-advanced.md similarity index 100% rename from app/enterprise/1.3-x/plugins/proxy-cache-advanced.md rename to archive/enterprise/1.3-x/plugins/proxy-cache-advanced.md diff --git a/app/enterprise/1.3-x/plugins/rate-limiting-advanced.md b/archive/enterprise/1.3-x/plugins/rate-limiting-advanced.md similarity index 100% rename from app/enterprise/1.3-x/plugins/rate-limiting-advanced.md rename to archive/enterprise/1.3-x/plugins/rate-limiting-advanced.md diff --git a/app/enterprise/1.3-x/plugins/request-transformer.md b/archive/enterprise/1.3-x/plugins/request-transformer.md similarity index 100% rename from app/enterprise/1.3-x/plugins/request-transformer.md rename to archive/enterprise/1.3-x/plugins/request-transformer.md diff --git a/app/enterprise/1.3-x/plugins/request-validator.md b/archive/enterprise/1.3-x/plugins/request-validator.md similarity index 100% rename from app/enterprise/1.3-x/plugins/request-validator.md rename to archive/enterprise/1.3-x/plugins/request-validator.md diff --git a/app/enterprise/1.3-x/plugins/response-transformer-advanced.md b/archive/enterprise/1.3-x/plugins/response-transformer-advanced.md similarity index 100% rename from app/enterprise/1.3-x/plugins/response-transformer-advanced.md rename to archive/enterprise/1.3-x/plugins/response-transformer-advanced.md diff --git a/app/enterprise/1.3-x/plugins/route-by-header.md b/archive/enterprise/1.3-x/plugins/route-by-header.md similarity index 100% rename from app/enterprise/1.3-x/plugins/route-by-header.md rename to archive/enterprise/1.3-x/plugins/route-by-header.md diff --git a/app/enterprise/1.3-x/plugins/route-by-headers.md b/archive/enterprise/1.3-x/plugins/route-by-headers.md similarity index 100% rename from app/enterprise/1.3-x/plugins/route-by-headers.md rename to archive/enterprise/1.3-x/plugins/route-by-headers.md diff --git a/app/enterprise/1.3-x/plugins/route-transformer-advanced.md b/archive/enterprise/1.3-x/plugins/route-transformer-advanced.md similarity index 100% rename from app/enterprise/1.3-x/plugins/route-transformer-advanced.md rename to archive/enterprise/1.3-x/plugins/route-transformer-advanced.md diff --git a/app/enterprise/1.3-x/plugins/session.md b/archive/enterprise/1.3-x/plugins/session.md similarity index 100% rename from app/enterprise/1.3-x/plugins/session.md rename to archive/enterprise/1.3-x/plugins/session.md diff --git a/app/enterprise/1.3-x/plugins/statsd-advanced.md b/archive/enterprise/1.3-x/plugins/statsd-advanced.md similarity index 100% rename from app/enterprise/1.3-x/plugins/statsd-advanced.md rename to archive/enterprise/1.3-x/plugins/statsd-advanced.md diff --git a/app/enterprise/1.3-x/plugins/statsd.rules.yaml b/archive/enterprise/1.3-x/plugins/statsd.rules.yaml similarity index 100% rename from app/enterprise/1.3-x/plugins/statsd.rules.yaml rename to archive/enterprise/1.3-x/plugins/statsd.rules.yaml diff --git a/app/enterprise/1.3-x/plugins/vault-auth.md b/archive/enterprise/1.3-x/plugins/vault-auth.md similarity index 100% rename from app/enterprise/1.3-x/plugins/vault-auth.md rename to archive/enterprise/1.3-x/plugins/vault-auth.md diff --git a/app/enterprise/1.3-x/property-reference.md b/archive/enterprise/1.3-x/property-reference.md similarity index 100% rename from app/enterprise/1.3-x/property-reference.md rename to archive/enterprise/1.3-x/property-reference.md diff --git a/app/enterprise/1.3-x/proxy.md b/archive/enterprise/1.3-x/proxy.md similarity index 100% rename from app/enterprise/1.3-x/proxy.md rename to archive/enterprise/1.3-x/proxy.md diff --git a/app/enterprise/1.3-x/secure-admin-api.md b/archive/enterprise/1.3-x/secure-admin-api.md similarity index 100% rename from app/enterprise/1.3-x/secure-admin-api.md rename to archive/enterprise/1.3-x/secure-admin-api.md diff --git a/app/enterprise/1.3-x/sizing-guidelines.md b/archive/enterprise/1.3-x/sizing-guidelines.md similarity index 100% rename from app/enterprise/1.3-x/sizing-guidelines.md rename to archive/enterprise/1.3-x/sizing-guidelines.md diff --git a/app/enterprise/1.3-x/systemd.md b/archive/enterprise/1.3-x/systemd.md similarity index 100% rename from app/enterprise/1.3-x/systemd.md rename to archive/enterprise/1.3-x/systemd.md diff --git a/app/enterprise/1.3-x/whats-new.md b/archive/enterprise/1.3-x/whats-new.md similarity index 100% rename from app/enterprise/1.3-x/whats-new.md rename to archive/enterprise/1.3-x/whats-new.md diff --git a/app/enterprise/1.5.x/admin-api/admins/examples.md b/archive/enterprise/1.5.x/admin-api/admins/examples.md similarity index 100% rename from app/enterprise/1.5.x/admin-api/admins/examples.md rename to archive/enterprise/1.5.x/admin-api/admins/examples.md diff --git a/app/enterprise/1.5.x/admin-api/admins/reference.md b/archive/enterprise/1.5.x/admin-api/admins/reference.md similarity index 100% rename from app/enterprise/1.5.x/admin-api/admins/reference.md rename to archive/enterprise/1.5.x/admin-api/admins/reference.md diff --git a/app/enterprise/1.5.x/admin-api/audit-log.md b/archive/enterprise/1.5.x/admin-api/audit-log.md similarity index 100% rename from app/enterprise/1.5.x/admin-api/audit-log.md rename to archive/enterprise/1.5.x/admin-api/audit-log.md diff --git a/app/enterprise/1.5.x/admin-api/db-encryption.md b/archive/enterprise/1.5.x/admin-api/db-encryption.md similarity index 100% rename from app/enterprise/1.5.x/admin-api/db-encryption.md rename to archive/enterprise/1.5.x/admin-api/db-encryption.md diff --git a/app/enterprise/1.5.x/admin-api/index.md b/archive/enterprise/1.5.x/admin-api/index.md similarity index 100% rename from app/enterprise/1.5.x/admin-api/index.md rename to archive/enterprise/1.5.x/admin-api/index.md diff --git a/app/enterprise/1.5.x/admin-api/rbac/examples.md b/archive/enterprise/1.5.x/admin-api/rbac/examples.md similarity index 100% rename from app/enterprise/1.5.x/admin-api/rbac/examples.md rename to archive/enterprise/1.5.x/admin-api/rbac/examples.md diff --git a/app/enterprise/1.5.x/admin-api/rbac/reference.md b/archive/enterprise/1.5.x/admin-api/rbac/reference.md similarity index 100% rename from app/enterprise/1.5.x/admin-api/rbac/reference.md rename to archive/enterprise/1.5.x/admin-api/rbac/reference.md diff --git a/app/enterprise/1.5.x/admin-api/vitals/index.md b/archive/enterprise/1.5.x/admin-api/vitals/index.md similarity index 100% rename from app/enterprise/1.5.x/admin-api/vitals/index.md rename to archive/enterprise/1.5.x/admin-api/vitals/index.md diff --git a/app/enterprise/1.5.x/admin-api/vitals/vitals-influx-strategy.md b/archive/enterprise/1.5.x/admin-api/vitals/vitals-influx-strategy.md similarity index 100% rename from app/enterprise/1.5.x/admin-api/vitals/vitals-influx-strategy.md rename to archive/enterprise/1.5.x/admin-api/vitals/vitals-influx-strategy.md diff --git a/app/enterprise/1.5.x/admin-api/vitals/vitals-prometheus-strategy.md b/archive/enterprise/1.5.x/admin-api/vitals/vitals-prometheus-strategy.md similarity index 100% rename from app/enterprise/1.5.x/admin-api/vitals/vitals-prometheus-strategy.md rename to archive/enterprise/1.5.x/admin-api/vitals/vitals-prometheus-strategy.md diff --git a/app/enterprise/1.5.x/admin-api/vitals/vitalsSpec.yaml b/archive/enterprise/1.5.x/admin-api/vitals/vitalsSpec.yaml similarity index 100% rename from app/enterprise/1.5.x/admin-api/vitals/vitalsSpec.yaml rename to archive/enterprise/1.5.x/admin-api/vitals/vitalsSpec.yaml diff --git a/app/enterprise/1.5.x/admin-api/workspaces/examples.md b/archive/enterprise/1.5.x/admin-api/workspaces/examples.md similarity index 100% rename from app/enterprise/1.5.x/admin-api/workspaces/examples.md rename to archive/enterprise/1.5.x/admin-api/workspaces/examples.md diff --git a/app/enterprise/1.5.x/admin-api/workspaces/reference.md b/archive/enterprise/1.5.x/admin-api/workspaces/reference.md similarity index 100% rename from app/enterprise/1.5.x/admin-api/workspaces/reference.md rename to archive/enterprise/1.5.x/admin-api/workspaces/reference.md diff --git a/app/enterprise/1.5.x/auth.md b/archive/enterprise/1.5.x/auth.md similarity index 100% rename from app/enterprise/1.5.x/auth.md rename to archive/enterprise/1.5.x/auth.md diff --git a/app/enterprise/1.5.x/cli.md b/archive/enterprise/1.5.x/cli.md similarity index 100% rename from app/enterprise/1.5.x/cli.md rename to archive/enterprise/1.5.x/cli.md diff --git a/app/enterprise/1.5.x/clustering.md b/archive/enterprise/1.5.x/clustering.md similarity index 100% rename from app/enterprise/1.5.x/clustering.md rename to archive/enterprise/1.5.x/clustering.md diff --git a/app/enterprise/1.5.x/compatibility.md b/archive/enterprise/1.5.x/compatibility.md similarity index 100% rename from app/enterprise/1.5.x/compatibility.md rename to archive/enterprise/1.5.x/compatibility.md diff --git a/app/enterprise/1.5.x/db-encryption.md b/archive/enterprise/1.5.x/db-encryption.md similarity index 100% rename from app/enterprise/1.5.x/db-encryption.md rename to archive/enterprise/1.5.x/db-encryption.md diff --git a/app/enterprise/1.5.x/deployment/access-license.md b/archive/enterprise/1.5.x/deployment/access-license.md similarity index 100% rename from app/enterprise/1.5.x/deployment/access-license.md rename to archive/enterprise/1.5.x/deployment/access-license.md diff --git a/app/enterprise/1.5.x/deployment/default-ports.md b/archive/enterprise/1.5.x/deployment/default-ports.md similarity index 100% rename from app/enterprise/1.5.x/deployment/default-ports.md rename to archive/enterprise/1.5.x/deployment/default-ports.md diff --git a/app/enterprise/1.5.x/deployment/dns-considerations.md b/archive/enterprise/1.5.x/deployment/dns-considerations.md similarity index 100% rename from app/enterprise/1.5.x/deployment/dns-considerations.md rename to archive/enterprise/1.5.x/deployment/dns-considerations.md diff --git a/app/enterprise/1.5.x/deployment/installation/amazon-linux-2.md b/archive/enterprise/1.5.x/deployment/installation/amazon-linux-2.md similarity index 100% rename from app/enterprise/1.5.x/deployment/installation/amazon-linux-2.md rename to archive/enterprise/1.5.x/deployment/installation/amazon-linux-2.md diff --git a/app/enterprise/1.5.x/deployment/installation/amazon-linux.md b/archive/enterprise/1.5.x/deployment/installation/amazon-linux.md similarity index 100% rename from app/enterprise/1.5.x/deployment/installation/amazon-linux.md rename to archive/enterprise/1.5.x/deployment/installation/amazon-linux.md diff --git a/app/enterprise/1.5.x/deployment/installation/centos.md b/archive/enterprise/1.5.x/deployment/installation/centos.md similarity index 100% rename from app/enterprise/1.5.x/deployment/installation/centos.md rename to archive/enterprise/1.5.x/deployment/installation/centos.md diff --git a/app/enterprise/1.5.x/deployment/installation/docker.md b/archive/enterprise/1.5.x/deployment/installation/docker.md similarity index 100% rename from app/enterprise/1.5.x/deployment/installation/docker.md rename to archive/enterprise/1.5.x/deployment/installation/docker.md diff --git a/app/enterprise/1.5.x/deployment/installation/index.md b/archive/enterprise/1.5.x/deployment/installation/index.md similarity index 100% rename from app/enterprise/1.5.x/deployment/installation/index.md rename to archive/enterprise/1.5.x/deployment/installation/index.md diff --git a/app/enterprise/1.5.x/deployment/installation/overview.md b/archive/enterprise/1.5.x/deployment/installation/overview.md similarity index 100% rename from app/enterprise/1.5.x/deployment/installation/overview.md rename to archive/enterprise/1.5.x/deployment/installation/overview.md diff --git a/app/enterprise/1.5.x/deployment/installation/rhel.md b/archive/enterprise/1.5.x/deployment/installation/rhel.md similarity index 100% rename from app/enterprise/1.5.x/deployment/installation/rhel.md rename to archive/enterprise/1.5.x/deployment/installation/rhel.md diff --git a/app/enterprise/1.5.x/deployment/installation/ubuntu.md b/archive/enterprise/1.5.x/deployment/installation/ubuntu.md similarity index 100% rename from app/enterprise/1.5.x/deployment/installation/ubuntu.md rename to archive/enterprise/1.5.x/deployment/installation/ubuntu.md diff --git a/app/enterprise/1.5.x/deployment/licenses/report.md b/archive/enterprise/1.5.x/deployment/licenses/report.md similarity index 100% rename from app/enterprise/1.5.x/deployment/licenses/report.md rename to archive/enterprise/1.5.x/deployment/licenses/report.md diff --git a/app/enterprise/1.5.x/deployment/licensing.md b/archive/enterprise/1.5.x/deployment/licensing.md similarity index 100% rename from app/enterprise/1.5.x/deployment/licensing.md rename to archive/enterprise/1.5.x/deployment/licensing.md diff --git a/app/enterprise/1.5.x/deployment/migrations.md b/archive/enterprise/1.5.x/deployment/migrations.md similarity index 100% rename from app/enterprise/1.5.x/deployment/migrations.md rename to archive/enterprise/1.5.x/deployment/migrations.md diff --git a/app/enterprise/1.5.x/developer-portal/administration/application-registration.md b/archive/enterprise/1.5.x/developer-portal/administration/application-registration.md similarity index 100% rename from app/enterprise/1.5.x/developer-portal/administration/application-registration.md rename to archive/enterprise/1.5.x/developer-portal/administration/application-registration.md diff --git a/app/enterprise/1.5.x/developer-portal/administration/developer-permissions.md b/archive/enterprise/1.5.x/developer-portal/administration/developer-permissions.md similarity index 100% rename from app/enterprise/1.5.x/developer-portal/administration/developer-permissions.md rename to archive/enterprise/1.5.x/developer-portal/administration/developer-permissions.md diff --git a/app/enterprise/1.5.x/developer-portal/administration/index.md b/archive/enterprise/1.5.x/developer-portal/administration/index.md similarity index 100% rename from app/enterprise/1.5.x/developer-portal/administration/index.md rename to archive/enterprise/1.5.x/developer-portal/administration/index.md diff --git a/app/enterprise/1.5.x/developer-portal/administration/managing-developers.md b/archive/enterprise/1.5.x/developer-portal/administration/managing-developers.md similarity index 100% rename from app/enterprise/1.5.x/developer-portal/administration/managing-developers.md rename to archive/enterprise/1.5.x/developer-portal/administration/managing-developers.md diff --git a/app/enterprise/1.5.x/developer-portal/configuration/authentication/adding-registration-fields.md b/archive/enterprise/1.5.x/developer-portal/configuration/authentication/adding-registration-fields.md similarity index 100% rename from app/enterprise/1.5.x/developer-portal/configuration/authentication/adding-registration-fields.md rename to archive/enterprise/1.5.x/developer-portal/configuration/authentication/adding-registration-fields.md diff --git a/app/enterprise/1.5.x/developer-portal/configuration/authentication/basic-auth.md b/archive/enterprise/1.5.x/developer-portal/configuration/authentication/basic-auth.md similarity index 100% rename from app/enterprise/1.5.x/developer-portal/configuration/authentication/basic-auth.md rename to archive/enterprise/1.5.x/developer-portal/configuration/authentication/basic-auth.md diff --git a/app/enterprise/1.5.x/developer-portal/configuration/authentication/index.md b/archive/enterprise/1.5.x/developer-portal/configuration/authentication/index.md similarity index 100% rename from app/enterprise/1.5.x/developer-portal/configuration/authentication/index.md rename to archive/enterprise/1.5.x/developer-portal/configuration/authentication/index.md diff --git a/app/enterprise/1.5.x/developer-portal/configuration/authentication/key-auth.md b/archive/enterprise/1.5.x/developer-portal/configuration/authentication/key-auth.md similarity index 100% rename from app/enterprise/1.5.x/developer-portal/configuration/authentication/key-auth.md rename to archive/enterprise/1.5.x/developer-portal/configuration/authentication/key-auth.md diff --git a/app/enterprise/1.5.x/developer-portal/configuration/authentication/oidc.md b/archive/enterprise/1.5.x/developer-portal/configuration/authentication/oidc.md similarity index 100% rename from app/enterprise/1.5.x/developer-portal/configuration/authentication/oidc.md rename to archive/enterprise/1.5.x/developer-portal/configuration/authentication/oidc.md diff --git a/app/enterprise/1.5.x/developer-portal/configuration/authentication/sessions.md b/archive/enterprise/1.5.x/developer-portal/configuration/authentication/sessions.md similarity index 100% rename from app/enterprise/1.5.x/developer-portal/configuration/authentication/sessions.md rename to archive/enterprise/1.5.x/developer-portal/configuration/authentication/sessions.md diff --git a/app/enterprise/1.5.x/developer-portal/configuration/index.md b/archive/enterprise/1.5.x/developer-portal/configuration/index.md similarity index 100% rename from app/enterprise/1.5.x/developer-portal/configuration/index.md rename to archive/enterprise/1.5.x/developer-portal/configuration/index.md diff --git a/app/enterprise/1.5.x/developer-portal/configuration/smtp.md b/archive/enterprise/1.5.x/developer-portal/configuration/smtp.md similarity index 100% rename from app/enterprise/1.5.x/developer-portal/configuration/smtp.md rename to archive/enterprise/1.5.x/developer-portal/configuration/smtp.md diff --git a/app/enterprise/1.5.x/developer-portal/configuration/workspaces.md b/archive/enterprise/1.5.x/developer-portal/configuration/workspaces.md similarity index 100% rename from app/enterprise/1.5.x/developer-portal/configuration/workspaces.md rename to archive/enterprise/1.5.x/developer-portal/configuration/workspaces.md diff --git a/app/enterprise/1.5.x/developer-portal/enable-dev-portal.md b/archive/enterprise/1.5.x/developer-portal/enable-dev-portal.md similarity index 100% rename from app/enterprise/1.5.x/developer-portal/enable-dev-portal.md rename to archive/enterprise/1.5.x/developer-portal/enable-dev-portal.md diff --git a/app/enterprise/1.5.x/developer-portal/files-api.md b/archive/enterprise/1.5.x/developer-portal/files-api.md similarity index 100% rename from app/enterprise/1.5.x/developer-portal/files-api.md rename to archive/enterprise/1.5.x/developer-portal/files-api.md diff --git a/app/enterprise/1.5.x/developer-portal/helpers/cli.md b/archive/enterprise/1.5.x/developer-portal/helpers/cli.md similarity index 100% rename from app/enterprise/1.5.x/developer-portal/helpers/cli.md rename to archive/enterprise/1.5.x/developer-portal/helpers/cli.md diff --git a/app/enterprise/1.5.x/developer-portal/index.md b/archive/enterprise/1.5.x/developer-portal/index.md similarity index 100% rename from app/enterprise/1.5.x/developer-portal/index.md rename to archive/enterprise/1.5.x/developer-portal/index.md diff --git a/app/enterprise/1.5.x/developer-portal/legacy-migration.md b/archive/enterprise/1.5.x/developer-portal/legacy-migration.md similarity index 100% rename from app/enterprise/1.5.x/developer-portal/legacy-migration.md rename to archive/enterprise/1.5.x/developer-portal/legacy-migration.md diff --git a/app/enterprise/1.5.x/developer-portal/migrating-to-1.5.md b/archive/enterprise/1.5.x/developer-portal/migrating-to-1.5.md similarity index 100% rename from app/enterprise/1.5.x/developer-portal/migrating-to-1.5.md rename to archive/enterprise/1.5.x/developer-portal/migrating-to-1.5.md diff --git a/app/enterprise/1.5.x/developer-portal/structure-and-file-types.md b/archive/enterprise/1.5.x/developer-portal/structure-and-file-types.md similarity index 100% rename from app/enterprise/1.5.x/developer-portal/structure-and-file-types.md rename to archive/enterprise/1.5.x/developer-portal/structure-and-file-types.md diff --git a/app/enterprise/1.5.x/developer-portal/theme-customization/adding-javascript-assets.md b/archive/enterprise/1.5.x/developer-portal/theme-customization/adding-javascript-assets.md similarity index 100% rename from app/enterprise/1.5.x/developer-portal/theme-customization/adding-javascript-assets.md rename to archive/enterprise/1.5.x/developer-portal/theme-customization/adding-javascript-assets.md diff --git a/app/enterprise/1.5.x/developer-portal/theme-customization/easy-theme-editing.md b/archive/enterprise/1.5.x/developer-portal/theme-customization/easy-theme-editing.md similarity index 100% rename from app/enterprise/1.5.x/developer-portal/theme-customization/easy-theme-editing.md rename to archive/enterprise/1.5.x/developer-portal/theme-customization/easy-theme-editing.md diff --git a/app/enterprise/1.5.x/developer-portal/theme-customization/emails.md b/archive/enterprise/1.5.x/developer-portal/theme-customization/emails.md similarity index 100% rename from app/enterprise/1.5.x/developer-portal/theme-customization/emails.md rename to archive/enterprise/1.5.x/developer-portal/theme-customization/emails.md diff --git a/app/enterprise/1.5.x/developer-portal/theme-customization/single-page-app.md b/archive/enterprise/1.5.x/developer-portal/theme-customization/single-page-app.md similarity index 100% rename from app/enterprise/1.5.x/developer-portal/theme-customization/single-page-app.md rename to archive/enterprise/1.5.x/developer-portal/theme-customization/single-page-app.md diff --git a/app/enterprise/1.5.x/developer-portal/using-the-editor.md b/archive/enterprise/1.5.x/developer-portal/using-the-editor.md similarity index 100% rename from app/enterprise/1.5.x/developer-portal/using-the-editor.md rename to archive/enterprise/1.5.x/developer-portal/using-the-editor.md diff --git a/app/enterprise/1.5.x/developer-portal/working-with-templates.md b/archive/enterprise/1.5.x/developer-portal/working-with-templates.md similarity index 100% rename from app/enterprise/1.5.x/developer-portal/working-with-templates.md rename to archive/enterprise/1.5.x/developer-portal/working-with-templates.md diff --git a/app/enterprise/1.5.x/health-checks-circuit-breakers.md b/archive/enterprise/1.5.x/health-checks-circuit-breakers.md similarity index 100% rename from app/enterprise/1.5.x/health-checks-circuit-breakers.md rename to archive/enterprise/1.5.x/health-checks-circuit-breakers.md diff --git a/app/enterprise/1.5.x/index.md b/archive/enterprise/1.5.x/index.md similarity index 100% rename from app/enterprise/1.5.x/index.md rename to archive/enterprise/1.5.x/index.md diff --git a/app/enterprise/1.5.x/introduction/index.md b/archive/enterprise/1.5.x/introduction/index.md similarity index 100% rename from app/enterprise/1.5.x/introduction/index.md rename to archive/enterprise/1.5.x/introduction/index.md diff --git a/app/enterprise/1.5.x/introduction/key-concepts.md b/archive/enterprise/1.5.x/introduction/key-concepts.md similarity index 100% rename from app/enterprise/1.5.x/introduction/key-concepts.md rename to archive/enterprise/1.5.x/introduction/key-concepts.md diff --git a/app/enterprise/1.5.x/kong-cloud.md b/archive/enterprise/1.5.x/kong-cloud.md similarity index 100% rename from app/enterprise/1.5.x/kong-cloud.md rename to archive/enterprise/1.5.x/kong-cloud.md diff --git a/app/enterprise/1.5.x/kong-for-kubernetes/changelog.md b/archive/enterprise/1.5.x/kong-for-kubernetes/changelog.md similarity index 100% rename from app/enterprise/1.5.x/kong-for-kubernetes/changelog.md rename to archive/enterprise/1.5.x/kong-for-kubernetes/changelog.md diff --git a/app/enterprise/1.5.x/kong-for-kubernetes/deployment-options.md b/archive/enterprise/1.5.x/kong-for-kubernetes/deployment-options.md similarity index 100% rename from app/enterprise/1.5.x/kong-for-kubernetes/deployment-options.md rename to archive/enterprise/1.5.x/kong-for-kubernetes/deployment-options.md diff --git a/app/enterprise/1.5.x/kong-for-kubernetes/index.md b/archive/enterprise/1.5.x/kong-for-kubernetes/index.md similarity index 100% rename from app/enterprise/1.5.x/kong-for-kubernetes/index.md rename to archive/enterprise/1.5.x/kong-for-kubernetes/index.md diff --git a/app/enterprise/1.5.x/kong-for-kubernetes/install-on-kubernetes.md b/archive/enterprise/1.5.x/kong-for-kubernetes/install-on-kubernetes.md similarity index 100% rename from app/enterprise/1.5.x/kong-for-kubernetes/install-on-kubernetes.md rename to archive/enterprise/1.5.x/kong-for-kubernetes/install-on-kubernetes.md diff --git a/app/enterprise/1.5.x/kong-for-kubernetes/install.md b/archive/enterprise/1.5.x/kong-for-kubernetes/install.md similarity index 100% rename from app/enterprise/1.5.x/kong-for-kubernetes/install.md rename to archive/enterprise/1.5.x/kong-for-kubernetes/install.md diff --git a/app/enterprise/1.5.x/kong-for-kubernetes/using-kong-for-kubernetes.md b/archive/enterprise/1.5.x/kong-for-kubernetes/using-kong-for-kubernetes.md similarity index 100% rename from app/enterprise/1.5.x/kong-for-kubernetes/using-kong-for-kubernetes.md rename to archive/enterprise/1.5.x/kong-for-kubernetes/using-kong-for-kubernetes.md diff --git a/app/enterprise/1.5.x/kong-manager/add-consumer.md b/archive/enterprise/1.5.x/kong-manager/add-consumer.md similarity index 100% rename from app/enterprise/1.5.x/kong-manager/add-consumer.md rename to archive/enterprise/1.5.x/kong-manager/add-consumer.md diff --git a/app/enterprise/1.5.x/kong-manager/add-service.md b/archive/enterprise/1.5.x/kong-manager/add-service.md similarity index 100% rename from app/enterprise/1.5.x/kong-manager/add-service.md rename to archive/enterprise/1.5.x/kong-manager/add-service.md diff --git a/app/enterprise/1.5.x/kong-manager/administration/admins/add-admin.md b/archive/enterprise/1.5.x/kong-manager/administration/admins/add-admin.md similarity index 100% rename from app/enterprise/1.5.x/kong-manager/administration/admins/add-admin.md rename to archive/enterprise/1.5.x/kong-manager/administration/admins/add-admin.md diff --git a/app/enterprise/1.5.x/kong-manager/administration/admins/invite.md b/archive/enterprise/1.5.x/kong-manager/administration/admins/invite.md similarity index 100% rename from app/enterprise/1.5.x/kong-manager/administration/admins/invite.md rename to archive/enterprise/1.5.x/kong-manager/administration/admins/invite.md diff --git a/app/enterprise/1.5.x/kong-manager/administration/rbac/add-role.md b/archive/enterprise/1.5.x/kong-manager/administration/rbac/add-role.md similarity index 100% rename from app/enterprise/1.5.x/kong-manager/administration/rbac/add-role.md rename to archive/enterprise/1.5.x/kong-manager/administration/rbac/add-role.md diff --git a/app/enterprise/1.5.x/kong-manager/administration/rbac/add-user.md b/archive/enterprise/1.5.x/kong-manager/administration/rbac/add-user.md similarity index 100% rename from app/enterprise/1.5.x/kong-manager/administration/rbac/add-user.md rename to archive/enterprise/1.5.x/kong-manager/administration/rbac/add-user.md diff --git a/app/enterprise/1.5.x/kong-manager/administration/rbac/index.md b/archive/enterprise/1.5.x/kong-manager/administration/rbac/index.md similarity index 100% rename from app/enterprise/1.5.x/kong-manager/administration/rbac/index.md rename to archive/enterprise/1.5.x/kong-manager/administration/rbac/index.md diff --git a/app/enterprise/1.5.x/kong-manager/administration/rbac/new-role.md b/archive/enterprise/1.5.x/kong-manager/administration/rbac/new-role.md similarity index 100% rename from app/enterprise/1.5.x/kong-manager/administration/rbac/new-role.md rename to archive/enterprise/1.5.x/kong-manager/administration/rbac/new-role.md diff --git a/app/enterprise/1.5.x/kong-manager/administration/rbac/rbac.md b/archive/enterprise/1.5.x/kong-manager/administration/rbac/rbac.md similarity index 100% rename from app/enterprise/1.5.x/kong-manager/administration/rbac/rbac.md rename to archive/enterprise/1.5.x/kong-manager/administration/rbac/rbac.md diff --git a/app/enterprise/1.5.x/kong-manager/administration/workspaces/add-workspace.md b/archive/enterprise/1.5.x/kong-manager/administration/workspaces/add-workspace.md similarity index 100% rename from app/enterprise/1.5.x/kong-manager/administration/workspaces/add-workspace.md rename to archive/enterprise/1.5.x/kong-manager/administration/workspaces/add-workspace.md diff --git a/app/enterprise/1.5.x/kong-manager/administration/workspaces/create-workspace.md b/archive/enterprise/1.5.x/kong-manager/administration/workspaces/create-workspace.md similarity index 100% rename from app/enterprise/1.5.x/kong-manager/administration/workspaces/create-workspace.md rename to archive/enterprise/1.5.x/kong-manager/administration/workspaces/create-workspace.md diff --git a/app/enterprise/1.5.x/kong-manager/administration/workspaces/update-workspace.md b/archive/enterprise/1.5.x/kong-manager/administration/workspaces/update-workspace.md similarity index 100% rename from app/enterprise/1.5.x/kong-manager/administration/workspaces/update-workspace.md rename to archive/enterprise/1.5.x/kong-manager/administration/workspaces/update-workspace.md diff --git a/app/enterprise/1.5.x/kong-manager/administration/workspaces/workspaces.md b/archive/enterprise/1.5.x/kong-manager/administration/workspaces/workspaces.md similarity index 100% rename from app/enterprise/1.5.x/kong-manager/administration/workspaces/workspaces.md rename to archive/enterprise/1.5.x/kong-manager/administration/workspaces/workspaces.md diff --git a/app/enterprise/1.5.x/kong-manager/authentication/basic.md b/archive/enterprise/1.5.x/kong-manager/authentication/basic.md similarity index 100% rename from app/enterprise/1.5.x/kong-manager/authentication/basic.md rename to archive/enterprise/1.5.x/kong-manager/authentication/basic.md diff --git a/app/enterprise/1.5.x/kong-manager/authentication/ldap.md b/archive/enterprise/1.5.x/kong-manager/authentication/ldap.md similarity index 100% rename from app/enterprise/1.5.x/kong-manager/authentication/ldap.md rename to archive/enterprise/1.5.x/kong-manager/authentication/ldap.md diff --git a/app/enterprise/1.5.x/kong-manager/authentication/oidc.md b/archive/enterprise/1.5.x/kong-manager/authentication/oidc.md similarity index 100% rename from app/enterprise/1.5.x/kong-manager/authentication/oidc.md rename to archive/enterprise/1.5.x/kong-manager/authentication/oidc.md diff --git a/app/enterprise/1.5.x/kong-manager/authentication/sessions.md b/archive/enterprise/1.5.x/kong-manager/authentication/sessions.md similarity index 100% rename from app/enterprise/1.5.x/kong-manager/authentication/sessions.md rename to archive/enterprise/1.5.x/kong-manager/authentication/sessions.md diff --git a/app/enterprise/1.5.x/kong-manager/authentication/super-admin.md b/archive/enterprise/1.5.x/kong-manager/authentication/super-admin.md similarity index 100% rename from app/enterprise/1.5.x/kong-manager/authentication/super-admin.md rename to archive/enterprise/1.5.x/kong-manager/authentication/super-admin.md diff --git a/app/enterprise/1.5.x/kong-manager/best-practices.md b/archive/enterprise/1.5.x/kong-manager/best-practices.md similarity index 100% rename from app/enterprise/1.5.x/kong-manager/best-practices.md rename to archive/enterprise/1.5.x/kong-manager/best-practices.md diff --git a/app/enterprise/1.5.x/kong-manager/enable-plugin.md b/archive/enterprise/1.5.x/kong-manager/enable-plugin.md similarity index 100% rename from app/enterprise/1.5.x/kong-manager/enable-plugin.md rename to archive/enterprise/1.5.x/kong-manager/enable-plugin.md diff --git a/app/enterprise/1.5.x/kong-manager/faq.md b/archive/enterprise/1.5.x/kong-manager/faq.md similarity index 100% rename from app/enterprise/1.5.x/kong-manager/faq.md rename to archive/enterprise/1.5.x/kong-manager/faq.md diff --git a/app/enterprise/1.5.x/kong-manager/networking/configuration.md b/archive/enterprise/1.5.x/kong-manager/networking/configuration.md similarity index 100% rename from app/enterprise/1.5.x/kong-manager/networking/configuration.md rename to archive/enterprise/1.5.x/kong-manager/networking/configuration.md diff --git a/app/enterprise/1.5.x/kong-manager/networking/email.md b/archive/enterprise/1.5.x/kong-manager/networking/email.md similarity index 100% rename from app/enterprise/1.5.x/kong-manager/networking/email.md rename to archive/enterprise/1.5.x/kong-manager/networking/email.md diff --git a/app/enterprise/1.5.x/kong-manager/overview.md b/archive/enterprise/1.5.x/kong-manager/overview.md similarity index 100% rename from app/enterprise/1.5.x/kong-manager/overview.md rename to archive/enterprise/1.5.x/kong-manager/overview.md diff --git a/app/enterprise/1.5.x/kong-manager/reset-password.md b/archive/enterprise/1.5.x/kong-manager/reset-password.md similarity index 100% rename from app/enterprise/1.5.x/kong-manager/reset-password.md rename to archive/enterprise/1.5.x/kong-manager/reset-password.md diff --git a/app/enterprise/1.5.x/kong-manager/security.md b/archive/enterprise/1.5.x/kong-manager/security.md similarity index 100% rename from app/enterprise/1.5.x/kong-manager/security.md rename to archive/enterprise/1.5.x/kong-manager/security.md diff --git a/app/enterprise/1.5.x/kong-manager/service-directory-mapping.md b/archive/enterprise/1.5.x/kong-manager/service-directory-mapping.md similarity index 100% rename from app/enterprise/1.5.x/kong-manager/service-directory-mapping.md rename to archive/enterprise/1.5.x/kong-manager/service-directory-mapping.md diff --git a/app/enterprise/1.5.x/kong-manager/vitals.md b/archive/enterprise/1.5.x/kong-manager/vitals.md similarity index 100% rename from app/enterprise/1.5.x/kong-manager/vitals.md rename to archive/enterprise/1.5.x/kong-manager/vitals.md diff --git a/app/enterprise/1.5.x/kong-security-update-process.md b/archive/enterprise/1.5.x/kong-security-update-process.md similarity index 100% rename from app/enterprise/1.5.x/kong-security-update-process.md rename to archive/enterprise/1.5.x/kong-security-update-process.md diff --git a/app/enterprise/1.5.x/loadbalancing.md b/archive/enterprise/1.5.x/loadbalancing.md similarity index 100% rename from app/enterprise/1.5.x/loadbalancing.md rename to archive/enterprise/1.5.x/loadbalancing.md diff --git a/app/enterprise/1.5.x/logging.md b/archive/enterprise/1.5.x/logging.md similarity index 100% rename from app/enterprise/1.5.x/logging.md rename to archive/enterprise/1.5.x/logging.md diff --git a/app/enterprise/1.5.x/network.md b/archive/enterprise/1.5.x/network.md similarity index 100% rename from app/enterprise/1.5.x/network.md rename to archive/enterprise/1.5.x/network.md diff --git a/app/enterprise/1.5.x/pdk/index.md b/archive/enterprise/1.5.x/pdk/index.md similarity index 100% rename from app/enterprise/1.5.x/pdk/index.md rename to archive/enterprise/1.5.x/pdk/index.md diff --git a/app/enterprise/1.5.x/pdk/kong.client.md b/archive/enterprise/1.5.x/pdk/kong.client.md similarity index 100% rename from app/enterprise/1.5.x/pdk/kong.client.md rename to archive/enterprise/1.5.x/pdk/kong.client.md diff --git a/app/enterprise/1.5.x/pdk/kong.ctx.md b/archive/enterprise/1.5.x/pdk/kong.ctx.md similarity index 100% rename from app/enterprise/1.5.x/pdk/kong.ctx.md rename to archive/enterprise/1.5.x/pdk/kong.ctx.md diff --git a/app/enterprise/1.5.x/pdk/kong.ip.md b/archive/enterprise/1.5.x/pdk/kong.ip.md similarity index 100% rename from app/enterprise/1.5.x/pdk/kong.ip.md rename to archive/enterprise/1.5.x/pdk/kong.ip.md diff --git a/app/enterprise/1.5.x/pdk/kong.log.md b/archive/enterprise/1.5.x/pdk/kong.log.md similarity index 100% rename from app/enterprise/1.5.x/pdk/kong.log.md rename to archive/enterprise/1.5.x/pdk/kong.log.md diff --git a/app/enterprise/1.5.x/pdk/kong.node.md b/archive/enterprise/1.5.x/pdk/kong.node.md similarity index 100% rename from app/enterprise/1.5.x/pdk/kong.node.md rename to archive/enterprise/1.5.x/pdk/kong.node.md diff --git a/app/enterprise/1.5.x/pdk/kong.request.md b/archive/enterprise/1.5.x/pdk/kong.request.md similarity index 100% rename from app/enterprise/1.5.x/pdk/kong.request.md rename to archive/enterprise/1.5.x/pdk/kong.request.md diff --git a/app/enterprise/1.5.x/pdk/kong.response.md b/archive/enterprise/1.5.x/pdk/kong.response.md similarity index 100% rename from app/enterprise/1.5.x/pdk/kong.response.md rename to archive/enterprise/1.5.x/pdk/kong.response.md diff --git a/app/enterprise/1.5.x/pdk/kong.router.md b/archive/enterprise/1.5.x/pdk/kong.router.md similarity index 100% rename from app/enterprise/1.5.x/pdk/kong.router.md rename to archive/enterprise/1.5.x/pdk/kong.router.md diff --git a/app/enterprise/1.5.x/pdk/kong.service.md b/archive/enterprise/1.5.x/pdk/kong.service.md similarity index 100% rename from app/enterprise/1.5.x/pdk/kong.service.md rename to archive/enterprise/1.5.x/pdk/kong.service.md diff --git a/app/enterprise/1.5.x/pdk/kong.service.request.md b/archive/enterprise/1.5.x/pdk/kong.service.request.md similarity index 100% rename from app/enterprise/1.5.x/pdk/kong.service.request.md rename to archive/enterprise/1.5.x/pdk/kong.service.request.md diff --git a/app/enterprise/1.5.x/pdk/kong.service.response.md b/archive/enterprise/1.5.x/pdk/kong.service.response.md similarity index 100% rename from app/enterprise/1.5.x/pdk/kong.service.response.md rename to archive/enterprise/1.5.x/pdk/kong.service.response.md diff --git a/app/enterprise/1.5.x/pdk/kong.table.md b/archive/enterprise/1.5.x/pdk/kong.table.md similarity index 100% rename from app/enterprise/1.5.x/pdk/kong.table.md rename to archive/enterprise/1.5.x/pdk/kong.table.md diff --git a/app/enterprise/1.5.x/plugin-development/access-the-datastore.md b/archive/enterprise/1.5.x/plugin-development/access-the-datastore.md similarity index 100% rename from app/enterprise/1.5.x/plugin-development/access-the-datastore.md rename to archive/enterprise/1.5.x/plugin-development/access-the-datastore.md diff --git a/app/enterprise/1.5.x/plugin-development/admin-api.md b/archive/enterprise/1.5.x/plugin-development/admin-api.md similarity index 100% rename from app/enterprise/1.5.x/plugin-development/admin-api.md rename to archive/enterprise/1.5.x/plugin-development/admin-api.md diff --git a/app/enterprise/1.5.x/plugin-development/custom-entities.md b/archive/enterprise/1.5.x/plugin-development/custom-entities.md similarity index 100% rename from app/enterprise/1.5.x/plugin-development/custom-entities.md rename to archive/enterprise/1.5.x/plugin-development/custom-entities.md diff --git a/app/enterprise/1.5.x/plugin-development/custom-logic.md b/archive/enterprise/1.5.x/plugin-development/custom-logic.md similarity index 100% rename from app/enterprise/1.5.x/plugin-development/custom-logic.md rename to archive/enterprise/1.5.x/plugin-development/custom-logic.md diff --git a/app/enterprise/1.5.x/plugin-development/distribution.md b/archive/enterprise/1.5.x/plugin-development/distribution.md similarity index 100% rename from app/enterprise/1.5.x/plugin-development/distribution.md rename to archive/enterprise/1.5.x/plugin-development/distribution.md diff --git a/app/enterprise/1.5.x/plugin-development/entities-cache.md b/archive/enterprise/1.5.x/plugin-development/entities-cache.md similarity index 100% rename from app/enterprise/1.5.x/plugin-development/entities-cache.md rename to archive/enterprise/1.5.x/plugin-development/entities-cache.md diff --git a/app/enterprise/1.5.x/plugin-development/file-structure.md b/archive/enterprise/1.5.x/plugin-development/file-structure.md similarity index 100% rename from app/enterprise/1.5.x/plugin-development/file-structure.md rename to archive/enterprise/1.5.x/plugin-development/file-structure.md diff --git a/app/enterprise/1.5.x/plugin-development/index.md b/archive/enterprise/1.5.x/plugin-development/index.md similarity index 100% rename from app/enterprise/1.5.x/plugin-development/index.md rename to archive/enterprise/1.5.x/plugin-development/index.md diff --git a/app/enterprise/1.5.x/plugin-development/plugin-configuration.md b/archive/enterprise/1.5.x/plugin-development/plugin-configuration.md similarity index 100% rename from app/enterprise/1.5.x/plugin-development/plugin-configuration.md rename to archive/enterprise/1.5.x/plugin-development/plugin-configuration.md diff --git a/app/enterprise/1.5.x/plugin-development/tests.md b/archive/enterprise/1.5.x/plugin-development/tests.md similarity index 100% rename from app/enterprise/1.5.x/plugin-development/tests.md rename to archive/enterprise/1.5.x/plugin-development/tests.md diff --git a/app/enterprise/1.5.x/plugins/allowing-multiple-authentication-methods.md b/archive/enterprise/1.5.x/plugins/allowing-multiple-authentication-methods.md similarity index 100% rename from app/enterprise/1.5.x/plugins/allowing-multiple-authentication-methods.md rename to archive/enterprise/1.5.x/plugins/allowing-multiple-authentication-methods.md diff --git a/app/enterprise/1.5.x/plugins/canary-release.md b/archive/enterprise/1.5.x/plugins/canary-release.md similarity index 100% rename from app/enterprise/1.5.x/plugins/canary-release.md rename to archive/enterprise/1.5.x/plugins/canary-release.md diff --git a/app/enterprise/1.5.x/plugins/degraphql.md b/archive/enterprise/1.5.x/plugins/degraphql.md similarity index 100% rename from app/enterprise/1.5.x/plugins/degraphql.md rename to archive/enterprise/1.5.x/plugins/degraphql.md diff --git a/app/enterprise/1.5.x/plugins/exit-transformer.md b/archive/enterprise/1.5.x/plugins/exit-transformer.md similarity index 100% rename from app/enterprise/1.5.x/plugins/exit-transformer.md rename to archive/enterprise/1.5.x/plugins/exit-transformer.md diff --git a/app/enterprise/1.5.x/plugins/forward-proxy.md b/archive/enterprise/1.5.x/plugins/forward-proxy.md similarity index 100% rename from app/enterprise/1.5.x/plugins/forward-proxy.md rename to archive/enterprise/1.5.x/plugins/forward-proxy.md diff --git a/app/enterprise/1.5.x/plugins/graphql-proxy-cache-advanced.md b/archive/enterprise/1.5.x/plugins/graphql-proxy-cache-advanced.md similarity index 100% rename from app/enterprise/1.5.x/plugins/graphql-proxy-cache-advanced.md rename to archive/enterprise/1.5.x/plugins/graphql-proxy-cache-advanced.md diff --git a/app/enterprise/1.5.x/plugins/graphql-quickstart.md b/archive/enterprise/1.5.x/plugins/graphql-quickstart.md similarity index 100% rename from app/enterprise/1.5.x/plugins/graphql-quickstart.md rename to archive/enterprise/1.5.x/plugins/graphql-quickstart.md diff --git a/app/enterprise/1.5.x/plugins/graphql-rate-limiting-advanced.md b/archive/enterprise/1.5.x/plugins/graphql-rate-limiting-advanced.md similarity index 100% rename from app/enterprise/1.5.x/plugins/graphql-rate-limiting-advanced.md rename to archive/enterprise/1.5.x/plugins/graphql-rate-limiting-advanced.md diff --git a/app/enterprise/1.5.x/plugins/http-proxy-caching.md b/archive/enterprise/1.5.x/plugins/http-proxy-caching.md similarity index 100% rename from app/enterprise/1.5.x/plugins/http-proxy-caching.md rename to archive/enterprise/1.5.x/plugins/http-proxy-caching.md diff --git a/app/enterprise/1.5.x/plugins/index.md b/archive/enterprise/1.5.x/plugins/index.md similarity index 100% rename from app/enterprise/1.5.x/plugins/index.md rename to archive/enterprise/1.5.x/plugins/index.md diff --git a/app/enterprise/1.5.x/plugins/jwt-signer.md b/archive/enterprise/1.5.x/plugins/jwt-signer.md similarity index 100% rename from app/enterprise/1.5.x/plugins/jwt-signer.md rename to archive/enterprise/1.5.x/plugins/jwt-signer.md diff --git a/app/enterprise/1.5.x/plugins/kafka-log.md b/archive/enterprise/1.5.x/plugins/kafka-log.md similarity index 100% rename from app/enterprise/1.5.x/plugins/kafka-log.md rename to archive/enterprise/1.5.x/plugins/kafka-log.md diff --git a/app/enterprise/1.5.x/plugins/kafka-upstream.md b/archive/enterprise/1.5.x/plugins/kafka-upstream.md similarity index 100% rename from app/enterprise/1.5.x/plugins/kafka-upstream.md rename to archive/enterprise/1.5.x/plugins/kafka-upstream.md diff --git a/app/enterprise/1.5.x/plugins/key-auth-enc.md b/archive/enterprise/1.5.x/plugins/key-auth-enc.md similarity index 100% rename from app/enterprise/1.5.x/plugins/key-auth-enc.md rename to archive/enterprise/1.5.x/plugins/key-auth-enc.md diff --git a/app/enterprise/1.5.x/plugins/ldap-authentication-advanced.md b/archive/enterprise/1.5.x/plugins/ldap-authentication-advanced.md similarity index 100% rename from app/enterprise/1.5.x/plugins/ldap-authentication-advanced.md rename to archive/enterprise/1.5.x/plugins/ldap-authentication-advanced.md diff --git a/app/enterprise/1.5.x/plugins/oauth2-introspection.md b/archive/enterprise/1.5.x/plugins/oauth2-introspection.md similarity index 100% rename from app/enterprise/1.5.x/plugins/oauth2-introspection.md rename to archive/enterprise/1.5.x/plugins/oauth2-introspection.md diff --git a/app/enterprise/1.5.x/plugins/oidc-auth0.md b/archive/enterprise/1.5.x/plugins/oidc-auth0.md similarity index 100% rename from app/enterprise/1.5.x/plugins/oidc-auth0.md rename to archive/enterprise/1.5.x/plugins/oidc-auth0.md diff --git a/app/enterprise/1.5.x/plugins/oidc-azuread.md b/archive/enterprise/1.5.x/plugins/oidc-azuread.md similarity index 100% rename from app/enterprise/1.5.x/plugins/oidc-azuread.md rename to archive/enterprise/1.5.x/plugins/oidc-azuread.md diff --git a/app/enterprise/1.5.x/plugins/oidc-cognito.md b/archive/enterprise/1.5.x/plugins/oidc-cognito.md similarity index 100% rename from app/enterprise/1.5.x/plugins/oidc-cognito.md rename to archive/enterprise/1.5.x/plugins/oidc-cognito.md diff --git a/app/enterprise/1.5.x/plugins/oidc-google.md b/archive/enterprise/1.5.x/plugins/oidc-google.md similarity index 100% rename from app/enterprise/1.5.x/plugins/oidc-google.md rename to archive/enterprise/1.5.x/plugins/oidc-google.md diff --git a/app/enterprise/1.5.x/plugins/oidc-okta.md b/archive/enterprise/1.5.x/plugins/oidc-okta.md similarity index 100% rename from app/enterprise/1.5.x/plugins/oidc-okta.md rename to archive/enterprise/1.5.x/plugins/oidc-okta.md diff --git a/app/enterprise/1.5.x/plugins/oidc-use-case.md b/archive/enterprise/1.5.x/plugins/oidc-use-case.md similarity index 100% rename from app/enterprise/1.5.x/plugins/oidc-use-case.md rename to archive/enterprise/1.5.x/plugins/oidc-use-case.md diff --git a/app/enterprise/1.5.x/plugins/openid-connect.md b/archive/enterprise/1.5.x/plugins/openid-connect.md similarity index 100% rename from app/enterprise/1.5.x/plugins/openid-connect.md rename to archive/enterprise/1.5.x/plugins/openid-connect.md diff --git a/app/enterprise/1.5.x/plugins/proxy-cache-advanced.md b/archive/enterprise/1.5.x/plugins/proxy-cache-advanced.md similarity index 100% rename from app/enterprise/1.5.x/plugins/proxy-cache-advanced.md rename to archive/enterprise/1.5.x/plugins/proxy-cache-advanced.md diff --git a/app/enterprise/1.5.x/plugins/rate-limiting-advanced.md b/archive/enterprise/1.5.x/plugins/rate-limiting-advanced.md similarity index 100% rename from app/enterprise/1.5.x/plugins/rate-limiting-advanced.md rename to archive/enterprise/1.5.x/plugins/rate-limiting-advanced.md diff --git a/app/enterprise/1.5.x/plugins/request-transformer.md b/archive/enterprise/1.5.x/plugins/request-transformer.md similarity index 100% rename from app/enterprise/1.5.x/plugins/request-transformer.md rename to archive/enterprise/1.5.x/plugins/request-transformer.md diff --git a/app/enterprise/1.5.x/plugins/request-validator.md b/archive/enterprise/1.5.x/plugins/request-validator.md similarity index 100% rename from app/enterprise/1.5.x/plugins/request-validator.md rename to archive/enterprise/1.5.x/plugins/request-validator.md diff --git a/app/enterprise/1.5.x/plugins/response-transformer-advanced.md b/archive/enterprise/1.5.x/plugins/response-transformer-advanced.md similarity index 100% rename from app/enterprise/1.5.x/plugins/response-transformer-advanced.md rename to archive/enterprise/1.5.x/plugins/response-transformer-advanced.md diff --git a/app/enterprise/1.5.x/plugins/route-by-header.md b/archive/enterprise/1.5.x/plugins/route-by-header.md similarity index 100% rename from app/enterprise/1.5.x/plugins/route-by-header.md rename to archive/enterprise/1.5.x/plugins/route-by-header.md diff --git a/app/enterprise/1.5.x/plugins/route-by-headers.md b/archive/enterprise/1.5.x/plugins/route-by-headers.md similarity index 100% rename from app/enterprise/1.5.x/plugins/route-by-headers.md rename to archive/enterprise/1.5.x/plugins/route-by-headers.md diff --git a/app/enterprise/1.5.x/plugins/route-transformer-advanced.md b/archive/enterprise/1.5.x/plugins/route-transformer-advanced.md similarity index 100% rename from app/enterprise/1.5.x/plugins/route-transformer-advanced.md rename to archive/enterprise/1.5.x/plugins/route-transformer-advanced.md diff --git a/app/enterprise/1.5.x/plugins/session.md b/archive/enterprise/1.5.x/plugins/session.md similarity index 100% rename from app/enterprise/1.5.x/plugins/session.md rename to archive/enterprise/1.5.x/plugins/session.md diff --git a/app/enterprise/1.5.x/plugins/statsd-advanced.md b/archive/enterprise/1.5.x/plugins/statsd-advanced.md similarity index 100% rename from app/enterprise/1.5.x/plugins/statsd-advanced.md rename to archive/enterprise/1.5.x/plugins/statsd-advanced.md diff --git a/app/enterprise/1.5.x/plugins/statsd.rules.yaml b/archive/enterprise/1.5.x/plugins/statsd.rules.yaml similarity index 100% rename from app/enterprise/1.5.x/plugins/statsd.rules.yaml rename to archive/enterprise/1.5.x/plugins/statsd.rules.yaml diff --git a/app/enterprise/1.5.x/plugins/vault-auth.md b/archive/enterprise/1.5.x/plugins/vault-auth.md similarity index 100% rename from app/enterprise/1.5.x/plugins/vault-auth.md rename to archive/enterprise/1.5.x/plugins/vault-auth.md diff --git a/app/enterprise/1.5.x/property-reference.md b/archive/enterprise/1.5.x/property-reference.md similarity index 100% rename from app/enterprise/1.5.x/property-reference.md rename to archive/enterprise/1.5.x/property-reference.md diff --git a/app/enterprise/1.5.x/proxy.md b/archive/enterprise/1.5.x/proxy.md similarity index 100% rename from app/enterprise/1.5.x/proxy.md rename to archive/enterprise/1.5.x/proxy.md diff --git a/app/enterprise/1.5.x/rate-limiting.md b/archive/enterprise/1.5.x/rate-limiting.md similarity index 100% rename from app/enterprise/1.5.x/rate-limiting.md rename to archive/enterprise/1.5.x/rate-limiting.md diff --git a/app/enterprise/1.5.x/release-notes.md b/archive/enterprise/1.5.x/release-notes.md similarity index 100% rename from app/enterprise/1.5.x/release-notes.md rename to archive/enterprise/1.5.x/release-notes.md diff --git a/app/enterprise/1.5.x/secure-admin-api.md b/archive/enterprise/1.5.x/secure-admin-api.md similarity index 100% rename from app/enterprise/1.5.x/secure-admin-api.md rename to archive/enterprise/1.5.x/secure-admin-api.md diff --git a/app/enterprise/1.5.x/sizing-guidelines.md b/archive/enterprise/1.5.x/sizing-guidelines.md similarity index 100% rename from app/enterprise/1.5.x/sizing-guidelines.md rename to archive/enterprise/1.5.x/sizing-guidelines.md diff --git a/app/enterprise/1.5.x/start-kong-securely.md b/archive/enterprise/1.5.x/start-kong-securely.md similarity index 100% rename from app/enterprise/1.5.x/start-kong-securely.md rename to archive/enterprise/1.5.x/start-kong-securely.md diff --git a/app/enterprise/1.5.x/studio/dec-conf-studio.md b/archive/enterprise/1.5.x/studio/dec-conf-studio.md similarity index 100% rename from app/enterprise/1.5.x/studio/dec-conf-studio.md rename to archive/enterprise/1.5.x/studio/dec-conf-studio.md diff --git a/app/enterprise/1.5.x/studio/deploy-to-dev-portal.md b/archive/enterprise/1.5.x/studio/deploy-to-dev-portal.md similarity index 100% rename from app/enterprise/1.5.x/studio/deploy-to-dev-portal.md rename to archive/enterprise/1.5.x/studio/deploy-to-dev-portal.md diff --git a/app/enterprise/1.5.x/studio/download-install.md b/archive/enterprise/1.5.x/studio/download-install.md similarity index 100% rename from app/enterprise/1.5.x/studio/download-install.md rename to archive/enterprise/1.5.x/studio/download-install.md diff --git a/app/enterprise/1.5.x/studio/index.md b/archive/enterprise/1.5.x/studio/index.md similarity index 100% rename from app/enterprise/1.5.x/studio/index.md rename to archive/enterprise/1.5.x/studio/index.md diff --git a/app/enterprise/1.5.x/studio/using-insomnia-designer.md b/archive/enterprise/1.5.x/studio/using-insomnia-designer.md similarity index 100% rename from app/enterprise/1.5.x/studio/using-insomnia-designer.md rename to archive/enterprise/1.5.x/studio/using-insomnia-designer.md diff --git a/app/enterprise/1.5.x/support-policy.md b/archive/enterprise/1.5.x/support-policy.md similarity index 100% rename from app/enterprise/1.5.x/support-policy.md rename to archive/enterprise/1.5.x/support-policy.md diff --git a/app/enterprise/1.5.x/systemd.md b/archive/enterprise/1.5.x/systemd.md similarity index 100% rename from app/enterprise/1.5.x/systemd.md rename to archive/enterprise/1.5.x/systemd.md diff --git a/app/gateway-oss/0.13.x/admin-api.md b/archive/gateway-oss/0.13.x/admin-api.md similarity index 100% rename from app/gateway-oss/0.13.x/admin-api.md rename to archive/gateway-oss/0.13.x/admin-api.md diff --git a/app/gateway-oss/0.13.x/auth.md b/archive/gateway-oss/0.13.x/auth.md similarity index 100% rename from app/gateway-oss/0.13.x/auth.md rename to archive/gateway-oss/0.13.x/auth.md diff --git a/app/gateway-oss/0.13.x/cli.md b/archive/gateway-oss/0.13.x/cli.md similarity index 100% rename from app/gateway-oss/0.13.x/cli.md rename to archive/gateway-oss/0.13.x/cli.md diff --git a/app/gateway-oss/0.13.x/clustering.md b/archive/gateway-oss/0.13.x/clustering.md similarity index 100% rename from app/gateway-oss/0.13.x/clustering.md rename to archive/gateway-oss/0.13.x/clustering.md diff --git a/app/gateway-oss/0.13.x/configuration.md b/archive/gateway-oss/0.13.x/configuration.md similarity index 100% rename from app/gateway-oss/0.13.x/configuration.md rename to archive/gateway-oss/0.13.x/configuration.md diff --git a/app/gateway-oss/0.13.x/getting-started/adding-consumers.md b/archive/gateway-oss/0.13.x/getting-started/adding-consumers.md similarity index 100% rename from app/gateway-oss/0.13.x/getting-started/adding-consumers.md rename to archive/gateway-oss/0.13.x/getting-started/adding-consumers.md diff --git a/app/gateway-oss/0.13.x/getting-started/configuring-a-service.md b/archive/gateway-oss/0.13.x/getting-started/configuring-a-service.md similarity index 100% rename from app/gateway-oss/0.13.x/getting-started/configuring-a-service.md rename to archive/gateway-oss/0.13.x/getting-started/configuring-a-service.md diff --git a/app/gateway-oss/0.13.x/getting-started/enabling-plugins.md b/archive/gateway-oss/0.13.x/getting-started/enabling-plugins.md similarity index 100% rename from app/gateway-oss/0.13.x/getting-started/enabling-plugins.md rename to archive/gateway-oss/0.13.x/getting-started/enabling-plugins.md diff --git a/app/gateway-oss/0.13.x/getting-started/introduction.md b/archive/gateway-oss/0.13.x/getting-started/introduction.md similarity index 100% rename from app/gateway-oss/0.13.x/getting-started/introduction.md rename to archive/gateway-oss/0.13.x/getting-started/introduction.md diff --git a/app/gateway-oss/0.13.x/getting-started/quickstart.md b/archive/gateway-oss/0.13.x/getting-started/quickstart.md similarity index 100% rename from app/gateway-oss/0.13.x/getting-started/quickstart.md rename to archive/gateway-oss/0.13.x/getting-started/quickstart.md diff --git a/app/gateway-oss/0.13.x/health-checks-circuit-breakers.md b/archive/gateway-oss/0.13.x/health-checks-circuit-breakers.md similarity index 100% rename from app/gateway-oss/0.13.x/health-checks-circuit-breakers.md rename to archive/gateway-oss/0.13.x/health-checks-circuit-breakers.md diff --git a/app/gateway-oss/0.13.x/index.md b/archive/gateway-oss/0.13.x/index.md similarity index 100% rename from app/gateway-oss/0.13.x/index.md rename to archive/gateway-oss/0.13.x/index.md diff --git a/app/gateway-oss/0.13.x/loadbalancing.md b/archive/gateway-oss/0.13.x/loadbalancing.md similarity index 100% rename from app/gateway-oss/0.13.x/loadbalancing.md rename to archive/gateway-oss/0.13.x/loadbalancing.md diff --git a/app/gateway-oss/0.13.x/lua-reference/index.html b/archive/gateway-oss/0.13.x/lua-reference/index.html similarity index 100% rename from app/gateway-oss/0.13.x/lua-reference/index.html rename to archive/gateway-oss/0.13.x/lua-reference/index.html diff --git a/app/gateway-oss/0.13.x/lua-reference/modules/kong.dao.html b/archive/gateway-oss/0.13.x/lua-reference/modules/kong.dao.html similarity index 100% rename from app/gateway-oss/0.13.x/lua-reference/modules/kong.dao.html rename to archive/gateway-oss/0.13.x/lua-reference/modules/kong.dao.html diff --git a/app/gateway-oss/0.13.x/lua-reference/modules/kong.plugins.basic-auth.crypto.html b/archive/gateway-oss/0.13.x/lua-reference/modules/kong.plugins.basic-auth.crypto.html similarity index 100% rename from app/gateway-oss/0.13.x/lua-reference/modules/kong.plugins.basic-auth.crypto.html rename to archive/gateway-oss/0.13.x/lua-reference/modules/kong.plugins.basic-auth.crypto.html diff --git a/app/gateway-oss/0.13.x/lua-reference/modules/kong.plugins.galileo.alf.html b/archive/gateway-oss/0.13.x/lua-reference/modules/kong.plugins.galileo.alf.html similarity index 100% rename from app/gateway-oss/0.13.x/lua-reference/modules/kong.plugins.galileo.alf.html rename to archive/gateway-oss/0.13.x/lua-reference/modules/kong.plugins.galileo.alf.html diff --git a/app/gateway-oss/0.13.x/lua-reference/modules/kong.plugins.galileo.buffer.html b/archive/gateway-oss/0.13.x/lua-reference/modules/kong.plugins.galileo.buffer.html similarity index 100% rename from app/gateway-oss/0.13.x/lua-reference/modules/kong.plugins.galileo.buffer.html rename to archive/gateway-oss/0.13.x/lua-reference/modules/kong.plugins.galileo.buffer.html diff --git a/app/gateway-oss/0.13.x/lua-reference/modules/kong.plugins.jwt.jwt_parser.html b/archive/gateway-oss/0.13.x/lua-reference/modules/kong.plugins.jwt.jwt_parser.html similarity index 100% rename from app/gateway-oss/0.13.x/lua-reference/modules/kong.plugins.jwt.jwt_parser.html rename to archive/gateway-oss/0.13.x/lua-reference/modules/kong.plugins.jwt.jwt_parser.html diff --git a/app/gateway-oss/0.13.x/lua-reference/modules/kong.tools.responses.html b/archive/gateway-oss/0.13.x/lua-reference/modules/kong.tools.responses.html similarity index 100% rename from app/gateway-oss/0.13.x/lua-reference/modules/kong.tools.responses.html rename to archive/gateway-oss/0.13.x/lua-reference/modules/kong.tools.responses.html diff --git a/app/gateway-oss/0.13.x/lua-reference/modules/kong.tools.responses/send.md b/archive/gateway-oss/0.13.x/lua-reference/modules/kong.tools.responses/send.md similarity index 100% rename from app/gateway-oss/0.13.x/lua-reference/modules/kong.tools.responses/send.md rename to archive/gateway-oss/0.13.x/lua-reference/modules/kong.tools.responses/send.md diff --git a/app/gateway-oss/0.13.x/lua-reference/modules/kong.tools.timestamp.html b/archive/gateway-oss/0.13.x/lua-reference/modules/kong.tools.timestamp.html similarity index 100% rename from app/gateway-oss/0.13.x/lua-reference/modules/kong.tools.timestamp.html rename to archive/gateway-oss/0.13.x/lua-reference/modules/kong.tools.timestamp.html diff --git a/app/gateway-oss/0.13.x/lua-reference/modules/kong.tools.utils.html b/archive/gateway-oss/0.13.x/lua-reference/modules/kong.tools.utils.html similarity index 100% rename from app/gateway-oss/0.13.x/lua-reference/modules/kong.tools.utils.html rename to archive/gateway-oss/0.13.x/lua-reference/modules/kong.tools.utils.html diff --git a/app/gateway-oss/0.13.x/lua-reference/modules/spec.helpers.html b/archive/gateway-oss/0.13.x/lua-reference/modules/spec.helpers.html similarity index 100% rename from app/gateway-oss/0.13.x/lua-reference/modules/spec.helpers.html rename to archive/gateway-oss/0.13.x/lua-reference/modules/spec.helpers.html diff --git a/app/gateway-oss/0.13.x/network.md b/archive/gateway-oss/0.13.x/network.md similarity index 100% rename from app/gateway-oss/0.13.x/network.md rename to archive/gateway-oss/0.13.x/network.md diff --git a/app/gateway-oss/0.13.x/plugin-development/access-the-datastore.md b/archive/gateway-oss/0.13.x/plugin-development/access-the-datastore.md similarity index 100% rename from app/gateway-oss/0.13.x/plugin-development/access-the-datastore.md rename to archive/gateway-oss/0.13.x/plugin-development/access-the-datastore.md diff --git a/app/gateway-oss/0.13.x/plugin-development/admin-api.md b/archive/gateway-oss/0.13.x/plugin-development/admin-api.md similarity index 100% rename from app/gateway-oss/0.13.x/plugin-development/admin-api.md rename to archive/gateway-oss/0.13.x/plugin-development/admin-api.md diff --git a/app/gateway-oss/0.13.x/plugin-development/custom-entities.md b/archive/gateway-oss/0.13.x/plugin-development/custom-entities.md similarity index 100% rename from app/gateway-oss/0.13.x/plugin-development/custom-entities.md rename to archive/gateway-oss/0.13.x/plugin-development/custom-entities.md diff --git a/app/gateway-oss/0.13.x/plugin-development/custom-logic.md b/archive/gateway-oss/0.13.x/plugin-development/custom-logic.md similarity index 100% rename from app/gateway-oss/0.13.x/plugin-development/custom-logic.md rename to archive/gateway-oss/0.13.x/plugin-development/custom-logic.md diff --git a/app/gateway-oss/0.13.x/plugin-development/distribution.md b/archive/gateway-oss/0.13.x/plugin-development/distribution.md similarity index 100% rename from app/gateway-oss/0.13.x/plugin-development/distribution.md rename to archive/gateway-oss/0.13.x/plugin-development/distribution.md diff --git a/app/gateway-oss/0.13.x/plugin-development/entities-cache.md b/archive/gateway-oss/0.13.x/plugin-development/entities-cache.md similarity index 100% rename from app/gateway-oss/0.13.x/plugin-development/entities-cache.md rename to archive/gateway-oss/0.13.x/plugin-development/entities-cache.md diff --git a/app/gateway-oss/0.13.x/plugin-development/file-structure.md b/archive/gateway-oss/0.13.x/plugin-development/file-structure.md similarity index 100% rename from app/gateway-oss/0.13.x/plugin-development/file-structure.md rename to archive/gateway-oss/0.13.x/plugin-development/file-structure.md diff --git a/app/gateway-oss/0.13.x/plugin-development/index.md b/archive/gateway-oss/0.13.x/plugin-development/index.md similarity index 100% rename from app/gateway-oss/0.13.x/plugin-development/index.md rename to archive/gateway-oss/0.13.x/plugin-development/index.md diff --git a/app/gateway-oss/0.13.x/plugin-development/plugin-configuration.md b/archive/gateway-oss/0.13.x/plugin-development/plugin-configuration.md similarity index 100% rename from app/gateway-oss/0.13.x/plugin-development/plugin-configuration.md rename to archive/gateway-oss/0.13.x/plugin-development/plugin-configuration.md diff --git a/app/gateway-oss/0.13.x/plugin-development/tests.md b/archive/gateway-oss/0.13.x/plugin-development/tests.md similarity index 100% rename from app/gateway-oss/0.13.x/plugin-development/tests.md rename to archive/gateway-oss/0.13.x/plugin-development/tests.md diff --git a/app/gateway-oss/0.13.x/proxy.md b/archive/gateway-oss/0.13.x/proxy.md similarity index 100% rename from app/gateway-oss/0.13.x/proxy.md rename to archive/gateway-oss/0.13.x/proxy.md diff --git a/app/gateway-oss/0.13.x/secure-admin-api.md b/archive/gateway-oss/0.13.x/secure-admin-api.md similarity index 100% rename from app/gateway-oss/0.13.x/secure-admin-api.md rename to archive/gateway-oss/0.13.x/secure-admin-api.md diff --git a/app/gateway-oss/0.14.x/admin-api.md b/archive/gateway-oss/0.14.x/admin-api.md similarity index 100% rename from app/gateway-oss/0.14.x/admin-api.md rename to archive/gateway-oss/0.14.x/admin-api.md diff --git a/app/gateway-oss/0.14.x/auth.md b/archive/gateway-oss/0.14.x/auth.md similarity index 100% rename from app/gateway-oss/0.14.x/auth.md rename to archive/gateway-oss/0.14.x/auth.md diff --git a/app/gateway-oss/0.14.x/cli.md b/archive/gateway-oss/0.14.x/cli.md similarity index 100% rename from app/gateway-oss/0.14.x/cli.md rename to archive/gateway-oss/0.14.x/cli.md diff --git a/app/gateway-oss/0.14.x/clustering.md b/archive/gateway-oss/0.14.x/clustering.md similarity index 100% rename from app/gateway-oss/0.14.x/clustering.md rename to archive/gateway-oss/0.14.x/clustering.md diff --git a/app/gateway-oss/0.14.x/configuration.md b/archive/gateway-oss/0.14.x/configuration.md similarity index 100% rename from app/gateway-oss/0.14.x/configuration.md rename to archive/gateway-oss/0.14.x/configuration.md diff --git a/app/gateway-oss/0.14.x/getting-started/adding-consumers.md b/archive/gateway-oss/0.14.x/getting-started/adding-consumers.md similarity index 100% rename from app/gateway-oss/0.14.x/getting-started/adding-consumers.md rename to archive/gateway-oss/0.14.x/getting-started/adding-consumers.md diff --git a/app/gateway-oss/0.14.x/getting-started/configuring-a-service.md b/archive/gateway-oss/0.14.x/getting-started/configuring-a-service.md similarity index 100% rename from app/gateway-oss/0.14.x/getting-started/configuring-a-service.md rename to archive/gateway-oss/0.14.x/getting-started/configuring-a-service.md diff --git a/app/gateway-oss/0.14.x/getting-started/enabling-plugins.md b/archive/gateway-oss/0.14.x/getting-started/enabling-plugins.md similarity index 100% rename from app/gateway-oss/0.14.x/getting-started/enabling-plugins.md rename to archive/gateway-oss/0.14.x/getting-started/enabling-plugins.md diff --git a/app/gateway-oss/0.14.x/getting-started/introduction.md b/archive/gateway-oss/0.14.x/getting-started/introduction.md similarity index 100% rename from app/gateway-oss/0.14.x/getting-started/introduction.md rename to archive/gateway-oss/0.14.x/getting-started/introduction.md diff --git a/app/gateway-oss/0.14.x/getting-started/quickstart.md b/archive/gateway-oss/0.14.x/getting-started/quickstart.md similarity index 100% rename from app/gateway-oss/0.14.x/getting-started/quickstart.md rename to archive/gateway-oss/0.14.x/getting-started/quickstart.md diff --git a/app/gateway-oss/0.14.x/health-checks-circuit-breakers.md b/archive/gateway-oss/0.14.x/health-checks-circuit-breakers.md similarity index 100% rename from app/gateway-oss/0.14.x/health-checks-circuit-breakers.md rename to archive/gateway-oss/0.14.x/health-checks-circuit-breakers.md diff --git a/app/gateway-oss/0.14.x/index.md b/archive/gateway-oss/0.14.x/index.md similarity index 100% rename from app/gateway-oss/0.14.x/index.md rename to archive/gateway-oss/0.14.x/index.md diff --git a/app/gateway-oss/0.14.x/loadbalancing.md b/archive/gateway-oss/0.14.x/loadbalancing.md similarity index 100% rename from app/gateway-oss/0.14.x/loadbalancing.md rename to archive/gateway-oss/0.14.x/loadbalancing.md diff --git a/app/gateway-oss/0.14.x/logging.md b/archive/gateway-oss/0.14.x/logging.md similarity index 100% rename from app/gateway-oss/0.14.x/logging.md rename to archive/gateway-oss/0.14.x/logging.md diff --git a/app/gateway-oss/0.14.x/network.md b/archive/gateway-oss/0.14.x/network.md similarity index 100% rename from app/gateway-oss/0.14.x/network.md rename to archive/gateway-oss/0.14.x/network.md diff --git a/app/gateway-oss/0.14.x/pdk/index.md b/archive/gateway-oss/0.14.x/pdk/index.md similarity index 100% rename from app/gateway-oss/0.14.x/pdk/index.md rename to archive/gateway-oss/0.14.x/pdk/index.md diff --git a/app/gateway-oss/0.14.x/pdk/kong.client.md b/archive/gateway-oss/0.14.x/pdk/kong.client.md similarity index 100% rename from app/gateway-oss/0.14.x/pdk/kong.client.md rename to archive/gateway-oss/0.14.x/pdk/kong.client.md diff --git a/app/gateway-oss/0.14.x/pdk/kong.ctx.md b/archive/gateway-oss/0.14.x/pdk/kong.ctx.md similarity index 100% rename from app/gateway-oss/0.14.x/pdk/kong.ctx.md rename to archive/gateway-oss/0.14.x/pdk/kong.ctx.md diff --git a/app/gateway-oss/0.14.x/pdk/kong.ip.md b/archive/gateway-oss/0.14.x/pdk/kong.ip.md similarity index 100% rename from app/gateway-oss/0.14.x/pdk/kong.ip.md rename to archive/gateway-oss/0.14.x/pdk/kong.ip.md diff --git a/app/gateway-oss/0.14.x/pdk/kong.log.md b/archive/gateway-oss/0.14.x/pdk/kong.log.md similarity index 100% rename from app/gateway-oss/0.14.x/pdk/kong.log.md rename to archive/gateway-oss/0.14.x/pdk/kong.log.md diff --git a/app/gateway-oss/0.14.x/pdk/kong.request.md b/archive/gateway-oss/0.14.x/pdk/kong.request.md similarity index 100% rename from app/gateway-oss/0.14.x/pdk/kong.request.md rename to archive/gateway-oss/0.14.x/pdk/kong.request.md diff --git a/app/gateway-oss/0.14.x/pdk/kong.response.md b/archive/gateway-oss/0.14.x/pdk/kong.response.md similarity index 100% rename from app/gateway-oss/0.14.x/pdk/kong.response.md rename to archive/gateway-oss/0.14.x/pdk/kong.response.md diff --git a/app/gateway-oss/0.14.x/pdk/kong.service.md b/archive/gateway-oss/0.14.x/pdk/kong.service.md similarity index 100% rename from app/gateway-oss/0.14.x/pdk/kong.service.md rename to archive/gateway-oss/0.14.x/pdk/kong.service.md diff --git a/app/gateway-oss/0.14.x/pdk/kong.service.request.md b/archive/gateway-oss/0.14.x/pdk/kong.service.request.md similarity index 100% rename from app/gateway-oss/0.14.x/pdk/kong.service.request.md rename to archive/gateway-oss/0.14.x/pdk/kong.service.request.md diff --git a/app/gateway-oss/0.14.x/pdk/kong.service.response.md b/archive/gateway-oss/0.14.x/pdk/kong.service.response.md similarity index 100% rename from app/gateway-oss/0.14.x/pdk/kong.service.response.md rename to archive/gateway-oss/0.14.x/pdk/kong.service.response.md diff --git a/app/gateway-oss/0.14.x/pdk/kong.table.md b/archive/gateway-oss/0.14.x/pdk/kong.table.md similarity index 100% rename from app/gateway-oss/0.14.x/pdk/kong.table.md rename to archive/gateway-oss/0.14.x/pdk/kong.table.md diff --git a/app/gateway-oss/0.14.x/plugin-development/access-the-datastore.md b/archive/gateway-oss/0.14.x/plugin-development/access-the-datastore.md similarity index 100% rename from app/gateway-oss/0.14.x/plugin-development/access-the-datastore.md rename to archive/gateway-oss/0.14.x/plugin-development/access-the-datastore.md diff --git a/app/gateway-oss/0.14.x/plugin-development/admin-api.md b/archive/gateway-oss/0.14.x/plugin-development/admin-api.md similarity index 100% rename from app/gateway-oss/0.14.x/plugin-development/admin-api.md rename to archive/gateway-oss/0.14.x/plugin-development/admin-api.md diff --git a/app/gateway-oss/0.14.x/plugin-development/custom-entities.md b/archive/gateway-oss/0.14.x/plugin-development/custom-entities.md similarity index 100% rename from app/gateway-oss/0.14.x/plugin-development/custom-entities.md rename to archive/gateway-oss/0.14.x/plugin-development/custom-entities.md diff --git a/app/gateway-oss/0.14.x/plugin-development/custom-logic.md b/archive/gateway-oss/0.14.x/plugin-development/custom-logic.md similarity index 100% rename from app/gateway-oss/0.14.x/plugin-development/custom-logic.md rename to archive/gateway-oss/0.14.x/plugin-development/custom-logic.md diff --git a/app/gateway-oss/0.14.x/plugin-development/distribution.md b/archive/gateway-oss/0.14.x/plugin-development/distribution.md similarity index 100% rename from app/gateway-oss/0.14.x/plugin-development/distribution.md rename to archive/gateway-oss/0.14.x/plugin-development/distribution.md diff --git a/app/gateway-oss/0.14.x/plugin-development/entities-cache.md b/archive/gateway-oss/0.14.x/plugin-development/entities-cache.md similarity index 100% rename from app/gateway-oss/0.14.x/plugin-development/entities-cache.md rename to archive/gateway-oss/0.14.x/plugin-development/entities-cache.md diff --git a/app/gateway-oss/0.14.x/plugin-development/file-structure.md b/archive/gateway-oss/0.14.x/plugin-development/file-structure.md similarity index 100% rename from app/gateway-oss/0.14.x/plugin-development/file-structure.md rename to archive/gateway-oss/0.14.x/plugin-development/file-structure.md diff --git a/app/gateway-oss/0.14.x/plugin-development/index.md b/archive/gateway-oss/0.14.x/plugin-development/index.md similarity index 100% rename from app/gateway-oss/0.14.x/plugin-development/index.md rename to archive/gateway-oss/0.14.x/plugin-development/index.md diff --git a/app/gateway-oss/0.14.x/plugin-development/plugin-configuration.md b/archive/gateway-oss/0.14.x/plugin-development/plugin-configuration.md similarity index 100% rename from app/gateway-oss/0.14.x/plugin-development/plugin-configuration.md rename to archive/gateway-oss/0.14.x/plugin-development/plugin-configuration.md diff --git a/app/gateway-oss/0.14.x/plugin-development/tests.md b/archive/gateway-oss/0.14.x/plugin-development/tests.md similarity index 100% rename from app/gateway-oss/0.14.x/plugin-development/tests.md rename to archive/gateway-oss/0.14.x/plugin-development/tests.md diff --git a/app/gateway-oss/0.14.x/proxy.md b/archive/gateway-oss/0.14.x/proxy.md similarity index 100% rename from app/gateway-oss/0.14.x/proxy.md rename to archive/gateway-oss/0.14.x/proxy.md diff --git a/app/gateway-oss/0.14.x/secure-admin-api.md b/archive/gateway-oss/0.14.x/secure-admin-api.md similarity index 100% rename from app/gateway-oss/0.14.x/secure-admin-api.md rename to archive/gateway-oss/0.14.x/secure-admin-api.md diff --git a/app/gateway-oss/0.15.x/configuration.md b/archive/gateway-oss/0.15.x/configuration.md similarity index 100% rename from app/gateway-oss/0.15.x/configuration.md rename to archive/gateway-oss/0.15.x/configuration.md diff --git a/app/gateway-oss/1.0.x/admin-api.md b/archive/gateway-oss/1.0.x/admin-api.md similarity index 100% rename from app/gateway-oss/1.0.x/admin-api.md rename to archive/gateway-oss/1.0.x/admin-api.md diff --git a/app/gateway-oss/1.0.x/auth.md b/archive/gateway-oss/1.0.x/auth.md similarity index 100% rename from app/gateway-oss/1.0.x/auth.md rename to archive/gateway-oss/1.0.x/auth.md diff --git a/app/gateway-oss/1.0.x/cli.md b/archive/gateway-oss/1.0.x/cli.md similarity index 100% rename from app/gateway-oss/1.0.x/cli.md rename to archive/gateway-oss/1.0.x/cli.md diff --git a/app/gateway-oss/1.0.x/clustering.md b/archive/gateway-oss/1.0.x/clustering.md similarity index 100% rename from app/gateway-oss/1.0.x/clustering.md rename to archive/gateway-oss/1.0.x/clustering.md diff --git a/app/gateway-oss/1.0.x/configuration.md b/archive/gateway-oss/1.0.x/configuration.md similarity index 100% rename from app/gateway-oss/1.0.x/configuration.md rename to archive/gateway-oss/1.0.x/configuration.md diff --git a/app/gateway-oss/1.0.x/getting-started/adding-consumers.md b/archive/gateway-oss/1.0.x/getting-started/adding-consumers.md similarity index 100% rename from app/gateway-oss/1.0.x/getting-started/adding-consumers.md rename to archive/gateway-oss/1.0.x/getting-started/adding-consumers.md diff --git a/app/gateway-oss/1.0.x/getting-started/configuring-a-service.md b/archive/gateway-oss/1.0.x/getting-started/configuring-a-service.md similarity index 100% rename from app/gateway-oss/1.0.x/getting-started/configuring-a-service.md rename to archive/gateway-oss/1.0.x/getting-started/configuring-a-service.md diff --git a/app/gateway-oss/1.0.x/getting-started/enabling-plugins.md b/archive/gateway-oss/1.0.x/getting-started/enabling-plugins.md similarity index 100% rename from app/gateway-oss/1.0.x/getting-started/enabling-plugins.md rename to archive/gateway-oss/1.0.x/getting-started/enabling-plugins.md diff --git a/app/gateway-oss/1.0.x/getting-started/introduction.md b/archive/gateway-oss/1.0.x/getting-started/introduction.md similarity index 100% rename from app/gateway-oss/1.0.x/getting-started/introduction.md rename to archive/gateway-oss/1.0.x/getting-started/introduction.md diff --git a/app/gateway-oss/1.0.x/getting-started/quickstart.md b/archive/gateway-oss/1.0.x/getting-started/quickstart.md similarity index 100% rename from app/gateway-oss/1.0.x/getting-started/quickstart.md rename to archive/gateway-oss/1.0.x/getting-started/quickstart.md diff --git a/app/gateway-oss/1.0.x/health-checks-circuit-breakers.md b/archive/gateway-oss/1.0.x/health-checks-circuit-breakers.md similarity index 100% rename from app/gateway-oss/1.0.x/health-checks-circuit-breakers.md rename to archive/gateway-oss/1.0.x/health-checks-circuit-breakers.md diff --git a/app/gateway-oss/1.0.x/index.md b/archive/gateway-oss/1.0.x/index.md similarity index 100% rename from app/gateway-oss/1.0.x/index.md rename to archive/gateway-oss/1.0.x/index.md diff --git a/app/gateway-oss/1.0.x/loadbalancing.md b/archive/gateway-oss/1.0.x/loadbalancing.md similarity index 100% rename from app/gateway-oss/1.0.x/loadbalancing.md rename to archive/gateway-oss/1.0.x/loadbalancing.md diff --git a/app/gateway-oss/1.0.x/logging.md b/archive/gateway-oss/1.0.x/logging.md similarity index 100% rename from app/gateway-oss/1.0.x/logging.md rename to archive/gateway-oss/1.0.x/logging.md diff --git a/app/gateway-oss/1.0.x/network.md b/archive/gateway-oss/1.0.x/network.md similarity index 100% rename from app/gateway-oss/1.0.x/network.md rename to archive/gateway-oss/1.0.x/network.md diff --git a/app/gateway-oss/1.0.x/pdk/index.md b/archive/gateway-oss/1.0.x/pdk/index.md similarity index 100% rename from app/gateway-oss/1.0.x/pdk/index.md rename to archive/gateway-oss/1.0.x/pdk/index.md diff --git a/app/gateway-oss/1.0.x/pdk/kong.client.md b/archive/gateway-oss/1.0.x/pdk/kong.client.md similarity index 100% rename from app/gateway-oss/1.0.x/pdk/kong.client.md rename to archive/gateway-oss/1.0.x/pdk/kong.client.md diff --git a/app/gateway-oss/1.0.x/pdk/kong.ctx.md b/archive/gateway-oss/1.0.x/pdk/kong.ctx.md similarity index 100% rename from app/gateway-oss/1.0.x/pdk/kong.ctx.md rename to archive/gateway-oss/1.0.x/pdk/kong.ctx.md diff --git a/app/gateway-oss/1.0.x/pdk/kong.ip.md b/archive/gateway-oss/1.0.x/pdk/kong.ip.md similarity index 100% rename from app/gateway-oss/1.0.x/pdk/kong.ip.md rename to archive/gateway-oss/1.0.x/pdk/kong.ip.md diff --git a/app/gateway-oss/1.0.x/pdk/kong.log.md b/archive/gateway-oss/1.0.x/pdk/kong.log.md similarity index 100% rename from app/gateway-oss/1.0.x/pdk/kong.log.md rename to archive/gateway-oss/1.0.x/pdk/kong.log.md diff --git a/app/gateway-oss/1.0.x/pdk/kong.node.md b/archive/gateway-oss/1.0.x/pdk/kong.node.md similarity index 100% rename from app/gateway-oss/1.0.x/pdk/kong.node.md rename to archive/gateway-oss/1.0.x/pdk/kong.node.md diff --git a/app/gateway-oss/1.0.x/pdk/kong.request.md b/archive/gateway-oss/1.0.x/pdk/kong.request.md similarity index 100% rename from app/gateway-oss/1.0.x/pdk/kong.request.md rename to archive/gateway-oss/1.0.x/pdk/kong.request.md diff --git a/app/gateway-oss/1.0.x/pdk/kong.response.md b/archive/gateway-oss/1.0.x/pdk/kong.response.md similarity index 100% rename from app/gateway-oss/1.0.x/pdk/kong.response.md rename to archive/gateway-oss/1.0.x/pdk/kong.response.md diff --git a/app/gateway-oss/1.0.x/pdk/kong.router.md b/archive/gateway-oss/1.0.x/pdk/kong.router.md similarity index 100% rename from app/gateway-oss/1.0.x/pdk/kong.router.md rename to archive/gateway-oss/1.0.x/pdk/kong.router.md diff --git a/app/gateway-oss/1.0.x/pdk/kong.service.md b/archive/gateway-oss/1.0.x/pdk/kong.service.md similarity index 100% rename from app/gateway-oss/1.0.x/pdk/kong.service.md rename to archive/gateway-oss/1.0.x/pdk/kong.service.md diff --git a/app/gateway-oss/1.0.x/pdk/kong.service.request.md b/archive/gateway-oss/1.0.x/pdk/kong.service.request.md similarity index 100% rename from app/gateway-oss/1.0.x/pdk/kong.service.request.md rename to archive/gateway-oss/1.0.x/pdk/kong.service.request.md diff --git a/app/gateway-oss/1.0.x/pdk/kong.service.response.md b/archive/gateway-oss/1.0.x/pdk/kong.service.response.md similarity index 100% rename from app/gateway-oss/1.0.x/pdk/kong.service.response.md rename to archive/gateway-oss/1.0.x/pdk/kong.service.response.md diff --git a/app/gateway-oss/1.0.x/pdk/kong.table.md b/archive/gateway-oss/1.0.x/pdk/kong.table.md similarity index 100% rename from app/gateway-oss/1.0.x/pdk/kong.table.md rename to archive/gateway-oss/1.0.x/pdk/kong.table.md diff --git a/app/gateway-oss/1.0.x/plugin-development/access-the-datastore.md b/archive/gateway-oss/1.0.x/plugin-development/access-the-datastore.md similarity index 100% rename from app/gateway-oss/1.0.x/plugin-development/access-the-datastore.md rename to archive/gateway-oss/1.0.x/plugin-development/access-the-datastore.md diff --git a/app/gateway-oss/1.0.x/plugin-development/admin-api.md b/archive/gateway-oss/1.0.x/plugin-development/admin-api.md similarity index 100% rename from app/gateway-oss/1.0.x/plugin-development/admin-api.md rename to archive/gateway-oss/1.0.x/plugin-development/admin-api.md diff --git a/app/gateway-oss/1.0.x/plugin-development/custom-entities.md b/archive/gateway-oss/1.0.x/plugin-development/custom-entities.md similarity index 100% rename from app/gateway-oss/1.0.x/plugin-development/custom-entities.md rename to archive/gateway-oss/1.0.x/plugin-development/custom-entities.md diff --git a/app/gateway-oss/1.0.x/plugin-development/custom-logic.md b/archive/gateway-oss/1.0.x/plugin-development/custom-logic.md similarity index 100% rename from app/gateway-oss/1.0.x/plugin-development/custom-logic.md rename to archive/gateway-oss/1.0.x/plugin-development/custom-logic.md diff --git a/app/gateway-oss/1.0.x/plugin-development/distribution.md b/archive/gateway-oss/1.0.x/plugin-development/distribution.md similarity index 100% rename from app/gateway-oss/1.0.x/plugin-development/distribution.md rename to archive/gateway-oss/1.0.x/plugin-development/distribution.md diff --git a/app/gateway-oss/1.0.x/plugin-development/entities-cache.md b/archive/gateway-oss/1.0.x/plugin-development/entities-cache.md similarity index 100% rename from app/gateway-oss/1.0.x/plugin-development/entities-cache.md rename to archive/gateway-oss/1.0.x/plugin-development/entities-cache.md diff --git a/app/gateway-oss/1.0.x/plugin-development/file-structure.md b/archive/gateway-oss/1.0.x/plugin-development/file-structure.md similarity index 100% rename from app/gateway-oss/1.0.x/plugin-development/file-structure.md rename to archive/gateway-oss/1.0.x/plugin-development/file-structure.md diff --git a/app/gateway-oss/1.0.x/plugin-development/index.md b/archive/gateway-oss/1.0.x/plugin-development/index.md similarity index 100% rename from app/gateway-oss/1.0.x/plugin-development/index.md rename to archive/gateway-oss/1.0.x/plugin-development/index.md diff --git a/app/gateway-oss/1.0.x/plugin-development/plugin-configuration.md b/archive/gateway-oss/1.0.x/plugin-development/plugin-configuration.md similarity index 100% rename from app/gateway-oss/1.0.x/plugin-development/plugin-configuration.md rename to archive/gateway-oss/1.0.x/plugin-development/plugin-configuration.md diff --git a/app/gateway-oss/1.0.x/plugin-development/tests.md b/archive/gateway-oss/1.0.x/plugin-development/tests.md similarity index 100% rename from app/gateway-oss/1.0.x/plugin-development/tests.md rename to archive/gateway-oss/1.0.x/plugin-development/tests.md diff --git a/app/gateway-oss/1.0.x/proxy.md b/archive/gateway-oss/1.0.x/proxy.md similarity index 100% rename from app/gateway-oss/1.0.x/proxy.md rename to archive/gateway-oss/1.0.x/proxy.md diff --git a/app/gateway-oss/1.0.x/secure-admin-api.md b/archive/gateway-oss/1.0.x/secure-admin-api.md similarity index 100% rename from app/gateway-oss/1.0.x/secure-admin-api.md rename to archive/gateway-oss/1.0.x/secure-admin-api.md diff --git a/app/gateway-oss/1.0.x/streams-and-service-mesh.md b/archive/gateway-oss/1.0.x/streams-and-service-mesh.md similarity index 100% rename from app/gateway-oss/1.0.x/streams-and-service-mesh.md rename to archive/gateway-oss/1.0.x/streams-and-service-mesh.md diff --git a/app/gateway-oss/1.0.x/upgrading.md b/archive/gateway-oss/1.0.x/upgrading.md similarity index 100% rename from app/gateway-oss/1.0.x/upgrading.md rename to archive/gateway-oss/1.0.x/upgrading.md diff --git a/app/gateway-oss/1.1.x/admin-api.md b/archive/gateway-oss/1.1.x/admin-api.md similarity index 100% rename from app/gateway-oss/1.1.x/admin-api.md rename to archive/gateway-oss/1.1.x/admin-api.md diff --git a/app/gateway-oss/1.1.x/auth.md b/archive/gateway-oss/1.1.x/auth.md similarity index 100% rename from app/gateway-oss/1.1.x/auth.md rename to archive/gateway-oss/1.1.x/auth.md diff --git a/app/gateway-oss/1.1.x/cli.md b/archive/gateway-oss/1.1.x/cli.md similarity index 100% rename from app/gateway-oss/1.1.x/cli.md rename to archive/gateway-oss/1.1.x/cli.md diff --git a/app/gateway-oss/1.1.x/clustering.md b/archive/gateway-oss/1.1.x/clustering.md similarity index 100% rename from app/gateway-oss/1.1.x/clustering.md rename to archive/gateway-oss/1.1.x/clustering.md diff --git a/app/gateway-oss/1.1.x/configuration.md b/archive/gateway-oss/1.1.x/configuration.md similarity index 100% rename from app/gateway-oss/1.1.x/configuration.md rename to archive/gateway-oss/1.1.x/configuration.md diff --git a/app/gateway-oss/1.1.x/db-less-admin-api.md b/archive/gateway-oss/1.1.x/db-less-admin-api.md similarity index 100% rename from app/gateway-oss/1.1.x/db-less-admin-api.md rename to archive/gateway-oss/1.1.x/db-less-admin-api.md diff --git a/app/gateway-oss/1.1.x/db-less-and-declarative-config.md b/archive/gateway-oss/1.1.x/db-less-and-declarative-config.md similarity index 100% rename from app/gateway-oss/1.1.x/db-less-and-declarative-config.md rename to archive/gateway-oss/1.1.x/db-less-and-declarative-config.md diff --git a/app/gateway-oss/1.1.x/getting-started/adding-consumers.md b/archive/gateway-oss/1.1.x/getting-started/adding-consumers.md similarity index 100% rename from app/gateway-oss/1.1.x/getting-started/adding-consumers.md rename to archive/gateway-oss/1.1.x/getting-started/adding-consumers.md diff --git a/app/gateway-oss/1.1.x/getting-started/configuring-a-service.md b/archive/gateway-oss/1.1.x/getting-started/configuring-a-service.md similarity index 100% rename from app/gateway-oss/1.1.x/getting-started/configuring-a-service.md rename to archive/gateway-oss/1.1.x/getting-started/configuring-a-service.md diff --git a/app/gateway-oss/1.1.x/getting-started/enabling-plugins.md b/archive/gateway-oss/1.1.x/getting-started/enabling-plugins.md similarity index 100% rename from app/gateway-oss/1.1.x/getting-started/enabling-plugins.md rename to archive/gateway-oss/1.1.x/getting-started/enabling-plugins.md diff --git a/app/gateway-oss/1.1.x/getting-started/introduction.md b/archive/gateway-oss/1.1.x/getting-started/introduction.md similarity index 100% rename from app/gateway-oss/1.1.x/getting-started/introduction.md rename to archive/gateway-oss/1.1.x/getting-started/introduction.md diff --git a/app/gateway-oss/1.1.x/getting-started/quickstart.md b/archive/gateway-oss/1.1.x/getting-started/quickstart.md similarity index 100% rename from app/gateway-oss/1.1.x/getting-started/quickstart.md rename to archive/gateway-oss/1.1.x/getting-started/quickstart.md diff --git a/app/gateway-oss/1.1.x/health-checks-circuit-breakers.md b/archive/gateway-oss/1.1.x/health-checks-circuit-breakers.md similarity index 100% rename from app/gateway-oss/1.1.x/health-checks-circuit-breakers.md rename to archive/gateway-oss/1.1.x/health-checks-circuit-breakers.md diff --git a/app/gateway-oss/1.1.x/index.md b/archive/gateway-oss/1.1.x/index.md similarity index 100% rename from app/gateway-oss/1.1.x/index.md rename to archive/gateway-oss/1.1.x/index.md diff --git a/app/gateway-oss/1.1.x/loadbalancing.md b/archive/gateway-oss/1.1.x/loadbalancing.md similarity index 100% rename from app/gateway-oss/1.1.x/loadbalancing.md rename to archive/gateway-oss/1.1.x/loadbalancing.md diff --git a/app/gateway-oss/1.1.x/logging.md b/archive/gateway-oss/1.1.x/logging.md similarity index 100% rename from app/gateway-oss/1.1.x/logging.md rename to archive/gateway-oss/1.1.x/logging.md diff --git a/app/gateway-oss/1.1.x/network.md b/archive/gateway-oss/1.1.x/network.md similarity index 100% rename from app/gateway-oss/1.1.x/network.md rename to archive/gateway-oss/1.1.x/network.md diff --git a/app/gateway-oss/1.1.x/pdk/index.md b/archive/gateway-oss/1.1.x/pdk/index.md similarity index 100% rename from app/gateway-oss/1.1.x/pdk/index.md rename to archive/gateway-oss/1.1.x/pdk/index.md diff --git a/app/gateway-oss/1.1.x/pdk/kong.client.md b/archive/gateway-oss/1.1.x/pdk/kong.client.md similarity index 100% rename from app/gateway-oss/1.1.x/pdk/kong.client.md rename to archive/gateway-oss/1.1.x/pdk/kong.client.md diff --git a/app/gateway-oss/1.1.x/pdk/kong.ctx.md b/archive/gateway-oss/1.1.x/pdk/kong.ctx.md similarity index 100% rename from app/gateway-oss/1.1.x/pdk/kong.ctx.md rename to archive/gateway-oss/1.1.x/pdk/kong.ctx.md diff --git a/app/gateway-oss/1.1.x/pdk/kong.ip.md b/archive/gateway-oss/1.1.x/pdk/kong.ip.md similarity index 100% rename from app/gateway-oss/1.1.x/pdk/kong.ip.md rename to archive/gateway-oss/1.1.x/pdk/kong.ip.md diff --git a/app/gateway-oss/1.1.x/pdk/kong.log.md b/archive/gateway-oss/1.1.x/pdk/kong.log.md similarity index 100% rename from app/gateway-oss/1.1.x/pdk/kong.log.md rename to archive/gateway-oss/1.1.x/pdk/kong.log.md diff --git a/app/gateway-oss/1.1.x/pdk/kong.node.md b/archive/gateway-oss/1.1.x/pdk/kong.node.md similarity index 100% rename from app/gateway-oss/1.1.x/pdk/kong.node.md rename to archive/gateway-oss/1.1.x/pdk/kong.node.md diff --git a/app/gateway-oss/1.1.x/pdk/kong.request.md b/archive/gateway-oss/1.1.x/pdk/kong.request.md similarity index 100% rename from app/gateway-oss/1.1.x/pdk/kong.request.md rename to archive/gateway-oss/1.1.x/pdk/kong.request.md diff --git a/app/gateway-oss/1.1.x/pdk/kong.response.md b/archive/gateway-oss/1.1.x/pdk/kong.response.md similarity index 100% rename from app/gateway-oss/1.1.x/pdk/kong.response.md rename to archive/gateway-oss/1.1.x/pdk/kong.response.md diff --git a/app/gateway-oss/1.1.x/pdk/kong.router.md b/archive/gateway-oss/1.1.x/pdk/kong.router.md similarity index 100% rename from app/gateway-oss/1.1.x/pdk/kong.router.md rename to archive/gateway-oss/1.1.x/pdk/kong.router.md diff --git a/app/gateway-oss/1.1.x/pdk/kong.service.md b/archive/gateway-oss/1.1.x/pdk/kong.service.md similarity index 100% rename from app/gateway-oss/1.1.x/pdk/kong.service.md rename to archive/gateway-oss/1.1.x/pdk/kong.service.md diff --git a/app/gateway-oss/1.1.x/pdk/kong.service.request.md b/archive/gateway-oss/1.1.x/pdk/kong.service.request.md similarity index 100% rename from app/gateway-oss/1.1.x/pdk/kong.service.request.md rename to archive/gateway-oss/1.1.x/pdk/kong.service.request.md diff --git a/app/gateway-oss/1.1.x/pdk/kong.service.response.md b/archive/gateway-oss/1.1.x/pdk/kong.service.response.md similarity index 100% rename from app/gateway-oss/1.1.x/pdk/kong.service.response.md rename to archive/gateway-oss/1.1.x/pdk/kong.service.response.md diff --git a/app/gateway-oss/1.1.x/pdk/kong.table.md b/archive/gateway-oss/1.1.x/pdk/kong.table.md similarity index 100% rename from app/gateway-oss/1.1.x/pdk/kong.table.md rename to archive/gateway-oss/1.1.x/pdk/kong.table.md diff --git a/app/gateway-oss/1.1.x/plugin-development/access-the-datastore.md b/archive/gateway-oss/1.1.x/plugin-development/access-the-datastore.md similarity index 100% rename from app/gateway-oss/1.1.x/plugin-development/access-the-datastore.md rename to archive/gateway-oss/1.1.x/plugin-development/access-the-datastore.md diff --git a/app/gateway-oss/1.1.x/plugin-development/admin-api.md b/archive/gateway-oss/1.1.x/plugin-development/admin-api.md similarity index 100% rename from app/gateway-oss/1.1.x/plugin-development/admin-api.md rename to archive/gateway-oss/1.1.x/plugin-development/admin-api.md diff --git a/app/gateway-oss/1.1.x/plugin-development/custom-entities.md b/archive/gateway-oss/1.1.x/plugin-development/custom-entities.md similarity index 100% rename from app/gateway-oss/1.1.x/plugin-development/custom-entities.md rename to archive/gateway-oss/1.1.x/plugin-development/custom-entities.md diff --git a/app/gateway-oss/1.1.x/plugin-development/custom-logic.md b/archive/gateway-oss/1.1.x/plugin-development/custom-logic.md similarity index 100% rename from app/gateway-oss/1.1.x/plugin-development/custom-logic.md rename to archive/gateway-oss/1.1.x/plugin-development/custom-logic.md diff --git a/app/gateway-oss/1.1.x/plugin-development/distribution.md b/archive/gateway-oss/1.1.x/plugin-development/distribution.md similarity index 100% rename from app/gateway-oss/1.1.x/plugin-development/distribution.md rename to archive/gateway-oss/1.1.x/plugin-development/distribution.md diff --git a/app/gateway-oss/1.1.x/plugin-development/entities-cache.md b/archive/gateway-oss/1.1.x/plugin-development/entities-cache.md similarity index 100% rename from app/gateway-oss/1.1.x/plugin-development/entities-cache.md rename to archive/gateway-oss/1.1.x/plugin-development/entities-cache.md diff --git a/app/gateway-oss/1.1.x/plugin-development/file-structure.md b/archive/gateway-oss/1.1.x/plugin-development/file-structure.md similarity index 100% rename from app/gateway-oss/1.1.x/plugin-development/file-structure.md rename to archive/gateway-oss/1.1.x/plugin-development/file-structure.md diff --git a/app/gateway-oss/1.1.x/plugin-development/index.md b/archive/gateway-oss/1.1.x/plugin-development/index.md similarity index 100% rename from app/gateway-oss/1.1.x/plugin-development/index.md rename to archive/gateway-oss/1.1.x/plugin-development/index.md diff --git a/app/gateway-oss/1.1.x/plugin-development/plugin-configuration.md b/archive/gateway-oss/1.1.x/plugin-development/plugin-configuration.md similarity index 100% rename from app/gateway-oss/1.1.x/plugin-development/plugin-configuration.md rename to archive/gateway-oss/1.1.x/plugin-development/plugin-configuration.md diff --git a/app/gateway-oss/1.1.x/plugin-development/tests.md b/archive/gateway-oss/1.1.x/plugin-development/tests.md similarity index 100% rename from app/gateway-oss/1.1.x/plugin-development/tests.md rename to archive/gateway-oss/1.1.x/plugin-development/tests.md diff --git a/app/gateway-oss/1.1.x/proxy.md b/archive/gateway-oss/1.1.x/proxy.md similarity index 100% rename from app/gateway-oss/1.1.x/proxy.md rename to archive/gateway-oss/1.1.x/proxy.md diff --git a/app/gateway-oss/1.1.x/secure-admin-api.md b/archive/gateway-oss/1.1.x/secure-admin-api.md similarity index 100% rename from app/gateway-oss/1.1.x/secure-admin-api.md rename to archive/gateway-oss/1.1.x/secure-admin-api.md diff --git a/app/gateway-oss/1.1.x/streams-and-service-mesh.md b/archive/gateway-oss/1.1.x/streams-and-service-mesh.md similarity index 100% rename from app/gateway-oss/1.1.x/streams-and-service-mesh.md rename to archive/gateway-oss/1.1.x/streams-and-service-mesh.md diff --git a/app/gateway-oss/1.1.x/upgrading.md b/archive/gateway-oss/1.1.x/upgrading.md similarity index 100% rename from app/gateway-oss/1.1.x/upgrading.md rename to archive/gateway-oss/1.1.x/upgrading.md diff --git a/app/gateway-oss/1.2.x/admin-api.md b/archive/gateway-oss/1.2.x/admin-api.md similarity index 100% rename from app/gateway-oss/1.2.x/admin-api.md rename to archive/gateway-oss/1.2.x/admin-api.md diff --git a/app/gateway-oss/1.2.x/auth.md b/archive/gateway-oss/1.2.x/auth.md similarity index 100% rename from app/gateway-oss/1.2.x/auth.md rename to archive/gateway-oss/1.2.x/auth.md diff --git a/app/gateway-oss/1.2.x/cli.md b/archive/gateway-oss/1.2.x/cli.md similarity index 100% rename from app/gateway-oss/1.2.x/cli.md rename to archive/gateway-oss/1.2.x/cli.md diff --git a/app/gateway-oss/1.2.x/clustering.md b/archive/gateway-oss/1.2.x/clustering.md similarity index 100% rename from app/gateway-oss/1.2.x/clustering.md rename to archive/gateway-oss/1.2.x/clustering.md diff --git a/app/gateway-oss/1.2.x/configuration.md b/archive/gateway-oss/1.2.x/configuration.md similarity index 100% rename from app/gateway-oss/1.2.x/configuration.md rename to archive/gateway-oss/1.2.x/configuration.md diff --git a/app/gateway-oss/1.2.x/db-less-admin-api.md b/archive/gateway-oss/1.2.x/db-less-admin-api.md similarity index 100% rename from app/gateway-oss/1.2.x/db-less-admin-api.md rename to archive/gateway-oss/1.2.x/db-less-admin-api.md diff --git a/app/gateway-oss/1.2.x/db-less-and-declarative-config.md b/archive/gateway-oss/1.2.x/db-less-and-declarative-config.md similarity index 100% rename from app/gateway-oss/1.2.x/db-less-and-declarative-config.md rename to archive/gateway-oss/1.2.x/db-less-and-declarative-config.md diff --git a/app/gateway-oss/1.2.x/getting-started/adding-consumers.md b/archive/gateway-oss/1.2.x/getting-started/adding-consumers.md similarity index 100% rename from app/gateway-oss/1.2.x/getting-started/adding-consumers.md rename to archive/gateway-oss/1.2.x/getting-started/adding-consumers.md diff --git a/app/gateway-oss/1.2.x/getting-started/configuring-a-service.md b/archive/gateway-oss/1.2.x/getting-started/configuring-a-service.md similarity index 100% rename from app/gateway-oss/1.2.x/getting-started/configuring-a-service.md rename to archive/gateway-oss/1.2.x/getting-started/configuring-a-service.md diff --git a/app/gateway-oss/1.2.x/getting-started/enabling-plugins.md b/archive/gateway-oss/1.2.x/getting-started/enabling-plugins.md similarity index 100% rename from app/gateway-oss/1.2.x/getting-started/enabling-plugins.md rename to archive/gateway-oss/1.2.x/getting-started/enabling-plugins.md diff --git a/app/gateway-oss/1.2.x/getting-started/introduction.md b/archive/gateway-oss/1.2.x/getting-started/introduction.md similarity index 100% rename from app/gateway-oss/1.2.x/getting-started/introduction.md rename to archive/gateway-oss/1.2.x/getting-started/introduction.md diff --git a/app/gateway-oss/1.2.x/getting-started/quickstart.md b/archive/gateway-oss/1.2.x/getting-started/quickstart.md similarity index 100% rename from app/gateway-oss/1.2.x/getting-started/quickstart.md rename to archive/gateway-oss/1.2.x/getting-started/quickstart.md diff --git a/app/gateway-oss/1.2.x/health-checks-circuit-breakers.md b/archive/gateway-oss/1.2.x/health-checks-circuit-breakers.md similarity index 100% rename from app/gateway-oss/1.2.x/health-checks-circuit-breakers.md rename to archive/gateway-oss/1.2.x/health-checks-circuit-breakers.md diff --git a/app/gateway-oss/1.2.x/index.md b/archive/gateway-oss/1.2.x/index.md similarity index 100% rename from app/gateway-oss/1.2.x/index.md rename to archive/gateway-oss/1.2.x/index.md diff --git a/app/gateway-oss/1.2.x/loadbalancing.md b/archive/gateway-oss/1.2.x/loadbalancing.md similarity index 100% rename from app/gateway-oss/1.2.x/loadbalancing.md rename to archive/gateway-oss/1.2.x/loadbalancing.md diff --git a/app/gateway-oss/1.2.x/logging.md b/archive/gateway-oss/1.2.x/logging.md similarity index 100% rename from app/gateway-oss/1.2.x/logging.md rename to archive/gateway-oss/1.2.x/logging.md diff --git a/app/gateway-oss/1.2.x/network.md b/archive/gateway-oss/1.2.x/network.md similarity index 100% rename from app/gateway-oss/1.2.x/network.md rename to archive/gateway-oss/1.2.x/network.md diff --git a/app/gateway-oss/1.2.x/pdk/index.md b/archive/gateway-oss/1.2.x/pdk/index.md similarity index 100% rename from app/gateway-oss/1.2.x/pdk/index.md rename to archive/gateway-oss/1.2.x/pdk/index.md diff --git a/app/gateway-oss/1.2.x/pdk/kong.client.md b/archive/gateway-oss/1.2.x/pdk/kong.client.md similarity index 100% rename from app/gateway-oss/1.2.x/pdk/kong.client.md rename to archive/gateway-oss/1.2.x/pdk/kong.client.md diff --git a/app/gateway-oss/1.2.x/pdk/kong.ctx.md b/archive/gateway-oss/1.2.x/pdk/kong.ctx.md similarity index 100% rename from app/gateway-oss/1.2.x/pdk/kong.ctx.md rename to archive/gateway-oss/1.2.x/pdk/kong.ctx.md diff --git a/app/gateway-oss/1.2.x/pdk/kong.ip.md b/archive/gateway-oss/1.2.x/pdk/kong.ip.md similarity index 100% rename from app/gateway-oss/1.2.x/pdk/kong.ip.md rename to archive/gateway-oss/1.2.x/pdk/kong.ip.md diff --git a/app/gateway-oss/1.2.x/pdk/kong.log.md b/archive/gateway-oss/1.2.x/pdk/kong.log.md similarity index 100% rename from app/gateway-oss/1.2.x/pdk/kong.log.md rename to archive/gateway-oss/1.2.x/pdk/kong.log.md diff --git a/app/gateway-oss/1.2.x/pdk/kong.node.md b/archive/gateway-oss/1.2.x/pdk/kong.node.md similarity index 100% rename from app/gateway-oss/1.2.x/pdk/kong.node.md rename to archive/gateway-oss/1.2.x/pdk/kong.node.md diff --git a/app/gateway-oss/1.2.x/pdk/kong.request.md b/archive/gateway-oss/1.2.x/pdk/kong.request.md similarity index 100% rename from app/gateway-oss/1.2.x/pdk/kong.request.md rename to archive/gateway-oss/1.2.x/pdk/kong.request.md diff --git a/app/gateway-oss/1.2.x/pdk/kong.response.md b/archive/gateway-oss/1.2.x/pdk/kong.response.md similarity index 100% rename from app/gateway-oss/1.2.x/pdk/kong.response.md rename to archive/gateway-oss/1.2.x/pdk/kong.response.md diff --git a/app/gateway-oss/1.2.x/pdk/kong.router.md b/archive/gateway-oss/1.2.x/pdk/kong.router.md similarity index 100% rename from app/gateway-oss/1.2.x/pdk/kong.router.md rename to archive/gateway-oss/1.2.x/pdk/kong.router.md diff --git a/app/gateway-oss/1.2.x/pdk/kong.service.md b/archive/gateway-oss/1.2.x/pdk/kong.service.md similarity index 100% rename from app/gateway-oss/1.2.x/pdk/kong.service.md rename to archive/gateway-oss/1.2.x/pdk/kong.service.md diff --git a/app/gateway-oss/1.2.x/pdk/kong.service.request.md b/archive/gateway-oss/1.2.x/pdk/kong.service.request.md similarity index 100% rename from app/gateway-oss/1.2.x/pdk/kong.service.request.md rename to archive/gateway-oss/1.2.x/pdk/kong.service.request.md diff --git a/app/gateway-oss/1.2.x/pdk/kong.service.response.md b/archive/gateway-oss/1.2.x/pdk/kong.service.response.md similarity index 100% rename from app/gateway-oss/1.2.x/pdk/kong.service.response.md rename to archive/gateway-oss/1.2.x/pdk/kong.service.response.md diff --git a/app/gateway-oss/1.2.x/pdk/kong.table.md b/archive/gateway-oss/1.2.x/pdk/kong.table.md similarity index 100% rename from app/gateway-oss/1.2.x/pdk/kong.table.md rename to archive/gateway-oss/1.2.x/pdk/kong.table.md diff --git a/app/gateway-oss/1.2.x/plugin-development/access-the-datastore.md b/archive/gateway-oss/1.2.x/plugin-development/access-the-datastore.md similarity index 100% rename from app/gateway-oss/1.2.x/plugin-development/access-the-datastore.md rename to archive/gateway-oss/1.2.x/plugin-development/access-the-datastore.md diff --git a/app/gateway-oss/1.2.x/plugin-development/admin-api.md b/archive/gateway-oss/1.2.x/plugin-development/admin-api.md similarity index 100% rename from app/gateway-oss/1.2.x/plugin-development/admin-api.md rename to archive/gateway-oss/1.2.x/plugin-development/admin-api.md diff --git a/app/gateway-oss/1.2.x/plugin-development/custom-entities.md b/archive/gateway-oss/1.2.x/plugin-development/custom-entities.md similarity index 100% rename from app/gateway-oss/1.2.x/plugin-development/custom-entities.md rename to archive/gateway-oss/1.2.x/plugin-development/custom-entities.md diff --git a/app/gateway-oss/1.2.x/plugin-development/custom-logic.md b/archive/gateway-oss/1.2.x/plugin-development/custom-logic.md similarity index 100% rename from app/gateway-oss/1.2.x/plugin-development/custom-logic.md rename to archive/gateway-oss/1.2.x/plugin-development/custom-logic.md diff --git a/app/gateway-oss/1.2.x/plugin-development/distribution.md b/archive/gateway-oss/1.2.x/plugin-development/distribution.md similarity index 100% rename from app/gateway-oss/1.2.x/plugin-development/distribution.md rename to archive/gateway-oss/1.2.x/plugin-development/distribution.md diff --git a/app/gateway-oss/1.2.x/plugin-development/entities-cache.md b/archive/gateway-oss/1.2.x/plugin-development/entities-cache.md similarity index 100% rename from app/gateway-oss/1.2.x/plugin-development/entities-cache.md rename to archive/gateway-oss/1.2.x/plugin-development/entities-cache.md diff --git a/app/gateway-oss/1.2.x/plugin-development/file-structure.md b/archive/gateway-oss/1.2.x/plugin-development/file-structure.md similarity index 100% rename from app/gateway-oss/1.2.x/plugin-development/file-structure.md rename to archive/gateway-oss/1.2.x/plugin-development/file-structure.md diff --git a/app/gateway-oss/1.2.x/plugin-development/index.md b/archive/gateway-oss/1.2.x/plugin-development/index.md similarity index 100% rename from app/gateway-oss/1.2.x/plugin-development/index.md rename to archive/gateway-oss/1.2.x/plugin-development/index.md diff --git a/app/gateway-oss/1.2.x/plugin-development/plugin-configuration.md b/archive/gateway-oss/1.2.x/plugin-development/plugin-configuration.md similarity index 100% rename from app/gateway-oss/1.2.x/plugin-development/plugin-configuration.md rename to archive/gateway-oss/1.2.x/plugin-development/plugin-configuration.md diff --git a/app/gateway-oss/1.2.x/plugin-development/tests.md b/archive/gateway-oss/1.2.x/plugin-development/tests.md similarity index 100% rename from app/gateway-oss/1.2.x/plugin-development/tests.md rename to archive/gateway-oss/1.2.x/plugin-development/tests.md diff --git a/app/gateway-oss/1.2.x/proxy.md b/archive/gateway-oss/1.2.x/proxy.md similarity index 100% rename from app/gateway-oss/1.2.x/proxy.md rename to archive/gateway-oss/1.2.x/proxy.md diff --git a/app/gateway-oss/1.2.x/secure-admin-api.md b/archive/gateway-oss/1.2.x/secure-admin-api.md similarity index 100% rename from app/gateway-oss/1.2.x/secure-admin-api.md rename to archive/gateway-oss/1.2.x/secure-admin-api.md diff --git a/app/gateway-oss/1.2.x/upgrading.md b/archive/gateway-oss/1.2.x/upgrading.md similarity index 100% rename from app/gateway-oss/1.2.x/upgrading.md rename to archive/gateway-oss/1.2.x/upgrading.md diff --git a/app/gateway-oss/1.3.x/admin-api.md b/archive/gateway-oss/1.3.x/admin-api.md similarity index 100% rename from app/gateway-oss/1.3.x/admin-api.md rename to archive/gateway-oss/1.3.x/admin-api.md diff --git a/app/gateway-oss/1.3.x/auth.md b/archive/gateway-oss/1.3.x/auth.md similarity index 100% rename from app/gateway-oss/1.3.x/auth.md rename to archive/gateway-oss/1.3.x/auth.md diff --git a/app/gateway-oss/1.3.x/cli.md b/archive/gateway-oss/1.3.x/cli.md similarity index 100% rename from app/gateway-oss/1.3.x/cli.md rename to archive/gateway-oss/1.3.x/cli.md diff --git a/app/gateway-oss/1.3.x/clustering.md b/archive/gateway-oss/1.3.x/clustering.md similarity index 100% rename from app/gateway-oss/1.3.x/clustering.md rename to archive/gateway-oss/1.3.x/clustering.md diff --git a/app/gateway-oss/1.3.x/configuration.md b/archive/gateway-oss/1.3.x/configuration.md similarity index 100% rename from app/gateway-oss/1.3.x/configuration.md rename to archive/gateway-oss/1.3.x/configuration.md diff --git a/app/gateway-oss/1.3.x/db-less-admin-api.md b/archive/gateway-oss/1.3.x/db-less-admin-api.md similarity index 100% rename from app/gateway-oss/1.3.x/db-less-admin-api.md rename to archive/gateway-oss/1.3.x/db-less-admin-api.md diff --git a/app/gateway-oss/1.3.x/db-less-and-declarative-config.md b/archive/gateway-oss/1.3.x/db-less-and-declarative-config.md similarity index 100% rename from app/gateway-oss/1.3.x/db-less-and-declarative-config.md rename to archive/gateway-oss/1.3.x/db-less-and-declarative-config.md diff --git a/app/gateway-oss/1.3.x/getting-started/adding-consumers.md b/archive/gateway-oss/1.3.x/getting-started/adding-consumers.md similarity index 100% rename from app/gateway-oss/1.3.x/getting-started/adding-consumers.md rename to archive/gateway-oss/1.3.x/getting-started/adding-consumers.md diff --git a/app/gateway-oss/1.3.x/getting-started/configuring-a-grpc-service.md b/archive/gateway-oss/1.3.x/getting-started/configuring-a-grpc-service.md similarity index 100% rename from app/gateway-oss/1.3.x/getting-started/configuring-a-grpc-service.md rename to archive/gateway-oss/1.3.x/getting-started/configuring-a-grpc-service.md diff --git a/app/gateway-oss/1.3.x/getting-started/configuring-a-service.md b/archive/gateway-oss/1.3.x/getting-started/configuring-a-service.md similarity index 100% rename from app/gateway-oss/1.3.x/getting-started/configuring-a-service.md rename to archive/gateway-oss/1.3.x/getting-started/configuring-a-service.md diff --git a/app/gateway-oss/1.3.x/getting-started/enabling-plugins.md b/archive/gateway-oss/1.3.x/getting-started/enabling-plugins.md similarity index 100% rename from app/gateway-oss/1.3.x/getting-started/enabling-plugins.md rename to archive/gateway-oss/1.3.x/getting-started/enabling-plugins.md diff --git a/app/gateway-oss/1.3.x/getting-started/introduction.md b/archive/gateway-oss/1.3.x/getting-started/introduction.md similarity index 100% rename from app/gateway-oss/1.3.x/getting-started/introduction.md rename to archive/gateway-oss/1.3.x/getting-started/introduction.md diff --git a/app/gateway-oss/1.3.x/getting-started/quickstart.md b/archive/gateway-oss/1.3.x/getting-started/quickstart.md similarity index 100% rename from app/gateway-oss/1.3.x/getting-started/quickstart.md rename to archive/gateway-oss/1.3.x/getting-started/quickstart.md diff --git a/app/gateway-oss/1.3.x/health-checks-circuit-breakers.md b/archive/gateway-oss/1.3.x/health-checks-circuit-breakers.md similarity index 100% rename from app/gateway-oss/1.3.x/health-checks-circuit-breakers.md rename to archive/gateway-oss/1.3.x/health-checks-circuit-breakers.md diff --git a/app/gateway-oss/1.3.x/index.md b/archive/gateway-oss/1.3.x/index.md similarity index 100% rename from app/gateway-oss/1.3.x/index.md rename to archive/gateway-oss/1.3.x/index.md diff --git a/app/gateway-oss/1.3.x/loadbalancing.md b/archive/gateway-oss/1.3.x/loadbalancing.md similarity index 100% rename from app/gateway-oss/1.3.x/loadbalancing.md rename to archive/gateway-oss/1.3.x/loadbalancing.md diff --git a/app/gateway-oss/1.3.x/logging.md b/archive/gateway-oss/1.3.x/logging.md similarity index 100% rename from app/gateway-oss/1.3.x/logging.md rename to archive/gateway-oss/1.3.x/logging.md diff --git a/app/gateway-oss/1.3.x/network.md b/archive/gateway-oss/1.3.x/network.md similarity index 100% rename from app/gateway-oss/1.3.x/network.md rename to archive/gateway-oss/1.3.x/network.md diff --git a/app/gateway-oss/1.3.x/pdk/index.md b/archive/gateway-oss/1.3.x/pdk/index.md similarity index 100% rename from app/gateway-oss/1.3.x/pdk/index.md rename to archive/gateway-oss/1.3.x/pdk/index.md diff --git a/app/gateway-oss/1.3.x/pdk/kong.client.md b/archive/gateway-oss/1.3.x/pdk/kong.client.md similarity index 100% rename from app/gateway-oss/1.3.x/pdk/kong.client.md rename to archive/gateway-oss/1.3.x/pdk/kong.client.md diff --git a/app/gateway-oss/1.3.x/pdk/kong.ctx.md b/archive/gateway-oss/1.3.x/pdk/kong.ctx.md similarity index 100% rename from app/gateway-oss/1.3.x/pdk/kong.ctx.md rename to archive/gateway-oss/1.3.x/pdk/kong.ctx.md diff --git a/app/gateway-oss/1.3.x/pdk/kong.ip.md b/archive/gateway-oss/1.3.x/pdk/kong.ip.md similarity index 100% rename from app/gateway-oss/1.3.x/pdk/kong.ip.md rename to archive/gateway-oss/1.3.x/pdk/kong.ip.md diff --git a/app/gateway-oss/1.3.x/pdk/kong.log.md b/archive/gateway-oss/1.3.x/pdk/kong.log.md similarity index 100% rename from app/gateway-oss/1.3.x/pdk/kong.log.md rename to archive/gateway-oss/1.3.x/pdk/kong.log.md diff --git a/app/gateway-oss/1.3.x/pdk/kong.nginx.md b/archive/gateway-oss/1.3.x/pdk/kong.nginx.md similarity index 100% rename from app/gateway-oss/1.3.x/pdk/kong.nginx.md rename to archive/gateway-oss/1.3.x/pdk/kong.nginx.md diff --git a/app/gateway-oss/1.3.x/pdk/kong.node.md b/archive/gateway-oss/1.3.x/pdk/kong.node.md similarity index 100% rename from app/gateway-oss/1.3.x/pdk/kong.node.md rename to archive/gateway-oss/1.3.x/pdk/kong.node.md diff --git a/app/gateway-oss/1.3.x/pdk/kong.request.md b/archive/gateway-oss/1.3.x/pdk/kong.request.md similarity index 100% rename from app/gateway-oss/1.3.x/pdk/kong.request.md rename to archive/gateway-oss/1.3.x/pdk/kong.request.md diff --git a/app/gateway-oss/1.3.x/pdk/kong.response.md b/archive/gateway-oss/1.3.x/pdk/kong.response.md similarity index 100% rename from app/gateway-oss/1.3.x/pdk/kong.response.md rename to archive/gateway-oss/1.3.x/pdk/kong.response.md diff --git a/app/gateway-oss/1.3.x/pdk/kong.router.md b/archive/gateway-oss/1.3.x/pdk/kong.router.md similarity index 100% rename from app/gateway-oss/1.3.x/pdk/kong.router.md rename to archive/gateway-oss/1.3.x/pdk/kong.router.md diff --git a/app/gateway-oss/1.3.x/pdk/kong.service.md b/archive/gateway-oss/1.3.x/pdk/kong.service.md similarity index 100% rename from app/gateway-oss/1.3.x/pdk/kong.service.md rename to archive/gateway-oss/1.3.x/pdk/kong.service.md diff --git a/app/gateway-oss/1.3.x/pdk/kong.service.request.md b/archive/gateway-oss/1.3.x/pdk/kong.service.request.md similarity index 100% rename from app/gateway-oss/1.3.x/pdk/kong.service.request.md rename to archive/gateway-oss/1.3.x/pdk/kong.service.request.md diff --git a/app/gateway-oss/1.3.x/pdk/kong.service.response.md b/archive/gateway-oss/1.3.x/pdk/kong.service.response.md similarity index 100% rename from app/gateway-oss/1.3.x/pdk/kong.service.response.md rename to archive/gateway-oss/1.3.x/pdk/kong.service.response.md diff --git a/app/gateway-oss/1.3.x/pdk/kong.table.md b/archive/gateway-oss/1.3.x/pdk/kong.table.md similarity index 100% rename from app/gateway-oss/1.3.x/pdk/kong.table.md rename to archive/gateway-oss/1.3.x/pdk/kong.table.md diff --git a/app/gateway-oss/1.3.x/plugin-development/access-the-datastore.md b/archive/gateway-oss/1.3.x/plugin-development/access-the-datastore.md similarity index 100% rename from app/gateway-oss/1.3.x/plugin-development/access-the-datastore.md rename to archive/gateway-oss/1.3.x/plugin-development/access-the-datastore.md diff --git a/app/gateway-oss/1.3.x/plugin-development/admin-api.md b/archive/gateway-oss/1.3.x/plugin-development/admin-api.md similarity index 100% rename from app/gateway-oss/1.3.x/plugin-development/admin-api.md rename to archive/gateway-oss/1.3.x/plugin-development/admin-api.md diff --git a/app/gateway-oss/1.3.x/plugin-development/custom-entities.md b/archive/gateway-oss/1.3.x/plugin-development/custom-entities.md similarity index 100% rename from app/gateway-oss/1.3.x/plugin-development/custom-entities.md rename to archive/gateway-oss/1.3.x/plugin-development/custom-entities.md diff --git a/app/gateway-oss/1.3.x/plugin-development/custom-logic.md b/archive/gateway-oss/1.3.x/plugin-development/custom-logic.md similarity index 100% rename from app/gateway-oss/1.3.x/plugin-development/custom-logic.md rename to archive/gateway-oss/1.3.x/plugin-development/custom-logic.md diff --git a/app/gateway-oss/1.3.x/plugin-development/distribution.md b/archive/gateway-oss/1.3.x/plugin-development/distribution.md similarity index 100% rename from app/gateway-oss/1.3.x/plugin-development/distribution.md rename to archive/gateway-oss/1.3.x/plugin-development/distribution.md diff --git a/app/gateway-oss/1.3.x/plugin-development/entities-cache.md b/archive/gateway-oss/1.3.x/plugin-development/entities-cache.md similarity index 100% rename from app/gateway-oss/1.3.x/plugin-development/entities-cache.md rename to archive/gateway-oss/1.3.x/plugin-development/entities-cache.md diff --git a/app/gateway-oss/1.3.x/plugin-development/file-structure.md b/archive/gateway-oss/1.3.x/plugin-development/file-structure.md similarity index 100% rename from app/gateway-oss/1.3.x/plugin-development/file-structure.md rename to archive/gateway-oss/1.3.x/plugin-development/file-structure.md diff --git a/app/gateway-oss/1.3.x/plugin-development/index.md b/archive/gateway-oss/1.3.x/plugin-development/index.md similarity index 100% rename from app/gateway-oss/1.3.x/plugin-development/index.md rename to archive/gateway-oss/1.3.x/plugin-development/index.md diff --git a/app/gateway-oss/1.3.x/plugin-development/plugin-configuration.md b/archive/gateway-oss/1.3.x/plugin-development/plugin-configuration.md similarity index 100% rename from app/gateway-oss/1.3.x/plugin-development/plugin-configuration.md rename to archive/gateway-oss/1.3.x/plugin-development/plugin-configuration.md diff --git a/app/gateway-oss/1.3.x/plugin-development/tests.md b/archive/gateway-oss/1.3.x/plugin-development/tests.md similarity index 100% rename from app/gateway-oss/1.3.x/plugin-development/tests.md rename to archive/gateway-oss/1.3.x/plugin-development/tests.md diff --git a/app/gateway-oss/1.3.x/proxy.md b/archive/gateway-oss/1.3.x/proxy.md similarity index 100% rename from app/gateway-oss/1.3.x/proxy.md rename to archive/gateway-oss/1.3.x/proxy.md diff --git a/app/gateway-oss/1.3.x/secure-admin-api.md b/archive/gateway-oss/1.3.x/secure-admin-api.md similarity index 100% rename from app/gateway-oss/1.3.x/secure-admin-api.md rename to archive/gateway-oss/1.3.x/secure-admin-api.md diff --git a/app/gateway-oss/1.3.x/upgrading.md b/archive/gateway-oss/1.3.x/upgrading.md similarity index 100% rename from app/gateway-oss/1.3.x/upgrading.md rename to archive/gateway-oss/1.3.x/upgrading.md diff --git a/app/gateway-oss/1.4.x/admin-api.md b/archive/gateway-oss/1.4.x/admin-api.md similarity index 100% rename from app/gateway-oss/1.4.x/admin-api.md rename to archive/gateway-oss/1.4.x/admin-api.md diff --git a/app/gateway-oss/1.4.x/auth.md b/archive/gateway-oss/1.4.x/auth.md similarity index 100% rename from app/gateway-oss/1.4.x/auth.md rename to archive/gateway-oss/1.4.x/auth.md diff --git a/app/gateway-oss/1.4.x/cli.md b/archive/gateway-oss/1.4.x/cli.md similarity index 100% rename from app/gateway-oss/1.4.x/cli.md rename to archive/gateway-oss/1.4.x/cli.md diff --git a/app/gateway-oss/1.4.x/clustering.md b/archive/gateway-oss/1.4.x/clustering.md similarity index 100% rename from app/gateway-oss/1.4.x/clustering.md rename to archive/gateway-oss/1.4.x/clustering.md diff --git a/app/gateway-oss/1.4.x/configuration.md b/archive/gateway-oss/1.4.x/configuration.md similarity index 100% rename from app/gateway-oss/1.4.x/configuration.md rename to archive/gateway-oss/1.4.x/configuration.md diff --git a/app/gateway-oss/1.4.x/db-less-admin-api.md b/archive/gateway-oss/1.4.x/db-less-admin-api.md similarity index 100% rename from app/gateway-oss/1.4.x/db-less-admin-api.md rename to archive/gateway-oss/1.4.x/db-less-admin-api.md diff --git a/app/gateway-oss/1.4.x/db-less-and-declarative-config.md b/archive/gateway-oss/1.4.x/db-less-and-declarative-config.md similarity index 100% rename from app/gateway-oss/1.4.x/db-less-and-declarative-config.md rename to archive/gateway-oss/1.4.x/db-less-and-declarative-config.md diff --git a/app/gateway-oss/1.4.x/getting-started/adding-consumers.md b/archive/gateway-oss/1.4.x/getting-started/adding-consumers.md similarity index 100% rename from app/gateway-oss/1.4.x/getting-started/adding-consumers.md rename to archive/gateway-oss/1.4.x/getting-started/adding-consumers.md diff --git a/app/gateway-oss/1.4.x/getting-started/configuring-a-grpc-service.md b/archive/gateway-oss/1.4.x/getting-started/configuring-a-grpc-service.md similarity index 100% rename from app/gateway-oss/1.4.x/getting-started/configuring-a-grpc-service.md rename to archive/gateway-oss/1.4.x/getting-started/configuring-a-grpc-service.md diff --git a/app/gateway-oss/1.4.x/getting-started/configuring-a-service.md b/archive/gateway-oss/1.4.x/getting-started/configuring-a-service.md similarity index 100% rename from app/gateway-oss/1.4.x/getting-started/configuring-a-service.md rename to archive/gateway-oss/1.4.x/getting-started/configuring-a-service.md diff --git a/app/gateway-oss/1.4.x/getting-started/enabling-plugins.md b/archive/gateway-oss/1.4.x/getting-started/enabling-plugins.md similarity index 100% rename from app/gateway-oss/1.4.x/getting-started/enabling-plugins.md rename to archive/gateway-oss/1.4.x/getting-started/enabling-plugins.md diff --git a/app/gateway-oss/1.4.x/getting-started/introduction.md b/archive/gateway-oss/1.4.x/getting-started/introduction.md similarity index 100% rename from app/gateway-oss/1.4.x/getting-started/introduction.md rename to archive/gateway-oss/1.4.x/getting-started/introduction.md diff --git a/app/gateway-oss/1.4.x/getting-started/quickstart.md b/archive/gateway-oss/1.4.x/getting-started/quickstart.md similarity index 100% rename from app/gateway-oss/1.4.x/getting-started/quickstart.md rename to archive/gateway-oss/1.4.x/getting-started/quickstart.md diff --git a/app/gateway-oss/1.4.x/health-checks-circuit-breakers.md b/archive/gateway-oss/1.4.x/health-checks-circuit-breakers.md similarity index 100% rename from app/gateway-oss/1.4.x/health-checks-circuit-breakers.md rename to archive/gateway-oss/1.4.x/health-checks-circuit-breakers.md diff --git a/app/gateway-oss/1.4.x/index.md b/archive/gateway-oss/1.4.x/index.md similarity index 100% rename from app/gateway-oss/1.4.x/index.md rename to archive/gateway-oss/1.4.x/index.md diff --git a/app/gateway-oss/1.4.x/kong-for-kubernetes/changelog.md b/archive/gateway-oss/1.4.x/kong-for-kubernetes/changelog.md similarity index 100% rename from app/gateway-oss/1.4.x/kong-for-kubernetes/changelog.md rename to archive/gateway-oss/1.4.x/kong-for-kubernetes/changelog.md diff --git a/app/gateway-oss/1.4.x/kong-for-kubernetes/index.md b/archive/gateway-oss/1.4.x/kong-for-kubernetes/index.md similarity index 100% rename from app/gateway-oss/1.4.x/kong-for-kubernetes/index.md rename to archive/gateway-oss/1.4.x/kong-for-kubernetes/index.md diff --git a/app/gateway-oss/1.4.x/kong-for-kubernetes/install.md b/archive/gateway-oss/1.4.x/kong-for-kubernetes/install.md similarity index 100% rename from app/gateway-oss/1.4.x/kong-for-kubernetes/install.md rename to archive/gateway-oss/1.4.x/kong-for-kubernetes/install.md diff --git a/app/gateway-oss/1.4.x/kong-for-kubernetes/using-kong-for-kubernetes.md b/archive/gateway-oss/1.4.x/kong-for-kubernetes/using-kong-for-kubernetes.md similarity index 100% rename from app/gateway-oss/1.4.x/kong-for-kubernetes/using-kong-for-kubernetes.md rename to archive/gateway-oss/1.4.x/kong-for-kubernetes/using-kong-for-kubernetes.md diff --git a/app/gateway-oss/1.4.x/loadbalancing.md b/archive/gateway-oss/1.4.x/loadbalancing.md similarity index 100% rename from app/gateway-oss/1.4.x/loadbalancing.md rename to archive/gateway-oss/1.4.x/loadbalancing.md diff --git a/app/gateway-oss/1.4.x/logging.md b/archive/gateway-oss/1.4.x/logging.md similarity index 100% rename from app/gateway-oss/1.4.x/logging.md rename to archive/gateway-oss/1.4.x/logging.md diff --git a/app/gateway-oss/1.4.x/network.md b/archive/gateway-oss/1.4.x/network.md similarity index 100% rename from app/gateway-oss/1.4.x/network.md rename to archive/gateway-oss/1.4.x/network.md diff --git a/app/gateway-oss/1.4.x/pdk/index.md b/archive/gateway-oss/1.4.x/pdk/index.md similarity index 100% rename from app/gateway-oss/1.4.x/pdk/index.md rename to archive/gateway-oss/1.4.x/pdk/index.md diff --git a/app/gateway-oss/1.4.x/pdk/kong.client.md b/archive/gateway-oss/1.4.x/pdk/kong.client.md similarity index 100% rename from app/gateway-oss/1.4.x/pdk/kong.client.md rename to archive/gateway-oss/1.4.x/pdk/kong.client.md diff --git a/app/gateway-oss/1.4.x/pdk/kong.ctx.md b/archive/gateway-oss/1.4.x/pdk/kong.ctx.md similarity index 100% rename from app/gateway-oss/1.4.x/pdk/kong.ctx.md rename to archive/gateway-oss/1.4.x/pdk/kong.ctx.md diff --git a/app/gateway-oss/1.4.x/pdk/kong.ip.md b/archive/gateway-oss/1.4.x/pdk/kong.ip.md similarity index 100% rename from app/gateway-oss/1.4.x/pdk/kong.ip.md rename to archive/gateway-oss/1.4.x/pdk/kong.ip.md diff --git a/app/gateway-oss/1.4.x/pdk/kong.log.md b/archive/gateway-oss/1.4.x/pdk/kong.log.md similarity index 100% rename from app/gateway-oss/1.4.x/pdk/kong.log.md rename to archive/gateway-oss/1.4.x/pdk/kong.log.md diff --git a/app/gateway-oss/1.4.x/pdk/kong.nginx.md b/archive/gateway-oss/1.4.x/pdk/kong.nginx.md similarity index 100% rename from app/gateway-oss/1.4.x/pdk/kong.nginx.md rename to archive/gateway-oss/1.4.x/pdk/kong.nginx.md diff --git a/app/gateway-oss/1.4.x/pdk/kong.node.md b/archive/gateway-oss/1.4.x/pdk/kong.node.md similarity index 100% rename from app/gateway-oss/1.4.x/pdk/kong.node.md rename to archive/gateway-oss/1.4.x/pdk/kong.node.md diff --git a/app/gateway-oss/1.4.x/pdk/kong.request.md b/archive/gateway-oss/1.4.x/pdk/kong.request.md similarity index 100% rename from app/gateway-oss/1.4.x/pdk/kong.request.md rename to archive/gateway-oss/1.4.x/pdk/kong.request.md diff --git a/app/gateway-oss/1.4.x/pdk/kong.response.md b/archive/gateway-oss/1.4.x/pdk/kong.response.md similarity index 100% rename from app/gateway-oss/1.4.x/pdk/kong.response.md rename to archive/gateway-oss/1.4.x/pdk/kong.response.md diff --git a/app/gateway-oss/1.4.x/pdk/kong.router.md b/archive/gateway-oss/1.4.x/pdk/kong.router.md similarity index 100% rename from app/gateway-oss/1.4.x/pdk/kong.router.md rename to archive/gateway-oss/1.4.x/pdk/kong.router.md diff --git a/app/gateway-oss/1.4.x/pdk/kong.service.md b/archive/gateway-oss/1.4.x/pdk/kong.service.md similarity index 100% rename from app/gateway-oss/1.4.x/pdk/kong.service.md rename to archive/gateway-oss/1.4.x/pdk/kong.service.md diff --git a/app/gateway-oss/1.4.x/pdk/kong.service.request.md b/archive/gateway-oss/1.4.x/pdk/kong.service.request.md similarity index 100% rename from app/gateway-oss/1.4.x/pdk/kong.service.request.md rename to archive/gateway-oss/1.4.x/pdk/kong.service.request.md diff --git a/app/gateway-oss/1.4.x/pdk/kong.service.response.md b/archive/gateway-oss/1.4.x/pdk/kong.service.response.md similarity index 100% rename from app/gateway-oss/1.4.x/pdk/kong.service.response.md rename to archive/gateway-oss/1.4.x/pdk/kong.service.response.md diff --git a/app/gateway-oss/1.4.x/pdk/kong.table.md b/archive/gateway-oss/1.4.x/pdk/kong.table.md similarity index 100% rename from app/gateway-oss/1.4.x/pdk/kong.table.md rename to archive/gateway-oss/1.4.x/pdk/kong.table.md diff --git a/app/gateway-oss/1.4.x/plugin-development/access-the-datastore.md b/archive/gateway-oss/1.4.x/plugin-development/access-the-datastore.md similarity index 100% rename from app/gateway-oss/1.4.x/plugin-development/access-the-datastore.md rename to archive/gateway-oss/1.4.x/plugin-development/access-the-datastore.md diff --git a/app/gateway-oss/1.4.x/plugin-development/admin-api.md b/archive/gateway-oss/1.4.x/plugin-development/admin-api.md similarity index 100% rename from app/gateway-oss/1.4.x/plugin-development/admin-api.md rename to archive/gateway-oss/1.4.x/plugin-development/admin-api.md diff --git a/app/gateway-oss/1.4.x/plugin-development/custom-entities.md b/archive/gateway-oss/1.4.x/plugin-development/custom-entities.md similarity index 100% rename from app/gateway-oss/1.4.x/plugin-development/custom-entities.md rename to archive/gateway-oss/1.4.x/plugin-development/custom-entities.md diff --git a/app/gateway-oss/1.4.x/plugin-development/custom-logic.md b/archive/gateway-oss/1.4.x/plugin-development/custom-logic.md similarity index 100% rename from app/gateway-oss/1.4.x/plugin-development/custom-logic.md rename to archive/gateway-oss/1.4.x/plugin-development/custom-logic.md diff --git a/app/gateway-oss/1.4.x/plugin-development/distribution.md b/archive/gateway-oss/1.4.x/plugin-development/distribution.md similarity index 100% rename from app/gateway-oss/1.4.x/plugin-development/distribution.md rename to archive/gateway-oss/1.4.x/plugin-development/distribution.md diff --git a/app/gateway-oss/1.4.x/plugin-development/entities-cache.md b/archive/gateway-oss/1.4.x/plugin-development/entities-cache.md similarity index 100% rename from app/gateway-oss/1.4.x/plugin-development/entities-cache.md rename to archive/gateway-oss/1.4.x/plugin-development/entities-cache.md diff --git a/app/gateway-oss/1.4.x/plugin-development/file-structure.md b/archive/gateway-oss/1.4.x/plugin-development/file-structure.md similarity index 100% rename from app/gateway-oss/1.4.x/plugin-development/file-structure.md rename to archive/gateway-oss/1.4.x/plugin-development/file-structure.md diff --git a/app/gateway-oss/1.4.x/plugin-development/index.md b/archive/gateway-oss/1.4.x/plugin-development/index.md similarity index 100% rename from app/gateway-oss/1.4.x/plugin-development/index.md rename to archive/gateway-oss/1.4.x/plugin-development/index.md diff --git a/app/gateway-oss/1.4.x/plugin-development/plugin-configuration.md b/archive/gateway-oss/1.4.x/plugin-development/plugin-configuration.md similarity index 100% rename from app/gateway-oss/1.4.x/plugin-development/plugin-configuration.md rename to archive/gateway-oss/1.4.x/plugin-development/plugin-configuration.md diff --git a/app/gateway-oss/1.4.x/plugin-development/tests.md b/archive/gateway-oss/1.4.x/plugin-development/tests.md similarity index 100% rename from app/gateway-oss/1.4.x/plugin-development/tests.md rename to archive/gateway-oss/1.4.x/plugin-development/tests.md diff --git a/app/gateway-oss/1.4.x/proxy.md b/archive/gateway-oss/1.4.x/proxy.md similarity index 100% rename from app/gateway-oss/1.4.x/proxy.md rename to archive/gateway-oss/1.4.x/proxy.md diff --git a/app/gateway-oss/1.4.x/secure-admin-api.md b/archive/gateway-oss/1.4.x/secure-admin-api.md similarity index 100% rename from app/gateway-oss/1.4.x/secure-admin-api.md rename to archive/gateway-oss/1.4.x/secure-admin-api.md diff --git a/app/gateway-oss/1.4.x/upgrading.md b/archive/gateway-oss/1.4.x/upgrading.md similarity index 100% rename from app/gateway-oss/1.4.x/upgrading.md rename to archive/gateway-oss/1.4.x/upgrading.md diff --git a/app/gateway-oss/1.5.x/admin-api.md b/archive/gateway-oss/1.5.x/admin-api.md similarity index 100% rename from app/gateway-oss/1.5.x/admin-api.md rename to archive/gateway-oss/1.5.x/admin-api.md diff --git a/app/gateway-oss/1.5.x/auth.md b/archive/gateway-oss/1.5.x/auth.md similarity index 100% rename from app/gateway-oss/1.5.x/auth.md rename to archive/gateway-oss/1.5.x/auth.md diff --git a/app/gateway-oss/1.5.x/cli.md b/archive/gateway-oss/1.5.x/cli.md similarity index 100% rename from app/gateway-oss/1.5.x/cli.md rename to archive/gateway-oss/1.5.x/cli.md diff --git a/app/gateway-oss/1.5.x/clustering.md b/archive/gateway-oss/1.5.x/clustering.md similarity index 100% rename from app/gateway-oss/1.5.x/clustering.md rename to archive/gateway-oss/1.5.x/clustering.md diff --git a/app/gateway-oss/1.5.x/configuration.md b/archive/gateway-oss/1.5.x/configuration.md similarity index 100% rename from app/gateway-oss/1.5.x/configuration.md rename to archive/gateway-oss/1.5.x/configuration.md diff --git a/app/gateway-oss/1.5.x/db-less-admin-api.md b/archive/gateway-oss/1.5.x/db-less-admin-api.md similarity index 100% rename from app/gateway-oss/1.5.x/db-less-admin-api.md rename to archive/gateway-oss/1.5.x/db-less-admin-api.md diff --git a/app/gateway-oss/1.5.x/db-less-and-declarative-config.md b/archive/gateway-oss/1.5.x/db-less-and-declarative-config.md similarity index 100% rename from app/gateway-oss/1.5.x/db-less-and-declarative-config.md rename to archive/gateway-oss/1.5.x/db-less-and-declarative-config.md diff --git a/app/gateway-oss/1.5.x/getting-started/adding-consumers.md b/archive/gateway-oss/1.5.x/getting-started/adding-consumers.md similarity index 100% rename from app/gateway-oss/1.5.x/getting-started/adding-consumers.md rename to archive/gateway-oss/1.5.x/getting-started/adding-consumers.md diff --git a/app/gateway-oss/1.5.x/getting-started/configuring-a-grpc-service.md b/archive/gateway-oss/1.5.x/getting-started/configuring-a-grpc-service.md similarity index 100% rename from app/gateway-oss/1.5.x/getting-started/configuring-a-grpc-service.md rename to archive/gateway-oss/1.5.x/getting-started/configuring-a-grpc-service.md diff --git a/app/gateway-oss/1.5.x/getting-started/configuring-a-service.md b/archive/gateway-oss/1.5.x/getting-started/configuring-a-service.md similarity index 100% rename from app/gateway-oss/1.5.x/getting-started/configuring-a-service.md rename to archive/gateway-oss/1.5.x/getting-started/configuring-a-service.md diff --git a/app/gateway-oss/1.5.x/getting-started/enabling-plugins.md b/archive/gateway-oss/1.5.x/getting-started/enabling-plugins.md similarity index 100% rename from app/gateway-oss/1.5.x/getting-started/enabling-plugins.md rename to archive/gateway-oss/1.5.x/getting-started/enabling-plugins.md diff --git a/app/gateway-oss/1.5.x/getting-started/introduction.md b/archive/gateway-oss/1.5.x/getting-started/introduction.md similarity index 100% rename from app/gateway-oss/1.5.x/getting-started/introduction.md rename to archive/gateway-oss/1.5.x/getting-started/introduction.md diff --git a/app/gateway-oss/1.5.x/getting-started/quickstart.md b/archive/gateway-oss/1.5.x/getting-started/quickstart.md similarity index 100% rename from app/gateway-oss/1.5.x/getting-started/quickstart.md rename to archive/gateway-oss/1.5.x/getting-started/quickstart.md diff --git a/app/gateway-oss/1.5.x/health-checks-circuit-breakers.md b/archive/gateway-oss/1.5.x/health-checks-circuit-breakers.md similarity index 100% rename from app/gateway-oss/1.5.x/health-checks-circuit-breakers.md rename to archive/gateway-oss/1.5.x/health-checks-circuit-breakers.md diff --git a/app/gateway-oss/1.5.x/index.md b/archive/gateway-oss/1.5.x/index.md similarity index 100% rename from app/gateway-oss/1.5.x/index.md rename to archive/gateway-oss/1.5.x/index.md diff --git a/app/gateway-oss/1.5.x/kong-for-kubernetes/changelog.md b/archive/gateway-oss/1.5.x/kong-for-kubernetes/changelog.md similarity index 100% rename from app/gateway-oss/1.5.x/kong-for-kubernetes/changelog.md rename to archive/gateway-oss/1.5.x/kong-for-kubernetes/changelog.md diff --git a/app/gateway-oss/1.5.x/kong-for-kubernetes/index.md b/archive/gateway-oss/1.5.x/kong-for-kubernetes/index.md similarity index 100% rename from app/gateway-oss/1.5.x/kong-for-kubernetes/index.md rename to archive/gateway-oss/1.5.x/kong-for-kubernetes/index.md diff --git a/app/gateway-oss/1.5.x/kong-for-kubernetes/install.md b/archive/gateway-oss/1.5.x/kong-for-kubernetes/install.md similarity index 100% rename from app/gateway-oss/1.5.x/kong-for-kubernetes/install.md rename to archive/gateway-oss/1.5.x/kong-for-kubernetes/install.md diff --git a/app/gateway-oss/1.5.x/kong-for-kubernetes/using-kong-for-kubernetes.md b/archive/gateway-oss/1.5.x/kong-for-kubernetes/using-kong-for-kubernetes.md similarity index 100% rename from app/gateway-oss/1.5.x/kong-for-kubernetes/using-kong-for-kubernetes.md rename to archive/gateway-oss/1.5.x/kong-for-kubernetes/using-kong-for-kubernetes.md diff --git a/app/gateway-oss/1.5.x/loadbalancing.md b/archive/gateway-oss/1.5.x/loadbalancing.md similarity index 100% rename from app/gateway-oss/1.5.x/loadbalancing.md rename to archive/gateway-oss/1.5.x/loadbalancing.md diff --git a/app/gateway-oss/1.5.x/logging.md b/archive/gateway-oss/1.5.x/logging.md similarity index 100% rename from app/gateway-oss/1.5.x/logging.md rename to archive/gateway-oss/1.5.x/logging.md diff --git a/app/gateway-oss/1.5.x/network.md b/archive/gateway-oss/1.5.x/network.md similarity index 100% rename from app/gateway-oss/1.5.x/network.md rename to archive/gateway-oss/1.5.x/network.md diff --git a/app/gateway-oss/1.5.x/pdk/index.md b/archive/gateway-oss/1.5.x/pdk/index.md similarity index 100% rename from app/gateway-oss/1.5.x/pdk/index.md rename to archive/gateway-oss/1.5.x/pdk/index.md diff --git a/app/gateway-oss/1.5.x/pdk/kong.client.md b/archive/gateway-oss/1.5.x/pdk/kong.client.md similarity index 100% rename from app/gateway-oss/1.5.x/pdk/kong.client.md rename to archive/gateway-oss/1.5.x/pdk/kong.client.md diff --git a/app/gateway-oss/1.5.x/pdk/kong.ctx.md b/archive/gateway-oss/1.5.x/pdk/kong.ctx.md similarity index 100% rename from app/gateway-oss/1.5.x/pdk/kong.ctx.md rename to archive/gateway-oss/1.5.x/pdk/kong.ctx.md diff --git a/app/gateway-oss/1.5.x/pdk/kong.ip.md b/archive/gateway-oss/1.5.x/pdk/kong.ip.md similarity index 100% rename from app/gateway-oss/1.5.x/pdk/kong.ip.md rename to archive/gateway-oss/1.5.x/pdk/kong.ip.md diff --git a/app/gateway-oss/1.5.x/pdk/kong.log.md b/archive/gateway-oss/1.5.x/pdk/kong.log.md similarity index 100% rename from app/gateway-oss/1.5.x/pdk/kong.log.md rename to archive/gateway-oss/1.5.x/pdk/kong.log.md diff --git a/app/gateway-oss/1.5.x/pdk/kong.nginx.md b/archive/gateway-oss/1.5.x/pdk/kong.nginx.md similarity index 100% rename from app/gateway-oss/1.5.x/pdk/kong.nginx.md rename to archive/gateway-oss/1.5.x/pdk/kong.nginx.md diff --git a/app/gateway-oss/1.5.x/pdk/kong.node.md b/archive/gateway-oss/1.5.x/pdk/kong.node.md similarity index 100% rename from app/gateway-oss/1.5.x/pdk/kong.node.md rename to archive/gateway-oss/1.5.x/pdk/kong.node.md diff --git a/app/gateway-oss/1.5.x/pdk/kong.request.md b/archive/gateway-oss/1.5.x/pdk/kong.request.md similarity index 100% rename from app/gateway-oss/1.5.x/pdk/kong.request.md rename to archive/gateway-oss/1.5.x/pdk/kong.request.md diff --git a/app/gateway-oss/1.5.x/pdk/kong.response.md b/archive/gateway-oss/1.5.x/pdk/kong.response.md similarity index 100% rename from app/gateway-oss/1.5.x/pdk/kong.response.md rename to archive/gateway-oss/1.5.x/pdk/kong.response.md diff --git a/app/gateway-oss/1.5.x/pdk/kong.router.md b/archive/gateway-oss/1.5.x/pdk/kong.router.md similarity index 100% rename from app/gateway-oss/1.5.x/pdk/kong.router.md rename to archive/gateway-oss/1.5.x/pdk/kong.router.md diff --git a/app/gateway-oss/1.5.x/pdk/kong.service.md b/archive/gateway-oss/1.5.x/pdk/kong.service.md similarity index 100% rename from app/gateway-oss/1.5.x/pdk/kong.service.md rename to archive/gateway-oss/1.5.x/pdk/kong.service.md diff --git a/app/gateway-oss/1.5.x/pdk/kong.service.request.md b/archive/gateway-oss/1.5.x/pdk/kong.service.request.md similarity index 100% rename from app/gateway-oss/1.5.x/pdk/kong.service.request.md rename to archive/gateway-oss/1.5.x/pdk/kong.service.request.md diff --git a/app/gateway-oss/1.5.x/pdk/kong.service.response.md b/archive/gateway-oss/1.5.x/pdk/kong.service.response.md similarity index 100% rename from app/gateway-oss/1.5.x/pdk/kong.service.response.md rename to archive/gateway-oss/1.5.x/pdk/kong.service.response.md diff --git a/app/gateway-oss/1.5.x/pdk/kong.table.md b/archive/gateway-oss/1.5.x/pdk/kong.table.md similarity index 100% rename from app/gateway-oss/1.5.x/pdk/kong.table.md rename to archive/gateway-oss/1.5.x/pdk/kong.table.md diff --git a/app/gateway-oss/1.5.x/plugin-development/access-the-datastore.md b/archive/gateway-oss/1.5.x/plugin-development/access-the-datastore.md similarity index 100% rename from app/gateway-oss/1.5.x/plugin-development/access-the-datastore.md rename to archive/gateway-oss/1.5.x/plugin-development/access-the-datastore.md diff --git a/app/gateway-oss/1.5.x/plugin-development/admin-api.md b/archive/gateway-oss/1.5.x/plugin-development/admin-api.md similarity index 100% rename from app/gateway-oss/1.5.x/plugin-development/admin-api.md rename to archive/gateway-oss/1.5.x/plugin-development/admin-api.md diff --git a/app/gateway-oss/1.5.x/plugin-development/custom-entities.md b/archive/gateway-oss/1.5.x/plugin-development/custom-entities.md similarity index 100% rename from app/gateway-oss/1.5.x/plugin-development/custom-entities.md rename to archive/gateway-oss/1.5.x/plugin-development/custom-entities.md diff --git a/app/gateway-oss/1.5.x/plugin-development/custom-logic.md b/archive/gateway-oss/1.5.x/plugin-development/custom-logic.md similarity index 100% rename from app/gateway-oss/1.5.x/plugin-development/custom-logic.md rename to archive/gateway-oss/1.5.x/plugin-development/custom-logic.md diff --git a/app/gateway-oss/1.5.x/plugin-development/distribution.md b/archive/gateway-oss/1.5.x/plugin-development/distribution.md similarity index 100% rename from app/gateway-oss/1.5.x/plugin-development/distribution.md rename to archive/gateway-oss/1.5.x/plugin-development/distribution.md diff --git a/app/gateway-oss/1.5.x/plugin-development/entities-cache.md b/archive/gateway-oss/1.5.x/plugin-development/entities-cache.md similarity index 100% rename from app/gateway-oss/1.5.x/plugin-development/entities-cache.md rename to archive/gateway-oss/1.5.x/plugin-development/entities-cache.md diff --git a/app/gateway-oss/1.5.x/plugin-development/file-structure.md b/archive/gateway-oss/1.5.x/plugin-development/file-structure.md similarity index 100% rename from app/gateway-oss/1.5.x/plugin-development/file-structure.md rename to archive/gateway-oss/1.5.x/plugin-development/file-structure.md diff --git a/app/gateway-oss/1.5.x/plugin-development/index.md b/archive/gateway-oss/1.5.x/plugin-development/index.md similarity index 100% rename from app/gateway-oss/1.5.x/plugin-development/index.md rename to archive/gateway-oss/1.5.x/plugin-development/index.md diff --git a/app/gateway-oss/1.5.x/plugin-development/plugin-configuration.md b/archive/gateway-oss/1.5.x/plugin-development/plugin-configuration.md similarity index 100% rename from app/gateway-oss/1.5.x/plugin-development/plugin-configuration.md rename to archive/gateway-oss/1.5.x/plugin-development/plugin-configuration.md diff --git a/app/gateway-oss/1.5.x/plugin-development/tests.md b/archive/gateway-oss/1.5.x/plugin-development/tests.md similarity index 100% rename from app/gateway-oss/1.5.x/plugin-development/tests.md rename to archive/gateway-oss/1.5.x/plugin-development/tests.md diff --git a/app/gateway-oss/1.5.x/proxy.md b/archive/gateway-oss/1.5.x/proxy.md similarity index 100% rename from app/gateway-oss/1.5.x/proxy.md rename to archive/gateway-oss/1.5.x/proxy.md diff --git a/app/gateway-oss/1.5.x/secure-admin-api.md b/archive/gateway-oss/1.5.x/secure-admin-api.md similarity index 100% rename from app/gateway-oss/1.5.x/secure-admin-api.md rename to archive/gateway-oss/1.5.x/secure-admin-api.md diff --git a/app/gateway-oss/1.5.x/upgrading.md b/archive/gateway-oss/1.5.x/upgrading.md similarity index 100% rename from app/gateway-oss/1.5.x/upgrading.md rename to archive/gateway-oss/1.5.x/upgrading.md diff --git a/autodoc-conf-ee/data.lua b/autodoc-conf-ee/data.lua index da24fe87d14c..f4969483c1fe 100644 --- a/autodoc-conf-ee/data.lua +++ b/autodoc-conf-ee/data.lua @@ -11,405 +11,9 @@ title: Configuration Reference for Kong Gateway source_url: https://github.com/Kong/kong-ee/blob/master/kong.conf.default --- -## Configuration loading +Reference for {{site.base_gateway}} configuration parameters. Set these parameters in `kong.conf`. -Kong comes with a default configuration file that can be found at -`/etc/kong/kong.conf.default` if you installed Kong via one of the official -packages. To start configuring Kong, you can copy this file: - -```bash -cp /etc/kong/kong.conf.default /etc/kong/kong.conf -``` - -Kong will operate with default settings should all the values in your -configuration be commented out. Upon starting, Kong looks for several -default locations that might contain a configuration file: - -``` -/etc/kong/kong.conf -/etc/kong.conf -``` - -You can override this behavior by specifying a custom path for your -configuration file using the `-c / --conf` argument in the CLI: - -```bash -kong start --conf /path/to/kong.conf -``` - -The configuration format is straightforward: simply uncomment any property -(comments are defined by the `#` character) and modify it to your needs. -Boolean values can be specified as `on`/`off` or `true`/`false` for convenience. - -## Verifying your configuration - -You can verify the integrity of your settings with the `check` command: - -```bash -kong check {PATH/TO/kong.conf} - -configuration at {PATH/TO/kong.conf} is valid -``` - -This command will take into account the environment variables you have -currently set, and will error out in case your settings are invalid. - -Additionally, you can also use the CLI in debug mode to have more insight -as to what properties Kong is being started with: - -```bash -kong start -c {kong.conf} --vv - -2016/08/11 14:53:36 [verbose] no config file found at /etc/kong.conf -2016/08/11 14:53:36 [verbose] no config file found at /etc/kong/kong.conf -2016/08/11 14:53:36 [debug] admin_listen = "0.0.0.0:8001" -2016/08/11 14:53:36 [debug] database = "postgres" -2016/08/11 14:53:36 [debug] log_level = "notice" -[...] -``` - -## Environment variables - -When loading properties out of a configuration file, Kong will also look for -environment variables of the same name. This allows you to fully configure Kong -via environment variables, which is very convenient for container-based -infrastructures, for example. - -To override a setting using an environment variable, declare an environment -variable with the name of the setting, prefixed with `KONG_` and capitalized. - -For example: - -``` -log_level = debug # in kong.conf -``` - -can be overridden with: - -```bash -export KONG_LOG_LEVEL=error -``` - -## Injecting Nginx directives - -Tweaking the Nginx configuration of your Kong instances allows you to optimize -its performance for your infrastructure. - -When Kong starts, it builds an Nginx configuration file. You can inject custom -Nginx directives to this file directly via your Kong configuration. - -### Injecting individual Nginx directives - -Any entry added to your `kong.conf` file that is prefixed by the following -supported namespaces will be converted into an equivalent Nginx -directive by removing the prefix and added to the appropriate section of the -Nginx configuration: - -- `nginx_main_`: Injects `` in Kong's configuration - `main` context. -- `nginx_events_`: Injects `` in Kong's `events {}` - block. -- `nginx_http_`: Injects `` in Kong's `http {}` block. -- `nginx_proxy_`: Injects `` in Kong's proxy - `server {}` block. -- `nginx_upstream_`: Injects `` in Kong's proxy - `upstream {}` block. -- `nginx_admin_`: Injects `` in Kong's Admin API - `server {}` block. -- `nginx_status_`: Injects `` in Kong's Status API - `server {}` block (only effective if `status_listen` is enabled). -- `nginx_stream_`: Injects `` in Kong's stream module - `stream {}` block (only effective if `stream_listen` is enabled). -- `nginx_sproxy_`: Injects `` in Kong's stream module - `server {}` block (only effective if `stream_listen` is enabled). -- `nginx_supstream_`: Injects `` in Kong's stream - module `upstream {}` block. - -For example, if you add the following line to your `kong.conf` file: - -``` -nginx_proxy_large_client_header_buffers=16 128k -``` - -it will add the following directive to the proxy `server` block of Kong's -Nginx configuration: - -``` -large_client_header_buffers 16 128k; -``` - -Like any other entry in `kong.conf`, these directives can also be specified -using [environment variables](#environment-variables) as shown above. For -example, if you declare an environment variable like this: - -```bash -export KONG_NGINX_HTTP_OUTPUT_BUFFERS="4 64k" -``` - -This will result in the following Nginx directive being added to the `http` -block: - -``` -output_buffers 4 64k; -``` - -If you want to add the same directive multiple times, you can specify it like the following example: - -```bash -export "KONG_NGINX_MAIN_ENV=HTTP_SSO_ENDPOINT;env PROXY_SSO_ENDPOINT" -export HTTP_SSO_ENDPOINT=http://example.com -export PROXY_SSO_ENDPOINT=http://example.com -``` - -This results in Kong injecting this line: - -``` -env HTTP_SSO_ENDPOINT;env PROXY_SSO_ENDPOINT; -``` - -As always, be mindful of your shell's quoting rules specifying values -containing spaces. - -For more details on the Nginx configuration file structure and block -directives, see the [Nginx reference](https://nginx.org/en/docs/beginners_guide.html#conf_structure). - -For a list of Nginx directives, see the [Nginx directives index](https://nginx.org/en/docs/dirindex.html). -Note however that some directives are dependent of specific Nginx modules, -some of which may not be included with the official builds of Kong. - -### Including files via injected Nginx directives - -For more complex configuration scenarios, such as adding entire new -`server` blocks, you can use the method described above to inject an -`include` directive to the Nginx configuration, pointing to a file -containing your additional Nginx settings. - -For example, if you create a file called `my-server.kong.conf` with -the following contents: - -``` -# custom server -server { - listen 2112; - location / { - # ...more settings... - return 200; - } -} -``` - -You can make the Kong node serve this port by adding the following -entry to your `kong.conf` file: - -``` -nginx_http_include = /path/to/your/my-server.kong.conf -``` - -or, alternatively, by configuring it via an environment variable: - -```bash -export KONG_NGINX_HTTP_INCLUDE="/path/to/your/my-server.kong.conf" -``` - -Now, when you start Kong, the `server` section from that file will be added to -that file, meaning that the custom server defined in it will be responding, -alongside the regular Kong ports: - -```bash -curl -I http://127.0.0.1:2112 -HTTP/1.1 200 OK -... -``` - -Note that if you use a relative path in an `nginx_http_include` property, that -path will be interpreted relative to the value of the `prefix` property of -your `kong.conf` file (or the value of the `-p` flag of `kong start` if you -used it to override the prefix when starting Kong). - -## Custom Nginx templates & embedding Kong - -For the vast majority of use-cases, using the Nginx directive injection system -explained above should be sufficient for customizing the behavior of Kong's -Nginx instance. This way, you can manage the configuration and tuning of your -Kong node from a single `kong.conf` file (and optionally your own included -files), without having to deal with custom Nginx configuration templates. - -There are two scenarios in which you may want to make use of custom Nginx -configuration templates directly: - -- In the rare occasion that you may need to modify some of Kong's default -Nginx configuration that are not adjustable via its standard `kong.conf` -properties, you can still modify the template used by Kong for producing its -Nginx configuration and launch Kong using your customized template. - -- If you need to embed Kong in an already running OpenResty instance, you -can reuse Kong's generated configuration and include it in your existing -configuration. - -### Custom Nginx templates - -Kong can be started, reloaded and restarted with an `--nginx-conf` argument, -which must specify an Nginx configuration template. Such a template uses the -[Penlight][Penlight] [templating engine][pl.template], which is compiled using -the given Kong configuration, before being dumped in your Kong prefix -directory, moments before starting Nginx. - -The following Lua functions are available in the [templating engine][pl.template]: - -- `pairs`, `ipairs` -- `tostring` -- `os.getenv` - -The default template for -Kong Gateway can be found by entering the following command on the system -running your Kong instance: `find / -type d -name "templates" | grep kong`. For -open-source Kong Gateway, you can also see the -[templates directory][templates]. - -The template is split in two -Nginx configuration files: `nginx.lua` and `nginx_kong.lua`. The former is -minimal and includes the latter, which contains everything Kong requires -to run. When `kong start` runs, right before starting Nginx, it copies these -two files into the prefix directory, which looks like so: - -``` -/usr/local/kong -├── nginx-kong.conf -└── nginx.conf -``` - -If you must tweak global settings that are defined by Kong but not adjustable -via the Kong configuration in `kong.conf`, you can inline the contents of the -`nginx_kong.lua` configuration template into a custom template file (in this -example called `custom_nginx.template`) like this: - -``` -# --------------------- -# custom_nginx.template -# --------------------- - -worker_processes ${{ "{{NGINX_WORKER_PROCESSES" }}}}; # can be set by kong.conf -daemon ${{ "{{NGINX_DAEMON" }}}}; # can be set by kong.conf - -pid pids/nginx.pid; # this setting is mandatory -error_log logs/error.log ${{ "{{LOG_LEVEL" }}}}; # can be set by kong.conf - -events { - use epoll; # a custom setting - multi_accept on; -} - -http { - - # contents of the nginx_kong.lua template follow: - - resolver ${{ "{{DNS_RESOLVER" }}}} ipv6=off; - charset UTF-8; - error_log logs/error.log ${{ "{{LOG_LEVEL" }}}}; - access_log logs/access.log; - - ... # etc -} -``` - -You can then start Kong with: - -```bash -kong start -c kong.conf --nginx-conf custom_nginx.template -``` - -## Embedding Kong in OpenResty - -If you are running your own OpenResty servers, you can also easily embed Kong -by including the Kong Nginx sub-configuration using the `include` directive. -If you have an existing Nginx configuration, you can simply include the -Kong-specific portion of the configuration which is output by Kong in a separate -`nginx-kong.conf` file: - -``` -# my_nginx.conf - -# ...your nginx settings... - -http { - include 'nginx-kong.conf'; - - # ...your nginx settings... -} -``` - -You can then start your Nginx instance like so: - -```bash -nginx -p /usr/local/openresty -c my_nginx.conf -``` - -and Kong will be running in that instance (as configured in `nginx-kong.conf`). - -## Serving both a website and your APIs from Kong - -A common use case for API providers is to make Kong serve both a website -and the APIs themselves over the Proxy port — `80` or `443` in -production. For example, `https://example.net` (Website) and -`https://example.net/api/v1` (API). - -To achieve this, we cannot simply declare a new virtual server block, -like we did in the previous section. A good solution is to use a custom -Nginx configuration template which inlines `nginx_kong.lua` and adds a new -`location` block serving the website alongside the Kong Proxy `location` -block: - -``` -# --------------------- -# custom_nginx.template -# --------------------- - -worker_processes ${{ "{{NGINX_WORKER_PROCESSES" }}}}; # can be set by kong.conf -daemon ${{ "{{NGINX_DAEMON" }}}}; # can be set by kong.conf - -pid pids/nginx.pid; # this setting is mandatory -error_log logs/error.log ${{ "{{LOG_LEVEL" }}}}; # can be set by kong.conf -events {} - -http { - # here, we inline the contents of nginx_kong.lua - charset UTF-8; - - # any contents until Kong's Proxy server block - ... - - # Kong's Proxy server block - server { - server_name kong; - - # any contents until the location / block - ... - - # here, we declare our custom location serving our website - # (or API portal) which we can optimize for serving static assets - location / { - root /var/www/example.net; - index index.htm index.html; - ... - } - - # Kong's Proxy location / has been changed to /api/v1 - location /api/v1 { - set $upstream_host nil; - set $upstream_scheme nil; - set $upstream_uri nil; - - # Any remaining configuration for the Proxy location - ... - } - } - - # Kong's Admin server block goes below - # ... -} -``` - -## Properties reference +To learn more about the `kong.conf` file, see the guide on the [Kong Configuration File](/gateway/{{page.kong_version}}/kong-production/kong-conf). ]] diff --git a/autodoc-conf-ee/run.lua b/autodoc-conf-ee/run.lua index f4d4a7a4b338..9b4bdc781bd2 100644 --- a/autodoc-conf-ee/run.lua +++ b/autodoc-conf-ee/run.lua @@ -140,7 +140,7 @@ infd:close() local parsed = assert(parser.parse(lines)) -local outpath = "app/gateway/" .. KONG_VERSION .. "/reference/configuration.md" +local outpath = "src/gateway/reference/configuration.md" local outfd = assert(io.open(outpath, "w+")) outfd:write(data.header) @@ -153,13 +153,13 @@ end for _, section in ipairs(parsed) do + write("---") write("") - write("### " .. titleize(section.name) .. " section") + write("## " .. titleize(section.name) .. " section") write("") if #section.description > 0 then write(format_description(section.description)) write("") - write("---") write("") end @@ -174,7 +174,7 @@ for _, section in ipairs(parsed) do if not pg_found then pg_found = true write("") - write("#### Postgres settings") + write("### Postgres settings") write("") write(table_header) end @@ -184,7 +184,7 @@ for _, section in ipairs(parsed) do if not cassandra_found then cassandra_found = true write("") - write("#### Cassandra settings") + write("### Cassandra settings") write("") write(table_header) end @@ -202,14 +202,14 @@ for _, section in ipairs(parsed) do " | " .. format_default(var.default)) else - write("#### " .. var.name) + write("### " .. var.name) if string.match(var.name, "admin_gui_auth") then write("{:.badge .enterprise}") elseif string.match(var.name, "admin_gui_session") then write("{:.badge .enterprise}") - elseif string.match(var.name, "telemetry") then + elseif string.match(var.name, "cluster_telemetry") then write("{:.badge .enterprise}") elseif string.match(var.name, "rbac") then @@ -218,7 +218,7 @@ for _, section in ipairs(parsed) do elseif string.match(var.name, "event_hooks") then write("{:.badge .enterprise}") - elseif string.match(var.name, "data_plane_config_cache") then + elseif string.match(var.name, "keyring") then write("{:.badge .enterprise}") elseif string.match(section.name, "PORTAL") then @@ -238,16 +238,12 @@ for _, section in ipairs(parsed) do elseif string.match(section.name, "ROUTE COLLISION") then write("{:.badge .enterprise}") - - elseif string.match(section.name, "DATABASE ENCRYPTION") then - write("{:.badge .enterprise}") end write("") write(format_description(var.description)) write("") write("**Default:** " .. format_default(var.default)) write("") - write("---") write("") end end diff --git a/broken-link-checker/excluded.json b/broken-link-checker/excluded.json index 865cd231d934..e235fe67ffed 100644 --- a/broken-link-checker/excluded.json +++ b/broken-link-checker/excluded.json @@ -17,6 +17,12 @@ "https://linkedin.com/*", "https://aws.amazon.com/*", "http://xip.io", - "https://admin.okta.com/", - "https://admin.okta.com/*" + "https://kong.127-0-0-1.nip.io/*", + "https://kong.127-0-0-1.nip.io", + "https://kong.7f000001.nip.io/*", + "https://portal.7f000001.nip.io/*", + "https://manager.7f000001.nip.io/*", + "https://admin.okta.com/*", + "https://kong.example.com", + "https://kong.127-0-0-1.nip.io/api" ] diff --git a/broken-link-checker/full.js b/broken-link-checker/full.js index 38d5a80455e6..ef77a192a780 100644 --- a/broken-link-checker/full.js +++ b/broken-link-checker/full.js @@ -44,11 +44,8 @@ const { SiteChecker } = require("broken-link-checker"); .replace("../app/_data/docs_nav_", "") .replace(/\.yml$/, ""); - // Special case Konnect Platform - if (info === "konnect_platform") { - item.type = "konnect-platform"; - item.version = ""; - } else if (info === "konnect") { + // Special case Konnect + if (info === "konnect") { item.type = "konnect"; item.version = ""; } else { diff --git a/docs/single-sourced-versions.md b/docs/single-sourced-versions.md index b6309bdb4f4a..8b3a5737dd75 100644 --- a/docs/single-sourced-versions.md +++ b/docs/single-sourced-versions.md @@ -112,6 +112,31 @@ items: src: terminology-v3 ``` +## Rendering unlisted pages + +In some cases you may want to render a page within a version without adding it to the side navigation. You can accomplish this by adding an `unlisted` section to the data file: + +```yaml +product: deck +release: 1.11.x +generate: true +items: + - title: Introduction + url: /deck/ + absolute_url: true + items: + - text: Terminology + # Reads `src/deck/terminology-v3.md` and writes `/deck//terminology/index.html` + # This is how you can have multiple release of a single source file when completely rewriting content + url: /terminology + src: terminology-v3 +unlisted: + # Read from src/deck/how-to/example.md. Rendered at /deck/how-to/example/ + # Not listed in the sidebar + # Options such as 'generate' and 'src' are valid here too + - url: /how-to/example +``` + ## Conditional Rendering As we add new functionality, we'll want content to be displayed for specific releases of a product. We can use the `if_version` block for this: diff --git a/jekyll-dev.yml b/jekyll-dev.yml index c0ca979f3e15..3d9f43611497 100644 --- a/jekyll-dev.yml +++ b/jekyll-dev.yml @@ -151,6 +151,12 @@ defaults: layout: "docs-v2" version-index: 2 + - scope: + path: "gateway/3.0.x/" + values: + layout: "docs-v2" + version-index: 3 + - scope: path: "about" values: @@ -170,7 +176,7 @@ defaults: layout: "docs-v2" # product name vars -ee_product_name: Kong Gateway # This is a legacy variable that used to differentiate the Enterprise package from the Gateway product. Leaving this in case of further rebranding. +ee_product_name: Kong Enterprise ce_product_name: Kong Gateway (OSS) base_gateway: Kong Gateway mesh_product_name: Kong Mesh @@ -180,8 +186,3 @@ konnect_short_name: Konnect konnect_saas: Konnect Cloud package_name: Kong Konnect company_name: Kong Inc. - -# Konnect tier vars -free_tier: Kong Gateway -plus_tier: Kong Konnect Plus -enterprise_tier: Kong Konnect Enterprise diff --git a/jekyll.yml b/jekyll.yml index d37ea17ebb05..1c14cef59413 100644 --- a/jekyll.yml +++ b/jekyll.yml @@ -152,6 +152,12 @@ defaults: layout: "docs-v2" version-index: 2 + - scope: + path: "gateway/3.0.x/" + values: + layout: "docs-v2" + version-index: 3 + - scope: path: "about" values: @@ -171,7 +177,7 @@ defaults: layout: "docs-v2" # product name vars -ee_product_name: Kong Gateway # This is a legacy variable that used to differentiate the Enterprise package from the Gateway product. Leaving this in case of further rebranding. +ee_product_name: Kong Enterprise ce_product_name: Kong Gateway (OSS) base_gateway: Kong Gateway mesh_product_name: Kong Mesh @@ -181,8 +187,3 @@ konnect_short_name: Konnect konnect_saas: Konnect Cloud package_name: Kong Konnect company_name: Kong Inc. - -# Konnect tier vars -free_tier: Kong Gateway -plus_tier: Kong Konnect Plus -enterprise_tier: Kong Konnect Enterprise diff --git a/pdf-generation/list-versions.js b/pdf-generation/list-versions.js index 1768eda0ae64..be80dbc606f6 100644 --- a/pdf-generation/list-versions.js +++ b/pdf-generation/list-versions.js @@ -20,15 +20,10 @@ module.exports = async function (path) { const item = { path: f } const info = f.replace('../app/_data/docs_nav_', '').replace(/\.yml$/, '') - // Special case Konnect Platform - if (info === 'konnect_platform') { - item.type = 'konnect-platform' - item.version = '' - } else { const x = info.split('_') item.type = lookup[x[0]] item.version = x[1] - } + return item }) .filter((n) => n) diff --git a/show-version-diff/run.js b/show-version-diff/run.js index f63a790df933..99e9c975b5df 100644 --- a/show-version-diff/run.js +++ b/show-version-diff/run.js @@ -73,11 +73,8 @@ files = files const item = { path: f }; const info = f.replace("../app/_data/docs_nav_", "").replace(/\.yml$/, ""); - // Special case Konnect Platform - if (info === "konnect_platform") { - item.type = "konnect-platform"; - item.version = ""; - } else if (info === "konnect") { + // Special case Konnect + if (info === "konnect") { item.type = "konnect"; item.version = ""; } else { diff --git a/src/deck/availability-stages.md b/src/deck/availability-stages.md new file mode 100644 index 000000000000..29c582eadfcc --- /dev/null +++ b/src/deck/availability-stages.md @@ -0,0 +1,6 @@ +--- +title: Stages of software availability +content-type: reference +--- + +{% include_cached /md/availability-stages.md %} diff --git a/src/deck/guides/defaults-v2.md b/src/deck/guides/defaults-v2.md index 7e8991661ecd..bf9ef5c9dd99 100644 --- a/src/deck/guides/defaults-v2.md +++ b/src/deck/guides/defaults-v2.md @@ -58,7 +58,7 @@ want to use, skip to [setting defaults](#set-defaults). 2. Add the following sample service and route to the file: ```yaml - _format_version: "0.1" + _format_version: "3.0" services: - host: mockbin.org name: example_service @@ -163,7 +163,7 @@ Summary: `defaults`: ```yaml - _format_version: "0.1" + _format_version: "3.0" _info: defaults: services: @@ -189,7 +189,7 @@ Summary: For example: ```yaml - _format_version: "0.1" + _format_version: "3.0" _info: defaults: route: diff --git a/src/deck/guides/defaults.md b/src/deck/guides/defaults.md index 0dc413c6a456..c8ab4442b260 100644 --- a/src/deck/guides/defaults.md +++ b/src/deck/guides/defaults.md @@ -43,7 +43,7 @@ again to see how decK interprets default values. 1. Add the following sample service, route, and plugin to the file: ```yaml - _format_version: "0.1" + _format_version: "3.0" services: - host: mockbin.org name: example_service @@ -127,7 +127,7 @@ overwriting your current state file, specify a different filename: default values populated for the service, route, and Basic Auth plugin: ```yaml - _format_version: "1.1" + _format_version: "3.0" plugins: - config: anonymous: null @@ -196,7 +196,7 @@ configuration would overwrite the value in your environment. `defaults`: ```yaml - _format_version: "0.1" + _format_version: "3.0" _info: defaults: services: @@ -223,7 +223,7 @@ configuration would overwrite the value in your environment. Service object: ```yaml - _format_version: "0.1" + _format_version: "3.0" _info: defaults: service: @@ -242,7 +242,7 @@ configuration would overwrite the value in your environment. Or you could define custom default values for all available fields: ```yaml - _format_version: "0.1" + _format_version: "3.0" _info: defaults: route: diff --git a/src/deck/guides/environment-variables.md b/src/deck/guides/environment-variables.md index 45fe0e57685a..6f4f232cad43 100644 --- a/src/deck/guides/environment-variables.md +++ b/src/deck/guides/environment-variables.md @@ -21,7 +21,7 @@ You can use this method for any sensitive content. 2. Save the following snippet into a `env-demo.yaml` file: ```yaml - _format_version: "1.1" + _format_version: "3.0" consumers: - keyauth_credentials: - key: {%raw%}${{ env "DECK_API_KEY" }}{%endraw%} diff --git a/src/deck/guides/getting-started.md b/src/deck/guides/getting-started.md index 845d1d0e6bdc..44e0c0dabfdf 100644 --- a/src/deck/guides/getting-started.md +++ b/src/deck/guides/getting-started.md @@ -124,7 +124,7 @@ If you already have {{site.base_gateway}} set up with the configuration of your configuration in this guide, the file should look like this: ```yaml - _format_version: "1.1" + _format_version: "3.0" services: - connect_timeout: 60000 host: example.com @@ -168,7 +168,7 @@ Edit the `kong.yaml` file, making the following changes: Your `kong.yaml` file should now look like this: ```yaml -_format_version: "1.1" +_format_version: "3.0" services: - connect_timeout: 60000 host: example.com diff --git a/src/deck/guides/kong-enterprise.md b/src/deck/guides/kong-enterprise.md index 46dc1f464c41..ec70e76d6e19 100644 --- a/src/deck/guides/kong-enterprise.md +++ b/src/deck/guides/kong-enterprise.md @@ -66,7 +66,7 @@ To set a workspace directly in the state file, use the `_workspace` parameter. For example: ```yaml -_format_version: "1.1" +_format_version: "3.0" _workspace: default services: - name: example_service diff --git a/src/deck/guides/konnect.md b/src/deck/guides/konnect.md index d9b56ea03ed9..490934ab2e4e 100644 --- a/src/deck/guides/konnect.md +++ b/src/deck/guides/konnect.md @@ -140,7 +140,7 @@ or use a flag when running any decK command. * Target a runtime group in your state file with the `konnect_runtime_group` parameter: ```yaml - _format_version: "1.1" + _format_version: "3.0" _konnect: runtime_group_name: staging ``` @@ -181,7 +181,7 @@ If the {{site.konnect_short_name}} service doesn't exist, setting a `_Konnect` t For example, see the following configuration snippet, where the Gateway service named `example_service` is attached to the {{site.konnect_short_name}} service `example`: ```yaml -_format_version: "1.1" +_format_version: "3.0" _konnect: runtime_group_name: default services: diff --git a/src/deck/guides/multi-file-state.md b/src/deck/guides/multi-file-state.md index b34d17abdec8..1bc17ad7c693 100644 --- a/src/deck/guides/multi-file-state.md +++ b/src/deck/guides/multi-file-state.md @@ -46,7 +46,7 @@ deck dump --select-tag team-svc1 -o svc1.yaml ```sh $ cat svc1.yaml -_format_version: "1.1" +_format_version: "3.0" _info: defaults: {} select_tags: @@ -70,7 +70,7 @@ deck dump --select-tag team-svc2 -o svc2.yaml ```sh $ cat svc2.yaml -_format_version: "1.1" +_format_version: "3.0" _info: defaults: {} select_tags: @@ -114,4 +114,4 @@ Summary: > As a best practice, the way you `sync` configurations should be consistent with the way you initially `dump`ed them. -{% endif_version %} \ No newline at end of file +{% endif_version %} diff --git a/src/gateway/admin-api/admins/reference.md b/src/gateway/admin-api/admins/reference.md new file mode 100644 index 000000000000..55b9c3a570d6 --- /dev/null +++ b/src/gateway/admin-api/admins/reference.md @@ -0,0 +1,338 @@ +--- +title: Admins Reference +badge: enterprise +--- + +## List Admins +**Endpoint** + +
      /admins
      + +**Response** + +``` +HTTP 200 OK +``` + +```json +{ + "data": [{ + "created_at": 1556638385, + "id": "665b4070-541f-48bf-82c1-53030babaa81", + "updated_at": 1556638385, + "status": 4, + "username": "test-admin", + "email": "test@test.com", + "rbac_token_enabled": true + }, { + "created_at": 1556563122, + "id": "a93ff120-9e6c-4198-b47e-f779104c7eac", + "updated_at": 1556563122, + "status": 0, + "username": "kong_admin", + "rbac_token_enabled": false + }], + "next": null +} +``` + +The `status` field in the response indicates if the admin has accepted their invitation: + +| Code | Status | +|------|------------| +| 0 | Approved | +| 1 | Pending | +| 2 | Rejected | +| 3 | Revoked | +| 4 | Invited | +| 5 | Unverified | + +## Invite an Admin +**Endpoint** + +
      /admins
      + +| Attribute | Description | +|-------------|------------------------------------------------------------| +| `email` | The **Admin**'s email address | +| `username` | The **Admin**'s username | +| `custom_id`
      optional | The **Admin**'s custom ID | +| `rbac_token_enabled` | Allows the **Admin** to use and reset their RBAC token; `true` by default | + +**Response** + +``` +HTTP 200 OK +``` + +```json +{ + "admin": { + "created_at": 1556638641, + "id": "8f0a742f-07f3-49e0-90d7-4fc7eea7e6a4", + "updated_at": 1556638641, + "status": 4, + "username": "test-case-3", + "email": "test3@test.com", + "rbac_token_enabled": true + } +} +``` + +## Register an Admin's Credentials +**Endpoint** + +
      /admins/register
      + +| Attribute | Description | +|-------------|---------------------------| +| `token` | The authentication token | +| `username` | The **Admin**'s username | +| `email` | The **Admin**'s email address | +| `password` | The **Admin**'s new password | + +**Response** + +``` +HTTP 201 Created +``` + +## Send a Password-Reset Email to an Admin +**Endpoint** + +
      /admins/password_resets
      + +| Attribute | Description | +|-------------|------------------------------------------------------------| +| `email` | The **Admin**'s email address | + +**Response** + +``` +HTTP 201 Created +``` + +## Reset an Admin's Password +**Endpoint** + +
      /admins/password_resets
      + +| Attribute | Description | +|-------------|------------------------------------------------------------| +| `email` | The **Admin**'s email address | +| `password` | The **Admin**'s new password | +| `token` | The authentication token | + +**Response** + +``` +HTTP 200 OK +``` + +## Retrieve an Admin +**Endpoint** + +
      /admins/{name_or_id}
      + +| Attribute | Description | +|------------|-----------------------------------| +| `name_or_id` | The **Admin**'s username or ID | +| `generate_register_url`
      optional | `true` returns a unique registration URL for the **Admin** | + +**Notes:** +* `generate_register_url` will only generate a URL if the **Admin**'s +invitation status is 4 ("invited"). +* `generate_register_url` will override the preåvious registration URL +for the particular **Admin** each time it is requested. + +**Response** + +``` +HTTP 200 OK +``` + +```json +{ + "created_at": 1556638385, + "id": "665b4070-541f-48bf-82c1-53030babaa81", + "updated_at": 1556638385, + "status": 4, + "username": "test-admin", + "email": "test@test.com", + "rbac_token_enabled": true +} +``` + +## Update an Admin +**Endpoint** + +
      /admins/{name_or_id}
      + +| Attribute | Description | +|----------------------|--------------------------------------------| +| `name_or_id` | The **Admin**'s current username or custom ID | +| `email`
      optional | The **Admin**'s new email address | +| `username`
      optional | The **Admin**'s new username | +| `custom_id`
      optional | The **Admin**'s new custom ID | +| `rbac_token_enabled` | Allows the **Admin** to use and reset their RBAC token; `true` by default | + +**Response** + +``` +HTTP 200 OK +``` + +```json +{ + "created_at": 1556638385, + "id": "665b4070-541f-48bf-82c1-53030babaa81", + "updated_at": 1556639017, + "status": 4, + "username": "test-renamed", + "email": "test@test.com" + "rbac_token_enabled": true +} +``` + +## Delete an Admin +**Endpoint** + +
      /admins/{name_or_id}
      + +| Attribute | Description | +|--------------|-----------------------------------| +| `name_or_id` | The **Admin**'s username or ID | + +**Response** + +``` +HTTP 204 No Content +``` + +## List an Admin's Roles +**Endpoint** + +
      /admins/{name_or_id}/roles
      + +| Attribute | Description | +|--------------|-----------------------------------| +| `name_or_id` | The **Admin**'s username or ID | + +**Response** + +``` +HTTP 200 OK +``` + +```json +{ + "roles": [{ + "comment": "Read access to all endpoints, across all workspaces", + "created_at": 1556563122, + "id": "7574eb1d-c9fa-46a9-bd3a-3f1b4b196287", + "name": "read-only", + "is_default": false + }, { + "comment": "Full access to all endpoints, across all workspaces—except RBAC Admin API", + "created_at": 1556563122, + "id": "7fdea5c8-2bfa-4aa9-9c21-7bb9e607186d", + "name": "admin", + "is_default": false + }] +} +``` + +## Create or Update an Admin's Roles +**Endpoint** + +
      /admins/{name_or_id}/roles
      + +| Attribute | Description | +|--------------|-----------------------------------------------------------| +| `name_or_id` | The **Admin**'s current username or ID | +| `roles` | (comma separated) string of names of Roles to create or update for an **Admin** | + +**Response** + +``` +HTTP 201 OK +``` + + +```json +{ + "roles": [{ + "comment": "Read access to all endpoints, across all workspaces", + "created_at": 1556563122, + "id": "7574eb1d-c9fa-46a9-bd3a-3f1b4b196287", + "name": "read-only", + "is_default": false + }, { + "comment": "Full access to all endpoints, across all workspaces—except RBAC Admin API", + "created_at": 1556563122, + "id": "7fdea5c8-2bfa-4aa9-9c21-7bb9e607186d", + "name": "admin", + "is_default": false + }, { + "comment": "Full access to all endpoints, across all workspaces", + "created_at": 1556563122, + "id": "99bd8d18-f5b6-410e-aefe-d75f4252f13c", + "name": "super-admin", + "is_default": false + }] +} +``` + +## Delete an Admin's Role +**Endpoint** + +
      /admins/{name_or_id}/roles
      + +| Attribute | Description | +|--------------|-----------------------------------------------------------| +| `name_or_id` | The **Admin**'s current username or custom ID | +| `roles` | (comma separated) string of names of Roles to remove from an **Admin** | + +**Response** + +``` +HTTP 204 No Content +``` + +## List an Admin's Workspaces +**Endpoint** + +
      /admins/{name_or_id}/workspaces
      + +| Attribute | Description | +|--------------|-----------------------------------| +| `name_or_id` | The **Admin**'s username or ID | + +**Response** + +``` +HTTP 200 OK +``` + +```json +[{ + "created_at": 1556563122, + "config": { + "portal": true, + "portal_auto_approve": true + }, + "id": "00000000-0000-0000-0000-000000000000", + "name": "default", + "meta": {} +}, { + "created_at": 1556570807, + "config": { + "portal": true + }, + "id": "57b3ce24-6d29-427f-af13-15bd60430e56", + "name": "sdfgsdfg", + "meta": { + "color": "#3894f0" + } +}] +``` diff --git a/src/gateway/admin-api/consumer-groups/reference.md b/src/gateway/admin-api/consumer-groups/reference.md new file mode 100644 index 000000000000..7a229c98ed3e --- /dev/null +++ b/src/gateway/admin-api/consumer-groups/reference.md @@ -0,0 +1,406 @@ +--- +title: Consumer Groups Reference +badge: enterprise +--- + +Use consumer groups to manage custom rate limiting configuration for +subsets of consumers. + +The `consumer_groups` endpoint works together with the [Rate Limiting Advanced plugin](/hub/kong-inc/rate-limiting-advanced). +To use consumer groups for rate limiting, configure the plugin with the +`enforce_consumer_groups` and `consumer_groups` parameters, then use the +`/consumer_groups` endpoint to manage the groups. + +For more information and examples of setting up and managing consumer groups, see the +[Consumer Groups examples](/gateway/{{page.kong_version}}/kong-enterprise/consumer-groups). + +{:.note} +> **Note:** Consumer groups are not supported in declarative configuration with +decK. If you have consumer groups in your configuration, decK will ignore them. + +## List consumer groups + +### List all consumer groups + +**Endpoint** + +
      /consumer_groups
      + +**Response** + +``` +HTTP/1.1 200 OK +``` + +```json +{ + "data": [ + { + "created_at": 1557522650, + "id": "42b022c1-eb3c-4512-badc-1aee8c0f50b5", + "name": "my_group" + }, + { + "created_at": 1637706162, + "id": "fa6881b2-f49f-4007-9475-577cd21d34f4", + "name": "my_group2" + } + ], + "next": null +} +``` + +### List a specific consumer group + +**Endpoint** + +
      /consumer_groups/{GROUP_NAME|GROUP_ID}
      + +Attribute | Description +---------: | -------- +`GROUP_NAME|GROUP_ID`
      *required* | The name or UUID of the consumer group. + +**Response** + +``` +HTTP/1.1 200 OK +``` + +```json +{ + "consumer_group": { + "created_at": 1638917780, + "id": "be4bcfca-b1df-4fac-83cc-5cf6774bf48e", + "name": "JL" + } +} +``` + + +### List all consumers in a consumer group + +**Endpoint** + +
      /consumer_groups/{GROUP_NAME|GROUP_ID}/consumers
      + +Attribute | Description +---------: | -------- +`GROUP_NAME|GROUP_ID`
      *required* | The name or UUID of the consumer group. + +**Response** + +``` +HTTP/1.1 200 OK +``` + +```json +{ + "consumers": [ + { + "created_at": 1638918560, + "id": "288f2bfc-04e2-4ec3-b6f3-40408dff5417", + "type": 0, + "username": "BarryAllen", + "username_lower": "barryallen" + }, + { + "created_at": 1638915577, + "id": "8089a0e6-1d31-4e00-bf51-5b902899b4cb", + "type": 0, + "username": "DianaPrince", + "username_lower": "dianaprince" + } + ] +} +``` + +### List consumer groups for a consumer + +View all consumer groups that a consumer is assigned to. + +**Endpoint** + +
      /consumers/{CONSUMER_NAME|CONSUMER_ID}/consumer_groups
      + +Attribute | Description +---------: | -------- +`USERNAME|CONSUMER_ID`
      *required* | The name or UUID of the consumer. + +**Response** + +``` +HTTP/1.1 200 OK +``` + +```json +{ + "consumer_groups": [ + { + "created_at": 1638918476, + "id": "e2c3f16e-22c7-4ef4-b6e4-ab25c522b339", + "name": "JL" + } + ] +} +``` + + +## Create a consumer group + +**Endpoint** + +
      /consumer_groups
      + +**Request body** + +Attribute | Description +---------: | -------- +`name`
      *required* | A unique name for the consumer group you want to create. + +**Response** + +``` +HTTP 201 Created +``` + +```json +{ + "created_at": 1557522650, + "id": "fa6881b2-f49f-4007-9475-577cd21d34f4", + "name": "JL", +} +``` + +**Endpoint** + +
      /consumer_groups/{GROUP_NAME}
      + +Attribute | Description +---------: | -------- +`GROUP_NAME`
      *required* | A unique name for the consumer group you want to create. + + +**Response** + +``` +HTTP 201 Created +``` + +```json +{ + "created_at": 1557522650, + "id": "fa6881b2-f49f-4007-9475-577cd21d34f4", + "name": "JL", +} +``` + +## Add a consumer to a group + +Add a consumer to a specific consumer group. + +If you add a consumer to multiple groups: +* If all groups are allowed by the Rate Limiting Advanced plugin, +only the first group's settings will apply. +* Otherwise, whichever group is specified in the Rate Limiting Advanced +plugin will be active. + +**Consumers endpoint** +
      /consumers/{CONSUMER_NAME|CONSUMER_ID}/consumer_groups
      + +Attribute | Description +---------: | -------- +`CONSUMER_NAME|CONSUMER_ID`
      *required* | The name or UUID of the consumer. + +**Request body** + +Attribute | Description +---------: | -------- +`group`
      *required* | The name or ID of the group to add the consumer to. + +**Response** + +``` +HTTP 201 Created +``` + +```json +{ + "consumer": { + "created_at": 1638918560, + "custom_id": null, + "id": "288f2bfc-04e2-4ec3-b6f3-40408dff5417", + "tags": null, + "type": 0, + "username": "BarryAllen", + "username_lower": "barryallen" + }, + "consumer_groups": [ + { + "created_at": 1638918476, + "id": "e2c3f16e-22c7-4ef4-b6e4-ab25c522b339", + "name": "JL" + } + ] +} +``` + +**Consumer groups endpoint** +
      /consumer_groups/{GROUP_NAME|GROUP_ID}/consumers
      + +Attribute | Description +---------: | -------- +`GROUP_NAME|GROUP_ID`
      *required* | The name or UUID of the consumer group. + + +**Request body** + +Attribute | Description +---------: | -------- +`consumer`
      *required* | The name or ID of the consumer to add to this group. + +**Response** + +``` +HTTP 201 Created +``` + +```json +{ + "consumer_group": { + "created_at": 1638915521, + "id": "8a4bba3c-7f82-45f0-8121-ed4d2847c4a4", + "name": "JL" + }, + "consumers": [ + { + "created_at": 1638915577, + "id": "8089a0e6-1d31-4e00-bf51-5b902899b4cb", + "type": 0, + "username": "DianaPrince", + "username_lower": "dianaprince" + } + ] +} +``` + +## Delete a consumer group + +Deleting a consumer group removes all consumers from that group. It does +**not** delete any consumers. + +**Endpoint** +
      /consumer_groups/{GROUP_NAME|GROUP_ID}
      + +Attribute | Description +---------: | -------- +`GROUP_NAME|GROUP_ID`
      *required* | The name or UUID of the consumer group to delete. + +**Response** + +``` +HTTP/1.1 204 No Content +``` + +## Remove consumers + +### Remove a consumer from all groups + +**Endpoint** +
      /consumers/{CONSUMER_NAME|CONSUMER_ID}/consumer_groups
      + +Attribute | Description +---------: | -------- +`CONSUMER_NAME|CONSUMER_ID`
      *required* | The name or UUID of the consumer to remove from all groups. + +**Response** + +``` +HTTP/1.1 204 No Content +``` + +### Remove a consumer from a consumer group + +**Consumer endpoint** +
      /consumers/{CONSUMER_NAME|CONSUMER_ID}/consumer_groups/{GROUP_NAME|GROUP_ID}
      + +Attribute | Description +---------: | -------- +`CONSUMER_NAME|CONSUMER_ID`
      *required* | The name or UUID of the consumer to remove. +`GROUP_NAME|GROUP_ID`
      *required* | The name or UUID of the consumer group to remove the consumer from. + +**Response** + +``` +HTTP/1.1 204 No Content +``` + +**Consumer groups endpoint** +
      /consumer_groups/{GROUP_NAME|GROUP_ID}/consumers/{CONSUMER_NAME|CONSUMER_ID}
      + +Attribute | Description +---------: | -------- +`GROUP_NAME|GROUP_ID`
      *required* | The name or UUID of the consumer group to remove the consumer from. +`CONSUMER_NAME|CONSUMER_ID`
      *required* | The name or UUID of the consumer to remove. + +**Response** + +``` +HTTP/1.1 204 No Content +``` + +### Remove all consumers from a consumer group + +
      /consumer_groups/{GROUP_NAME|GROUP_ID}/consumers
      + +Attribute | Description +---------: | -------- +`GROUP_NAME|GROUP_ID`
      *required* | The name or UUID of the consumer group to remove all consumers from. + +**Response** + +``` +HTTP/1.1 204 No Content +``` + +## Configure rate limiting for a consumer group + +Define custom rate limiting settings for a consumer group. This endpoint +overrides the settings of the Rate Limiting Advanced plugin. + +
      /consumer_groups/{GROUP_NAME|GROUP_ID}/overrides/plugins/rate-limiting-advanced
      + +Attribute | Description +---------: | -------- +`GROUP_NAME|GROUP_ID`
      *required* | The name or UUID of the consumer group to configure. + +**Request Body** + +Attribute | Description +---------: | -------- +`config.limit`
      *required* | An array of one or more requests-per-window limits to apply. There must be a matching number of window limits and sizes specified. +`config.window_size`
      *required* | An array of one or more window sizes to apply a limit to (defined in seconds). There must be a matching number of window limits and sizes specified. +`config.window_type`
      *optional* | Set the time window type to either `sliding` (default) or `fixed`. +`config.retry_after_jitter_max`
      *optional* | The upper bound of a jitter (random delay) in seconds to be added to the `Retry-After` header of denied requests (status = `429`) in order to prevent all the clients from coming back at the same time. The lower bound of the jitter is `0`; in this case, the `Retry-After` header is equal to the `RateLimit-Reset` header. + +**Response** + +``` +HTTP/1.1 201 Created +``` + +```json +{ + "config": { + "limit": [ + 10 + ], + "retry_after_jitter_max": 0, + "window_size": [ + 10 + ], + "window_type": "sliding" + }, + "group": "test-group", + "plugin": "rate-limiting-advanced" +} +``` diff --git a/src/gateway/admin-api/db-encryption.md b/src/gateway/admin-api/db-encryption.md new file mode 100644 index 000000000000..bff20650be0d --- /dev/null +++ b/src/gateway/admin-api/db-encryption.md @@ -0,0 +1,203 @@ +--- +title: Keyring and Data Encryption Reference +badge: enterprise +--- + +## View Keyring +**Endpoint** + +
      /keyring
      + +**Response** + +``` +HTTP 200 OK +``` + +```json +{ + "active": "RfsDJ2Ol", + "ids": [ + "RfsDJ2Ol", + "xSD219lH" + ] +} + +``` + +## View Active Key +**Endpoint** + +
      /keyring/active
      + +**Response** + +``` +HTTP 200 OK +``` + +```json +{ + "id": "RfsDJ2Ol" +} + +``` + +## Export Keyring + +*This endpoint is only available with the `cluster` keyring strategy.* + +*The endpoint requires that the `keyring_public_key` and `keyring_private_key` Kong configuration values are defined.* + +**Endpoint** + +
      /keyring/export
      + +**Response** + +``` +HTTP 200 OK +``` + +```json +{ + "data": "..." +} +``` + +## Import Exported Keyring + +*This endpoint is only available with the `cluster` keyring strategy.* + +*The endpoint requires that the `keyring_public_key` and `keyring_private_key` Kong configuration values are defined.* + +**Endpoint** + +
      /keyring/import
      + +**Request Body** + +| Attribute | Description | +| --------- | ----------- | +| `data` | Base64-encoded keyring export material. | + + +**Response** + +``` +HTTP 201 Created +``` + +## Import Key + +*This endpoint is only available with the `cluster` keyring strategy.* + +*The endpoint requires that the `keyring_public_key` and `keyring_private_key` Kong configuration values are defined.* + +**Endpoint** + +
      /keyring/import/raw
      + +**Request Body** + +| Attribute | Description | +| --------- | ----------- | +| `id` | 8-byte key identifier. | +| `data` | Base64-encoded keyring export material. | + + +**Response** + +``` +HTTP 201 Created +``` + +## Recover Keyring from Database + +*This endpoint is only available with the `cluster` keyring strategy.* + +*The endpoint requires that the `keyring_recovery_public_key` Kong configuration value is defined.* + +**Endpoint** + +
      /keyring/recover
      + +**Request Body** + +| Attribute | Description | +| --------- | ----------- | +| `recovery_private_key` | The content of the private key. | + +**Response** + +``` +HTTP 200 OK +``` + +```json +{ + "message": "successfully recovered 1 keys", + "recovered": [ + "RfsDJ2Ol" + ], + "not_recovered": [ + "xSD219lH" + ] +} +``` + +## Generate New Key + +*This endpoint is only available with the `cluster` keyring strategy.* + +**Endpoint** + +
      /keyring/generate
      + +**Response** + +``` +HTTP 201 Created +``` + +```json +{ + "id": "500pIquV", + "key": "3I23Ben5m7qKcCA/PK7rnsNeD3kI4IPtA6ki7YjAgKA=" +} +``` + +## Remove Key from Keyring + +*This endpoint is only available with the `cluster` keyring strategy.* + +**Endpoint** + +
      /keyring/remove
      + +**Request Body** + +| Attribute | Description | +| --------- | ----------- | +| `key` | 8-byte key identifier. | + + +**Response** + +``` +HTTP 204 No Content +``` + +## Sync Keyring with Vault Endpoint + +*This endpoint is only available with the `vault` keyring strategy.* + +**Endpoint** + +
      /keyring/vault/sync
      + +**Response** + +``` +HTTP 204 No Content +``` diff --git a/src/gateway/admin-api/developers/reference.md b/src/gateway/admin-api/developers/reference.md new file mode 100644 index 000000000000..6a2c5a33ca2d --- /dev/null +++ b/src/gateway/admin-api/developers/reference.md @@ -0,0 +1,1565 @@ +--- +title: Developers Reference +badge: enterprise +--- + +You can administer a Dev Portal instance through the Kong Admin API. Use the +`/developers` API to: +* Manage developers and applications +* Create, update, and delete roles +* Manage authentication for developers and applications + +{:.note} +> **Note:** The `/developers` API is part of the Kong Admin API, and is meant +for bulk developer administration. +This is not the same as the Dev Portal API [`/developer`](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/portal-api/#/operations/get-developer) endpoints, +which return data on the logged-in developer. + +## Using the API in workspaces + +Any requests that don't specify a workspace target the `default` workspace. +To target a different workspace, add `/{WORKSPACE_NAME}/` to the start of any +endpoint. + +For example, if you don't specify a workspace, +this request retrieves a list of developers from the `default` workspace: + +{% navtabs codeblock %} +{% navtab cURL %} +```sh +curl -i -X GET http://localhost:8001/developers +``` +{% endnavtab %} +{% navtab HTTPie %} +```sh +http :8001/developers +``` +{% endnavtab %} +{% endnavtabs %} + +While this request retrieves all developers from the workspace `SRE`: + +{% navtabs codeblock %} +{% navtab cURL %} +```sh +curl -i -X GET http://localhost:8001/SRE/developers +``` +{% endnavtab %} +{% navtab HTTPie %} +```sh +http :8001/SRE/developers +``` +{% endnavtab %} +{% endnavtabs %} + +## Developers + +### List all developers + +Retrieve metadata for all developers. + +**Endpoint** + +
      /developers
      + +**Response** + +``` +HTTP/1.1 200 OK +``` + +```json +{ + "data": [ + { + "consumer": { + "id": "3f0ad41f-39b5-4fd0-ad1e-0b779fcee35c" + }, + "created_at": 1644615612, + "email": "some-email@example.com", + "id": "3c6d4d8c-db86-4236-800b-8911e788425b", + "meta": "{\"full_name\":\"Barry\"}", + "roles": [ + "application developer" + ], + "status": 0, + "updated_at": 1644615612 + }, + { + "consumer": { + "id": "9dbd764c-9548-4c9f-a4d1-6ea11e32a803" + }, + "created_at": 1644615583, + "email": "some-other-email@example.com", + "id": "5f60930a-ad12-4303-ac5a-59d121ad4942", + "meta": "{\"full_name\":\"Diana\"}", + "roles": [ + "application developer" + ], + "status": 0, + "updated_at": 1644615583 + } + ], + "next": null, + "total": 2 +} +``` + +### Create a developer account + +Create a new developer account. + +All new developers are set to **Requested Approval** status by default, and +must be changed to **Approved** before anyone can use the account. + +You can approve developers through the Kong Manager, or approve the developer +account as you're creating it by setting the developer's status manually. + +**Endpoint** + +
      /developers
      + +**Request body** + +Attribute | Description +---------: | -------- +`meta` | Metadata for the account in JSON format. Accepts fields defined in the Dev Portal settings.

      By default, the meta attribute requires a `full_name` field. You can remove this requirement, or add other fields as neccessary.

      For example: `meta: {"full_name":""}`. +`email`
      *required* | The email of the developer to create. This becomes their login username. +`password`
      *semi-optional* | Create a password for the developer. Required if basic authentication is enabled. +`key`
      *semi-optional* | Assign an API key to the developer. Required if key authentication is enabled. +`id` | The developer entity ID. You can set your own UUID for this value, or leave it out to let Kong Gateway autogenerate a UUID. +`status` | The account approval status. If not provided, the status is set to `1` by default and developers are automatically placed in the **Requested Access** queue.

      Accepts one of the following integers:
      • `0` - Approved
      • `1` - Requested access
      • `2` - Rejected
      • `3` - Revoked + +Example request: + +```sh +http POST :8001/developers \ + email=example@example.com \ + meta="{\"full_name\":\"Wally\"}" \ + password=mypass \ + id=62d17e63-0628-43a3-b936-97b8dcbd366f +``` + +**Response** + +``` +HTTP/1.1 200 OK +``` + +```json +{ + "consumer": { + "id": "62d17e63-0628-43a3-b936-97b8dcbd366f" + }, + "created_at": 1644616521, + "email": "example@example.com", + "id": "a82f9477-1a24-45b9-827c-23f1c1a7ebb3", + "meta": "{\"full_name\":\"Wally\"}", + "status": 0, + "updated_at": 1644616521 +} +``` + +### Invite developers + +Send invitations to a list of emails. +[SMTP](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/smtp/) must +be enabled to send invite emails. + +**Endpoint** + +
      /developers/invite
      + +**Request body** + +Attribute | Description +---------: | -------- +`emails` | A comma-separated array of emails. + +Example request: +```sh +http POST :8001/developers/invite emails:='["example@example.com", "example2@example.com"]' +``` + +**Response** + +``` +HTTP/1.1 200 OK +``` + +```json +{ + "error": { + "count": 0, + "emails": {} + }, + "sent": { + "count": 2, + "emails": { + "example@example.com": true, + "example2@example.com": true + } + }, + "smtp_mock": true +} +``` + +### Inspect a developer + +Retrieve metadata for a specific developer account. + +**Endpoint** + +
      /developers/{DEVELOPER_EMAIL|DEVELOPER_ID}
      + + +Attribute | Description +---------: | -------- +`{DEVELOPER_EMAIL|DEVELOPER_ID}` | The email or UUID of the developer you want to inspect. + + +**Response** + +``` +HTTP/1.1 200 OK +``` + +```json +{ + "consumer": { + "id": "855fe098-3bb3-4041-8a3d-149a9e5462c6" + }, + "created_at": 1644617754, + "email": "example@example.com", + "id": "f94e4fbd-c30b-41d7-b349-13c8f4fc23ca", + "rbac_user": { + "id": "7d40540b-4b65-4fa6-b04e-ffe6c2c40b0d" + }, + "roles": [ + "QA" + ], + "status": 0, + "updated_at": 1644619493 +} +``` + +### Update a developer + +Update the configuration or status for a specific developer account. + +**Endpoint** + +
      /developers/{DEVELOPER_EMAIL|DEVELOPER_ID}
      + +Attribute | Description +---------: | -------- +`{DEVELOPER_EMAIL|DEVELOPER_ID}` | The email or UUID of the developer you want to update. + + +**Request Body** + +Attribute | Description +---------: | -------- +`meta` | Metadata for the account in JSON format. Accepts fields defined in the Dev Portal settings.

      By default, the meta attribute requires a `full_name` field. You can remove this requirement, or add other fields as neccessary.

      For example: `meta: {"full_name":""}`. +`email` | The email of the developer to create. This becomes their login username. +`status` | The account approval status.

      Accepts one of the following integers:
      • `0` - Approved
      • `1` - Requested access
      • `2` - Rejected
      • `3` - Revoked + + +**Response** + +``` +HTTP/1.1 200 OK +``` + +```json +{ + "developer": { + "consumer": { + "id": "855fe098-3bb3-4041-8a3d-149a9e5462c6" + }, + "created_at": 1644617754, + "email": "example@example.com", + "id": "f94e4fbd-c30b-41d7-b349-13c8f4fc23ca", + "rbac_user": { + "id": "7d40540b-4b65-4fa6-b04e-ffe6c2c40b0d" + }, + "roles": [ + "QA" + ], + "status": 0, + "updated_at": 1644621148 + } +} +``` + +### Delete a developer + +Delete a specific developer account. + +**Endpoint** + +
      /developers/{DEVELOPER_ID}
      + +Attribute | Description +---------: | -------- +`{DEVELOPER_ID}` | The UUID of the developer you want to delete. + +**Response** + +``` +HTTP/1.1 204 No Content +``` + +## Export developer metadata + +Prints a list of developers in CSV format. + +
      /developers/export
      + +**Response** + +``` +HTTP/1.1 200 OK +``` + +```csv +Email, Status +test@example.com,APPROVED +test1@example.com,PENDING +test2@example.com,REVOKED +test3@example.com,REJECTED +``` + +## Roles + +### List all Dev Portal roles + +List all RBAC roles configured for the Dev Portal. + +By default, there are no roles. All Dev Portal roles are custom. + +**Endpoint** + +
      /developers/roles
      + +**Response** + +``` +HTTP/1.1 200 OK +``` + +```json +{ + "data": [ + { + "created_at": 1644615388, + "id": "525694de-776c-43ad-a940-769295d0c54e", + "name": "Application Developer" + }, + { + "created_at": 1644619493, + "id": "c8535760-e37f-4578-921f-04e781a3f8f1", + "name": "QA" + } + ], + "next": null, + "total": 2 +} +``` + +### Create a Dev Portal role + +Create an RBAC role for grouping developers. + +When you create a role, by default, the role has no specific permissions and +has access to all content in the Dev Portal. Use the **Dev Portal** > +**Permissions** page in Kong Manager +(`//portal/permissions/#roles`) to specify +permissions for the role. + +**Endpoint** + +
      /developers/roles
      + +**Request body** + +Attribute | Description +---------: | -------- +`name`
      *required* | A name for the role. +`comment` | A description of the role. + +**Response** + +``` +HTTP/1.1 201 Created +``` + +```json +{ + "comment": "Billing services team", + "created_at": 1644620475, + "id": "b7794758-394e-46f1-a9a1-f495f2e97a68", + "name": "Billing", + "permissions": {} +} +``` + +### Inspect a role + +Inspect a specific Dev Portal RBAC role. + +**Endpoint** + +
      /developers/roles/{ROLE_NAME|ROLE_ID}
      + +Attribute | Description +---------: | -------- +`{ROLE_NAME|ROLE_ID}`
      *required* | The name or UUID of the role you are inspecting. + +**Response** + +``` +HTTP/1.1 200 OK +``` + +```json +{ + "comment": "Billing services team", + "created_at": 1644620475, + "id": "b7794758-394e-46f1-a9a1-f495f2e97a68", + "name": "Billing", + "permissions": {} +} +``` + + +### Update a role + +Update a specific Dev Portal RBAC role. + +**Endpoint** + +
      /developers/roles/{ROLE_NAME|ROLE_ID}
      + +Attribute | Description +---------: | -------- +`{ROLE_NAME|ROLE_ID}`
      *required* | The name or UUID of the role you are inspecting. + +**Request body** + +Attribute | Description +---------: | -------- +`name` | A name for the role. +`comment` | A description of the role. + +**Response** + +``` +HTTP/1.1 200 OK +``` + +```json +{ + "comment": "Billing services team", + "created_at": 1644620475, + "id": "b7794758-394e-46f1-a9a1-f495f2e97a68", + "name": "Billing", + "permissions": {} +} +``` + + + +### Delete a role + +Delete a specific Dev Portal RBAC role. + +**Endpoint** + +
      /developers/roles/{ROLE_NAME|ROLE_ID}
      + +Attribute | Description +---------: | -------- +`{ROLE_NAME|ROLE_ID}`
      *required* | The name or UUID of the role you are inspecting. + +**Response** + +``` +HTTP/1.1 204 No Content +``` + + +## Applications + +Applications consume Services in {{site.base_gateway}} via application-level +authentication. Developers, or the persona that logs into the Dev Portal, +create and manage applications through the Dev Portal. + +Admins must first [enable application registration](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/applications/enable-application-registration) through so that Developers can associate Services with applications. + +### List all applications for a developer + +**Endpoint** + +
      /developers/{DEVELOPER_EMAIL|DEVELOPER_ID}/applications
      + +Attribute | Description +---------: | -------- +`{DEVELOPER_EMAIL|DEVELOPER_ID}` | The email or UUID of a developer. + + +**Response** +``` +HTTP/1.1 200 OK +``` + +```json +{ + "data": [ + { + "consumer": { + "id": "6e31bf1e-dbcb-4a31-bac9-a192fa24f088" + }, + "created_at": 1644963627, + "developer": { + "id": "5f60930a-ad12-4303-ac5a-59d121ad4942" + }, + "id": "5ff48aaf-3951-4c99-a636-3b682081705c", + "name": "example_app", + "redirect_uri": "http://mockbin.org", + "updated_at": 1644963627 + }, + { + "consumer": { + "id": "2390fd02-bbcd-48f1-b32f-89c262fa68a8" + }, + "created_at": 1644963657, + "developer": { + "id": "5f60930a-ad12-4303-ac5a-59d121ad4942" + }, + "id": "94e0f633-e8fd-4647-a0cd-4c3015ff2722", + "name": "example_app2", + "redirect_uri": "http://mockbin.org", + "updated_at": 1644963657 + } + ], + "next": null, + "total": 2 +} + +``` + +### Inspect an application + +Inspect a specific application using the application ID. + +**Endpoint** + +
      /developers/{DEVELOPER_EMAIL|DEVELOPER_ID}/applications/{APPLICATION_ID}
      + +Attribute | Description +---------: | -------- +`{DEVELOPER_EMAIL|DEVELOPER_ID}` | The email or UUID of a developer. +`{APPLICATION_ID}` | The application UUID. + +**Response** +``` +HTTP/1.1 200 OK +``` + +```json +{ + "consumer": { + "id": "d5ea9628-f359-4b96-9f76-61562aaf4300" + }, + "created_at": 1644965555, + "custom_id": "billing", + "developer": { + "id": "5f60930a-ad12-4303-ac5a-59d121ad4942" + }, + "id": "ca0d62bd-4616-4b87-b947-43e33e5418f0", + "name": "testapp", + "redirect_uri": "http://mockbin.org", + "updated_at": 1644965555 +} +``` + + +### Create an application + +Create a new application for a specific developer. + +**Endpoint** + +
      /developers/{DEVELOPER_EMAIL|DEVELOPER_ID}/applications
      + + +Attribute | Description +---------: | -------- +`{DEVELOPER_EMAIL|DEVELOPER_ID}` | The email or UUID of a developer. + +**Request body** + +Attribute | Description +---------: | -------- +`name`
      *required* | A name for the application. +`redirect_uri`
      *required* | The application's URI. +`custom_id` | A custom name for the application. The `custom_id` is saved to the linked consumer entity for the application. This can be used for OIDC claim mapping when configuring the application's `openid-connect` authentication plugin. + +**Response** + +``` +HTTP/1.1 201 Created +``` + +```json +{ + "consumer": { + "id": "d5ea9628-f359-4b96-9f76-61562aaf4300" + }, + "created_at": 1644965555, + "custom_id": "billing-app", + "developer": { + "id": "5f60930a-ad12-4303-ac5a-59d121ad4942" + }, + "id": "ca0d62bd-4616-4b87-b947-43e33e5418f0", + "name": "testapp", + "redirect_uri": "http://mockbin.org", + "updated_at": 1644965555 +} +``` + + +### Update an application + +Update a specific application using the application ID. + +**Endpoint** + +
      /developers/{DEVELOPER_EMAIL|DEVELOPER_ID}/applications/{APPLICATION_ID}
      + + +Attribute | Description +---------: | -------- +`{DEVELOPER_EMAIL|DEVELOPER_ID}` | The email or UUID of a developer. +`{APPLICATION_ID}` | The application UUID. + +**Request body** + +Attribute | Description +---------: | -------- +`name` | A name for the application. +`redirect_uri` | The application's URI. +`custom_id` | A custom identifier for the application. + +**Response** + +``` +HTTP/1.1 200 OK +``` + +```json +{ + "consumer": { + "id": "6e31bf1e-dbcb-4a31-bac9-a192fa24f088" + }, + "created_at": 1644963627, + "developer": { + "id": "5f60930a-ad12-4303-ac5a-59d121ad4942" + }, + "id": "5ff48aaf-3951-4c99-a636-3b682081705c", + "name": "ExampleApp", + "redirect_uri": "http://mockbin.org", + "updated_at": 1645575611 +} +``` + +### Delete an application + +Delete a specific application using the application ID. + +**Endpoint** +
      /developers/{DEVELOPER_EMAIL|DEVELOPER_ID}/applications/{APPLICATION_ID}
      + +Attribute | Description +---------: | -------- +`{DEVELOPER_EMAIL|DEVELOPER_ID}` | The email or UUID of a developer. +`{APPLICATION_ID}` | The application UUID. + +**Response** + +``` +HTTP/1.1 204 No Content +``` + +### View all instances of an application + +View all application instances that are connected to a Service in the Kong Gateway. + + +**Endpoint** + +
      /developers/{DEVELOPER_EMAIL|DEVELOPER_ID}/applications/{APPLICATION_ID}/application_instances
      + +Attribute | Description +---------: | -------- +`{DEVELOPER_EMAIL|DEVELOPER_ID}` | The email or UUID of a developer. +`{APPLICATION_ID}` | The application UUID. + +**Response** +``` +HTTP/1.1 200 OK +``` + +```json +{ + "data": [ + { + "application": { + "consumer": { + "id": "a4e8f835-e5bb-498c-8b6a-73a21c82776d" + }, + "created_at": 1644965487, + "developer": { + "consumer": { + "id": "9dbd764c-9548-4c9f-a4d1-6ea11e32a803" + }, + "created_at": 1644615583, + "email": "example@example.com", + "id": "5f60930a-ad12-4303-ac5a-59d121ad4942", + "meta": "{\"full_name\":\"Wally\"}", + "rbac_user": { + "id": "431cae60-5d60-40be-8636-1b349a70a88d" + }, + "status": 0, + "updated_at": 1644615874 + }, + "id": "645682ae-0be6-420a-bcf3-0e711a391546", + "name": "testapp", + "redirect_uri": "http://mockbin.org", + "updated_at": 1644965487 + }, + "composite_id": "645682ae-0be6-420a-bcf3-0e711a391546_212a758a-810b-4226-9175-b1b44eecebec", + "created_at": 1644968368, + "id": "13fdfd32-8412-4479-b04f-a83d155e5de5", + "service": { + "id": "212a758a-810b-4226-9175-b1b44eecebec" + }, + "status": 0, + "suspended": false, + "updated_at": 1644968411 + } + ], + "next": null, + "total": 1 +} + +``` + +### Create an application instance + +Connect an application to a Service in the Kong Gateway. + +**Endpoint** + +
      /developers/{DEVELOPER_EMAIL|DEVELOPER_ID}/applications/{APPLICATION_ID}/application_instances
      + +Attribute | Description +---------: | -------- +`{DEVELOPER_EMAIL|DEVELOPER_ID}` | The email or UUID of a developer. +`{APPLICATION_ID}` | The application UUID. + +**Request body** + +Attribute | Description +---------: | -------- +`service.id` | The UUID of the Service to connect the application to. + +**Response** + +``` +HTTP/1.1 201 Created +``` + +```json +{ + "application": { + "id": "5ff48aaf-3951-4c99-a636-3b682081705c" + }, + "composite_id": "5ff48aaf-3951-4c99-a636-3b682081705c_212a758a-810b-4226-9175-b1b44eecebec", + "created_at": 1645570372, + "id": "50193ee0-372a-4694-874c-90ffbc0ae522", + "service": { + "id": "212a758a-810b-4226-9175-b1b44eecebec" + }, + "status": 1, + "suspended": false, + "updated_at": 1645570372 +} +``` + +### Inspect an application instance + +Get information about a specific instance of an application. + +**Endpoint** + +
      /developers/{DEVELOPER_EMAIL|DEVELOPER_ID}/applications/{APPLICATION_ID}/application_instances/{APPLICATION_INSTANCE_ID}
      + +Attribute | Description +---------: | -------- +`{DEVELOPER_EMAIL|DEVELOPER_ID}` | The email or UUID of a developer. +`{APPLICATION_ID}` | The application UUID. +`{APPLICATION_INSTANCE_ID}` | The application instance UUID. + +**Response** + +``` +HTTP/1.1 200 OK +``` + +```json +{ + "application": { + "id": "645682ae-0be6-420a-bcf3-0e711a391546" + }, + "composite_id": "645682ae-0be6-420a-bcf3-0e711a391546_212a758a-810b-4226-9175-b1b44eecebec", + "created_at": 1644968368, + "id": "13fdfd32-8412-4479-b04f-a83d155e5de5", + "service": { + "id": "212a758a-810b-4226-9175-b1b44eecebec" + }, + "status": 0, + "suspended": false, + "updated_at": 1644968411 +} +``` + + +### Update an application instance + +Update a specific instance of an application. + +**Endpoint** + +
      /developers/{DEVELOPER_EMAIL|DEVELOPER_ID}/applications/{APPLICATION_ID}/application_instances/{APPLICATION_INSTANCE_ID}
      + +Attribute | Description +---------: | -------- +`{DEVELOPER_EMAIL|DEVELOPER_ID}` | The email or UUID of a developer. +`{APPLICATION_ID}` | The application UUID. +`{APPLICATION_INSTANCE_ID}` | The application instance UUID. + +**Request body** + +Attribute | Description +---------: | -------- +`service.id` | The UUID of the Service to connect the application to. + +**Response** + +``` +HTTP/1.1 201 OK +``` + +```json +{ + "application": { + "id": "645682ae-0be6-420a-bcf3-0e711a391546" + }, + "composite_id": "645682ae-0be6-420a-bcf3-0e711a391546_212a758a-810b-4226-9175-b1b44eecebec", + "created_at": 1644968368, + "id": "13fdfd32-8412-4479-b04f-a83d155e5de5", + "service": { + "id": "212a758a-810b-4226-9175-b1b44eecebec" + }, + "status": 0, + "suspended": false, + "updated_at": 1644968411 +} +``` + + +### Delete an application instance + +Disconnect an application from a Service. + +**Endpoint** + +
      /developers/{DEVELOPER_EMAIL|DEVELOPER_ID}/applications/{APPLICATION_ID}/application_instances/{APPLICATION_INSTANCE_ID}
      + +Attribute | Description +---------: | -------- +`{DEVELOPER_EMAIL|DEVELOPER_ID}` | The email or UUID of a developer. +`{APPLICATION_ID}` | The application UUID. +`{APPLICATION_INSTANCE_ID}` | The application instance UUID. + +**Response** + +``` +HTTP/1.1 204 No Content +``` + +## Plugins + +### List all plugins + +List all plugins for a developer. + +**Endpoint** + +
      /developers/{DEVELOPER_EMAIL|DEVELOPER_ID}/plugins
      + +Attribute | Description +---------: | -------- +`{DEVELOPER_EMAIL|DEVELOPER_ID}` | The email or UUID of a developer. + +**Response** + +``` +HTTP/1.1 200 OK +``` + +The exact response depends on the plugins that this developer has configured. +For example, if there is a `proxy-cache` plugin enabled: + +```json +{ + "config": { + "cache_control": false, + "cache_ttl": 300, + "content_type": [ + "text/plain", + "application/json" + ], + "memory": { + "dictionary_name": "kong_db_cache" + }, + "request_method": [ + "GET", + "HEAD" + ], + "response_code": [ + 200, + 301, + 404 + ], + "strategy": "memory" + }, + "consumer": { + "id": "bc504999-b3e5-4b08-8544-86962c969335" + }, + "created_at": 1645564279, + "enabled": true, + "id": "d5f70fe4-58e6-4153-8569-07a1f901e751", + "name": "proxy-cache", + "protocols": [ + "grpc", + "grpcs", + "http", + "https" + ] +} +``` + +### Apply a plugin + +Configure a plugin and apply it to a developer. + +**Endpoint** + +
      /developers/{DEVELOPER_EMAIL|DEVELOPER_ID}/plugins
      + +Attribute | Description +---------: | -------- +`{DEVELOPER_EMAIL|DEVELOPER_ID}` | The email or UUID of a developer. + + +**Request body** + +Attribute | Description +---------: | -------- +`name`
      *required* | The name of a plugin to enable. You can use any plugin that can be enabled on a Consumer. +Plugin configuration fields | Any configuration parameters for the plugin that you are enabling. See the plugin's reference on the [Plugin Hub](/hub/) to find the parameters for a specific plugin. + +Example request: + +```sh +http POST :8001/developers/example@example.com/plugins \ + name=proxy-cache \ + config.strategy=memory +``` + +**Response** + +``` +HTTP/1.1 201 Created +``` + +The exact response depends on the plugin. For example, for `proxy-cache`: + +```json +{ + "config": { + "cache_control": false, + "cache_ttl": 300, + "content_type": [ + "text/plain", + "application/json" + ], + "memory": { + "dictionary_name": "kong_db_cache" + }, + "request_method": [ + "GET", + "HEAD" + ], + "response_code": [ + 200, + 301, + 404 + ], + "strategy": "memory" + }, + "consumer": { + "id": "bc504999-b3e5-4b08-8544-86962c969335" + }, + "created_at": 1645564279, + "enabled": true, + "id": "d5f70fe4-58e6-4153-8569-07a1f901e751", + "name": "proxy-cache", + "protocols": [ + "grpc", + "grpcs", + "http", + "https" + ] +} +``` + +### Inspect a developer plugin + +Inspect a plugin that is applied to a developer. + +**Endpoint** + +
      /developers/{DEVELOPER_EMAIL|DEVELOPER_ID}/plugins/{PLUGIN_ID}
      + +Attribute | Description +---------: | -------- +`{DEVELOPER_EMAIL|DEVELOPER_ID}` | The email or UUID of a developer. +`{PLUGIN_ID}` | The UUID of the plugin to inspect. + +**Response** +``` +HTTP/1.1 200 OK +``` + +The exact response depends on the plugin. For example, for `proxy-cache`: + +```json +{ + "config": { + "cache_control": false, + "cache_ttl": 300, + "content_type": [ + "text/plain", + "application/json" + ], + "memory": { + "dictionary_name": "kong_db_cache" + }, + "request_method": [ + "GET", + "HEAD" + ], + "response_code": [ + 200, + 301, + 404 + ], + "strategy": "memory" + }, + "consumer": { + "id": "bc504999-b3e5-4b08-8544-86962c969335" + }, + "created_at": 1645564279, + "enabled": true, + "id": "d5f70fe4-58e6-4153-8569-07a1f901e751", + "name": "proxy-cache", + "protocols": [ + "grpc", + "grpcs", + "http", + "https" + ] +} +``` + +### Update a developer plugin + +Edit a plugin that is applied to a developer. + +**Endpoint** + +
      /developers/{DEVELOPER_EMAIL|DEVELOPER_ID}/plugins/{PLUGIN_ID}
      + +Attribute | Description +---------: | -------- +`{DEVELOPER_EMAIL|DEVELOPER_ID}` | The email or UUID of a developer. +`{PLUGIN_ID}` | The UUID of the plugin to update. + +**Request body** + +Attribute | Description +---------: | -------- +Plugin configuration fields | Any configuration parameters for the plugin that you are editing. See the plugin's reference on the [Plugin Hub](/hub/) to find the parameters for a specific plugin. + + +Example request to update an instance of the `proxy-cache` plugin: + +```sh +http PATCH :8001/developers/91a1fb59-d90f-4f07-b609-4c2a1e3d847e/plugins/d5f70fe4-58e6-4153-8569-07a1f901e751 \ + config.response_code:='[200, 301, 400, 404]' +``` + +**Response** + +``` +HTTP/1.1 200 OK +``` + +The exact response depends on the plugin. For example, if you change accepted +response codes for `proxy-cache` to add `400`: + +```json +{ + "config": { + "cache_control": false, + "cache_ttl": 300, + "content_type": [ + "text/plain", + "application/json" + ], + "memory": { + "dictionary_name": "kong_db_cache" + }, + "request_method": [ + "GET", + "HEAD" + ], + "response_code": [ + 200, + 301, + 400, + 404 + ], + "strategy": "memory" + }, + "consumer": { + "id": "bc504999-b3e5-4b08-8544-86962c969335" + }, + "created_at": 1645564279, + "enabled": true, + "id": "d5f70fe4-58e6-4153-8569-07a1f901e751", + "name": "proxy-cache", + "protocols": [ + "grpc", + "grpcs", + "http", + "https" + ] +} +``` + + +### Delete a developer plugin + +Remove an authentication plugin from a developer. + +**Endpoint** + +
      /developers/{DEVELOPER_EMAIL|DEVELOPER_ID}/plugins/{PLUGIN_ID}
      + +Attribute | Description +---------: | -------- +`{DEVELOPER_EMAIL|DEVELOPER_ID}` | The email or UUID of a developer. +`{PLUGIN_ID}` | The UUID of the plugin to delete. + +**Response** + +``` +HTTP/1.1 204 No Content +``` + +## Developer authentication + +Developers can authenticate to the Dev Portal using one of the following +authentication methods: +* [`basic-auth`](/hub/kong-inc/basic-auth/) +* [`oauth2`](/hub/kong-inc/oauth2/) +* [`hmac-auth`](/hub/kong-inc/hmac-auth/) +* [`jwt`](/hub/kong-inc/jwt/) +* [`key-auth`](/hub/kong-inc/key-auth/) +* [`openid-connect`](/hub/kong-inc/openid-connect/) + +Each of these methods configures an instance of the related {{site.base_gateway}} +authentication plugin. + +For a developer to be able to manage applications, the Dev Portal must use some +kind of authentication, and each developer must be granted access to the Dev Portal. +If authentication is disabled and the Dev Portal URL is public, application +registration is not available. + +### Get all credentials + +Get a list of all configured Dev Portal credentials for a specific type of +authentication plugin. + +**Endpoint** + +
      /developers/{DEVELOPER_EMAIL|DEVELOPER_ID}/credentials/{PLUGIN_NAME}
      + +Attribute | Description +---------: | -------- +`{DEVELOPER_EMAIL|DEVELOPER_ID}` | The email or UUID of a developer. +`{PLUGIN_NAME}` | The name of a supported authentication plugin. Can be one of:
      • `basic-auth`
      • `oauth2`
      • `hmac-auth`
      • `jwt`
      • `key-auth`
      • `openid-connect` + +**Response** +``` +HTTP/1.1 200 OK +``` + +The exact response depends on the plugin. For example, if you have two `key-auth` +credentials: + +```json +{ + "data": [ + { + "consumer": { + "id": "bc504999-b3e5-4b08-8544-86962c969335" + }, + "created_at": 1645566606, + "id": "1a86d7eb-53ce-4a29-b573-a545e602fc05", + "key": "testing" + }, + { + "consumer": { + "id": "bc504999-b3e5-4b08-8544-86962c969335" + }, + "created_at": 1645567499, + "id": "1b0ba8f4-dd9f-4f68-8108-c81952e05b8e", + "key": "wpJqvsTFRjgQstL16pQTYKtlHfkzdJpb" + } + ], + "next": null, + "total": 2 +} +``` + +### Create a credential + +Create a Dev Portal credential. The credentials you can create depend on the +type of authentication currently enabled for your Dev Portal. + +**Endpoint** + +
      /developers/{DEVELOPER_EMAIL|DEVELOPER_ID}/credentials/{PLUGIN_NAME}
      + +Attribute | Description +---------: | -------- +`{DEVELOPER_EMAIL|DEVELOPER_ID}` | The email or UUID of a developer. +`{PLUGIN_NAME}` | The name of a supported authentication plugin. Can be one of:
      • `basic-auth`
      • `oauth2`
      • `hmac-auth`
      • `jwt`
      • `key-auth`
      • `openid-connect` + +**Request body** + +Attribute | Description +---------: | -------- +Plugin configuration fields | Any authentication credentials for the plugin that you are configuring. See the plugin's reference documentation to find the parameters for a specific plugin:
      • [`basic-auth`](/hub/kong-inc/basic-auth/)
      • [`oauth2`](/hub/kong-inc/oauth2/)
      • [`hmac-auth`](/hub/kong-inc/hmac-auth/)
      • [`jwt`](/hub/kong-inc/jwt/)
      • [`key-auth`](/hub/kong-inc/key-auth/)
      • [`openid-connect`](/hub/kong-inc/openid-connect/) + + +Example request for creating a `key-auth` credential: +```sh +http POST :8001/developers/91a1fb59-d90f-4f07-b609-4c2a1e3d847e/credentials/key-auth +``` + +**Response** +``` +HTTP/1.1 201 Created +``` + +The exact response depends on the plugin. For example, if you add a `key-auth` +credential: + +```json +{ + "consumer": { + "id": "bc504999-b3e5-4b08-8544-86962c969335" + }, + "created_at": 1645567499, + "id": "1b0ba8f4-dd9f-4f68-8108-c81952e05b8e", + "key": "wpJqvsTFRjgQstL16pQTYKtlHfkzdJpb" +} + +``` + +### Inspect a credential + +Retrieve information about a specific Dev Portal credential using its ID. + +**Endpoint** + +
      /developers/{DEVELOPER_EMAIL|DEVELOPER_ID}/credentials/{PLUGIN_NAME}/{CREDENTIAL_ID}
      + +Attribute | Description +---------: | -------- +`{DEVELOPER_EMAIL|DEVELOPER_ID}` | The email or UUID of a developer. +`{PLUGIN_NAME}` | The name of a supported authentication plugin. Can be one of:
      • `basic-auth`
      • `oauth2`
      • `hmac-auth`
      • `jwt`
      • `key-auth`
      • `openid-connect` +`{CREDENTIAL_ID}` | The UUID of a credential for the plugin. + +**Response** +``` +HTTP/1.1 200 OK +``` + +The exact response depends on the plugin. For example, if you inspect a `key-auth` +credential: + +```json +{ + "consumer": { + "id": "bc504999-b3e5-4b08-8544-86962c969335" + }, + "created_at": 1645567499, + "id": "1b0ba8f4-dd9f-4f68-8108-c81952e05b8e", + "key": "wpJqvsTFRjgQstL16pQTYKtlHfkzdJpb" +} +``` + +### Update a credential + +Update a specific Dev Portal credential. + +**Endpoint** + +
      /developers/{DEVELOPER_EMAIL|DEVELOPER_ID}/credentials/{PLUGIN_NAME}/{CREDENTIAL_ID}
      + +Attribute | Description +---------: | -------- +`{DEVELOPER_EMAIL|DEVELOPER_ID}` | The email or UUID of a developer. +`{PLUGIN_NAME}` | The name of a supported authentication plugin. Can be one of: Can be one of:
      • `basic-auth`
      • `oauth2`
      • `hmac-auth`
      • `jwt`
      • `key-auth`
      • `openid-connect` +`{CREDENTIAL_ID}` | The UUID of a credential for the plugin. + +**Request body** + +Attribute | Description +---------: | -------- +Plugin configuration fields | Any authentication credentials for the plugin that you are configuring. See the plugin's reference documentation to find the parameters for a specific plugin:
      • [`basic-auth`](/hub/kong-inc/basic-auth/)
      • [`oauth2`](/hub/kong-inc/oauth2/)
      • [`hmac-auth`](/hub/kong-inc/hmac-auth/)
      • [`jwt`](/hub/kong-inc/jwt/)
      • [`key-auth`](/hub/kong-inc/key-auth/)
      • [`openid-connect`](/hub/kong-inc/openid-connect/) + +Example request to update a `key-auth` key: +``` +http PATCH :8001/developers/91a1fb59-d90f-4f07-b609-4c2a1e3d847e/credentials/key-auth/1b0ba8f4-dd9f-4f68-8108-c81952e05b8e \ + key=apikey +``` + +**Response** +``` +HTTP/1.1 200 OK +``` + +The exact response depends on the plugin. For example, if you update a `key-auth` +credential to use a custom key instead of a UUID: + +```json +{ + "consumer": { + "id": "bc504999-b3e5-4b08-8544-86962c969335" + }, + "created_at": 1645567499, + "id": "1b0ba8f4-dd9f-4f68-8108-c81952e05b8e", + "key": "apikey" +} +``` + +### Delete a credential + +**Endpoint** + +
      /developers/{DEVELOPER_EMAIL|DEVELOPER_ID}/credentials/{PLUGIN_NAME}/{CREDENTIAL_ID}
      + +Attribute | Description +---------: | -------- +`{DEVELOPER_EMAIL|DEVELOPER_ID}` | The email or UUID of a developer. +`{PLUGIN_NAME}` | The name of a supported authentication plugin. Can be one of:
      • `basic-auth`
      • `oauth2`
      • `hmac-auth`
      • `jwt`
      • `key-auth`
      • `openid-connect` +`{CREDENTIAL_ID}` | The UUID of a credential for the plugin. + +**Response** +``` +HTTP/1.1 204 No Content +``` + +## Application authentication + +When application registration is enabled, it requires an +[authentication strategy](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/applications/auth-provider-strategy). +By default, this strategy is `kong-oauth2`, and it is set in `kong.conf`: + +``` +portal_app_auth = kong-oauth2 +``` + +If you use the default strategy, you can configure authentication for applications +using the following APIs. If using the `external-oauth2` strategy, +[manage it through your IdP](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/applications/auth-provider-strategy). + +### Inspect all credentials for an application + +Get a list of all application credentials for a specific type of authentication +plugin. + +**Endpoint** + +
      /developers/{DEVELOPER_EMAIL|DEVELOPER_ID}/applications/{APPLICATION_ID}/credentials/oauth2
      + +Attribute | Description +---------: | -------- +`{DEVELOPER_EMAIL|DEVELOPER_ID}` | The email or UUID of a developer. +`{APPLICATION_ID}` | The application UUID. + +**Response** +``` +HTTP/1.1 200 OK +``` + +```json +{ + "data": [ + { + "client_id": "3psqvdiojUKoJudqCh1U5P5mvR9k3zFF", + "client_secret": "HUbYpUw8sNrEZGqyCs19HmRo08l9shC0", + "client_type": "confidential", + "consumer": { + "id": "6e31bf1e-dbcb-4a31-bac9-a192fa24f088" + }, + "created_at": 1644963627, + "hash_secret": false, + "id": "e22760bc-c6d4-4572-9814-132825286618", + "name": "example_app", + "redirect_uris": [ + "http://mockbin.org" + ] + } + ], + "next": null, + "total": 1 +} +``` + +### Create a credential for an application + +Create an OAuth2 authentication credential for an application. +This request configures an instance of the [OAuth2 plugin](/hub/kong-inc/oauth2). + +**Endpoint** + +
      /developers/{DEVELOPER_EMAIL|DEVELOPER_ID}/applications/{APPLICATION_ID}/credentials/oauth2
      + +Attribute | Description +---------: | -------- +`{DEVELOPER_EMAIL|DEVELOPER_ID}` | The email or UUID of a developer. +`{APPLICATION_ID}` | The application UUID. + +**Request body** + +Attribute | Description +---------: | -------- +`client_id` | You can optionally set your own unique client_id. If not provided, the plugin will generate one. +`client_secret` | You can optionally set your own unique client_secret. If not provided, the plugin will generate one. +`redirect_uris` | An array with one or more URLs in your app where users will be sent after authorization ([RFC 6742 Section 3.1.2](https://tools.ietf.org/html/rfc6749#section-3.1.2)). +`hash_secret` | A boolean flag that indicates whether the `client_secret` field will be stored in hashed form. If enabled on existing plugin instances, client secrets are hashed on the fly upon first usage.
      Default: `false` + +Example request for creating an `oauth2` credential: + +```sh +http POST :8001/developers/5f60930a-ad12-4303-ac5a-59d121ad4942/applications/5ff48aaf-3951-4c99-a636-3b682081705c/credentials/oauth2 client_id=myclient client_secret=mysecret +``` + +**Response** +``` +HTTP/1.1 201 Created +``` + +```json +{ + "client_id": "t2vTlxxV1ANi9jFq2U1rlR1yp03Mi6uf", + "client_secret": "EdKxXDD97LSe45lG5G5f6CBn5G9gXcp4", + "client_type": "confidential", + "consumer": { + "id": "6e31bf1e-dbcb-4a31-bac9-a192fa24f088" + }, + "created_at": 1645569439, + "hash_secret": false, + "id": "2dc8ee2a-ecfd-4ca5-a9c1-db371480e2cf", + "name": "example_app", + "redirect_uris": [ + "http://mockbin.org" + ] +} +``` + + +### Inspect a credential for an application + +Inspect an OAuth2 authentication credential of an application. + +**Endpoint** + +
      /developers/{DEVELOPER_EMAIL|DEVELOPER_ID}/applications/{APPLICATION_ID}/credentials/oauth2/{CREDENTIAL_ID}
      + +Attribute | Description +---------: | -------- +`{DEVELOPER_EMAIL|DEVELOPER_ID}` | The email or UUID of a developer. +`{APPLICATION_ID}` | The application UUID. +`{CREDENTIAL_ID}` | The UUID of a credential. + +**Response** +``` +HTTP/1.1 200 OK +``` + +```json +{ + "client_id": "3psqvdiojUKoJudqCh1U5P5mvR9k3zFF", + "client_secret": "HUbYpUw8sNrEZGqyCs19HmRo08l9shC0", + "client_type": "confidential", + "consumer": { + "id": "6e31bf1e-dbcb-4a31-bac9-a192fa24f088" + }, + "created_at": 1644963627, + "hash_secret": false, + "id": "e22760bc-c6d4-4572-9814-132825286618", + "name": "example_app", + "redirect_uris": [ + "http://mockbin.org" + ] +} +``` + +### Delete a credential from an application + +Delete an OAuth2 authentication credential of an application. + +**Endpoint** + +
      /developers/{DEVELOPER_EMAIL|DEVELOPER_ID}/applications/{APPLICATION_ID}/credentials/oauth2/{CREDENTIAL_ID}
      + +Attribute | Description +---------: | -------- +`{DEVELOPER_EMAIL|DEVELOPER_ID}` | The email or UUID of a developer. +`{CREDENTIAL_ID}` | The UUID of a credential for the plugin. + +**Response** +``` +HTTP/1.1 204 No Content +``` diff --git a/src/gateway/admin-api/event-hooks/reference.md b/src/gateway/admin-api/event-hooks/reference.md new file mode 100644 index 000000000000..570d3ab37dcc --- /dev/null +++ b/src/gateway/admin-api/event-hooks/reference.md @@ -0,0 +1,427 @@ +--- +title: Event Hooks Reference +badge: enterprise +--- + +{:.important} +> **Important:** Before you can use event hooks for the first time, Kong needs to be +reloaded. + +{% include_cached /md/enterprise/event-hooks-intro.md %} + +{:.note} +> **Note:** Event hooks do not work with Konnect Cloud yet. + +## List all event hooks + +**Endpoint** + +
      /event-hooks
      + +**Response** + +```json +{ + "data": [ + { + "config": { + "body": null, + "body_format": true, + "headers": { + "content-type": "application/json" + }, + "headers_format": false, + "method": "POST", + "payload": { + "text": "{% raw %}Admin account \`{{ entity.username }}\` {{ operation}}d; email address set to \`{{ entity.email }}\`{% endraw %}" + }, + "payload_format": true, + "secret": null, + "ssl_verify": false, + "url": "https://hooks.slack.com/services/foo/bar/baz" + }, + "created_at": 1627588552, + "event": "admins", + "handler": "webhook-custom", + "id": "937df175-3db2-4e6d-8aa1-d95c94a76089", + "on_change": null, + "snooze": null, + "source": "crud" + }, + { + "config": { + "headers": {}, + "secret": null, + "ssl_verify": false, + "url": "https://webhook.site/a1b2c3-d4e5-g6h7-i8j9-k1l2m3n4o5p6" + }, + "created_at": 1627581575, + "event": "consumers", + "handler": "webhook", + "id": "c57340ab-9fed-40fd-bb7e-1cef8d37c2df", + "on_change": null, + "snooze": null, + "source": "crud" + }, + { + "config": { + "functions": [ + "return function (data, event, source, pid)\n local user = data.entity.username\n error(\"Event hook on consumer \" .. user .. \"\")\nend\n" + ] + }, + "created_at": 1627595513, + "event": "consumers", + "handler": "lambda", + "id": "c9fdd58d-5416-4d3a-9467-51e5cfe4ca0e", + "on_change": null, + "snooze": null, + "source": "crud" + } + ], + "next": null +} +``` + +## List all sources + +Sources are the actions that trigger the event hook. The `/sources` JSON output follows the following pattern: +- 1st level = The source, which is the action that triggers the event hook. +- 2nd level = The event, which is the Kong entity the event hook will listen to for events. +- 3rd level = The available template parameters for use in webhook-custom payloads. + +For instance, in the example below `balancer` is the source, `health` is the event, and `upstream_id`, +`ip`, `port`, `hostname`, and `health` are the available template parameters. + +**Endpoint** + +
      /event-hooks/sources/
      + +**Response** + +```json +{ + "data": { + "balancer": { + "health": { + "fields": [ + "upstream_id", + "ip", + "port", + "hostname", + "health" + ] + } + }, + "crud": { + "acls": { + "fields": [ + "operation", + "entity", + "old_entity", + "schema" + ] + }, + . . . + + "rate-limiting-advanced": { + "rate-limit-exceeded": { + "description": "Run an event when a rate limit has been exceeded", + "fields": [ + "consumer", + "ip", + "service", + "rate", + "limit", + "window" + ], + "unique": [ + "consumer", + "ip", + "service" + ] + } + } + } +} +``` + +{:.note} +> **Note:** The response has been shortened because it is too long to include in its entirety. +The ellipsis in the center of the response represents the missing content. + +## List all events for a source + +Events are the Kong entities the event hook will listen to for events. With this endpoint you +can list all of the events associated with a particular source. + +
      /event-hooks/sources/{source}/
      + +The following response lists all of the events for the `dao:crud` source. + +**Response** + +```json +{ + "data": { + "create": { + "fields": [ + "operation", + "entity", + "old_entity", + "schema" + ] + }, + "delete": { + "fields": [ + "operation", + "entity", + "old_entity", + "schema" + ] + }, + "update": { + "fields": [ + "operation", + "entity", + "old_entity", + "schema" + ] + } + } +} +``` + +## Add a webhook + +**Endpoint** + +
      /event-hooks
      + +**Request Body** + +| Attribute | Description | +| ---------: | -------- | +| `event`
      *optional* | A string describing the Kong entity the event hook will listen to for events. | +| `handler`
      *required* | A string describing one of four handler options: webhook, webhook-custom, log, or lambda. | +| `source`
      *required* | A string describing the action that triggers the event hook. | +| `snooze`
      *optional* | An optional integer describing the time in seconds to delay an event trigger to avoid spamming an integration. | +| `on_change`
      *optional* | An optional boolean indicating whether to trigger an event when key parts of a payload have changed. | +| `config.url`
      *required* | The URL the JSON POST request is made to with the event data as the payload. | +| `config.headers`
      *optional* | An object defining additional HTTP headers to send in the webhook request, for example `{"X-Custom-Header": "My Value"}`.| +| `config.secret`
      *optional* | An optional string used to sign the remote webhook for remote verification. When set, Kong will sign the body of the event hook with HMAC-SHA1 and include it in a header, `x-kong-signature`, to the remote endpoint. | +| `config.ssl_verify`
      *optional* | A boolean indicating whether to verify the SSL certificate of the remote HTTPS server where the event hook will be sent. The default is `false`. | + +**Response** + +```json +{ + "config": { + "headers": {}, + "secret": null, + "ssl_verify": false, + "url": "https://webhook.site/a1b2c3-d4e5-g6h7-i8j9-k1l2m3n4o5p6" + }, + "created_at": 1627581575, + "event": "consumers", + "handler": "webhook", + "id": "c57340ab-9fed-40fd-bb7e-1cef8d37c2df", + "on_change": null, + "snooze": null, + "source": "crud" +} +``` + +## Add a custom webhook + +**Endpoint** + +
      /event-hooks
      + +**Request Body** + +| Attribute | Description | +| ---------: | -------- | +| `event`
      *optional* | A string describing the Kong entity the event-hook will listen to for events. | +| `handler`
      *required* | A string describing one of four handler options: webhook, webhook-custom, log, or lambda. | +| `source`
      *required* | A string describing the action that triggers the event hook. | +| `snooze`
      *optional* | An optional integer describing the time in seconds to delay an event trigger to avoid spamming an integration. | +| `on_change`
      *optional* | An optional boolean indicating whether to trigger an event when key parts of a payload have changed. | +| `config.url`
      *required* | The URL the JSON POST request is made to with the event data as the payload. | +| `config.method`
      *required* | The HTTP method used to create the custom webhook. | +| `config.payload`
      *optional* | An object that includes key/value pairs that describe the configurable payload body. Supports templating. The full list of available template parameters can be found in the `/sources` API output, under the `fields` JSON object. | +| `config.payload_format`
      *optional* | A optional boolean (defaults to `true`) indicating whether to format the `config.payload` with resty templating. When set to `false`, the payload is sent as a raw object. | +| `config.body`
      *optional* | An optional string sent in the remote request. | +| `config.body_format`
      *optional* | An optional boolean (defaults to `true`) indicating whether to format the `config.body` with resty templating. When set to `false`, the body is sent as a raw object. To see all the available parameters defined for a specific `source`, check the source fields displayed by the `/event-hooks/source` endpoint. | +| `config.headers` | An object defining additional HTTP headers to send in the webhook request, for example `{"Content-type": "application/json", "X-Custom-Header": "My Value"}`. | +| `config.headers_format`
      *optional* | An optional boolean (defaults to `false`) indicating whether to format the `config.headers` with resty templating. When set to `true`, the `config.headers` value will be treated as a template. To see all the available parameters defined for a specific `source`, check the source fields displayed by the `/event-hooks/sources` endpoint. | +| `config.secret`
      *optional* | An optional string used to sign the remote webhook for remote verification. When set, Kong will sign the body of the event hook with HMAC-SHA1 and include it in a header, `x-kong-signature`, to the remote endpoint. | +| `config.ssl_verify`
      *optional* | A boolean indicating whether to verify the SSL certificate of the remote HTTPS server where the event hook will be sent. The default value is `false`. | + +**Response** + +```json +{ + "config": { + "body": null, + "body_format": true, + "headers": { + "content-type": "application/json" + }, + "headers_format": false, + "method": "POST", + "payload": { + "text": "Admin account `{{ entity.username }}` {{ operation }}d; email address set to `{{ entity.email }}`" + }, + "payload_format": true, + "secret": null, + "ssl_verify": false, + "url": "https://hooks.slack.com/services/foo/bar/baz" + }, + "created_at": 1627588552, + "event": "admins", + "handler": "webhook-custom", + "id": "937df175-3db2-4e6d-8aa1-d95c94a76089", + "on_change": null, + "snooze": null, + "source": "crud" +} +``` + +## Add a log event hook + +**Endpoint** + +
      /event-hooks
      + +**Request Body** + +| Attribute | Description | +| ---------: | -------- | +| `event`
      *optional* | A string describing the Kong entity the event hook will listen to for events. | +| `handler`
      *required* | A string describing one of four handler options: webhook, webhook-custom, log, or lambda. | +| `source`
      *required* | A string describing the action that triggers the event hook. | +| `snooze`
      *optional* | An optional integer describing the time in seconds to delay an event trigger to avoid spamming an integration. | +| `on_change`
      *optional* | An optional boolean indicating whether to trigger an event when key parts of a payload have changed. | + +**Response** + +```json +{ + "config": {}, + "on_change": null, + "created_at": 1627346155, + "snooze": null, + "id": "13a16f91-68b6-4384-97f7-d02763a551ac", + "handler": "log", + "source": "crud", + "event": "routes" +} +``` + +## Add a lambda event hook + +**Endpoint** + +
      /event-hooks
      + +**Request Body** + +| Attribute | Description | +| ---------: | -------- | +| `event`
      *optional* | A string describing the Kong entity the event hook will listen to for events. | +| `handler`
      *required* | A string describing one of four handler options: webhook, webhook-custom, log, or lambda. | +| `source`
      *required* | A string describing the action that triggers the event hook. | +| `snooze`
      *optional* | An optional integer describing the time in seconds to delay an event trigger to avoid spamming an integration. | +| `on_change`
      *optional* | An optional boolean indicating whether to trigger an event when key parts of a payload have changed. | +| `config.functions`
      *required* | An array of Lua code functions to execute on the event hook. | + +**Response** + +```json +{ + "config": { + "functions": [ + "return function (data, event, source, pid)\n local user = data.entity.username\n error(\"Event hook on consumer \" .. user .. \"\")\nend\n" + ] + }, + "created_at": 1627595513, + "event": "consumers", + "handler": "lambda", + "id": "c9fdd58d-5416-4d3a-9467-51e5cfe4ca0e", + "on_change": null, + "snooze": null, + "source": "crud" +} +``` + +## Test an event hook + +It's useful to manually trigger an event hook without provoking the event to be triggered. +For instance, you might want to test the integration, or see if your hook's service is receiving a payload from Kong. + +POST any data to `/event-hooks/:id-of-hook/test`, and the `/test` endpoint executes the with the provided data as the event payload. + +**Endpoint** + +
      /event-hooks/{event-hook-id}/test
      + +**Response** + +```json +{ + "data": { + "consumer": { + "username": "Jane Austen" + }, + "event": "consumers", + "source": "crud" + }, + "result": { + "body": "", + "headers": { + "Cache-Control": "no-cache, private", + "Content-Type": "text/plain; charset=UTF-8", + "Date": "Fri, 30 Jul 2021 16:07:09 GMT", + "Server": "nginx/1.14.2", + "Transfer-Encoding": "chunked", + "Vary": "Accept-Encoding", + "X-Request-Id": "f1e703a5-d22c-435c-8d5d-bc9c561ead4a", + "X-Token-Id": "1cc1c53b-f613-467f-a5c9-20d276405104" + }, + "status": 200 + } +} + +``` + +## Ping a webhook event hook + +**Endpoint** + +
      /event-hooks/{event-hook-id}/ping
      + +**Response** + +```json +{ + "source": "kong:event_hooks", + "event_hooks": { + "source": "crud", + "id": "c57340ab-9fed-40fd-bb7e-1cef8d37c2df", + "on_change": null, + "event": "consumers", + "handler": "webhook", + "created_at": 1627581575, + "config": { + "headers": { + "content-type": "application/json" + }, + "ssl_verify": false, + "url": "https://webhook.site/a1b2c3-d4e5-g6h7-i8j9-k1l2m3n4o5p6", + "secret": null + }, + "snooze": null + }, + "event": "ping" +} +``` diff --git a/src/gateway/admin-api/index.md b/src/gateway/admin-api/index.md new file mode 100644 index 000000000000..459390e1765d --- /dev/null +++ b/src/gateway/admin-api/index.md @@ -0,0 +1,4440 @@ +--- +# +# WARNING: this file was auto-generated by a script. +# DO NOT edit this file directly. Instead, send a pull request to change +# https://github.com/Kong/kong/blob/master/scripts/autodoc/admin-api/generate.lua +# or its associated files instead. +# +title: Admin API +source_url: https://github.com/Kong/kong/blob/master/autodoc/admin-api/data/admin-api.lua +toc: false + +service_body: | + Attributes | Description + ---:| --- + `name`
      *optional* | The Service name. + `retries`
      *optional* | The number of retries to execute upon failure to proxy. Default: `5`. + `protocol` | The protocol used to communicate with the upstream. Accepted values are: `"grpc"`, `"grpcs"`, `"http"`, `"https"`, `"tcp"`, `"tls"`, `"tls_passthrough"`, `"udp"`, `"ws"` , `"wss"` . Default: `"http"`. + `host` | The host of the upstream server. Note that the host value is case sensitive. + `port` | The upstream server port. Default: `80`. + `path`
      *optional* | The path to be used in requests to the upstream server. + `connect_timeout`
      *optional* | The timeout in milliseconds for establishing a connection to the upstream server. Default: `60000`. + `write_timeout`
      *optional* | The timeout in milliseconds between two successive write operations for transmitting a request to the upstream server. Default: `60000`. + `read_timeout`
      *optional* | The timeout in milliseconds between two successive read operations for transmitting a request to the upstream server. Default: `60000`. + `tags`
      *optional* | An optional set of strings associated with the Service for grouping and filtering. + `client_certificate`
      *optional* | Certificate to be used as client certificate while TLS handshaking to the upstream server. With form-encoded, the notation is `client_certificate.id=`. With JSON, use "`"client_certificate":{"id":""}`. + `tls_verify`
      *optional* | Whether to enable verification of upstream server TLS certificate. If set to `null`, then the Nginx default is respected. + `tls_verify_depth`
      *optional* | Maximum depth of chain while verifying Upstream server's TLS certificate. If set to `null`, then the Nginx default is respected. Default: `null`. + `ca_certificates`
      *optional* | Array of `CA Certificate` object UUIDs that are used to build the trust store while verifying upstream server's TLS certificate. If set to `null` when Nginx default is respected. If default CA list in Nginx are not specified and TLS verification is enabled, then handshake with upstream server will always fail (because no CA are trusted). With form-encoded, the notation is `ca_certificates[]=4e3ad2e4-0bc4-4638-8e34-c84a417ba39b&ca_certificates[]=51e77dc2-8f3e-4afa-9d0e-0e3bbbcfd515`. With JSON, use an Array. + `enabled` | Whether the Service is active. If set to `false`, the proxy behavior will be as if any routes attached to it do not exist (404). Default: `true`. Default: `true`. + `url`
      *shorthand-attribute* | Shorthand attribute to set `protocol`, `host`, `port` and `path` at once. This attribute is write-only (the Admin API never returns the URL). + +service_json: | + { + "id": "9748f662-7711-4a90-8186-dc02f10eb0f5", + "created_at": 1422386534, + "updated_at": 1422386534, + "name": "my-service", + "retries": 5, + "protocol": "http", + "host": "example.com", + "port": 80, + "path": "/some_api", + "connect_timeout": 60000, + "write_timeout": 60000, + "read_timeout": 60000, + "tags": ["user-level", "low-priority"], + "client_certificate": {"id":"4e3ad2e4-0bc4-4638-8e34-c84a417ba39b"}, + "tls_verify": true, + "tls_verify_depth": null, + "ca_certificates": ["4e3ad2e4-0bc4-4638-8e34-c84a417ba39b", "51e77dc2-8f3e-4afa-9d0e-0e3bbbcfd515"], + "enabled": true + } + +service_data: | + "data": [{ + "id": "a5fb8d9b-a99d-40e9-9d35-72d42a62d83a", + "created_at": 1422386534, + "updated_at": 1422386534, + "name": "my-service", + "retries": 5, + "protocol": "http", + "host": "example.com", + "port": 80, + "path": "/some_api", + "connect_timeout": 60000, + "write_timeout": 60000, + "read_timeout": 60000, + "tags": ["user-level", "low-priority"], + "client_certificate": {"id":"51e77dc2-8f3e-4afa-9d0e-0e3bbbcfd515"}, + "tls_verify": true, + "tls_verify_depth": null, + "ca_certificates": ["4e3ad2e4-0bc4-4638-8e34-c84a417ba39b", "51e77dc2-8f3e-4afa-9d0e-0e3bbbcfd515"], + "enabled": true + }, { + "id": "fc73f2af-890d-4f9b-8363-af8945001f7f", + "created_at": 1422386534, + "updated_at": 1422386534, + "name": "my-service", + "retries": 5, + "protocol": "http", + "host": "example.com", + "port": 80, + "path": "/another_api", + "connect_timeout": 60000, + "write_timeout": 60000, + "read_timeout": 60000, + "tags": ["admin", "high-priority", "critical"], + "client_certificate": {"id":"4506673d-c825-444c-a25b-602e3c2ec16e"}, + "tls_verify": true, + "tls_verify_depth": null, + "ca_certificates": ["4e3ad2e4-0bc4-4638-8e34-c84a417ba39b", "51e77dc2-8f3e-4afa-9d0e-0e3bbbcfd515"], + "enabled": true + }], + +route_body: | + Attributes | Description + ---:| --- + `name`
      *optional* | The name of the Route. Route names must be unique, and they are case sensitive. For example, there can be two different Routes named "test" and "Test". + `protocols` | An array of the protocols this Route should allow. See the [Route Object](#route-object) section for a list of accepted protocols. When set to only `"https"`, HTTP requests are answered with an upgrade error. When set to only `"http"`, HTTPS requests are answered with an error. Default: `["http", "https"]`. + `methods`
      *semi-optional* | A list of HTTP methods that match this Route. + `hosts`
      *semi-optional* | A list of domain names that match this Route. Note that the hosts value is case sensitive. With form-encoded, the notation is `hosts[]=example.com&hosts[]=foo.test`. With JSON, use an Array. + `paths`
      *semi-optional* | A list of paths that match this Route. With form-encoded, the notation is `paths[]=/foo&paths[]=/bar`. With JSON, use an array. The path can be a regular expression, or a plain text pattern. The path patterns are matched against a normalized path, with most percent-encoded characters decoded, path folding, and preserved semantics. For more details read [rfc3986](https://datatracker.ietf.org/doc/html/rfc3986#section-6). + `headers`
      *semi-optional* | One or more lists of values indexed by header name that will cause this Route to match if present in the request. The `Host` header cannot be used with this attribute: hosts should be specified using the `hosts` attribute. When `headers` contains only one value and that value starts with the special prefix `~*`, the value is interpreted as a regular expression. + `https_redirect_status_code` | The status code Kong responds with when all properties of a Route match except the protocol i.e. if the protocol of the request is `HTTP` instead of `HTTPS`. `Location` header is injected by Kong if the field is set to 301, 302, 307 or 308. Accepted values are: `426`, `301`, `302`, `307`, `308`. Default: `426`. + `regex_priority`
      *optional* | A number used to choose which route resolves a given request when several routes match it using regexes simultaneously. When two routes match the path and have the same `regex_priority`, the older one (lowest `created_at`) is used. Note that the priority for non-regex routes is different (longer non-regex routes are matched before shorter ones). Default: `0`. + `strip_path` | When matching a Route via one of the `paths`, strip the matching prefix from the upstream request URL. Default: `true`. + `path_handling`
      *optional* | Controls how the Service path, Route path and requested path are combined when sending a request to the upstream. See above for a detailed description of each behavior. Accepted values are: `"v0"`, `"v1"`. Default: `"v0"`. + `preserve_host` | When matching a Route via one of the `hosts` domain names, use the request `Host` header in the upstream request headers. If set to `false`, the upstream `Host` header will be that of the Service's `host`. + `request_buffering` | Whether to enable request body buffering or not. With HTTP 1.1, it may make sense to turn this off on services that receive data with chunked transfer encoding. Default: `true`. + `response_buffering` | Whether to enable response body buffering or not. With HTTP 1.1, it may make sense to turn this off on services that send data with chunked transfer encoding. Default: `true`. + `snis`
      *semi-optional* | A list of SNIs that match this Route when using stream routing. + `sources`
      *semi-optional* | A list of IP sources of incoming connections that match this Route when using stream routing. Each entry is an object with fields "ip" (optionally in CIDR range notation) and/or "port". + `destinations`
      *semi-optional* | A list of IP destinations of incoming connections that match this Route when using stream routing. Each entry is an object with fields "ip" (optionally in CIDR range notation) and/or "port". + `tags`
      *optional* | An optional set of strings associated with the Route for grouping and filtering. + `service`
      *optional* | The Service this Route is associated to. This is where the Route proxies traffic to. With form-encoded, the notation is `service.id=` or `service.name=`. With JSON, use "`"service":{"id":""}` or `"service":{"name":""}`. + +route_json: | + { + "id": "d35165e2-d03e-461a-bdeb-dad0a112abfe", + "created_at": 1422386534, + "updated_at": 1422386534, + "name": "my-route", + "protocols": ["http", "https"], + "methods": ["GET", "POST"], + "hosts": ["example.com", "foo.test"], + "paths": ["/foo", "/bar"], + "headers": {"x-my-header":["foo", "bar"], "x-another-header":["bla"]}, + "https_redirect_status_code": 426, + "regex_priority": 0, + "strip_path": true, + "path_handling": "v0", + "preserve_host": false, + "request_buffering": true, + "response_buffering": true, + "tags": ["user-level", "low-priority"], + "service": {"id":"af8330d3-dbdc-48bd-b1be-55b98608834b"} + } + +route_data: | + "data": [{ + "id": "a9daa3ba-8186-4a0d-96e8-00d80ce7240b", + "created_at": 1422386534, + "updated_at": 1422386534, + "name": "my-route", + "protocols": ["http", "https"], + "methods": ["GET", "POST"], + "hosts": ["example.com", "foo.test"], + "paths": ["/foo", "/bar"], + "headers": {"x-my-header":["foo", "bar"], "x-another-header":["bla"]}, + "https_redirect_status_code": 426, + "regex_priority": 0, + "strip_path": true, + "path_handling": "v0", + "preserve_host": false, + "request_buffering": true, + "response_buffering": true, + "tags": ["user-level", "low-priority"], + "service": {"id":"127dfc88-ed57-45bf-b77a-a9d3a152ad31"} + }, { + "id": "9aa116fd-ef4a-4efa-89bf-a0b17c4be982", + "created_at": 1422386534, + "updated_at": 1422386534, + "name": "my-route", + "protocols": ["tcp", "tls"], + "https_redirect_status_code": 426, + "regex_priority": 0, + "strip_path": true, + "path_handling": "v0", + "preserve_host": false, + "request_buffering": true, + "response_buffering": true, + "snis": ["foo.test", "example.com"], + "sources": [{"ip":"10.1.0.0/16", "port":1234}, {"ip":"10.2.2.2"}, {"port":9123}], + "destinations": [{"ip":"10.1.0.0/16", "port":1234}, {"ip":"10.2.2.2"}, {"port":9123}], + "tags": ["admin", "high-priority", "critical"], + "service": {"id":"ba641b07-e74a-430a-ab46-94b61e5ea66b"} + }], + +consumer_body: | + Attributes | Description + ---:| --- + `username`
      *semi-optional* | The unique username of the Consumer. You must send either this field or `custom_id` with the request. + `custom_id`
      *semi-optional* | Field for storing an existing unique ID for the Consumer - useful for mapping Kong with users in your existing database. You must send either this field or `username` with the request. + `type`
      *required* | The type of consumer. It can be `0` (proxy), `1` (developer), `2` (admin) or `3` (application) Default: `0`. + `tags`
      *optional* | An optional set of strings associated with the Consumer for grouping and filtering. + +consumer_json: | + { + "id": "ec1a1f6f-2aa4-4e58-93ff-b56368f19b27", + "created_at": 1422386534, + "username": "my-username", + "custom_id": "my-custom-id", + "type": 0, + "tags": ["user-level", "low-priority"] + } + +consumer_data: | + "data": [{ + "id": "a4407883-c166-43fd-80ca-3ca035b0cdb7", + "created_at": 1422386534, + "username": "my-username", + "custom_id": "my-custom-id", + "type": 0, + "tags": ["user-level", "low-priority"] + }, { + "id": "01c23299-839c-49a5-a6d5-8864c09184af", + "created_at": 1422386534, + "username": "my-username", + "custom_id": "my-custom-id", + "type": 0, + "tags": ["admin", "high-priority", "critical"] + }], + +plugin_body: | + Attributes | Description + ---:| --- + `name` | The name of the Plugin that's going to be added. Currently, the Plugin must be installed in every Kong instance separately. + `route`
      *optional* | If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the Route being used. Default: `null`.With form-encoded, the notation is `route.id=` or `route.name=`. With JSON, use "`"route":{"id":""}` or `"route":{"name":""}`. + `service`
      *optional* | If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched. Default: `null`.With form-encoded, the notation is `service.id=` or `service.name=`. With JSON, use "`"service":{"id":""}` or `"service":{"name":""}`. + `consumer`
      *optional* | If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer. Default: `null`.With form-encoded, the notation is `consumer.id=` or `consumer.username=`. With JSON, use "`"consumer":{"id":""}` or `"consumer":{"username":""}`. + `config`
      *optional* | The configuration properties for the Plugin which can be found on the plugins documentation page in the [Kong Hub](https://docs.konghq.com/hub/). + `protocols` | A list of the request protocols that will trigger this plugin. The default value, as well as the possible values allowed on this field, may change depending on the plugin type. For example, plugins that only work in stream mode will only support `"tcp"` and `"tls"`. Default: `["grpc", "grpcs", "http",`` "https"]`. + `enabled` | Whether the plugin is applied. Default: `true`. + `tags`
      *optional* | An optional set of strings associated with the Plugin for grouping and filtering. + `ordering`
      *optional* | Describes a dependency to another plugin to determine plugin ordering during the `access` phase.
      --`before`: The plugin will be executed _before_ a specified plugin or list of plugins.
      -- `after`: The plugin will be executed _after_ a specified plugin or list of plugins. + +plugin_json: | + { + "id": "ce44eef5-41ed-47f6-baab-f725cecf98c7", + "name": "rate-limiting", + "created_at": 1422386534, + "route": null, + "service": null, + "consumer": null, + "config": {"minute":20, "hour":500}, + "protocols": ["http", "https"], + "enabled": true, + "tags": ["user-level", "low-priority"], + "ordering": {"before":["plugin-name"]} + } + +plugin_data: | + "data": [{ + "id": "02621eee-8309-4bf6-b36b-a82017a5393e", + "name": "rate-limiting", + "created_at": 1422386534, + "route": null, + "service": null, + "consumer": null, + "config": {"minute":20, "hour":500}, + "protocols": ["http", "https"], + "enabled": true, + "tags": ["user-level", "low-priority"], + "ordering": {"before":["plugin-name"]} + }, { + "id": "66c7b5c4-4aaf-4119-af1e-ee3ad75d0af4", + "name": "rate-limiting", + "created_at": 1422386534, + "route": null, + "service": null, + "consumer": null, + "config": {"minute":20, "hour":500}, + "protocols": ["tcp", "tls"], + "enabled": true, + "tags": ["admin", "high-priority", "critical"], + "ordering": {"after":["plugin-name"]} + }], + +certificate_body: | + Attributes | Description + ---:| --- + `cert` | PEM-encoded public certificate chain of the SSL key pair. This field is _referenceable_, which means it can be securely stored as a [secret](/gateway/latest/kong-enterprise/secrets-management/getting-started) in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/secrets-management/reference-format). + `key` | PEM-encoded private key of the SSL key pair. This field is _referenceable_, which means it can be securely stored as a [secret](/gateway/latest/kong-enterprise/secrets-management/getting-started) in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/secrets-management/reference-format). + `cert_alt`
      *optional* | PEM-encoded public certificate chain of the alternate SSL key pair. This should only be set if you have both RSA and ECDSA types of certificate available and would like Kong to prefer serving using ECDSA certs when client advertises support for it. This field is _referenceable_, which means it can be securely stored as a [secret](/gateway/latest/kong-enterprise/secrets-management/getting-started) in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/secrets-management/reference-format). + `key_alt`
      *optional* | PEM-encoded private key of the alternate SSL key pair. This should only be set if you have both RSA and ECDSA types of certificate available and would like Kong to prefer serving using ECDSA certs when client advertises support for it. This field is _referenceable_, which means it can be securely stored as a [secret](/gateway/latest/kong-enterprise/secrets-management/getting-started) in a vault. References must follow a [specific format](/gateway/latest/kong-enterprise/secrets-management/reference-format). + `tags`
      *optional* | An optional set of strings associated with the Certificate for grouping and filtering. + `snis`
      *shorthand-attribute* | An array of zero or more hostnames to associate with this certificate as SNIs. This is a sugar parameter that will, under the hood, create an SNI object and associate it with this certificate for your convenience. To set this attribute this certificate must have a valid private key associated with it. + +certificate_json: | + { + "id": "7fca84d6-7d37-4a74-a7b0-93e576089a41", + "created_at": 1422386534, + "cert": "-----BEGIN CERTIFICATE-----...", + "key": "-----BEGIN RSA PRIVATE KEY-----...", + "cert_alt": "-----BEGIN CERTIFICATE-----...", + "key_alt": "-----BEGIN EC PRIVATE KEY-----...", + "tags": ["user-level", "low-priority"] + } + +certificate_data: | + "data": [{ + "id": "d044b7d4-3dc2-4bbc-8e9f-6b7a69416df6", + "created_at": 1422386534, + "cert": "-----BEGIN CERTIFICATE-----...", + "key": "-----BEGIN RSA PRIVATE KEY-----...", + "cert_alt": "-----BEGIN CERTIFICATE-----...", + "key_alt": "-----BEGIN EC PRIVATE KEY-----...", + "tags": ["user-level", "low-priority"] + }, { + "id": "a9b2107f-a214-47b3-add4-46b942187924", + "created_at": 1422386534, + "cert": "-----BEGIN CERTIFICATE-----...", + "key": "-----BEGIN RSA PRIVATE KEY-----...", + "cert_alt": "-----BEGIN CERTIFICATE-----...", + "key_alt": "-----BEGIN EC PRIVATE KEY-----...", + "tags": ["admin", "high-priority", "critical"] + }], + +ca_certificate_body: | + Attributes | Description + ---:| --- + `cert` | PEM-encoded public certificate of the CA. + `cert_digest`
      *optional* | SHA256 hex digest of the public certificate. + `tags`
      *optional* | An optional set of strings associated with the Certificate for grouping and filtering. + +ca_certificate_json: | + { + "id": "04fbeacf-a9f1-4a5d-ae4a-b0407445db3f", + "created_at": 1422386534, + "cert": "-----BEGIN CERTIFICATE-----...", + "cert_digest": "c641e28d77e93544f2fa87b2cf3f3d51...", + "tags": ["user-level", "low-priority"] + } + +ca_certificate_data: | + "data": [{ + "id": "43429efd-b3a5-4048-94cb-5cc4029909bb", + "created_at": 1422386534, + "cert": "-----BEGIN CERTIFICATE-----...", + "cert_digest": "c641e28d77e93544f2fa87b2cf3f3d51...", + "tags": ["user-level", "low-priority"] + }, { + "id": "d26761d5-83a4-4f24-ac6c-cff276f2b79c", + "created_at": 1422386534, + "cert": "-----BEGIN CERTIFICATE-----...", + "cert_digest": "c641e28d77e93544f2fa87b2cf3f3d51...", + "tags": ["admin", "high-priority", "critical"] + }], + +sni_body: | + Attributes | Description + ---:| --- + `name` | The SNI name to associate with the given certificate. + `tags`
      *optional* | An optional set of strings associated with the SNIs for grouping and filtering. + `certificate` | The id (a UUID) of the certificate with which to associate the SNI hostname. The Certificate must have a valid private key associated with it to be used by the SNI object. With form-encoded, the notation is `certificate.id=`. With JSON, use "`"certificate":{"id":""}`. + +sni_json: | + { + "id": "91020192-062d-416f-a275-9addeeaffaf2", + "name": "my-sni", + "created_at": 1422386534, + "tags": ["user-level", "low-priority"], + "certificate": {"id":"a2e013e8-7623-4494-a347-6d29108ff68b"} + } + +sni_data: | + "data": [{ + "id": "147f5ef0-1ed6-4711-b77f-489262f8bff7", + "name": "my-sni", + "created_at": 1422386534, + "tags": ["user-level", "low-priority"], + "certificate": {"id":"a3ad71a8-6685-4b03-a101-980a953544f6"} + }, { + "id": "b87eb55d-69a1-41d2-8653-8d706eecefc0", + "name": "my-sni", + "created_at": 1422386534, + "tags": ["admin", "high-priority", "critical"], + "certificate": {"id":"4e8d95d4-40f2-4818-adcb-30e00c349618"} + }], + + +upstream_body: | + Attributes | Description + ---:| --- + `name` | This is a hostname, which must be equal to the `host` of a Service. + `algorithm`
      *optional* | Which load balancing algorithm to use. Accepted values are: `"consistent-hashing"`, `"least-connections"`, `"round-robin"`. Default: `"round-robin"`. + `hash_on`
      *optional* | What to use as hashing input. Using `none` results in a weighted-round-robin scheme with no hashing. Accepted values are: `"none"`, `"consumer"`, `"ip"`, `"header"`, `"cookie"`, `"path"`, `"query_arg"`, `"uri_capture"`. Default: `"none"`. + `hash_fallback`
      *optional* | What to use as hashing input if the primary `hash_on` does not return a hash (eg. header is missing, or no Consumer identified). Not available if `hash_on` is set to `cookie`. Accepted values are: `"none"`, `"consumer"`, `"ip"`, `"header"`, `"cookie"`, `"path"`, `"query_arg"`, `"uri_capture"`. Default: `"none"`. + `hash_on_header`
      *semi-optional* | The header name to take the value from as hash input. Only required when `hash_on` is set to `header`. + `hash_fallback_header`
      *semi-optional* | The header name to take the value from as hash input. Only required when `hash_fallback` is set to `header`. + `hash_on_cookie`
      *semi-optional* | The cookie name to take the value from as hash input. Only required when `hash_on` or `hash_fallback` is set to `cookie`. If the specified cookie is not in the request, Kong will generate a value and set the cookie in the response. + `hash_on_cookie_path`
      *semi-optional* | The cookie path to set in the response headers. Only required when `hash_on` or `hash_fallback` is set to `cookie`. Default: `"/"`. + `hash_on_query_arg`
      *semi-optional* | The name of the query string argument to take the value from as hash input. Only required when `hash_on` is set to `query_arg`. + `hash_fallback_query_arg`
      *semi-optional* | The name of the query string argument to take the value from as hash input. Only required when `hash_fallback` is set to `query_arg`. + `hash_on_uri_capture`
      *semi-optional* | The name of the route URI capture to take the value from as hash input. Only required when `hash_on` is set to `uri_capture`. + `hash_fallback_uri_capture`
      *semi-optional* | The name of the route URI capture to take the value from as hash input. Only required when `hash_fallback` is set to `uri_capture`. + `slots`
      *optional* | The number of slots in the load balancer algorithm. If `algorithm` is set to `round-robin`, this setting determines the maximum number of slots. If `algorithm` is set to `consistent-hashing`, this setting determines the actual number of slots in the algorithm. Accepts an integer in the range `10`-`65536`. Default: `10000`. + `healthchecks.active.``headers`
      *optional* | One or more lists of values indexed by header name to use in GET HTTP request to run as a probe on active health checks. Values must be pre-formatted. + `healthchecks.active.``https_sni`
      *optional* | The hostname to use as an SNI (Server Name Identification) when performing active health checks using HTTPS. This is particularly useful when Targets are configured using IPs, so that the target host's certificate can be verified with the proper SNI. + `healthchecks.active.``https_verify_certificate` | Whether to check the validity of the SSL certificate of the remote host when performing active health checks using HTTPS. Default: `true`. + `healthchecks.active.``healthy.interval`
      *optional* | Interval between active health checks for healthy targets (in seconds). A value of zero indicates that active probes for healthy targets should not be performed. Default: `0`. + `healthchecks.active.``healthy.http_statuses`
      *optional* | An array of HTTP statuses to consider a success, indicating healthiness, when returned by a probe in active health checks. Default: `[200, 302]`. With form-encoded, the notation is `http_statuses[]=200&http_statuses[]=302`. With JSON, use an Array. + `healthchecks.active.``healthy.successes`
      *optional* | Number of successes in active probes (as defined by `healthchecks.active.healthy.http_statuses`) to consider a target healthy. Default: `0`. + `healthchecks.active.``unhealthy.tcp_failures`
      *optional* | Number of TCP failures in active probes to consider a target unhealthy. Default: `0`. + `healthchecks.active.``unhealthy.http_statuses`
      *optional* | An array of HTTP statuses to consider a failure, indicating unhealthiness, when returned by a probe in active health checks. Default: `[429, 404, 500, 501, 502, 503,`` 504, 505]`. With form-encoded, the notation is `http_statuses[]=429&http_statuses[]=404`. With JSON, use an Array. + `healthchecks.active.``unhealthy.http_failures`
      *optional* | Number of HTTP failures in active probes (as defined by `healthchecks.active.unhealthy.http_statuses`) to consider a target unhealthy. Default: `0`. + `healthchecks.active.``unhealthy.interval`
      *optional* | Interval between active health checks for unhealthy targets (in seconds). A value of zero indicates that active probes for unhealthy targets should not be performed. Default: `0`. + `healthchecks.active.``unhealthy.timeouts`
      *optional* | Number of timeouts in active probes to consider a target unhealthy. Default: `0`. + `healthchecks.active.``http_path`
      *optional* | Path to use in GET HTTP request to run as a probe on active health checks. Default: `"/"`. + `healthchecks.active.``concurrency`
      *optional* | Number of targets to check concurrently in active health checks. Default: `10`. + `healthchecks.active.``timeout`
      *optional* | Socket timeout for active health checks (in seconds). Default: `1`. + `healthchecks.active.type`
      *optional* | Whether to perform active health checks using HTTP or HTTPS, or just attempt a TCP connection. Accepted values are: `"tcp"`, `"http"`, `"https"`, `"grpc"`, `"grpcs"`. Default: `"http"`. + `healthchecks.passive.``healthy.successes`
      *optional* | Number of successes in proxied traffic (as defined by `healthchecks.passive.healthy.http_statuses`) to consider a target healthy, as observed by passive health checks. Default: `0`. + `healthchecks.passive.``healthy.http_statuses`
      *optional* | An array of HTTP statuses which represent healthiness when produced by proxied traffic, as observed by passive health checks. Default: `[200, 201, 202, 203, 204, 205,`` 206, 207, 208, 226, 300, 301,`` 302, 303, 304, 305, 306, 307,`` 308]`. With form-encoded, the notation is `http_statuses[]=200&http_statuses[]=201`. With JSON, use an Array. + `healthchecks.passive.``unhealthy.tcp_failures`
      *optional* | Number of TCP failures in proxied traffic to consider a target unhealthy, as observed by passive health checks. Default: `0`. + `healthchecks.passive.``unhealthy.http_statuses`
      *optional* | An array of HTTP statuses which represent unhealthiness when produced by proxied traffic, as observed by passive health checks. Default: `[429, 500, 503]`. With form-encoded, the notation is `http_statuses[]=429&http_statuses[]=500`. With JSON, use an Array. + `healthchecks.passive.``unhealthy.http_failures`
      *optional* | Number of HTTP failures in proxied traffic (as defined by `healthchecks.passive.unhealthy.http_statuses`) to consider a target unhealthy, as observed by passive health checks. Default: `0`. + `healthchecks.passive.``unhealthy.timeouts`
      *optional* | Number of timeouts in proxied traffic to consider a target unhealthy, as observed by passive health checks. Default: `0`. + `healthchecks.passive.``type`
      *optional* | Whether to perform passive health checks interpreting HTTP/HTTPS statuses, or just check for TCP connection success. In passive checks, `http` and `https` options are equivalent. Accepted values are: `"tcp"`, `"http"`, `"https"`, `"grpc"`, `"grpcs"`. Default: `"http"`. + `healthchecks.threshold`
      *optional* | The minimum percentage of the upstream's targets' weight that must be available for the whole upstream to be considered healthy. Default: `0`. + `tags`
      *optional* | An optional set of strings associated with the Upstream for grouping and filtering. + `host_header`
      *optional* | The hostname to be used as `Host` header when proxying requests through Kong. + `client_certificate`
      *optional* | If set, the certificate to be used as client certificate while TLS handshaking to the upstream server.With form-encoded, the notation is `client_certificate.id=`. With JSON, use "`"client_certificate":{"id":""}`. + +upstream_json: | + { + "id": "58c8ccbb-eafb-4566-991f-2ed4f678fa70", + "created_at": 1422386534, + "name": "my-upstream", + "algorithm": "round-robin", + "hash_on": "none", + "hash_fallback": "none", + "hash_on_cookie_path": "/", + "slots": 10000, + "healthchecks": { + "active": { + "headers": [{"x-my-header":["foo", "bar"], "x-another-header":["bla"]}], + "https_sni": "example.com", + "https_verify_certificate": true, + "healthy": { + "interval": 0, + "http_statuses": [200, 302], + "successes": 0 + }, + "unhealthy": { + "tcp_failures": 0, + "http_statuses": [429, 404, 500, 501, 502, 503, 504, 505], + "http_failures": 0, + "interval": 0, + "timeouts": 0 + }, + "http_path": "/", + "concurrency": 10, + "timeout": 1, + "type": "http" + }, + "passive": { + "healthy": { + "successes": 0, + "http_statuses": [200, 201, 202, 203, 204, 205, 206, 207, 208, 226, 300, 301, 302, 303, 304, 305, 306, 307, 308] + }, + "unhealthy": { + "tcp_failures": 0, + "http_statuses": [429, 500, 503], + "http_failures": 0, + "timeouts": 0 + }, + "type": "http" + }, + "threshold": 0 + }, + "tags": ["user-level", "low-priority"], + "host_header": "example.com", + "client_certificate": {"id":"ea29aaa3-3b2d-488c-b90c-56df8e0dd8c6"} + } + +upstream_data: | + "data": [{ + "id": "4fe14415-73d5-4f00-9fbc-c72a0fccfcb2", + "created_at": 1422386534, + "name": "my-upstream", + "algorithm": "round-robin", + "hash_on": "none", + "hash_fallback": "none", + "hash_on_cookie_path": "/", + "slots": 10000, + "healthchecks": { + "active": { + "headers": [{"x-my-header":["foo", "bar"], "x-another-header":["bla"]}], + "https_sni": "example.com", + "https_verify_certificate": true, + "healthy": { + "interval": 0, + "http_statuses": [200, 302], + "successes": 0 + }, + "unhealthy": { + "tcp_failures": 0, + "http_statuses": [429, 404, 500, 501, 502, 503, 504, 505], + "http_failures": 0, + "interval": 0, + "timeouts": 0 + }, + "http_path": "/", + "concurrency": 10, + "timeout": 1, + "type": "http" + }, + "passive": { + "healthy": { + "successes": 0, + "http_statuses": [200, 201, 202, 203, 204, 205, 206, 207, 208, 226, 300, 301, 302, 303, 304, 305, 306, 307, 308] + }, + "unhealthy": { + "tcp_failures": 0, + "http_statuses": [429, 500, 503], + "http_failures": 0, + "timeouts": 0 + }, + "type": "http" + }, + "threshold": 0 + }, + "tags": ["user-level", "low-priority"], + "host_header": "example.com", + "client_certificate": {"id":"a3395f66-2af6-4c79-bea2-1b6933764f80"} + }, { + "id": "885a0392-ef1b-4de3-aacf-af3f1697ce2c", + "created_at": 1422386534, + "name": "my-upstream", + "algorithm": "round-robin", + "hash_on": "none", + "hash_fallback": "none", + "hash_on_cookie_path": "/", + "slots": 10000, + "healthchecks": { + "active": { + "headers": [{"x-my-header":["foo", "bar"], "x-another-header":["bla"]}], + "https_sni": "example.com", + "https_verify_certificate": true, + "healthy": { + "interval": 0, + "http_statuses": [200, 302], + "successes": 0 + }, + "unhealthy": { + "tcp_failures": 0, + "http_statuses": [429, 404, 500, 501, 502, 503, 504, 505], + "http_failures": 0, + "interval": 0, + "timeouts": 0 + }, + "http_path": "/", + "concurrency": 10, + "timeout": 1, + "type": "http" + }, + "passive": { + "healthy": { + "successes": 0, + "http_statuses": [200, 201, 202, 203, 204, 205, 206, 207, 208, 226, 300, 301, 302, 303, 304, 305, 306, 307, 308] + }, + "unhealthy": { + "tcp_failures": 0, + "http_statuses": [429, 500, 503], + "http_failures": 0, + "timeouts": 0 + }, + "type": "http" + }, + "threshold": 0 + }, + "tags": ["admin", "high-priority", "critical"], + "host_header": "example.com", + "client_certificate": {"id":"f5a9c0ca-bdbb-490f-8928-2ca95836239a"} + }], + +target_body: | + Attributes | Description + ---:| --- + `target` | The target address (ip or hostname) and port. If the hostname resolves to an SRV record, the `port` value will be overridden by the value from the DNS record. + `weight`
      *optional* | The weight this target gets within the upstream loadbalancer (`0`-`65535`). If the hostname resolves to an SRV record, the `weight` value will be overridden by the value from the DNS record. Default: `100`. + `tags`
      *optional* | An optional set of strings associated with the Target for grouping and filtering. + +target_json: | + { + "id": "173a6cee-90d1-40a7-89cf-0329eca780a6", + "created_at": 1422386534, + "upstream": {"id":"bdab0e47-4e37-4f0b-8fd0-87d95cc4addc"}, + "target": "example.com:8000", + "weight": 100, + "tags": ["user-level", "low-priority"] + } + +target_data: | + "data": [{ + "id": "f00c6da4-3679-4b44-b9fb-36a19bd3ae83", + "created_at": 1422386534, + "upstream": {"id":"0c61e164-6171-4837-8836-8f5298726d53"}, + "target": "example.com:8000", + "weight": 100, + "tags": ["user-level", "low-priority"] + }, { + "id": "5027BBC1-508C-41F8-87F2-AB1801E9D5C3", + "created_at": 1422386534, + "upstream": {"id":"68FDB05B-7B08-47E9-9727-AF7F897CFF1A"}, + "target": "example.com:8000", + "weight": 100, + "tags": ["admin", "high-priority", "critical"] + }], + +vault_body: | + Attributes | Description + ---:| --- + `prefix` | The unique prefix (or identifier) for this Vault configuration. The prefix is used to load the right Vault configuration and implementation when referencing secrets with the other entities. + `name` | The name of the Vault that's going to be added. Currently, the Vault implementation must be installed in every Kong instance. + `description`
      *optional* | The description of the Vault entity. + `config`
      *optional* | The configuration properties for the Vault which can be found on the vaults' documentation page. + `tags`
      *optional* | An optional set of strings associated with the Vault for grouping and filtering. + +vault_json: | + { + "id": "B2A30E8F-C542-49CF-8015-FB674987D1A5", + "prefix": "env", + "name": "env", + "description": "This vault is used to retrieve redis database access credentials", + "config": {"prefix":"SSL_"}, + "created_at": 1422386534, + "updated_at": 1422386534, + "tags": ["database-credentials", "data-plane"] + } + +vault_data: | + "data": [{ + "id": "518BBE43-2454-4559-99B0-8E7D1CD3E8C8", + "prefix": "env", + "name": "env", + "description": "This vault is used to retrieve redis database access credentials", + "config": {"prefix":"SSL_"}, + "created_at": 1422386534, + "updated_at": 1422386534, + "tags": ["database-credentials", "data-plane"] + }, { + "id": "7C4747E9-E831-4ED8-9377-83A6F8A37603", + "prefix": "env", + "name": "env", + "description": "This vault is used to retrieve redis database access credentials", + "config": {"prefix":"SSL_"}, + "created_at": 1422386534, + "updated_at": 1422386534, + "tags": ["certificates", "critical"] + }], + + +--- + +{{site.base_gateway}} comes with an **internal** RESTful Admin API for administration purposes. + Requests to the Admin API can be sent to any node in the cluster, and Kong will + keep the configuration consistent across all nodes. + + - `8001` is the default port on which the Admin API listens. + - `8444` is the default port for HTTPS traffic to the Admin API. + + This API is designed for internal use and provides full control over Kong, so + care should be taken when setting up Kong environments to avoid undue public + exposure of this API. See [this document][secure-admin-api] for a discussion + of methods to secure the Admin API. + +--- + + +## DB-less Mode + + +In [DB-less mode](/gateway/{{page.kong_version}}/production/deployment-topologies/db-less-and-declarative-config), the Admin API can be used to load a new declarative +configuration, and for inspecting the current configuration. In DB-less mode, +the Admin API for each Kong node functions independently, reflecting the memory state +of that particular Kong node. This is the case because there is no database +coordination between Kong nodes. + +In DB-less mode, you configure {{site.base_gateway}} declaratively. +Therefore, the Admin API is mostly read-only. The only tasks it can perform are all +related to handling the declarative config, including: + +* [Validating configurations against schemas](#validate-a-configuration-against-a-schema) +* [Validating plugin configurations against schemas](#validate-a-plugin-configuration-against-the-schema) +* [Reloading the declarative configuration](#reload-declarative-configuration) +* [Setting a target's health status in the load balancer](#set-target-as-healthy) + + +--- + + +## Declarative Configuration + + +Loading the declarative configuration of entities into {{site.base_gateway}} +can be done in two ways: at start-up, through the `declarative_config` +property, or at run-time, through the Admin API using the `/config` +endpoint. + +To get started using declarative configuration, you need a file +(in YAML or JSON format) containing entity definitions. You can +generate a sample declarative configuration with the command: + +``` +kong config init +``` + +It generates a file named `kong.yml` in the current directory, +containing the appropriate structure and examples. + + +### Reload Declarative Configuration + +This endpoint allows resetting a DB-less Kong with a new +declarative configuration data file. All previous contents +are erased from memory, and the entities specified in the +given file take their place. + +To learn more about the file format, see the +[declarative configuration](/gateway/{{page.kong_version}}/production/deployment-topologies/db-less-and-declarative-config) documentation. + + +
      /config
      + +{:.indent} +Attributes | Description +---:| --- +`config`
      **required** | The config data (in YAML or JSON format) to be loaded. + + +#### Request Querystring Parameters + +Attributes | Description +---:| --- +`check_hash`
      *optional* | If set to 1, Kong will compare the hash of the input config data against that of the previous one. If the configuration is identical, it will not reload it and will return HTTP 304. + + +#### Response + +``` +HTTP 200 OK +``` + +``` json +{ + { + "services": [], + "routes": [] + } +} +``` + +The response contains a list of all the entities that were parsed from the +input file. + +--- + + +## Supported Content Types + +The Admin API accepts 3 content types on every endpoint: + +- **application/json** + +Handy for complex bodies (ex: complex plugin configuration), in that case simply send +a JSON representation of the data you want to send. Example: + +```json +{ + "config": { + "limit": 10, + "period": "seconds" + } +} +``` + +An example adding a Route to a Service named `test-service`: + +``` +curl -i -X POST http://localhost:8001/services/test-service/routes \ + -H "Content-Type: application/json" \ + -d '{"name": "test-route", "paths": [ "/path/one", "/path/two" ]}' +``` + +- **application/x-www-form-urlencoded** + +Simple enough for basic request bodies, you will probably use it most of the time. +Note that when sending nested values, Kong expects nested objects to be referenced +with dotted keys. Example: + +``` +config.limit=10&config.period=seconds +``` + +When specifying arrays, send the values in order, or use square brackets (numbering +inside the brackets is optional but if provided it must be 1-indexed, and +consecutive). An example Route added to a Service named `test-service`: + +``` +curl -i -X POST http://localhost:8001/services/test-service/routes \ + -d "name=test-route" \ + -d "paths[1]=/path/one" \ + -d "paths[2]=/path/two" +``` + +The following two examples are identical to the one above, but less explicit: +``` +curl -i -X POST http://localhost:8001/services/test-service/routes \ + -d "name=test-route" \ + -d "paths[]=/path/one" \ + -d "paths[]=/path/two" + +curl -i -X POST http://localhost:8001/services/test-service/routes \ + -d "name=test-route" \ + -d "paths=/path/one" \ + -d "paths=/path/two" +``` + + +- **multipart/form-data** + +Similar to URL-encoded, this content type uses dotted keys to reference nested +objects. Here is an example of sending a Lua file to the pre-function Kong plugin: + +``` +curl -i -X POST http://localhost:8001/services/plugin-testing/plugins \ + -F "name=pre-function" \ + -F "config.access=@custom-auth.lua" +``` + +When specifying arrays for this content-type, the array indices must be specified. +An example Route added to a Service named `test-service`: + +``` +curl -i -X POST http://localhost:8001/services/test-service/routes \ + -F "name=test-route" \ + -F "paths[1]=/path/one" \ + -F "paths[2]=/path/two" +``` + +--- + +## Information Routes + + + +### Retrieve Node Information +{:.badge .dbless} + +Retrieve generic details about a node. + +
      /
      + +#### Response + +``` +HTTP 200 OK +``` + +```json +{ + "hostname": "", + "node_id": "6a72192c-a3a1-4c8d-95c6-efabae9fb969", + "lua_version": "LuaJIT 2.1.0-beta3", + "plugins": { + "available_on_server": [ + ... + ], + "enabled_in_cluster": [ + ... + ] + }, + "configuration" : { + ... + }, + "tagline": "Welcome to Kong", + "version": "0.14.0" +} +``` + +* `node_id`: A UUID representing the running Kong node. This UUID + is randomly generated when Kong starts, so the node will have a + different `node_id` each time it is restarted. +* `available_on_server`: Names of plugins that are installed on the node. +* `enabled_in_cluster`: Names of plugins that are enabled/configured. + That is, the plugins configurations currently in the data store shared + by all Kong nodes. + + +--- + +### Check Endpoint Or Entity Existence +{:.badge .dbless} + +Similar to `HTTP GET`, but does not return the body. Returns `HTTP 200` when the endpoint exits or `HTTP 404` when it does not. Other status codes are possible. + +
      /<any-endpoint>
      + +#### Response + +``` +HTTP 200 OK +``` + +```http +Access-Control-Allow-Origin: * +Content-Length: 11389 +Content-Type: application/json; charset=utf-8 +X-Kong-Admin-Latency: 1 +``` + + +--- + +### List Http Methods by Endpoint +{:.badge .dbless} + +List all the supported `HTTP` methods by an endpoint. This can also be used with a `CORS` preflight request. + +
      /<any-endpoint>
      + +#### Response + +``` +HTTP 204 No Content +``` + +```http +Access-Control-Allow-Headers: Content-Type +Access-Control-Allow-Methods: GET, HEAD, OPTIONS +Access-Control-Allow-Origin: * +Allow: GET, HEAD, OPTIONS +``` + + +--- + +### List Available Endpoints +{:.badge .dbless} + +List all available endpoints provided by the Admin API. + +
      /endpoints
      + +#### Response + +``` +HTTP 200 OK +``` + +```json +{ + "data": [ + "/", + "/acls", + "/acls/{acls}", + "/acls/{acls}/consumer", + "/basic-auths", + "/basic-auths/{basicauth_credentials}", + "/basic-auths/{basicauth_credentials}/consumer", + "/ca_certificates", + "/ca_certificates/{ca_certificates}", + "/cache", + "/cache/{key}", + "..." + ] +} +``` + + +--- + +### Validate A Configuration against A Schema +{:.badge .dbless} + +Check validity of a configuration against its entity schema. +This allows you to test your input before submitting a request +to the entity endpoints of the Admin API. + +Note that this only performs the schema validation checks, +checking that the input configuration is well-formed. +A requests to the entity endpoint using the given configuration +may still fail due to other reasons, such as invalid foreign +key relationships or uniqueness check failures against the +contents of the data store. + + +
      /schemas/{entity}/validate
      + +#### Response + +``` +HTTP 200 OK +``` + +```json +{ + "message": "schema validation successful" +} +``` + + +--- + +### Retrieve Entity Schema +{:.badge .dbless} + +Retrieve the schema of an entity. This is useful to +understand what fields an entity accepts, and can be used for building +third-party integrations to the Kong. + + +
      /schemas/{entity name}
      + +#### Response + +``` +HTTP 200 OK +``` + +```json +{ + "fields": [ + { + "id": { + "auto": true, + "type": "string", + "uuid": true + } + }, + { + "created_at": { + "auto": true, + "timestamp": true, + "type": "integer" + } + }, + ... + ] +} +``` + + +--- + +### Retrieve Plugin Schema +{:.badge .dbless} + +Retrieve the schema of a plugin's configuration. This is useful to +understand what fields a plugin accepts, and can be used for building +third-party integrations to the Kong's plugin system. + + +
      /schemas/plugins/{plugin name}
      + +#### Response + +``` +HTTP 200 OK +``` + +```json +{ + "fields": { + "hide_credentials": { + "default": false, + "type": "boolean" + }, + "key_names": { + "default": "function", + "required": true, + "type": "array" + } + } +} +``` + + +--- + +### Validate A Plugin Configuration against The Schema +{:.badge .dbless} + +Check validity of a plugin configuration against the plugins entity schema. +This allows you to test your input before submitting a request +to the entity endpoints of the Admin API. + +Note that this only performs the schema validation checks, +checking that the input configuration is well-formed. +A requests to the entity endpoint using the given configuration +may still fail due to other reasons, such as invalid foreign +key relationships or uniqueness check failures against the +contents of the data store. + + +
      /schemas/plugins/validate
      + +#### Response + +``` +HTTP 200 OK +``` + +```json +{ + "message": "schema validation successful" +} +``` + +--- + +### Retrieve Runtime Debugging Info of Kong's Timers +{:.badge .dbless} + +Retrieve runtime stats data from [lua-resty-timer-ng](https://github.com/Kong/lua-resty-timer-ng). + + +
      /timers
      + +#### Response + +``` +HTTP 200 OK +``` + +```json +{ "worker": { + "id": 0, + "count": 4, + }, + "stats": { + "flamegraph": { + "running": "@./kong/init.lua:706:init_worker();@./kong/runloop/handler.lua:1086:before() 0\n", + "elapsed_time": "@./kong/init.lua:706:init_worker();@./kong/runloop/handler.lua:1086:before() 17\n", + "pending": "@./kong/init.lua:706:init_worker();@./kong/runloop/handler.lua:1086:before() 0\n" + }, + "sys": { + "running": 0, + "runs": 7, + "pending": 0, + "waiting": 7, + "total": 7 + }, + "timers": { + "healthcheck-localhost:8080": { + "name": "healthcheck-localhost:8080", + "meta": { + "name": "@/build/luarocks/share/lua/5.1/resty/counter.lua:71:new()", + "callstack": "@./kong/plugins/prometheus/prometheus.lua:673:init_worker();@/build/luarocks/share/lua/5.1/resty/counter.lua:71:new()" + }, + "stats": { + "finish": 2, + "runs": 2, + "elapsed_time": { + "min": 0, + "max": 0, + "avg": 0, + "variance": 0 + }, + "last_err_msg": "" + } + } + } + } +} +``` +* `worker`: + * `id`: The ordinal number of the current Nginx worker processes (starting from number 0). + * `count`: The total number of the Nginx worker processes. +* `stats.flamegraph`: String-encoded timer-related flamegraph data. + You can use [brendangregg/FlameGraph](https://github.com/brendangregg/FlameGraph) to generate flamegraph svgs. +* `stats.sys`: List the number of different type of timers. + * `running`: number of running timers. + * `pending`: number of pending timers. + * `waiting`: number of unexpired timers. + * `total`: running + pending + waiting. +* `timers.meta`: Program callstack of created timers. + * `name`: An automatically generated string that stores the location where the creation timer was created. + * `callstack`: Lua call stack string showing where this timer was created. +* `timers.stats.elapsed_time`: An object that stores the maximum, minimum, average and variance + of the time spent on each run of the timer (second). +* `timers.stats.runs`: Total number of runs. +* `timers.stats.finish`: Total number of successful runs. + +Note: `flamegraph`, `timers.meta` and `timers.stats.elapsed_time` keys are only available when Kong's `log_level` config is set to `debug`. +Read the [doc of lua-resty-timer-ng](https://github.com/Kong/lua-resty-timer-ng#stats) for more details. + +--- + +## Health Routes + + + +### Retrieve Node Status +{:.badge .dbless} + +Retrieve usage information about a node, with some basic information +about the connections being processed by the underlying nginx process, +the status of the database connection, and node's memory usage. + +If you want to monitor the Kong process, since Kong is built on top +of nginx, every existing nginx monitoring tool or agent can be used. + + +
      /status
      + +#### Response + +``` +HTTP 200 OK +``` + +```json +{ + "database": { + "reachable": true + }, + "memory": { + "workers_lua_vms": [{ + "http_allocated_gc": "0.02 MiB", + "pid": 18477 + }, { + "http_allocated_gc": "0.02 MiB", + "pid": 18478 + }], + "lua_shared_dicts": { + "kong": { + "allocated_slabs": "0.04 MiB", + "capacity": "5.00 MiB" + }, + "kong_db_cache": { + "allocated_slabs": "0.80 MiB", + "capacity": "128.00 MiB" + }, + } + }, + "server": { + "total_requests": 3, + "connections_active": 1, + "connections_accepted": 1, + "connections_handled": 1, + "connections_reading": 0, + "connections_writing": 1, + "connections_waiting": 0 + }, + "configuration_hash": "779742c3d7afee2e38f977044d2ed96b" +} +``` + +* `memory`: Metrics about the memory usage. + * `workers_lua_vms`: An array with all workers of the Kong node, where each + entry contains: + * `http_allocated_gc`: HTTP submodule's Lua virtual machine's memory + usage information, as reported by `collectgarbage("count")`, for every + active worker, i.e. a worker that received a proxy call in the last 10 + seconds. + * `pid`: worker's process identification number. + * `lua_shared_dicts`: An array of information about dictionaries that are + shared with all workers in a Kong node, where each array node contains how + much memory is dedicated for the specific shared dictionary (`capacity`) + and how much of said memory is in use (`allocated_slabs`). + These shared dictionaries have least recent used (LRU) eviction + capabilities, so a full dictionary, where `allocated_slabs == capacity`, + will work properly. However for some dictionaries, e.g. cache HIT/MISS + shared dictionaries, increasing their size can be beneficial for the + overall performance of a Kong node. + * The memory usage unit and precision can be changed using the querystring + arguments `unit` and `scale`: + * `unit`: one of `b/B`, `k/K`, `m/M`, `g/G`, which will return results + in bytes, kibibytes, mebibytes, or gibibytes, respectively. When + "bytes" are requested, the memory values in the response will have a + number type instead of string. Defaults to `m`. + * `scale`: the number of digits to the right of the decimal points when + values are given in human-readable memory strings (unit other than + "bytes"). Defaults to `2`. + You can get the shared dictionaries memory usage in kibibytes with 4 + digits of precision by doing: `GET /status?unit=k&scale=4` +* `server`: Metrics about the nginx HTTP/S server. + * `total_requests`: The total number of client requests. + * `connections_active`: The current number of active client + connections including Waiting connections. + * `connections_accepted`: The total number of accepted client + connections. + * `connections_handled`: The total number of handled connections. + Generally, the parameter value is the same as accepts unless + some resource limits have been reached. + * `connections_reading`: The current number of connections + where Kong is reading the request header. + * `connections_writing`: The current number of connections + where nginx is writing the response back to the client. + * `connections_waiting`: The current number of idle client + connections waiting for a request. +* `database`: Metrics about the database. + * `reachable`: A boolean value reflecting the state of the + database connection. Please note that this flag **does not** + reflect the health of the database itself. +* `configuration_hash`: The hash of the current configuration. This +field is only returned when the Kong node is running in DB-less +or data-plane mode. The special return value "00000000000000000000000000000000" +means Kong does not currently have a valid configuration loaded. + + +--- + +## Tags + +Tags are strings associated to entities in Kong. + +Tags can contain almost all UTF-8 characters, with the following exceptions: + +- `,` and `/` are reserved for filtering tags with "and" and "or", so they are not allowed in tags. +- Non-printable ASCII (for example, the space character) is not allowed. + +Most core entities can be *tagged* via their `tags` attribute, upon creation or edition. + +Tags can be used to filter core entities as well, via the `?tags` querystring parameter. + +For example: if you normally get a list of all the Services by doing: + +``` +GET /services +``` + +You can get the list of all the Services tagged `example` by doing: + +``` +GET /services?tags=example +``` + +Similarly, if you want to filter Services so that you only get the ones tagged `example` *and* +`admin`, you can do that like so: + +``` +GET /services?tags=example,admin +``` + +Finally, if you wanted to filter the Services tagged `example` *or* `admin`, you could use: + +``` +GET /services?tags=example/admin +``` + +Some notes: + +* A maximum of 5 tags can be queried simultaneously in a single request with `,` or `/` +* Mixing operators is not supported: if you try to mix `,` with `/` in the same querystring, + you will receive an error. +* You may need to quote and/or escape some characters when using them from the + command line. +* Filtering by `tags` is not supported in foreign key relationship endpoints. For example, + the `tags` parameter will be ignored in a request such as `GET /services/foo/routes?tags=a,b` +* `offset` parameters are not guaranteed to work if the `tags` parameter is altered or removed + + +### List All Tags +{:.badge .dbless} + +Returns a paginated list of all the tags in the system. + +The list of entities will not be restricted to a single entity type: all the +entities tagged with tags will be present on this list. + +If an entity is tagged with more than one tag, the `entity_id` for that entity +will appear more than once in the resulting list. Similarly, if several entities +have been tagged with the same tag, the tag will appear in several items of this list. + + +
      /tags
      + +#### Response + +``` +HTTP 200 OK +``` + +``` json +{ + { + "data": [ + { "entity_name": "services", + "entity_id": "acf60b10-125c-4c1a-bffe-6ed55daefba4", + "tag": "s1", + }, + { "entity_name": "services", + "entity_id": "acf60b10-125c-4c1a-bffe-6ed55daefba4", + "tag": "s2", + }, + { "entity_name": "routes", + "entity_id": "60631e85-ba6d-4c59-bd28-e36dd90f6000", + "tag": "s1", + }, + ... + ], + "offset": "c47139f3-d780-483d-8a97-17e9adc5a7ab", + "next": "/tags?offset=c47139f3-d780-483d-8a97-17e9adc5a7ab", + } +} +``` + + +--- + +### List Entity Ids by Tag +{:.badge .dbless} + +Returns the entities that have been tagged with the specified tag. + +The list of entities will not be restricted to a single entity type: all the +entities tagged with tags will be present on this list. + + +
      /tags/{tags}
      + +#### Response + +``` +HTTP 200 OK +``` + +``` json +{ + { + "data": [ + { "entity_name": "services", + "entity_id": "c87440e1-0496-420b-b06f-dac59544bb6c", + "tag": "example", + }, + { "entity_name": "routes", + "entity_id": "8a99e4b1-d268-446b-ab8b-cd25cff129b1", + "tag": "example", + }, + ... + ], + "offset": "1fb491c4-f4a7-4bca-aeba-7f3bcee4d2f9", + "next": "/tags/example?offset=1fb491c4-f4a7-4bca-aeba-7f3bcee4d2f9", + } +} +``` + + +--- + +## Service Object + +Service entities, as the name implies, are abstractions of each of your own +upstream services. Examples of Services would be a data transformation +microservice, a billing API, etc. + +The main attribute of a Service is its URL (where Kong should proxy traffic +to), which can be set as a single string or by specifying its `protocol`, +`host`, `port` and `path` individually. + +Services are associated to Routes (a Service can have many Routes associated +with it). Routes are entry-points in Kong and define rules to match client +requests. Once a Route is matched, Kong proxies the request to its associated +Service. See the [Proxy Reference][proxy-reference] for a detailed explanation +of how Kong proxies traffic. + +Services can be both [tagged and filtered by tags](#tags). + + +```json +{{ page.service_json }} +``` + +### Add Service + + + +{:.note} +> **Note**: This API is not available in DB-less mode. + +##### Create Service + +
      /services
      + + +##### Create Service Associated to a Specific Certificate + +
      /certificates/{certificate name or id}/services
      + +{:.indent} +Attributes | Description +---:| --- +`certificate name or id`
      **required** | The unique identifier or the `name` attribute of the Certificate that should be associated to the newly-created Service. + + +#### Request Body + +{{ page.service_body }} + + +#### Response + +``` +HTTP 201 Created +``` + +```json +{{ page.service_json }} +``` + + +--- + +### List Services +{:.badge .dbless} + +##### List All Services + +
      /services
      + + +##### List Services Associated to a Specific Certificate + +
      /certificates/{certificate name or id}/services
      + +{:.indent} +Attributes | Description +---:| --- +`certificate name or id`
      **required** | The unique identifier or the `name` attribute of the Certificate whose Services are to be retrieved. When using this endpoint, only Services associated to the specified Certificate will be listed. + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{ +{{ page.service_data }} + "next": "http://localhost:8001/services?offset=6378122c-a0a1-438d-a5c6-efabae9fb969" +} +``` + + +--- + +### Retrieve Service +{:.badge .dbless} + +##### Retrieve Service + +
      /services/{service name or id}
      + +{:.indent} +Attributes | Description +---:| --- +`service name or id`
      **required** | The unique identifier **or** the name of the Service to retrieve. + + +##### Retrieve Service Associated to a Specific Certificate + +
      /certificates/{certificate id}/services/{service name or id}
      + +{:.indent} +Attributes | Description +---:| --- +`certificate id`
      **required** | The unique identifier of the Certificate to retrieve. +`service name or id`
      **required** | The unique identifier **or** the name of the Service to retrieve. + + +##### Retrieve Service Associated to a Specific Route + +
      /routes/{route name or id}/service
      + +{:.indent} +Attributes | Description +---:| --- +`route name or id`
      **required** | The unique identifier **or** the name of the Route associated to the Service to be retrieved. + + +##### Retrieve Service Associated to a Specific Plugin + +
      /plugins/{plugin id}/service
      + +{:.indent} +Attributes | Description +---:| --- +`plugin id`
      **required** | The unique identifier of the Plugin associated to the Service to be retrieved. + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{{ page.service_json }} +``` + + +--- + +### Update Service + + + +{:.note} +> **Note**: This API is not available in DB-less mode. + +##### Update Service + +
      /services/{service name or id}
      + +{:.indent} +Attributes | Description +---:| --- +`service name or id`
      **required** | The unique identifier **or** the name of the Service to update. + + +##### Update Service Associated to a Specific Certificate + +
      /certificates/{certificate id}/services/{service name or id}
      + +{:.indent} +Attributes | Description +---:| --- +`certificate id`
      **required** | The unique identifier of the Certificate to update. +`service name or id`
      **required** | The unique identifier **or** the name of the Service to update. + + +##### Update Service Associated to a Specific Route + +
      /routes/{route name or id}/service
      + +{:.indent} +Attributes | Description +---:| --- +`route name or id`
      **required** | The unique identifier **or** the name of the Route associated to the Service to be updated. + + +##### Update Service Associated to a Specific Plugin + +
      /plugins/{plugin id}/service
      + +{:.indent} +Attributes | Description +---:| --- +`plugin id`
      **required** | The unique identifier of the Plugin associated to the Service to be updated. + + +#### Request Body + +{{ page.service_body }} + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{{ page.service_json }} +``` + + +--- + +### Update Or Create Service + + + +{:.note} +> **Note**: This API is not available in DB-less mode. + +##### Create Or Update Service + +
      /services/{service name or id}
      + +{:.indent} +Attributes | Description +---:| --- +`service name or id`
      **required** | The unique identifier **or** the name of the Service to create or update. + + +##### Create Or Update Service Associated to a Specific Certificate + +
      /certificates/{certificate id}/services/{service name or id}
      + +{:.indent} +Attributes | Description +---:| --- +`certificate id`
      **required** | The unique identifier of the Certificate to create or update. +`service name or id`
      **required** | The unique identifier **or** the name of the Service to create or update. + + +##### Create Or Update Service Associated to a Specific Route + +
      /routes/{route name or id}/service
      + +{:.indent} +Attributes | Description +---:| --- +`route name or id`
      **required** | The unique identifier **or** the name of the Route associated to the Service to be created or updated. + + +##### Create Or Update Service Associated to a Specific Plugin + +
      /plugins/{plugin id}/service
      + +{:.indent} +Attributes | Description +---:| --- +`plugin id`
      **required** | The unique identifier of the Plugin associated to the Service to be created or updated. + + +#### Request Body + +{{ page.service_body }} + + +Inserts (or replaces) the Service under the requested resource with the +definition specified in the body. The Service will be identified via the `name +or id` attribute. + +When the `name or id` attribute has the structure of a UUID, the Service being +inserted/replaced will be identified by its `id`. Otherwise it will be +identified by its `name`. + +When creating a new Service without specifying `id` (neither in the URL nor in +the body), then it will be auto-generated. + +Notice that specifying a `name` in the URL and a different one in the request +body is not allowed. + + +#### Response + +``` +HTTP 200 OK +``` + +See POST and PATCH responses. + + +--- + +### Delete Service + + + +{:.note} +> **Note**: This API is not available in DB-less mode. + +##### Delete Service + +
      /services/{service name or id}
      + +{:.indent} +Attributes | Description +---:| --- +`service name or id`
      **required** | The unique identifier **or** the name of the Service to delete. + + +##### Delete Service Associated to a Specific Certificate + +
      /certificates/{certificate id}/services/{service name or id}
      + +{:.indent} +Attributes | Description +---:| --- +`certificate id`
      **required** | The unique identifier of the Certificate to delete. +`service name or id`
      **required** | The unique identifier **or** the name of the Service to delete. + +#### Response + +``` +HTTP 204 No Content +``` + + +--- + +## Route Object + +Route entities define rules to match client requests. Each Route is +associated with a Service, and a Service may have multiple Routes associated to +it. Every request matching a given Route will be proxied to its associated +Service. + +The combination of Routes and Services (and the separation of concerns between +them) offers a powerful routing mechanism with which it is possible to define +fine-grained entry-points in Kong leading to different upstream services of +your infrastructure. + +You need at least one matching rule that applies to the protocol being matched +by the Route. Depending on the protocols configured to be matched by the Route +(as defined with the `protocols` field), this means that at least one of the +following attributes must be set: + +* For `http`, at least one of `methods`, `hosts`, `headers` or `paths`; +* For `https`, at least one of `methods`, `hosts`, `headers`, `paths` or `snis`; +* For `tcp`, at least one of `sources` or `destinations`; +* For `tls`, at least one of `sources`, `destinations` or `snis`; +* For `tls_passthrough`, set `snis`; +* For `grpc`, at least one of `hosts`, `headers` or `paths`; +* For `grpcs`, at least one of `hosts`, `headers`, `paths` or `snis`. +* For `ws`, at least one of `hosts`, `headers` or `paths`; +* For `wss`, at least one of `hosts`, `headers`, `paths` or `snis`; + +A route can't have both `tls` and `tls_passthrough` protocols at same time. + +#### Path handling algorithms + +{:.note} +> **Note**: Path handling algorithms v1 was deprecated in Kong 3.0. From Kong 3.0, when `router_flavor` +> is set to `expressions`, `route.path_handling` will be not be configurable and the path handling behavior +> will be `"v0"`; when `router_flavor` is set to `traditional_compatible`, the path handling behavior +> will be `"v0"` regardless of the value of `route.path_handling`. Only `router_flavor` = `traditional` +> will support `path_handling` `"v1'` behavior. + +`"v0"` is the behavior used in Kong 0.x, 2.x and 3.x. It treats `service.path`, `route.path` and request path as +*segments* of a URL. It will always join them via slashes. Given a service path `/s`, route path `/r` +and request path `/re`, the concatenated path will be `/s/re`. If the resulting path is a single slash, +no further transformation is done to it. If it's longer, then the trailing slash is removed. + +`"v1"` is the behavior used in Kong 1.x. It treats `service.path` as a *prefix*, and ignores the initial +slashes of the request and route paths. Given service path `/s`, route path `/r` and request path `/re`, +the concatenated path will be `/sre`. + +Both versions of the algorithm detect "double slashes" when combining paths, replacing them by single +slashes. + +The following table shows the possible combinations of path handling version, strip path, and request: + +| `service.path` | `route.path` | `request` |`route.strip_path` | `route.path_handling` | request path | upstream path | +|----------------|--------------|-----------|-------------------|-----------------------|--------------|---------------| +| `/s` | `/fv0` | `req` | `false` | `v0` | `/fv0/req` | `/s/fv0/req` | +| `/s` | `/fv0` | `blank` | `false` | `v0` | `/fv0` | `/s/fv0` | +| `/s` | `/fv1` | `req` | `false` | `v1` | `/fv1/req` | `/sfv1/req` | +| `/s` | `/fv1` | `blank` | `false` | `v1` | `/fv1` | `/sfv1` | +| `/s` | `/tv0` | `req` | `true` | `v0` | `/tv0/req` | `/s/req` | +| `/s` | `/tv0` | `blank` | `true` | `v0` | `/tv0` | `/s` | +| `/s` | `/tv1` | `req` | `true` | `v1` | `/tv1/req` | `/s/req` | +| `/s` | `/tv1` | `blank` | `true` | `v1` | `/tv1` | `/s` | +| `/s` | `/fv0/` | `req` | `false` | `v0` | `/fv0/req` | `/s/fv0/req` | +| `/s` | `/fv0/` | `blank` | `false` | `v0` | `/fv0/` | `/s/fv01/` | +| `/s` | `/fv1/` | `req` | `false` | `v1` | `/fv1/req` | `/sfv1/req` | +| `/s` | `/fv1/` | `blank` | `false` | `v1` | `/fv1/` | `/sfv1/` | +| `/s` | `/tv0/` | `req` | `true` | `v0` | `/tv0/req` | `/s/req` | +| `/s` | `/tv0/` | `blank` | `true` | `v0` | `/tv0/` | `/s/` | +| `/s` | `/tv1/` | `req` | `true` | `v1` | `/tv1/req` | `/sreq` | +| `/s` | `/tv1/` | `blank` | `true` | `v1` | `/tv1/` | `/s` | + + +Routes can be both [tagged and filtered by tags](#tags). + + +```json +{{ page.route_json }} +``` + +### Add Route + + + +{:.note} +> **Note**: This API is not available in DB-less mode. + +##### Create Route + +
      /routes
      + + +##### Create Route Associated to a Specific Service + +
      /services/{service name or id}/routes
      + +{:.indent} +Attributes | Description +---:| --- +`service name or id`
      **required** | The unique identifier or the `name` attribute of the Service that should be associated to the newly-created Route. + + +#### Request Body + +{{ page.route_body }} + + +#### Response + +``` +HTTP 201 Created +``` + +```json +{{ page.route_json }} +``` + + +--- + +### List Routes +{:.badge .dbless} + +##### List All Routes + +
      /routes
      + + +##### List Routes Associated to a Specific Service + +
      /services/{service name or id}/routes
      + +{:.indent} +Attributes | Description +---:| --- +`service name or id`
      **required** | The unique identifier or the `name` attribute of the Service whose Routes are to be retrieved. When using this endpoint, only Routes associated to the specified Service will be listed. + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{ +{{ page.route_data }} + "next": "http://localhost:8001/routes?offset=6378122c-a0a1-438d-a5c6-efabae9fb969" +} +``` + + +--- + +### Retrieve Route +{:.badge .dbless} + +##### Retrieve Route + +
      /routes/{route name or id}
      + +{:.indent} +Attributes | Description +---:| --- +`route name or id`
      **required** | The unique identifier **or** the name of the Route to retrieve. + + +##### Retrieve Route Associated to a Specific Service + +
      /services/{service name or id}/routes/{route name or id}
      + +{:.indent} +Attributes | Description +---:| --- +`service name or id`
      **required** | The unique identifier **or** the name of the Service to retrieve. +`route name or id`
      **required** | The unique identifier **or** the name of the Route to retrieve. + + +##### Retrieve Route Associated to a Specific Plugin + +
      /plugins/{plugin id}/route
      + +{:.indent} +Attributes | Description +---:| --- +`plugin id`
      **required** | The unique identifier of the Plugin associated to the Route to be retrieved. + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{{ page.route_json }} +``` + + +--- + +### Update Route + + + +{:.note} +> **Note**: This API is not available in DB-less mode. + +##### Update Route + +
      /routes/{route name or id}
      + +{:.indent} +Attributes | Description +---:| --- +`route name or id`
      **required** | The unique identifier **or** the name of the Route to update. + + +##### Update Route Associated to a Specific Service + +
      /services/{service name or id}/routes/{route name or id}
      + +{:.indent} +Attributes | Description +---:| --- +`service name or id`
      **required** | The unique identifier **or** the name of the Service to update. +`route name or id`
      **required** | The unique identifier **or** the name of the Route to update. + + +##### Update Route Associated to a Specific Plugin + +
      /plugins/{plugin id}/route
      + +{:.indent} +Attributes | Description +---:| --- +`plugin id`
      **required** | The unique identifier of the Plugin associated to the Route to be updated. + + +#### Request Body + +{{ page.route_body }} + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{{ page.route_json }} +``` + + +--- + +### Update Or Create Route + + + +{:.note} +> **Note**: This API is not available in DB-less mode. + +##### Create Or Update Route + +
      /routes/{route name or id}
      + +{:.indent} +Attributes | Description +---:| --- +`route name or id`
      **required** | The unique identifier **or** the name of the Route to create or update. + + +##### Create Or Update Route Associated to a Specific Service + +
      /services/{service name or id}/routes/{route name or id}
      + +{:.indent} +Attributes | Description +---:| --- +`service name or id`
      **required** | The unique identifier **or** the name of the Service to create or update. +`route name or id`
      **required** | The unique identifier **or** the name of the Route to create or update. + + +##### Create Or Update Route Associated to a Specific Plugin + +
      /plugins/{plugin id}/route
      + +{:.indent} +Attributes | Description +---:| --- +`plugin id`
      **required** | The unique identifier of the Plugin associated to the Route to be created or updated. + + +#### Request Body + +{{ page.route_body }} + + +Inserts (or replaces) the Route under the requested resource with the +definition specified in the body. The Route will be identified via the `name +or id` attribute. + +When the `name or id` attribute has the structure of a UUID, the Route being +inserted/replaced will be identified by its `id`. Otherwise it will be +identified by its `name`. + +When creating a new Route without specifying `id` (neither in the URL nor in +the body), then it will be auto-generated. + +Notice that specifying a `name` in the URL and a different one in the request +body is not allowed. + + +#### Response + +``` +HTTP 200 OK +``` + +See POST and PATCH responses. + + +--- + +### Delete Route + + + +{:.note} +> **Note**: This API is not available in DB-less mode. + +##### Delete Route + +
      /routes/{route name or id}
      + +{:.indent} +Attributes | Description +---:| --- +`route name or id`
      **required** | The unique identifier **or** the name of the Route to delete. + + +##### Delete Route Associated to a Specific Service + +
      /services/{service name or id}/routes/{route name or id}
      + +{:.indent} +Attributes | Description +---:| --- +`service name or id`
      **required** | The unique identifier **or** the name of the Service to delete. +`route name or id`
      **required** | The unique identifier **or** the name of the Route to delete. + + +#### Response + +``` +HTTP 204 No Content +``` + + +--- + +## Consumer Object + +The Consumer object represents a consumer - or a user - of a Service. You can +either rely on Kong as the primary data store, or you can map the consumer list +with your database to keep consistency between Kong and your existing primary +data store. + +Consumers can be both [tagged and filtered by tags](#tags). + + +```json +{{ page.consumer_json }} +``` + +### Add Consumer + + + +{:.note} +> **Note**: This API is not available in DB-less mode. + +##### Create Consumer + +
      /consumers
      + + +#### Request Body + +{{ page.consumer_body }} + + +#### Response + +``` +HTTP 201 Created +``` + +```json +{{ page.consumer_json }} +``` + + +--- + +### List Consumers +{:.badge .dbless} + +##### List All Consumers + +
      /consumers
      + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{ +{{ page.consumer_data }} + "next": "http://localhost:8001/consumers?offset=6378122c-a0a1-438d-a5c6-efabae9fb969" +} +``` + + +--- + +### Retrieve Consumer +{:.badge .dbless} + +##### Retrieve Consumer + +
      /consumers/{consumer username or id}
      + +{:.indent} +Attributes | Description +---:| --- +`consumer username or id`
      **required** | The unique identifier **or** the username of the Consumer to retrieve. + + +##### Retrieve Consumer Associated to a Specific Plugin + +
      /plugins/{plugin id}/consumer
      + +{:.indent} +Attributes | Description +---:| --- +`plugin id`
      **required** | The unique identifier of the Plugin associated to the Consumer to be retrieved. + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{{ page.consumer_json }} +``` + + +--- + +### Update Consumer + + + +{:.note} +> **Note**: This API is not available in DB-less mode. + +##### Update Consumer + +
      /consumers/{consumer username or id}
      + +{:.indent} +Attributes | Description +---:| --- +`consumer username or id`
      **required** | The unique identifier **or** the username of the Consumer to update. + + +##### Update Consumer Associated to a Specific Plugin + +
      /plugins/{plugin id}/consumer
      + +{:.indent} +Attributes | Description +---:| --- +`plugin id`
      **required** | The unique identifier of the Plugin associated to the Consumer to be updated. + + +#### Request Body + +{{ page.consumer_body }} + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{{ page.consumer_json }} +``` + + +--- + +### Update Or Create Consumer + + + +{:.note} +> **Note**: This API is not available in DB-less mode. + +##### Create Or Update Consumer + +
      /consumers/{consumer username or id}
      + +{:.indent} +Attributes | Description +---:| --- +`consumer username or id`
      **required** | The unique identifier **or** the username of the Consumer to create or update. + + +##### Create Or Update Consumer Associated to a Specific Plugin + +
      /plugins/{plugin id}/consumer
      + +{:.indent} +Attributes | Description +---:| --- +`plugin id`
      **required** | The unique identifier of the Plugin associated to the Consumer to be created or updated. + + +#### Request Body + +{{ page.consumer_body }} + + +Inserts (or replaces) the Consumer under the requested resource with the +definition specified in the body. The Consumer will be identified via the `username +or id` attribute. + +When the `username or id` attribute has the structure of a UUID, the Consumer being +inserted/replaced will be identified by its `id`. Otherwise it will be +identified by its `username`. + +When creating a new Consumer without specifying `id` (neither in the URL nor in +the body), then it will be auto-generated. + +Notice that specifying a `username` in the URL and a different one in the request +body is not allowed. + + +#### Response + +``` +HTTP 200 OK +``` + +See POST and PATCH responses. + + +--- + +### Delete Consumer + + + +{:.note} +> **Note**: This API is not available in DB-less mode. + +##### Delete Consumer + +
      /consumers/{consumer username or id}
      + +{:.indent} +Attributes | Description +---:| --- +`consumer username or id`
      **required** | The unique identifier **or** the username of the Consumer to delete. + + +#### Response + +``` +HTTP 204 No Content +``` + + +--- + +## Plugin Object + +A Plugin entity represents a plugin configuration that will be executed during +the HTTP request/response lifecycle. It is how you can add functionalities +to Services that run behind Kong, like Authentication or Rate Limiting for +example. You can find more information about how to install and what values +each plugin takes by visiting the [Kong Hub](https://docs.konghq.com/hub/). + +When adding a Plugin Configuration to a Service, every request made by a client to +that Service will run said Plugin. If a Plugin needs to be tuned to different +values for some specific Consumers, you can do so by creating a separate +plugin instance that specifies both the Service and the Consumer, through the +`service` and `consumer` fields. + +Plugins can be both [tagged and filtered by tags](#tags). + + +```json +{{ page.plugin_json }} +``` + +See the [Precedence](#precedence) section below for more details. + +#### Precedence + +A plugin will always be run once and only once per request. But the +configuration with which it will run depends on the entities it has been +configured for. + +Plugins can be configured for various entities, combination of entities, or +even globally. This is useful, for example, when you wish to configure a plugin +a certain way for most requests, but make _authenticated requests_ behave +slightly differently. + +Therefore, there exists an order of precedence for running a plugin when it has +been applied to different entities with different configurations. The rule of +thumb is: the more specific a plugin is with regards to how many entities it +has been configured on, the higher its priority. + +The complete order of precedence when a plugin has been configured multiple +times is: + +1. Plugins configured on a combination of: a Route, a Service, and a Consumer. + (Consumer means the request must be authenticated). +2. Plugins configured on a combination of a Route and a Consumer. + (Consumer means the request must be authenticated). +3. Plugins configured on a combination of a Service and a Consumer. + (Consumer means the request must be authenticated). +4. Plugins configured on a combination of a Route and a Service. +5. Plugins configured on a Consumer. + (Consumer means the request must be authenticated). +6. Plugins configured on a Route. +7. Plugins configured on a Service. +8. Plugins configured to run globally. + +**Example**: if the `rate-limiting` plugin is applied twice (with different +configurations): for a Service (Plugin config A), and for a Consumer (Plugin +config B), then requests authenticating this Consumer will run Plugin config B +and ignore A. However, requests that do not authenticate this Consumer will +fallback to running Plugin config A. Note that if config B is disabled +(its `enabled` flag is set to `false`), config A will apply to requests that +would have otherwise matched config B. + + +### Add Plugin + + + +{:.note} +> **Note**: This API is not available in DB-less mode. + +##### Create Plugin + +
      /plugins
      + + +##### Create Plugin Associated to a Specific Route + +
      /routes/{route name or id}/plugins
      + +{:.indent} +Attributes | Description +---:| --- +`route name or id`
      **required** | The unique identifier or the `name` attribute of the Route that should be associated to the newly-created Plugin. + + +##### Create Plugin Associated to a Specific Service + +
      /services/{service name or id}/plugins
      + +{:.indent} +Attributes | Description +---:| --- +`service name or id`
      **required** | The unique identifier or the `name` attribute of the Service that should be associated to the newly-created Plugin. + + +##### Create Plugin Associated to a Specific Consumer + +
      /consumers/{consumer name or id}/plugins
      + +{:.indent} +Attributes | Description +---:| --- +`consumer name or id`
      **required** | The unique identifier or the `name` attribute of the Consumer that should be associated to the newly-created Plugin. + + +#### Request Body + +{{ page.plugin_body }} + + +#### Response + +``` +HTTP 201 Created +``` + +```json +{{ page.plugin_json }} +``` + + +--- + +### List Plugins +{:.badge .dbless} + +##### List All Plugins + +
      /plugins
      + + +##### List Plugins Associated to a Specific Route + +
      /routes/{route name or id}/plugins
      + +{:.indent} +Attributes | Description +---:| --- +`route name or id`
      **required** | The unique identifier or the `name` attribute of the Route whose Plugins are to be retrieved. When using this endpoint, only Plugins associated to the specified Route will be listed. + + +##### List Plugins Associated to a Specific Service + +
      /services/{service name or id}/plugins
      + +{:.indent} +Attributes | Description +---:| --- +`service name or id`
      **required** | The unique identifier or the `name` attribute of the Service whose Plugins are to be retrieved. When using this endpoint, only Plugins associated to the specified Service will be listed. + + +##### List Plugins Associated to a Specific Consumer + +
      /consumers/{consumer name or id}/plugins
      + +{:.indent} +Attributes | Description +---:| --- +`consumer name or id`
      **required** | The unique identifier or the `name` attribute of the Consumer whose Plugins are to be retrieved. When using this endpoint, only Plugins associated to the specified Consumer will be listed. + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{ +{{ page.plugin_data }} + "next": "http://localhost:8001/plugins?offset=6378122c-a0a1-438d-a5c6-efabae9fb969" +} +``` + + +--- + +### Retrieve Plugin +{:.badge .dbless} + +##### Retrieve Plugin + +
      /plugins/{plugin id}
      + +{:.indent} +Attributes | Description +---:| --- +`plugin id`
      **required** | The unique identifier of the Plugin to retrieve. + + +##### Retrieve Plugin Associated to a Specific Route + +
      /routes/{route name or id}/plugins/{plugin id}
      + +{:.indent} +Attributes | Description +---:| --- +`route name or id`
      **required** | The unique identifier **or** the name of the Route to retrieve. +`plugin id`
      **required** | The unique identifier of the Plugin to retrieve. + + +##### Retrieve Plugin Associated to a Specific Service + +
      /services/{service name or id}/plugins/{plugin id}
      + +{:.indent} +Attributes | Description +---:| --- +`service name or id`
      **required** | The unique identifier **or** the name of the Service to retrieve. +`plugin id`
      **required** | The unique identifier of the Plugin to retrieve. + + +##### Retrieve Plugin Associated to a Specific Consumer + +
      /consumers/{consumer username or id}/plugins/{plugin id}
      + +{:.indent} +Attributes | Description +---:| --- +`consumer username or id`
      **required** | The unique identifier **or** the username of the Consumer to retrieve. +`plugin id`
      **required** | The unique identifier of the Plugin to retrieve. + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{{ page.plugin_json }} +``` + + +--- + +### Update Plugin + + + +{:.note} +> **Note**: This API is not available in DB-less mode. + +##### Update Plugin + +
      /plugins/{plugin id}
      + +{:.indent} +Attributes | Description +---:| --- +`plugin id`
      **required** | The unique identifier of the Plugin to update. + + +##### Update Plugin Associated to a Specific Route + +
      /routes/{route name or id}/plugins/{plugin id}
      + +{:.indent} +Attributes | Description +---:| --- +`route name or id`
      **required** | The unique identifier **or** the name of the Route to update. +`plugin id`
      **required** | The unique identifier of the Plugin to update. + + +##### Update Plugin Associated to a Specific Service + +
      /services/{service name or id}/plugins/{plugin id}
      + +{:.indent} +Attributes | Description +---:| --- +`service name or id`
      **required** | The unique identifier **or** the name of the Service to update. +`plugin id`
      **required** | The unique identifier of the Plugin to update. + + +##### Update Plugin Associated to a Specific Consumer + +
      /consumers/{consumer username or id}/plugins/{plugin id}
      + +{:.indent} +Attributes | Description +---:| --- +`consumer username or id`
      **required** | The unique identifier **or** the username of the Consumer to update. +`plugin id`
      **required** | The unique identifier of the Plugin to update. + + +#### Request Body + +{{ page.plugin_body }} + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{{ page.plugin_json }} +``` + + +--- + +### Update Or Create Plugin + + + +{:.note} +> **Note**: This API is not available in DB-less mode. + +##### Create Or Update Plugin + +
      /plugins/{plugin id}
      + +{:.indent} +Attributes | Description +---:| --- +`plugin id`
      **required** | The unique identifier of the Plugin to create or update. + + +##### Create Or Update Plugin Associated to a Specific Route + +
      /routes/{route name or id}/plugins/{plugin id}
      + +{:.indent} +Attributes | Description +---:| --- +`route name or id`
      **required** | The unique identifier **or** the name of the Route to create or update. +`plugin id`
      **required** | The unique identifier of the Plugin to create or update. + + +##### Create Or Update Plugin Associated to a Specific Service + +
      /services/{service name or id}/plugins/{plugin id}
      + +{:.indent} +Attributes | Description +---:| --- +`service name or id`
      **required** | The unique identifier **or** the name of the Service to create or update. +`plugin id`
      **required** | The unique identifier of the Plugin to create or update. + + +##### Create Or Update Plugin Associated to a Specific Consumer + +
      /consumers/{consumer username or id}/plugins/{plugin id}
      + +{:.indent} +Attributes | Description +---:| --- +`consumer username or id`
      **required** | The unique identifier **or** the username of the Consumer to create or update. +`plugin id`
      **required** | The unique identifier of the Plugin to create or update. + + +#### Request Body + +{{ page.plugin_body }} + + +Inserts (or replaces) the Plugin under the requested resource with the +definition specified in the body. The Plugin will be identified via the `name +or id` attribute. + +When the `name or id` attribute has the structure of a UUID, the Plugin being +inserted/replaced will be identified by its `id`. Otherwise it will be +identified by its `name`. + +When creating a new Plugin without specifying `id` (neither in the URL nor in +the body), then it will be auto-generated. + +Notice that specifying a `name` in the URL and a different one in the request +body is not allowed. + + +#### Response + +``` + HTTP 200 OK +``` + +See POST and PATCH responses. + + +--- + +### Delete Plugin + + + +{:.note} +> **Note**: This API is not available in DB-less mode. + +##### Delete Plugin + +
      /plugins/{plugin id}
      + +{:.indent} +Attributes | Description +---:| --- +`plugin id`
      **required** | The unique identifier of the Plugin to delete. + + +##### Delete Plugin Associated to a Specific Route + +
      /routes/{route name or id}/plugins/{plugin id}
      + +{:.indent} +Attributes | Description +---:| --- +`route name or id`
      **required** | The unique identifier **or** the name of the Route to delete. +`plugin id`
      **required** | The unique identifier of the Plugin to delete. + + +##### Delete Plugin Associated to a Specific Service + +
      /services/{service name or id}/plugins/{plugin id}
      + +{:.indent} +Attributes | Description +---:| --- +`service name or id`
      **required** | The unique identifier **or** the name of the Service to delete. +`plugin id`
      **required** | The unique identifier of the Plugin to delete. + + +##### Delete Plugin Associated to a Specific Consumer + +
      /consumers/{consumer username or id}/plugins/{plugin id}
      + +{:.indent} +Attributes | Description +---:| --- +`consumer username or id`
      **required** | The unique identifier **or** the username of the Consumer to delete. +`plugin id`
      **required** | The unique identifier of the Plugin to delete. + + +#### Response + +``` +HTTP 204 No Content +``` + + +--- + +### Retrieve Enabled Plugins +{:.badge .dbless} + +Retrieve a list of all installed plugins on the Kong node. + +
      /plugins/enabled
      + +#### Response + +``` +HTTP 200 OK +``` + +```json +{ + "enabled_plugins": [ + "jwt", + "acl", + "cors", + "oauth2", + "tcp-log", + "udp-log", + "file-log", + "http-log", + "key-auth", + "hmac-auth", + "basic-auth", + "ip-restriction", + "request-transformer", + "response-transformer", + "request-size-limiting", + "rate-limiting", + "response-ratelimiting", + "aws-lambda", + "bot-detection", + "correlation-id", + "datadog", + "galileo", + "ldap-auth", + "loggly", + "statsd", + "syslog" + ] +} +``` + + +--- + +## Certificate Object + +A certificate object represents a public certificate, and can be optionally paired with the +corresponding private key. These objects are used by Kong to handle SSL/TLS termination for +encrypted requests, or for use as a trusted CA store when validating peer certificate of +client/service. Certificates are optionally associated with SNI objects to +tie a cert/key pair to one or more hostnames. + +If intermediate certificates are required in addition to the main +certificate, they should be concatenated together into one string according to +the following order: main certificate on the top, followed by any intermediates. + +Certificates can be both [tagged and filtered by tags](#tags). + + +```json +{{ page.certificate_json }} +``` + +### Add Certificate + + + +{:.note} +> **Note**: This API is not available in DB-less mode. + +##### Create Certificate + +
      /certificates
      + + +#### Request Body + +{{ page.certificate_body }} + + +#### Response + +``` +HTTP 201 Created +``` + +```json +{{ page.certificate_json }} +``` + + +--- + +### List Certificates +{:.badge .dbless} + +##### List All Certificates + +
      /certificates
      + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{ +{{ page.certificate_data }} + "next": "http://localhost:8001/certificates?offset=6378122c-a0a1-438d-a5c6-efabae9fb969" +} +``` + + +--- + +### Retrieve Certificate +{:.badge .dbless} + +##### Retrieve Certificate + +
      /certificates/{certificate id}
      + +{:.indent} +Attributes | Description +---:| --- +`certificate id`
      **required** | The unique identifier of the Certificate to retrieve. + + +##### Retrieve Certificate Associated to a Specific Upstream + +
      /upstreams/{upstream name or id}/client_certificate
      + +{:.indent} +Attributes | Description +---:| --- +`upstream name or id`
      **required** | The unique identifier **or** the name of the Upstream associated to the Certificate to be retrieved. + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{{ page.certificate_json }} +``` + + +--- + +### Update Certificate + + + +{:.note} +> **Note**: This API is not available in DB-less mode. + +##### Update Certificate + +
      /certificates/{certificate id}
      + +{:.indent} +Attributes | Description +---:| --- +`certificate id`
      **required** | The unique identifier of the Certificate to update. + + +##### Update Certificate Associated to a Specific Upstream + +
      /upstreams/{upstream name or id}/client_certificate
      + +{:.indent} +Attributes | Description +---:| --- +`upstream name or id`
      **required** | The unique identifier **or** the name of the Upstream associated to the Certificate to be updated. + + +#### Request Body + +{{ page.certificate_body }} + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{{ page.certificate_json }} +``` + + +--- + +### Update Or Create Certificate + + + +{:.note} +> **Note**: This API is not available in DB-less mode. + +##### Create Or Update Certificate + +
      /certificates/{certificate id}
      + +{:.indent} +Attributes | Description +---:| --- +`certificate id`
      **required** | The unique identifier of the Certificate to create or update. + + +##### Create Or Update Certificate Associated to a Specific Upstream + +
      /upstreams/{upstream name or id}/client_certificate
      + +{:.indent} +Attributes | Description +---:| --- +`upstream name or id`
      **required** | The unique identifier **or** the name of the Upstream associated to the Certificate to be created or updated. + + +#### Request Body + +{{ page.certificate_body }} + + +Inserts (or replaces) the Certificate under the requested resource with the +definition specified in the body. The Certificate will be identified via the `name +or id` attribute. + +When the `name or id` attribute has the structure of a UUID, the Certificate being +inserted/replaced will be identified by its `id`. Otherwise it will be +identified by its `name`. + +When creating a new Certificate without specifying `id` (neither in the URL nor in +the body), then it will be auto-generated. + +Notice that specifying a `name` in the URL and a different one in the request +body is not allowed. + + +#### Response + +``` +HTTP 200 OK +``` + +See POST and PATCH responses. + + +--- + +### Delete Certificate + + + +{:.note} +> **Note**: This API is not available in DB-less mode. + +##### Delete Certificate + +
      /certificates/{certificate id}
      + +{:.indent} +Attributes | Description +---:| --- +`certificate id`
      **required** | The unique identifier of the Certificate to delete. + + +##### Delete Certificate Associated to a Specific Upstream + +
      /upstreams/{upstream name or id}/client_certificate
      + +{:.indent} +Attributes | Description +---:| --- +`upstream name or id`
      **required** | The unique identifier **or** the name of the Upstream associated to the Certificate to be deleted. + + +#### Response + +``` +HTTP 204 No Content +``` + + +--- + +## CA Certificate Object + +A CA certificate object represents a trusted CA. These objects are used by Kong to +verify the validity of a client or server certificate. + +CA Certificates can be both [tagged and filtered by tags](#tags). + + +```json +{{ page.ca_certificate_json }} +``` + +### Add CA Certificate + + + +{:.note} +> **Note**: This API is not available in DB-less mode. + +##### Create CA Certificate + +
      /ca_certificates
      + + +#### Request Body + +{{ page.ca_certificate_body }} + + +#### Response + +``` +HTTP 201 Created +``` + +```json +{{ page.ca_certificate_json }} +``` + + +--- + +### List CA Certificates +{:.badge .dbless} + +##### List All CA Certificates + +
      /ca_certificates
      + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{ +{{ page.ca_certificate_data }} + "next": "http://localhost:8001/ca_certificates?offset=6378122c-a0a1-438d-a5c6-efabae9fb969" +} +``` + + +--- + +### Retrieve CA Certificate +{:.badge .dbless} + +##### Retrieve CA Certificate + +
      /ca_certificates/{ca_certificate id}
      + +{:.indent} +Attributes | Description +---:| --- +`ca_certificate id`
      **required** | The unique identifier of the CA Certificate to retrieve. + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{{ page.ca_certificate_json }} +``` + + +--- + +### Update CA Certificate + + + +{:.note} +> **Note**: This API is not available in DB-less mode. + +##### Update CA Certificate + +
      /ca_certificates/{ca_certificate id}
      + +{:.indent} +Attributes | Description +---:| --- +`ca_certificate id`
      **required** | The unique identifier of the CA Certificate to update. + + +#### Request Body + +{{ page.ca_certificate_body }} + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{{ page.ca_certificate_json }} +``` + + +--- + +### Update Or Create CA Certificate + + + +{:.note} +> **Note**: This API is not available in DB-less mode. + +##### Create Or Update CA Certificate + +
      /ca_certificates/{ca_certificate id}
      + +{:.indent} +Attributes | Description +---:| --- +`ca_certificate id`
      **required** | The unique identifier of the CA Certificate to create or update. + + +#### Request Body + +{{ page.ca_certificate_body }} + + +Inserts (or replaces) the CA Certificate under the requested resource with the +definition specified in the body. The CA Certificate will be identified via the `name +or id` attribute. + +When the `name or id` attribute has the structure of a UUID, the CA Certificate being +inserted/replaced will be identified by its `id`. Otherwise it will be +identified by its `name`. + +When creating a new CA Certificate without specifying `id` (neither in the URL nor in +the body), then it will be auto-generated. + +Notice that specifying a `name` in the URL and a different one in the request +body is not allowed. + + +#### Response + +``` +HTTP 200 OK +``` + +See POST and PATCH responses. + + +--- + +### Delete CA Certificate + + + +{:.note} +> **Note**: This API is not available in DB-less mode. + +##### Delete CA Certificate + +
      /ca_certificates/{ca_certificate id}
      + +{:.indent} +Attributes | Description +---:| --- +`ca_certificate id`
      **required** | The unique identifier of the CA Certificate to delete. + + +#### Response + +``` +HTTP 204 No Content +``` + + +--- + +## SNI Object + +An SNI object represents a many-to-one mapping of hostnames to a certificate. +That is, a certificate object can have many hostnames associated with it; when +Kong receives an SSL request, it uses the SNI field in the Client Hello to +lookup the certificate object based on the SNI associated with the certificate. + +SNIs can be both [tagged and filtered by tags](#tags). + + +```json +{{ page.sni_json }} +``` + +### Add SNI + + + +{:.note} +> **Note**: This API is not available in DB-less mode. + +##### Create SNI + +
      /snis
      + + +##### Create SNI Associated to a Specific Certificate + +
      /certificates/{certificate name or id}/snis
      + +{:.indent} +Attributes | Description +---:| --- +`certificate name or id`
      **required** | The unique identifier or the `name` attribute of the Certificate that should be associated to the newly-created SNI. + + +#### Request Body + +{{ page.sni_body }} + + +#### Response + +``` +HTTP 201 Created +``` + +```json +{{ page.sni_json }} +``` + + +--- + +### List SNIs +{:.badge .dbless} + +##### List All SNIs + +
      /snis
      + + +##### List SNIs Associated to a Specific Certificate + +
      /certificates/{certificate name or id}/snis
      + +{:.indent} +Attributes | Description +---:| --- +`certificate name or id`
      **required** | The unique identifier or the `name` attribute of the Certificate whose SNIs are to be retrieved. When using this endpoint, only SNIs associated to the specified Certificate will be listed. + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{ +{{ page.sni_data }} + "next": "http://localhost:8001/snis?offset=6378122c-a0a1-438d-a5c6-efabae9fb969" +} +``` + + +--- + +### Retrieve SNI +{:.badge .dbless} + +##### Retrieve SNI + +
      /snis/{sni name or id}
      + +{:.indent} +Attributes | Description +---:| --- +`sni name or id`
      **required** | The unique identifier **or** the name of the SNI to retrieve. + + +##### Retrieve SNI Associated to a Specific Certificate + +
      /certificates/{certificate id}/snis/{sni name or id}
      + +{:.indent} +Attributes | Description +---:| --- +`certificate id`
      **required** | The unique identifier of the Certificate to retrieve. +`sni name or id`
      **required** | The unique identifier **or** the name of the SNI to retrieve. + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{{ page.sni_json }} +``` + + +--- + +### Update SNI + + + +{:.note} +> **Note**: This API is not available in DB-less mode. + +##### Update SNI + +
      /snis/{sni name or id}
      + +{:.indent} +Attributes | Description +---:| --- +`sni name or id`
      **required** | The unique identifier **or** the name of the SNI to update. + + +##### Update SNI Associated to a Specific Certificate + +
      /certificates/{certificate id}/snis/{sni name or id}
      + +{:.indent} +Attributes | Description +---:| --- +`certificate id`
      **required** | The unique identifier of the Certificate to update. +`sni name or id`
      **required** | The unique identifier **or** the name of the SNI to update. + + +#### Request Body + +{{ page.sni_body }} + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{{ page.sni_json }} +``` + + +--- + +### Update Or Create SNI + + + +{:.note} +> **Note**: This API is not available in DB-less mode. + +##### Create Or Update SNI + +
      /snis/{sni name or id}
      + +{:.indent} +Attributes | Description +---:| --- +`sni name or id`
      **required** | The unique identifier **or** the name of the SNI to create or update. + + +##### Create Or Update SNI Associated to a Specific Certificate + +
      /certificates/{certificate id}/snis/{sni name or id}
      + +{:.indent} +Attributes | Description +---:| --- +`certificate id`
      **required** | The unique identifier of the Certificate to create or update. +`sni name or id`
      **required** | The unique identifier **or** the name of the SNI to create or update. + + +#### Request Body + +{{ page.sni_body }} + + +Inserts (or replaces) the SNI under the requested resource with the +definition specified in the body. The SNI will be identified via the `name +or id` attribute. + +When the `name or id` attribute has the structure of a UUID, the SNI being +inserted/replaced will be identified by its `id`. Otherwise it will be +identified by its `name`. + +When creating a new SNI without specifying `id` (neither in the URL nor in +the body), then it will be auto-generated. + +Notice that specifying a `name` in the URL and a different one in the request +body is not allowed. + + +#### Response + +``` +HTTP 200 OK +``` + +See POST and PATCH responses. + + +--- + +### Delete SNI + + + +{:.note} +> **Note**: This API is not available in DB-less mode. + +##### Delete SNI + +
      /snis/{sni name or id}
      + +{:.indent} +Attributes | Description +---:| --- +`sni name or id`
      **required** | The unique identifier **or** the name of the SNI to delete. + + +##### Delete SNI Associated to a Specific Certificate + +
      /certificates/{certificate id}/snis/{sni name or id}
      + +{:.indent} +Attributes | Description +---:| --- +`certificate id`
      **required** | The unique identifier of the Certificate to delete. +`sni name or id`
      **required** | The unique identifier **or** the name of the SNI to delete. + + +#### Response + +``` +HTTP 204 No Content +``` + + +--- + +## Upstream Object + +The upstream object represents a virtual hostname and can be used to load balance +incoming requests over multiple services (targets). So for example an upstream +named `service.v1.xyz` for a Service object whose `host` is `service.v1.xyz`. +Requests for this Service would be proxied to the targets defined within the upstream. + +An upstream also includes a [health checker][healthchecks], which is able to +enable and disable targets based on their ability or inability to serve +requests. The configuration for the health checker is stored in the upstream +object, and applies to all of its targets. + +Upstreams can be both [tagged and filtered by tags](#tags). + + +```json +{{ page.upstream_json }} +``` + +### Add Upstream + + + +{:.note} +> **Note**: This API is not available in DB-less mode. + +##### Create Upstream + +
      /upstreams
      + + +##### Create Upstream Associated to a Specific Certificate + +
      /certificates/{certificate name or id}/upstreams
      + +{:.indent} +Attributes | Description +---:| --- +`certificate name or id`
      **required** | The unique identifier or the `name` attribute of the Certificate that should be associated to the newly-created Upstream. + + +#### Request Body + +{{ page.upstream_body }} + + +#### Response + +``` +HTTP 201 Created +``` + +```json +{{ page.upstream_json }} +``` + + +--- + +### List Upstreams +{:.badge .dbless} + +##### List All Upstreams + +
      /upstreams
      + + +##### List Upstreams Associated to a Specific Certificate + +
      /certificates/{certificate name or id}/upstreams
      + +{:.indent} +Attributes | Description +---:| --- +`certificate name or id`
      **required** | The unique identifier or the `name` attribute of the Certificate whose Upstreams are to be retrieved. When using this endpoint, only Upstreams associated to the specified Certificate will be listed. + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{ +{{ page.upstream_data }} + "next": "http://localhost:8001/upstreams?offset=6378122c-a0a1-438d-a5c6-efabae9fb969" +} +``` + + +--- + +### Retrieve Upstream +{:.badge .dbless} + +##### Retrieve Upstream + +
      /upstreams/{upstream name or id}
      + +{:.indent} +Attributes | Description +---:| --- +`upstream name or id`
      **required** | The unique identifier **or** the name of the Upstream to retrieve. + + +##### Retrieve Upstream Associated to a Specific Certificate + +
      /certificates/{certificate id}/upstreams/{upstream name or id}
      + +{:.indent} +Attributes | Description +---:| --- +`certificate id`
      **required** | The unique identifier of the Certificate to retrieve. +`upstream name or id`
      **required** | The unique identifier **or** the name of the Upstream to retrieve. + +#### Response + +``` +HTTP 200 OK +``` + +```json +{{ page.upstream_json }} +``` + + +--- + +### Update Upstream + + + +{:.note} +> **Note**: This API is not available in DB-less mode. + +##### Update Upstream + +
      /upstreams/{upstream name or id}
      + +{:.indent} +Attributes | Description +---:| --- +`upstream name or id`
      **required** | The unique identifier **or** the name of the Upstream to update. + + +##### Update Upstream Associated to a Specific Certificate + +
      /certificates/{certificate id}/upstreams/{upstream name or id}
      + +{:.indent} +Attributes | Description +---:| --- +`certificate id`
      **required** | The unique identifier of the Certificate to update. +`upstream name or id`
      **required** | The unique identifier **or** the name of the Upstream to update. + +#### Request Body + +{{ page.upstream_body }} + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{{ page.upstream_json }} +``` + + +--- + +### Update Or Create Upstream + + + +{:.note} +> **Note**: This API is not available in DB-less mode. + +##### Create Or Update Upstream + +
      /upstreams/{upstream name or id}
      + +{:.indent} +Attributes | Description +---:| --- +`upstream name or id`
      **required** | The unique identifier **or** the name of the Upstream to create or update. + + +##### Create Or Update Upstream Associated to a Specific Certificate + +
      /certificates/{certificate id}/upstreams/{upstream name or id}
      + +{:.indent} +Attributes | Description +---:| --- +`certificate id`
      **required** | The unique identifier of the Certificate to create or update. +`upstream name or id`
      **required** | The unique identifier **or** the name of the Upstream to create or update. + +#### Request Body + +{{ page.upstream_body }} + + +Inserts (or replaces) the Upstream under the requested resource with the +definition specified in the body. The Upstream will be identified via the `name +or id` attribute. + +When the `name or id` attribute has the structure of a UUID, the Upstream being +inserted/replaced will be identified by its `id`. Otherwise it will be +identified by its `name`. + +When creating a new Upstream without specifying `id` (neither in the URL nor in +the body), then it will be auto-generated. + +Notice that specifying a `name` in the URL and a different one in the request +body is not allowed. + + +#### Response + +``` +HTTP 200 OK +``` + +See POST and PATCH responses. + + +--- + +### Delete Upstream + + + +{:.note} +> **Note**: This API is not available in DB-less mode. + +##### Delete Upstream + +
      /upstreams/{upstream name or id}
      + +{:.indent} +Attributes | Description +---:| --- +`upstream name or id`
      **required** | The unique identifier **or** the name of the Upstream to delete. + + +##### Delete Upstream Associated to a Specific Certificate + +
      /certificates/{certificate id}/upstreams/{upstream name or id}
      + +{:.indent} +Attributes | Description +---:| --- +`certificate id`
      **required** | The unique identifier of the Certificate to delete. +`upstream name or id`
      **required** | The unique identifier **or** the name of the Upstream to delete. + +#### Response + +``` +HTTP 204 No Content +``` + + +--- + +### Show Upstream Health for Node +{:.badge .dbless} + +Displays the health status for all Targets of a given Upstream, or for +the whole Upstream, according to the perspective of a specific Kong node. +Note that, being node-specific information, making this same request +to different nodes of the Kong cluster may produce different results. +For example, one specific node of the Kong cluster may be experiencing +network issues, causing it to fail to connect to some Targets: these +Targets will be marked as unhealthy by that node (directing traffic from +this node to other Targets that it can successfully reach), but healthy +to all others Kong nodes (which have no problems using that Target). + +The `data` field of the response contains an array of Target objects. +The health for each Target is returned in its `health` field: + +* If a Target fails to be activated in the balancer due to DNS issues, + its status displays as `DNS_ERROR`. +* When [health checks][healthchecks] are not enabled in the Upstream + configuration, the health status for active Targets is displayed as + `HEALTHCHECKS_OFF`. +* When health checks are enabled and the Target is determined to be healthy, + either automatically or [manually](#set-target-as-healthy), + its status is displayed as `HEALTHY`. This means that this Target is + currently included in this Upstream's load balancer execution. +* When a Target has been disabled by either active or passive health checks + (circuit breakers) or [manually](#set-target-as-unhealthy), + its status is displayed as `UNHEALTHY`. The load balancer is not directing + any traffic to this Target via this Upstream. + +When the request query parameter `balancer_health` is set to `1`, the +`data` field of the response refers to the Upstream itself, and its `health` +attribute is defined by the state of all of Upstream's Targets, according +to the field `healthchecks.threshold`. + + +
      /upstreams/{name or id}/health/
      + +{:.indent} +Attributes | Description +---:| --- +`name or id`
      **required** | The unique identifier **or** the name of the Upstream for which to display Target health. + + +#### Request Querystring Parameters + +Attributes | Description +---:| --- +`balancer_health`
      *optional* | If set to 1, Kong will return the health status of the Upstream itself. See the `healthchecks.threshold` property. + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{ + "total": 2, + "node_id": "cbb297c0-14a9-46bc-ad91-1d0ef9b42df9", + "data": [ + { + "created_at": 1485524883980, + "id": "18c0ad90-f942-4098-88db-bbee3e43b27f", + "health": "HEALTHY", + "target": "127.0.0.1:20000", + "upstream_id": "07131005-ba30-4204-a29f-0927d53257b4", + "weight": 100 + }, + { + "created_at": 1485524914883, + "id": "6c6f34eb-e6c3-4c1f-ac58-4060e5bca890", + "health": "UNHEALTHY", + "target": "127.0.0.1:20002", + "upstream_id": "07131005-ba30-4204-a29f-0927d53257b4", + "weight": 200 + } + ] +} +``` + +If `balancer_health=1`: +``` +HTTP 200 OK +``` + +```json +{ + "data": { + "health": "HEALTHY", + "id": "07131005-ba30-4204-a29f-0927d53257b4" + }, + "next": null, + "node_id": "cbb297c0-14a9-46bc-ad91-1d0ef9b42df9" +} +``` + + +--- + +## Target Object + +A target is an ip address/hostname with a port that identifies an instance of a backend +service. Every upstream can have many targets, and the targets can be +dynamically added, modified, or deleted. Changes take effect on the fly. + +To disable a target, post a new one with `weight=0`; +alternatively, use the `DELETE` convenience method to accomplish the same. + +The current target object definition is the one with the latest `created_at`. + +Targets can be both [tagged and filtered by tags](#tags). + + +```json +{{ page.target_json }} +``` + +--- + +### Update Target + + + +{:.note} +> **Note**: This API is not available in DB-less mode. + +Update a target. + + +
      /upstreams/{upstream name or id}/targets/{host:port or id}
      + +{:.indent} +Attributes | Description +---:| --- +`upstream name or id`
      **required** | The unique identifier **or** the name of the upstream for which to update the target. +`host:port or id`
      **required** | The host:port combination element of the target to update, or the `id` of an existing target entry. + + +#### Response + +``` +HTTP 201 Created +``` + + +--- + +### Delete Target + + + +{:.note} +> **Note**: This API is not available in DB-less mode. + +Remove a target from the load balancer. + + +
      /upstreams/{upstream name or id}/targets/{host:port or id}
      + +{:.indent} +Attributes | Description +---:| --- +`upstream name or id`
      **required** | The unique identifier **or** the name of the upstream for which to delete the target. +`host:port or id`
      **required** | The host:port combination element of the target to remove, or the `id` of an existing target entry. + + +#### Response + +``` +HTTP 204 No Content +``` + + +--- + +### Set Target Address As Healthy + + + +{:.note} +> **Note**: This API is not available in DB-less mode. + +Set the current health status of an individual address resolved by a target +in the load balancer to "healthy" in the entire Kong cluster. + +This endpoint can be used to manually re-enable an address resolved by a +target that was previously disabled by the upstream's [health checker][healthchecks]. +Upstreams only forward requests to healthy nodes, so this call tells Kong +to start using this address again. + +This resets the health counters of the health checkers running in all workers +of the Kong node, and broadcasts a cluster-wide message so that the "healthy" +status is propagated to the whole Kong cluster. + +Note: This API is not available when Kong is running in hybrid mode. + +
      /upstreams/{upstream name or id}/targets/{target or id}/{address}/healthy
      + +{:.indent} +Attributes | Description +---:| --- +`upstream name or id`
      **required** | The unique identifier **or** the name of the upstream. +`target or id`
      **required** | The host/port combination element of the target to set as healthy, or the `id` of an existing target entry. +`address`
      **required** | The host/port combination element of the address to set as healthy. + + +#### Response + +``` +HTTP 204 No Content +``` + + +--- + +### Set Target Address As Unhealthy + + + +{:.note} +> **Note**: This API is not available in DB-less mode. + +Set the current health status of an individual address resolved by a target +in the load balancer to "unhealthy" in the entire Kong cluster. + +This endpoint can be used to manually disable an address and have it stop +responding to requests. Upstreams only forward requests to healthy nodes, so +this call tells Kong to start skipping this address. + +This call resets the health counters of the health checkers running in all +workers of the Kong node, and broadcasts a cluster-wide message so that the +"unhealthy" status is propagated to the whole Kong cluster. + +[Active health checks][active] continue to execute for unhealthy +addresses. Note that if active health checks are enabled and the probe detects +that the address is actually healthy, it will automatically re-enable it again. +To permanently remove a target from the balancer, you should [delete a +target](#delete-target) instead. + +Note: This API is not available when Kong is running in hybrid mode. + +
      /upstreams/{upstream name or id}/targets/{target or id}/unhealthy
      + +{:.indent} +Attributes | Description +---:| --- +`upstream name or id`
      **required** | The unique identifier **or** the name of the upstream. +`target or id`
      **required** | The host/port combination element of the target to set as unhealthy, or the `id` of an existing target entry. + + +#### Response + +``` +HTTP 204 No Content +``` + + +--- + +### Set Target As Healthy +{:.badge .dbless} + +Set the current health status of a target in the load balancer to "healthy" +in the entire Kong cluster. This sets the "healthy" status to all addresses +resolved by this target. + +This endpoint can be used to manually re-enable a target that was previously +disabled by the upstream's [health checker][healthchecks]. Upstreams only +forward requests to healthy nodes, so this call tells Kong to start using this +target again. + +This resets the health counters of the health checkers running in all workers +of the Kong node, and broadcasts a cluster-wide message so that the "healthy" +status is propagated to the whole Kong cluster. + +Note: This API is not available when Kong is running in hybrid mode. + +
      /upstreams/{upstream name or id}/targets/{target or id}/healthy
      + +{:.indent} +Attributes | Description +---:| --- +`upstream name or id`
      **required** | The unique identifier **or** the name of the upstream. +`target or id`
      **required** | The host/port combination element of the target to set as healthy, or the `id` of an existing target entry. + + +#### Response + +``` +HTTP 204 No Content +``` + + +--- + +### Set Target As Unhealthy +{:.badge .dbless} + +Set the current health status of a target in the load balancer to "unhealthy" +in the entire Kong cluster. This sets the "unhealthy" status to all addresses +resolved by this target. + +This endpoint can be used to manually disable a target and have it stop +responding to requests. Upstreams only forward requests to healthy nodes, so +this call tells Kong to start skipping this target. + +This call resets the health counters of the health checkers running in all +workers of the Kong node, and broadcasts a cluster-wide message so that the +"unhealthy" status is propagated to the whole Kong cluster. + +[Active health checks][active] continue to execute for unhealthy +targets. Note that if active health checks are enabled and the probe detects +that the target is actually healthy, it will automatically re-enable it again. +To permanently remove a target from the balancer, you should [delete a +target](#delete-target) instead. + +Note: This API is not available when Kong is running in hybrid mode. + +
      /upstreams/{upstream name or id}/targets/{target or id}/unhealthy
      + +{:.indent} +Attributes | Description +---:| --- +`upstream name or id`
      **required** | The unique identifier **or** the name of the upstream. +`target or id`
      **required** | The host/port combination element of the target to set as unhealthy, or the `id` of an existing target entry. + + +#### Response + +``` +HTTP 204 No Content +``` + + +--- + +### List All Targets +{:.badge .dbless} + +Lists all targets of the upstream. Multiple target objects for the same +target may be returned, showing the history of changes for a specific target. +The target object with the latest `created_at` is the current definition. + + +
      /upstreams/{name or id}/targets/all/
      + +{:.indent} +Attributes | Description +---:| --- +`name or id`
      **required** | The unique identifier **or** the name of the upstream for which to list the targets. + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{ + "total": 2, + "data": [ + { + "created_at": 1485524883980, + "id": "18c0ad90-f942-4098-88db-bbee3e43b27f", + "target": "127.0.0.1:20000", + "upstream_id": "07131005-ba30-4204-a29f-0927d53257b4", + "weight": 100 + }, + { + "created_at": 1485524914883, + "id": "6c6f34eb-e6c3-4c1f-ac58-4060e5bca890", + "target": "127.0.0.1:20002", + "upstream_id": "07131005-ba30-4204-a29f-0927d53257b4", + "weight": 200 + } + ] +} +``` + + +--- + +## Vaults Entity + +Vault entities are used to configure different Vault connectors. Examples of +Vaults are Environment Variables, Hashicorp Vault and AWS Secrets Manager. + +Configuring a Vault allows referencing the secrets with other entities. For +example a certificate entity can store a reference to a certificate and key, +stored in a vault, instead of storing the certificate and key within the +entity. This allows a proper separation of secrets and configuration and +prevents secret sprawl. + +Vaults can be both [tagged and filtered by tags](#tags). + + +```json +{{ page.vault_json }} +``` + +### Add Vault + + + +{:.note} +> **Note**: This API is not available in DB-less mode. + +##### Create Vault + +
      /vaults
      + + +#### Request Body + +{{ page.vault_body }} + + +#### Response + +``` +HTTP 201 Created +``` + +```json +{{ page.vault_json }} +``` + + +--- + +### List Vaults +{:.badge .dbless} + +##### List All Vaults + +
      /vaults
      + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{ +{{ page.vault_data }} + "next": "http://localhost:8001/vaults?offset=6378122c-a0a1-438d-a5c6-efabae9fb969" +} +``` + + +--- + +### Retrieve Vault +{:.badge .dbless} + +##### Retrieve Vault + +
      /vaults/{vault prefix or id}
      + +{:.indent} +Attributes | Description +---:| --- +`vault prefix or id`
      **required** | The unique identifier **or** the prefix of the Vault to retrieve. + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{{ page.vault_json }} +``` + + +--- + +### Update Vault + + + +{:.note} +> **Note**: This API is not available in DB-less mode. + +##### Update Vault + +
      /vaults/{vault prefix or id}
      + +{:.indent} +Attributes | Description +---:| --- +`vault prefix or id`
      **required** | The unique identifier **or** the prefix of the Vault to update. + + +#### Request Body + +{{ page.vault_body }} + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{{ page.vault_json }} +``` + + +--- + +### Update Or Create Vault + + + +{:.note} +> **Note**: This API is not available in DB-less mode. + +##### Create Or Update Vault + +
      /vaults/{vault prefix or id}
      + +{:.indent} +Attributes | Description +---:| --- +`vault prefix or id`
      **required** | The unique identifier **or** the prefix of the Vault to create or update. + + +#### Request Body + +{{ page.vault_body }} + + +Inserts (or replaces) the Vault under the requested resource with the +definition specified in the body. The Vault will be identified via the `prefix +or id` attribute. + +When the `prefix or id` attribute has the structure of a UUID, the Vault being +inserted/replaced will be identified by its `id`. Otherwise it will be +identified by its `prefix`. + +When creating a new Vault without specifying `id` (neither in the URL nor in +the body), then it will be auto-generated. + +Notice that specifying a `prefix` in the URL and a different one in the request +body is not allowed. + + +#### Response + +``` +HTTP 200 OK +``` + +See POST and PATCH responses. + + +--- + +### Delete Vault + + + +{:.note} +> **Note**: This API is not available in DB-less mode. + +##### Delete Vault + +
      /vaults/{vault prefix or id}
      + +{:.indent} +Attributes | Description +---:| --- +`vault prefix or id`
      **required** | The unique identifier **or** the prefix of the Vault to delete. + + +#### Response + +``` +HTTP 204 No Content +``` + + +--- + +[clustering]: /gateway/{{page.kong_version}}/production/clustering +[cli]: /gateway/{{page.kong_version}}/reference/cli +[active]: /gateway/{{page.kong_version}}/how-kong-works/health-checks/#active-health-checks +[healthchecks]: /gateway/{{page.kong_version}}/how-kong-works/health-checks +[secure-admin-api]: /gateway/{{page.kong_version}}/production/running-kong/secure-admin-api +[proxy-reference]: /gateway/{{page.kong_version}}/how-kong-works/routing-traffic/ diff --git a/src/gateway/admin-api/licenses/reference.md b/src/gateway/admin-api/licenses/reference.md new file mode 100644 index 000000000000..b874aa1f5b26 --- /dev/null +++ b/src/gateway/admin-api/licenses/reference.md @@ -0,0 +1,277 @@ +--- +title: Licenses Reference +badge: enterprise + +licenses_attribute_id: | + Attributes | Description + ---:| --- + `id` | The **license's** unique ID. + +licenses_body: | + Attribute | Description + ---:| --- + `payload` | The **Kong Gateway license** in JSON format. +--- + +The {{site.base_gateway}} Licenses feature is configurable through the +[Admin API]. This feature lets you configure a license in your +{{site.base_gateway}} cluster, in both traditional and hybrid mode deployments. +In hybrid mode deployments, the control plane sends licenses configured +through the `/licenses` endpoint to all data planes in the cluster. The data +planes use the most recent `updated_at` license. + +## List licenses +**Endpoint** + +
      /licenses/
      + +**Response** + +``` +HTTP 200 OK +``` + +```json +{ + "data": [ + { + "payload": "{\"license\":{\"payload\":{\"admin_seats\":\"1\",\"customer\":\"Example Company, Inc\",\"dataplanes\":\"1\",\"license_creation_date\":\"2017-07-20\",\"license_expiration_date\":\"2017-07-20\",\"license_key\":\"00141000017ODj3AAG_a1V41000004wT0OEAU\",\"product_subscription\":\"Konnect Enterprise\",\"support_plan\":\"None\"},\"signature\":\"6985968131533a967fcc721244a979948b1066967f1e9cd65dbd8eeabe060fc32d894a2945f5e4a03c1cd2198c74e058ac63d28b045c2f1fcec95877bd790e1b\",\"version\":\"1\"}}", + "created_at": 1500508800, + "id": "30b4edb7-0847-4f65-af90-efbed8b0161f", + "updated_at": 1500508800 + }, + ], + "next": null, +} +``` + +If there are no licenses stored by {{site.base_gateway}}, the data array will +be empty. + +```json +{ + "data": [], + "next": null +} +``` + +## List a specific license + +**Endpoint** + +
      /licenses/{id}
      + +{{ page.licenses_attribute_id }} + +**Response** + +``` +HTTP 200 OK +``` + +```json +{ + "created_at": 1500508800, + "id": "30b4edb7-0847-4f65-af90-efbed8b0161f", + "payload": "{\"license\":{\"payload\":{\"admin_seats\":\"1\",\"customer\":\"Example Company, Inc\",\"dataplanes\":\"1\",\"license_creation_date\":\"2017-07-20\",\"license_expiration_date\":\"2017-07-21\",\"license_key\":\"00141000017ODj3AAG_a1V41000004wT0OEAU\",\"product_subscription\":\"Konnect Enterprise\",\"support_plan\":\"None\"},\"signature\":\"24cc21223633044c15c300be19cacc26ccc5aca0dd9a12df8a7324a1970fe304bc07b8dcd7fb08d7b92e04169313377ae3b550ead653b951bc44cd2eb59f6beb\",\"version\":\"1\"}}", + "updated_at": 1500508800 +} +``` + +## Add a license + +To create a license using an auto-generated UUID: + +**Endpoint** + +
      /licenses/
      + +**Request Body** + +{{ page.licenses_body }} + +When using `POST`, if the request payload **does** +contain a valid {{site.base_gateway}} license, the license will be added. + +If the request payload **does not** contain a valid licence, a `400 BAD REQUEST` +will be returned. + +**Response** + +``` +HTTP 201 Created +``` + +```json +{ + "created_at": 1500508800, + "id": "30b4edb7-0847-4f65-af90-efbed8b0161f", + "payload": "{\"license\":{\"payload\":{\"admin_seats\":\"1\",\"customer\":\"Example Company, Inc\",\"dataplanes\":\"1\",\"license_creation_date\":\"2017-07-20\",\"license_expiration_date\":\"2017-07-20\",\"license_key\":\"00141000017ODj3AAG_a1V41000004wT0OEAU\",\"product_subscription\":\"Konnect Enterprise\",\"support_plan\":\"None\"},\"signature\":\"6985968131533a967fcc721244a979948b1066967f1e9cd65dbd8eeabe060fc32d894a2945f5e4a03c1cd2198c74e058ac63d28b045c2f1fcec95877bd790e1b\",\"version\":\"1\"}}", + "updated_at": 1500508800 +} +``` + +## Update or add a license + +**Endpoint** + +
      /licenses/{id}
      + +{{ page.licenses_attribute_id }} + +When using `PUT`, if the request payload +**does not** contain an entity's primary key (`id` for licenses), the +license will be added and assigned the given ID. + +If the request payload +**does** contain an entity's primary key (`id` for Licenses), the license +will be replaced with the given payload attribute. +If the ID is not a valid UUID, a `400 BAD REQUEST` will be returned. If the ID +is omitted, a `405 NOT ALLOWED` will be returned. + +**Request Body** + +{{ page.licenses_body }} + +**Response** + +``` +HTTP 200 OK +``` + +```json +{ + "created_at": 1500508800, + "id": "e8201120-4ee3-43ca-9e92-3fed08b1a15d", + "payload": "{\"license\":{\"payload\":{\"admin_seats\":\"1\",\"customer\":\"Example Company, Inc\",\"dataplanes\":\"1\",\"license_creation_date\":\"2017-07-20\",\"license_expiration_date\":\"2017-07-20\",\"license_key\":\"00141000017ODj3AAG_a1V41000004wT0OEAU\",\"product_subscription\":\"Konnect Enterprise\",\"support_plan\":\"None\"},\"signature\":\"6985968131533a967fcc721244a979948b1066967f1e9cd65dbd8eeabe060fc32d894a2945f5e4a03c1cd2198c74e058ac63d28b045c2f1fcec95877bd790e1b\",\"version\":\"1\"}}", + "updated_at": 1500508800 +} +``` + +## Update a license + +**Endpoint** + +
      /licenses/{id}
      + +{{ page.licenses_attribute_id }} + +When using `PATCH`, if the request payload +**does** contain an entity's primary key (`id` for licenses), the license will +be replaced with the given payload attribute. + +If the request payload **does +not** contain an entity's primary key (`id` for licenses), a `404 NOT FOUND` +will be returned or if the request payload contains a invalid licence, a `400 +BAD REQUEST` will be returned. + +**Request Body** + +{{ page.licenses_body }} + +**Response** + +``` +HTTP 200 OK +``` + +```json +{ + "created_at": 1500595200, + "id": "30b4edb7-0847-4f65-af90-efbed8b0161f", + "payload": "{\"license\":{\"payload\":{\"admin_seats\":\"1\",\"customer\":\"Example Company, Inc\",\"dataplanes\":\"1\",\"license_creation_date\":\"2017-07-20\",\"license_expiration_date\":\"2017-07-21\",\"license_key\":\"00141000017ODj3AAG_a1V41000004wT0OEAU\",\"product_subscription\":\"Konnect Enterprise\",\"support_plan\":\"None\"},\"signature\":\"24cc21223633044c15c300be19cacc26ccc5aca0dd9a12df8a7324a1970fe304bc07b8dcd7fb08d7b92e04169313377ae3b550ead653b951bc44cd2eb59f6beb\",\"version\":\"1\"}}", + "updated_at": 1500595200 +} +``` + +## Delete a license + +**Endpoint** + +
      /licenses/{id}
      + +{{ page.licenses_attribute_id }} + +**Response** + +``` +HTTP 204 No Content +``` + +## Generate a report + +Generate a report on the Kong Gateway instance to gather monthly usage data. + +
      /license/report
      + +Fields available in the report: + +Field | Description +------|------------ +`counters` | Counts the number of requests made in a given month.

      • `bucket`: Year and month when the requests were processed. If the value in `bucket` is `UNKNOWN`, then the requests were processed before Kong Gateway 2.7.0.1.
      • `request_count`: Number of requests processed in the given month and year. +`db_version` | The type and version of the datastore Kong Gateway is using. +`kong_version` | The version of the Kong Gateway instance. +`license_key` | An encrypted identifier for the current license key. If no license is present, the field displays as `UNLICENSED`. +`rbac_users` | The number of users registered with through RBAC. +`services_count` | The number of configured services in the Kong Gateway instance. +`system_info` | Displays information about the system running Kong Gateway.

      • `cores`: Number of CPU cores on the node
      • `hostname`: Encrypted system hostname
      • `uname`: Operating system +`workspaces_count` | The number of workspaces configured in the Kong Gateway instance. + +**Response** + +``` +HTTP 200 OK +``` + +```json +{ + "counters": [ + { + "bucket": "2021-12", + "request_count": 0 + } + ], + "db_version": "postgres 9.6.19", + "kong_version": "2.7.0.0", + "license_key": "ASDASDASDASDASDASDASDASDASD_ASDASDA", + "rbac_users": 0, + "services_count": 0, + "system_info": { + "cores": 4, + "hostname": "13b867agsa008", + "uname": "Linux x86_64" + }, + "workspaces_count": 1 +} +``` + +If there are no licenses stored by {{site.base_gateway}}, the report will include +`"license_key": "UNLICENSED"`: + +``` +HTTP 200 OK +``` + +```json +{ + "counters": [ + { + "bucket": "2021-12", + "request_count": 0 + } + ], + "db_version": "postgres 9.6.19", + "kong_version": "2.7.0.0", + "license_key": "UNLICENSED", + "rbac_users": 0, + "services_count": 0, + "system_info": { + "cores": 4, + "hostname": "13b867agsa008", + "uname": "Linux x86_64" + }, + "workspaces_count": 1 +} +``` + +[Admin API]: /gateway/{{page.kong_version}}/admin-api/ diff --git a/src/gateway/admin-api/rbac/reference.md b/src/gateway/admin-api/rbac/reference.md new file mode 100644 index 000000000000..2f58d7ebee6e --- /dev/null +++ b/src/gateway/admin-api/rbac/reference.md @@ -0,0 +1,950 @@ +--- +title: RBAC Reference +badge: enterprise +--- + +Kong {{site.base_gateway}}'s RBAC feature is configurable through Kong's +[Admin API](/gateway/{{page.kong_version}}/admin-api/) or via the [Kong Manager](/gateway/{{page.kong_version}}/kong-manager/auth/rbac). + +There are 4 basic entities involving RBAC. + +- **User**: The entity interacting with the system. Can be associated with + zero, one or more roles. Example: user `bob` has token `1234`. +- **Role**: Set of permissions (`role_endpoint` and + `role_entity`). Has a name and can be associated with zero, one or + more permissions. Example: user bob is associated with role + `developer`. +- **role_endpoint**: A set of enabled or disabled (see `negative` + parameter) actions (`read`, `create`, `update`, `delete`) + `endpoint`. Example: Role `developer` has 1 role_endpoint: `read & + write` to endpoint `/routes` +- **role_entity**: A set of enabled or disabled (see `negative` + parameter) actions (`read`, `create`, `update`, `delete`) + `entity`. Example: Role `developer` has 1 role_entity: `read & write + & delete` to entity `283fccff-2d4f-49a9-8730-dc8b71ec2245`. + +## Add a User +**Endpoint** + +
      /rbac/users
      + +**Request Body** + +| Attribute | Description | +| --------- | ----------- | +| `name` | The RBAC user name. | +| `user_token` | The authentication token to be presented to the Admin API. The value will be hashed and cannot be fetched in plaintext. | +| `enabled`
      optional | A flag to enable or disable the user. By default, users are enabled. | +| `comment`
      optional | A string describing the RBAC user object. | + +**Response** + +``` +HTTP 201 Created +``` + +```json +{ + "comment": null, + "created_at": 1557522650, + "enabled": true, + "id": "fa6881b2-f49f-4007-9475-577cd21d34f4", + "name": "doc_knight", + "user_token": "$2b$09$Za30VKAAAmyoB9zF2PNEF.9hgKcN2BdKkptPMCubPK/Ps08lzZjYG", + "user_token_ident": "4d870" +} +``` +___ + +## Retrieve a User +**Endpoint** + +
      /rbac/users/{name_or_id}
      + +| Attribute | Description | +| --------- | ----------- | +| `name_or_id` | The RBAC user name or UUID. | + +**Response** + +``` +HTTP 200 OK +``` + +```json +{ + "created_at": 1557522650, + "enabled": true, + "id": "fa6881b2-f49f-4007-9475-577cd21d34f4", + "name": "doc_lord", + "user_token": "$2b$09$Za30VKAAAmyoB9zF2PNEF.9hgKcN2BdKkptPMCubPK/Ps08lzZjYG", + "user_token_ident": "4d870" +} +``` +___ + +## List Users +**Endpoint** + +
      /rbac/users/
      + +**Response** + +``` +HTTP 200 OK +``` + +```json +{ + "data": [ + { + "comment": null, + "created_at": 1557512629, + "enabled": true, + "id": "f035f120-a95e-4327-b2ae-8fa264601d75", + "name": "doc_lord", + "user_token": "$2b$09$TIMneYcTosdG9WbzRsqcweAS2zote8g6I8HqXAtbFHR1pds2ymsh6", + "user_token_ident": "88ea3" + }, + { + "comment": null, + "created_at": 1557522650, + "enabled": true, + "id": "fa6881b2-f49f-4007-9475-577cd21d34f4", + "name": "doc_knight", + "user_token": "$2b$09$Za30VKAAAmyoB9zF2PNEF.9hgKcN2BdKkptPMCubPK/Ps08lzZjYG", + "user_token_ident": "4d870" + } + ], + "next": null +} +``` + +⚠️ **Note**: **RBAC Users** associated with **Admins** will _not_ be +listed with **`GET`** `/rbac/users`. Instead, use +[**`GET`** `/admins`](/gateway/{{page.kong_version}}/admin-api/admins/reference/#list-admins) +to list all **Admins**. + +___ + +## Update a User +**Endpoint** + +
      /rbac/users/{name_or_id}
      + +| Attribute | Description | +| --------- | ----------- | +| `name_or_id` | The RBAC user name or UUID. | + +**Request Body** + +| Attribute | Description | +| --------- | ----------- | +| `user_token`
      optional | The authentication token to be presented to the Admin API. If this value is not present, the token will automatically be generated. | +| `enabled`
      optional | A flag to enable or disable the user. By default, users are enabled. | +| `comment`
      optional | A string describing the RBAC user object. | + +**Response** + +``` +HTTP 200 OK +``` + +```json +{ + "comment": "this comment came from a patch request", + "created_at": 1557522650, + "enabled": true, + "id": "fa6881b2-f49f-4007-9475-577cd21d34f4", + "name": "donut_lord", + "user_token": "$2b$09$Za30VKAAAmyoB9zF2PNEF.9hgKcN2BdKkptPMCubPK/Ps08lzZjYG", + "user_token_ident": "4d870" +} +``` +___ + +## Delete a User +**Endpoint** + +
      /rbac/users/{name_or_id}
      + +| Attribute | Description | +| --------- | ----------- | +| `name_or_id` | The RBAC user name or UUID. | + +**Response** + +``` +HTTP 204 No Content +``` +___ + +## Add a Role +**Endpoint** + +
      /rbac/roles
      + +| Attribute | Description | +| --------- | ----------- | +| `name` | The RBAC role name. | +| `comment`
      optional | A string describing the RBAC user object. | + +**Response** + +``` +HTTP 201 Created +``` + +```json +{ + "comment": null, + "created_at": 1557532241, + "id": "b5c5cfd4-3330-4796-9b7b-6026e91e3ad6", + "is_default": false, + "name": "service_reader" +} +``` +___ + +## Retrieve a Role +Endpoint + +
      /rbac/roles/{name_or_id}
      + +| Attribute | Description | +| --------- | ----------- | +| `name_or_id` | The RBAC role name or UUID. | + +**Response** + +``` +HTTP 200 OK +``` + +```json +{ + "created_at": 1557532241, + "id": "b5c5cfd4-3330-4796-9b7b-6026e91e3ad6", + "is_default": false, + "name": "service_reader" +} +``` +___ + +## List Roles +**Endpoint** + +
      /rbac/roles
      + +**Response** + +``` +HTTP 200 OK +``` + +```json +{ + "data": [ + { + "comment": "Full access to all endpoints, across all workspaces—except RBAC Admin API", + "created_at": 1557506249, + "id": "38a03d47-faae-4366-b430-f6c10aee5029", + "name": "admin" + }, + { + "comment": "Read access to all endpoints, across all workspaces", + "created_at": 1557506249, + "id": "4141675c-8beb-41a5-aa04-6258ab2d2f7f", + "name": "read-only" + }, + { + "comment": "Full access to all endpoints, across all workspaces", + "created_at": 1557506249, + "id": "888117e0-f2b3-404d-823b-dee595423505", + "name": "super-admin" + }, + { + "comment": null, + "created_at": 1557532241, + "id": "b5c5cfd4-3330-4796-9b7b-6026e91e3ad6", + "name": "doc_lord" + } + ], + "next": null +} +``` +___ + +## Update or Create a Role +**Endpoint** + +
      /rbac/roles/{name_or_id}
      + +**Request Body** + +| Attribute | Description | +| --------- | ----------- | +| `name` | The RBAC role name. | +| `comment`
      optional | A string describing the RBAC user object. | + +The behavior of `PUT` endpoints is the following: if the request +payload **does** contain an entity's primary key, the payload will +"replace" the entity specified by the given primary key. If the +primary key is **not** that of an existing entity, the entity will be +created with the given payload. + +**Response** + +If creating the entity: + +``` +HTTP 201 Created +``` + +If replacing the entity: + +``` +HTTP 200 OK +``` + +```json +{ + "comment": "the best", + "created_at": 1557532566, + "id": "b5c5cfd4-3330-4796-9b7b-6026e91e3ad6", + "is_default": false, + "name": "doc_lord" +} +``` + +## Update a Role +**Endpoint** + +
      /rbac/roles/{name_or_id}
      + +| Attribute | Description | +| --------- | ----------- | +| `name_or_id` | The RBAC role or UUID. | + +**Request Body** + +| Attribute | Description | +| --------- | ----------- | +| `comment`
      optional | A string describing the RBAC role object. | + +**Response** + +``` +HTTP 200 OK +``` + +```json +{ + "comment": "comment from patch request", + "created_at": 1557532566, + "id": "b5c5cfd4-3330-4796-9b7b-6026e91e3ad6", + "is_default": false, + "name": "service_reader" +} +``` +___ + +## Delete a Role +**Endpoint** + +
      /rbac/roles/{name_or_id}
      + +| Attribute | Description | +| --------- | ----------- | +| `name` | The RBAC role name. | + +**Response** + +``` +HTTP 204 No Content +``` +___ + +## Add a Role Endpoint Permission +**Endpoint** + +
      /rbac/roles/{name_or_id}/endpoints
      + + +| Attribute | Description | +| --------- | ----------- | +| `name_or_id` | The RBAC role name. | + + +**Request Body** + +| Attribute | Description | +| --------- | ----------- | +| `workspace` | Workspace tied to the endpoint. Defaults to the default permission. Special value of "*" means **all** workspaces are affected | +| `endpoint` | Endpoint associated with this permission. | +| `negative` | If true, explicitly disallow the actions associated with the permissions tied to this endpoint. By default this value is false. | +| `actions` | One or more actions associated with this permission. This is a comma separated string (read,create,update,delete) | +| `comment`
      optional | A string describing the RBAC permission object. | + +`endpoint` must be the path of the associated endpoint. They can be +exact matches, or contain wildcards, represented by `*`. + +- Exact matches; eg: + * /services/ + * /services/foo + +- Wildcards; eg: + * /services/* + * /services/*/plugins + +Where `*` replaces exactly one segment between slashes (or the end of +the path). + +Note that wildcards can be nested (`/rbac/*`, `/rbac/*/*`, +`/rbac/*/*/*` would refer to all paths under `/rbac/`) + +**Response** + +``` +HTTP 201 Created +``` + +```json +{ + "actions": [ + "delete", + "create", + "update", + "read" + ], + "created_at": 1557764505, + "endpoint": "/consumers", + "negative": false, + "role": { + "id": "23df9f20-e7cc-4da4-bc89-d3a08f976e50" + }, + "workspace": "default" +} +``` + +--- + +## Retrieve a Role Endpoint Permission +**Endpoint** + +
      /rbac/roles/{name_or_id}/endpoints/{workspace_name_or_id}/{endpoint}
      + +| Attribute | Description | +| --------- | ----------- | +| `name_or_id` | The RBAC role name or UUID. | +| `workspace_name_or_id` | The workspace name or UUID. | +| `endpoint` | The endpoint associated with this permission. | + +**Response** + +``` +HTTP 200 OK +``` + +```json +{ + "actions": [ + "delete", + "create", + "update", + "read" + ], + "created_at": 1557764505, + "endpoint": "/consumers", + "negative": false, + "role": { + "id": "23df9f20-e7cc-4da4-bc89-d3a08f976e50" + }, + "workspace": "default" +} +``` + +--- + + + +## List Role Endpoints Permissions +**Endpoint** + +
      /rbac/roles/{role_name_or_id}/endpoints
      + +| Attribute | Description | +| --------- | ----------- | +| `role_name_or_id` | The RBAC role name or UUID. | + +**Response** + +``` +HTTP 200 OK +``` + +```json +{ + "data": [ + { + "actions": [ + "delete", + "create", + "update", + "read" + ], + "created_at": 1557764505, + "endpoint": "/consumers", + "negative": false, + "role": { + "id": "23df9f20-e7cc-4da4-bc89-d3a08f976e50" + }, + "workspace": "default" + }, + { + "actions": [ + "read" + ], + "created_at": 1557764438, + "endpoint": "/services", + "negative": false, + "role": { + "id": "23df9f20-e7cc-4da4-bc89-d3a08f976e50" + }, + "workspace": "default" + } + ] +} +``` + +--- + +## Update a Role Endpoint Permission +**Endpoint** + +
      /rbac/roles/{name_or_id}/endpoints/{workspace_name_or_id}/{endpoint}
      + +| Attribute | Description | +| --------- | ----------- | +| `name_or_id` | The RBAC role name or UUID. | +| `workspace_name_or_id` | The workspace name or UUID. | +| `endpoint` | The endpoint associated with this permission. | + +**Request Body** + +| Attribute | Description | +| --------- | ----------- | +| `negative` | If true, explicitly disallow the actions associated with the permissions tied to this resource. By default this value is false. | +| `actions` | One or more actions associated with this permission. | + +**Response** + +``` +HTTP 200 OK +``` + +```json +{ + "actions": [ + "delete", + "create", + "update", + "read" + ], + "created_at": 1557764438, + "endpoint": "/services", + "negative": false, + "role": { + "id": "23df9f20-e7cc-4da4-bc89-d3a08f976e50" + }, + "workspace": "default" +} +``` + +--- + + + +## Delete a Role Endpoint Permission +**Endpoint** + +
      /rbac/roles/{name_or_id}/endpoints/{workspace_name_or_id}/{endpoint}
      + +| Attribute | Description | +| --------- | ----------- | +| `name_or_id` | The RBAC role name or UUID. | +| `workspace_name_or_id` | The workspace name or UUID. | +| `endpoint` | The endpoint associated with this permission. | + +**Response** + +``` +HTTP 204 No Content +``` + +--- + + + +## Add a Role Entity Permission +**Endpoint** +
      /rbac/roles/{name_or_id}/entities
      + +| Attribute | Description | +| --------- | ----------- | +| `name_or_id` | The RBAC role name or UUID. | + +**Request Body** + +| Attribute | Description | +| --------- | ----------- | +| `negative` | If true, explicitly disallow the actions associated with the permissions tied to this resource. By default this value is false. | +| `entity_id` | id of the entity associated with this permission. +| `entity_type` | Type of the entity of a given `entity_id`. | +| `actions` | One or more actions associated with this permission. | +| `comment`
      optional | A string describing the RBAC permission object | + +`entity_id` must be the ID of an entity in Kong; if the ID of a +workspace is given, the permission will apply to all entities in that +workspace. Future entities belonging to that workspace will get the +same permissions. A wildcard `*` will be interpreted as **all +entities** in the system. + + +**Response** + +``` +HTTP 201 Created +``` + +```json +{ + "actions": [ + "delete", + "create", + "read" + ], + "created_at": 1557771505, + "entity_id": "*", + "entity_type": "wildcard", + "negative": false, + "role": { + "id": "bba049fa-bf7e-40ef-8e89-553dda292e99" + } +} +``` + +--- + +## Retrieve a Role Entity Permission +**Endpoint** +
      /rbac/roles/{name_or_id}/entities/{entity_id}
      + +| Attribute | Description | +| --------- | ----------- | +| `name_or_id` | The RBAC permission name or UUID. | +| `entity_id` | id of the entity associated with this permission. | + +**Response** + +``` +HTTP 200 Ok +``` + +```json +{ + "actions": [ + "delete", + "create", + "read" + ], + "created_at": 1557771505, + "entity_id": "*", + "entity_type": "wildcard", + "negative": false, + "role": { + "id": "bba049fa-bf7e-40ef-8e89-553dda292e99" + } +} +``` + +--- + +## List Entity Permissions + +**Endpoint** +
      /rbac/roles/{name_or_id}/entities
      + +| Attribute | Description | +| --------- | ----------- | +| `name_or_id` | The RBAC permission name or UUID. | + +**Response** + +``` +HTTP 200 Ok +``` + +```json +{ + "data": [ + { + "actions": [ + "delete", + "create", + "read" + ], + "created_at": 1557771505, + "entity_id": "*", + "entity_type": "wildcard", + "negative": false, + "role": { + "id": "bba049fa-bf7e-40ef-8e89-553dda292e99" + } + } + ] +} +``` + +--- +## Update an Entity Permission +**Endpoint** + +
      /rbac/roles/{name_or_id}/entities/{entity_id}
      + +| Attribute | Description | +| --------- | ----------- | +| `name_or_id` | The RBAC role name or UUID. | +| `entity_id` | The entity name or UUID. | + +**Request Body** + +| Attribute | Description | +| --------- | ----------- | +| `negative` | If true, explicitly disallow the actions associated with the permissions tied to this resource. By default this value is false. | +| `actions` | One or more actions associated with this permission. | + +**Response** + +``` +HTTP 200 OK +``` + +```json +{ + "actions": [ + "update" + ], + "created_at": 1557771505, + "entity_id": "*", + "entity_type": "wildcard", + "negative": false, + "role": { + "id": "bba049fa-bf7e-40ef-8e89-553dda292e99" + } +} +``` + +--- + +## Delete an Entity Permission +**Endpoint** + +
      /rbac/roles/{name_or_id}/entities/{entity_id}
      + +| Attribute | Description | +| --------- | ----------- | +| `name_or_id` | The RBAC role name or UUID. | +| `entity_id` | The entity name or UUID. | + +**Response** + +``` +HTTP 204 No Content +``` + +--- + +## List Role Permissions +**Endpoint** +
      /rbac/roles/{name_or_id}/permissions/
      + +| Attribute | Description | +| --------- | ----------- | +| `name_or_id` | The RBAC role name or UUID. | + + +**Response** + +``` +HTTP 200 OK +``` +```json +{ + "endpoints": { + "*": { + "*": { + "actions": [ + "delete", + "create", + "update", + "read" + ], + "negative": false + }, + "/*/rbac/*": { + "actions": [ + "delete", + "create", + "update", + "read" + ], + "negative": true + } + } + }, + "entities": {} +} +``` + +## Add a User to a Role +**Endpoint** + +
      /rbac/users/{name_or_id}/roles
      + +| Attribute | Description | +| --------- | ----------- | +| `name_or_id` | The RBAC role name or UUID. | + + +**Request Body** + +| Attribute | Description | +| --------- | ----------- | +| `roles` | Comma-separated list of role names to assign to the user. | + +**Response** + +``` +HTTP 201 Created +``` +```json +{ + "roles": [ + { + "created_at": 1557772263, + "id": "aae80073-095f-4553-ba9a-bee5ed3b8b91", + "name": "doc-knight" + } + ], + "user": { + "comment": null, + "created_at": 1557772232, + "enabled": true, + "id": "b65ca712-7ceb-4114-87f4-5c310492582c", + "name": "gruce-wayne", + "user_token": "$2b$09$gZnMKK/mm/d2rAXN7gL63uL43mjdX/62iwMqdyCQwLyC0af3ce/1K", + "user_token_ident": "88ea3" + } +} +``` + +--- +## List a User's Roles +**Endpoint** + +
      /rbac/users/{name_or_id}/roles
      + +| Attribute | Description | +| --------- | ----------- | +| `name_or_id` | The RBAC role name or UUID. | + + +**Response** + +``` +HTTP 200 OK +``` +```json + +{ + "roles": [ + { + "comment": "Read access to all endpoints, across all workspaces", + "created_at": 1557765500, + "id": "a1c810ee-8366-4654-ba0c-963ffb9ccf2e", + "name": "read-only" + }, + { + "created_at": 1557772263, + "id": "aae80073-095f-4553-ba9a-bee5ed3b8b91", + "name": "doc-knight" + } + ], + "user": { + "comment": null, + "created_at": 1557772232, + "enabled": true, + "id": "b65ca712-7ceb-4114-87f4-5c310492582c", + "name": "gruce-wayne", + "user_token": "$2b$09$gZnMKK/mm/d2rAXN7gL63uL43mjdX/62iwMqdyCQwLyC0af3ce/1K", + "user_token_ident": "88ea3" + } +} +``` + +--- +## Delete a Role from a User +**Endpoint** + +
      /rbac/users/{name_or_id}/roles
      + +| Attribute | Description | +| --------- | ----------- | +| `name_or_id` | The RBAC role name or UUID. | + + +**Request Body** + +| Attribute | Description | +| --------- | ----------- | +| `roles` | Comma-separated list of role names to assign to the user. | + +**Response** + +``` +HTTP 204 No Content +``` + +--- + +## List a User's Permissions +**Endpoint** + +
      /rbac/users/{name_or_id}/permissions
      + +| Attribute | Description | +| --------- | ----------- | +| `name_or_id` | The RBAC role name or UUID. | + +**Response** + +``` +HTTP 200 OK +``` +```json +{ + "endpoints": { + "*": { + "*": { + "actions": [ + "read" + ], + "negative": false + } + } + }, + "entities": {} +} + +``` diff --git a/src/gateway/admin-api/workspaces/reference.md b/src/gateway/admin-api/workspaces/reference.md new file mode 100644 index 000000000000..50d5edc7219e --- /dev/null +++ b/src/gateway/admin-api/workspaces/reference.md @@ -0,0 +1,353 @@ +--- +title: Workspaces Reference +badge: enterprise + +workspace_body: | + Attribute | Description + ---:| --- + `name` | The **Workspace** name. +--- + + +{{site.base_gateway}}'s Workspaces feature is configurable through Kong's +Admin API. + +## Workspace Object + +The **Workspace** object describes the **Workspace** entity, which has an ID +and a name. + +### Add Workspace + +**Endpoint** + +
      /workspaces/
      + +#### Request Body + +{{ page.workspace_body }} + +**Response** + +``` +HTTP 201 Created +``` + +```json +{ + "comment": null, + "config": { + "meta": null, + "portal": false, + "portal_access_request_email": null, + "portal_approved_email": null, + "portal_auth": null, + "portal_auth_conf": null, + "portal_auto_approve": null, + "portal_cors_origins": null, + "portal_developer_meta_fields": "[{\"label\":\"Full Name\",\"title\":\"full_name\",\"validator\":{\"required\":true,\"type\":\"string\"}}]", + "portal_emails_from": null, + "portal_emails_reply_to": null, + "portal_invite_email": null, + "portal_reset_email": null, + "portal_reset_success_email": null, + "portal_token_exp": null + }, + "created_at": 1557441226, + "id": "c663cca5-c6f6-474a-ae44-01f62aba16a9", + "meta": { + "color": null, + "thumbnail": null + }, + "name": "green-team" +} +``` + +### List Workspaces + +**Endpoint** + +
      /workspaces/
      + +**Response** + +``` +HTTP 200 OK +``` + +```json +{ + "data": [ + { + "comment": null, + "config": { + "meta": null, + "portal": false, + "portal_access_request_email": null, + "portal_approved_email": null, + "portal_auth": null, + "portal_auth_conf": null, + "portal_auto_approve": null, + "portal_cors_origins": null, + "portal_developer_meta_fields": "[{\"label\":\"Full Name\",\"title\":\"full_name\",\"validator\":{\"required\":true,\"type\":\"string\"}}]", + "portal_emails_from": null, + "portal_emails_reply_to": null, + "portal_invite_email": null, + "portal_reset_email": null, + "portal_reset_success_email": null, + "portal_token_exp": null + }, + "created_at": 1557419951, + "id": "00000000-0000-0000-0000-000000000000", + "meta": { + "color": null, + "thumbnail": null + }, + "name": "default" + }, + { + "comment": null, + "config": { + "meta": null, + "portal": false, + "portal_access_request_email": null, + "portal_approved_email": null, + "portal_auth": null, + "portal_auth_conf": null, + "portal_auto_approve": null, + "portal_cors_origins": null, + "portal_developer_meta_fields": "[{\"label\":\"Full Name\",\"title\":\"full_name\",\"validator\":{\"required\":true,\"type\":\"string\"}}]", + "portal_emails_from": null, + "portal_emails_reply_to": null, + "portal_invite_email": null, + "portal_reset_email": null, + "portal_reset_success_email": null, + "portal_token_exp": null + }, + "created_at": 1557441226, + "id": "c663cca5-c6f6-474a-ae44-01f62aba16a9", + "meta": { + "color": null, + "thumbnail": null + }, + "name": "green-team" + } + ], + "next": null +} +``` + +### Update or Create a Workspace + +**Endpoint** + +
      /workspaces/{id}
      + +Attributes | Description +---:| --- +`id`
      **conditional** | The **Workspace's** unique ID, if replacing it.* + +* The behavior of `PUT` endpoints is the following: if the request payload **does +not** contain an entity's primary key (`id` for Workspaces), the entity will be +created with the given payload. If the request payload **does** contain an +entity's primary key, the payload will "replace" the entity specified by the +given primary key. If the primary key is **not** that of an existing entity, `404 +NOT FOUND` will be returned. + +#### Request Body + +Attribute | Description +---:| --- +`name` | The **Workspace** name. + +**Response** + +If creating the entity: + +``` +HTTP 201 Created +``` + +If replacing the entity: + +``` +HTTP 200 OK +``` + +```json +{ + "comment": null, + "config": { + "meta": null, + "portal": false, + "portal_access_request_email": null, + "portal_approved_email": null, + "portal_auth": null, + "portal_auth_conf": null, + "portal_auto_approve": null, + "portal_cors_origins": null, + "portal_developer_meta_fields": "[{\"label\":\"Full Name\",\"title\":\"full_name\",\"validator\":{\"required\":true,\"type\":\"string\"}}]", + "portal_emails_from": null, + "portal_emails_reply_to": null, + "portal_invite_email": null, + "portal_reset_email": null, + "portal_reset_success_email": null, + "portal_token_exp": null + }, + "created_at": 1557504202, + "id": "c663cca5-c6f6-474a-ae44-01f62aba16a9", + "meta": { + "color": null, + "thumbnail": null + }, + "name": "rocket-team" +} +``` + +### Retrieve a Workspace + +**Endpoint** + +
      /workspaces/{name or id}
      + +Attributes | Description +---:| --- +`name or id`
      **required** | The unique identifier **or** the name of the **Workspace** to retrieve + +**Response** + +``` +HTTP 200 OK +``` + +```json +{ + "config": { + "portal": false, + "portal_developer_meta_fields": "[{\"label\":\"Full Name\",\"title\":\"full_name\",\"validator\":{\"required\":true,\"type\":\"string\"}}]" + }, + "created_at": 1557504202, + "id": "c663cca5-c6f6-474a-ae44-01f62aba16a9", + "meta": { }, + "name": "rocket-team" +} +``` + +### Retrieve Workspace Metadata + +#### Endpoint + +
      /workspaces/{name or id}/meta
      + +Attributes | Description +---:| --- +`name or id`
      **required** | The unique identifier **or** the name of the **Workspace** to retrieve + +#### Response + +``` +HTTP 200 OK +``` + +```json +{ + "counts": { + "acls": 1, + "apis": 1, + "basicauth_credentials": 1, + "consumers": 1234, + "files": 41, + "hmacauth_credentials": 1, + "jwt_secrets": 1, + "keyauth_credentials": 1, + "oauth2_authorization_codes": 1, + "oauth2_credentials": 1, + "oauth2_tokens": 1, + "plugins": 5, + "rbac_roles": 3, + "rbac_users": 12, + "routes": 15, + "services": 2, + "ssl_certificates": 1, + "ssl_servers_names": 1, + "targets": 1, + "upstreams": 1 + } +} +``` + +### Delete a Workspace + +**Endpoint** + +
      /workspaces/{name or id}
      + +Attributes | Description +---:| --- +`name or id`
      **required** | The unique identifier **or** the name of the **Workspace** to delete + +**Note:** All entities within a **Workspace** must be deleted before the +**Workspace** itself can be. + +**Response** + +``` +HTTP 204 No Content +``` + +### Update a Workspace + +**Endpoint** + +
      /workspaces/{name or id}
      + +Attributes | Description +---:| --- +`name or id`
      **required** | The unique identifier **or** the name of the **Workspace** to patch + +#### Request Body + +Attributes | Description +---:| --- +`comment` | A string describing the **Workspace** + +The behavior of `PATCH` endpoints prevents the renaming of a **Workspace**. + +**Response** + +``` +HTTP 200 OK +``` + +```json +{ + "comment": "this is a sample comment in the patch request", + "config": { + "meta": null, + "portal": false, + "portal_access_request_email": null, + "portal_approved_email": null, + "portal_auth": null, + "portal_auth_conf": null, + "portal_auto_approve": null, + "portal_cors_origins": null, + "portal_developer_meta_fields": "[{\"label\":\"Full Name\",\"title\":\"full_name\",\"validator\":{\"required\":true,\"type\":\"string\"}}]", + "portal_emails_from": null, + "portal_emails_reply_to": null, + "portal_invite_email": null, + "portal_reset_email": null, + "portal_reset_success_email": null, + "portal_token_exp": null + }, + "created_at": 1557509909, + "id": "c543d2c8-d297-4c9c-adf5-cd64212868fd", + "meta": { + "color": null, + "thumbnail": null + }, + "name": "green-team" +} +``` +--- + +[Admin API]: /gateway/{{page.kong_version}}/admin-api/ diff --git a/src/gateway/get-started/expose-services.md b/src/gateway/get-started/expose-services.md new file mode 100644 index 000000000000..0bf2a35ec19d --- /dev/null +++ b/src/gateway/get-started/expose-services.md @@ -0,0 +1,99 @@ +--- +title: Expose your Services with Kong Gateway +--- + +In this topic, you’ll learn how to expose your Services using Routes. + +If you are following the Getting Started workflow, make sure you have completed +[Prepare to Administer {{site.base_gateway}}](/gateway/{{page.kong_version}}/get-started//prepare) +before moving on. + +If you are not following the Getting Started workflow, make sure you have +{{site.base_gateway}} installed and started. + +## What are Services and Routes? + +**Service** and **Route** objects let you expose your services to clients with +{{site.base_gateway}}. When configuring access to your API, you’ll start by specifying a +Service. In {{site.base_gateway}}, a Service is an entity representing an external +upstream API or microservice — for example, a data transformation +microservice, a billing API, and so on. + +The main attribute of a Service is its **URL**, where the service listens for +requests. You can specify the URL with a single string, or by specifying its +protocol, host, port, and path individually. + +Before you can start making requests against the Service, you will need to add +a Route to it. Routes determine how (and if) requests are sent to their Services +after they reach {{site.base_gateway}}. A single Service can have many Routes. + +After configuring the Service and the Route, you’ll be able to start making +requests through {{site.base_gateway}}. + +This diagram illustrates the flow of requests and responses being routed through +the Service to the backend API. + +![Services and routes](/assets/images/docs/getting-started-guide/route-and-service.png) + +## Add a Service + +For the purpose of this example, you’ll create a Service pointing to the Mockbin +API. Mockbin is an “echo” type public website that returns requests back to the +requester as responses. This visualization will be helpful for learning how Kong +Gateway proxies API requests. + +{{site.base_gateway}} exposes the RESTful Admin API on port `8001`. The gateway’s +configuration, including adding Services and Routes, is done through requests to +the Admin API. + +```sh +curl -i -X POST http://localhost:8001/services \ + --data name=example_service \ + --data url='http://mockbin.org' +``` + +If the service is created successfully, you'll get a 201 success message. + +Verify the service’s endpoint: + +```sh +curl -i http://localhost:8001/services/example_service +``` + +## Add a Route + +For the Service to be accessible through the API gateway, you need to add a +Route to it. + +Define a Route (`/mock`) for the Service (`example_service`) with a specific +path that clients need to request. Note at least one of the hosts, paths, or +methods must be set for the Route to be matched to the service. + +```sh +curl -i -X POST http://localhost:8001/services/example_service/routes \ + --data 'paths[]=/mock' \ + --data name=mocking +``` + +A `201` message indicates the Route was created successfully. + +## Verify the Route is forwarding requests to the Service + +By default, {{site.base_gateway}} handles proxy requests on port `8000`. The proxy is often referred to as the data plane. + +```sh +curl -i -X GET http://localhost:8000/mock/request +``` +## Summary and next steps + +In this section, you: + +* Added a Service named `example_service` with a URL of `http://mockbin.org`. +* Added a Route named `/mock`. +* This means if an HTTP request is sent to the {{site.base_gateway}} node on +port `8000`(the proxy port) and it matches route `/mock`, then that request is +sent to `http://mockbin.org`. +* Abstracted a backend/upstream service and put a route of your choice on the +front end, which you can now give to clients to make requests. + +Next, go on to learn about [enforcing rate limiting](/gateway/{{page.kong_version}}/get-started//protect-services). diff --git a/src/gateway/get-started/index.md b/src/gateway/get-started/index.md new file mode 100644 index 000000000000..169840c13178 --- /dev/null +++ b/src/gateway/get-started/index.md @@ -0,0 +1,92 @@ +--- +title: Get Kong +content-type: tutorial +book: get-started +chapter: 1 +--- + +[{{site.base_gateway}}](/gateway/latest/) is a lightweight, fast, and flexible cloud-native API gateway. +{{site.base_gateway}} sits in front of your service applications, dynamically controlling, analyzing, and +routing requests and responses. {{site.base_gateway}} implements your API traffic policies +by using a flexible, low-code, plug-in based approach. + +This tutorial will help you get started with {{site.base_gateway}} by setting up a local installation +and walking through some common API management tasks. + +This page will walk you through running {{site.base_gateway}} and verifying it with the +[Admin API](/gateway/latest/admin-api). Once complete, the following tasks +can be performed to complete the tutorial: + +* [Understanding and configuring Services and Routes](/gateway/{{ page.kong_version }}/get-started/services-and-routes) +* [Configuring Rate Limiting to protect upstream Services](/gateway/{{ page.kong_version }}/get-started/rate-limiting) +* [Increase system performance with Proxy Caching](/gateway/{{ page.kong_version }}/get-started/proxy-caching) +* [Load Balancing for horizontal Service scaling](/gateway/{{ page.kong_version }}/get-started/load-balancing) +* [Protecting Services with Key Authentication](/gateway/{{ page.kong_version }}/get-started/key-authentication) + +### Prerequisites + +* [Docker](https://docs.docker.com/get-docker/) is used to run {{site.base_gateway}} and supporting database locally +* [curl](https://curl.se/) is used to send requests to {{site.base_gateway}}. `curl` is pre-installed on most systems +* [jq](https://stedolan.github.io/jq/) is used to process JSON responses on the command line. While useful, this tool is +not necessary to complete the tasks of this tutorial. If you wish to proceed without `jq`, modify the commands to +remove `jq` processing. + +### Get Kong + +For the purposes of this tutorial, a `quickstart` script is provided to quickly run {{site.base_gateway}} and its supporting database. +This script uses Docker to run {{site.base_gateway}} and a [PostgreSQL](https://www.postgresql.org/) database as the backing database. + +1. Run {{site.base_gateway}} with the `quickstart` script: + + ```sh + curl -Ls get.konghq.com/quickstart | sh -s + ``` + + This script runs Docker containers for {{site.base_gateway}} and the supporting PostgreSQL database. + The script also creates a Docker network for those containers to communicate over. Finally, the database is + initialized with the appropriate [migration](/gateway/latest/reference/cli/#kong-migrations) steps, + and once the {{site.base_gateway}} is ready, you will see the following message: + + ```text + ✔ Kong is ready! + ``` + +1. Verify that {{site.base_gateway}} is running: + + {{site.base_gateway}} serves an Admin API on the default port `8001`. The Admin API can be used for + both querying and controlling the state of {{site.base_gateway}}. The following command + will query the Admin API, fetching the headers only: + + ```sh + curl --head localhost:8001 + ``` + + If {{site.base_gateway}} is running properly, it will respond with a `200` HTTP code, similar to the following: + + ```text + HTTP/1.1 200 OK + Date: Mon, 22 Aug 2022 19:25:49 GMT + Content-Type: application/json; charset=utf-8 + Connection: keep-alive + Access-Control-Allow-Origin: * + Content-Length: 11063 + X-Kong-Admin-Latency: 6 + Server: kong/{{page.kong_version}} + ``` + +1. Evaluate the {{site.base_gateway}} configuration: + + The root route of the Admin API provides important information about the running + {{site.base_gateway}} including networking, security, and plugin information. The full + configuration is provided in the `.configuration` key of the returned JSON document. + + ```sh + curl -s localhost:8001 | jq '.configuration' + ``` + + You should receive a large JSON response with {{site.base_gateway}} configuration information. + + +Every step in this tutorial requires a running {{site.base_gateway}}, so leave +everything running and proceed to the next steps in this tutorial. + diff --git a/src/gateway/get-started/key-authentication.md b/src/gateway/get-started/key-authentication.md new file mode 100644 index 000000000000..22a695057681 --- /dev/null +++ b/src/gateway/get-started/key-authentication.md @@ -0,0 +1,223 @@ +--- +title: Key Authentication +content-type: tutorial +book: get-started +chapter: 5 +--- + +Authentication is the process of verifying that a requester has permissions to access a resource. +As it's name implies, API gateway authentication authenticates the flow of data to and from your upstream services. + +{{site.base_gateway}} has a library of plugins that support +the most widely used [methods of API gateway authentication](/hub/#authentication). + +Common authentication methods include: +* Key Authentication +* Basic Authentication +* OAuth 2.0 Authentication +* LDAP Authentication Advanced +* OpenID Connect + +## Authentication benefits + +With {{site.base_gateway}} controlling authentication, requests won't reach upstream services unless the client has successfully +authenticated. This means upstream services process pre-authorized requests, freeing them from the +cost of authentication, which is a savings in compute time *and* development effort. + +{{site.base_gateway}} has visibility into all authentication attempts, which provides the ability to build +monitoring and alerting capabilities supporting service availability and compliance. + +For more information, see [What is API Gateway Authentication?](https://konghq.com/learning-center/api-gateway/api-gateway-authentication). + +## Enable authentication + +The following tutorial walks through how to enable the [Key Authentication plugin](/hub/kong-inc/key-auth/) across +various aspects in {{site.base_gateway}}. + +API key authentication is a popular method for enforcing API authentication. In key authentication, +{{site.base_gateway}} is used to generate and associate an API key with a [consumer](/gateway/latest/admin-api/#consumer-object). +That key is the authentication secret presented by the client when making subsequent requests. {{site.base_gateway}} approves or +denies requests based on the validity of the presented key. This process can be applied globally or to individual +[services](/gateway/latest/key-concepts/services/) and [routes](/gateway/latest/key-concepts/routes/). + +### Prerequisites + +This chapter is part of the *Get Started with Kong* series. For the best experience, it is recommended that you follow the +series from the beginning. + +Start with the introduction, [Get Kong](/gateway/latest/get-started/), which includes +tool prerequisites and instructions for running a local {{site.base_gateway}}. + +Step two of the guide, [Services and Routes](/gateway/latest/get-started/services-and-routes), +includes instructions for installing a mock service used throughout this series. + +If you haven't completed these steps already, complete them before proceeding. + +### Set up consumers and keys + +Key authentication in {{site.base_gateway}} works by using the consumer object. Keys are assigned to +consumers, and client applications present the key within the requests they make. + +1. **Create a new consumer** + + For the purposes of this tutorial, create a new consumer with a username `luka`: + + ```sh + curl -i -X POST http://localhost:8001/consumers/ \ + --data username=luka + ``` + + You will receive a `201` response indicating the consumer was created. + +1. **Assign the consumer a key** + + Once provisioned, call the Admin API to assign a key for the new consumer. + For this tutorial, set the key value to `top-secret-key`: + + ```sh + curl -i -X POST http://localhost:8001/consumers/luka/key-auth \ + --data key=top-secret-key + ``` + + You will receive a `201` response indicating the key was created. + + In this example, you have explicitly set the key contents to `top-secret-key`. + If you do not provide the `key` field, {{site.base_gateway}} will generate the key value for you. + + {:.important} + > **Warning**: For the purposes of this tutorial, we have assigned an example key value. It is recommended that you let the + API gateway autogenerate a complex key for you. Only specify a key for testing or when migrating existing systems. + + +### Global key authentication + +Installing the plugin globally means *every* proxy request to {{site.base_gateway}} is protected by key authentication. + +1. **Enable key authentication** + + The Key Authentication plugin is installed by default on {{site.base_gateway}} and can be enabled + by sending a `POST` request to the plugins object on the Admin API: + + ```sh + curl -X POST http://localhost:8001/plugins/ \ + --data "name=key-auth" \ + --data "config.key_names=apikey" + ``` + + You will receive a `201` response indicating the plugin was installed. + + The `key_names` configuration field in the above request defines the name of the field that the + plugin looks for to read the key when authenticating requests. The plugin looks for the field in headers, + query string parameters, and the request body. + +1. **Send an unauthenticated request** + + Try to access the service without providing the key: + + ```sh + curl -i http://localhost:8000/mock/request + ``` + + Since you enabled key authentication globally, you will receive an unauthorized response: + + ```text + HTTP/1.1 401 Unauthorized + ... + { + "message": "No API key found in request" + } + ``` + +1. **Send the wrong key** + + Try to access the service with the wrong key: + + ```sh + curl -i http://localhost:8000/mock/request \ + -H 'apikey:bad-key' + ``` + + You will receive an unauthorized response: + + ```text + HTTP/1.1 401 Unauthorized + ... + { + "message":"Invalid authentication credentials" + } + ``` + +1. **Send a valid request** + + Send a request with the valid key in the `apikey` header: + + ```sh + curl -i http://localhost:8000/mock/request \ + -H 'apikey:top-secret-key' + ``` + + You will receive a `200 OK` response. + +### Service based key authentication + +The Key Authentication plugin can be enabled for specific services. The request is the same as above, but the `POST` request is sent +to the service URL: + + ```sh + curl -X POST http://localhost:8001/services/example_service/plugins \ + --data name=key-auth + ``` +### Route based key authentication + +The Key Authentication plugin can be enabled for specific routes. The request is the same as above, but the `POST` request is sent to the route URL: + + ```sh + curl -X POST http://localhost:8001/routes/example_route/plugins \ + --data name=key-auth + ``` + +## (Optional) Disable the plugin + +If you are following this getting started guide section by section, you will need to use this API key +in any requests going forward. If you don’t want to keep specifying the key, disable the plugin before moving on. + + +1. **Find the Key Authentication plugin ID** + + ```sh + curl -X GET http://localhost:8001/plugins/ + ``` + + You will receive a JSON response that contains the `id` field, similar to the following snippet: + + ```text + ... + "id": "2512e48d9-7by0-674c-84b7-00606792f96b" + ... + ``` + +1. **Disable the plugin** + + Use the plugin ID obtained above to `PATCH` the `enabled` field on the + installed Key Authentication plugin. Your request will look similar to this, + substituting the proper plugin ID: + + ```sh + curl -X PATCH http://localhost:8001/plugins/2512e48d9-7by0-674c-84b7-00606792f96b \ + --data enabled=false + ``` + +1. **Test disabled authentication** + + Now you can make a request without providing an API key: + + ```sh + curl -i http://localhost:8000/mock/request + ``` + + You should receive: + + ```text + HTTP/1.1 200 OK + ``` + diff --git a/src/gateway/get-started/load-balancing.md b/src/gateway/get-started/load-balancing.md new file mode 100644 index 000000000000..7eb82ec87902 --- /dev/null +++ b/src/gateway/get-started/load-balancing.md @@ -0,0 +1,94 @@ +--- +title: Load Balancing +content-type: tutorial +book: get-started +chapter: 6 +--- + +Load balancing is a method of distributing API request traffic across +multiple upstream services. Load balancing improves overall system responsiveness +and reduces failures by preventing overloading of individual resources. + +In the following example, you’ll use an application deployed across two different servers, or upstream targets. +{{site.base_gateway}} needs to load balance across both servers, so that if one of the servers is unavailable, +it automatically detects the problem and routes all traffic to the working server. + +An [upstream](/gateway/latest/key-concepts/upstreams/) +refers to the service applications sitting behind {{site.base_gateway}}, +to which client requests are forwarded. In {{site.base_gateway}}, an upstream represents a virtual hostname and can be +used to health check, circuit break, and load balance incoming requests over multiple [target](/gateway/latest/admin-api/#target-object) backend services. + +In this section, you’ll re-configure the service created earlier, (`example_service`) to point to an upstream +instead of a specific host. For the purposes of our example, the upstream will point to two different targets, +`httpbin.org` and `mockbin.org`. More commonly, targets will be instances of the same backend service running on different host systems. + +Here is a diagram illustrating the setup: + +![Upstream targets](/assets/images/docs/getting-started-guide/upstream-targets.png) + +## Enable load balancing + +In this section, you will create an upstream named `example_upstream` and add two targets to it. + +### Prerequisites + +This chapter is part of the *Get Started with Kong* series. For the best experience, it is recommended that you follow the +series from the beginning. + +Start with the introduction, [Get Kong](/gateway/latest/get-started/), which includes +a list of prerequisites and instructions for running a local {{site.base_gateway}}. + +Step two of the guide, [Services and Routes](/gateway/latest/get-started/services-and-routes), +includes instructions for installing a mock service used throughout this series. + +If you haven't completed these steps already, complete them before proceeding. + +### Steps to enable load balancing + +1. **Create an upstream** + + Use the Admin API to create an upstream named `example_upstream`: + + ```sh + curl -X POST http://localhost:8001/upstreams \ + --data name=example_upstream + ``` + +1. **Create upstream targets** + + Create two targets for `example_upstream`. Each request creates a new target, and + sets the backend service connection endpoint: + + ```sh + curl -X POST http://localhost:8001/upstreams/example_upstream/targets \ + --data target='mockbin.org:80' + curl -X POST http://localhost:8001/upstreams/example_upstream/targets \ + --data target='httpbin.org:80' + ``` + +1. **Update the service** + + In the [services and routes](/gateway/latest/get-started/services-and-routes/) section of this guide, you created `example_service` which pointed + to an explicit host, `http://mockbin.org`. Now you'll modify that service to point to the upstream instead: + + ```sh + curl -X PATCH http://localhost:8001/services/example_service \ + --data host='example_upstream' + ``` + + You now have an upstream with two targets, `httpbin.org` and `mockbin.org`, and a service pointing to that upstream. + +1. **Validate** + + Validate that the upstream you configured is working by visiting the route `http://localhost:8000/mock` using a web browser or CLI. + Continue pinging the endpoint and the site should change from `httpbin` to `mockbin`. + +## What's next + +You've completed the Get Started with Kong guide, but a lot more is possible with [{{site.base_gateway}}](/gateway/latest). +The following are guides to advanced features of {{site.base_gateway}}: + +* [Monitoring with {{site.base_gateway}}](/gateway/{{ page.kong_version }}/production/monitoring/) +* [Securing {{site.base_gateway}} with RBAC](/gateway/{{ page.kong_version }}/kong-manager/auth/rbac/enable/) +* [Managing Workspaces and Team with {{site.base_gateway}}](/gateway/{{ page.kong_version }}/kong-manager/auth/workspaces-and-teams/) + diff --git a/src/gateway/get-started/prepare.md b/src/gateway/get-started/prepare.md new file mode 100644 index 000000000000..251ecdb77567 --- /dev/null +++ b/src/gateway/get-started/prepare.md @@ -0,0 +1,77 @@ +--- +title: Configure Services and Routes +--- + +Before getting started with using {{site.base_gateway}}, verify that it was +installed correctly, and that you’re ready to administer it. + +## Before you begin + +Before you start this section, make sure that: + +* {{site.base_gateway}} is installed and running. +* Kong Admin API ports are listening on the +appropriate port/IP/DNS settings. +* If using declarative configuration to configure {{site.base_gateway}}, +[decK](/deck/latest/installation) is installed. + +In this guide, an instance of {{site.base_gateway}} is referenced using +`localhost`. If you are not using `localhost`, make sure to replace `localhost` with the hostname +of your control plane instance. + +## Verify the {{site.base_gateway}} configuration + +Ensure that you can send requests to the gateway's Admin API using either cURL +or HTTPie. + +View the current configuration by issuing the following command in a terminal +window: + +```bash +curl -i -X GET http://localhost:8001 +``` + +## (Optional) Verify Control Plane and Data Plane connection + +If you're running {{site.base_gateway}} in [hybrid mode](/gateway/{{page.kong_version}}/production/deployment-topologies/hybrid-mode/), +you need to perform all tasks in this guide from the control plane. You can check +that all of your configurations are being pushed from the control plane to your +data planes using the Cluster Status CLI. + +Run the following from a control plane: + +```bash +curl -i -X GET http://localhost:8001/clustering/data-planes +``` + +The output shows all of the connected data plane instances in the cluster: + +```json +{ + "data": [ + { + "config_hash": "a9a166c59873245db8f1a747ba9a80a7", + "hostname": "data-plane-2", + "id": "ed58ac85-dba6-4946-999d-e8b5071607d4", + "ip": "192.168.10.3", + "last_seen": 1580623199, + "status": "connected" + }, + { + "config_hash": "a9a166c59873245db8f1a747ba9a80a7", + "hostname": "data-plane-1", + "id": "ed58ac85-dba6-4946-999d-e8b5071607d4", + "ip": "192.168.10.4", + "last_seen": 1580623200, + "status": "connected" + } + ], + "next": null +} +``` + +## Summary and next steps + +In this section, you learned about the methods of administering +{{site.base_gateway}} and how to access its configuration. Next, go on to +learn about [exposing your services with {{site.base_gateway}}](/gateway/{{page.kong_version}}/get-started//expose-services). diff --git a/src/gateway/get-started/proxy-caching.md b/src/gateway/get-started/proxy-caching.md new file mode 100644 index 000000000000..07574a1dbae5 --- /dev/null +++ b/src/gateway/get-started/proxy-caching.md @@ -0,0 +1,189 @@ +--- +title: Proxy Caching +content-type: tutorial +book: get-started +chapter: 4 +--- + +One of the ways Kong delivers performance is through caching. +The [Proxy Cache plugin](/hub/kong-inc/proxy-cache/) accelerates performance by caching +responses based on configurable response codes, content types, and request methods. +When caching is enabled, upstream services are not bogged down with repetitive requests, +because {{site.base_gateway}} responds on their behalf with cached results. Caching can be +enabled on specific {{site.base_gateway}} objects or for all requests globally. + +### Cache Time To Live (TTL) + +TTL governs the refresh rate of cached content, which is critical for ensuring +that clients aren't served outdated content. A TTL of 30 seconds means content older than +30 seconds is deemed expired and will be refreshed on subsequent requests. +TTL configurations should be set differently based on the type of the content the upstream +service is serving. + +* Static data that is rarely updated can have longer TTL + +* Dynamic data should use shorter TTL to avoid serving outdated data + +{{site.base_gateway}} follows [RFC-7234 section 5.2](https://tools.ietf.org/html/rfc7234) +for cached controlled operations. See the specification and the Proxy Cache +plugin [parameter reference](/hub/kong-inc/proxy-cache/#parameters) for more details on TTL configurations. + +## Enable caching + +The following tutorial walks through managing proxy caching across various aspects in {{site.base_gateway}}. + +### Prerequisites + +This chapter is part of the *Get Started with Kong* series. For the best experience, it is recommended that you follow the +series from the beginning. + +Start with the introduction [Get Kong](/gateway/latest/get-started/), which includes +a list of prerequisites and instructions for running a local {{site.base_gateway}}. + +Step two of the guide, [Services and Routes](/gateway/latest/get-started/services-and-routes), +includes instructions for installing a mock service used throughout this series. + +If you haven't completed these steps already, complete them before proceeding. + +### Global proxy caching + +Installing the plugin globally means *every* proxy request to {{site.base_gateway}} +will potentially be cached. + +1. **Enable proxy caching** + + The Proxy Cache plugin is installed by default on {{site.base_gateway}}, and can be enabled by + sending a `POST` request to the plugins object on the Admin API: + + ```sh + curl -i -X POST http://localhost:8001/plugins \ + --data "name=proxy-cache" \ + --data "config.request_method=GET" \ + --data "config.response_code=200" \ + --data "config.content_type=application/json; charset=utf-8" \ + --data "config.cache_ttl=30" \ + --data "config.strategy=memory" + ``` + + If configuration was successful, you will receive a `201` response code. + + This Admin API request configured a Proxy Cache plugin for all `GET` requests that resulted + in response codes of `200` and *response* `Content-Type` headers that *equal* + `application/json; charset=utf-8`. `cache_ttl` instructed the plugin to flush values after 30 seconds. + + The final option `config.strategy=memory` specifies the backing data store for cached responses. More + information on `strategy` can be found in the [parameter reference](/hub/kong-inc/proxy-cache/) + for the Proxy Cache plugin. + +1. **Validate** + + You can check that the Proxy Cache plugin is working by sending `GET` requests and examining + the returned headers. In step two of this guide, [services and routes](/gateway/latest/get-started/services-and-routes), + you setup a `/mock` route and service that can help you see proxy caching in action. + + First, make an initial request to the `/mock` route. The Proxy Cache plugin returns status + information headers prefixed with `X-Cache`, so use `grep` to filter for that information: + + ``` + curl -i -s -XGET http://localhost:8000/mock/requests | grep X-Cache + ``` + + On the initial request, there should be no cached responses, and the headers will indicate this with + `X-Cache-Status: Miss`. + + ``` + X-Cache-Key: c9e1d4c8e5fd8209a5969eb3b0e85bc6 + X-Cache-Status: Miss + ``` + + Within 30 seconds of the initial request, repeat the command to send an identical request and the + headers will indicate a cache `Hit`: + + ``` + X-Cache-Key: c9e1d4c8e5fd8209a5969eb3b0e85bc6 + X-Cache-Status: Hit + ``` + + The `X-Cache-Status` headers can return the following cache results: + + |State| Description| + |---|---| + |Miss| The request could be satisfied in cache, but an entry for the resource was not found in cache, and the request was proxied upstream.| + |Hit| The request could be satisfied in cache, but an entry for the resource was not found in cache, and the request was proxied upstream.| + |Refresh| The resource was found in cache, but could not satisfy the request, due to Cache-Control behaviors or reaching its hard-coded `cache_ttl` threshold.| + |Bypass| The request could not be satisfied from cache based on plugin configuration.| + +### Service level proxy caching + +The Proxy Cache plugin can be enabled for specific services. The request is the same as above, but the request is sent to the service URL: + +```sh +curl -X POST http://localhost:8001/services/example_service/plugins \ + --data "name=proxy-cache" \ + --data "config.request_method=GET" \ + --data "config.response_code=200" \ + --data "config.content_type=application/json; charset=utf-8" \ + --data "config.cache_ttl=30" \ + --data "config.strategy=memory" +``` + +### Route level proxy caching + +The Proxy Caching plugin can be enabled for specific routes. The request is the same as above, but the request is sent to the route URL: + +```sh +curl -X POST http://localhost:8001/routes/example_route/plugins \ + --data "name=proxy-cache" \ + --data "config.request_method=GET" \ + --data "config.response_code=200" \ + --data "config.content_type=application/json; charset=utf-8" \ + --data "config.cache_ttl=30" \ + --data "config.strategy=memory" +``` + +### Consumer level proxy caching + +In {{site.base_gateway}}, [consumers](/gateway/latest/admin-api/#consumer-object) are an abstraction that defines a user of a service. +Consumer-level proxy caching can be used to cache responses per consumer. + +1. **Create a consumer** + +Consumers are created using the consumer object in the Admin API. + +```sh +curl -X POST http://localhost:8001/consumers/ \ + --data username=sasha +``` + +1. **Enable caching for the consumer** + +```sh +curl -X POST http://localhost:8001/consumers/sasha/plugins \ + --data "name=proxy-cache" \ + --data "config.request_method=GET" \ + --data "config.response_code=200" \ + --data "config.content_type=application/json; charset=utf-8" \ + --data "config.cache_ttl=30" \ + --data "config.strategy=memory" +``` + +## Manage cached entities + +The Proxy Cache plugin supports administrative endpoints to manage cached entities. Administrators can +view and delete cached entities, or purge the entire cache by sending requests to the Admin API. + +To retrieve the cached entity, submit a request to the Admin API `/proxy-cache` endpoint with the +`X-Cache-Key` value of a known cached value. This request must be submitted prior to the TTL expiration, +otherwise the cached entity has been purged. + +For example, using the response headers above, pass the `X-Cache-Key` value of +`c9e1d4c8e5fd8209a5969eb3b0e85bc6` to the Admin API: + +```sh +curl -i http://localhost/proxy-cache/c9e1d4c8e5fd8209a5969eb3b0e85bc6 +``` + +A response with `200 OK` will contain full details of the cached entity. + +See the [Proxy Cache plugin documentation](/hub/kong-inc/proxy-cache/#admin-api) for the full list of the +Proxy Cache specific Admin API endpoints. diff --git a/src/gateway/get-started/quickstart/adding-consumers.md b/src/gateway/get-started/quickstart/adding-consumers.md new file mode 100644 index 000000000000..8e3e92d0fa58 --- /dev/null +++ b/src/gateway/get-started/quickstart/adding-consumers.md @@ -0,0 +1,90 @@ +--- +title: Adding Consumers +--- + +In the last section, we learned how to add plugins to Kong, in this section +we're going to learn how to add consumers to your Kong instances. Consumers are +associated to individuals using your Service, and can be used for tracking, access +management, and more. + +## Before you start + +* You have installed and started {{site.base_gateway}}, either through the [Docker quickstart](/gateway/{{page.kong_version}}/get-started) or a more [comprehensive installation](/gateway/{{page.kong_version}}/install). +* You have [configured a Service](/gateway/{{page.kong_version}}/get-started/services-and-routes) +* You have [enabled the key-auth plugin](/gateway/{{page.kong_version}}/get-started/enabling-plugins) + +## 1. Create a Consumer through the RESTful API + +Lets create a user named `Jason` by issuing the following request: + +```bash +curl -i -X POST \ + --url http://localhost:8001/consumers/ \ + --data "username=Jason" +``` + +You should see a response similar to the one below: + +```http +HTTP/1.1 201 Created +Content-Type: application/json +Connection: keep-alive + +{ + "username": "Jason", + "created_at": 1428555626000, + "id": "bbdf1c48-19dc-4ab7-cae0-ff4f59d87dc9" +} +``` + +Congratulations! You've just added your first consumer to Kong. + +**Note:** Kong also accepts a `custom_id` parameter when [creating +consumers][API-consumers] to associate a consumer with your existing user +database. + +## 2. Provision key credentials for your Consumer + +Now, we can create a key for our recently created consumer `Jason` by +issuing the following request: + +```bash +curl -i -X POST \ + --url http://localhost:8001/consumers/Jason/key-auth/ \ + --data 'key=ENTER_KEY_HERE' +``` + +## 3. Verify that your Consumer credentials are valid + +We can now issue the following request to verify that the credentials of +our `Jason` Consumer is valid: + +```bash +curl -i -X GET \ + --url http://localhost:8000 \ + --header "Host: example.com" \ + --header "apikey: ENTER_KEY_HERE" +``` + +## Next Steps + +Now that we've covered the basics of adding Services, Routes, Consumers and enabling +Plugins, feel free to read more on Kong in one of the following documents: + +- [Configuration file Reference][configuration] +- [CLI Reference][CLI] +- [Proxy Reference][proxy] +- [Admin API Reference][API] +- [Clustering Reference][cluster] + +Questions? Issues? Contact us on one of the [Community Channels](/community) +for help! + +[key-auth]: /hub/kong-inc/key-auth +[API-consumers]: /gateway/{{page.kong_version}}/admin-api#create-consumer +[enabling-plugins]: /gateway/{{page.kong_version}}/get-started/enabling-plugins +[configuration]: /gateway/{{page.kong_version}}/reference/configuration +[CLI]: /gateway/{{page.kong_version}}/reference/cli +[proxy]: /gateway/{{page.kong_version}}/reference/proxy +[API]: /gateway/{{page.kong_version}}/admin-api +[cluster]: /gateway/{{page.kong_version}}/reference/clustering diff --git a/src/gateway/get-started/quickstart/configuring-a-service.md b/src/gateway/get-started/quickstart/configuring-a-service.md new file mode 100644 index 000000000000..da6898007b7b --- /dev/null +++ b/src/gateway/get-started/quickstart/configuring-a-service.md @@ -0,0 +1,128 @@ +--- +title: Configuring a Service +--- + +In this section, you'll be adding an API to Kong. In order to do this, you'll +first need to add a [Service](/gateway/{{page.kong_version}}/admin-api/#service-object); that is the name Kong uses to refer to the upstream APIs and microservices +it manages. + +For the purpose of this guide, we'll create a Service pointing to the [Mockbin API][mockbin]. Mockbin is +an "echo" type public website which returns the requests it gets back to the requester, as responses. This +makes it helpful for learning how Kong proxies your API requests. + +Before you can start making requests against the Service, you will need to add a [Route](/gateway/{{page.kong_version}}/admin-api/#route-object) to it. +Routes specify how (and if) requests are sent to their Services after they reach Kong. There can be multiple Routes to a Service. + +After configuring the Service and a Route, you'll be able to proxy a request through Kong to Mockbin. + +By default, Kong exposes a [RESTful Admin API][API] on port `8001`. +You can use the Admin API to modify Kong's configuration, including adding +Services and Routes. + +## Before you start +You have installed and started {{site.base_gateway}}, either through the [Docker quickstart](/gateway/{{page.kong_version}}/get-started) or a more [comprehensive installation](/gateway/{{page.kong_version}}/install). + +## 1. Add a Service using the Admin API + +Issue the following `POST` request to add your first Service to Kong. +This instructs Kong to create a new Service named `example-service` which will accept traffic at `http://mockbin.org`. + +```bash +curl -i -X POST \ + --url http://localhost:8001/services/ \ + --data 'name=example-service' \ + --data 'url=http://mockbin.org' +``` + +You should receive a response similar to: + +```http +HTTP/1.1 201 Created +Content-Type: application/json +Connection: keep-alive + +{ + "host":"mockbin.org", + "created_at":1519130509, + "connect_timeout":60000, + "id":"92956672-f5ea-4e9a-b096-667bf55bc40c", + "protocol":"http", + "name":"example-service", + "read_timeout":60000, + "port":80, + "path":null, + "updated_at":1519130509, + "retries":5, + "write_timeout":60000 +} +``` + + +## 2. Add a Route for the Service + +Issue the following `POST` request to add a Route to the `example-service`. +Here, we are instructing Kong to proxy requests with a `Host` header that contains +`example.com` to the `example-service`. + +```bash +curl -i -X POST \ + --url http://localhost:8001/services/example-service/routes \ + --data 'hosts[]=example.com' +``` + +The answer should be similar to: + +```http +HTTP/1.1 201 Created +Content-Type: application/json +Connection: keep-alive + +{ + "created_at":1519131139, + "strip_path":true, + "hosts":[ + "example.com" + ], + "preserve_host":false, + "regex_priority":0, + "updated_at":1519131139, + "paths":null, + "service":{ + "id":"79d7ee6e-9fc7-4b95-aa3b-61d2e17e7516" + }, + "methods":null, + "protocols":[ + "http", + "https" + ], + "id":"f9ce2ed7-c06e-4e16-bd5d-3a82daef3f9d" +} +``` + +Kong is now aware of your Service and ready to proxy requests. + +## 3. Forward your requests through Kong + +Issue the following request to verify that Kong is properly forwarding +requests with the `Host` header to the `example-service`. Take note that proxy requests are handled on port `8000` [by default][proxy-port]. + +```bash +curl -i -X GET \ + --url http://localhost:8000/ \ + --header 'Host: example.com' +``` + +A successful response means Kong is now forwarding requests with a `Host: example.com` header to the Mockbin Service we configured in step #1. + +
      + +## Next Steps + +Now that you've added your Service to Kong, let's learn how to enable plugins. + +Go to [Enabling Plugins ›][enabling-plugins] + +[API]: /gateway/{{page.kong_version}}/admin-api +[enabling-plugins]: /gateway/{{page.kong_version}}/get-started/enabling-plugins +[proxy-port]: /gateway/{{page.kong_version}}/reference/configuration/#nginx-section +[mockbin]: https://mockbin.com/ diff --git a/src/gateway/get-started/quickstart/enabling-plugins.md b/src/gateway/get-started/quickstart/enabling-plugins.md new file mode 100644 index 000000000000..e00f108aacc2 --- /dev/null +++ b/src/gateway/get-started/quickstart/enabling-plugins.md @@ -0,0 +1,69 @@ +--- +title: Enabling Plugins +--- + +In this section, you'll learn how to configure Kong plugins. One of the core +principles of Kong is its extensibility through [plugins][plugins]. Plugins +allow you to easily add new features to your Service or make it easier to +manage. + +In the steps below, you will configure the [key-auth][key-auth] plugin to add +authentication to your Service. Prior to the addition of this plugin, **all** +requests to your Service would be proxied upstream. Once you add and configure this +plugin, **only** requests with the correct key(s) will be proxied - all +other requests will be rejected by Kong, thus protecting your upstream service +from unauthorized use. + +## Before you start + +* You have installed and started {{site.base_gateway}}, either through the [Docker quickstart](/gateway/{{page.kong_version}}/get-started) or a more [comprehensive installation](/gateway/{{page.kong_version}}/install) +* You have [configured your Service](/gateway/{{page.kong_version}}/get-started/services-and-routes) in {{site.base_gateway}} + +## 1. Configure the key-auth plugin + +To configure the key-auth plugin for the Service you configured in Kong, +issue the following cURL request: + +```bash +curl -i -X POST \ + --url http://localhost:8001/services/example-service/plugins/ \ + --data 'name=key-auth' +``` + +**Note:** This plugin also accepts a `config.key_names` parameter, which +defaults to `['apikey']`. It is a list of headers and parameters names (both +are supported) that are supposed to contain the apikey during a request. + +## 2. Verify that the plugin is properly configured + +Issue the following cURL request to verify that the [key-auth][key-auth] +plugin was properly configured on the Service: + +```bash +curl -i -X GET \ + --url http://localhost:8000/ \ + --header 'Host: example.com' +``` + +Since you did not specify the required `apikey` header or parameter, the +response should be `401 Unauthorized`: + +```http +HTTP/1.1 401 Unauthorized +... + +{ + "message": "No API key found in request" +} +``` + +## Next Steps + +Now that you've configured the **key-auth** plugin lets learn how to add +consumers to your Service so we can continue proxying requests through Kong. + +Go to [Adding Consumers ›][adding-consumers] + +[key-auth]: /hub/kong-inc/key-auth +[plugins]: /hub/ +[adding-consumers]: /gateway/{{page.kong_version}}/get-started/adding-consumers diff --git a/src/gateway/get-started/quickstart/index.md b/src/gateway/get-started/quickstart/index.md new file mode 100644 index 000000000000..00ecbb35c53b --- /dev/null +++ b/src/gateway/get-started/quickstart/index.md @@ -0,0 +1,121 @@ +--- +title: Start Kong Gateway +--- + +In this section, you'll learn how to install and manage your Kong Gateway instance. First, you'll start Kong Gateway to gain access to its Admin +API, where you'll manage entities including Services, Routes, and Consumers. + +## Start Kong Gateway using Docker with a database + +One quick way to get Kong Gateway up and running is by using [Docker with a PostgreSQL database](/gateway/{{page.kong_version}}/install/docker). We recommend this method to test out basic Kong Gateway functionality. + +For a comprehensive list of installation options, see our [Install page](/gateway/{{page.kong_version}}/install/). + +1. Create a Docker network: + + ```bash + docker network create kong-net + ``` + +2. Run a PostGreSQL container: + + ```bash + docker run -d --name kong-database \ + --network=kong-net \ + -p 5432:5432 \ + -e "POSTGRES_USER=kong" \ + -e "POSTGRES_DB=kong" \ + -e "POSTGRES_PASSWORD=kong" \ + postgres:9.6 + ``` + + +{% include_cached /md/enterprise/cassandra-deprecation.md %} + + + Data sent through the Admin API is stored in Kong's [datastore][datastore-section] (Kong + supports PostgreSQL and Cassandra). + +3. Prep your database: + + ```bash + docker run --rm \ + --network=kong-net \ + -e "KONG_DATABASE=postgres" \ + -e "KONG_PG_HOST=kong-database" \ + -e "KONG_PG_USER=kong" \ + -e "KONG_PG_PASSWORD=kong" \ + -e "KONG_CASSANDRA_CONTACT_POINTS=kong-database" \ + kong:latest kong migrations bootstrap + ``` + +4. Start Kong: + + ```bash + docker run -d --name kong \ + --network=kong-net \ + -e "KONG_DATABASE=postgres" \ + -e "KONG_PG_HOST=kong-database" \ + -e "KONG_PG_USER=kong" \ + -e "KONG_PG_PASSWORD=kong" \ + -e "KONG_CASSANDRA_CONTACT_POINTS=kong-database" \ + -e "KONG_PROXY_ACCESS_LOG=/dev/stdout" \ + -e "KONG_ADMIN_ACCESS_LOG=/dev/stdout" \ + -e "KONG_PROXY_ERROR_LOG=/dev/stderr" \ + -e "KONG_ADMIN_ERROR_LOG=/dev/stderr" \ + -e "KONG_ADMIN_LISTEN=0.0.0.0:8001, 0.0.0.0:8444 ssl" \ + -p 8000:8000 \ + -p 8443:8443 \ + -p 127.0.0.1:8001:8001 \ + -p 127.0.0.1:8444:8444 \ + kong:latest + ``` + +5. Navigate to `http://localhost:8001/`. + +## Kong default ports + +By default, Kong listens on the following ports: + +- `8000`: listens for incoming `HTTP` traffic from your + clients, and forwards it to your upstream services. +- `8001`: [Admin API][API] listens for calls from the command line over `HTTP`. +- `8443`: listens for incoming HTTPS traffic. This port has a + similar behavior to `8000`, except that it expects `HTTPS` + traffic only. This port can be disabled via the configuration file. +- `8444`: [Admin API][API] listens for `HTTPS` traffic. + +## Lifecycle commands + +{:.note} +> **Note**: If you are using Docker, [`exec`](https://docs.docker.com/engine/reference/commandline/exec) into the Docker container to use these commands. + +Stop Kong Gateway using the [stop][CLI] command: + +```bash +kong stop +``` + +Reload Kong Gateway using the [reload][CLI] command: + +```bash +kong reload +``` + +Start Kong Gateway using the [start][CLI] command: + +```bash +kong start +``` + +## Next Steps + +Now that you have Kong Gateway running, you can interact with the Admin API. + +To begin, go to [Configuring a Service ›][configuring-a-service] + +[configuration-loading]: /gateway/{{page.kong_version}}/reference/configuration/#configuration-loading +[CLI]: /gateway/{{page.kong_version}}/reference/cli +[API]: /gateway/{{page.kong_version}}/admin-api +[datastore-section]: /gateway/{{page.kong_version}}/reference/configuration/#datastore-section +[configuring-a-service]: /gateway/{{page.kong_version}}/get-started/services-and-routes diff --git a/src/gateway/get-started/rate-limiting.md b/src/gateway/get-started/rate-limiting.md new file mode 100644 index 000000000000..e5b5081aaa41 --- /dev/null +++ b/src/gateway/get-started/rate-limiting.md @@ -0,0 +1,177 @@ +--- +title: Rate Limiting +content-type: tutorial +book: get-started +chapter: 3 +--- + +Rate limiting is used to control the rate of requests sent to an upstream service. +It can be used to prevent DoS attacks, limit web scraping, and other forms of overuse. +Without rate limiting, clients have unlimited access to your upstream services, which +may negatively impact availability. + +## The Rate Limiting plugin + +{{site.base_gateway}} imposes rate limits on clients through the use of the [Rate Limiting plugin](/hub/kong-inc/rate-limiting). +When rate limiting is enabled, clients are restricted in the number of requests that can be made in a configurable period of time. +The plugin supports identifying clients as [consumers](/gateway/latest/admin-api/#consumer-object) +or by the client IP address of the requests. + +{:.note} +> This tutorial uses the [Rate Limiting](/hub/kong-inc/rate-limiting) plugin. Also available is the +[Rate Limiting Advanced](/hub/kong-inc/rate-limiting-advanced) +plugin. The advanced version provides additional features like support for the sliding window algorithm +and advanced Redis support for greater performance. + +## Managing rate limiting + +The following tutorial walks through managing rate limiting across various aspects in {{site.base_gateway}}. + +### Prerequisites + +This chapter is part of the *Get Started with Kong* series. For the best experience, it is recommended that you follow the +series from the beginning. + +Start with the introduction [Get Kong](/gateway/latest/get-started/), which includes +tool prerequisites and instructions for running a local {{site.base_gateway}}. + +Step two of the guide, [Services and Routes](/gateway/latest/get-started/services-and-routes), +includes instructions for installing a mock service used throughout this series. + +If you haven't completed these steps already, complete them before proceeding. + +### Global rate limiting + +Installing the plugin globally means *every* proxy request to {{site.base_gateway}} +will be subject to rate limit enforcement. + +1. **Enable rate limiting** + + The rate limiting plugin is installed by default on {{site.base_gateway}}, and can be enabled + by sending a `POST` request to the [plugins](/gateway/latest/admin-api/#add-plugin) object on the Admin API: + + ```sh + curl -i -X POST http://localhost:8001/plugins \ + --data name=rate-limiting \ + --data config.minute=5 \ + --data config.policy=local + ``` + + This command has instructed {{site.base_gateway}} to impose a maximum of 5 requests per minute per client IP address + for all routes and services. + + The `policy` configuration determines where {{site.base_gateway}} retrieves and increments limits. See the full + [plugin configuration reference](/hub/kong-inc/rate-limiting/#configuration) for details. + + You will see a response that contains the new plugin configuration, including identification information similar to: + + ```text + ... + "id": "fc559a2d-ac80-4be8-8e43-cb705524be7f", + "name": "rate-limiting", + "enabled": true + ... + ``` + +1. **Validate** + + After configuring rate limiting, you can verify that it was configured correctly and is working, + by sending more requests then allowed in the configured time limit. + +{% capture global_instructions %} +{% navtabs %} +{% navtab Command Line %} + +Run the following command to quickly send 6 mock requests: + +```sh +for _ in {1..6}; do {curl -s -i localhost:8000/mock/request; echo; sleep 1; } done +``` + +{% endnavtab %} +{% navtab Web browser %} + +Open [http://localhost:8000/mock/request](http://localhost:8000/mock/request) in your browser +and refresh the page 6 times within 1 minute. + +{% endnavtab %} +{% endnavtabs %} +{% endcapture %} +{{ global_instructions | indent }} + + After the 6th request, you should receive a 429 "API rate limit exceeded" error: + ``` + { + "message": "API rate limit exceeded" + } + ``` + +### Service level rate limiting + +The Rate Limiting plugin can be enabled for specific services. The request is the same as above, +but posted to the service URL: + +```sh +curl -X POST http://localhost:8001/services/example_service/plugins \ + --data "name=rate-limiting" \ + --data config.minute=5 \ + --data config.policy=local +``` + +### Route level rate limiting + +The Rate Limiting plugin can be enabled for specific routes. The request is the same as above, +but posted to the route URL: + +```sh +curl -X POST http://localhost:8001/routes/example_route/plugins \ + --data "name=rate-limiting" \ + --data config.minute=5 \ + --data config.policy=local +``` + +### Consumer level rate limiting + +In {{site.base_gateway}}, [consumers](/gateway/latest/admin-api/#consumer-object) are an abstraction +that defines a user of a service. Consumer-level rate limiting can be used to limit request rates per consumer. + +1. **Create a consumer** + + Consumers are created using the [consumer object](/gateway/latest/admin-api/#consumer-object) in the Admin API. + + ```sh + curl -X POST http://localhost:8001/consumers/ \ + --data username=jsmith + ``` + +1. **Enable rate limiting for the consumer** + + Using the consumer id, enable rate limiting for all routes and services for + the `jsmith` consumer. + + ```sh + curl -X POST http://localhost:8001/plugins \ + --data "name=rate-limiting" \ + --data "consumer.id=jsmith" \ + --data "config.second=5" \ + ``` + +## Advanced rate limiting + +In high scale production scenarios, effective rate limiting may require +advanced techniques. The basic Rate Limiting plugin described above +only allows you to define limits over fixed-time windows. Fixed-time windows +are sufficient for many cases, however, there are disadvantages: +* Bursts of requests around the boundary time of the fixed window, +may result in strained resources as the window counter is reset in the middle +of the traffic burst. +* Multiple client applications may be waiting for the fixed-time window to reset +so they can resume making requests. When the fixed-window resets, multiple clients +may flood the system with requests, causing a stampeding effect on your upstream services. + +The [Rate Limiting Advanced](/hub/kong-inc/rate-limiting-advanced/) +plugin is an enhanced version of the Rate Limiting plugin. The advanced plugin +provides additional limiting algorithm capabilities and superior performance compared +to the basic plugin. For more information on advanced rate limiting algorithms, see +[How to Design a Scalable Rate Limiting Algorithm with Kong API](https://konghq.com/blog/how-to-design-a-scalable-rate-limiting-algorithm). + diff --git a/src/gateway/get-started/ratelimiting.md b/src/gateway/get-started/ratelimiting.md new file mode 100644 index 000000000000..607cdb82e9cc --- /dev/null +++ b/src/gateway/get-started/ratelimiting.md @@ -0,0 +1,184 @@ +--- +title: Configure Rate Limiting +content-type: tutorial +--- + + +## What is rate limiting? + +Rate limiting is used to control the rate of requests sent to an upstream service. It can be used to prevent DoS attacks, limit web scraping, and other forms of overuse. Without rate limiting, a user may make requests as often as they like, this leads to traffic spikes and it can impact other users of your upstream services. In {{site.base_gateway}} rate limiting allows you to set parameters that limit requests to your upstream service. + + +## The rate limiting plugin + +{{site.base_gateway}} manages rate limiting through the use of Kong's [Rate Limiting plugin](/hub/kong-inc/rate-limiting). The rate limiting plugin has an open source and an enterprise version, with the enterprise version giving you access to features like [sliding window algorithm support](https://en.wikipedia.org/wiki/Sliding_window_protocol), and Redis support. + + +The rate limiting plug-ins limit how often each user can call the API. This protects them from inadvertent or malicious overuse. Without rate limiting, each user may request as often as they like, which can lead to “spikes” of requests that starve other consumers. After rate limiting is enabled, they are limited to a fixed number of requests per second. Kong offers an open source and an Enterprise version of the rate limiting plug-in, with the Enterprise version providing support for the sliding window algorithm to prevent the API from being overloaded near window boundaries, and adds Redis support for greater performance. For this guide we will use the Enterprise version of plug-in. More details on the advanced rate limiting plug-in can be found here. + + +Kong's [Rate Limiting plugin](/hub/kong-inc/rate-limiting) lets you restrict how many requests your upstream services receive from your API consumers, or how often each user can call the API. + +{:.note} +> The [**Rate Limiting Advanced**](/hub/kong-inc/rate-limiting-advanced) plugin provides support for the sliding window algorithm to prevent the API from being overloaded near the window boundaries, and adds Redis support for greater performance. + + + +## Configure the Rate Limiting plugin + + +To activate a plugin send a `POST` request to the [plugins](/gateway/latest/admin-api/#add-plugin) object of the Admin API: + +```sh +curl -i -X POST http://localhost:8001/plugins \ + --data name=rate-limiting \ + --data config.minute=5 \ + --data config.policy=local +``` + +This request configures the rate limiting plugin to enforce rate limiting on requests that exceed 5 per minute. + +### validate rate limiting + +After configuring rate limiting, you can verify that it was configured correctly and is working, by creating 6 requests within a 5 minute period. +To validate rate limiting, send a request to the API six (6) times from the CLI to confirm the requests are rate limited. +If you configured {{site.base_gateway}} with the [configure services and routes](/gateway/latest/get-started/configure-services-and-routes) guide use the example below, otherwise substitute the existing values for your own: + +{% navtabs %} +{% navtab Admin API %} + +```sh +curl -i -X GET http://localhost:8000/mock/request +``` + +{% endnavtab %} +{% navtab Web browser %} + +Or you can follow these instructions from your web browser: + +1. Enter `localhost:8000/mock` and refresh your browser six times. + After the sixth request, you’ll receive an error message. +2. Wait at least 30 seconds and try again. + The service will be accessible until the sixth access attempt within a 30-second window. + +{% endnavtab %} +{% endnavtabs %} + +After the 6th request, you should receive a 429 "API rate limit exceeded" error: +``` +{ +"message": "API rate limit exceeded" +} +``` + +Every request triggers a counter that checks against the policy that was configured in the `POST` request. +The value `config.policy = local` instructs {{site.base_gateway}} to store the policies and counters locally in memory. +The available options for `config.policy` are: + +* `local` - Counters are stored locally in-memory on the node. +* `cluster` - Counters are stored in the Kong data store and shared across the nodes. +* `redis` - Counters are stored on a Redis server and shared across the nodes. + + +### Rate limiting by domain + + +The Rate Limiting plugin can be enabled and associated to three different scopes: + +* Service — restricts every consumer making requests to the service. + +* Route — restricts every consumer making requests to the specific route of the service. + +* Consumer — restricts only that specified consumer making requests to any routes of the service, using a `consumer_id`. + + +### Service-level rate limiting + +You can rate limit specific services in order to restrict requests to an upstream application. + +```sh + +curl -X POST http://localhost:8001/services/example_service/plugins \ +--data "name=rate-limiting" \ +--data config.minute=5 \ +--data config.policy=local + +``` + + +### Route-level rate limiting + +You can limit traffic to a specific route: + +```sh + +curl -X POST http://localhost:8001/routes/mock/plugins \ +--data "name=rate-limiting" \ +--data "config.minute=2" \ +--data "config.hour=100" + +``` + +If you did not follow the [configure services and routes](/gateway/latest/get-started/configure-services-and-routes) guide, replace the `mock` value with a `route_id`. + + +### Consumer-level rate limiting + +Consumer-level rate limiting can be used when trying to apply rate limiting rules to specific consumer. Consumers are created using the [consumer object](/gateway/latest/admin-api/#consumer-object) in the Admin API. Because you haven't created a consumer yet, to try this type of rate limiting out you will have to first create a consumer: + + +```sh + +curl -X POST http://localhost:8001/consumers/ \ + --data username=example_consumer + +``` + +And with the `example_consumer` variable, create another request to the `plugins` object, and pass `example_consumer` to the `consumer.id` parameter. +```sh + +curl -X POST http://localhost:8001/plugins \ +--data "name=rate-limiting" \ +--data "consumer.id=example_consumer" \ +--data "config.second=5" \ +``` + + +## The Rate Limiting Advanced plugin + +Rate Limiting Advanced provides: + +* Additional configurations: `limit`, `window_size`, and `sync_rate` +* Support for Redis Sentinel, Redis cluster, and Redis SSL +* Increased performance: Rate Limiting Advanced has better throughput performance with better accuracy. Configure `sync_rate` to periodically sync with backend storage. +* More limiting algorithms to choose from: These algorithms are more accurate and they enable configuration with more specificity. Learn more about our algorithms in How to Design a Scalable Rate Limiting Algorithm. +* Consumer groups support: apply different rate limiting configurations to select groups of consumers. + + +### Additional configuration + +The configuration process for the Rate Limiting Advanced plugin is similar to configuring the Rate Limiting plugin. To configure the Rate Limiting Advanced plugin create a `POST` request like this: + +```sh + +curl -i -X POST http://localhost:8001/plugins \ +--data name=rate-limiting-advanced \ +--data config.limit=5 \ +--data config.window_size=30 + +``` + +This request utilizes the `config.limit` and `config.window_size` form parameters. + + +* config.limit: Number of requests allows per window. +* config.window_size: Window size to track request for in seconds. +* config.sync_rate: how often to sync counter data to the central data store. `-1` ignores sync behavior entirely and only stores counters in node memory, `>0 ` sync the counters in that many number of seconds. + + +The word "window" here refers to a window of time, and the requests that can be made within that time frame. In the request you created, 5 requests can be made within a 30 second window of time. On the 6th request, the server will return a `429` response code. You can add multiple `window_size` and `config.limit` parameters to this request to specify, with granularity, the rate limiting rules. + + +### Next steps + +The next tutorial in this series walks you through how and why to [configure proxy caching](/gateway/latest/get-started/configure-ratelimiting/). diff --git a/src/gateway/get-started/services-and-routes.md b/src/gateway/get-started/services-and-routes.md new file mode 100644 index 000000000000..4612d6a3ca5b --- /dev/null +++ b/src/gateway/get-started/services-and-routes.md @@ -0,0 +1,427 @@ +--- +title: Services and Routes +content-type: tutorial +book: get-started +chapter: 2 +--- + +{{site.base_gateway}} administrators work with an object model to define their +desired traffic management policies. Two important objects in that model are +[services](/gateway/latest/admin-api/#service-object) and +[routes](/gateway/latest/admin-api/#route-object). Services and routes are configured in a +coordinated manner to define the routing path that requests and responses will take +through the system. + +The high level overview below shows requests arriving at routes and being forward to services, +with responses taking the opposite pathway: + +![Services and routes](/assets/images/docs/getting-started-guide/route-and-service.png) + +### What is a service + +In {{site.base_gateway}}, a service is an abstraction of an existing upstream application. +Services can store collections of objects like plugin configurations, and policies, and they can be +associated with routes. + +When defining a service, the administrator provides a *name* and the upstream application connection +information. The connection details can be provided in the `url` field as a single string, or by providing +individual values for `protocol`, `host`, `port`, and `path` individually. + +Services have a one-to-many relationship with upstream applications, which allows administrators to +create sophisticated traffic management behaviors. + +### What is a route + +A route is a path to a resource within an upstream application. Routes are added to services to allow +access to the underlying application. In {{site.base_gateway}}, routes typically map to endpoints that are +exposed through the {{site.base_gateway}} application. Routes can also define rules that match requests to +associated services. Because of this, one route can reference multiple endpoints. A basic route should have a +name, path or paths, and reference an existing service. + +You can also configure routes with: +* Protocols: The protocol used to communicate with the upstream application. +* Hosts: Lists of domains that match a route +* Methods: HTTP methods that match a route +* Headers: Lists of values that are expected in the header of a request +* Redirect status codes: HTTPS status codes +* Tags: Optional set of strings to group routes with + +## Managing services and routes + +The following tutorial walks through managing and testing services and routes using the +{{site.base_gateway}} [Admin API](/gateway/latest/admin-api). {{site.base_gateway}} +also offers other options for configuration management including +[Kong {{site.konnect_saas}}](/konnect/) and [decK](/deck/latest/). + +In this section of the tutorial, you will complete the following steps: +* Create a service pointing to the [Mockbin](https://mockbin.org/) API, which provides testing facilities + for HTTP requests and responses. +* Define a route by providing a URL path that will be available to clients on the running {{site.base_gateway}}. +* Use the new Mockbin service to echo a test request, helping you understand how + {{site.base_gateway}} proxies API requests. + +### Prerequisites + +This chapter is part of the *Get Started with Kong* series. For the best experience, it is recommended that you follow the +series from the beginning. + +The introduction, [Get Kong](/gateway/latest/get-started/), includes +tool prerequisites and instructions for running a local {{site.base_gateway}}. + +If you haven't completed the [Get Kong](/gateway/latest/get-started/) step already, +complete that before proceeding. + +### Managing services + +1. **Creating services** + + To add a new service, send a `POST` request to {{site.base_gateway}}'s + Admin API `/services` route: + + ```sh + curl -i -s -X POST http://localhost:8001/services \ + --data name=example_service \ + --data url='http://mockbin.org' + ``` + + This request instructs {{site.base_gateway}} to create a new + service mapped to the upstream URL `http://mockbin.org`. + + In our example, the request body contained two strings: + + * `name`: The name of the service + * `url` : An argument that populates the `host`, `port`, and `path` attributes of the service + + If your request was successful, you will see a `201` response header from {{site.base_gateway}} + confirming that your service was created and the response body will be similar to: + + ```text + { + "host": "mockbin.org", + "name": "example_service", + "enabled": true, + "connect_timeout": 60000, + "read_timeout": 60000, + "retries": 5, + "protocol": "http", + "path": null, + "port": 80, + "tags": null, + "client_certificate": null, + "tls_verify": null, + "created_at": 1661346938, + "updated_at": 1661346938, + "tls_verify_depth": null, + "id": "3b2be74e-335b-4f25-9f08-6c41b4720315", + "write_timeout": 60000, + "ca_certificates": null + } + ``` + + Fields that are not explicitly provided in the create request are automatically given + a default value based on the current {{site.base_gateway}} configuration. + +1. **Viewing service configuration** + + When you create a service, {{site.base_gateway}} assigns it a unique `id` as shown in the response above. + The `id` field, or the name provided when creating the service, can be used to identify the service + in subsequent requests. This is the service URL and takes the form of `/services/{service name or id}`. + + To view the current state of a service, make a `GET` request to the service + URL. + + ```sh + curl -X GET http://localhost:8001/services/example_service + ``` + + A successful request will contain the current configuration of your service in the response + body and will look something like the following snippet: + + ```text + { + "host": "mockbin.org", + "name": "example_service", + "enabled": true, + ... + } + ``` + +1. **Updating services** + + Existing service configurations can be updated dynamically by sending a `PATCH` + request to the service URL. + + To dynamically set the service retries from `5` to `6`, send this `PATCH` request: + + ```sh + curl --request PATCH \ + --url localhost:8001/services/example_service \ + --data retries=6 + ``` + + The response body contains the full service configuration including the updated value: + + ```sh + { + "host": "mockbin.org", + "name": "example_service", + "enabled": true, + "retries": 6, + ... + } + ``` + +1. **Listing services** + + You can list all current services by sending a `GET` request to the base `/services` URL. + + ```sh + curl -X GET http://localhost:8001/services + ``` + +The [Admin API documentation](/gateway/latest/admin-api/#update-service) provides +the full service update specification. + +### Managing routes + +1. **Creating routes** + + Routes define how requests are proxied by {{site.base_gateway}}. You can + create a route associated with a specific service by sending a `POST` + request to the service URL. + + Configure a new route on the `/mock` path to direct traffic to the `example_service` service + created earlier: + + + ```sh + curl -i -X POST http://localhost:8001/services/example_service/routes \ + --data 'paths[]=/mock' \ + --data name=example_route + ``` + + If the route was successfully created, the API returns a `201` response code and a response body like this: + + ```text + { + "paths": [ + "/mock" + ], + "methods": null, + "sources": null, + "destinations": null, + "name": "example_route", + "headers": null, + "hosts": null, + "preserve_host": false, + "regex_priority": 0, + "snis": null, + "https_redirect_status_code": 426, + "tags": null, + "protocols": [ + "http", + "https" + ], + "path_handling": "v0", + "id": "52d58293-ae25-4c69-acc8-6dd729718a61", + "updated_at": 1661345592, + "service": { + "id": "c1e98b2b-6e77-476c-82ca-a5f1fb877e07" + }, + "response_buffering": true, + "strip_path": true, + "request_buffering": true, + "created_at": 1661345592 + } + ``` + +1. **Viewing route configuration** + + Like services, when you create a route, {{site.base_gateway}} + assigns it a unique `id` as shown in the response above. The `id` field, or the name provided + when creating the route, can be used to identify the route in subsequent requests. + The route URL can take either of the following forms: + + * `/services/{service name or id}/routes/{route name or id}` + * `/routes/{route name or id}` + + To view the current state of the `example_route` route, make a `GET` request to the route URL: + + ```sh + curl -X GET http://localhost:8001/services/example_service/routes/example_route + ``` + + The response body contains the current configuration of your route: + + ```text + { + "paths": [ + "/mock" + ], + "methods": null, + "sources": null, + "destinations": null, + "name": "example_route", + "headers": null, + "hosts": null, + "preserve_host": false, + "regex_priority": 0, + "snis": null, + "https_redirect_status_code": 426, + "tags": null, + "protocols": [ + "http", + "https" + ], + "path_handling": "v0", + "id": "189e0a57-205a-4f48-aec6-d57f2e8a9985", + "updated_at": 1661347991, + "service": { + "id": "3b2be74e-335b-4f25-9f08-6c41b4720315" + }, + "response_buffering": true, + "strip_path": true, + "request_buffering": true, + "created_at": 1661347991 + } + ``` + +1. **Updating routes** + + Like services, routes can be updated dynamically by sending a `PATCH` + request to the route URL. + + Tags are an optional set of strings that can be associated with the route for grouping and filtering. + You can assign tags by sending a `PATCH` request to the + [services endpoint](/gateway/latest/admin-api/#update-route) and specifying a route. + + Update the route by assigning it a tag with the value `tutorial`: + + ``` + curl --request PATCH \ + --url localhost:8001/services/example_service/routes/example_route \ + --data tags="tutorial" + ``` + + The above example used the service and route `name` fields for the route URL. + + If the tag was successfully applied, the response body will contain the following JSON value: + + ```text + ... + "tags":["tutorial"] + ... + ``` + +1. **Listing routes** + + The Admin API also supports the listing of all routes currently configured: + + ```sh + curl http://localhost:8001/routes + ``` + + This request returns an HTTP `200` status code and a JSON response body object array with all of + the routes configured on this {{site.base_gateway}} instance. Your response should look like the following: + + ```text + { + "next": null, + "data": [ + { + "paths": [ + "/mock" + ], + "methods": null, + "sources": null, + "destinations": null, + "name": "example_route", + "headers": null, + "hosts": null, + "preserve_host": false, + "regex_priority": 0, + "snis": null, + "https_redirect_status_code": 426, + "tags": [ + "tutorial" + ], + "protocols": [ + "http", + "https" + ], + "path_handling": "v0", + "id": "52d58293-ae25-4c69-acc8-6dd729718a61", + "updated_at": 1661346132, + "service": { + "id": "c1e98b2b-6e77-476c-82ca-a5f1fb877e07" + }, + "response_buffering": true, + "strip_path": true, + "request_buffering": true, + "created_at": 1661345592 + } + ] + } + ``` + +The [Admin API documentation](/gateway/latest/admin-api/#route-object) has the +full specification for managing route objects. + +## Proxy a request + +Kong is an API Gateway, it takes requests from clients and routes them to the appropriate upstream application +based on a the current configuration. Using the service and route that was previously configured, you can now +access `https://mockbin.org/` using `http://localhost:8000/mock`. + +By default, {{site.base_gateway}}'s Admin API listens for administrative requests on port `8001`, this is sometimes referred to as the +*control plane*. Clients use port `8000` to make data requests, and this is often referred to as the *data plane*. + +Mockbin provides a `/requests` resource which will echo back to clients information about requests made to it. +Proxy a request through {{site.base_gateway}} to the `/requests` resource: + +```sh +curl -X GET http://localhost:8000/mock/requests +``` + +You should see a response similar to the following: +```text +{ + "startedDateTime": "2022-08-24T13:44:28.449Z", + "clientIPAddress": "172.19.0.1", + "method": "GET", + "url": "http://localhost/requests", + "httpVersion": "HTTP/1.1", + "cookies": {}, + "headers": { + "host": "mockbin.org", + "connection": "close", + "accept-encoding": "gzip", + "x-forwarded-for": "172.19.0.1,98.63.188.11, 162.158.63.41", + "cf-ray": "73fc85d999f2e6b0-EWR", + "x-forwarded-proto": "http", + "cf-visitor": "{\"scheme\":\"http\"}", + "x-forwarded-host": "localhost", + "x-forwarded-port": "80", + "x-forwarded-path": "/mock/requests", + "x-forwarded-prefix": "/mock", + "user-agent": "curl/7.79.1", + "accept": "*/*", + "cf-connecting-ip": "00.00.00.00", + "cdn-loop": "cloudflare", + "x-request-id": "1dae4762-5d7f-4d7b-af45-b05720762878", + "via": "1.1 vegur", + "connect-time": "0", + "x-request-start": "1661348668447", + "total-route-time": "0" + }, + "queryString": {}, + "postData": { + "mimeType": "application/octet-stream", + "text": "", + "params": [] + }, + "headersSize": 588, + "bodySize": 0 +} +``` + diff --git a/src/gateway/glossary.md b/src/gateway/glossary.md new file mode 100644 index 000000000000..52379792710c --- /dev/null +++ b/src/gateway/glossary.md @@ -0,0 +1,34 @@ +--- +title: Glossary + +--- + +| Term | Definition | +| ----------- | ----------- | +|Admin | An admin is a {{site.base_gateway}} user account capable of accessing the Admin API or Kong Manager. | +|Authentication| Authentication is the process by which a system validates the identity of a user account. | +|Authorization| Authorization is the system of defining access to certain resources. In {{site.base_gateway}}, role-based access control (RBAC) is the main authorization mode. | +|Beta| See [stability](/gateway/{{page.kong_version}}/stability). | +|Catalog| A list of all specs within a Dev Portal instance. This catalog can react to developer permissions, allowing a given developer to see whatever specs their role permits.| +|Client| A Kong client refers to the downstream client making requests to {{site.base_gateway}}’s proxy port. It could be another service in a distributed application, a user’s identity, a user’s browser, or a specific device. | +|Consumer| A consumer object represents the client of a service. A consumer is also the Admin API entity representing a developer or machine using the API. | +|Credential| A unique string associated with a consumer; also referred to as an API key. | +|Dev Portal| A web application that functions as a collection of service version specs and documentation objects. The purpose of a portal is to allow registration and consumption of services running through Kong to other teams, developers, and partners.| +|Groups| Sets of role-defined entities.| +|Host | A host represents the domain hosts (using DNS) intended to receive upstream traffic. In {{site.base_gateway}}, it is a list of domain names that match a route object. | +| Kong plugin| A plugin developed, maintained, and supported by Kong.| +|Permission| A permission is a policy representing the ability to create, read, update, or destroy an Admin API entity defined by endpoints.| +|Plugin| Plugins provide advanced functionality and extend the use of {{site.base_gateway}}, allowing you to add new features to your gateway. Plugins can be configured to run in a variety of contexts, ranging from a specific route to all upstreams. Plugins can perform operations in your environment, such as authentication, rate-limiting, or transformations on a proxied request.| +|Proxy| {{site.base_gateway}} is a reverse proxy that manages traffic between clients and hosts. As a gateway, Kong’s proxy functionality evaluates any incoming HTTP request against configured routes. | +|Rate Limiting| Rate limiting allows you to restrict how many requests your upstream services receive from your API consumers, or how often each user can call the API. Rate limiting protects the APIs from inadvertent or malicious overuse.| +|Role |A role is a set of permissions that may be reused and assigned to admins.| +|Route| A route, also referred to as a route object, defines rules to match client requests to upstream services. Each route is associated with a service, and a service may have multiple routes associated with it. routes are entry points to upstream services.| +|Service| A service, also referred to as a service object, is the upstream APIs and microservices that Kong manages. For example, a service could be a data transformation microservice or a billing API. The main attribute of a service is its URL, the destination where {{site.base_gateway}} proxies traffic. The URL can be set as a single string, or by specifying its protocol, host, port, and path. | +|Super admin| A super admin, or any role with read and write access to the /admins and /rbac endpoints, creates new Roles and customize permissions. A super admin can invite and disable other admin accounts, assign and revoke roles to admins, create new roles with custom permissions, and create new workspaces.| +|Spec| An OpenAPI definition of your service in YAML or JSON format. Can be uploaded to Dev Portal to share with developers in your organization. | +|Tags| Tags are customer-defined labels that let you manage, search for, and filter core entities using the `?tags` querystring parameter. Tags can be added when creating or editing most core entities. Each tag must be composed of one or more alphanumeric characters,` \_\`, `-`, `.` or `~`. | +|Teams| Teams organize developers into working groups.| +|Tech preview | See [stability](/gateway/latest/stability). | +|Third-party or community plugin| A custom plugin developed, maintained, and supported by an external developer, not by Kong. Kong does not test these plugins, or update their version compatibility.| +|Upstream| An upstream object refers to the API or service managed by {{site.base_gateway}}, to which client requests are forwarded. An upstream object represents a virtual hostname and can be used to load balance incoming requests over multiple services.| +|Workspaces| Workspaces enable an organization to segment objects and admins into namespaces. The segmentation allows teams of admins sharing the same {{site.base_gateway}} cluster to adopt roles for interacting with specific objects.| \ No newline at end of file diff --git a/src/gateway/how-kong-works/health-checks.md b/src/gateway/how-kong-works/health-checks.md new file mode 100644 index 000000000000..fad7c0066cb0 --- /dev/null +++ b/src/gateway/how-kong-works/health-checks.md @@ -0,0 +1,356 @@ +--- +title: Health Checks and Circuit Breakers Reference +--- + +You can make an API proxied by Kong use a [ring-balancer][ringbalancer], configured +by adding an [upstream][upstream] entity that contains one or more [target][ringtarget] +entities, each target pointing to a different IP address (or hostname) and +port. The ring-balancer will balance load among the various targets, and based +on the [upstream][upstream] configuration, will perform health checks on the targets, +marking them as healthy or unhealthy based on whether they are responsive or not. The +ring-balancer will then only route traffic to healthy targets. + +Kong supports two kinds of health checks, which can be used separately or in +conjunction: + +* **active checks**, where a specific HTTP or HTTPS endpoint in the target is +periodically requested and the health of the target is determined based on its +response; + +* **passive checks** (also known as **circuit breakers**), where Kong analyzes +the ongoing traffic being proxied and determines the health of targets based +on their behavior responding to requests. + +## Defining healthy and unhealthy + +### Targets + +The objective of the health checks functionality is to dynamically mark +targets as healthy or unhealthy, **for a given Kong node**. There is +no cluster-wide synchronization of health information: each Kong node +determines the health of its targets separately. This is desirable since at a +given point one Kong node may be able to connect to a target successfully +while another node is failing to reach it: the first node will consider +it healthy, while the second will mark it as unhealthy and start routing +traffic to other targets of the upstream. + +Either an active probe (on active health checks) or a proxied request +(on passive health checks) produces data which is used to determine +whether a target is healthy or unhealthy. A request may produce a TCP +error, timeout, or produce an HTTP status code. Based on this +information, the health checker updates a series of internal counters: + +* If the returned status code is one configured as "healthy", it will +increment the "Successes" counter for the target and clear all its other +counters; +* If it fails to connect, it will increment the "TCP failures" counter +for the target and clear the "Successes" counter; +* If it times out, it will increment the "timeouts" counter +for the target and clear the "Successes" counter; +* If the returned status code is one configured as "unhealthy", it will +increment the "HTTP failures" counter for the target and clear the "Successes" counter. + +If any of the "TCP failures", "HTTP failures" or "timeouts" counters reaches +their configured threshold, the target will be marked as unhealthy. + +If the "Successes" counter reaches its configured threshold, the target will be +marked as healthy. + +The list of which HTTP status codes are "healthy" or "unhealthy", and the +individual thresholds for each of these counters are configurable on a +per-upstream basis. Below, we have an example of a configuration for an +Upstream entity, showcasing the default values of the various fields +available for configuring health checks. A description of each +field is included in the [Admin API][addupstream] reference documentation. + +```json +{ + "name": "service.v1.xyz", + "healthchecks": { + "active": { + "concurrency": 10, + "healthy": { + "http_statuses": [ 200, 302 ], + "interval": 0, + "successes": 0 + }, + "http_path": "/", + "timeout": 1, + "unhealthy": { + "http_failures": 0, + "http_statuses": [ 429, 404, 500, 501, + 502, 503, 504, 505 ], + "interval": 0, + "tcp_failures": 0, + "timeouts": 0 + } + }, + "passive": { + "healthy": { + "http_statuses": [ 200, 201, 202, 203, + 204, 205, 206, 207, + 208, 226, 300, 301, + 302, 303, 304, 305, + 306, 307, 308 ], + "successes": 0 + }, + "unhealthy": { + "http_failures": 0, + "http_statuses": [ 429, 500, 503 ], + "tcp_failures": 0, + "timeouts": 0 + } + }, + "threshold": 0 + }, + "slots": 10 +} +``` + +If an upstream is unhealthy (the available capacity % is less than the configured +threshold), Kong will respond to requests to the upstream with +`503 Service Unavailable`. + +Note: + +1. Health checks operate only on [*active* targets][targetobject] and do not + modify the *active* status of a target in the Kong database. +2. Unhealthy targets will not be removed from the loadbalancer, and hence will + not have any impact on the balancer layout when using the hashing algorithm + (they will just be skipped). +3. The [DNS caveats][dnscaveats] and [balancer caveats][balancercaveats] + also apply to health checks. If using hostnames for the targets, then make + sure the DNS server always returns the full set of IP addresses for a name, + and does not limit the response. *Failing to do so might lead to health + checks not being executed.* + +### Upstreams + +Along with health check functionality on individual targets, Upstreams also +have a notion of health. The health of an Upstream is determined based on the +status of its Targets. + +Configuration of the Upstream's health is done though the property +`healthchecks.threshold`. This is a percentage of minimum available target +"weight" (capacity) for the Upstream to be considered healthy. + +Here is a simple example: + +- Assume an Upstream configured with `healthchecks.threshold=55`. +- It has 5 targets, each with `weight=100`, so the total weight in the ring-balancer is 500. + +When failures start to occur, the circuit-breaker for the first target trips. +It is now considered unhealthy. This means that in the ring-balancer, 20% of +the capacity is now unhealthy (100 weight out of 500). This is still above the +threshold of 55, so the remaining targets will serve the traffic of the failed +one. + +When a second failure occurs, another target fails, and another 100 weight is lost +as unhealthy. Now the ring-balancer operates at 60% of its capacity, but still +within the configured threshold. + +If we assume that the 2 failures occured due to a system overload, we can now assume +that the remaining 60% will also not be able to cope with the full load and soon a third +node will fail, reducing healthy capacity to 40%. At this point, the Upstream health +will be less than its threshold, and it will be marked as unhealthy itself. + +Once it enters an unhealthy state, the Upstream will only return errors. This lets the +targets/services recover from the cascading failure they were experiencing. + +Once the Targets start recovering and the Upstream's available capacity passes the +threshold again, the health status of the ring-balancer will automatically be updated. + +## Types of health checks + +### Active health checks + +Active health checks, as the name implies, actively probe targets for +their health. When active health checks are enabled in an upstream entity, +Kong will periodically issue HTTP or HTTPS requests to a configured path at each target +of the upstream. This allows Kong to automatically enable and disable targets +in the balancer based on the [probe results](#healthy-and-unhealthy-targets). + +The periodicity of active health checks can be configured separately for +when a target is healthy or unhealthy. If the `interval` value for either +is set to zero, the checking is disabled at the corresponding scenario. +When both are zero, active health checks are disabled altogether. + +
      +Note: Active health checks currently only support HTTP/HTTPS targets. They +do not apply to Upstreams assigned to Services with the protocol attribute set to "tcp" or "tls". +
      + +### Passive health checks (circuit breakers) + +Passive health checks, also known as circuit breakers, are +checks performed based on the requests being proxied by Kong (HTTP/HTTPS/TCP), +with no additional traffic being generated. When a target becomes +unresponsive, the passive health checker will detect that and mark +the target as unhealthy. The ring-balancer will start skipping this +target, so no more traffic will be routed to it. + +Once the problem with a target is solved and it is ready to receive +traffic again, the Kong administrator can manually inform the +health checker that the target should be enabled again, via an +Admin API endpoint: + +```bash +curl -i -X POST http://localhost:8001/upstreams/my_upstream/targets/10.1.2.3:1234/healthy +``` + +Response: +``` +HTTP/1.1 204 No Content +``` + +This command will broadcast a cluster-wide message so that the "healthy" +status is propagated to the whole [Kong cluster][clustering]. This will cause Kong nodes to +reset the health counters of the health checkers running in all workers of the +Kong node, allowing the ring-balancer to route traffic to the target again. + +Passive health checks have the advantage of not producing extra +traffic, but they are unable to automatically mark a target as +healthy again: the "circuit is broken", and the target needs to +be re-enabled again by the system administrator. + +## Summary of pros and cons + +* Active health checks can automatically re-enable a target in the +ring balancer as soon as it is healthy again. Passive health checks cannot. +* Passive health checks do not produce additional traffic to the +target. Active health checks do. +* An active health checker demands a known URL with a reliable status response +in the target to be configured as a probe endpoint (which may be as +simple as `"/"`). Passive health checks do not demand such configuration. +* By providing a custom probe endpoint for an active health checker, +an application may determine its own health metrics and produce a status +code to be consumed by Kong. Even though a target continues to serve +traffic which looks healthy to the passive health checker, +it would be able to respond to the active probe with a failure +status, essentially requesting to be relieved from taking new traffic. + +It is possible to combine the two modes. For example, one can enable +passive health checks to monitor the target health based solely on its +traffic, and only use active health checks while the target is unhealthy, +in order to re-enable it automatically. + +## Enabling and disabling health checks + +### Enabling active health checks + +To enable active health checks, you need to specify the configuration items +under `healthchecks.active` in the [Upstream object][upstreamobject] configuration. You +need to specify the necessary information so that Kong can perform periodic +probing on the target, and how to interpret the resulting information. + +You can use the `healthchecks.active.type` field to specify whether to perform +HTTP or HTTPS probes (setting it to `"http"` or `"https"`), or by simply +testing if the connection to a given host and port is successful +(setting it to `"tcp"`). + +For configuring the probe, you need to specify: + +* `healthchecks.active.http_path` - The path that should be used when +issuing the HTTP GET request to the target. The default value is `"/"`. +* `healthchecks.active.timeout` - The connection timeout limit for the +HTTP GET request of the probe. The default value is 1 second. +* `healthchecks.active.concurrency` - Number of targets to check concurrently +in active health checks. + +You also need to specify positive values for intervals, for running +probes: + +* `healthchecks.active.healthy.interval` - Interval between active health +checks for healthy targets (in seconds). A value of zero indicates that active +probes for healthy targets should not be performed. +* `healthchecks.active.unhealthy.interval` - Interval between active health +checks for unhealthy targets (in seconds). A value of zero indicates that active +probes for unhealthy targets should not be performed. + +This allows you to tune the behavior of the active health checks, whether you +want probes for healthy and unhealthy targets to run at the same interval, or +one to be more frequent than the other. + +If you are using HTTPS healthchecks, you can also specify the following +fields: + +* `healthchecks.active.https_verify_certificate` - Whether to check the +validity of the SSL certificate of the remote host when performing active +health checks using HTTPS. +* `healthchecks.active.https_sni` - The hostname to use as an SNI +(Server Name Identification) when performing active health checks +using HTTPS. This is particularly useful when Targets are configured +using IPs, so that the target host's certificate can be verified +with the proper SNI. + +Note that failed TLS verifications will increment the "TCP failures" counter; +the "HTTP failures" refer only to HTTP status codes, whether probes are done +through HTTP or HTTPS. + +Finally, you need to configure how Kong should interpret the probe, by setting +the various thresholds on the [health +counters](#healthy-and-unhealthy-targets), which, once reached will trigger a +status change. The counter threshold fields are: + +* `healthchecks.active.healthy.successes` - Number of successes in active +probes (as defined by `healthchecks.active.healthy.http_statuses`) to consider +a target healthy. +* `healthchecks.active.unhealthy.tcp_failures` - Number of TCP failures +or TLS verification failures in active probes to consider a target unhealthy. +* `healthchecks.active.unhealthy.timeouts` - Number of timeouts in active +probes to consider a target unhealthy. +* `healthchecks.active.unhealthy.http_failures` - Number of HTTP failures in +active probes (as defined by `healthchecks.active.unhealthy.http_statuses`) to +consider a target unhealthy. + +### Enabling passive health checks + +Passive health checks do not feature a probe, as they work by interpreting +the ongoing traffic that flows from a target. This means that to enable +passive checks you only need to configure its counter thresholds: + +* `healthchecks.passive.healthy.successes` - Number of successes in proxied +traffic (as defined by `healthchecks.passive.healthy.http_statuses`) to +consider a target healthy, as observed by passive health checks. This needs to +be positive when passive checks are enabled so that healthy traffic resets the +unhealthy counters. +* `healthchecks.passive.unhealthy.tcp_failures` - Number of TCP failures in +proxied traffic to consider a target unhealthy, as observed by passive health +checks. +* `healthchecks.passive.unhealthy.timeouts` - Number of timeouts in proxied +traffic to consider a target unhealthy, as observed by passive health checks. +* `healthchecks.passive.unhealthy.http_failures` - Number of HTTP failures in +proxied traffic (as defined by `healthchecks.passive.unhealthy.http_statuses`) +to consider a target unhealthy, as observed by passive health checks. + +### Disabling health checks + +In all counter thresholds and intervals specified in the `healthchecks` +configuration, setting a value to zero means that the functionality the field +represents is disabled. Setting a probe interval to zero disables a probe. +Likewise, you can disable certain types of checks by setting their counter +thresholds to zero. For example, to not consider timeouts when performing +healthchecks, you can set both `timeouts` fields (for active and passive +checks) to zero. This gives you a fine-grained control of the behavior of the +health checker. + +In summary, to completely disable active health checks for an upstream, you +need to set both `healthchecks.active.healthy.interval` and +`healthchecks.active.unhealthy.interval` to `0`. + +To completely disable passive health checks, you need to set all counter +thresholds under `healthchecks.passive` for its various counters to zero. + +All counter thresholds and intervals in `healthchecks` are zero by default, +meaning that health checks are completely disabled by default in newly created +upstreams. + +[ringbalancer]: /gateway/{{page.kong_version}}/how-kong-works/load-balancing#ring-balancer +[ringtarget]: /gateway/{{page.kong_version}}/how-kong-works/load-balancing#target +[upstream]: /gateway/{{page.kong_version}}/how-kong-works/load-balancing#upstream +[targetobject]: /gateway/{{page.kong_version}}/admin-api#target-object +[addupstream]: /gateway/{{page.kong_version}}/admin-api#add-upstream +[clustering]: /gateway/{{page.kong_version}}/production/deployment-topologies/traditional +[upstreamobject]: /gateway/{{page.kong_version}}/admin-api#upstream-object +[balancercaveats]: /gateway/{{page.kong_version}}/how-kong-works/load-balancing#balancing-caveats +[dnscaveats]: /gateway/{{page.kong_version}}/how-kong-works/load-balancing#dns-caveats diff --git a/src/gateway/how-kong-works/load-balancing.md b/src/gateway/how-kong-works/load-balancing.md new file mode 100644 index 000000000000..bf3b3f4a8f3a --- /dev/null +++ b/src/gateway/how-kong-works/load-balancing.md @@ -0,0 +1,237 @@ +--- +title: Load Balancing Reference +--- + +Kong provides multiple ways of load balancing requests to multiple backend +services: a straightforward DNS-based method, and a more dynamic ring-balancer +that also allows for service registry without needing a DNS server. + +## DNS-based load balancing + +When using DNS-based load balancing, the registration of the backend services +is done outside of Kong, and Kong only receives updates from the DNS server. + +Every Service that has been defined with a `host` containing a hostname +(instead of an IP address) will automatically use DNS-based load balancing +if the name resolves to multiple IP addresses, provided the hostname does not +resolve to an `upstream` name or a name in your DNS hosts file. + +The DNS record `ttl` setting (time to live) determines how often the information +is refreshed. When using a `ttl` of 0, every request will be resolved using its +own DNS query. Obviously this will have a performance penalty, but the latency of +updates/changes will be very low. + +### A records + +An A record contains one or more IP addresses. Hence, when a hostname +resolves to an A record, each backend service must have its own IP address. + +Because there is no `weight` information, all entries will be treated as equally +weighted in the load balancer, and the balancer will do a straight forward +round-robin. + +### SRV records + +An SRV record contains weight and port information for all of its IP addresses. +A backend service can be identified by a unique combination of IP address +and port number. Hence, a single IP address can host multiple instances of the +same service on different ports. + +Because the `weight` information is available, each entry will get its own +weight in the load balancer and it will perform a weighted round-robin. + +Similarly, any given port information will be overridden by the port information from +the DNS server. If a Service has attributes `host=myhost.com` and `port=123`, +and `myhost.com` resolves to an SRV record with `127.0.0.1:456`, then the request +will be proxied to `http://127.0.0.1:456/somepath`, as port `123` will be +overridden by `456`. + +### DNS priorities + +The DNS resolver will start resolving the following record types in order: + + 1. The last successful type previously resolved + 2. SRV record + 3. A record + 4. CNAME record + +This order is configurable through the [`dns_order` configuration property][dns-order-config]. + +### DNS caveats + +- Whenever the DNS record is refreshed a list is generated to handle the +weighting properly. Try to keep the weights as multiples of each other to keep +the algorithm performance, e.g., 2 weights of 17 and 31 would result in a structure +with 527 entries, whereas weights 16 and 32 (or their smallest relative +counterparts 1 and 2) would result in a structure with merely 3 entries, +especially with a very small (or even 0) `ttl` value. + +- DNS is carried over UDP with a default limit of 512 Bytes. If there are many entries +to be returned, a DNS Server will respond with partial data and set a truncate flag, +indicating there are more entries unsent. +DNS clients, including Kong's, will then make a second request over TCP to retrieve the full +list of entries. + +- Some nameservers by default do not respond with the truncate flag, but trim the response +to be under 512 byte UDP size. + - Consul is an example. Consul, in its default configuration, returns up to the first +three entries only, and does not set the truncate flag to indicate there are remaining entries unsent. +Consul includes an option to enable the truncate flag. Please refer to [Consul documentation](https://www.consul.io/docs/agent/options.html#enable_truncate) +for more information. + +- If a deployed nameserver does not provide the truncate flag, the pool +of upstream instances might be loaded inconsistently. The Kong node is effectively +unaware of some of the instances, due to the limited information provided by the nameserver. +To mitigate this, use a different nameserver, use IP addresses instead of names, or make sure +you use enough Kong nodes to still keep all upstream services in use. + +- When the nameserver returns a `3 name error`, then that is a valid response +for Kong. If this is unexpected, first validate the correct name is being +queried for, and second check your nameserver configuration. + +- The initial pick of an IP address from a DNS record (A or SRV) is not +randomized. So when using records with a `ttl` of 0, the nameserver is +expected to randomize the record entries. + +## Ring-balancer + +When using the ring-balancer, the adding and removing of backend services will +be handled by Kong, and no DNS updates will be necessary. Kong will act as the +service registry. Nodes can be added/deleted with a single HTTP request and +will instantly start/stop receiving traffic. + +Configuring the ring-balancer is done through the `upstream` and `target` +entities. + + - `target`: an IP address or hostname with a port number where a backend + service resides, e.g. "192.168.100.12:80". Each target gets an additional + `weight` to indicate the relative load it gets. IP addresses can be + in both IPv4 and IPv6 format. + + - `upstream`: a 'virtual hostname' which can be used in a Route `host` + field, e.g., an upstream named `weather.v2.service` would get all requests + from a Service with `host=weather.v2.service`. + +### Upstream + +Each upstream gets its own ring-balancer. Each `upstream` can have many +`target` entries attached to it, and requests proxied to the 'virtual hostname' +(which can be overwritten before proxying, using `upstream`'s property +`host_header`) will be load balanced over the targets. A ring-balancer has a +maximum predefined number of slots, and based on the target weights the slots get +assigned to the targets of the upstream. + +Adding and removing targets can be done with a simple HTTP request on the +Admin API. This operation is relatively cheap. Changing the upstream +itself is more expensive as the balancer will need to be rebuilt when the +number of slots change for example. + +Within the balancer there are the positions (from 1 up to the value defined in the `slots` attribute), +which are __randomly distributed__ on the ring. +The randomness is required to make invoking the ring-balancer cheap at +runtime. A simple round-robin over the wheel (the positions) will do to +provide a well distributed weighted round-robin over the `targets`, while +also having cheap operations when inserting/deleting targets. + +Detailed information on adding and manipulating +upstreams is available in the `upstream` section of the +[Admin API reference][upstream-object-reference]. + +### Target + +A target is an IP address/hostname with a port that identifies an instance of +a backend service. Each upstream can have many targets. +Detailed information on adding and manipulating targets is available in the +`target` section of the [Admin API reference][target-object-reference]. + +The targets will be automatically cleaned when there are 10x more inactive +entries than active ones. Cleaning will involve rebuilding the balancer, and +hence is more expensive than just adding a target entry. + +A `target` can also have a hostname instead of an IP address. In that case +the name will be resolved and all entries found will individually be added to +the ring balancer, e.g., adding `api.host.com:123` with `weight=100`. The +name 'api.host.com' resolves to an A record with 2 IP addresses. Then both +IP addresses will be added as target, each getting `weight=100` and port 123. +__NOTE__: the weight is used for the individual entries, not for the whole! + +Would it resolve to an SRV record, then also the `port` and `weight` fields +from the DNS record would be picked up, and would overrule the given port `123` +and `weight=100`. + +The balancer will honor the DNS record's `ttl` setting, and queries and updates +the balancer when it expires. + +__Exception__: When a DNS record has `ttl=0`, the hostname will be added +as a single target, with the specified weight. Upon every proxied request +to this target it will query the nameserver again. + +### Balancing algorithms + +The ring-balancer supports the following load balancing algorithms: `round-robin`, +`consistent-hashing`, and `least-connections`. By default, a ring-balancer +uses the `round-robin` algorithm, which provides a well-distributed weighted +round-robin over the targets. + +When using the `consistent-hashing` algorithm, the input for the hash can be either +`none`, `consumer`, `ip`, `header`, or `cookie`. When set to `none`, the +`round-robin` scheme will be used, and hashing will be disabled. The `consistent-hashing` +algorithm supports a primary and a fallback hashing attribute; in case the primary +fails (e.g., if the primary is set to `consumer`, but no Consumer is authenticated), +the fallback attribute is used. + +Supported hashing attributes are: + +- `none`: Do not use `consistent-hashing`; use `round-robin` instead (default). +- `consumer`: Use the Consumer ID as the hash input. If no Consumer ID is available, + it will fall back on the Credential ID (for example, in case of an external authentication mechanism like LDAP). +- `ip`: Use the originating IP address as the hash input. Review the configuration + settings for [determining the real IP][real-ip-config] when using this. +- `header`: Use a specified header as the hash input. The header name is + specified in either `hash_on_header` or `hash_fallback_header`, depending on whether + `header` is a primary or fallback attribute, respectively. +- `cookie`: Use a specified cookie with a specified path as the hash input. + The cookie name is specified in the `hash_on_cookie` field and the path is + specified in the `hash_on_cookie_path` field. If the specified cookie is not + present in the request, it will be set by the response. Hence, the `hash_fallback` + setting is invalid if `cookie` is the primary hashing mechanism. + +The `consistent-hashing` algorithm is based on _Consistent Hashing_, which ensures that when the balancer gets modified by +a change in its targets (adding, removing, failing, or changing weights), only +the minimum number of hashing losses occur. This maximizes upstream cache hits. + +The ring-balancer also supports the `least-connections` algorithm, which selects +the target with the lowest number of connections, weighted by the Target's +`weight` attribute. + +For more information on the exact settings see the `upstream` section of the +[Admin API reference][upstream-object-reference]. + +### Balancing caveats + +The ring-balancer is designed to work both with a single node as well as in a cluster. +For the weighted-round-robin algorithm there isn't much difference, but when using +the hash based algorithm it is important that all nodes build the exact same +ring-balancer to make sure they all work identical. To do this the balancer +must be build in a deterministic way. + +- Do not use hostnames in the balancer as the +balancers might/will slowly diverge because the DNS ttl has only second precision +and renewal is determined by when a name is actually requested. On top of this is +the issue with some nameservers not returning all entries, which exacerbates +this problem. So when using the hashing approach in a Kong cluster, add `target` +entities only by their IP address, and never by name. + +- When picking your hash input make sure the input has enough variance to get +to a well distributed hash. Hashes will be calculated using the CRC-32 digest. +So for example, if your system has thousands of users, but only a few consumers, defined +per platform (e.g. 3 consumers: Web, iOS and Android) then picking the `consumer` +hash input will not suffice, using the remote IP address by setting the hash to +`ip` would provide more variance in the input and hence a better distribution +in the hash output. However, if many clients will be behind the same NAT gateway (e.g. in +call center), `cookie` will provide a better distribution than `ip`. + +[upstream-object-reference]: /gateway/{{page.kong_version}}/admin-api#upstream-object +[target-object-reference]: /gateway/{{page.kong_version}}/admin-api#target-object +[dns-order-config]: /gateway/{{page.kong_version}}/reference/configuration/#dns_order +[real-ip-config]: /gateway/{{page.kong_version}}/reference/configuration/#real_ip_header \ No newline at end of file diff --git a/src/gateway/how-kong-works/performance-testing.md b/src/gateway/how-kong-works/performance-testing.md new file mode 100644 index 000000000000..6015d724c558 --- /dev/null +++ b/src/gateway/how-kong-works/performance-testing.md @@ -0,0 +1,233 @@ +--- +title: Kong Gateway Performance Testing +content_type: explanation +--- + +The {{site.base_gateway}} codebase includes a performance testing framework. It allows Kong developers and users to evaluate the performance of Kong itself as well as +bundled or custom plugins, and plot frame graphs to debug performance bottlenecks. +The framework collects RPS (request per second) and latencies of Kong processing the request +to represent performance metrics under different workloads. + +The framework is implemented as an extension to Kong's integration test suite. + +## Installation + +The framework uses [busted](https://github.com/lunarmodules/busted) and some +Lua development dependencies of Kong. To set up the environment, +run `make dev` on your Kong repository to install all Lua dependencies. + +## Usage + +### Basic usage + +Install Lua development dependencies of Kong being installed and invoke each test file with `busted`. The following runs the RPS and latency +test using the `docker` driver. + +```shell +PERF_TEST_USE_DAILY_IMAGE=true PERF_TEST_VERSIONS=git:master,git:perf/your-other-branch bin/busted -o gtest spec/04-perf/01-rps/01-simple_spec.lua +``` + + +### Terraform managed instances + +By default, Terraform doesn't teardown instances after each test in `lazy_teardown`, allowing users +to run multiple tests consecutively without rebuilding the infrastructure each time. + +This behavior can be changed by setting the `PERF_TEST_TEARDOWN_ALL` environment variable to true. Users can +also manually teardown the infrastructure by running: + +``` +PERF_TEST_TEARDOWN_ALL=1 PERF_TEST_DRIVER=terraform PERF_TEST_TERRAFORM_PROVIDER=your-provider bin/busted -o gtest -t single spec/04-perf/99-teardown/ +``` + +### AWS + +When using the `terraform` driver and `aws-ec2` as the provider, AWS credentials can be provided using environment variables. +It's common to pass the `AWS_PROFILE` variable to point to a stored AWS credentials profile, or `AWS_ACCESS_KEY_ID` and +`AWS_SECRET_ACCESS_KEY` to use credentials directly. See the +[Terraform AWS provider document](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#authentication-and-configuration) +for further information. + +### Charts + +Charts are not rendered by default. There's a reference implementation to draw graphs on all JSON +data stored in the `output` directory. Use the following commands to draw graphs: + +```shell +cwd=$(pwd) +cd spec/helpers/perf/charts/ +pip install -r requirements.txt +for i in $(ls ${cwd}/output/*.data.json); do + python ./charts.py $i -o "${cwd}/output/" +done +``` + + +## Drivers + +Three "drivers" are implemented depending on different environments, accuracy +requirements, and setup complexity. + +| Driver | Test between git commits | Test between binary releases | Flame Graph | Test unreleased version | +|----------|--------------------------|------------------------------|------------|----------------------------| +| Docker | yes | yes | | yes (`use_daily_image` = true) | +|Terraform | yes | yes | yes | yes (`use_daily_image` = true) | + +You must install the following Lua development dependencies to use either of the drivers: + +- **Docker** Driver is based on Docker images. +It requires fewer dependencies. +And it doesn't support FlameGraph generation. + +- **terraform** Driver runs in a remote VM or on a bare metal machine. It's most accurate, +but it requires Terraform knowledge to operate and setup. + + * Requires the [Terraform](https://www.terraform.io/downloads.html) binary be installed. + * Requires git binary if testing between git commits. When testing between git commits, + the framework assumes the current directory is Kong's repo. It will stash your working + directory and remove the stash after the test is finished. When using the Docker or Terraform driver, + the framework derives the base version of each commit and uses the matching Docker image or + Kong binary package and puts the local source code inside. + +## Workflow + +Multiple +test cases can share the same Lua file. + +The following code snippet demonstrates a basic workflow for defining a workload and load testing Kong. + +```lua +local perf = require("spec.helpers.perf") + +perf.use_defaults() + +local versions = { "git:master", "3.0.0" } + +for _, version in ipairs(versions) do + describe("perf test for Kong " .. version .. " #simple #no_plugins", function() + local bp + lazy_setup(function() + local helpers = perf.setup_kong(version) + + bp = helpers.get_db_utils("postgres", { + "routes", + "services", + }) + + local upstream_uri = perf.start_worker([[ + location = /test { + return 200; + } + ]]) + + local service = bp.services:insert { + url = upstream_uri .. "/test", + } + + bp.routes:insert { + paths = { "/s1-r1" }, + service = service, + strip_path = true, + } + end) + + before_each(function() + perf.start_kong({ + --kong configs + }) + end) + + after_each(function() + perf.stop_kong() + end) + + lazy_teardown(function() + perf.teardown() + end) + + it("#single_route", function() + local results = {} + for i=1,3 do + perf.start_load({ + path = "/s1-r1", + connections = 1000, + threads = 5, + duration = 10, + }) + + ngx.sleep(10) + + local result = assert(perf.wait_result()) + + print(("### Result for Kong %s (run %d):\n%s"):format(version, i, result)) + results[i] = result + end + + print(("### Combined result for Kong %s:\n%s"):format(version, assert(perf.combine_results(results)))) + + perf.save_error_log("output/" .. version:gsub("[:/]", "#") .. "-single_route.log") + end) + end) +end +``` + +The test can be run as a normal Busted test, using `bin/busted path/to/this_file_spec.lua`. + +More examples can be found in the [spec/04-perf](https://github.com/Kong/kong/tree/master/spec/04-perf) folder in the Kong +repository. + +## Sample Output + +``` +### Test Suite: git:origin/master~10 #simple #hybrid #no_plugins #single_route +### Result for Kong git:origin/master~10 (run 1): +Running 30s test @ http://172.17.0.50:8000/s1-r1 + 5 threads and 100 connections + Thread Stats Avg Stdev Max +/- Stdev + Latency 3.53ms 3.35ms 87.02ms 89.65% + Req/Sec 6.42k 1.33k 10.53k 67.29% + Latency Distribution + 50% 2.65ms + 75% 4.35ms + 90% 6.99ms + 99% 16.86ms + 960330 requests in 30.10s, 228.96MB read +Requests/sec: 31904.97 +Transfer/sec: 7.61MB +### Result for Kong git:origin/master~10 (run 2): +Running 30s test @ http://172.17.0.50:8000/s1-r1 + 5 threads and 100 connections + Thread Stats Avg Stdev Max +/- Stdev + Latency 4.56ms 6.55ms 236.87ms 91.95% + Req/Sec 5.79k 1.54k 10.50k 66.18% + Latency Distribution + 50% 2.82ms + 75% 5.31ms + 90% 9.72ms + 99% 26.33ms + 863963 requests in 30.07s, 206.00MB read +Requests/sec: 28730.72 +Transfer/sec: 6.85MB +### Result for Kong git:origin/master~10 (run 3): +Running 30s test @ http://172.17.0.50:8000/s1-r1 + 5 threads and 100 connections + Thread Stats Avg Stdev Max +/- Stdev + Latency 3.79ms 3.81ms 82.25ms 89.60% + Req/Sec 6.14k 1.43k 12.59k 66.49% + Latency Distribution + 50% 2.77ms + 75% 4.69ms + 90% 7.71ms + 99% 18.88ms + 917366 requests in 30.08s, 218.72MB read +Requests/sec: 30499.09 +Transfer/sec: 7.27MB +### Combined result for Kong git:origin/master~10: +RPS Avg: 30378.26 +Latency Avg: 3.94ms Max: 236.87ms + P90 (ms): 6.99, 9.72, 7.71 + P99 (ms): 16.86, 26.33, 18.88 +``` + +With samples in [spec/04-perf](https://github.com/Kong/kong/tree/master/spec/04-perf), the RPS and latency +results, Kong error logs, charts and Flame Graph files are saved to the `output` directory in the current directory. diff --git a/src/gateway/how-kong-works/routing-traffic.md b/src/gateway/how-kong-works/routing-traffic.md new file mode 100644 index 000000000000..08c567af65d2 --- /dev/null +++ b/src/gateway/how-kong-works/routing-traffic.md @@ -0,0 +1,1507 @@ +--- +title: Proxy Reference +--- + +In this document, we cover {{site.base_gateway}}'s **proxying capabilities** by explaining +its routing capabilities and internal workings in details. + +{{site.base_gateway}} exposes several interfaces which can be tweaked by the following configuration +properties: + +- `proxy_listen`, which defines a list of addresses/ports on which {{site.base_gateway}} will + accept **public HTTP (gRPC, WebSocket, etc) traffic** from clients and proxy + it to your upstream services (`8000` by default). +- `admin_listen`, which also defines a list of addresses and ports, but those + should be restricted to only be accessed by administrators, as they expose + Kong's configuration capabilities: the **Admin API** (`8001` by default). +{% include_cached /md/admin-listen.md desc='short' kong_version=page.kong_version %} +- `stream_listen`, which is similar to `proxy_listen` but for Layer 4 (TCP, TLS) + generic proxy. This is turned off by default. + +## Terminology + +- `client`: Refers to the *downstream* client making requests to {{site.base_gateway}}'s + proxy port. +- `upstream service`: Refers to your own API/service sitting behind {{site.base_gateway}}, to + which client requests/connections are forwarded. +- `Service`: Service entities, as the name implies, are abstractions of each of + your own upstream services. Examples of services would be a data + transformation microservice, a billing API, etc. +- `Route`: This refers to the {{site.base_gateway}} routes entity. Routes are entrypoints into + {{site.base_gateway}}, and defining rules for a request to be matched, and routed to a given + service. +- `Plugin`: This refers to {{site.base_gateway}} "plugins", which are pieces of business logic + that run in the proxying lifecycle. Plugins can be configured through the + Admin API, either globally (all incoming traffic) or on specific routes + and services. + +## Overview + +From a high-level perspective, {{site.base_gateway}} listens for HTTP traffic on its configured +proxy port(s) (`8000` and `8443` by default) and L4 traffic on explicitly configured +`stream_listen` ports. {{site.base_gateway}} will evaluate any incoming +HTTP request or L4 connection against the routes you have configured and try to find a matching +one. If a given request matches the rules of a specific route, {{site.base_gateway}} will +process proxying the request. + +Because each route may be linked to a service, {{site.base_gateway}} will run the plugins you +have configured on your route and its associated service, and then proxy the +request upstream. You can manage routes via {{site.base_gateway}}'s Admin API. Routes have +special attributes that are used for routing, matching incoming HTTP requests. +Routing attributes differ by subsystem (HTTP/HTTPS, gRPC/gRPCS, and TCP/TLS). + +Subsystems and routing attributes: +- `http`: `methods`, `hosts`, `headers`, `paths` (and `snis`, if `https`) +- `tcp`: `sources`, `destinations` (and `snis`, if `tls`) +- `grpc`: `hosts`, `headers`, `paths` (and `snis`, if `grpcs`) + +If you attempt to configure a route with a routing attribute it doesn't support +(e.g., an `http` route with `sources` or `destinations` fields), an error message +is reported: + +``` +HTTP/1.1 400 Bad Request +Content-Type: application/json +Server: kong/ + +{ + "code": 2, + "fields": { + "sources": "cannot set 'sources' when 'protocols' is 'http' or 'https'" + }, + "message": "schema violation (sources: cannot set 'sources' when 'protocols' is 'http' or 'https')", + "name": "schema violation" +} +``` + +If {{site.base_gateway}} receives a request that it cannot match against any of the configured +routes (or if no routes are configured), it will respond with: + +```http +HTTP/1.1 404 Not Found +Content-Type: application/json +Server: kong/ + +{ + "message": "no route and no Service found with those values" +} +``` + +## How to configure a service + +The [Configuring a Service][configuring-a-service] quickstart guide explains +how Kong is configured via the [Admin API][API]. + +Adding a service to {{site.base_gateway}} is done by sending an HTTP request to the Admin API: + +```bash +curl -i -X POST http://localhost:8001/services/ \ + -d 'name=foo-service' \ + -d 'url=http://foo-service.com' +``` + +Response: +```json +HTTP/1.1 201 Created +... + +{ + "connect_timeout": 60000, + "created_at": 1515537771, + "host": "foo-service.com", + "id": "d54da06c-d69f-4910-8896-915c63c270cd", + "name": "foo-service", + "path": "/", + "port": 80, + "protocol": "http", + "read_timeout": 60000, + "retries": 5, + "updated_at": 1515537771, + "write_timeout": 60000 +} +``` + +This request instructs {{site.base_gateway}} to register a service named "foo-service", which +points to `http://foo-service.com` (your upstream). + +**Note:** The `url` argument is a shorthand argument to populate the +`protocol`, `host`, `port`, and `path` attributes at once. + +Now, in order to send traffic to this service through {{site.base_gateway}}, we need to specify +a route, which acts as an entry point to {{site.base_gateway}}: + +```bash +curl -i -X POST http://localhost:8001/routes/ \ + -d 'hosts[]=example.com' \ + -d 'paths[]=/foo' \ + -d 'service.id=d54da06c-d69f-4910-8896-915c63c270cd' +``` + +Response: +```json +HTTP/1.1 201 Created +... + +{ + "created_at": 1515539858, + "hosts": [ + "example.com" + ], + "id": "ee794195-6783-4056-a5cc-a7e0fde88c81", + "methods": null, + "paths": [ + "/foo" + ], + "preserve_host": false, + "priority": 0, + "protocols": [ + "http", + "https" + ], + "service": { + "id": "d54da06c-d69f-4910-8896-915c63c270cd" + }, + "strip_path": true, + "updated_at": 1515539858 +} +``` + +We have now configured a route to match incoming requests matching the given +`hosts` and `paths`, and forward them to the `foo-service` we configured, thus +proxying this traffic to `http://foo-service.com`. + +{{site.base_gateway}} is a transparent proxy, and it defaults to forwarding the request to your +upstream service untouched, with the exception of various headers such as +`Connection`, `Date`, and others as required by the HTTP specifications. + +## Routes and matching capabilities + +Let's now discuss how {{site.base_gateway}} matches a request against the configured routing +attributes. + +{{site.base_gateway}} supports native proxying of HTTP/HTTPS, TCL/TLS, and GRPC/GRPCS protocols; +as mentioned earlier, each of these protocols accept a different set of routing +attributes: +- `http`: `methods`, `hosts`, `headers`, `paths` (and `snis`, if `https`) +- `tcp`: `sources`, `destinations` (and `snis`, if `tls`) +- `grpc`: `hosts`, `headers`, `paths` (and `snis`, if `grpcs`) + +Note that all of these fields are **optional**, but at least **one of them** +must be specified. + +For a request to match a route: + +- The request **must** include **all** of the configured fields +- The values of the fields in the request **must** match at least one of the + configured values (While the field configurations accepts one or more values, + a request needs only one of the values to be considered a match) + +Let's go through a few examples. Consider a route configured like the following: + +```json +{ + "hosts": ["example.com", "foo-service.com"], + "paths": ["/foo", "/bar"], + "methods": ["GET"] +} +``` + +Some of the possible requests matching this route would look like the following: + +```http +GET /foo HTTP/1.1 +Host: example.com +``` + +```http +GET /bar HTTP/1.1 +Host: foo-service.com +``` + +```http +GET /foo/hello/world HTTP/1.1 +Host: example.com +``` + +All three of these requests satisfy all the conditions set in the route +definition. + +However, the following requests would **not** match the configured conditions: + +```http +GET / HTTP/1.1 +Host: example.com +``` + +```http +POST /foo HTTP/1.1 +Host: example.com +``` + +```http +GET /foo HTTP/1.1 +Host: foo.com +``` + +All three of these requests satisfy only two of configured conditions. The +first request's path is not a match for any of the configured `paths`, same for +the second request's HTTP method, and the third request's Host header. + +Now that we understand how the routing properties work together, let's explore +each property individually. + +### Request header + +{{site.base_gateway}} supports routing by arbitrary HTTP headers. A special case of this +feature is routing by the Host header. + +Routing a request based on its Host header is the most straightforward way to +proxy traffic through {{site.base_gateway}}, especially since this is the intended usage of the +HTTP Host header. {{site.base_gateway}} makes it easy to do via the `hosts` field of the route +entity. + +`hosts` accepts multiple values, which must be comma-separated when specifying +them via the Admin API, and is represented in a JSON payload: + +```bash +curl -i -X POST http://localhost:8001/routes/ \ + -H 'Content-Type: application/json' \ + -d '{"hosts":["example.com", "foo-service.com"]}' +``` + +Response: +``` +HTTP/1.1 201 Created +... +``` + +But since the Admin API also supports form-urlencoded content types, you +can specify an array via the `[]` notation: + +```bash +curl -i -X POST http://localhost:8001/routes/ \ + -d 'hosts[]=example.com' \ + -d 'hosts[]=foo-service.com' +``` + +Response: +``` +HTTP/1.1 201 Created +... +``` + +To satisfy the `hosts` condition of this route, any incoming request from a +client must now have its Host header set to one of: + +``` +Host: example.com +``` + +or: + +``` +Host: foo-service.com +``` + +Similarly, any other header can be used for routing: + +```sh +curl -i -X POST http://localhost:8001/routes/ \ + -d 'headers.region=north' +``` + +Response: +``` +HTTP/1.1 201 Created +``` + +Incoming requests containing a `Region` header set to `North` are routed to +said route. + +``` +Region: North +``` + +#### Using wildcard hostnames + +To provide flexibility, {{site.base_gateway}} allows you to specify hostnames with wildcards in +the `hosts` field. Wildcard hostnames allow any matching Host header to satisfy +the condition, and thus match a given Route. + +Wildcard hostnames **must** contain **only one** asterisk at the leftmost +**or** rightmost label of the domain. For example: + +- `*.example.com` would allow Host values such as `a.example.com` and + `x.y.example.com` to match. +- `example.*` would allow Host values such as `example.com` and `example.org` + to match. + +A complete example would look like this: + +```json +{ + "hosts": ["*.example.com", "service.com"] +} +``` + +Which would allow the following requests to match this route: + +```http +GET / HTTP/1.1 +Host: an.example.com +``` + +```http +GET / HTTP/1.1 +Host: service.com +``` + +#### The `preserve_host` property + +When proxying, {{site.base_gateway}}'s default behavior is to set the upstream request's Host +header to the hostname specified in the service's `host`. The +`preserve_host` field accepts a boolean flag instructing {{site.base_gateway}} not to do so. + +For example, when the `preserve_host` property is not changed and a route is +configured like so: + +```json +{ + "hosts": ["service.com"], + "service": { + "id": "..." + } +} +``` + +A possible request from a client to {{site.base_gateway}} could be: + +```http +GET / HTTP/1.1 +Host: service.com +``` + +{{site.base_gateway}} would extract the Host header value from the service's `host` property, , +and would send the following upstream request: + +```http +GET / HTTP/1.1 +Host: +``` + +However, by explicitly configuring a route with `preserve_host=true`: + +```json +{ + "hosts": ["service.com"], + "preserve_host": true, + "service": { + "id": "..." + } +} +``` + +And assuming the same request from the client: + +```http +GET / HTTP/1.1 +Host: service.com +``` + +{{site.base_gateway}} would preserve the Host on the client request and would send the following +upstream request instead: + +```http +GET / HTTP/1.1 +Host: service.com +``` + +### Additional request headers + +It's possible to route requests by other headers besides `Host`. + +To do this, use the `headers` property in your route: + +```json +{ + "headers": { "version": ["v1", "v2"] }, + "service": { + "id": "..." + } +} +``` + +Given a request with a header such as: + +```http +GET / HTTP/1.1 +version: v1 +``` + +This request will be routed through to the service. The same happens with this one: + +```http +GET / HTTP/1.1 +version: v2 +``` + +But this request isn't routed to the service: + +```http +GET / HTTP/1.1 +version: v3 +``` + +**Note**: The `headers` keys are a logical `AND` and their values a logical `OR`. + +### Request path + +Another way for a route to be matched is via request paths. To satisfy this +routing condition, a client request's normalized path **must** be prefixed with one of the +values of the `paths` attribute. + +For example, with a route configured like so: + +```json +{ + "paths": ["/service", "/hello/world"] +} +``` + +The following requests would be matched: + +```http +GET /service HTTP/1.1 +Host: example.com +``` + +```http +GET /service/resource?param=value HTTP/1.1 +Host: example.com +``` + +```http +GET /hello/world/resource HTTP/1.1 +Host: anything.com +``` + +For each of these requests, {{site.base_gateway}} detects that their normalized URL path is prefixed with +one of the routes's `paths` values. By default, {{site.base_gateway}} would then proxy the +request upstream without changing the URL path. + +When proxying with path prefixes, **the longest paths get evaluated first**. +This allow you to define two routes with two paths: `/service` and +`/service/resource`, and ensure that the former does not "shadow" the latter. + +#### Using Regex in paths + +{{site.base_gateway}} supports regular expression pattern matching for an route's `paths` field +via [PCRE](http://pcre.org/) (Perl Compatible Regular Expression). You can +assign paths as both prefixes and Regex to a route at the same time. + +For a path to be considered as Regex, it must fall **outside** of the following regex: + +``` +^[a-zA-Z0-9\.\-_~/%]*$ +``` + +In other words, if a path contains any character that is **not** alphanumerical, dot (`.`), +dash (`-`), underscore (`_`), tilde (`~`), forward-slash (`/`), or percent (`%`), then +it will be considered a Regex path. This determination is done on a per-path basis +and it is allowed to mix plain text and regex paths inside the same `paths` array of the same +route object. + +For example, if we consider the following route: + +```json +{ + "paths": ["/users/\d+/profile", "/following"] +} +``` + +The following requests would be matched by this route: + +```http +GET /following HTTP/1.1 +Host: ... +``` + +```http +GET /users/123/profile HTTP/1.1 +Host: ... +``` + +The provided Regex are evaluated with the `a` PCRE flag (`PCRE_ANCHORED`), +meaning that they will be constrained to match at the first matching point +in the path (the root `/` character). + +**Note**: Regex matching is in general very fast, but it is possible to +construct expressions that take a very long time to determine that they don't +actually match. This happens when the expression results in a "backtrace +exponential explosion", which means that there's an astronomical number of +tests to be performed before it's conclusive that they're all negative. +If undetected, this could take hours to finish with a single regular expression. +The [PCRE](http://pcre.org/) engine automatically detects most types of this +and replaces with more direct approaches, but there are more complex expressions +that could result in this scenario. + +To limit the worst-case scenario, {{site.base_gateway}} applies the OpenResty +[`lua_regex_match_limit`](https://github.com/openresty/lua-nginx-module#lua_regex_match_limit) +to ensure that any regex operation terminates in around two seconds in the +worst case. Apart from that, a smaller limit is applied to some "critical" +regex operations, like those for path selection, in order to terminate them +within two milliseconds, at most. + +##### Evaluation order + +As previously mentioned, {{site.base_gateway}} evaluates prefix paths by length, the longest +prefix paths are evaluated first. However, {{site.base_gateway}} will evaluate Regex paths based +on the `regex_priority` attribute of routes from highest priority to lowest. +Regex paths are furthermore evaluated before prefix paths. + +Consider the following routes: + +```json +[ + { + "paths": ["/status/\d+"], + "regex_priority": 0 + }, + { + "paths": ["/version/\d+/status/\d+"], + "regex_priority": 6 + }, + { + "paths": ["/version"], + }, + { + "paths": ["/version/any/"], + } +] +``` + +In this scenario, {{site.base_gateway}} evaluates incoming requests against the following +defined URIs, in this order: + +1. `/version/\d+/status/\d+` +2. `/status/\d+` +3. `/version/any/` +4. `/version` + +Take care to avoid writing Regex rules that are overly broad and may consume +traffic intended for a prefix rule. Adding a rule with the path `/version/.*` to +the ruleset above would likely consume some traffic intended for the `/version` +prefix path. If you see unexpected behavior, sending `Kong-Debug: 1` in your +request headers will indicate the matched route ID in the response headers for +troubleshooting purposes. + +As usual, a request must still match a route's `hosts` and `methods` properties +as well, and {{site.base_gateway}} traverses your routes until it finds one that [matches +the most rules](#matching-priorities). + +##### Capturing groups + +Capturing groups are also supported, and the matched group will be extracted +from the path and available for plugins consumption. If we consider the +following regex: + +``` +/version/(?\d+)/users/(?\S+) +``` + +And the following request path: + +``` +/version/1/users/john +``` + +{{site.base_gateway}} considers the request path a match, and if the overall route is +matched (considering other routing attributes), the extracted capturing groups +will be available from the plugins in the `ngx.ctx` variable: + +```lua +local router_matches = ngx.ctx.router_matches + +-- router_matches.uri_captures is: +-- { "1", "john", version = "1", user = "john" } +``` + +##### Escaping special characters + +Next, it is worth noting that characters found in Regex are often +reserved characters according to +[RFC 3986](https://tools.ietf.org/html/rfc3986) and as such, +should be percent-encoded. **When configuring routes with regex paths via the +Admin API, be sure to URL encode your payload if necessary**. For example, +with `curl` and using an `application/x-www-form-urlencoded` MIME type: + +```bash +curl -i -X POST http://localhost:8001/routes \ + --data-urlencode 'uris[]=/status/\d+' +``` + +Response: +``` +HTTP/1.1 201 Created +... +``` + +Note that `curl` does not automatically URL encode your payload, and note the +usage of `--data-urlencode`, which prevents the `+` character to be URL decoded +and interpreted as a space ` ` by {{site.base_gateway}}'s Admin API. + +#### The `strip_path` property + +It may be desirable to specify a path prefix to match a route, but not +include it in the upstream request. To do so, use the `strip_path` boolean +property by configuring a route like so: + +```json +{ + "paths": ["/service"], + "strip_path": true, + "service": { + "id": "..." + } +} +``` + +Enabling this flag instructs {{site.base_gateway}} that when matching this route, and proceeding +with the proxying to a service, it should **not** include the matched part of +the URL path in the upstream request's URL. For example, the following +client's request to the above route: + +```http +GET /service/path/to/resource HTTP/1.1 +Host: ... +``` + +This causes {{site.base_gateway}} to send the following upstream request: + +```http +GET /path/to/resource HTTP/1.1 +Host: ... +``` + +The same way, if a Regex path is defined on a route that has `strip_path` +enabled, the entirety of the request URL matching sequence will be stripped. +For example: + +```json +{ + "paths": ["/version/\d+/service"], + "strip_path": true, + "service": { + "id": "..." + } +} +``` + +The following HTTP request matching the provided Regex path: + +```http +GET /version/1/service/path/to/resource HTTP/1.1 +Host: ... +``` + +Is proxied upstream by {{site.base_gateway}} as: + +```http +GET /path/to/resource HTTP/1.1 +Host: ... +``` + +#### Normalization behavior + +To prevent trivial route match bypass, the incoming request URI from client +is always normalized according to [RFC 3986](https://tools.ietf.org/html/rfc3986) +before router matching occurs. Specifically, the following normalization techniques are +used for incoming request URIs, which are selected because they generally do not change +semantics of the request URI: + +1. Percent-encoded triplets are converted to uppercase. For example: `/foo%3a` becomes `/foo%3A`. +2. Percent-encoded triplets of unreserved characters are decoded. For example: `/fo%6F` becomes `/foo`. +3. Dot segments are removed as necessary. For example: `/foo/./bar/../baz` becomes `/foo/baz`. +4. Duplicate slashes are merged. For example: `/foo//bar` becomes `/foo/bar`. + +The `paths` attribute of the Route object are also normalized. It is achieved by first determining +if the path is a plain text or regex path. Based on the result, different normalization techniques +are used. + +For plain text route path: + +Same normalization technique as above is used, that is, methods 1 through 4. + +For regex route path: + +Only methods 1 and 2 are used. In addition, if the decoded character becomes a regex +meta character, it will be escaped with backslash. + +{{site.base_gateway}} normalizes any incoming request URI before performing router +matches. As a result, any request URI sent over to the upstream services will also +be in normalized form that preserves the original URI semantics. + +### Request HTTP method + +The `methods` field allows matching the requests depending on their HTTP +method. It accepts multiple values. Its default value is empty (the HTTP +method is not used for routing). + +The following route allows routing via `GET` and `HEAD`: + +```json +{ + "methods": ["GET", "HEAD"], + "service": { + "id": "..." + } +} +``` + +Such a route would be matched with the following requests: + +```http +GET / HTTP/1.1 +Host: ... +``` + +```http +HEAD /resource HTTP/1.1 +Host: ... +``` + +But it would not match a `POST` or `DELETE` request. This allows for much more +granularity when configuring plugins on routes. For example, one could imagine +two routes pointing to the same service: one with unlimited unauthenticated +`GET` requests, and a second one allowing only authenticated and rate-limited +`POST` requests (by applying the authentication and rate limiting plugins to +such requests). + +### Request source + +
      + **Note:** This section only applies to TCP and TLS routes. +
      + +The `sources` routing attribute allows +matching a route by a list of incoming connection IP and/or port sources. + +The following route allows routing via a list of source IP/ports: + +```json +{ + "protocols": ["tcp", "tls"], + "sources": [{"ip":"10.1.0.0/16", "port":1234}, {"ip":"10.2.2.2"}, {"port":9123}], + "id": "...", +} +``` + +TCP or TLS connections originating from IPs in CIDR range "10.1.0.0/16" or IP +address "10.2.2.2" or Port "9123" would match such route. + +### Request destination + +
      + **Note:** This section only applies to TCP and TLS routes. +
      + +The `destinations` attribute, similarly to `sources`, +allows matching a route by a list of incoming connection IP and/or port, but +uses the destination of the TCP/TLS connection as routing attribute. + +### Request SNI + +When using secure protocols (`https`, `grpcs`, or `tls`), a [Server +Name Indication][SNI] can be used as a routing attribute. The following route +allows routing via SNIs: + +```json +{ + "snis": ["foo.test", "example.com"], + "id": "..." +} +``` + +Incoming requests with a matching hostname set in the TLS connection's SNI +extension would be routed to this route. As mentioned, SNI routing applies not +only to TLS, but also to other protocols carried over TLS - such as HTTPS and +If multiple SNIs are specified in the route, any of them can match with the incoming request's SNI. +with the incoming request (OR relationship between the names). + +The SNI is indicated at TLS handshake time and cannot be modified after the TLS connection has +been established. This means, for example, that multiple requests reusing the same keepalive connection +will have the same SNI hostname while performing router match, regardless of the `Host` header. +has been established. This means keepalive connections that send multiple requests +will have the same SNI hostnames while performing router match +(regardless of the `Host` header). + +Please note that creating a route with mismatched SNI and `Host` header matcher +is possible, but generally discouraged. + +## Matching priorities + +A route may define matching rules based on its `headers`, `hosts`, `paths`, and +`methods` (plus `snis` for secure routes - `"https"`, `"grpcs"`, `"tls"`) +fields. For {{site.base_gateway}} to match an incoming request to a route, all existing fields +must be satisfied. However, {{site.base_gateway}} allows for quite some flexibility by allowing +two or more routes to be configured with fields containing the same values - +when this occurs, {{site.base_gateway}} applies a priority rule. + +The rule is: **when evaluating a request, {{site.base_gateway}} first tries to match the +routes with the most rules**. + +For example, if two routes are configured like so: + +```json +{ + "hosts": ["example.com"], + "service": { + "id": "..." + } +}, +{ + "hosts": ["example.com"], + "methods": ["POST"], + "service": { + "id": "..." + } +} +``` + +The second route has a `hosts` field **and** a `methods` field, so it is +evaluated first by {{site.base_gateway}}. By doing so, we avoid the first route "shadowing" +calls intended for the second one. + +Thus, this request matches the first route: + +```http +GET / HTTP/1.1 +Host: example.com +``` + +And this request matches the second one: + +```http +POST / HTTP/1.1 +Host: example.com +``` + +Following this logic, if a third route was to be configured with a `hosts` +field, a `methods` field, and a `uris` field, it would be evaluated first by +{{site.base_gateway}}. + +If the rule count for the given request is the same in two routes `A` and +`B`, then the following tiebreaker rules will be applied in the order they +are listed. Route `A` will be selected over `B` if: + +* `A` has only "plain" Host headers and `B` has one or more "wildcard" + host headers +* `A` has more non-Host headers than `B`. +* `A` has at least one "regex" paths and `B` has only "plain" paths. +* `A`'s longest path is longer than `B`'s longest path. +* `A.created_at < B.created_at` + +## Proxying behavior + +The proxying rules above detail how {{site.base_gateway}} forwards incoming requests to your +upstream services. Below, we detail what happens internally between the time +{{site.base_gateway}} *matches* an HTTP request with a registered route, and the actual +*forwarding* of the request. + +### Load balancing + +{{site.base_gateway}} implements load balancing capabilities to distribute proxied +requests across a pool of instances of an upstream service. + +You can find more information about configuring load balancing by consulting +the [Load Balancing Reference][load-balancing-reference]. + +### Plugins execution + +{{site.base_gateway}} is extensible via "plugins" that hook themselves in the request/response +lifecycle of the proxied requests. Plugins can perform a variety of operations +in your environment and/or transformations on the proxied request. + +Plugins can be configured to run globally (for all proxied traffic) or on +specific routes and services. In both cases, you must create a [plugin +configuration][plugin-configuration-object] via the Admin API. + +Once a route has been matched (and its associated service entity), {{site.base_gateway}} will +run plugins associated to either of those entities. Plugins configured on a +route run before plugins configured on a service, but otherwise, the usual +rules of [plugins association][plugin-association-rules] apply. + +These configured plugins will run their `access` phase, which you can find more +information about in the [Plugin development guide][plugin-development-guide]. + +### Proxying and upstream timeouts + +Once {{site.base_gateway}} has executed all the necessary logic (including plugins), it is ready +to forward the request to your upstream service. This is done via Nginx's +[ngx_http_proxy_module][ngx-http-proxy-module]. You can configure the desired +timeouts for the connection between {{site.base_gateway}} and a given upstream, via the following +properties of a service: + +- `connect_timeout`: defines in milliseconds the timeout for + establishing a connection to your upstream service. Defaults to `60000`. +- `write_timeout`: defines in milliseconds a timeout between two + successive write operations for transmitting a request to your upstream + service. Defaults to `60000`. +- `read_timeout`: defines in milliseconds a timeout between two + successive read operations for receiving a request from your upstream + service. Defaults to `60000`. + +{{site.base_gateway}} will send the request over HTTP/1.1, and set the following headers: + + +- `Host: `, as previously described in this document. +- `Connection: keep-alive`, to allow for reusing the upstream connections. +- `X-Real-IP: `, where `$remote_addr` is the variable bearing + the same name provided by + [ngx_http_core_module][ngx-remote-addr-variable]. Please note that the + `$remote_addr` is likely overridden by + [ngx_http_realip_module][ngx-http-realip-module]. +- `X-Forwarded-For:
      `, where `
      ` is the content of + `$realip_remote_addr` provided by + [ngx_http_realip_module][ngx-http-realip-module] appended to the request + header with the same name. +- `X-Forwarded-Proto: `, where `` is the protocol used by + the client. In the case where `$realip_remote_addr` is one of the **trusted** + addresses, the request header with the same name gets forwarded if provided. + Otherwise, the value of the `$scheme` variable provided by + [ngx_http_core_module][ngx-scheme-variable] will be used. +- `X-Forwarded-Host: `, where `` is the host name sent by + the client. In the case where `$realip_remote_addr` is one of the **trusted** + addresses, the request header with the same name gets forwarded if provided. + Otherwise, the value of the `$host` variable provided by + [ngx_http_core_module][ngx-host-variable] will be used. +- `X-Forwarded-Port: `, where `` is the port of the server which + accepted a request. In the case where `$realip_remote_addr` is one of the + **trusted** addresses, the request header with the same name gets forwarded + if provided. Otherwise, the value of the `$server_port` variable provided by + [ngx_http_core_module][ngx-server-port-variable] will be used. +- `X-Forwarded-Prefix: `, where `` is the path of the request which + was accepted by {{site.base_gateway}}. In the case where `$realip_remote_addr` is one of the + **trusted** addresses, the request header with the same name gets forwarded + if provided. Otherwise, the value of the `$request_uri` variable (with + the query string stripped) provided by [ngx_http_core_module][ngx-server-port-variable] + will be used. + + + {:.note} + > **Note**: {{site.base_gateway}} returns `"/"` for an empty path, but it doesn't do any other + > normalization on the request path. + +All the other request headers are forwarded as-is by {{site.base_gateway}}. + +One exception to this is made when using the WebSocket protocol. If so, {{site.base_gateway}} +sets the following headers to allow for upgrading the protocol between the +client and your upstream services: + +- `Connection: Upgrade` +- `Upgrade: websocket` + +More information on this topic is covered in the +[Proxy WebSocket traffic][proxy-websocket] section. + +### Errors and retries + +Whenever an error occurs during proxying, {{site.base_gateway}} uses the underlying +Nginx [retries][ngx-http-proxy-retries] mechanism to pass the request on to +the next upstream. + +There are two configurable elements here: + +1. The number of retries: this can be configured per service using the + `retries` property. See the [Admin API][API] for more details on this. + +2. What exactly constitutes an error: here {{site.base_gateway}} uses the Nginx defaults, which + means an error or timeout occurring while establishing a connection with the + server, passing a request to it, or reading the response headers. + +The second option is based on Nginx's +[proxy_next_upstream][proxy_next_upstream] directive. This option is not +directly configurable through {{site.base_gateway}}, but can be added using a custom Nginx +configuration. See the [configuration reference][configuration-reference] for +more details. + +### Response + +{{site.base_gateway}} receives the response from the upstream service and sends it back to the +downstream client in a streaming fashion. At this point, {{site.base_gateway}} executes +subsequent plugins added to the route and/or service that implement a hook in +the `header_filter` phase. + +Once the `header_filter` phase of all registered plugins has been executed, the +following headers are added by {{site.base_gateway}} and the full set of headers be sent to +the client: + +- `Via: kong/x.x.x`, where `x.x.x` is the {{site.base_gateway}} version in use +- `X-Kong-Proxy-Latency: `, where `latency` is the time in milliseconds + between {{site.base_gateway}} receiving the request from the client and sending the request to + your upstream service. +- `X-Kong-Upstream-Latency: `, where `latency` is the time in + milliseconds that {{site.base_gateway}} was waiting for the first byte of the upstream service + response. + +Once the headers are sent to the client, {{site.base_gateway}} starts executing +registered plugins for the route and/or service that implement the +`body_filter` hook. This hook may be called multiple times, due to the +streaming nature of Nginx. Each chunk of the upstream response that is +successfully processed by such `body_filter` hooks is sent back to the client. +You can find more information about the `body_filter` hook in the [Plugin +development guide][plugin-development-guide]. + +## Configuring a fallback route + +As a practical use-case and example of the flexibility offered by {{site.base_gateway}}'s +proxying capabilities, let's try to implement a "fallback route", so that in +order to avoid {{site.base_gateway}} responding with an HTTP `404`, "no route found", we can +catch such requests and proxy them to a special upstream service, or apply a +plugin to it (such a plugin could, for example, terminate the request with a +different status code or response without proxying the request). + +Here is an example of such a fallback route: + +```json +{ + "paths": ["/"], + "service": { + "id": "..." + } +} +``` + +As you can guess, any HTTP request made to {{site.base_gateway}} would actually match this +route, since all URIs are prefixed by the root character `/`. As we know from +the [Request path][proxy-request-path] section, the longest URL paths are +evaluated first by {{site.base_gateway}}, so the `/` path will eventually be evaluated last by +{{site.base_gateway}}, and effectively provide a "fallback" route, only matched as a last +resort. You can then send traffic to a special service or apply any plugin you +wish on this route. + +## Configuring TLS for a route + +{{site.base_gateway}} provides a way to dynamically serve TLS certificates on a per-connection +basis. TLS certificates are directly handled by the core, and configurable via +the Admin API. Clients connecting to {{site.base_gateway}} over TLS must support the [Server +Name Indication][SNI] extension to make use of this feature. + +TLS certificates are handled by two resources in the {{site.base_gateway}} Admin API: + +- `/certificates`, which stores your keys and certificates. +- `/snis`, which associates a registered certificate with a Server Name + Indication. + +You can find the documentation for those two resources in the +[Admin API Reference][API]. + +Here is how to configure a TLS certificate on a given route: first, upload +your TLS certificate and key via the Admin API: + +```bash +curl -i -X POST http://localhost:8001/certificates \ + -F "cert=@/path/to/cert.pem" \ + -F "key=@/path/to/cert.key" \ + -F "snis=*.tls-example.com,other-tls-example.com" +``` + +Response: +``` +HTTP/1.1 201 Created +... +``` + +The `snis` form parameter is a sugar parameter, directly inserting an SNI and +associating the uploaded certificate to it. + +Note that one of the SNI names defined in `snis` above contains a wildcard +(`*.tls-example.com`). An SNI may contain a single wildcard in the leftmost (prefix) or +rightmost (suffix) position. This can be useful when maintaining multiple subdomains. A +single `sni` configured with a wildcard name can be used to match multiple +subdomains, instead of creating an SNI for each. + +Valid wildcard positions are `mydomain.*`, `*.mydomain.com`, and `*.www.mydomain.com`. + +A default certificate can be added using the following parameters in {{site.base_gateway}} configuration: +1. [`ssl_cert`](/gateway/{{page.kong_version}}/reference/configuration/#ssl_cert) +2. [`ssl_cert_key`](/gateway/{{page.kong_version}}/reference/configuration/#ssl_cert_key) + +Or, by dynamically configuring the default certificate with an SNI of `*`: + +```bash +curl -i -X POST http://localhost:8001/certificates \ + -F "cert=@/path/to/default-cert.pem" \ + -F "key=@/path/to/default-cert.key" \ + -F "snis=*" +``` + +Response: +``` +HTTP/1.1 201 Created +... +``` + +Matching of `snis` respects the following priority: + + 1. Exact SNI matching certificate + 2. Search for a certificate by prefix wildcard + 3. Search for a certificate by suffix wildcard + 4. Search for a certificate associated with the SNI `*` + 5. The default certificate on the file system + +You must now register the following route within {{site.base_gateway}}. We match requests +to this route using only the Host header for convenience: + +```bash +curl -i -X POST http://localhost:8001/routes \ + -d 'hosts=prefix.tls-example.com,other-tls-example.com' \ + -d 'service.id=d54da06c-d69f-4910-8896-915c63c270cd' +``` + +Response: +``` +HTTP/1.1 201 Created +... +``` + +You can now expect the route to be served over HTTPS by {{site.base_gateway}}: + +```bash +curl -i https://localhost:8443/ \ + -H "Host: prefix.tls-example.com" +``` + +Response: +``` +HTTP/1.1 200 OK +... +``` + +When establishing the connection and negotiating the TLS handshake, if your +client sends `prefix.tls-example.com` as part of the SNI extension, {{site.base_gateway}} serves +the `cert.pem` certificate previously configured. This is the same for both HTTPS and +TLS connections. + +### Restricting the client protocol + +Routes have a `protocols` property to restrict the client protocol they should +listen for. This attribute accepts a set of values, which can be `"http"`, +`"https"`, `"grpc"`, `"grpcs"`, `"tcp"`, or `"tls"`. + +A Route with `http` and `https` will accept traffic in both protocols. + +```json +{ + "hosts": ["..."], + "paths": ["..."], + "methods": ["..."], + "protocols": ["http", "https"], + "service": { + "id": "..." + } +} +``` + +Not specifying any protocol has the same effect, since routes default to +`["http", "https"]`. + +However, a route with *only* `https` would _only_ accept traffic over HTTPS. It +would _also_ accept unencrypted traffic _if_ TLS termination previously +occurred from a trusted IP. TLS termination is considered valid when the +request comes from one of the configured IPs in +[trusted_ips][configuration-trusted-ips] and if the `X-Forwarded-Proto: https` +header is set: + +```json +{ + "hosts": ["..."], + "paths": ["..."], + "methods": ["..."], + "protocols": ["https"], + "service": { + "id": "..." + } +} +``` + +If a route such as the above matches a request, but that request is in +plain-text without valid prior TLS termination, {{site.base_gateway}} responds with: + +```http +HTTP/1.1 426 Upgrade Required +Content-Type: application/json; charset=utf-8 +Transfer-Encoding: chunked +Connection: Upgrade +Upgrade: TLS/1.2, HTTP/1.1 +Server: kong/x.y.z + +{"message":"Please use HTTPS protocol"} +``` + +It's possible to create routes for raw TCP (not necessarily HTTP) +connections by using `"tcp"` in the `protocols` attribute: + +```json +{ + "hosts": ["..."], + "paths": ["..."], + "methods": ["..."], + "protocols": ["tcp"], + "service": { + "id": "..." + } +} +``` + +Similarly, we can create routes which accept raw TLS traffic (not necessarily HTTPS) with +the `"tls"` value: + +```json +{ + "hosts": ["..."], + "paths": ["..."], + "methods": ["..."], + "protocols": ["tls"], + "service": { + "id": "..." + } +} +``` + +A route with *only* `TLS` would _only_ accept traffic over TLS. + +It is also possible to accept both TCP and TLS simultaneously: + +``` +{ + "hosts": ["..."], + "paths": ["..."], + "methods": ["..."], + "protocols": ["tcp", "tls"], + "service": { + "id": "..." + } +} + +``` + +For L4 TLS proxy to work, it is necessary to create route that accepts +the `tls` `protocol`, as well as having the appropriate TLS certificate +uploaded and their `sni` attribute properly set to match incoming connection's +SNI. Please refer to the [Configuring TLS for a Route](#configuring-tls-for-a-route) +section above for instructions on setting this up. + +## Proxy WebSocket traffic + +{{site.base_gateway}} supports WebSocket traffic thanks to the underlying Nginx implementation. +When you want to establish a WebSocket connection between a client and your +upstream services *through* {{site.base_gateway}}, you must establish a WebSocket handshake. +This is done via the HTTP Upgrade mechanism. This is what your client request +made to {{site.base_gateway}} would look like: + +```http +GET / HTTP/1.1 +Connection: Upgrade +Host: my-websocket-api.com +Upgrade: WebSocket +``` + +This makes {{site.base_gateway}} forward the `Connection` and `Upgrade` headers to your +upstream service, instead of dismissing them due to the hop-by-hop nature of a +standard HTTP proxy. + +### WebSocket proxy modes + +There are two methods for proxying WebSocket traffic in {{site.base_gateway}}: + +* HTTP(S) services and routes +* WS(S) services and routes + +#### HTTP(S) services and routes + +Services and routes using the `http` and `https` protocols are fully capable of +handling WebSocket connections with no special configuration. With this method, +WebSocket sessions behave identically to regular HTTP requests, and all of the +request/response data is treated as an opaque stream of bytes. + +```yaml +services: + - name: my-http-websocket-service + protocol: http + host: 1.2.3.4 + port: 80 + path: / + routes: + - name: my-http-websocket-route + protocols: + - http + - https +``` + +#### WS(S) services and routes +{:.badge .enterprise} + +In addition to HTTP services and routes, {{site.ee_product_name}} includes +the `ws` (WebSocket-over-http) and `wss` (WebSocket-over-https) options for +service `protocol` and route `protocols`. In contrast to `http`/`https`, `ws` +and `wss` services have full control over the underlying WebSocket connection. +This means that they can use WebSocket plugins and the [WebSocket PDK](/gateway/{{page.kong_version}}/plugin-development/pdk/kong.websocket.client/) to +perform business logic on a per-message basis (message validation, accounting, +rate-limiting, etc). + +```yaml +services: + - name: my-dedicated-websocket-service + protocol: ws + host: 1.2.3.4 + port: 80 + path: / + routes: + - name: my-dedicated-websocket-route + protocols: + - ws + - wss +``` + +{:.note} +> **Note**: +> Decoding and encoding WebSocket messages comes with a non-zero amount of +> performance overhead when compared with the protocol-agnostic behavior of +> `http(s)` services. If your API does not need the extra capabilities +> provided by a `ws(s)` service, it's recommended that you use an `http(s)` +> service instead. + +### WebSocket and TLS + +Regardless of which service/route protocols are in use (`http(s)` or `ws(s)`), +{{site.base_gateway}} will accept plain and TLS WebSocket connections on its +respective `http` and `https` ports. To enforce TLS connections from clients, +set the `protocols` property of the [route][route-entity] to `https` or `wss` +only. + +When setting up the [service][service-entity] to point to your upstream +WebSocket service, you should carefully pick the protocol you want to use +between {{site.base_gateway}} and the upstream. + +If you want to use TLS, your upstream WebSocket service must be defined using +the `https` (or `wss`) protocol in the service `protocol` property and the +proper port (usually 443). To connect without TLS, then the `http` (or `ws`) +protocol and port (usually 80) should be used in `protocol` instead. + +If you want {{site.base_gateway}} to terminate TLS, you can accept +`https`/`wss` only from the client, but proxy to the upstream service over +plain text (`http` or `ws`). + +## Proxy gRPC traffic + +gRPC proxying is natively supported in {{site.base_gateway}}. In order +to manage gRPC services and proxy gRPC requests with {{site.base_gateway}}, create services and +routes for your gRPC services. + +Only observability and logging plugins are supported with +gRPC - plugins known to be supported with gRPC have "grpc" and "grpcs" listed +under the supported protocols field in their Kong Hub page - for example, +check out the [File Log][file-log] plugin's page. + +## Proxy TCP/TLS traffic + +TCP and TLS proxying is natively supported in {{site.base_gateway}}. + +In this mode, data of incoming connections reaching the `stream_listen` endpoints will +be passed through to the upstream. It is possible to terminate TLS connections +from clients using this mode as well. + +To use this mode, aside from defining `stream_listen`, appropriate route/service +object with protocol types of `tcp` or `tls` should be created. + +If TLS termination by {{site.base_gateway}} is desired, the following conditions must be met: + +1. The {{site.base_gateway}} port where TLS connection connects to must have the `ssl` flag enabled +2. A certificate/key that can be used for TLS termination must be present inside {{site.base_gateway}}, + as shown in [Configuring TLS for a Route](#configuring-tls-for-a-route) + +{{site.base_gateway}} will use the connecting client's TLS SNI server name extension to find +the appropriate TLS certificate to use. + +On the service side, depends on whether connection between {{site.base_gateway}} and the upstream +service need to be encrypted, `tcp` or `tls` protocol types can be set accordingly. +This means all of the below setup are supported in this mode: + +1. Client <- TLS -> Kong <- TLS -> Upstream +2. Client <- TLS -> Kong <- Cleartext -> Upstream +3. Client <- Cleartext -> Kong <- TLS -> Upstream + +**Note:** In L4 proxy mode, only plugins that has `tcp` or `tls` in the supported +protocol list are supported. This list can be found in their respective documentation +on [Kong Hub](https://docs.konghq.com/hub/). + +[Back to top](#introduction) + +## Proxy TLS passthrough traffic + +{{site.base_gateway}} supports proxying a TLS request without terminating or known +as SNI proxy. + +{{site.base_gateway}} uses the connecting +client's TLS SNI extension to find the matching Route and Service and forward the +complete TLS request upstream, without decrypting the incoming TLS traffic. + +In this mode, you need to: +* Create a route object with the protocol `tls_passthrough`, and the +`snis` field set to one or more SNIs. +* Set the corresponding service object's protocol to `tcp`. +* Send requests to a port that has the `ssl` flag in its `stream_listen` +directive. + +Separate SNI and Certificate entities aren't required and won't be used. + +Routes are not allowed to match `tls` and `tls_passthrough` protocols at same time. +However, the same SNI is allowed to match `tls` and `tls_passthrough` in different +routes. + +It's also possible to set route to `tls_passthrough` and service to `tls`. In this +mode, the connection to the upstream will be TLS-encrypted twice. + +{:.note} +> **Note:** To run any plugins in this mode, the plugin's `protocols` field must +include `tls_passthrough`. + +[Back to top](#introduction) + +## Conclusion + +Through this guide, we hope you gained knowledge of the underlying proxying +mechanism of {{site.base_gateway}}, from how does a request match a route to be routed to its +associated service, on to how to allow for using the WebSocket protocol or +setup dynamic TLS certificates. + +This website is open-source and can be found at +[github.com/Kong/docs.konghq.com](https://github.com/Kong/docs.konghq.com/). +Feel free to provide feedback to this document there, or propose improvements! + +If you haven't already, we suggest that you also read the [Load balancing +Reference][load-balancing-reference], as it closely relates to the topic we +just covered. + +[plugin-configuration-object]: /gateway/{{page.kong_version}}/admin-api#plugin-object +[plugin-development-guide]: /gateway/{{page.kong_version}}/plugin-development +[plugin-association-rules]: /gateway/{{page.kong_version}}/admin-api/#precedence +[proxy-websocket]: /gateway/{{page.kong_version}}/how-kong-works/routing-traffic#proxy-websocket-traffic +[load-balancing-reference]: /gateway/{{page.kong_version}}/how-kong-works/load-balancing +[configuration-reference]: /gateway/{{page.kong_version}}/reference/configuration/ +[configuration-trusted-ips]: /gateway/{{page.kong_version}}/reference/configuration/#trusted_ips +[configuring-a-service]: /gateway/{{page.kong_version}}/get-started/services-and-routes +[API]: /gateway/{{page.kong_version}}/admin-api +[service-entity]: /gateway/{{page.kong_version}}/admin-api/#add-service +[route-entity]: /gateway/{{page.kong_version}}/admin-api/#add-route + +[ngx-http-proxy-module]: http://nginx.org/en/docs/http/ngx_http_proxy_module.html +[ngx-http-realip-module]: http://nginx.org/en/docs/http/ngx_http_realip_module.html +[ngx-remote-addr-variable]: http://nginx.org/en/docs/http/ngx_http_core_module.html#var_remote_addr +[ngx-scheme-variable]: http://nginx.org/en/docs/http/ngx_http_core_module.html#var_scheme +[ngx-host-variable]: http://nginx.org/en/docs/http/ngx_http_core_module.html#var_host +[ngx-server-port-variable]: http://nginx.org/en/docs/http/ngx_http_core_module.html#var_server_port +[ngx-http-proxy-retries]: http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_next_upstream_tries +[SNI]: https://en.wikipedia.org/wiki/Server_Name_Indication +[file-log]: /hub/kong-inc/file-log diff --git a/src/gateway/index.md b/src/gateway/index.md new file mode 100644 index 000000000000..8604645a1b50 --- /dev/null +++ b/src/gateway/index.md @@ -0,0 +1,205 @@ +--- +title: Kong Gateway +subtitle: API gateway built for hybrid and multi-cloud, optimized for microservices and distributed architectures +--- + +## Quick Links + + + +## Introducing {{ site.base_gateway }} + +{{site.base_gateway}} is a lightweight, fast, and flexible cloud-native API +gateway. An API gateway is a reverse proxy that lets you manage, configure, and route +requests to your APIs. + +{{site.base_gateway}} runs in front of any RESTful API and can be extended through +modules and plugins. It's designed to run on decentralized architectures, including +hybrid-cloud and multi-cloud deployments. + +With {{site.base_gateway}}, users can: + +* Leverage workflow automation and modern GitOps practices +* Decentralize applications/services and transition to microservices +* Create a thriving API developer ecosystem +* Proactively identify API-related anomalies and threats +* Secure and govern APIs/services, and improve API visibility across the +entire organization. + +## Extending the {{site.base_gateway}} + +{{site.base_gateway}} is a Lua application running in Nginx. {{site.base_gateway}} +is distributed along with [OpenResty](https://openresty.org/), which is a bundle +of modules that extend the [lua-nginx-module](https://github.com/openresty/lua-nginx-module). + +This sets the foundations for a modular architecture, where +plugins can be enabled and executed at runtime. At its core, +{{site.base_gateway}} implements database abstraction, routing, and plugin +management. Plugins can live in separate code bases and be injected anywhere +into the request lifecycle, all with a few lines of code. + +Kong provides many [plugins](#kong-gateway-plugins) for you to use in your +Gateway deployments. You can also create your own custom plugins. For more +information, see the +[plugin development guide](/gateway/{{page.kong_version}}/plugin-development), +the [PDK reference](/gateway/{{page.kong_version}}/plugin-development/pdk/), and the guide on creating plugins with other languages ([JavaScript](/gateway/{{page.kong_version}}/plugin-development/pluginserver/javascript), [Go](/gateway/{{page.kong_version}}/plugin-development/pluginserver/go), and [Python](/gateway/{{page.kong_version}}/plugin-development/pluginserver/python)). + +## Packages and modes + +{{site.base_gateway}} is available in the following modes: + +**{{site.base_gateway}} (OSS)**: an open-source package containing the basic API gateway +functionality and open-source plugins. You can manage the open-source Gateway +with Kong's [Admin API](#kong-admin-api) or with [declarative configuration](#deck). + +**{{site.base_gateway}}** (available in +[Free, Plus, or Enterprise modes](https://konghq.com/pricing)): Kong's API gateway +with added functionality. +* In **Free mode**, + this package adds [Kong Manager](#kong-manager) to the basic open-source functionality. +* In **Plus mode**, you have access to more +{{site.base_gateway}} features, but only through {{site.konnect_saas}}. +See the [{{site.konnect_saas}} documentation](/konnect/) and the +**Plus**-labelled plugins on the [Plugin Hub](/hub/) for more information. +* With an **Enterprise** subscription, + it also includes: + * [Dev Portal](#kong-dev-portal) + * [Vitals](#kong-vitals) + * [RBAC](/gateway/{{page.kong_version}}/admin-api/rbac/reference) + * [Enterprise plugins](/hub/) + +You can manage {{site.base_gateway}} in Free or Enterprise mode with Kong's +[Admin API](#kong-admin-api), [declarative configuration](#deck), or [Kong Manager](#kong-manager). + +This package is also available as part of +[{{site.konnect_product_name}}](/konnect/). + +![Introduction to {{site.base_gateway}}](/assets/images/docs/gateway/gateway_overview.png) +> _Figure 1: Diagram of {{site.base_gateway}} modules and how they relate to the +foundational Gateway components._ +>
      +> _Requests flow from an API client into the +Gateway, are modified and managed by the proxy based on your Gateway +configuration, and forwarded to upstream services._ + +## Features + +{% include_cached feature-table.html config=site.data.tables.features.gateway %} + +### Kong Admin API + +[Kong Admin API](/gateway/{{page.kong_version}}/admin-api) provides a RESTful +interface for administration and configuration of Services, Routes, Plugins, and +Consumers. All of the tasks you can perform against the Gateway can be automated +using the Kong Admin API. + +### Kong Manager +{:.badge .free} + +{:.note} +> **Note**: If you are running Kong in traditional mode, increased traffic could +> lead to potential performance with Kong Proxy. +> Server-side sorting and filtering large quantities of entities will also cause increased CPU usage in both Kong CP and database. + + +[Kong Manager](/gateway/{{page.kong_version}}/kong-manager/) is +the graphical user interface (GUI) for {{site.base_gateway}}. It uses the Kong +Admin API under the hood to administer and control {{site.base_gateway}}. + +Here are some of the things you can do with Kong Manager: + +* Create new Routes and Services +* Activate or deactivate plugins with a couple of clicks +* Group your teams, services, plugins, consumer management, and everything else +exactly how you want them +* Monitor performance: visualize cluster-wide, workspace-level, or +object-level health using intuitive, customizable dashboards + +### Kong Dev Portal +{:.badge .enterprise} + +[Kong Dev Portal](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/) is used to onboard new developers and to generate API documentation, create custom pages, manage API versions, and secure developer access. + +### Kong Vitals +{:.badge .enterprise} + +[Kong Vitals](/gateway/{{page.kong_version}}/kong-enterprise/analytics/) provides useful metrics about the health and performance of your {{site.base_gateway}} nodes, as well as metrics about the usage of your proxied APIs. You can visually monitor vital signs and pinpoint anomalies in real-time, and use visual API analytics to see exactly how your APIs and Gateway are performing and access key statistics. Kong Vitals is part of the Kong Manager UI. + +### Kubernetes + +{{site.base_gateway}} can run natively on Kubernetes with its custom [ingress controller](/kubernetes-ingress-controller/), Helm chart, and Operator. A Kubernetes ingress controller is a proxy that exposes Kubernetes services from applications (for example, Deployments, ReplicaSets) running on a Kubernetes cluster to client applications running outside of the cluster. The intent of an ingress controller is to provide a single point of control for all incoming traffic into the Kubernetes cluster. + +### {{site.base_gateway}} plugins + +[{{site.base_gateway}} plugins](/hub/) provide advanced functionality to better manage your API and microservices. With turnkey capabilities to meet the most challenging use cases, {{site.base_gateway}} plugins ensure maximum control and minimizes unnecessary overhead. Enable features like authentication, rate-limiting, and transformations by enabling {{site.base_gateway}} plugins through Kong Manager or the Admin API. + +## Tools +Kong also provides API lifecycle management tools that you can use with {{site.base_gateway}}. + +### Insomnia + +[Insomnia](https://docs.insomnia.rest) enables spec-first development for all REST and GraphQL services. With Insomnia, organizations can accelerate design and test workflows using automated testing, direct Git sync, and inspection of all response types. Teams of all sizes can use Insomnia to increase development velocity, reduce deployment risk, and increase collaboration. + +### decK +[decK](/deck) helps manage {{site.base_gateway}}’s configuration in a declarative fashion. +This means that a developer can define the desired state of {{site.base_gateway}} or +{{site.konnect_short_name}} – services, routes, plugins, and more – and let decK handle +implementation without needing to execute each step manually, as you would with +the Kong Admin API. + + +## Get started with {{site.base_gateway}} + +[Download and install {{site.base_gateway}}](/gateway/{{page.kong_version}}/install/). +To test it out, you can choose either the open-source package, or +run {{site.base_gateway}} in free mode and also try out Kong Manager. + +After installation, get started with our introductory [quickstart guide](/gateway/{{page.kong_version}}/get-started/) + +### Try in {{site.konnect_short_name}} + +[{{site.konnect_product_name}}](/konnect/) can manage {{site.base_gateway}} +instances. With this setup, Kong hosts the control plane and you host your +own data planes. + +There are a few ways to test out the Gateway's Plus or Enterprise features: + +* Sign up for a [free trial of {{site.konnect_product_name}} Plus](https://konnect.konghq.com/register). +* Check out learning labs at [Kong Academy]({{site.links.learn}}). +* If you are interested in evaluating Enterprise features locally, +[request a demo](https://konghq.com/get-started/#request-demo) and a Kong +representative will reach out with details to get you started. + +## Support policy +Kong primarily follows a [semantic versioning](https://semver.org/) (SemVer) +model for its products. + +For the latest version support information for {{site.ee_product_name}} and +{{site.mesh_product_name}}, see our [version support policy](/gateway/{{page.kong_version}}/support-policy/). diff --git a/src/gateway/install/docker/build-custom-images.md b/src/gateway/install/docker/build-custom-images.md new file mode 100644 index 000000000000..710863199e19 --- /dev/null +++ b/src/gateway/install/docker/build-custom-images.md @@ -0,0 +1,149 @@ +--- +title: Build your own Docker images +--- + +Kong is distributed as prebuilt `apk`, `deb` and `rpm` packages, in addition to official Docker images hosted on [DockerHub](https://hub.docker.com/r/kong) + +Kong builds and verifies [Debian](#dockerhub-debian-link-here) and [RHEL](#dockerhub-rhel-link-here) images for use in production. [Alpine](#dockerhub-alpine-link-here) images are provided for **development purposes only** as they contain development tooling such as `git` for plugin development purposes. + +Our Debian and RHEL images are built with minimal dependencies (as of {{ site.base_gateway }} 3.0) and run through automated security scanners before being published. Any vulnerabilities detected in supported images will be addressed in the next available patch release. + +If you would like to build your own images to further customise the base image and any dependencies, follow the instructions below: + +1. Download the [docker-entrypoint.sh](https://raw.githubusercontent.com/Kong/docker-kong/master/docker-entrypoint.sh) script from `docker-kong` and make it executable with `chmod +x docker-entrypoint.sh` + +1. Download the [.deb]({{ site.links.download }}/gateway-3.x-ubuntu-focal/pool/all/k/kong-enterprise-edition/kong-enterprise-edition_{{ page.kong_versions[page.version-index].ee-version }}_amd64.deb), [.rpm]({{ site.links.download }}/gateway-3.x-rhel-8/Packages/k/kong-enterprise-edition-{{page.kong_versions[page.version-index].ee-version}}.rhel8.amd64.rpm) or .apk ([amd64]({{ site.links.download }}/gateway-3.x-alpine/kong-enterprise-edition-{{page.kong_versions[page.version-index].ee-version}}.amd64.apk.tar.gz), [arm64]({{ site.links.download }}/gateway-3.x-alpine/kong-enterprise-edition-{{page.kong_versions[page.version-index].ee-version}}.arm64.apk.tar.gz)) as required + +1. Create a `Dockerfile` with the following contents: + +{% capture dockerfile_run_steps %}COPY docker-entrypoint.sh /docker-entrypoint.sh + +USER kong + +ENTRYPOINT ["/docker-entrypoint.sh"] + +EXPOSE 8000 8443 8001 8444 8002 8445 8003 8446 8004 8447 + +STOPSIGNAL SIGQUIT + +HEALTHCHECK --interval=10s --timeout=10s --retries=10 CMD kong health + +CMD ["kong", "docker-start"]{% endcapture %} + +{% capture dockerfile %} +{% navtabs codeblock indent %} + +{% navtab Debian %} +```dockerfile + +FROM debian:bullseye-slim + +COPY kong.deb /tmp/kong.deb + +RUN set -ex; \ + apt-get update \ + && apt-get install --yes /tmp/kong.deb \ + && rm -rf /var/lib/apt/lists/* \ + && rm -rf /tmp/kong.deb \ + && chown kong:0 /usr/local/bin/kong \ + && chown -R kong:0 /usr/local/kong \ + && ln -s /usr/local/openresty/bin/resty /usr/local/bin/resty \ + && ln -s /usr/local/openresty/luajit/bin/luajit /usr/local/bin/luajit \ + && ln -s /usr/local/openresty/luajit/bin/luajit /usr/local/bin/lua \ + && ln -s /usr/local/openresty/nginx/sbin/nginx /usr/local/bin/nginx \ + && kong version + +{{ dockerfile_run_steps }} +``` +{% endnavtab %} + +{% navtab Ubuntu %} +```dockerfile + +FROM ubuntu:20.04 + +COPY kong.deb /tmp/kong.deb + +RUN set -ex; \ + apt-get update \ + && apt-get install --yes /tmp/kong.deb \ + && rm -rf /var/lib/apt/lists/* \ + && rm -rf /tmp/kong.deb \ + && chown kong:0 /usr/local/bin/kong \ + && chown -R kong:0 /usr/local/kong \ + && ln -s /usr/local/openresty/bin/resty /usr/local/bin/resty \ + && ln -s /usr/local/openresty/luajit/bin/luajit /usr/local/bin/luajit \ + && ln -s /usr/local/openresty/luajit/bin/luajit /usr/local/bin/lua \ + && ln -s /usr/local/openresty/nginx/sbin/nginx /usr/local/bin/nginx \ + && kong version + +{{ dockerfile_run_steps }} +``` +{% endnavtab %} + +{% navtab RHEL %} +```dockerfile + +FROM registry.access.redhat.com/ubi8/ubi:8.1 + +COPY kong.rpm /tmp/kong.rpm + +RUN set -ex; \ + yum install -y /tmp/kong.rpm \ + && rm /tmp/kong.rpm \ + && chown kong:0 /usr/local/bin/kong \ + && chown -R kong:0 /usr/local/kong \ + && ln -s /usr/local/openresty/bin/resty /usr/local/bin/resty \ + && ln -s /usr/local/openresty/luajit/bin/luajit /usr/local/bin/luajit \ + && ln -s /usr/local/openresty/luajit/bin/luajit /usr/local/bin/lua \ + && ln -s /usr/local/openresty/nginx/sbin/nginx /usr/local/bin/nginx \ + && kong version + +{{ dockerfile_run_steps }} +``` +{% endnavtab %} + +{% navtab Alpine %} +```dockerfile + +FROM alpine:latest + +COPY kong.apk.tar.gz /tmp/kong.apk.tar.gz + +RUN set -ex; \ + apk add bash curl ca-certificates; \ + arch="$(apk --print-arch)"; \ + case "${arch}" in \ + x86_64) export ARCH='amd64'; KONG_SHA256=$KONG_AMD64_SHA ;; \ + aarch64) export ARCH='arm64'; KONG_SHA256=$KONG_ARM64_SHA ;; \ + esac; \ + apk add --no-cache --virtual .build-deps tar gzip \ + && tar -C / -xzf /tmp/kong.apk.tar.gz \ + && apk add --no-cache libstdc++ libgcc openssl pcre perl tzdata libcap zlib zlib-dev bash \ + && adduser -S kong \ + && addgroup -S kong \ + && mkdir -p "/usr/local/kong" \ + && chown -R kong:0 /usr/local/kong \ + && chown kong:0 /usr/local/bin/kong \ + && chmod -R g=u /usr/local/kong \ + && rm -rf /tmp/kong.tar.gz \ + && ln -s /usr/local/openresty/bin/resty /usr/local/bin/resty \ + && ln -s /usr/local/openresty/luajit/bin/luajit /usr/local/bin/luajit \ + && ln -s /usr/local/openresty/luajit/bin/luajit /usr/local/bin/lua \ + && ln -s /usr/local/openresty/nginx/sbin/nginx /usr/local/bin/nginx \ + && apk del .build-deps \ + && kong version + +{{ dockerfile_run_steps }} +``` +{% endnavtab %} + +{% endnavtabs %} +{% endcapture %} +{{ dockerfile | indent }} + +1. Build your image with `docker build --no-cache -t kong-your-tag .` + +1. Test that the image built correctly with `docker run -it kong-your-tag kong version` + +1. To run {{ site.base_gateway }} and process traffic, follow the [Docker install instructions](/gateway/latest/install/docker/), replacing the image name with your custom name diff --git a/src/gateway/install/docker/index.md b/src/gateway/install/docker/index.md new file mode 100644 index 000000000000..b6dc6b14a064 --- /dev/null +++ b/src/gateway/install/docker/index.md @@ -0,0 +1,449 @@ +--- +title: Install Kong Gateway on Docker +--- + +{{site.base_gateway}} supports both PostgreSQL 9.5+ and Cassandra 3.11.* as its +datastore. This guide provides steps to configure PostgreSQL. + +If you prefer to use the open-source {{site.base_gateway}} image with Docker +Compose, Kong also provides a +[Docker Compose template](https://github.com/Kong/docker-kong/tree/master/compose) +with built-in orchestration and scalability. + +Some [older {{site.base_gateway}} images](https://support.konghq.com/support/s/article/Downloading-older-Kong-versions) +are not publicly accessible. If you need a specific patch version and can't +find it on [Kong's public Docker Hub page](https://hub.docker.com/r/kong/kong-gateway), contact +[Kong Support](https://support.konghq.com/). + +The {{site.base_gateway}} software is governed by the +[Kong Software License Agreement](https://konghq.com/kongsoftwarelicense). +{{site.ce_product_name}} is licensed under an +[Apache 2.0 license](https://github.com/Kong/kong/blob/master/LICENSE). + +## Prerequisites + +* A Docker-enabled system with proper Docker access +* (Enterprise only) A `license.json` file from Kong + +Choose a path to install Kong Gateway: +* [With a database](#install-kong-gateway-with-a-database): Use a database to +store Kong entity configurations. Can use the Admin API or declarative +configuration files to configure Kong. +* [Without a database (DB-less mode)](#install-kong-gateway-in-db-less-mode): +Store Kong configuration in-memory on the node. In this mode, the Admin API is +read only, and you have to manage Kong using declarative configuration. + +If this is your first time trying out Kong Gateway, we recommend installing it +with a database. + +## Install Kong Gateway with a database + +Set up a {{site.base_gateway}} container with a PostgreSQL database to store +Kong configuration. + +{% include_cached /md/enterprise/cassandra-deprecation.md %} + +### Prepare the database + +1. Create a custom Docker network to allow the containers to discover and +communicate with each other: + + ```sh + docker network create kong-net + ``` + + You can name this network anything you want. We use `kong-net` as + an example throughout this guide. + +1. Start a PostgreSQL container: + + ```sh + docker run -d --name kong-database \ + --network=kong-net \ + -p 5432:5432 \ + -e "POSTGRES_USER=kong" \ + -e "POSTGRES_DB=kong" \ + -e "POSTGRES_PASSWORD=kongpass" \ + postgres:9.6 + ``` + + * `POSTGRES_USER` and `POSTGRES_DB`: Set these values to `kong`. This is + the default value that Kong Gateway expects. + * `POSTGRES_PASSWORD`: Set the database password to any string. + + In this example, the Postgres container named `kong-database` can + communicate with any containers on the `kong-net` network. + +1. Prepare the Kong database: + +{% capture migrations %} +{% navtabs_ee codeblock %} +{% navtab Kong Gateway %} +```sh +docker run --rm --network=kong-net \ + -e "KONG_DATABASE=postgres" \ + -e "KONG_PG_HOST=kong-database" \ + -e "KONG_PG_PASSWORD=kongpass" \ + -e "KONG_PASSWORD=test" \ +kong/kong-gateway:{{page.kong_versions[page.version-index].ee-version}}-alpine kong migrations bootstrap +``` +{% endnavtab %} +{% navtab Kong Gateway (OSS) %} +```sh +docker run --rm --network=kong-net \ + -e "KONG_DATABASE=postgres" \ + -e "KONG_PG_HOST=kong-database" \ + -e "KONG_PG_PASSWORD=kongpass" \ +kong:{{page.kong_versions[page.version-index].ce-version}}-alpine kong migrations bootstrap +``` +{% endnavtab %} +{% endnavtabs_ee %} +{% endcapture %} +{{ migrations | indent | replace: "
      ", "" }} + + Where: + * [`KONG_DATABASE`](/gateway/{{page.kong_version}}/reference/configuration/#database): + Specifies the type of database that Kong is using. + * [`KONG_PG_HOST`](/gateway/{{page.kong_version}}/reference/configuration/#postgres-settings): + The name of the Postgres Docker container that is communicating over the + `kong-net` network, from the previous step. + * [`KONG_PG_PASSWORD`](/gateway/{{page.kong_version}}/reference/configuration/#postgres-settings): + The password that you set when bringing up the Postgres container in the + previous step. + * `KONG_PASSWORD` (Enterprise only): The default password for the admin + super user for Kong Gateway. + * `{IMAGE-NAME:TAG} kong migrations bootstrap`: + In order, this is the Kong Gateway container name and tag, followed by the + command to Kong to prepare the Postgres database. + +### Start Kong Gateway + +{% include_cached /md/admin-listen.md desc='long' kong_version=page.kong_version %} + +1. (Optional) If you have an Enterprise license for {{site.base_gateway}}, +export the license key to a variable: + + The license data must contain straight quotes to be considered valid JSON + (`'` and `"`, not `’` or `“`). + + {:.note} + > **Note:** + The following license is only an example. You must use the following format, + but provide your own content. + + ```bash + export KONG_LICENSE_DATA='{"license":{"payload":{"admin_seats":"1","customer":"Example Company, Inc","dataplanes":"1","license_creation_date":"2017-07-20","license_expiration_date":"2017-07-20","license_key":"00141000017ODj3AAG_a1V41000004wT0OEAU","product_subscription":"Konnect Enterprise","support_plan":"None"},"signature":"6985968131533a967fcc721244a979948b1066967f1e9cd65dbd8eeabe060fc32d894a2945f5e4a03c1cd2198c74e058ac63d28b045c2f1fcec95877bd790e1b","version":"1"}}' + ``` + +1. Run the following command to start a container with {{site.base_gateway}}: +{% capture start_container %} +{% navtabs_ee codeblock %} +{% navtab Kong Gateway %} +```sh +docker run -d --name kong-gateway \ + --network=kong-net \ + -e "KONG_DATABASE=postgres" \ + -e "KONG_PG_HOST=kong-database" \ + -e "KONG_PG_USER=kong" \ + -e "KONG_PG_PASSWORD=kongpass" \ + -e "KONG_PROXY_ACCESS_LOG=/dev/stdout" \ + -e "KONG_ADMIN_ACCESS_LOG=/dev/stdout" \ + -e "KONG_PROXY_ERROR_LOG=/dev/stderr" \ + -e "KONG_ADMIN_ERROR_LOG=/dev/stderr" \ + -e "KONG_ADMIN_LISTEN=0.0.0.0:8001" \ + -e "KONG_ADMIN_GUI_URL=http://localhost:8002" \ + -e KONG_LICENSE_DATA \ + -p 8000:8000 \ + -p 8443:8443 \ + -p 8001:8001 \ + -p 8444:8444 \ + -p 8002:8002 \ + -p 8445:8445 \ + -p 8003:8003 \ + -p 8004:8004 \ + kong/kong-gateway:{{page.kong_versions[page.version-index].ee-version}}-alpine +``` +{% endnavtab %} +{% navtab Kong Gateway (OSS) %} +```sh +docker run -d --name kong-gateway \ + --network=kong-net \ + -e "KONG_DATABASE=postgres" \ + -e "KONG_PG_HOST=kong-database" \ + -e "KONG_PG_USER=kong" \ + -e "KONG_PG_PASSWORD=kongpass" \ + -e "KONG_PROXY_ACCESS_LOG=/dev/stdout" \ + -e "KONG_ADMIN_ACCESS_LOG=/dev/stdout" \ + -e "KONG_PROXY_ERROR_LOG=/dev/stderr" \ + -e "KONG_ADMIN_ERROR_LOG=/dev/stderr" \ + -e "KONG_ADMIN_LISTEN=0.0.0.0:8001, 0.0.0.0:8444 ssl" \ + -p 8000:8000 \ + -p 8443:8443 \ + -p 127.0.0.1:8001:8001 \ + -p 127.0.0.1:8444:8444 \ + kong:{{page.kong_versions[page.version-index].ce-version}}-alpine + ``` +{% endnavtab %} +{% endnavtabs_ee %} +{% endcapture %} +{{ start_container | indent | replace: " ", "" }} + + Where: + * `--name` and `--network`: The name of the container to create, + and the Docker network it communicates on. + * [`KONG_DATABASE`](/gateway/{{page.kong_version}}/reference/configuration/#database): + Specifies the type of database that Kong is using. + * [`KONG_PG_HOST`](/gateway/{{page.kong_version}}/reference/configuration/#postgres-settings): + The name of the Postgres Docker container that is communicating over the + `kong-net` network. + * [`KONG_PG_USER` and `KONG_PG_PASSWORD`](/gateway/{{page.kong_version}}/reference/configuration/#postgres-settings): + The Postgres username and password. Kong Gateway needs the login information + to store configuration data in the `KONG_PG_HOST` database. + * All [`_LOG`](/gateway/{{page.kong_version}}/reference/configuration/#general-section) + parameters: set filepaths for the logs to output to, or use the values in + the example to print messages and errors to `stdout` and `stderr`. + * [`KONG_ADMIN_LISTEN`](/gateway/{{page.kong_version}}/reference/configuration/#admin_listen): + The port that the Kong Admin API listens on for requests. + * [`KONG_ADMIN_GUI_URL`](/gateway/{{page.kong_version}}/reference/configuration/#admin_gui_url): + (Enterprise only) The URL for accessing Kong Manager, preceded by a protocol + (for example, `http://`). + * `KONG_LICENSE_DATA`: (Enterprise only) If you have a license file and have saved it + as an environment variable, this parameter pulls the license from your environment. + +1. Verify your installation: + + Access the `/services` endpoint using the Admin API: + + ```sh + curl -i -X GET --url http://localhost:8001/services + ``` + + You should receive a `200` status code. + +1. (Not available in OSS) Verify that Kong Manager is running by accessing it +using the URL specified in `KONG_ADMIN_GUI_URL`: + + ``` + http://localhost:8002 + ``` + +### Get started with Kong Gateway + +Now that you have a running Gateway instance, Kong provides a series of +[getting started guides](/gateway/{{page.kong_version}}/get-started/services-and-routes/) + to help you set up and enhance your first Service. + + +In particular, right after installation you might want to: +* [Create a service and a route](/gateway/{{page.kong_version}}/get-started/services-and-routes) +* [Configure a plugin](/gateway/{{page.kong_version}}/get-started/rate-limiting) +* [Secure your services with authentication](/gateway/{{page.kong_version}}/get-started/key-authentication) + +### Clean up containers + +If you're done testing Kong Gateway and no longer need the containers, you +can clean them up using the following commands: + +``` +docker kill kong-gateway +docker kill kong-database +docker container rm kong-gateway +docker container rm kong-database +docker network rm kong-net +``` + +## Install Kong Gateway in DB-less mode + +The following steps walk you through starting Kong Gateway in +[DB-less mode](/gateway/{{page.kong_version}}/production/deployment-topologies/db-less-and-declarative-config). + +### Create a Docker network + +Run the following command: + +```bash +docker network create kong-net +``` + +You can name this network anything you want. We use `kong-net` as +an example throughout this guide. + +This step is not strictly needed for running Kong in DB-less mode, but it is a good +precaution in case you want to add other things in the future (like a Rate Limiting plugin +backed up by a Redis cluster). + +### Prepare your configuration file + +1. Prepare your declarative configuration file in `.yml` or `.json` format. + + The syntax and properties are + described in the [Declarative Configuration format] guide. Add whatever core + entities (Services, Routes, Plugins, Consumers, etc) you need to this file. + + For example, a simple file with a Service and a Route + could look something like this: + + ```yaml + _format_version: "3.0" + _transform: true + + services: + - host: mockbin.org + name: example_service + port: 80 + protocol: http + routes: + - name: example_route + paths: + - /mock + strip_path: true + ``` + + This guide assumes you named the file `kong.yml`. + +1. Save your declarative configuration locally, and note the filepath. + +### Start Kong Gateway in DB-less mode + +{% include_cached /md/admin-listen.md desc='long' kong_version=page.kong_version %} + +1. (Optional) If you have an Enterprise license for {{site.base_gateway}}, +export the license key to a variable: + + The license data must contain straight quotes to be considered valid JSON + (`'` and `"`, not `’` or `“`). + + {:.note} + > **Note:** + The following license is only an example. You must use the following format, + but provide your own content. + + ```bash + export KONG_LICENSE_DATA='{"license":{"payload":{"admin_seats":"1","customer":"Example Company, Inc","dataplanes":"1","license_creation_date":"2017-07-20","license_expiration_date":"2017-07-20","license_key":"00141000017ODj3AAG_a1V41000004wT0OEAU","product_subscription":"Konnect Enterprise","support_plan":"None"},"signature":"6985968131533a967fcc721244a979948b1066967f1e9cd65dbd8eeabe060fc32d894a2945f5e4a03c1cd2198c74e058ac63d28b045c2f1fcec95877bd790e1b","version":"1"}}' + ``` + +1. From the same directory where you just created the `kong.yml` file, +run the following command to start a container with {{site.base_gateway}}: + +{% capture start_container %} +{% navtabs_ee codeblock %} +{% navtab Kong Gateway %} +```sh +docker run -d --name kong-dbless \ + --network=kong-net \ + -v "$(pwd):/kong/declarative/" \ + -e "KONG_DATABASE=off" \ + -e "KONG_DECLARATIVE_CONFIG=/kong/declarative/kong.yml" \ + -e "KONG_PROXY_ACCESS_LOG=/dev/stdout" \ + -e "KONG_ADMIN_ACCESS_LOG=/dev/stdout" \ + -e "KONG_PROXY_ERROR_LOG=/dev/stderr" \ + -e "KONG_ADMIN_ERROR_LOG=/dev/stderr" \ + -e "KONG_ADMIN_LISTEN=0.0.0.0:8001" \ + -e "KONG_ADMIN_GUI_URL=http://localhost:8002" \ + -e KONG_LICENSE_DATA \ + -p 8000:8000 \ + -p 8443:8443 \ + -p 8001:8001 \ + -p 8444:8444 \ + -p 8002:8002 \ + -p 8445:8445 \ + -p 8003:8003 \ + -p 8004:8004 \ + kong/kong-gateway:{{page.kong_versions[page.version-index].ee-version}}-alpine +``` +{% endnavtab %} +{% navtab Kong Gateway (OSS) %} +```sh +docker run -d --name kong-dbless \ + --network=kong-net \ + -v "$(pwd):/kong/declarative/" \ + -e "KONG_DATABASE=off" \ + -e "KONG_DECLARATIVE_CONFIG=/kong/declarative/kong.yml" \ + -e "KONG_PROXY_ACCESS_LOG=/dev/stdout" \ + -e "KONG_ADMIN_ACCESS_LOG=/dev/stdout" \ + -e "KONG_PROXY_ERROR_LOG=/dev/stderr" \ + -e "KONG_ADMIN_ERROR_LOG=/dev/stderr" \ + -e "KONG_ADMIN_LISTEN=0.0.0.0:8001, 0.0.0.0:8444 ssl" \ + -p 8000:8000 \ + -p 8443:8443 \ + -p 127.0.0.1:8001:8001 \ + -p 127.0.0.1:8444:8444 \ + kong:{{page.kong_versions[page.version-index].ce-version}}-alpine + ``` +{% endnavtab %} +{% endnavtabs_ee %} +{% endcapture %} +{{ start_container | indent | replace: " ", "" }} + + Where: + * `--name` and `--network`: The name of the container to create, + and the Docker network it communicates on. + * `-v $(pwd):/path/to/target/`: Mount the current directory on your + local filesystem to a directory in the Docker container. This makes the + `kong.yml` file visible from the Docker container. + * [`KONG_DATABASE`](/gateway/{{page.kong_version}}/reference/configuration/#database): + Sets the database to `off` to tell Kong not to use any + backing database for configuration storage. + * [`KONG_DECLARATIVE_CONFIG`](/gateway/{{page.kong_version}}/reference/configuration/#declarative_config): + The path to a declarative configuration file inside the container. + This path should match the target path that you're mapping with `-v`. + * All [`_LOG`](/gateway/{{page.kong_version}}/reference/configuration/#general-section) + parameters: set filepaths for the logs to output to, or use the values in + the example to print messages and errors to `stdout` and `stderr`. + * [`KONG_ADMIN_LISTEN`](/gateway/{{page.kong_version}}/reference/configuration/#admin_listen): + The port that the Kong Admin API listens on for requests. + * [`KONG_ADMIN_GUI_URL`](/gateway/{{page.kong_version}}/reference/configuration/#admin_gui_url): + (Enterprise only) The URL for accessing Kong Manager, preceded by a protocol + (for example, `http://`). + * `KONG_LICENSE_DATA`: (Enterprise only) If you have a license file and have saved it + as an environment variable, this parameter pulls the license from your environment. + +1. Verify that {{site.base_gateway}} is running: + + ```sh + curl -i http://localhost:8001 + ``` + + Test an endpoint. For example, get a list of services: + + ```sh + curl -i http://localhost:8001/services + ``` + +[DB-less mode]: /gateway/{{page.kong_version}}/production/deployment-topologies/db-less-and-declarative-config/ +[Declarative Configuration format]: /gateway/{{page.kong_version}}/production/deployment-topologies/db-less-and-declarative-config/#the-declarative-configuration-format +[Docker Volume]: https://docs.docker.com/storage/volumes/ + +### Get started with Kong Gateway + +Now that you have a running Gateway instance, Kong provides a series of +[getting started guides](/gateway/{{page.kong_version}}/get-started/services-and-routes/) +to help you set up and enhance your first Service. + +If you use the sample `kong.yml` in this guide, you already have a Service and +a Route configured. Here are a few more things to check out: +* [Configure a plugin](/gateway/{{page.kong_version}}/get-started/rate-limiting?tab=using-deck-yaml) +* [Secure your services with authentication](/gateway/{{page.kong_version}}/get-started/key-authentication?tab=using-deck-yaml) +* [Load balance traffic across targets](/gateway/{{page.kong_version}}/get-started/load-balancing/?tab=using-deck-yaml) + +### Clean up containers + +If you're done testing Kong Gateway and no longer need the containers, you +can clean them up using the following commands: + +``` +docker kill kong-dbless +docker container rm kong-dbless +docker network rm kong-net +``` + +## Troubleshooting + +For troubleshooting license issues, see: +* [Deployment options for licenses](/gateway/{{page.kong_version}}/licenses/deploy/) +* [`/licenses` API reference](/gateway/{{page.kong_version}}/admin-api/licenses/reference/) +* [`/licenses` API examples](/gateway/{{page.kong_version}}/licenses/examples) + +If you did not receive a `200 OK` status code or need assistance completing +setup, reach out to your support contact or head over to the +[Support Portal](https://support.konghq.com/support/s/). diff --git a/src/gateway/install/helm-quickstart.md b/src/gateway/install/helm-quickstart.md new file mode 100644 index 000000000000..22ca33377667 --- /dev/null +++ b/src/gateway/install/helm-quickstart.md @@ -0,0 +1,428 @@ +--- +title: Install with Kong Gateway using Helm +toc: true +content-type: how-to +--- + + +This guide will show you how to install {{site.base_gateway}} on Kubernetes with Helm. Two options are provided for deploying a local development environment using [Docker Desktop Kubernetes](https://docs.docker.com/desktop/kubernetes/) and [Kind Kubernetes](https://kind.sigs.k8s.io/). You can also follow this guide using an existing cloud hosted Kubernetes cluster. + + +{% navtabs %} +{% navtab Docker Desktop Kubernetes %} +## Docker Desktop + +Docker Desktop Kubernetes is a tool for running a local Kubernetes cluster using Docker. These instructions will guide you through deploying {{site.base_gateway}} to a local Docker Desktop Kubernetes cluster. + +## Dependencies + +- [`Helm 3`](https://helm.sh/) +- [`kubectl`](https://kubernetes.io/docs/tasks/tools/) v1.19 or later +- [Docker Desktop Kubernetes](https://docs.docker.com/desktop/kubernetes/) + +{:.note} +> Kong services will be published to localhost at the domain name `https://kong.127-0-0-1.nip.io`. The [nip.io](https://nip.io) service is used to automatically resolve this domain to the localhost address. + +## Configure Kubectl + +Set your kubeconfig context and verify with the following command: + + kubectl config use-context docker-desktop && kubectl cluster-info + + +{% endnavtab %} +{% navtab Kind Kubernetes %} + +## Kind Kubernetes + +Kind or "Kubernetes-in-Docker", is a tool for running local Kubernetes clusters in Docker containers. These instructions will guide you through deploying {{site.base_gateway}} to a local Kind Kubernetes cluster. + + +## Dependencies + +- [`Helm 3`](https://helm.sh/) +- [`kubectl`](https://kubernetes.io/docs/tasks/tools/) v1.19 or later +- [KinD](https://kind.sigs.k8s.io/) + +{:.note} +> Kong services will be published to localhost at the domain name `https://kong.127-0-0-1.nip.io`. The [nip.io](https://nip.io) service is used to automatically resolve this domain to the localhost address. + +## Create Kubernetes Cluster + +A Kind config file is required to build a local cluster listening locally on ports `80` and `443`. Starting from the `bash` command, and ending with the `EOF"` line, highlight and copy this text block, then paste it into your terminal. + + bash -c "cat < /tmp/kind-config.yaml && kind create cluster --config /tmp/kind-config.yaml + apiVersion: kind.x-k8s.io/v1alpha4 + kind: Cluster + name: kong + networking: + apiServerAddress: "0.0.0.0" + apiServerPort: 16443 + nodes: + - role: control-plane + extraPortMappings: + - listenAddress: "0.0.0.0" + protocol: TCP + hostPort: 80 + containerPort: 80 + - listenAddress: "0.0.0.0" + protocol: TCP + hostPort: 443 + containerPort: 443 + EOF" + +Set your kubeconfig context and verify with the following commands. + + kubectl config use-context kind-kong && kubectl cluster-info + +{% endnavtab %} +{% navtab Kubernetes in the Cloud%} + +## Kubernetes in the cloud + +These instructions will guide you through deploying {{site.base_gateway}} to a cloud hosted Kubernetes cluster you have already built. Please ensure your local system and your Kubernetes cluster meet the dependency criteria listed below before continuing. + +{:.note} +> Please note that it is recommended to first try the Docker Desktop or Kind Kubernetes local deploys before proceeding to build on a cloud hosted kubernetes cluster. + +## Dependencies + +- [`Helm 3`](https://helm.sh/) +- [`kubectl`](https://kubernetes.io/docs/tasks/tools/) v1.19 or later +- Domain Name +- DNS configured with your DNS Provider +- Public Cloud hosted Kubernetes cluster +- [Cloud load balancer support](https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/) + +## Configure Kubectl + +Verify your kubeconfig context is set correctly with the following command. + + kubectl cluster-info + +## Prepare the Helm chart + +To inject your custom domain name into the Helm values file configure the {{site.base_gateway}} deployment with: + +1. `curl` the example values.yaml file. + + curl -o ~/quickstart.yaml -L https://bit.ly/KongGatewayHelmValuesAIO + +2. Replace `example.com` with your preferred domain name and export as a variable. + + export BASE_DOMAIN="example.com" + +3. Replace the `127-0-0-1.nip.io` base domain in the values file with your preferred domain name. + + sed -i "s/127-0-0-1\.nip\.io/$BASE_DOMAIN/g" ~/quickstart.yaml + +{% endnavtab %} +{% endnavtabs %} + +## Create {{site.base_gateway}} secrets + +Configuring {{site.base_gateway}} requires a namespace and configuration secrets. The secrets contain Kong's enterprise license, admin password, session configurations, and PostgreSQL connection details. + +1. Create the Kong namespace for {{site.base_gateway}}: + + kubectl create namespace kong + +2. Create Kong config and credential variables: + + kubectl create secret generic kong-config-secret -n kong \ + --from-literal=portal_session_conf='{"storage":"kong","secret":"super_secret_salt_string","cookie_name":"portal_session","cookie_samesite":"off","cookie_secure":false}' \ + --from-literal=admin_gui_session_conf='{"storage":"kong","secret":"super_secret_salt_string","cookie_name":"admin_session","cookie_samesite":"off","cookie_secure":false}' \ + --from-literal=pg_host="enterprise-postgresql.kong.svc.cluster.local" \ + --from-literal=kong_admin_password=kong \ + --from-literal=password=kong + +4. Create a Kong Enterprise license secret: + +{% navtabs %} +{% navtab Kong Enterprise Free Mode%} + + kubectl create secret generic kong-enterprise-license --from-literal=license="'{}'" -n kong --dry-run=client -o yaml | kubectl apply -f - + +{% endnavtab %} +{% navtab Kong Enterprise Licensed Mode%} + + >This command must be run in the directory that contains your `license.json` file. + + kubectl create secret generic kong-enterprise-license --from-file=license=license.json -n kong --dry-run=client -o yaml | kubectl apply -f - + +{% endnavtab %} +{% endnavtabs %} + +{:.note} +> Kong can run in two license modes, Enterprise Licensed, or Enterprise Free. If you would like to run all enterprise features, please contact your account manager to request a `license.json` file. + +## Install Cert Manager + +Cert Manager provides automation for generating SSL certificates. {{site.base_gateway}} uses Cert Manager to provide the required certificates. + + + +Install Cert Manager and create a basic [SelfSigned](https://cert-manager.io/docs/configuration/selfsigned/) certificate issuer: + +1. Add the Jetstack Cert Manager Helm repository: + + helm repo add jetstack https://charts.jetstack.io ; helm repo update + +2. Install Cert Manager: + + helm upgrade --install cert-manager jetstack/cert-manager \ + --set installCRDs=true --namespace cert-manager --create-namespace + +3. Create a SelfSigned certificate issuer: + + bash -c "cat < You will receive a "Your Connection is not Private" warning message due to using selfsigned certs. If you are using Chrome there may not be an "Accept risk and continue" option, to continue type `thisisunsafe` while the tab is in focus to continue. + +5. If running {{site.base_gateway}} in Licensed Mode, use the Super Admin username with the password set in the secret `kong-config-secret` created earlier: `kong_admin`:`kong` + +{% endnavtab %} +{% navtab Kind Kubernetes %} + +Once all dependencies are installed and ready, deploy {{site.base_gateway}} to your cluster: + +1. Add the Kong Helm repo: + + helm repo add kong https://charts.konghq.com ; helm repo update + +2. Install Kong: + + helm install quickstart kong/kong --namespace kong --values https://bit.ly/KongGatewayHelmValuesAIO + +3. Wait for all pods to be in the `Running` state: + + kubectl get po --namespace kong -w + +4. Once all the pods are running, open Kong Manager in your browser at its ingress host domain, for example: [https://kong.127-0-0-1.nip.io](https://kong.127-0-0-1.nip.io). Or open it with the following command: + + open "https://$(kubectl get ingress --namespace kong quickstart-kong-manager -o jsonpath='{.spec.tls[0].hosts[0]}')" + + {:.important} + > You will receive a "Your Connection is not Private" warning message due to using selfsigned certs. If you are using Chrome there may not be an "Accept risk and continue" option, to continue type `thisisunsafe` while the tab is in focus to continue. + +5. If running {{site.base_gateway}} in Licensed Mode, use the Super Admin username with the password set in the secret `kong-config-secret` created earlier: `kong_admin`:`kong` + +{% endnavtab %} +{% navtab Kubernetes in the Cloud%} + +Once all dependencies are installed and ready, deploy {{site.base_gateway}} to your cluster: + +1. Add the Kong Helm repo: + + helm repo add kong https://charts.konghq.com ; helm repo update + +2. Install Kong: + + helm install quickstart kong/kong --namespace kong --values ~/quickstart.yaml + +3. Wait for all pods to be in the `Running` state: + + kubectl get po --namespace kong -w + +4. Once all pods are running, find the cloud load balancer of your {{site.base_gateway}} data plane: + + kubectl get svc --namespace kong quickstart-kong-proxy -w + +5. Using your DNS Provider, configure a DNS entry to point to the load balancer shown by the last step. A wildcard DNS record is recommended for development environments. + +6. Open Kong Manager with the kong subdomain on your domain. For example: `https://kong.example.com`, or open it with the following command: + + open "https://$(kubectl get ingress --namespace kong quickstart-kong-manager -o jsonpath='{.spec.tls[0].hosts[0]}')" + + {:.important} + > You will receive a "Your Connection is not Private" warning message due to using selfsigned certs. If you are using Chrome there may not be an "Accept risk and continue" option, to continue type `thisisunsafe` while the tab is in focus to continue. + +7. If running {{site.base_gateway}} in Licensed Mode, use the Super Admin username with the password set in the secret `kong-config-secret` created earlier: `kong_admin`:`kong` + +{% endnavtab %} +{% endnavtabs %} + +## Use {{site.base_gateway}} + +{{site.base_gateway}} is now serving the Kong Manager WebGUI and the Kong Admin API. + +For local deployments, Kong Manager is locally accessible at `https://kong.127-0-0-1.nip.io`. The [nip.io](https://nip.io) service resolves this domain to localhost also known as `127.0.0.1`. + +You can configure Kong via the Admin API with [decK](https://docs.konghq.com/deck/latest/), [Insomnia](https://docs.insomnia.rest/insomnia/get-started), HTTPie, or cURL, at `https://kong.127-0-0-1.nip.io/api`: + +{% navtabs codeblock %} +{% navtab cURL %} + + curl --silent --insecure -X GET https://kong.127-0-0-1.nip.io/api -H 'kong-admin-token:kong' + +{% endnavtab %} +{% navtab HTTPie %} + + http --verify=no get https://kong.127-0-0-1.nip.io/api kong-admin-token:kong + +{% endnavtab %} +{% endnavtabs %} + +## Teardown + +{% navtabs %} +{% navtab Docker Desktop Kubernetes %} + +To remove {{site.base_gateway}} from your system, follow these instructions: + +1. Remove Kong + + helm uninstall --namespace kong quickstart + +2. Delete Kong secrets + + kubectl delete secrets -nkong kong-enterprise-license + kubectl delete secrets -nkong kong-config-secret + +3. Remove Kong database PVC + + kubectl delete pvc -n kong data-quickstart-postgresql-0 + +4. Remove Kong Helm chart repository + + helm repo remove kong + +5. Remove cert-manager + + helm uninstall --namespace cert-manager cert-manager + +6. Remove jetstack cert-manager Helm repository + + helm repo remove jetstack + +{% endnavtab %} +{% navtab Kind Kubernetes %} + +To remove {{site.base_gateway}} from your system, follow these instructions: + +1. Remove Kong + + helm uninstall --namespace kong quickstart + +2. Delete Kong secrets + + kubectl delete secrets -nkong kong-enterprise-license + kubectl delete secrets -nkong kong-config-secret + +3. Remove Kong database PVC + + kubectl delete pvc -n kong data-quickstart-postgresql-0 + +4. Remove Kong Helm chart repository + + helm repo remove kong + +5. Remove cert-manager + + helm uninstall --namespace cert-manager cert-manager + +6. Remove jetstack cert-manager Helm repository + + helm repo remove jetstack + +7. Destroy the Kind cluster + + kind delete cluster --name=kong + rm /tmp/kind-config.yaml + +{% endnavtab %} +{% navtab Kubernetes in the Cloud%} + +To remove {{site.base_gateway}} from your system, follow these instructions: + +1. Remove Kong + + helm uninstall --namespace kong quickstart + +2. Delete Kong secrets + + kubectl delete secrets -nkong kong-enterprise-license + kubectl delete secrets -nkong kong-config-secret + +3. Remove Kong database PVC + + kubectl delete pvc -n kong data-quickstart-postgresql-0 + +4. Remove Kong Helm chart repository + + helm repo remove kong + +5. Remove cert-manager + + helm uninstall --namespace cert-manager cert-manager + +6. Remove jetstack cert-manager Helm Repository + + helm repo remove jetstack + +{% endnavtab %} +{% endnavtabs %} + +## Next Steps + +See the [Kong Ingress Controller docs](/kubernetes-ingress-controller/) for how-to guides, reference guides, and more. diff --git a/src/gateway/install/index.md b/src/gateway/install/index.md new file mode 100644 index 000000000000..63666075f51f --- /dev/null +++ b/src/gateway/install/index.md @@ -0,0 +1,14 @@ +--- +title: Installation Options +--- + +Kong can be installed on many different systems. From bare metal, to virtual machines, and cloud native Kubernetes environments, Kong is a low-demand, high-performing API gateway. + +This page outlines Kong's official support policy and provides links to detailed installation instructions for each. + +**Legend:** +* : Full production support +* : Runs as expected, but no official support is available + + +{% include feature-table.html config=site.data.tables.install_options %} diff --git a/src/gateway/install/kubernetes/deployment-options.md b/src/gateway/install/kubernetes/deployment-options.md new file mode 100644 index 000000000000..0bfa67f886ea --- /dev/null +++ b/src/gateway/install/kubernetes/deployment-options.md @@ -0,0 +1,160 @@ +--- +title: Kubernetes Deployment Options +badge: enterprise +--- + +The {{site.kic_product_name}} translates Kubernetes resources into +{{site.base_gateway}} configuration. {{site.base_gateway}} uses that +configuration to route and control traffic. + +The [kong-gateway][enterprise-download] proxy image supports DB-less +operation and is recommended for all deployments. +* [DB-less installation with the Kong Ingress Controller][k4k8s-enterprise-install] +* [Database-backed installation with or without the Kong Ingress Controller](/gateway/{{page.kong_version}}/install/kubernetes/helm-quickstart) + +### Migrating to 2.1.x and up + +Existing users of the `kong-enterprise-k8s` image who want to use 2.1.x or later +should switch to the `kong-gateway` image. + +If you encounter issues after switching images, please +[contact Enterprise Support][support]. + +## DB-less versus database-backed deployments + +When using {{site.base_gateway}} with {{site.kic_product_name}}, the source +of truth for Kong's configuration is +the Kubernetes configuration in etcd: Kong's custom Kubernetes resources, +ingresses, and services provide the information necessary for the ingress +controller to configure Kong. This differs from Kong deployments that do not +use an ingress controller, where configuration in the database or DB-less +config file is the source of truth. + +In traditional deployments, Kong's database provides +a persistent store of configuration available to all Kong nodes to ensure +consistent proxy behavior across the cluster that is not affected by node +restarts. Because etcd provides this functionality in Kong for Kubernetes +deployments, it is not necessary to run an additional database, reducing +maintenance and infrastructure requirements. + +While running {{site.base_gateway}} with {{site.kic_product_name}} +does not require a database, it is fully compatible +with PostgreSQL and requires it for some features. etcd still remains the +source of truth in database-backed deployments: the controller translates +Kubernetes resources from etcd into Kong configuration and inserts them into +the database via the Admin API. + +## Choosing between DB-less or database-backed deployments + +In general, DB-less deployments are simpler to maintain and require less +resources to run. +These deployments must set `KONG_DATABASE=off` in their environment variables. + +Database-backed deployments offer a wider range of features. Review the +sections below to determine if your use case requires a feature that is not +available in DB-less deployments. + +### Feature availability + +Some Enterprise features are not available in DB-less deployments. +Use a database-backed deployment if you want to use: + +* Dev Portal +* Teams (RBAC) +* Workspaces + +The following features have support in DB-less mode, but +work differently than in DB-backed modes: + +* Kong Manager (read-only) +* Vitals (using [Prometheus][vitals-prometheus] or [InfluxDB][vitals-influxdb] + strategies) + +When {{site.base_gateway}} is configured by the ingress controller, some +functionality in these features is different from traditional deployments: + +* Instead of using Kong Manager, proxy configuration is managed by the + controller, and you provide configuration via Kubernetes resources. +* Because the controller creates proxy configuration on behalf of users, you do + not need to interact with the Admin API directly. Kong's own RBAC + implementation isn't required for typical Kong for Kubernetes deployments, as + they do not expose the Admin API; only the controller can access it. + Kubernetes-level RBAC rules and namespaces should be used to restrict what + configuration administrators can create. +* Ingress controller instances create configuration in a single workspace only + (`default` by default). To use multiple workspaces, deploy + multiple controller instances, setting the `CONTROLLER_KONG_WORKSPACE` + environment variable to the workspace that instance should use. These + instances should set `CONTROLLER_INGRESS_CLASS` to unique values for each + instance to avoid creating duplicate configuration in workspaces. Note that + if controller instances are deployed outside the Kong pod the Admin API must + be exposed, and users should enable RBAC with workspace admin users for the + controllers. Set `CONTROLLER_KONG_ADMIN_TOKEN` to the RBAC user's token. +* The controller cannot manage configuration for features that require a + database: it cannot create workspaces, Dev Portal content, admins, etc. These + features must be configured manually through the Admin API or Kong Manager. + +### Plugin compatibility + +Not all plugins are compatible with DB-less operation. Review the +[list of supported plugins][supported-plugins] to see if you require a plugin +that needs a database. + +Third-party plugins are generally compatible with DB-less as long as they do +not create custom entities (i.e. they do not add new entities that users can +create and modify through the Admin API). + +### Manual configuration + +DB-less configuration must be supplied as a complete unit: it is not possible +to add or modify entities individually through the Admin API, or provide +partial configuration that is added to existing configuration. As such, all +configuration must be sourced from Kubernetes resources so that the ingress +controller can render it into a complete configuration. + +On database-backed deployments, users can create or modify configuration +through the Admin API. The ingress controller uses a tag (set by the +`CONTROLLER_KONG_ADMIN_FILTER_TAG` environment variable) to to identify +configuration that it manages. While the controller will revert changes to +configuration with its tag, other configuration is left as-is. + +Although database-backed deployments can use controller-generated and +manually-added configuration simultaneously, Kong's recommended best practice +is to manage as much configuration through Kubernetes resources as possible. +Using both controller-managed and manual configuration can result in conflicts +between the two, and conflicts will prevent the controller from applying its +configuration. To minimize this risk: + +* Use the [admission webhook][admission-webhook] + to reject Kubernetes resources that conflict with other configuration, or are + otherwise invalid. +* Manually create configuration in a workspace that is not managed by the + controller. This avoids most conflicts, but not all: routes may still + conflict depending on your [route validation][route-validation] setting. + +Large numbers of consumers (and associated credentials) are the exception to +this rule: if your consumer count is in the tens of thousands, we recommend +that you create them and their credentials through the Admin API to reduce etcd +load. + +## Migrating between deployment types + +Because etcd is the source of truth for Kong's configuration, the ingress +controller can re-create Kong's proxy configuration even if the underlying +datastore changes. + +While most Kubernetes resources can be left unchanged when migrating between +deployment types, users must remove any KongPlugin resources that use +unavailable plugins when migrating from a database-backed deployment to a +DB-less deployment. No changes to Kubernetes resources are required if +migrating in the opposite direction. + +[enterprise-download]: https://hub.docker.com/r/kong/kong-gateway/ +[admission-webhook]: /kubernetes-ingress-controller/latest/deployment/admission-webhook +[route-validation]: /gateway/{{page.kong_version}}/reference/configuration/#route_validation_strategy +[supported-plugins]:/kubernetes-ingress-controller/latest/references/plugin-compatibility +[k4k8s-enterprise-install]: /gateway/{{page.kong_version}}/install/kubernetes/helm-quickstart +[k4k8s-with-enterprise-install]: /gateway/{{page.kong_version}}/install/kubernetes/helm-quickstart +[vitals-prometheus]: /gateway/{{page.kong_version}}/kong-enterprise/analytics/prometheus-strategy +[vitals-influxdb]: /gateway/{{page.kong_version}}/kong-enterprise/analytics/influx-strategy +[support]: https://support.konghq.com/ diff --git a/src/gateway/install/kubernetes/helm-quickstart.md b/src/gateway/install/kubernetes/helm-quickstart.md new file mode 100644 index 000000000000..bf2f3e7f295c --- /dev/null +++ b/src/gateway/install/kubernetes/helm-quickstart.md @@ -0,0 +1,439 @@ +--- +title: Install with Kong Gateway using Helm +toc: true +content-type: how-to +--- + + +This guide will show you how to install {{site.base_gateway}} on Kubernetes with Helm. Two options are provided for deploying a local development environment using [Docker Desktop Kubernetes](https://docs.docker.com/desktop/kubernetes/) and [Kind Kubernetes](https://kind.sigs.k8s.io/). You can also follow this guide using an existing cloud hosted Kubernetes cluster. + + +{% navtabs %} +{% navtab Docker Desktop Kubernetes %} +## Docker Desktop + +Docker Desktop Kubernetes is a tool for running a local Kubernetes cluster using Docker. These instructions will guide you through deploying {{site.base_gateway}} to a local Docker Desktop Kubernetes cluster. + +## Dependencies + +- [`Helm 3`](https://helm.sh/) +- [`kubectl`](https://kubernetes.io/docs/tasks/tools/) v1.19 or later +- [Docker Desktop Kubernetes](https://docs.docker.com/desktop/kubernetes/) + +{:.note} +> [Kong Admin API](/gateway/{{page.kong_version}}/admin-api) & [Kong Manager](/gateway/{{page.kong_version}}/kong-manager) services will be published to `localhost` at the domain name `kong.127-0-0-1.nip.io`. The [nip.io](https://nip.io) service is used to automatically resolve this domain to the localhost address. + +## Configure Kubectl + +Set your kubeconfig context and verify with the following command: + + kubectl config use-context docker-desktop && kubectl cluster-info + + +{% endnavtab %} +{% navtab Kind Kubernetes %} + +## Kind Kubernetes + +Kind or "Kubernetes-in-Docker", is a tool for running local Kubernetes clusters in Docker containers. These instructions will guide you through deploying {{site.base_gateway}} to a local Kind Kubernetes cluster. + + +## Dependencies + +- [`Helm 3`](https://helm.sh/) +- [`kubectl`](https://kubernetes.io/docs/tasks/tools/) v1.19 or later +- [KinD](https://kind.sigs.k8s.io/) + +{:.note} +> [Kong Admin API](/gateway/{{page.kong_version}}/admin-api) & [Kong Manager](/gateway/{{page.kong_version}}/kong-manager) services will be published to `localhost` at the domain name `kong.127-0-0-1.nip.io`. The [nip.io](https://nip.io) service is used to automatically resolve this domain to the localhost address. + +## Create Kubernetes Cluster + +A Kind config file is required to build a local cluster listening locally on ports `80` and `443`. Starting from the `bash` command, and ending with the `EOF"` line, highlight and copy this text block, then paste it into your terminal. + + bash -c "cat < /tmp/kind-config.yaml && kind create cluster --config /tmp/kind-config.yaml + apiVersion: kind.x-k8s.io/v1alpha4 + kind: Cluster + name: kong + networking: + apiServerAddress: "0.0.0.0" + apiServerPort: 16443 + nodes: + - role: control-plane + extraPortMappings: + - listenAddress: "0.0.0.0" + protocol: TCP + hostPort: 80 + containerPort: 80 + - listenAddress: "0.0.0.0" + protocol: TCP + hostPort: 443 + containerPort: 443 + EOF" + +Set your kubeconfig context and verify with the following commands. + + kubectl config use-context kind-kong && kubectl cluster-info + +{% endnavtab %} +{% navtab Kubernetes in the Cloud%} + +## Kubernetes in the cloud + +These instructions will guide you through deploying {{site.base_gateway}} to a cloud hosted Kubernetes cluster you have already built. Please ensure your local system and your Kubernetes cluster meet the dependency criteria listed below before continuing. + +{:.note} +> Please note that it is recommended to first try the Docker Desktop or Kind Kubernetes local deploys before proceeding to build on a cloud hosted kubernetes cluster. + +## Dependencies + +- [`Helm 3`](https://helm.sh/) +- [`kubectl`](https://kubernetes.io/docs/tasks/tools/) v1.19 or later +- Domain Name +- DNS configured with your DNS Provider +- Public Cloud hosted Kubernetes cluster +- [Cloud load balancer support](https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/) + +## Configure Kubectl + +Verify your kubeconfig context is set correctly with the following command. + + kubectl cluster-info + +## Prepare the Helm chart + +To inject your custom domain name into the Helm values file configure the {{site.base_gateway}} deployment with: + +1. `curl` the example values.yaml file. + + curl -o ~/quickstart.yaml -L https://bit.ly/KongGatewayHelmValuesAIO + +2. Replace `example.com` with your preferred domain name and export as a variable. + + export BASE_DOMAIN="example.com" + +3. Find & replace the `127-0-0-1.nip.io` base domain in the values file with your preferred domain name. + +{% navtabs %} +{% navtab MacOS%} + + sed -i '' "s/127-0-0-1\.nip\.io/$BASE_DOMAIN/g" ~/quickstart.yaml + +{% endnavtab %} +{% navtab Linux%} + + sed -i "s/127-0-0-1\.nip\.io/$BASE_DOMAIN/g" ~/quickstart.yaml + +{% endnavtab %} +{% endnavtabs %} + +{% endnavtab %} +{% endnavtabs %} + +## Create {{site.base_gateway}} secrets + +Configuring {{site.base_gateway}} requires a namespace and configuration secrets. The secrets contain Kong's enterprise license, admin password, session configurations, and PostgreSQL connection details. + +1. Create the Kong namespace for {{site.base_gateway}}: + + kubectl create namespace kong + +2. Create Kong config and credential variables: + + kubectl create secret generic kong-config-secret -n kong \ + --from-literal=portal_session_conf='{"storage":"kong","secret":"super_secret_salt_string","cookie_name":"portal_session","cookie_samesite":"off","cookie_secure":false}' \ + --from-literal=admin_gui_session_conf='{"storage":"kong","secret":"super_secret_salt_string","cookie_name":"admin_session","cookie_samesite":"off","cookie_secure":false}' \ + --from-literal=pg_host="enterprise-postgresql.kong.svc.cluster.local" \ + --from-literal=kong_admin_password=kong \ + --from-literal=password=kong + +4. Create a Kong Enterprise license secret: + +{% navtabs %} +{% navtab Kong Enterprise Free Mode%} + + kubectl create secret generic kong-enterprise-license --from-literal=license="'{}'" -n kong --dry-run=client -o yaml | kubectl apply -f - + +{% endnavtab %} +{% navtab Kong Enterprise Licensed Mode%} + + >This command must be run in the directory that contains your `license.json` file. + + kubectl create secret generic kong-enterprise-license --from-file=license=license.json -n kong --dry-run=client -o yaml | kubectl apply -f - + +{% endnavtab %} +{% endnavtabs %} + +{:.note} +> Kong can run in two license modes, Enterprise Licensed, or Enterprise Free. If you would like to run all enterprise features, please contact your account manager to request a `license.json` file. + +## Install Cert Manager + +[Cert Manager](https://cert-manager.io/docs/) provides automation for generating SSL certificates. {{site.base_gateway}} uses Cert Manager to provide the required certificates. + + + +Install Cert Manager and create a basic [SelfSigned](https://cert-manager.io/docs/configuration/selfsigned/) certificate issuer: + +1. Add the Jetstack Cert Manager Helm repository: + + helm repo add jetstack https://charts.jetstack.io ; helm repo update + +2. Install Cert Manager: + + helm upgrade --install cert-manager jetstack/cert-manager \ + --set installCRDs=true --namespace cert-manager --create-namespace + +3. Create a SelfSigned certificate issuer: + + bash -c "cat < You will receive a "Your Connection is not Private" warning message due to using selfsigned certs. If you are using Chrome there may not be an "Accept risk and continue" option, to continue type `thisisunsafe` while the tab is in focus to continue. + +5. If running {{site.base_gateway}} in Licensed Mode, use the Super Admin username with the password set in the secret `kong-config-secret` created earlier: `kong_admin`:`kong` + +{% endnavtab %} +{% navtab Kind Kubernetes %} + +Once all dependencies are installed and ready, deploy {{site.base_gateway}} to your cluster: + +1. Add the Kong Helm repo: + + helm repo add kong https://charts.konghq.com ; helm repo update + +2. Install Kong: + + helm install quickstart kong/kong --namespace kong --values https://bit.ly/KongGatewayHelmValuesAIO + +3. Wait for all pods to be in the `Running` and `Completed` states: + + kubectl get po --namespace kong -w + +4. Once all the pods are running, open Kong Manager in your browser at its ingress host domain, for example: [https://kong.127-0-0-1.nip.io](https://kong.127-0-0-1.nip.io). Or open it with the following command: + + open "https://$(kubectl get ingress --namespace kong quickstart-kong-manager -o jsonpath='{.spec.tls[0].hosts[0]}')" + + {:.important} + > You will receive a "Your Connection is not Private" warning message due to using selfsigned certs. If you are using Chrome there may not be an "Accept risk and continue" option, to continue type `thisisunsafe` while the tab is in focus to continue. + +5. If running {{site.base_gateway}} in Licensed Mode, use the Super Admin username with the password set in the secret `kong-config-secret` created earlier: `kong_admin`:`kong` + +{% endnavtab %} +{% navtab Kubernetes in the Cloud%} + +Once all dependencies are installed and ready, deploy {{site.base_gateway}} to your cluster: + +1. Add the Kong Helm repo: + + helm repo add kong https://charts.konghq.com ; helm repo update + +2. Install Kong: + + helm install quickstart kong/kong --namespace kong --values ~/quickstart.yaml + +3. Wait for all pods to be in the `Running` and `Completed` states: + + kubectl get po --namespace kong -w + +4. Once all pods are running, find the cloud load balancer of your {{site.base_gateway}} data plane: + + kubectl get svc --namespace kong quickstart-kong-proxy -w + +5. Using your DNS Provider, configure a DNS entry to point to the load balancer shown by the last step. A wildcard DNS record is recommended for development environments. + +6. Open Kong Manager with the kong subdomain on your domain. For example: `https://kong.example.com`, or open it with the following command: + + open "https://$(kubectl get ingress --namespace kong quickstart-kong-manager -o jsonpath='{.spec.tls[0].hosts[0]}')" + + {:.important} + > You will receive a "Your Connection is not Private" warning message due to using selfsigned certs. If you are using Chrome there may not be an "Accept risk and continue" option, to continue type `thisisunsafe` while the tab is in focus to continue. + +7. If running {{site.base_gateway}} in Licensed Mode, use the Super Admin username with the password set in the secret `kong-config-secret` created earlier: `kong_admin`:`kong` + +{% endnavtab %} +{% endnavtabs %} + +## Use {{site.base_gateway}} + +{{site.base_gateway}} is now serving the [Kong Manager](/gateway/{{page.kong_version}}/kong-manager) Web UI and the [Kong Admin API](/gateway/{{page.kong_version}}/admin-api). + +For local deployments, Kong Manager is locally accessible at `https://kong.127-0-0-1.nip.io`. The [nip.io](https://nip.io) service resolves this domain to localhost also known as `127.0.0.1`. + +You can configure Kong via the Admin API with [decK](https://docs.konghq.com/deck/latest/), [Insomnia](https://docs.insomnia.rest/insomnia/get-started), HTTPie, or cURL, at `https://kong.127-0-0-1.nip.io/api`: + +{% navtabs codeblock %} +{% navtab cURL %} + + curl --silent --insecure -X GET https://kong.127-0-0-1.nip.io/api -H 'kong-admin-token:kong' + +{% endnavtab %} +{% navtab HTTPie %} + + http --verify=no get https://kong.127-0-0-1.nip.io/api kong-admin-token:kong + +{% endnavtab %} +{% endnavtabs %} + +## Teardown + +{% navtabs %} +{% navtab Docker Desktop Kubernetes %} + +To remove {{site.base_gateway}} from your system, follow these instructions: + +1. Remove Kong + + helm uninstall --namespace kong quickstart + +2. Delete Kong secrets + + kubectl delete secrets -nkong kong-enterprise-license + kubectl delete secrets -nkong kong-config-secret + +3. Remove Kong database [PVC](https://kubernetes.io/docs/concepts/storage/persistent-volumes/) + + kubectl delete pvc -n kong data-quickstart-postgresql-0 + +4. Remove Kong Helm chart repository + + helm repo remove kong + +5. Remove cert-manager + + helm uninstall --namespace cert-manager cert-manager + +6. Remove jetstack cert-manager Helm repository + + helm repo remove jetstack + +{% endnavtab %} +{% navtab Kind Kubernetes %} + +To remove {{site.base_gateway}} from your system, follow these instructions: + +1. Remove Kong + + helm uninstall --namespace kong quickstart + +2. Delete Kong secrets + + kubectl delete secrets -nkong kong-enterprise-license + kubectl delete secrets -nkong kong-config-secret + +3. Remove Kong database [PVC](https://kubernetes.io/docs/concepts/storage/persistent-volumes/) + + kubectl delete pvc -n kong data-quickstart-postgresql-0 + +4. Remove Kong Helm chart repository + + helm repo remove kong + +5. Remove cert-manager + + helm uninstall --namespace cert-manager cert-manager + +6. Remove jetstack cert-manager Helm repository + + helm repo remove jetstack + +7. Destroy the Kind cluster + + kind delete cluster --name=kong + rm /tmp/kind-config.yaml + +{% endnavtab %} +{% navtab Kubernetes in the Cloud%} + +To remove {{site.base_gateway}} from your system, follow these instructions: + +1. Remove Kong + + helm uninstall --namespace kong quickstart + +2. Delete Kong secrets + + kubectl delete secrets -nkong kong-enterprise-license + kubectl delete secrets -nkong kong-config-secret + +3. Remove Kong database [PVC](https://kubernetes.io/docs/concepts/storage/persistent-volumes/) + + kubectl delete pvc -n kong data-quickstart-postgresql-0 + +4. Remove Kong Helm chart repository + + helm repo remove kong + +5. Remove cert-manager + + helm uninstall --namespace cert-manager cert-manager + +6. Remove jetstack cert-manager Helm Repository + + helm repo remove jetstack + +{% endnavtab %} +{% endnavtabs %} + +## Next Steps + +See the [Kong Ingress Controller docs](/kubernetes-ingress-controller/) for how-to guides, reference guides, and more. diff --git a/src/gateway/install/kubernetes/helm.md b/src/gateway/install/kubernetes/helm.md new file mode 100644 index 000000000000..20cdb8cc47a2 --- /dev/null +++ b/src/gateway/install/kubernetes/helm.md @@ -0,0 +1,197 @@ +--- +title: Install on Kubernetes with Helm +--- + +This page explains how to install {{site.base_gateway}} with {{site.kic_product_name}} using Helm. + +* The Enterprise deployment includes a Postgres sub-chart provided by Bitnami. +* For open-source deployments, you can choose to use the Postgres sub-chart, or install without a database. + +Configuration for both options is flexible and depends on your environment. + +The documentation on installing with a [flat Kubernetes manifest](/gateway/{{page.kong_version}}/install/kubernetes/helm-quickstart) also explains how to install in DB-less mode for both Enterprise and OSS deployments. + +The {{site.base_gateway}} software is governed by the +[Kong Software License Agreement](https://konghq.com/kongsoftwarelicense). +{{site.ce_product_name}} is licensed under an +[Apache 2.0 license](https://github.com/Kong/kong/blob/master/LICENSE). + +## Prerequisites + +- A Kubernetes cluster, v1.19 or later +- `kubectl` v1.19 or later +- (Enterprise only) A `license.json` file from Kong +- Helm 3 + +## Create namespace + +Create the namespace for {{site.base_gateway}} with {{site.kic_product_name}}. For example: + +```sh +kubectl create namespace kong +``` + +## Set up Helm + +1. Add the Kong charts repository: + + ```sh + helm repo add kong https://charts.konghq.com + ``` + +1. Update Helm: + + ```sh + helm repo update + ``` + +## Create license secret +{:.badge .enterprise} + +1. Save your license file temporarily with the filename `license` (no file extension). + +1. Run: + + ```sh + kubectl create secret generic kong-enterprise-license --from-file=./license -n kong + ``` + +## Create secret for RBAC superuser (recommended) +{:.badge .enterprise} + +If you plan to use RBAC, you must create a secret for the superuser account password at this step in installation. You cannot create it later. + +1. Create the RBAC account. + +1. Create the secret: + + ```sh + kubectl create secret generic kong-enterprise-superuser-password \ + -n kong \ + --from-literal=password={YOUR_PASSWORD} + ``` + +## Create secret for Session plugin +{:.badge .enterprise} + +If you create an RBAC superuser and plan to work with Kong Manager or Dev Portal, you must also configure the Session plugin and store its config in a Kubernetes secret: + +1. Create a session config file for Kong Manager: + + ```bash + echo '{"cookie_name":"admin_session","cookie_samesite":"off","secret":"","cookie_secure":false,"storage":"kong"}' > admin_gui_session_conf + ``` + +1. Create a session config file for Kong Dev Portal: + + ```bash + echo '{"cookie_name":"portal_session","cookie_samesite":"off","secret":"","cookie_secure":false,"storage":"kong"}' > portal_session_conf + ``` + + Or, if you have different subdomains for the `portal_api_url` and `portal_gui_host`, set the `cookie_domain` + and `cookie_samesite` properties as follows: + + ``` + echo '{"cookie_name":"portal_session","cookie_samesite":"off","cookie_domain":"<.your_subdomain.com">,"secret":"","cookie_secure":false,"storage":"kong"}' > portal_session_conf + ``` + +1. Create the secret: + + For Kong Manager only: + + ```sh + kubectl create secret generic kong-session-config \ + -n kong \ + --from-file=admin_gui_session_conf + ``` + + For Kong Manager and Dev Portal: + + ```sh + kubectl create secret generic kong-session-config \ + -n kong \ + --from-file=admin_gui_session_conf \ + --from-file=portal_session_conf + ``` + +## Create values.yaml file + +Create a `values.yaml` file to provide required values such as password secrets or optional email addresses for notifications. You can work from the [Enterprise example file](https://github.com/Kong/charts/blob/main/charts/kong/example-values/full-k4k8s-with-kong-enterprise.yaml). The example file includes comments to explain which values you must set. + +For OSS deployments, the default install might be sufficient, but you can explore other `values.yaml` files and [the readme in the charts repository](https://github.com/Kong/charts/blob/main/charts/kong/README.md), which includes an exhaustive list of all possible configuration properties. + +Note that the Enterprise deployment includes a Postgres sub-chart provided by Bitnami. You might need to delete the PersistentVolume objects for Postgres in your Kubernetes cluster to connect to the database after install. + +## Deploy {{site.base_gateway}} with {{site.kic_product_name}} + +1. Run: + + ```sh + ## Kong Gateway + helm install my-kong kong/kong -n kong --values ./values.yaml + ``` + + ```sh + ## Kong Gateway (OSS) + helm install kong/kong --generate-name --set ingressController.installCRDs=false + ``` + + For more information on working with Helm charts for {{site.ce_product_name}}, see the [chart documentation](https://github.com/Kong/charts/blob/main/charts/kong/README.md). + + This might take some time. + +1. Check pod status, and make sure the `my-kong-kong-{ID}` pod is running: + + ```bash + kubectl get pods -n kong + ``` + +## Finalize configuration and verify installation +{:.badge .enterprise} + +1. Run: + + ```sh + kubectl get svc my-kong-kong-admin \ + -n kong \ + --output=jsonpath='{.status.loadBalancer.ingress[0].ip}' + ``` + +1. Copy the IP address from the output, then add the following to the `.env` section of your `values.yaml` file: + + ```yaml + admin_api_uri: {YOUR-DNS-OR-IP} + ``` + + {:.note} + > **Note:** If you configure RBAC, you must specify a DNS hostname instead of an IP address. + +1. Clean up: + + ```sh + kubectl delete jobs -n kong --all + ``` + +1. Update with changed `values.yaml`: + + ``` + helm upgrade my-kong kong/kong -n kong --values ./values.yaml + ``` + +1. After the upgrade finishes, run: + + ``` + kubectl get svc -n kong + ``` + + With an Enterprise deployment, the output includes `EXTERNAL-IP` values for Kong Manager and Dev Portal. For example: + + ```sh + NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE + my-kong-kong-manager LoadBalancer 10.96.61.116 10.96.61.116 8002:31308/TCP,8445:32420/TCP 24m + my-kong-kong-portal LoadBalancer 10.101.251.123 10.101.251.123 8003:31609/TCP,8446:32002/TCP 24m + ``` + +## Next steps + +See the [Kong Ingress Controller docs](/kubernetes-ingress-controller/) for how-to guides, reference guides, and more. diff --git a/src/gateway/install/kubernetes/kubectl.md b/src/gateway/install/kubernetes/kubectl.md new file mode 100644 index 000000000000..411d0e0adeb5 --- /dev/null +++ b/src/gateway/install/kubernetes/kubectl.md @@ -0,0 +1,126 @@ +--- +title: Install on Kubernetes +--- + +This page explains how to install {{site.base_gateway}} with {{site.kic_product_name}} in DB-less mode. To install with a database, see the documentation on installing with [Helm](/gateway/{{page.kong_version}}/install/kubernetes/helm-quickstart). + +This page also includes the equivalent commands for OpenShift. + +In DB-less mode on Kubernetes, the config is stored in etcd, the Kubernetes native data store. For more information, see [Kubernetes Deployment Options](/gateway/{{page.kong_version}}/install/kubernetes/deployment-options). + +The {{site.base_gateway}} software is governed by the +[Kong Software License Agreement](https://konghq.com/kongsoftwarelicense). +{{site.ce_product_name}} is licensed under an +[Apache 2.0 license](https://github.com/Kong/kong/blob/master/LICENSE). + +## Prerequisites + +- A Kubernetes cluster, v1.19 or later +- `kubectl` v1.19 or later +- (Enterprise only) A `license.json` file from Kong + +## Create namespace + +Create the namespace for {{site.base_gateway}} with {{site.kic_product_name}}. For example: + +```sh +## on Kubernetes native +kubectl create namespace kong +``` + +```sh +## on OpenShift +oc new-project kong +``` + +## Create license secret +{:.badge .enterprise} + +1. Save your license file temporarily with the filename `license` (no file extension). + +1. Run: + + ```sh + ## on Kubernetes native + kubectl create secret generic kong-enterprise-license --from-file=/license -n kong + ``` + + ```sh + ## on OpenShift + oc create secret generic kong-enterprise-license --from-file=./license -n kong + ``` + +## Deploy + +1. Run one of the following: + + ```sh + ## Kong Gateway on Kubernetes native + kubectl apply -f https://bit.ly/k4k8s-enterprise-install + ``` + + ```sh + ## Kong Gateway on OpenShift + oc create -f https://bit.ly/k4k8s-enterprise-install + ``` + + ```sh + ## Kong Gateway (OSS) on Kubernetes native + kubectl apply -f https://bit.ly/kong-ingress-dbless + ``` + + This might take a few minutes. + +1. Check the install status: + + ```sh + kubectl get pods -n kong + ``` + + or: + + ```sh + oc get pods -n kong + ``` + +1. To make HTTP requests, you need the IP address of the load balancer. Get the `loadBalancer` address and store it in a local `PROXY_IP` environment variable: + + {:.note} + > **Note:** Some cluster providers only provide a DNS name for load balancers. In this case, specify `.hostname` instead of `.ip`. + + ```sh + export PROXY_IP=$(kubectl get -o jsonpath="{.status.loadBalancer.ingress[0].ip}" service -n kong kong-proxy) + ``` + +1. Verify that the value of `$PROXY_IP` matches the value of the external host: + + ```sh + echo $PROXY_IP + ``` + + This should match the `EXTERNAL_IP` value of the `kong-proxy` service returned by the Kubernetes API: + + ```sh + kubectl get service kong-proxy -n kong + ``` + + or: + + ```sh + oc get service kong-proxy -n kong + ``` + +1. Invoke a test request: + ```sh + curl $PROXY_IP + ``` + + This should return the following response from Gateway: + + ```sh + {"message":"no Route matched with those values"} + ``` + +## Next steps + +See the [Kong Ingress Controller docs](/kubernetes-ingress-controller/) for how-to guides, reference guides, and more. diff --git a/src/gateway/install/kubernetes/openshift.md b/src/gateway/install/kubernetes/openshift.md new file mode 100644 index 000000000000..3dc35bcfcde9 --- /dev/null +++ b/src/gateway/install/kubernetes/openshift.md @@ -0,0 +1,179 @@ +--- +title: Install on OpenShift with Helm +badge: enterprise +--- + +This page explains how to install {{site.base_gateway}} with {{site.kic_product_name}} with a database. To install in DB-less mode, see the documentation on installing with a [flat Kubernetes manifest](/gateway/{{page.kong_version}}/install/kubernetes/helm-quickstart). + +The {{site.base_gateway}} software is governed by the +[Kong Software License Agreement](https://konghq.com/kongsoftwarelicense). +{{site.ce_product_name}} is licensed under an +[Apache 2.0 license](https://github.com/Kong/kong/blob/master/LICENSE). + + +## Prerequisites + +- A Kubernetes cluster, v1.19 or later +- `kubectl` v1.19 or later +- (Enterprise only) A `license.json` file from Kong +- Helm 3 + +## Create namespace + +Create the namespace for {{site.base_gateway}} with {{site.kic_product_name}}. For example: + +```sh +oc new-project kong +``` + +## Create license secret + +1. Save your license file temporarily with the filename `license` (no file extension). + +1. Run: + + ```sh + oc create secret generic kong-enterprise-license -n kong --from-file=./license + ``` + +## Set up Helm + +1. Add the Kong charts repository: + + ```sh + helm repo add kong https://charts.konghq.com + ``` + +1. Update Helm: + + ```sh + helm repo update + ``` + +## Create secret for RBAC superuser (recommended) +{:.badge .enterprise} + +If you plan to use RBAC, you must create the superuser account at this step in installation. You cannot create it later. + +1. Create the RBAC account. + +1. Create the secret: + + ```sh + oc create secret generic kong-enterprise-superuser-password \ + -n kong \ + --from-literal=password={your-password} + ``` + +## Create secret for Session plugin + +If you create an RBAC superuser and plan to work with Kong Manager or Dev Portal, you must also configure the Session plugin and store its config in a Kubernetes secret: + +1. Create a session config file for Kong Manager: + + ```bash + echo '{"cookie_name":"admin_session","cookie_samesite":"off","secret":"","cookie_secure":false,"storage":"kong"}' > admin_gui_session_conf + ``` + +1. Create a session config file for Kong Dev Portal: + + ```bash + echo '{"cookie_name":"portal_session","cookie_samesite":"off","secret":"","cookie_secure":false,"storage":"kong"}' > portal_session_conf + ``` + + Or, if you have different subdomains for the `portal_api_url` and `portal_gui_host`, set the `cookie_domain` + and `cookie_samesite` properties as follows: + + ``` + echo '{"cookie_name":"portal_session","cookie_samesite":"off","cookie_domain":"<.your_subdomain.com">,"secret":"","cookie_secure":false,"storage":"kong"}' > portal_session_conf + ``` + +1. Create the secret: + + For Kong Manager only: + + ```sh + oc create secret generic kong-session-config \ + -n kong \ + --from-file=admin_gui_session_conf + ``` + + For Kong Manager and Dev Portal: + + ```sh + oc create secret generic kong-session-config \ + -n kong \ + --from-file=admin_gui_session_conf \ + --from-file=portal_session_conf + ``` + +## Create values.yaml file + +Create a `values.yaml` file to provide required values such as password secrets or optional email addresses for notifications. Work from the [Enterprise example file](https://github.com/Kong/charts/blob/main/charts/kong/example-values/full-k4k8s-with-kong-enterprise.yaml). The example file includes comments to explain which values you must set. The [readme in the charts repository](https://github.com/Kong/charts/blob/main/charts/kong/README.md) includes an exhaustive list of all possible configuration properties. + +Note that this deployment includes a Postgres sub-chart provided by Bitnami. You might need to delete the PersistentVolume objects for Postgres in your Kubernetes cluster to connect to the database after install. + +## Deploy {{site.base_gateway}} with {{site.kic_product_name}} + +1. Run: + + ```sh + helm install my-kong kong/kong -n kong --values ./values.yaml + ``` + + This might take some time. + +1. Check pod status, and make sure the `my-kong-kong-` pod is running: + + ```bash + oc get pods -n kong + ``` + +## Finalize configuration and verify installation + +1. Run: + + ```sh + oc get svc my-kong-kong-admin \ + -n kong \ + --output=jsonpath='{.status.loadBalancer.ingress[0].ip}' + ``` + +1. Copy the IP address from the output, then add the following to the `.env` section of your `values.yaml` file: + + ```yaml + admin_api_uri: + ``` + + {:.note} + > **Note:** If you configure RBAC, you must specify a DNS hostname instead of an IP address. + +1. Clean up: + + ```sh + oc delete jobs -n kong --all + ``` + +1. Update with changed `values.yaml`: + + ``` + helm upgrade my-kong kong/kong -n kong --values ./values.yaml + ``` + +1. After the upgrade finishes, run: + + ``` + oc get svc -n kong + ``` + + The output includes `EXTERNAL-IP` values for Kong Manager and Dev Portal. For example: + + ```sh + NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE + my-kong-kong-manager LoadBalancer 10.96.61.116 10.96.61.116 8002:31308/TCP,8445:32420/TCP 24m + my-kong-kong-portal LoadBalancer 10.101.251.123 10.101.251.123 8003:31609/TCP,8446:32002/TCP 24m + ``` + +## Next steps + +See the [Kong Ingress Controller docs](/kubernetes-ingress-controller/) for how-to guides, reference guides, and more. diff --git a/src/gateway/install/linux/amazon-linux.md b/src/gateway/install/linux/amazon-linux.md new file mode 100644 index 000000000000..2024ade3b05f --- /dev/null +++ b/src/gateway/install/linux/amazon-linux.md @@ -0,0 +1,94 @@ +--- +title: Install Kong Gateway on Amazon Linux +--- + +The {{site.base_gateway}} software is governed by the +[Kong Software License Agreement](https://konghq.com/kongsoftwarelicense). +Kong is licensed under an +[Apache 2.0 license](https://github.com/Kong/kong/blob/master/LICENSE). + +## Prerequisites + +* A [supported system](/gateway/{{page.kong_version}}/install/linux/os-support) with root or [root-equivalent](/gateway/{{page.kong_version}}/production/running-kong/kong-user) access. +* (Enterprise only) A `license.json` file from Kong. + +## Download and Install + +You can install {{site.base_gateway}} by downloading an installation package or using our yum repository. + +{% navtabs %} +{% navtab Package %} + +Install {{site.base_gateway}} on Amazon Linux from the command line. + +1. Download the Kong package: + +{% capture download_package %} +{% navtabs_ee codeblock %} +{% navtab Kong Gateway %} +```bash +curl -Lo kong-enterprise-edition-{{page.kong_versions[page.version-index].ee-version}}.amzn2.amd64.rpm "{{ site.links.download }}/gateway-3.x-amazonlinux-2/Packages/k/kong-enterprise-edition-{{page.kong_versions[page.version-index].ee-version}}.amzn2.amd64.rpm" +``` +{% endnavtab %} +{% navtab Kong Gateway (OSS) %} +```bash +curl -Lo kong-{{page.kong_versions[page.version-index].ce-version}}.aws.amd64.rpm "{{ site.links.download }}/gateway-3.x-amazonlinux-2/Packages/k/kong-{{page.kong_versions[page.version-index].ce-version}}.aws.amd64.rpm" +``` +{% endnavtab %} +{% endnavtabs_ee %} +{% endcapture %} + +{{ download_package | indent | replace: " ", "" }} + +2. Install the package: + +{% capture install_package %} +{% navtabs_ee codeblock %} +{% navtab Kong Gateway %} +```bash +sudo yum install kong-enterprise-edition-{{page.kong_versions[page.version-index].ee-version}}.amzn2.amd64.rpm +``` +{% endnavtab %} +{% navtab Kong Gateway (OSS) %} +```bash +sudo yum install kong-{{page.kong_versions[page.version-index].ce-version}}.aws.amd64.rpm +``` +{% endnavtab %} +{% endnavtabs_ee %} +{% endcapture %} + +{{ install_package | indent | replace: " ", "" }} + +{% endnavtab %} +{% navtab YUM repository %} + +Install the YUM repository from the command line. + +1. Download the Kong APT repository: + ```bash + curl https://download.konghq.com/gateway-3.x-amazonlinux-2/config.repo | sudo tee /etc/yum.repos.d/kong.repo + ``` + +2. Install Kong: + +{% capture install_from_repo %} +{% navtabs_ee codeblock %} +{% navtab Kong Gateway %} +```bash +sudo yum install kong-enterprise-edition-{{page.kong_versions[page.version-index].ee-version}} +``` +{% endnavtab %} +{% navtab Kong Gateway (OSS) %} +```bash +sudo yum install kong-{{page.kong_versions[page.version-index].ce-version}} +``` +{% endnavtab %} +{% endnavtabs_ee %} +{% endcapture %} + +{{ install_from_repo | indent | replace: " ", "" }} + +{% endnavtab %} +{% endnavtabs %} + +{% include_cached /md/gateway/setup.md kong_version=page.kong_version %} diff --git a/src/gateway/install/linux/centos.md b/src/gateway/install/linux/centos.md new file mode 100644 index 000000000000..26b54bad388c --- /dev/null +++ b/src/gateway/install/linux/centos.md @@ -0,0 +1,75 @@ +--- +title: Install Kong Gateway on CentOS +--- + +{:.important} +> **Deprecation notice**: Support for running open-source Kong Gateway on +CentOS is now deprecated, as [CentOS has reached End of Life (EOL)](https://www.centos.org/centos-linux-eol/). +Starting with Kong Gateway 2.8.0.0, Kong is not building new open-source CentOS images. +> If you need to install Kong Gateway (OSS) on CentOS, see the documentation for +[previous versions](/gateway/2.7.x/install/centos/). +>

      +> Kong Gateway Enterprise subscriptions can still use CentOS in 2.8, but support +for CentOS is planned to be removed in 3.0. + + +The {{site.base_gateway}} software is governed by the +[Kong Software License Agreement](https://konghq.com/kongsoftwarelicense). +Kong is licensed under an +[Apache 2.0 license](https://github.com/Kong/kong/blob/master/LICENSE). + +## Prerequisites + +* A [supported system](/gateway/{{page.kong_version}}/install/linux/os-support) with root or [root-equivalent](/gateway/{{page.kong_version}}/production/running-kong/kong-user) access. +* (Enterprise only) A `license.json` file from Kong. + +## Download and Install + +You can install {{site.base_gateway}} by downloading an installation package or +using our YUM repository. + +{% navtabs %} +{% navtab Package %} + +Install {{site.base_gateway}} on CentOS from the command line. + +1. Download the Kong package: + + ```bash + curl -Lo kong-enterprise-edition-{{page.kong_versions[page.version-index].ee-version}}.rpm $(rpm --eval "{{ site.links.download }}/gateway-3.x-centos-%{centos_ver}/Packages/k/kong-enterprise-edition-{{page.kong_versions[page.version-index].ee-version}}.el%{centos_ver}.amd64.rpm") + ``` + +2. Install the package: + + ```bash + sudo yum install kong-enterprise-edition-{{page.kong_versions[page.version-index].ee-version}}.rpm + ``` + +{% endnavtab %} +{% navtab YUM repository %} + +Install the YUM repository from the command line. + +1. Download the Kong APT repository: + ```bash + curl $(rpm --eval "{{ site.links.download }}/gateway-3.x-centos-%{centos_ver}/config.repo") | sudo tee /etc/yum.repos.d/kong.repo + ``` + +2. Install Kong: + + ```bash + sudo yum install kong-enterprise-edition-{{page.kong_versions[page.version-index].ee-version}} + ``` + +{% endnavtab %} +{% endnavtabs %} + + + +{% include_cached /md/gateway/setup.md kong_version=page.kong_version %} diff --git a/src/gateway/install/linux/debian.md b/src/gateway/install/linux/debian.md new file mode 100644 index 000000000000..4140efe19e2d --- /dev/null +++ b/src/gateway/install/linux/debian.md @@ -0,0 +1,113 @@ +--- +title: Install Kong Gateway on Debian +--- + +The {{site.base_gateway}} software is governed by the +[Kong Software License Agreement](https://konghq.com/kongsoftwarelicense). +{{site.ce_product_name}} is licensed under an +[Apache 2.0 license](https://github.com/Kong/kong/blob/master/LICENSE). + +## Prerequisites + +* A [supported system](/gateway/{{page.kong_version}}/install/linux/os-support) with root or [root-equivalent](/gateway/{{page.kong_version}}/production/running-kong/kong-user) access. +* The following tools are installed: + * [`curl`](https://curl.se/) + * [`lsb-release`](https://packages.debian.org/lsb-release) + * [`apt-transport-https`](https://packages.debian.org/apt-transport-https) (Only if installing the APT repository) +* (Enterprise only) A `license.json` file from Kong. + +## Download and install + +You can install {{site.base_gateway}} by downloading an installation package or using our APT repository. + +{% navtabs %} +{% navtab Package %} + +Install {{site.base_gateway}} on Debian from the command line. + +1. Download the Kong package: + +{% capture download_package %} +{% navtabs_ee codeblock %} +{% navtab Kong Gateway %} +```bash +curl -Lo kong-enterprise-edition-{{page.kong_versions[page.version-index].ee-version}}.all.deb "{{ site.links.download }}/gateway-3.x-debian-$(lsb_release -cs)/pool/all/k/kong-enterprise-edition/kong-enterprise-edition_{{page.kong_versions[page.version-index].ee-version}}_amd64.deb" +``` +{% endnavtab %} +{% navtab Kong Gateway (OSS) %} +```bash +curl -Lo kong-{{page.kong_versions[page.version-index].ce-version}}.amd64.deb "{{ site.links.download }}/gateway-3.x-debian-$(lsb_release -cs)/pool/all/k/kong/kong_{{page.kong_versions[page.version-index].ce-version}}_amd64.deb" +``` +{% endnavtab %} +{% endnavtabs_ee %} +{% endcapture %} + +{{ download_package | indent | replace: " ", "" }} + +2. Install the package: + +{% capture install_package %} +{% navtabs_ee codeblock %} +{% navtab Kong Gateway %} +```bash +sudo dpkg -i kong-enterprise-edition-{{page.kong_versions[page.version-index].ee-version}}.all.deb +``` +{% endnavtab %} +{% navtab Kong Gateway (OSS) %} +```bash +sudo dpkg -i kong-{{page.kong_versions[page.version-index].ce-version}}.amd64.deb +``` +{% endnavtab %} +{% endnavtabs_ee %} +{% endcapture %} + +{{ install_package | indent | replace: " ", "" }} + +{% navtabs_ee %} +{% navtab Kong Gateway %} +{:.note .no-icon} +> Once {{ site.base_gateway }} is installed, you may want to run `sudo apt-mark hold kong-enterprise-edition`. This will prevent an accidental upgrade to a new version. +{% endnavtab %} +{% navtab Kong Gateway (OSS) %} +{:.note .no-icon} +> Once {{ site.base_gateway }} is installed, you may want to run `sudo apt-mark hold kong`. This will prevent an accidental upgrade to a new version. +{% endnavtab %} +{% endnavtabs_ee %} + +{% endnavtab %} +{% navtab APT repository %} + +Install the APT repository from the command line. + +1. Download the Kong APT repository: + ```bash + echo "deb [trusted=yes] {{ site.links.download }}/gateway-3.x-debian-$(lsb_release -sc)/ \ + default all" | sudo tee /etc/apt/sources.list.d/kong.list + ``` +2. Update the repository: + ```bash + sudo apt-get update + ``` +3. Install Kong: + +{% capture install_from_repo %} +{% navtabs_ee codeblock %} +{% navtab Kong Gateway %} +```bash +apt install -y kong-enterprise-edition={{page.kong_versions[page.version-index].ee-version}} +``` +{% endnavtab %} +{% navtab Kong Gateway (OSS) %} +```bash +apt install -y kong={{page.kong_versions[page.version-index].ce-version}} +``` +{% endnavtab %} +{% endnavtabs_ee %} +{% endcapture %} + +{{ install_from_repo | indent | replace: " ", "" }} + +{% endnavtab %} +{% endnavtabs %} + +{% include_cached /md/gateway/setup.md kong_version=page.kong_version %} diff --git a/src/gateway/install/linux/os-support.md b/src/gateway/install/linux/os-support.md new file mode 100644 index 000000000000..7a084edf90ff --- /dev/null +++ b/src/gateway/install/linux/os-support.md @@ -0,0 +1,84 @@ +--- +title: Supported Operating Systems +--- + +{% assign os_versions = site.data.tables.os_support %} + +## Supported + +Kong Gateway currently supports the following Linux operating systems: + + + + + + + + + {% for item in os_versions %} + {% if item.status == "active" %} + + + + + + {% endif %} + {% endfor %} + +
      OS versionFirst Enterprise Gateway versionFirst open-source Gateway version
      + {{ item.name }} + + {% if item.enterprise == true and item.enterprise_versions.first_version != null %} + {{ item.enterprise_versions.first_version }} + {% else %} + Not supported + {% endif %} + + {% if item.oss == true and item.oss_versions.first_version != null %} + {{ item.oss_versions.first_version }} + {% else %} + Not supported + {% endif %} +
      + +## Deprecated + +The following versions have reached end of life (EoL) and are no longer +supported by Kong: + + + + + + + + + + {% for item in os_versions %} + {% if item.status == "deprecated" %} + + + + + + + {% endif %} + {% endfor %} + +
      OS versionEnd of LifeLast Enterprise Gateway versionLast open-source Gateway version
      + {{ item.name }} + + {{ item.deprecation_date }} + + {% if item.enterprise == true %} + {{ item.enterprise_versions.last_version }} + {% else %} + Not applicable + {% endif %} + + {% if item.oss == true %} + {{ item.oss_versions.last_version }} + {% else %} + Not applicable + {% endif %} +
      diff --git a/src/gateway/install/linux/rhel.md b/src/gateway/install/linux/rhel.md new file mode 100644 index 000000000000..be1f6e129722 --- /dev/null +++ b/src/gateway/install/linux/rhel.md @@ -0,0 +1,110 @@ +--- +title: Install Kong Gateway on RHEL +--- + +The {{site.base_gateway}} software is governed by the +[Kong Software License Agreement](https://konghq.com/kongsoftwarelicense). +Kong is licensed under an +[Apache 2.0 license](https://github.com/Kong/kong/blob/master/LICENSE). + +## Prerequisites + +* A supported system with root or [root-equivalent](/gateway/{{page.kong_version}}/production/running-kong/kong-user) access. +* (Enterprise only) A `license.json` file from Kong + +## Download and Install + +You can install {{site.base_gateway}} by downloading an installation package or using our yum repository. + +{% navtabs %} +{% navtab Package %} + +Install {{site.base_gateway}} on RHEL from the command line. + +1. Download the Kong package: + +{% capture download_package %} +{% navtabs_ee codeblock %} +{% navtab Kong Gateway %} +```bash +curl -Lo kong-enterprise-edition-{{page.kong_versions[page.version-index].ee-version}}.rpm $( rpm --eval "{{ site.links.download }}/gateway-3.x-rhel-%{rhel}/Packages/k/kong-enterprise-edition-{{page.kong_versions[page.version-index].ee-version}}.rhel%{rhel}.amd64.rpm") +``` +{% endnavtab %} +{% navtab Kong Gateway (OSS) %} +```bash +curl -Lo kong-{{page.kong_versions[page.version-index].ce-version}}.rpm $(rpm --eval "{{ site.links.download }}/gateway-3.x-rhel-%{rhel}/Packages/k/kong-{{page.kong_versions[page.version-index].ce-version}}.rhel%{rhel}.amd64.rpm") + ``` +{% endnavtab %} +{% endnavtabs_ee %} +{% endcapture %} + +{{ download_package | indent | replace: " ", "" }} + +2. Install the package using `yum` or `rpm`. + + If you use the `rpm` install method, the packages _only_ contain {{site.base_gateway}}. They don't include any dependencies. + +{% capture install_package %} +{% navtabs %} +{% navtab yum %} +{% navtabs_ee codeblock %} +{% navtab Kong Gateway %} +```bash +sudo yum install kong-enterprise-edition-{{page.kong_versions[page.version-index].ee-version}}.rpm +``` +{% endnavtab %} +{% navtab Kong Gateway (OSS) %} +```bash +sudo yum install kong-{{page.kong_versions[page.version-index].ce-version}}.rpm +``` +{% endnavtab %} +{% endnavtabs_ee %} +{% endnavtab %} +{% navtab rpm %} + +{:.important} +> The `rpm` method is only available for open-source packages. For the `kong-enterprise-edition` package, use `yum`. + +```bash +rpm -iv kong-{{page.kong_versions[page.version-index].ce-version}}.rpm +``` +{% endnavtab %} +{% endnavtabs %} +{% endcapture %} + +{{ install_package | indent | replace: " ", "" }} + + Installing directly using `rpm` is suitable for Red Hat's [Universal Base Image](https://developers.redhat.com/blog/2020/03/24/red-hat-universal-base-images-for-docker-users) "minimal" variant. You will need to install Kong's dependencies separately via `microdnf`. + +{% endnavtab %} +{% navtab YUM repository %} + +Install the YUM repository from the command line. + +1. Download the Kong APT repository: + ```bash + curl $(rpm --eval "{{ site.links.download }}/gateway-3.x-rhel-%{rhel}/config.repo") | sudo tee /etc/yum.repos.d/kong.repo + ``` + +2. Install Kong: +{% capture install_from_repo %} +{% navtabs_ee codeblock %} +{% navtab Kong Gateway %} +```bash +sudo yum install kong-enterprise-edition-{{page.kong_versions[page.version-index].ee-version}} +``` +{% endnavtab %} +{% navtab Kong Gateway (OSS) %} +```bash +sudo yum install kong-{{page.kong_versions[page.version-index].ce-version}} +``` +{% endnavtab %} +{% endnavtabs_ee %} +{% endcapture %} + +{{ install_from_repo | indent | replace: " ", "" }} + +{% endnavtab %} +{% endnavtabs %} + +{% include_cached /md/gateway/setup.md kong_version=page.kong_version %} diff --git a/src/gateway/install/linux/ubuntu.md b/src/gateway/install/linux/ubuntu.md new file mode 100644 index 000000000000..7a692e28ade1 --- /dev/null +++ b/src/gateway/install/linux/ubuntu.md @@ -0,0 +1,118 @@ +--- +title: Install Kong Gateway on Ubuntu +--- + +The {{site.base_gateway}} software is governed by the +[Kong Software License Agreement](https://konghq.com/kongsoftwarelicense). +Kong is licensed under an +[Apache 2.0 license](https://github.com/Kong/kong/blob/master/LICENSE). + +## Prerequisites + +* A supported system with root or [root-equivalent](/gateway/{{page.kong_version}}/production/running-kong/kong-user) access. +* (Enterprise only) A `license.json` file from Kong + +## Download and install + +You can install {{site.base_gateway}} by downloading an installation package or using our APT repository. + +{:.note .no-icon} +> We currently package {{ site.base_gateway }} for Ubuntu Bionic and Focal. +> If you are using a different release, replace `$(lsb_release -sc)` with `focal` in the commands below. +>

      +> To check your release name run `lsb_release -sc`. + + +{% navtabs %} +{% navtab Package %} + +Install {{site.base_gateway}} on Ubuntu from the command line. + +1. Download the Kong package: + +{% capture download_package %} +{% navtabs_ee codeblock %} +{% navtab Kong Gateway %} +```bash +curl -Lo kong-enterprise-edition-{{page.kong_versions[page.version-index].ee-version}}.all.deb "{{ site.links.download }}/gateway-3.x-ubuntu-$(lsb_release -sc)/pool/all/k/kong-enterprise-edition/kong-enterprise-edition_{{page.kong_versions[page.version-index].ee-version}}_amd64.deb" +``` +{% endnavtab %} +{% navtab Kong Gateway (OSS) %} +```bash +curl -Lo kong-{{page.kong_versions[page.version-index].ce-version}}.amd64.deb "{{ site.links.download }}/gateway-3.x-ubuntu-$(lsb_release -sc)/pool/all/k/kong/kong_{{page.kong_versions[page.version-index].ce-version}}_amd64.deb" + ``` +{% endnavtab %} +{% endnavtabs_ee %} +{% endcapture %} + +{{ download_package | indent | replace: " ", "" }} + +2. Install the package: + +{% capture install_package %} +{% navtabs_ee codeblock %} +{% navtab Kong Gateway %} +```bash +sudo dpkg -i kong-enterprise-edition-{{page.kong_versions[page.version-index].ee-version}}.all.deb +``` +{% endnavtab %} +{% navtab Kong Gateway (OSS) %} +```bash +sudo dpkg -i kong-{{page.kong_versions[page.version-index].ce-version}}.amd64.deb +``` +{% endnavtab %} +{% endnavtabs_ee %} +{% endcapture %} + +{{ install_package | indent | replace: " ", "" }} + +{% navtabs_ee %} +{% navtab Kong Gateway %} +{:.note .no-icon} +> Once {{ site.base_gateway }} is installed, you may want to run `sudo apt-mark hold kong-enterprise-edition`. This will prevent an accidental upgrade to a new version. +{% endnavtab %} +{% navtab Kong Gateway (OSS) %} +{:.note .no-icon} +> Once {{ site.base_gateway }} is installed, you may want to run `sudo apt-mark hold kong`. This will prevent an accidental upgrade to a new version. +{% endnavtab %} +{% endnavtabs_ee %} + +{% endnavtab %} +{% navtab APT repository %} + +Install the APT repository from the command line. + +1. Setup the Kong APT repository: + ```bash + echo "deb [trusted=yes] {{ site.links.download }}/gateway-3.x-ubuntu-$(lsb_release -sc)/ \ + default all" | sudo tee /etc/apt/sources.list.d/kong.list + ``` + +2. Update the repository: + ```bash + sudo apt-get update + ``` + +3. Install Kong: + +{% capture install_from_repo %} +{% navtabs_ee codeblock %} +{% navtab Kong Gateway %} +```bash +sudo apt install -y kong-enterprise-edition={{page.kong_versions[page.version-index].ee-version}} +``` +{% endnavtab %} +{% navtab Kong Gateway (OSS) %} +```bash +apt install -y kong={{page.kong_versions[page.version-index].ce-version}} +``` +{% endnavtab %} +{% endnavtabs_ee %} +{% endcapture %} + +{{ install_from_repo | indent | replace: " ", "" }} + +{% endnavtab %} +{% endnavtabs %} + +{% include_cached /md/gateway/setup.md kong_version=page.kong_version %} diff --git a/src/gateway/install/macos.md b/src/gateway/install/macos.md new file mode 100644 index 000000000000..ecd048c539cb --- /dev/null +++ b/src/gateway/install/macos.md @@ -0,0 +1,108 @@ +--- +title: Install Kong Gateway on macOS +badge: oss +--- + +{{site.ce_product_name}} is licensed under an +[Apache 2.0 license](https://github.com/Kong/kong/blob/master/LICENSE). + +## Prerequisites + +You have [root-equivalent](/gateway/{{page.kong_version}}/production/running-kong/kong-user) access. + +## Download and install + +Install {{site.base_gateway}}: + +Use the [Homebrew](https://brew.sh/) package manager to add Kong as a tap and install it: + +```bash +brew tap kong/kong +brew install kong +``` + +## Prepare your configs + +Kong can run either with or without a database. + +When using a database, you will use the `kong.conf` configuration file for setting Kong's +configuration properties at start-up and the database as storage of all configured entities, +such as the Routes and Services to which Kong proxies. + +When not using a database, you will use `kong.conf`'s configuration properties and a `kong.yml` +file for specifying the entities as a declarative configuration. + +### Using a database + + +{% include_cached /md/enterprise/cassandra-deprecation.md %} + +[Configure][configuration] Kong so it can connect to your database. Kong supports +[PostgreSQL {{site.data.kong_latest.dependencies.postgres}}](http://www.postgresql.org/) and +[Cassandra {{site.data.kong_latest.dependencies.cassandra}}](http://cassandra.apache.org/) as datastores, and +can also run in [DB-less mode](/gateway/{{ page.kong_version }}/production/deployment-topologies/db-less-and-declarative-config) + +1. If you are using Postgres, provision a database and a user before starting Kong: + + ```sql + CREATE USER kong; CREATE DATABASE kong OWNER kong; + ``` + +2. Run the Kong migrations: + + ```bash + kong migrations bootstrap [-c /path/to/kong.conf] + ``` + + By default, Kong is configured to communicate with a local Postgres instance. + If you are using Cassandra, or need to modify any settings, download the [`kong.conf.default`](https://raw.githubusercontent.com/Kong/kong/master/kong.conf.default) file and [adjust][configuration] it as necessary. + +3. As root, add `kong.conf.default` to `/etc`: + + ```bash + sudo mkdir -p /etc/kong + sudo cp kong.conf.default /etc/kong/kong.conf + ``` + +### Without a database + +If you are going to run Kong in [DB-less mode](/gateway/latest/production/deployment-topologies/db-less-and-declarative-config), +you should start by generating a declarative config file. + +1. Generate a `kong.yml` file in your current folder using the following command: + + ``` bash + kong config init + ``` + + The file contains instructions about how to populate it. + +2. Edit your `kong.conf` file. Set the `database` option + to `off` and the `declarative_config` option to the path of your `kong.yml` file: + + ``` conf + database = off + declarative_config = /path/to/kong.yml + ``` + +## Run Kong Gateway + +1. Start {{site.base_gateway}}: + + ```bash + kong start [-c /path/to/kong.conf] + ``` + +2. Verify that {{site.base_gateway}} is running: + + ```bash + curl -i http://localhost:8001/ + ``` + +## Next steps + +Check out {{site.base_gateway}}'s series of +[Getting Started](/gateway/{{page.kong_version}}/get-started/services-and-routes) guides to get the most +out of {{site.base_gateway}}. + +[configuration]: /gateway/{{page.kong_version}}/reference/configuration#database diff --git a/src/gateway/key-concepts/manage-kong-with-deck.md b/src/gateway/key-concepts/manage-kong-with-deck.md new file mode 100644 index 000000000000..fbf57f4d43f4 --- /dev/null +++ b/src/gateway/key-concepts/manage-kong-with-deck.md @@ -0,0 +1,6 @@ +--- +title: Manage Kong Gateway with decK + +--- + +## PLACEHOLDER Manage {{site.base_gateway}} with decK diff --git a/src/gateway/key-concepts/plugins.md b/src/gateway/key-concepts/plugins.md new file mode 100644 index 000000000000..9dfd5db984b0 --- /dev/null +++ b/src/gateway/key-concepts/plugins.md @@ -0,0 +1,6 @@ +--- +title: Plugins +concept_type: explanation +--- + +{% include_cached /md/about-plugins.md %} \ No newline at end of file diff --git a/src/gateway/key-concepts/routes/expressions.md b/src/gateway/key-concepts/routes/expressions.md new file mode 100644 index 000000000000..5d93bbfa2a29 --- /dev/null +++ b/src/gateway/key-concepts/routes/expressions.md @@ -0,0 +1,134 @@ +--- +title: How to Configure Routes using Expressions +content-type: how-to +--- + + +Expressions can describe routes or paths as patterns using logical expressions. +This how-to guide will walk through switching to the new router, and configuring routes with the new expressive domain specific language. +For a list of all available operators and configurable fields please review the [reference documentation](/gateway/latest/reference/router-operators). + +## Prerequisite + +Edit [kong.conf](/gateway/latest/production/kong-conf) to contain the line `router_flavor = expressions` and restart {{site.base_gateway}}. +Note: once you enable expressions, the match fields that traditionally exist on the Route object (such as `paths`, `methods`) will no longer +be configurable and you must specify Expressions in the `atc` field. + +## Create routes with Expressions + +To create a new router object using expressions, send a `POST` request to the [services endpoint](/gateway/latest/admin-api/#update-route) like this: +```sh +curl --request POST \ + --url http://localhost:8001/services/example-service/routes \ + --form atc='http.path == "/mock"' +``` + +In this example, you associated a new route object with the path `/mock` to the existing service `example-service`. The Expressions DSL also allows you to create complex router match conditions. + +```sh +curl --request POST \ + --url http://localhost:8001/services/example-service/routes \ + --header 'Content-Type: multipart/form-data' \ + --form 'atc=(http.path == "/mock" || net.protocol == "https")' +``` +In this example the || operator created an expression that set variables for the following fields: + +``` +curl --request POST \ + --url http://localhost:8001/services/example-service/routes \ + --header 'Content-Type: multipart/form-data' \ + --form 'atc=http.path == "/mock" && (net.protocol == "http" || net.protocol == "https")' +``` + +### Create complex routes with Expressions + +You can describe complex route objects using operators within a `POST` request. + +```sh + +curl --request POST \ + --url http://localhost:8001/services/example-service/routes \ + --header 'Content-Type: multipart/form-data' \ + --form name=complex_object \ + --form 'atc=(net.protocol == "http" || net.protocol == "https") && + (http.method == "GET" || http.method == "POST") && + (http.host == "example.com" || http.host == "example.test") && + (http.path ^= "/mock" || http.path ^= "/mocking") && + http.headers.x_another_header == "example_header" && (http.headers.x_my_header == "example" || http.headers.x_my_header == "example2")' +``` + + +For a list of all available operators, see the [reference documentation](/gateway/latest/reference/router-operators/). + +## Performance considerations when using Expressions + +Generally, Expressions are evaluated sequentially until a match could be found. This means with large number of Routes, the worst case match time +will tends to scale linearly as the number of routes increase. Therefore it is desirable to reduce the number of unique routes by leveraging +the combination capability of the language. + +Keep regex usages to a minimum. Regular expressions are much more expensive to build and execute, and can not be optimized easily. Leveraging the +powerful operators provided by the language instead. + +### Examples + +#### Exact matches + +When performing exact (not prefix) matches on paths, traditionally regex has to be used in the following form: + +``` +paths: ["~/foo/bar$"] +``` + +Routers with large amount of regexes are expensive to build and execute. With Expressions, avoid using regex by write the following: + +``` +http.path == "/foo/bar" +``` + +#### Optional slash at the end + +Sometimes it is desirable to match both `/foo` and `/foo/` in the same route. Traditionally, this has been done using the following regex: + + +``` +paths: ["~/foo/?$"] +``` + +With Expressions, avoid using regex by write the following: + +``` +http.path == "/foo/bar" || http.path == "/foo/bar/" +``` + +#### Multiple routes with same Service and Plugin config + +If multiple routes results in the same Service and Plugin config being used, they should be combined into a single Expression Route +with logical or operator `||`. + +Example: + +Route 1: +``` +service: example-service +atc: http.path == "/hello" +``` + +Route 2: +``` +service: example-service +atc: http.path == "/world" +``` + +Should be simply be combined as: + +``` +service: example-service +atc: http.path == "/hello" || http.path == "/world" +``` + +This reduces the number of routes the Expressions engine has to consider, which helps with the matching performance at runtime + +## More information + +* [Expressions repository](https://github.com/Kong/atc-router#table-of-contents) +* [Expressions Reference](/gateway/latest/reference/router-operators) diff --git a/src/gateway/key-concepts/routes/index.md b/src/gateway/key-concepts/routes/index.md new file mode 100644 index 000000000000..473f2ad5ec21 --- /dev/null +++ b/src/gateway/key-concepts/routes/index.md @@ -0,0 +1,43 @@ +--- +title: Routes +concept_type: explanation +--- + +Routes determine how (and if) requests are sent to their services after they reach {{site.base_gateway}}. Where a service represents the backend API, a route defines what is exposed to clients. + +A single service can have many routes. Once a route is matched, {{site.base_gateway}} proxies the request to its associated service. + +## Route and service interaction + +Routes, in conjunction with [services](/gateway/{{page.kong_version}}/key-concepts/services/), let you expose your services to applications with {{site.base_gateway}}. {{site.base_gateway}} abstracts the service from the applications by using routes. Since the application always uses the route to make a request, changes to the services, like versioning, don't impact how applications make the request. Routes also allow the same service to be used by multiple applications and apply different policies based on the route used. + +For example, if you have an external application and an internal application that need to access the `example_service` service, but the external application should be limited in how often it can query the service to assure no denial of service. If a rate limit policy is configured for the service when the internal application calls the service, the internal application is limited as well. Routes can solve this problem. + +In the example above, two routes can be created, say `/external` and `/internal`, and both routes can point to `example_service`. A policy can be configured to limit how often the `/external` route is used and the route can be communicated to the external client for use. When the external client tries to access the service via {{site.base_gateway}} using `/external`, they are rate limited. But when the internal client accesses the service using {{site.base_gateway}} using `/internal`, the internal client will not be limited. + +## Dynamically rewrite request URLs with routes + +Routes can be configured dynamically to rewrite the requested URL to a different URL for the upstream. For example, your legacy upstream endpoint may have a base URI like `/api/old/`. However, you want your publicly accessible API endpoint to now be named `/new/api`. To route the service's upstream endpoint to the new URL, you could set up a service with the path `/api/old/` and a route with the path `/new/api`. + +{{site.base_gateway}} can also handle more complex URL rewriting cases by using regular expression capture groups in the route path and the [Request Transformer Advanced](/hub/kong-inc/request-transformer-advanced/) plugin. For example, this can be used when you must replace `/api//old` with `/new/api/`. + +{{site.base_gateway}} 3.0.x or later ships with a new router. The new router can use regex expression capture groups to describe routes using a domain-specific language called Expressions. Expressions can describe routes or paths as patterns using regular expressions. For more information about how to configure the router using Expressions, see [How to configure routes using expressions](/gateway/{{page.kong_version}}/key-concepts/routes/expressions). + +## Plugins for routes + +You can also use plugins to interface with routes. This allows you to further your routing capabilities in {{site.base_gateway}}. + +See the following plugins for more information: + +* [LDAP Authentication Advanced](/hub/kong-inc/ldap-auth-advanced/): Secure {{site.base_gateway}} clusters, routes, and services with username and password protection. +* [Mutual TLS Authentication](/hub/kong-inc/mtls-auth/): Secure routes and services with client certificate and mutual TLS authentication. +* [Route By Header](/hub/kong-inc/route-by-header/): Route request based on request headers. +* [Route Transformer Advanced](/hub/kong-inc/route-transformer-advanced/): Transform routing by changing the upstream server, port, or path. + +## Route configuration +Before you can start making requests against a service, you must add a route to it. + +You can add routes to a service in {{site.base_gateway}} using the following methods: + +* [Send an HTTP request using the Admin API](/gateway/{{page.kong_version}}/get-started/services-and-routes/) +* [Create a route using the Kong Manager user interface](/gateway/{{page.kong_version}}/kong-manager/get-started/services-and-routes/) diff --git a/src/gateway/key-concepts/services.md b/src/gateway/key-concepts/services.md new file mode 100644 index 000000000000..03abc3bbed9e --- /dev/null +++ b/src/gateway/key-concepts/services.md @@ -0,0 +1,27 @@ +--- +title: Services +content_type: explanation +--- + +In {{site.base_gateway}}, a service is an entity representing an external upstream API or microservice. For example, a data transformation microservice, a billing API, and so on. + +The main attribute of a service is its URL. You can specify the URL with a single string, or by specifying its protocol, host, port, and path individually. + +Service entities are abstractions of each of your own upstream services. Examples of services would be a data transformation microservice or a billing API. + +## Service and route interaction + +Services, in conjunction with [routes](/gateway/latest/key-concepts/routes/), let you expose your services to clients with {{site.base_gateway}}. {{site.base_gateway}} abstracts the service from the clients by using routes. Since the client always calls the route, changes to the services(like versioning) don't impact how clients make the call. Routes also allow the same service to be used by multiple clients and apply different policies based on the route used. + +For example, if you have an external client and an internal client that need to access the `hwservice` service, but the external client should be limited in how often it can query the service to assure no denial of service. If a rate limit policy is configured for the service when the internal client calls the service, the internal client is limited as well. Routes solve this problem. + +In the example above, two routes can be created, say `/external` and `/internal`, and both routes can point to `hwservice`. A policy can be configured to limit how often the `/external` route is used and the route can be communicated to the external client for use. When the external client tries to access the service via {{site.base_gateway}} using `/external`, they are rate limited. But when the internal client accesses the service via {{site.base_gateway}} using `/internal`, the internal client will not be limited. + +## Service configuration + +When configuring access to your API, you start by specifying a service. + +You can configure a service in {{site.base_gateway}} using the following methods: + +* [Send an HTTP request using the Admin API](/gateway/latest/get-started/services-and-routes/) +* [Create a service using the Kong Manager user interface](/gateway/latest/kong-manager/get-started/services-and-routes/) \ No newline at end of file diff --git a/src/gateway/key-concepts/upstreams.md b/src/gateway/key-concepts/upstreams.md new file mode 100644 index 000000000000..d944e0d37bce --- /dev/null +++ b/src/gateway/key-concepts/upstreams.md @@ -0,0 +1,29 @@ +--- +title: Upstreams +concept_type: explanation +--- + +Upstream refers to an API, application, or micro-service that {{site.base_gateway}} forwards requests to. +In {{site.base_gateway}}, an upstream object represents a virtual hostname and can be used to health check, circuit break, and load balance incoming requests over multiple services. + +## Upstream and service interaction + +You can configure a [service](/gateway/{{ page.kong_version }}/key-concepts/services/) to point to an upstream instead of a host. +For example, if you have a service called `example_service` and an upstream called `example_upstream`, you can point `example_service` to `example_upstream` instead of specifying a host. +The `example_upstream` upstream can then point both `httpbin.org` and `mockbin.org`. +In a real environment, the upstream points to the same service running on multiple systems. + +This setup allows you to [load balance](/gateway/{{ page.kong_version }}/how-kong-works/load-balancing) between upstream targets. +For example, if an application is deployed across two different servers or upstream targets, {{site.base_gateway}} needs to load balance across both servers. +This is so that if one of the servers (like `httpbin.org` in the previous example) is unavailable, it automatically detects the problem and routes all traffic to the working server (`mockbin.org`). + + +## Upstream configuration + +You can add upstreams to a service in {{site.base_gateway}} using the following methods: + +* Using Kong Manager +* Using the Admin API +* Using decK (YAML) + +For more information about how to configure upstreams, see [Configure Load Balancing](/gateway/{{ page.kong_version }}/get-started/load-balancing/). \ No newline at end of file diff --git a/src/gateway/kong-enterprise/analytics/estimates.md b/src/gateway/kong-enterprise/analytics/estimates.md new file mode 100644 index 000000000000..08dabcea0dbc --- /dev/null +++ b/src/gateway/kong-enterprise/analytics/estimates.md @@ -0,0 +1,177 @@ +--- +title: Estimate Vitals Storage in PostgreSQL +badge: enterprise +--- + +Vitals data can be divided into two categories: {{site.base_gateway}} node statistics and request response codes. + +## {{site.base_gateway}} node statistics + +These types of metrics are proxy latency, upstream latency, and cache hit/miss. {{site.base_gateway}} node statistics are stored in tables like the following: + +* `vitals_stats_seconds_timestamp` stores 1 new row for every _second_ Kong runs +* `vitals_stats_minutes` stores 1 new row for every _minute_ Kong runs +* `vitals_stats_days` stores 1 new row for every _day_ Kong runs + +{{site.base_gateway}} node statistics are not associated with specific {{site.base_gateway}} entities like Workspaces, Services, or Routes. They're designed to represent the cluster's state in time. This means the tables will have new rows regardless if {{site.base_gateway}} is routing traffic or idle. + +The tables do not grow infinitely and hold data for the following duration of time: + +* `vitals_stats_seconds_timestamp` holds data for 1 hour (3600 rows) +* `vitals_stats_minutes` holds data for 25 hours (90000 rows) +* `vitals_stats_days` holds data for 2 years (730 rows) + +## Request response codes + +Request response codes are stored in the other group of tables following a different rationale. Tables in this group share the same structure (`entity_id`, `at`, `duration`, `status_code`, `count`): + +* `vitals_code_classes_by_workspace` +* `vitals_code_classes_by_cluster` +* `vitals_codes_by_route` + +The `entity_id` does not exist in `vitals_code_classes_by_cluster` as this table doesn't store entity-specific information. +In the `vitals_code_classes_by_workspace` table, `entity_id` is `workspace_id`. In the `vitals_codes_by_route` table, `entity_id` is `service_id` and `route_id`. + +`at` is a timestamp. It logs the start of the period a row represents, while `duration` is the duration of that period. + +`status_code` and `count` are the quantity of the HTTP status codes (200, 300, 400, 500) observed in the period represented by a row. + +While {{site.base_gateway}} node statistic tables grow only according to time, status code tables only have new rows when {{site.base_gateway}} proxies traffic, and the number of new rows depends on the traffic itself. + +## Example + +Consider a brand new {{site.base_gateway}} that hasn't proxied any traffic yet. {{site.base_gateway}} node statistic tables have rows but status codes tables don't. + +When {{site.base_gateway}} proxies its first request at `t` returning status code 200, the following rows are added: + +```bash +vitals_codes_by_cluster +[second(t), 1, 200, 1] +[minute(t), 60, 200, 1] +[day(t), 84600, 200, 1] +``` + +Second, minute, and day content is trimmed in the following way: + +* `second(t)` is `t` trimmed to seconds, for example: `second(2021-01-01 20:21:30)` would be `2021-01-01 20:21:30`. +* `minute(t)` is `t` trimmed to minutes, for example: `minute(2021-01-01 20:21:30.234)` would be `2021-01-01 20:21:00`. +* `day(t)` is `t` trimmed to day, for example: `day(2021-01-01 20:21:30.234)` would be `2021-01-01 00:00:00`. + +```bash +vitals_codes_by_workspace +[workspace_id, second(t), 1, 200, 1] +[workspace_id, minute(t), 60, 200, 1] +[workspace_id, day(t), 84600, 200, 1] + +vitals_codes_by_route +[service_id, route_id, second(t), 1, 200, 1] +[service_id, route_id, minute(t), 60, 200, 1] +[service_id, route_id, day(t), 84600, 200, 1] +``` + +Let's consider what happens when new requests are proxied in some scenarios. + +### Scenario where no rows are inserted + +If we make the same request again at the same `t` and it also receives 200, no new rows will be inserted. + +In this case, the existing rows have their count column incremented accordingly: + +```bash +vitals_codes_by_cluster +[second(t), 1, 200, 2] +[minute(t), 60, 200, 2] +[day(t), 84600, 200, 2] + +vitals_codes_by_workspace +[workspace_id, second(t), 1, 200, 2] +[workspace_id, minute(t), 60, 200, 2] +[workspace_id, day(t), 84600, 200, 2] + +vitals_codes_by_route +[service_id, route_id, second(t), 1, 200, 2] +[service_id, route_id, minute(t), 60, 200, 2] +[service_id, route_id, day(t), 84600, 200, 2] +``` + +### Scenario where new rows are inserted + +If the last request received a 500 status code, new rows are inserted: + +```bash +vitals_codes_by_cluster +[second(t), 1, 200, 1] +[minute(t), 60, 200, 1] +[day(t), 84600, 200, 1] + +[second(t), 1, 500, 1] +[minute(t), 60, 500, 1] +[day(t), 84600, 500, 1] + +vitals_codes_by_workspace +[workspace_id, second(t), 1, 200, 1] +[workspace_id, minute(t), 60, 200, 1] +[workspace_id, day(t), 84600, 200, 1] + +[workspace_id, second(t), 1, 500, 1] +[workspace_id, minute(t), 60, 500, 1] +[workspace_id, day(t), 84600, 500, 1] + +vitals_codes_by_route +[service_id, route_id, second(t), 1, 200, 1] +[service_id, route_id, minute(t), 60, 200, 1] +[service_id, route_id, day(t), 84600, 200, 1] + +[service_id, route_id, second(t), 1, 500, 1] +[service_id, route_id, minute(t), 60, 500, 1] +[service_id, route_id, day(t), 84600, 500, 1] +``` + +### Scenario where a second row is inserted + +Assume that at `t + 5s`, where `minute(t)==minute(t + 5s)`, {{site.base_gateway}} proxies the same request returning 200. Since `minute()` and `day()` for both `t` and `t + 5s` are the same, minute and day rows should just be updated. Since `second()` is different for the two instants, a new second row should be inserted in each table. + +```bash +vitals_codes_by_cluster +[second(t), 1, 200, 1] +[second(t + 5s), 1, 200, 1] +[minute(t), 60, 200, 2] +[day(t), 84600, 200, 2] + +vitals_codes_by_workspace +[workspace_id, second(t), 1, 200, 1] +[workspace_id, second(t + 5s), 1, 200, 1] +[workspace_id, minute(t), 60, 200, 2] +[workspace_id, day(t), 84600, 200, 2] + +vitals_codes_by_route +[service_id, route_id, second(t), 1, 200, 1] +[service_id, route_id, second(t + 5s), 1, 200, 1] +[service_id, route_id, minute(t), 60, 200, 2] +[service_id, route_id, day(t), 84600, 200, 2] +``` + +In summary, the number of rows in those status codes tables is directly related to: + +* The number of status codes observed in {{site.base_gateway}} proxied requests +* The number of {{site.base_gateway}} entities involved in those requests +* The constant flow of proxied requests + +In an estimate of row numbers in scenario, consider a {{site.base_gateway}} cluster with the following characteristics: + +* A constant flow of requests returning all 5 possible groups of status codes (1xx, 2xx, 3xx, 4xx and 5xx). +* Just 1 workspace, 1 service, and 1 route + +After 24 hours of traffic, the status codes tables will have this number of rows: + +Status code table name | Day | Minute | Seconds | Total +---------------------- | --- | ------ | ------- | ----- +**vitals_codes_by_cluster** | 5 | 7200 | 18000 | 25200 +**vitals_codes_by_workspace** | 5 | 7200 | 18000 | 25200 +**vitals_codes_by_route** | 5 | 7200 | 18000 | 25200 + +It's important to note that this assumes that all 5 groups of status codes had been observed in those 24 hours of traffic. This is why quantities were multiplied by 5. + +With this baseline scenario, it's easier to calculate what happens when the number of {{site.base_gateway}} entities (Workspaces and Routes) involved in the traffic increases. Tables `vitals_codes_by_workspace` and `vitals_codes_by_route` have their row number change with increase in workspaces and routes, respectively. + +If the above {{site.base_gateway}} cluster is expanded to have 10 workspaces with 1 route each (10 routes total) and it proxies traffic for 24 hours and returns all 5 status codes, `vitals_codes_by_workspace` and `vitals_codes_by_route` would have 252,000 rows. diff --git a/src/gateway/kong-enterprise/analytics/index.md b/src/gateway/kong-enterprise/analytics/index.md new file mode 100644 index 000000000000..5d7807ddc601 --- /dev/null +++ b/src/gateway/kong-enterprise/analytics/index.md @@ -0,0 +1,94 @@ +--- +title: Vitals Overview +badge: enterprise +--- + +Use Kong Vitals (Vitals) to monitor {{site.ee_product_name}} health and performance, and to understand the microservice API transactions traversing Kong. Vitals uses visual API analytics to see exactly how your APIs and Gateway are performing. Quickly access key statistics, monitor vital signs, and pinpoint anomalies in real time. + +* Use Kong Admin API to access Vitals data via endpoints. Additional visualizations, including dashboarding of Vitals data alongside data from other systems, can be achieved using the Vitals API to integrate with common monitoring systems. + +* Use Kong Manager to view visualizations of Vitals data, including the Workspaces Overview Dashboard, Workspace Charts, Vitals tab, and Status Codes, and to generate CSV Reports. + +![Vitals Overview](/assets/images/docs/ee/vitals_overview.png) + +## Prerequisites +Vitals is enabled by default in {{site.ee_product_name}} and available upon the first login of a Super Admin. + + +{% include_cached /md/enterprise/cassandra-deprecation.md %} + + +You will need one of the following databases to use Vitals: +* InfluxDB +* PostgresSQL 9.5+ +* Cassandra 2.1+ + +## Guidelines for viewing Vitals +When using Vitals, note: +* Vitals is enabled by default and accessible the first time a Super Admin logs in. + * To enable or disable Vitals, see [Enable or Disable Vitals](#enable-or-disable-vitals). +* Any authorized user can view Vitals for the entire Kong cluster or for a particular Workspace. + * If a user does not have access to a Workspace, its Vitals are hidden from view. + * If a user does not have access to Vitals data, charts will not display. + +## Vitals API +Vitals data is available via endpoints on Kong’s Admin API. Access to these endpoints may be controlled via Admin API RBAC. The Vitals API is described in the OAS (Open API Spec, formerly Swagger) file. See a sample here (downloadable file): [`vitals.yaml`](/api/vitals.yaml). + +## Viewing Vitals in Kong Manager +View Vitals information in Kong Manager using any of the following: +* Overview Dashboard, available from the Workspaces page for an overview of your Kong cluster, or an individual Workspace for an overview of the selected Workspace. +* Workspace charts, which display on the Workspaces page beneath the Overview Dashboard. These charts give a quick overview of the status of an individual Workspace. +* Vitals tab, which provides detailed information about your Kong cluster, including total requests, latency, and cache information. +* Status Codes to view cluster-wide status code classes. + +## Overview Dashboard +When you log in to Kong Manager, the Workspaces page displays by default. The top of the page displays the Vitals Overview Dashboard summarizing your Kong cluster, including the health and performance of your APIs and Gateway, total requests, average error rate, total consumers, and total services. This Vitals Overview Dashboard makes it easy for an Admin to quickly identify any issues that need attention. + +## Workspace charts +On the Workspaces page, beneath the Overview Dashboard, the Workspaces section displays each Workspace with a chart showing Vitals for the most recently added services, consumers, and plugins for that Workspace. Hover over a coordinate to view the exact number of successes and errors at a given timestamp, or drilldown into the Workspace chart for more details. + +## Vitals tab +The Vitals tab, or Vitals view, displays metrics about the health and performance of Kong nodes and Kong-proxied APIs. The Vitals View displays total requests, latency, and cache information. You also can generate reports from the Vitals view. + +Options to populate the Vitals view, or areas in the chart, include: + +| Option | Description | +|--------------------------|----------------------------------------------------------------------------------------------| +| Timeframe Selector | A timeframe selector controls the timeframe of data visualized, which indirectly controls the granularity of the data. For example, the “Last 5 Minutes” selection displays 1-second resolution data, while longer time frames display 1-minute resolution data. +| View | Select to populate the Vitals chart by Hostname, Hostname + ID, or ID.| +| Total Requests | The Total Requests chart displays a count of all proxy requests received. This includes requests that were rejected due to rate-limiting, failed authentication, and so on.| +| Cluster and Node Data | Metrics are displayed on Vitals charts at both node and cluster level. Controls are available to show cluster-wide metrics and/or node-specific metrics. Clicking on individual nodes will toggle the display of data from those nodes. Nodes are identified by a unique Kong node identifier, by hostname, or by a combination of the two.| + +## Status Codes +The Status Codes view displays visualizations of cluster-wide status code classes (1xx, 2xx, 3xx, 4xx, 5xx). The Status Codes view contains the counts of status code classes graphed over time, as well as the ratio of code classes to total requests. See [Status Codes](/gateway/{{page.kong_version}}/kong-enterprise/analytics/metrics/#status-codes). + +>**Note**: The Status Codes view does not include non-standard code classes (6xx, 7xx, etc.). Individual status code data can be viewed in the Consumer, Route, and Service details pages under the Activity tab. Both standard and non-standard status codes are visible in these views. + +## Enable or disable Vitals +{{site.ee_product_name}} ships with Vitals enabled by default. To enable or disable Vitals, edit the configuration file or environment variables. + +{% navtabs %} +{% navtab Using kong.conf %} + +1. Edit the configuration file to enable or disable Vitals: + ```bash + # via your Kong configuration file; e.g., kong.conf + vitals = on # vitals is enabled + vitals = off # vitals is disabled + ``` +2. Restart Kong. + +{% endnavtab %} +{% navtab Using environment variables %} + +1. Use environment variables to enable or disable Vitals: + ```bash + # or via environment variables + export KONG_VITALS=on + export KONG_VITALS=off + ``` + +2. Restart Kong. + +{% endnavtab %} +{% endnavtabs %} diff --git a/src/gateway/kong-enterprise/analytics/influx-strategy.md b/src/gateway/kong-enterprise/analytics/influx-strategy.md new file mode 100644 index 000000000000..e765ba031641 --- /dev/null +++ b/src/gateway/kong-enterprise/analytics/influx-strategy.md @@ -0,0 +1,281 @@ +--- +title: Vitals with InfluxDB +badge: enterprise +--- + +Leveraging a time series database for Vitals data +can improve request and Vitals performance in very-high traffic {{site.ee_product_name}} +clusters (such as environments handling tens or hundreds of thousands of +requests per second), without placing additional write load on the database +backing the Kong cluster. + +For information about using Kong Vitals with a database as the backend, refer to +[Kong Vitals](/gateway/{{page.kong_version}}/kong-enterprise/analytics/). + +## Set up Kong Vitals with InfluxDB + +### Install Kong Gateway + +If you already have a {{site.base_gateway}} instance, skip to [deploying a license](#deploy-a-kong-gateway-license). + +If you have not installed {{site.base_gateway}}, a Docker installation +will work for the purposes of this guide. + + +### Pull the Kong Gateway Docker image {#pull-image} + +1. Pull the following Docker image. + + ```bash + docker pull kong/kong-gateway:{{page.kong_versions[page.version-index].ee-version}}-alpine + ``` + + {:.important} + > Some [older {{site.base_gateway}} images](https://support.konghq.com/support/s/article/Downloading-older-Kong-versions) + are not publicly accessible. If you need a specific patch version and can't + find it on [Kong's public Docker Hub page](https://hub.docker.com/r/kong/kong-gateway), contact + [Kong Support](https://support.konghq.com/). + + You should now have your {{site.base_gateway}} image locally. + +1. Tag the image. + + ```bash + docker tag kong/kong-gateway:{{page.kong_versions[page.version-index].ee-version}}-alpine kong-ee + ``` + + +### Start the database and Kong Gateway containers + +1. Create a custom network to allow the containers to discover and communicate +with each other. + + ```bash + docker network create kong-ee-net + ``` + +1. Start a PostgreSQL container: + + ```p + docker run -d --name kong-ee-database \ + --network=kong-ee-net \ + -p 5432:5432 \ + -e "POSTGRES_USER=kong" \ + -e "POSTGRES_DB=kong" \ + -e "POSTGRES_PASSWORD=kong" \ + postgres:9.6 + ``` + +1. Prepare the Kong database: + +
      docker run --rm --network=kong-ee-net \
      +      -e "KONG_DATABASE=postgres" \
      +      -e "KONG_PG_HOST=kong-ee-database" \
      +      -e "KONG_PG_PASSWORD=kong" \
      +      -e "KONG_PASSWORD=
      {PASSWORD}
      " \ + kong-ee kong migrations bootstrap
      + + +1. Start the gateway with Kong Manager: + +{% include_cached /md/admin-listen.md desc='long' kong_version=page.kong_version %} + +
      docker run -d --name kong-ee --network=kong-ee-net \
      +      -e "KONG_DATABASE=postgres" \
      +      -e "KONG_PG_HOST=kong-ee-database" \
      +      -e "KONG_PG_PASSWORD=kong" \
      +      -e "KONG_PROXY_ACCESS_LOG=/dev/stdout" \
      +      -e "KONG_ADMIN_ACCESS_LOG=/dev/stdout" \
      +      -e "KONG_PROXY_ERROR_LOG=/dev/stderr" \
      +      -e "KONG_ADMIN_ERROR_LOG=/dev/stderr" \
      +      -e "KONG_ADMIN_LISTEN=0.0.0.0:8001" \
      +      -e "KONG_ADMIN_GUI_URL=http://
      {DNSorIP}
      :8002" \ + -e "KONG_VITALS_STRATEGY=influxdb" \ + -e "KONG_VITALS_TSDB_ADDRESS=influxdb:8086" \ + -p 8000:8000 \ + -p 8443:8443 \ + -p 8001:8001 \ + -p 8444:8444 \ + -p 8002:8002 \ + -p 8445:8445 \ + -p 8003:8003 \ + -p 8004:8004 \ + kong-ee
      + + {:.note} + > **Note:** For `KONG_ADMIN_GUI_URL`, replace `DNSorIP` + with with the DNS name or IP of the Docker host. KONG_ADMIN_GUI_URL + _should_ have a protocol, for example, `http://`. + +### Deploy a {{site.base_gateway}} license + +If you already have a {{site.ee_product_name}} license attached to your {{site.base_gateway}} +instance, skip to [starting an InfluxDB database](#start-an-influxdb-database). + +You will not be able to access the Kong Vitals functionality without a valid +{{site.ee_product_name}} license attached to your {{site.base_gateway}} instance. + +{% include_cached /md/enterprise/deploy-license.md heading="####" kong_version=page.kong_version %} + +### Start an InfluxDB database + +Production-ready InfluxDB installations should be deployed as a separate +effort, but for proof-of-concept testing, running a local InfluxDB instance +is possible with Docker: + +```bash +docker run -p 8086:8086 \ + --network= \ + --name influxdb \ + -e INFLUXDB_DB=kong \ + influxdb:1.8.4-alpine +``` + +{:.warning} +> You **must** use InfluxDB 1.8.4-alpine because +InfluxDB 2.0 will **not** work. + +Writing Vitals data to InfluxDB requires that the `kong` database is created, +this is done using the `INFLUXDB_DB` variable. + +### Configure Kong Gateway + +{:.note} +> **Note:** If you used the configuration in +[Installing {{site.base_gateway}} on Docker](#install-kong-gateway), +then you do not need to complete this step. + +In addition to enabling Kong Vitals, {{site.base_gateway}} must be configured to use InfluxDB as the +backing strategy for Vitals. The InfluxDB host and port must also be defined: + +```bash +echo "KONG_VITALS_STRATEGY=influxdb KONG_VITALS_TSDB_ADDRESS=influxdb:8086 kong reload exit" \ +| docker exec -i kong-ee /bin/sh +``` + +{:.note} +> **Note**: In Hybrid Mode, configure [`vitals_strategy`](/gateway/{{page.kong_version}}/reference/configuration/#vitals_strategy) +and [`vitals_tsdb_address`](/gateway/{{page.kong_version}}/reference/configuration/#vitals_tsdb_address) +on both the control plane and all data planes. + +## Understanding Vitals data using InfluxDB measurements + +Kong Vitals records metrics in two InfluxDB measurements: + +1. `kong_request`: Contains field values for request latencies and HTTP, + and tags for various Kong entities associated with the requests (for + example, the Route and Service in question). +2. `kong_datastore_cache`: Contains points about cache hits and + misses. + +To display the measurement schemas on your InfluxDB instance running +in Docker: + +1. Open command line in your InfluxDB Docker container. + + ```sh + docker exec -it influxdb /bin/sh + ``` + +2. Log in to the InfluxDB CLI. + + ```sh + influx -precision rfc3339 + ``` + +3. Enter the InfluxQL query for returning a list of tag keys associated +with the specified database. + + ```sql + > SHOW TAG KEYS ON kong + ``` + + Example result: + + ```sql + name: kong_request + tagKey + ------ + consumer + hostname + route + service + status_f + wid + workspace + + name: kong_datastore_cache + tagKey + ------ + hostname + wid + ``` + +4. Enter the InfluxQL query for returning the field keys and the +data type of their field values. + + ```sh + > SHOW FIELD KEYS ON kong + ``` + + Example result: + + ```sql + name: kong_request + fieldKey fieldType + -------- --------- + kong_latency integer + proxy_latency integer + request_latency integer + status integer + + name: kong_datastore_cache + fieldKey fieldType + -------- --------- + + hits integer + misses integer + ``` + +The tag `wid` is used to differentiate the unique worker ID per host, to avoid +duplicate metrics shipped at the same point in time. + +As demonstrated above, the series cardinality of the `kong_request` measurement +varies based on the cardinality of the Kong cluster configuration - a greater +number of Service/Route/Consumer/Workspace combinations handled by Kong results +in a greater series cardinality as written by Vitals. + +## Sizing an InfluxDB node/cluster for Vitals + +Consult the +[InfluxDB sizing guidelines](https://docs.influxdata.com/influxdb/v1.8/guides/hardware_sizing/) +for reference on appropriately sizing an InfluxDB node/cluster. + +{:.note} +> **Note:** The query behavior when reading Vitals data falls under the "moderate" load +category as defined by the InfluxDB sizing guidelines. Several `GROUP BY` statements and +functions are used to generate the Vitals API responses, which can require +significant CPU resources to execute when hundreds of thousands or millions of +data points are present. + +## Query frequency and precision + +Kong buffers Vitals metrics and writes InfluxDB points in batches to improve +throughput in InfluxDB and reduce overhead in the Kong proxy path. Each Kong +worker process flushes its buffer of metrics every 5 seconds or 5000 data points, +whichever comes first. + +Metrics points are written with microsecond (`u`) precision. To comply with +the [Vitals API](/api/vitals.yaml), measurement +values are read back grouped by second. + +{:.note} +> **Note:** Because of limitations in the OpenResty API, writing values with +microsecond precision requires an additional syscall per request. + +## Managing the retention policy of the Kong database + +Vitals InfluxDB data points are not downsampled or managed by a +retention policy through Kong. InfluxDB operators are encouraged to manually manage +the retention policy of the `kong` database to reduce the disk space and memory +needed to manage Vitals data points. diff --git a/src/gateway/kong-enterprise/analytics/metrics.md b/src/gateway/kong-enterprise/analytics/metrics.md new file mode 100644 index 000000000000..99edb5dca20a --- /dev/null +++ b/src/gateway/kong-enterprise/analytics/metrics.md @@ -0,0 +1,113 @@ +--- +title: Vitals Metrics +badge: enterprise +--- + +Vitals metrics fall into two categories: +* Health Metrics — for monitoring the health of a Kong cluster +* Traffic Metrics — for monitoring the usage of upstream services + + +All metrics are collected at 1-second intervals and aggregated into 1-minute +intervals. The 1-second intervals are retained for one hour. The 1-minute +intervals are retained for 25 hours. + +If longer retention times are needed, the Vitals API can be used to pull metrics +out of Kong and into a data retention tool. + +## Health Metrics + +Health metrics give insight into the performance of a Kong cluster; for example, +how many requests the cluster is processing and the latency on those requests. + +Health metrics are tracked for each node in a cluster as well as for the cluster +as a whole. In Kong, a node is a running process with a unique identifier, +configuration, cache layout, and connections to both Kong’s datastores and the +upstream APIs it proxies. Note that node identifiers are unique to the process, +and not to the host on which the process runs. In other words, each Kong restart +results in a new node, and therefore a new node ID. + +### Latency + +The Vitals API may return null for Latency metrics. This occurs when no API +requests were proxied during the timeframe. Null latencies are not graphed in +Kong Manager; periods with null latencies appear as gaps in Vitals charts. + +#### Proxy Latency (Request) + +The Proxy Latency metrics are the min, max, and average values for the time, in milliseconds, that the Kong proxy spends processing API proxy requests. This includes time to execute plugins that run in the access phase and the DNS lookup time. This does not include time spent in Kong’s load balancer, time spent sending the request to the upstream, or time spent on the response. + +These metrics are referenced in the Vitals API with the following labels: `latency_proxy_request_min_ms`, `latency_proxy_request_max_ms`, `latency_proxy_request_avg_ms`. + +Latency is not reported when a request is prematurely ended by Kong (e.g., bad auth, rate limited, etc.). Note that this differs from the **Total Requests** metric that does count such requests. + +#### Upstream Latency + +The Upstream Latency metrics are the min, max, and average values for the time elapsed, in milliseconds, between Kong sending requests upstream and Kong receiving the first bytes of responses from upstream. + +These metrics are referenced in the Vitals API with the following labels: `latency_upstream_min_ms`, `latency_upstream_max_ms`, `latency_upstream_avg_ms`. + +### Datastore Cache + +#### Datastore Cache Hit/Miss + +The Datastore Cache Hit/Miss metrics are the count of requests to Kong's node-level datastore cache. When Kong workers need configuration information to respond to a given API proxy request, they first check their worker-specific cache (also known as L1 cache), then if the information isn’t available they check the node-wide datastore cache (also known as L2 cache). If neither cache contains the necessary information, Kong requests it from the datastore. + +A `Hit` indicates that an entity was retrieved from the data store cache. A `Miss` indicates that the record had to be fetched from the datastore. Not every API request will result in datastore cache access; some entities will be retrieved from Kong's worker-specific cache memory. + +These metrics are referenced in the Vitals API with the following labels: `cache_datastore_hits_total`, `cache_datastore_misses_total`. + +#### Datastore Cache Hit Ratio + +This metric contains the ratio of datastore cache hits to the total count of datastore cache requests. + +> **Note:** Datastore Cache Hit Ratio cannot be calculated for time indices with no hits and no misses. + +## Traffic Metrics + +Traffic metrics provide insight into which of your services are being used, who is using them, and how they are responding. + +### Request Counts + +#### Total Requests + + +This metric is the count of all API proxy requests received. This includes requests that were rejected due to rate-limiting, failed authentication, etc. + +This metric is referenced in the Vitals API with the following label: `requests_proxy_total`. + +#### Requests Per Consumer + +This metric is the count of all API proxy requests received from each specific consumer. Consumers are identified by credentials in their requests (e.g., API key, OAuth token) as required by the Kong Auth plugins in use. + +This metric is referenced in the Vitals API with the following label: `requests_consumer_total`. + +### Status Codes + +#### Total Status Code Classes + +This metric is the count of all status codes grouped by status code class (e.g. 4xx, 5xx). + +This metric is referenced in the Vitals API with the following label: `status_code_classes_total`. + +#### Total Status Codes per Service + +This metric is the total count of each specific status code for a given service. + +This metric is referenced in the Vitals API with the following label: `status_codes_per_service_total`. + +#### Total Status Codes per Route + +This metric is the total count of each specific status code for a given route. + +This metric is referenced in the Vitals API with the following label: `status_codes_per_route_total`. + +#### Total Status Codes per Consumer +This metric is the total count of each specific status code for a given consumer. + +This metric is referenced in the Vitals API with the following label: `status_codes_per_consumer_total`. + +#### Total Status Codes per Consumer Per Route +This metric is the total count of each specific status code for a given consumer and route. + +This metric is referenced in the Vitals API with the following label: `status_codes_per_consumer_route_total`. diff --git a/src/gateway/kong-enterprise/analytics/prometheus-strategy.md b/src/gateway/kong-enterprise/analytics/prometheus-strategy.md new file mode 100644 index 000000000000..de02101e6fbf --- /dev/null +++ b/src/gateway/kong-enterprise/analytics/prometheus-strategy.md @@ -0,0 +1,299 @@ +--- +title: Vitals with Prometheus +badge: enterprise +--- + +This document covers integrating Kong Vitals with a new or existing Prometheus +time-series server or cluster. Leveraging a time-series database for Vitals data +can improve request and Vitals performance in very-high traffic {{site.base_gateway}} +clusters (such as environments handling tens or hundreds of thousands of +requests per second), without placing addition write load on the database +backing the Kong cluster. + +For using Vitals with a database as the backend, refer to [Kong Vitals](/gateway/{{page.kong_version}}/kong-enterprise/analytics/). + +## Lifecycle Overview + +Kong Vitals integrates with Prometheus using an intermediary data exporter, the [Prometheus StatsD exporter](https://github.com/prometheus/statsd_exporter). +This integration allows Kong to efficiently ship Vitals metrics to an outside process where data points +can be aggregated and made available for consumption by Prometheus, without impeding performance +within the Kong proxy itself. In this design, Kong writes Vitals metrics to the StatsD exporter +as [StatsD metrics](https://github.com/statsd/statsd/blob/master/docs/metric_types.md). Prometheus +scrapes this exporter as it would any other endpoint. Kong then queries Prometheus to retrieve and +display Vitals data via the API and Kong Manager. Prometheus does not ever directly scrape the Kong +nodes for time series data. A trivialized workflow looks as follows: + +![Single Node Example Data Flow](/assets/images/docs/ee/vitals-prometheus/single.png) + +It is not uncommon to separate Kong functionality amongst a cluster of nodes. For example, +one or more nodes serve only proxy traffic, while another node is responsible for serving the +Kong Admin API and Kong Manager. In this case, the node responsible for proxy traffic writes +the data to a StatsD exporter, and the node responsible for Admin API reads from Prometheus: + +![Multi Node Example Data Flow](/assets/images/docs/ee/vitals-prometheus/read-write.png) + +In either case, the StatsD exporter process can be run either as a standalone process/container +or as a sidecar/adjacent process within a VM. Note that in high-traffic environments, data aggregation +within the StatsD exporter process can cause significant CPU usage. In such cases, we recommend to +run Kong and StatsD processes on separate hardware/VM/container environments to avoid saturating CPU usage. + +## Set up Prometheus environment for Vitals + +### Download Prometheus + +The latest release of Prometheus can be found at the [Prometheus download page](https://prometheus.io/download/#prometheus). + +Prometheus should be running on a separate node from the one running Kong. +For users that are already using Prometheus in their infrastructure, it's +possible to use existing Prometheus nodes as Vitals storage backend. + +In this guide, we assume Prometheus is running on hostname `prometheus-node` +using default config that listens on port `9090`. + +### Download and configure StatsD exporter + +StatsD exporter is distributed as a Docker image. Pull the latest version +with the following command: + +```sh +docker pull kong/statsd-exporter-advanced:0.3.1 +``` + +The binary includes features like min/max gauges and Unix domain +socket support which are not supported in the public project. + +{:.important} +> This Docker image is a Kong fork of the Prometheus community project and the mapping rules linked below +> do not work with the public image. Ensure you are using the correct one. +> +> If you prefer to use the Prometheus community Helm chart to deploy the exporter, override the image +> and tag in the `values` file as shown below: +> +> ```yaml +> image: +> repository: kong/statsd-exporter-advanced +> tag: 0.3.1 +> ``` + +StatsD exporter needed to configured with a set of mapping rules to translate +the StatsD UDP events to Prometheus metrics. A default set of mapping rules can +be downloaded at +[statsd.rules.yaml](/code-snippets/statsd.rules.yaml). +Then start StatsD exporter with + +```bash +./statsd_exporter --statsd.mapping-config=statsd.rules.yaml \ + --statsd.listen-unixgram='' +``` + +The StatsD mapping rules file must be configured to match the metrics sent from +Kong. To learn how to customize the StatsD events name, please refer to +[Enable Vitals with Prometheus strategy in Kong](#enable-vitals-with-prometheus-strategy-in-kong) +section. + +StatsD exporter can run either on a separate node from Kong (to avoid resource +competition with Kong), or on the same host with Kong (to reduce unnecessary +network overhead). + +In this guide, we assume StatsD exporter is running on hostname `statsd-node`, +using default config that listens to UDP traffic on port `9125` and the metrics +in Prometheus Exposition Format are exposed on port `9102`. + +### Configure Prometheus to scrape StatsD exporter + +To configure Prometheus to scrape StatsD exporter, add the following section to +`scrape_configs` in `prometheus.yaml`. + +```yaml +scrape_configs: + - job_name: 'vitals_statsd_exporter' + scrape_interval: "5s" + static_configs: + - targets: ['statsd-node:9102'] +``` + +Please update `statsd-node` with the actual hostname that runs StatsD exporter. + +If you are using service discovery, it will be more convenient to configure +multiple StatsD exporters in Prometheus. Please refer to the +[scape_configs](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#%3Cscrape_config%3E) +section of Prometheus document for further reading. + +By default, the Vitals graph in Kong Manager uses the configured target address +in the legend, which is named `instance` in the Prometheus metrics label. For some service +discovery setups where `instance` is `IP:PORT`, the user might want to relabel the `instance` +label to display a more meaningful hostname in the legend. +To do so, the user can also refer to the [scape_configs](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#%3Cscrape_config%3E) +section and rewrite the `instance` label with the corresponding meta label. + +For example, in a Kubernetes environment, use the following relabel rules: + +```yaml +scrape_configs: + - job_name: 'vitals_statsd_exporter' + kubernetes_sd_configs: + # your SD config to filter statsd exporter pods + relabel_configs: + - source_labels: [__meta_kubernetes_pod_name] + action: replace + target_label: 'instance' +``` + +### Enable Vitals with Prometheus strategy in Kong + +You can change this in your configuration to enable Vitals with Prometheus: + +```bash +# via your Kong configuration file +vitals = on +vitals_strategy = prometheus +vitals_statsd_address = statsd-node:9125 +vitals_tsdb_address = prometheus-node:9090 +``` + +```bash +# or via environment variables +export KONG_VITALS=on +export KONG_VITALS_STRATEGY=prometheus +export KONG_VITALS_STATSD_ADDRESS=statsd-node:9125 +export KONG_VITALS_TSDB_ADDRESS=prometheus-node:9090 +``` + +{:.note} +> **Note**: In Hybrid Mode, configure [`vitals_strategy`](/gateway/{{page.kong_version}}/reference/configuration/#vitals_strategy) +and [`vitals_tsdb_address`](/gateway/{{page.kong_version}}/reference/configuration/#vitals_tsdb_address) +on both the control plane and all data planes. + +Please update `statsd-node` and `prometheus-node` with the actual hostname that +runs StatsD exporter and Prometheus. + +As with other Kong configurations, your changes take effect on `kong reload` or +`kong restart`. + +If you set `scrape_interval` in Prometheus other than the default value of `5` +seconds, you will also need to update the following: + +```bash +# via your Kong configuration file +vitals_prometheus_scrape_interval = new_value_in_seconds +``` + +```bash +# or via environment variables +export KONG_VITALS_PROMETHEUS_SCRAPE_INTERVAL=new_value_in_seconds +``` + +The above option configures `interval` parameter when querying Prometheus. +The value `new_value_in_seconds` should be equal or larger than +`scrape_interval` config in Prometheus. + +You can also configure Kong to send StatsD events with a different prefix from +the default value of `kong`. Make sure the prefix in statsd.rules +is same as that in Kong configuration: + +```bash +# via your Kong configuration file +vitals_statsd_prefix = kong-vitals +``` + +```bash +# or via environment variables +export KONG_VITALS_STATSD_PREFIX=kong-vitals +``` + +```yaml +# in statsd.rules +mappings: +# by API +- match: kong-vitals.api.*.request.count + name: "kong_requests_proxy" + labels: + job: "kong_metrics" +# follows other metrics +# ... +``` + +### Install Grafana dashboard + +If you use Grafana, you can import the Kong Vitals Prometheus dashboard to visualize the data. + +In your Grafana installation, click the **+** button in the sidebar, and choose **Import**. + +On the **Import** screen, find the **Grafana.com Dashboard** field and enter `11870`. Then, click **Load**. Optionally, you +can also download the JSON model from [https://grafana.com/grafana/dashboards/11870](https://grafana.com/grafana/dashboards/11870) and import it manually. + +On the next screen, select the **Prometheus** datasource that is configured to scrape `statsd-exporter`, then +click **Import**. + +## Tuning and Optimization + +### StatsD exporter UDP buffer + +As the amount of concurrent requests increases, the length of the queue to store +unprocessed UDP events will grow as well. +It's necessary to increase the UDP read buffer size to avoid possible packet +dropping. + +To increase the UDP read buffer for the StatsD exporter process, run the binary +using the following example to set read buffer to around 3 MB: + +``` +./statsd_exporter --statsd.mapping-config=statsd.rules.yaml \ + --statsd.listen-unixgram='' \ + --statsd.read-buffer=30000000 +``` + +To increase the UDP read buffer for the host that's running, adding the +following example line to `/etc/sysctl.conf`: + +``` +net.core.rmem_max = 60000000 +``` + +And then apply the setting with root privilege: + +``` +# sysctl -p +``` + +### StatsD exporter with Unix domain socket + +It is possible to further reduce network overhead by deploying StatsD exporter +on the same node with Kong and let the exporter listen on local Unix domain +socket. + +```bash +./statsd_exporter --statsd.mapping-config=statsd.rules.yaml \ + --statsd.read-buffer=30000000 \ + --statsd.listen-unixgram='/tmp/statsd.sock' +``` + +By default the socket is created with permission `0755`, so that StatsD exporter + has to be running with the same user with Kong to allow Kong to write UDP + packets to the socket. To allow the exporter and Kong to run as different + users, the socket can be created with permission `0777` with the following: + +```bash +./statsd_exporter --statsd.mapping-config=statsd.rules.yaml \ + --statsd.read-buffer=30000000 \ + --statsd.listen-unixgram='/tmp/statsd.sock' \ + --statsd.unixsocket-umask="777" +``` + +## Exported Metrics + +With the above configuration, the Prometheus StatsD exporter will make available all +metrics as provided by the [standard Vitals configuration](/api/vitals.yaml). + +Additionally, the exporter process provides access to the default metrics exposed by the [Golang +Prometheus client library](https://prometheus.io/docs/guides/go-application/). These metric names +include the `go_` and `process_` prefixes. These data points are related specifically +to the StatsD exporter process itself, not Kong. Infrastructure teams may find this data +useful, but they are of limited value with respect to monitoring Kong behavior. + +## Accessing Vitals metrics from Prometheus + +You can also access Kong Vitals metrics in Prometheus and display on Grafana +or setup alerting rules. With the example StatsD mapping rules, all metrics are +labeled with `exported_job=kong_vitals`. With the above Prometheus scrape config +above, all metrics are also labeled with `job=vitals_statsd_exporter`. diff --git a/src/gateway/kong-enterprise/analytics/reports.md b/src/gateway/kong-enterprise/analytics/reports.md new file mode 100644 index 000000000000..2edbeca75094 --- /dev/null +++ b/src/gateway/kong-enterprise/analytics/reports.md @@ -0,0 +1,49 @@ +--- +title: Vitals Reports +badge: enterprise +--- + +Browse, filter, and view your data in a Vitals time-series report, and export the data into a comma-separated values (CSV) file. + +When generating a Vitals report, you can: +* Generate a report across all Workspaces or a single Workspace. +* Filter report parameters, such as object, metric, metric type, and values. +* Select the time period or interval for the report, such as minutes, hours, or days. +* View a line chart that automatically generates depending on the selected criteria. +* Export your report to a CSV file. + + +## Prerequisites + +InfluxDB database installed and configured. For more information, see +[Vitals with InfluxDB](/gateway/{{page.kong_version}}/kong-enterprise/analytics/influx-strategy/). + +**Important**: The Vitals Reports feature is not compatible with a Postgres or Cassandra database. If using one of these databases, the Reports button will not display on the Vitals view. + + +## Generate a Vitals Report + +To create a time-series report containing Vitals data, complete the steps in this section. + +1. On the Vitals view, click the **Reports** button. + +2. On the Reports page select the **Timeframe**, up to 12 hours, for which you want to create the report. + +3. Select the report criteria for the report: + + | Selection | Description | + |--------------------------|----------------------------------------------------------------------------------------------| + | *Report Type* | Consumer Requests: This report is for requests made by Consumers.
      Service Requests: This report is for services with a Service ID and name of the service that is stored in the {{site.base_gateway}} database.
      Cluster Latency: This report is the aggregation of two fields. | + | *Scope* | Drill down and filter for more detailed information. | + | *Interval* | Select the time interval to display in the report: weeks, hours, days, minutes. If you select an interval that is out of the available range, the results return zeroes. | + + +4. A Vitals report generates, starting with a summary of data in your report, including Id, Name, App Name, App Id, and Total. Note that the App Name and App Id are dependent on the Dev Portal App Registration plugin. For more information about status codes (2XX, 4XX, etc), see [_Vitals Metrics_](/gateway/{{page.kong_version}}/kong-enterprise/analytics/metrics/). + +5. To download your report, click **Export**. A CSV file containing your Vitals report data downloads to your system. + +## Export Vitals Data to a CSV Report + +1. Create a Vitals report, as defined above in [Generate a Vitals Report](#generate-a-vitals-report). + +2. Click **Export** to download a CSV file to your system. diff --git a/src/gateway/kong-enterprise/analytics/vitalsSpec.yaml b/src/gateway/kong-enterprise/analytics/vitalsSpec.yaml new file mode 100644 index 000000000000..2cbcf24c9dfb --- /dev/null +++ b/src/gateway/kong-enterprise/analytics/vitalsSpec.yaml @@ -0,0 +1,847 @@ +swagger: '2.0' +info: + description: Vitals API + version: 2.4.0 + title: Vitals API +basePath: / +tags: + - name: health + description: Stats about the health of a Kong cluster + - name: traffic + description: Stats about traffic routed through Kong +schemes: + - http +paths: + /vitals: + get: + tags: + - vitals + summary: Get information about stats collected + description: '' + operationId: getVitalsInfo + produces: + - application/json + responses: + '200': + description: successful operation + schema: + $ref: '#/definitions/VitalsInfo' + /vitals/cluster: + get: + tags: + - health + summary: Get health stats for this Kong cluster + description: '' + operationId: getClusterStats + produces: + - application/json + parameters: + - name: interval + in: query + description: Granularity of the time series (days, minutes or seconds) + required: true + type: string + - name: start_ts + in: query + description: Requested start of the time series, in Unix epoch format (seconds) + required: false + type: string + - name: end_ts + in: query + description: Requested end of the time series, in Unix epoch format (seconds) + required: false + type: string + responses: + '200': + description: successful operation + schema: + $ref: '#/definitions/ClusterVitalsTimeSeriesWithMetadata' + '400': + description: Invalid query params + /vitals/cluster/status_codes: + get: + deprecated: true + tags: + - traffic + summary: Get the status code classes returned across the cluster + description: This operation is deprecated. Use /status_code_classes. + operationId: getClusterStatusCodeStats + produces: + - application/json + parameters: + - name: interval + in: query + description: Granularity of the time series (days, minutes or seconds) + required: true + type: string + - name: start_ts + in: query + description: Requested start of the time series, in Unix epoch format (seconds) + required: false + type: string + - name: end_ts + in: query + description: Requested end of the time series, in Unix epoch format (seconds) + required: false + type: string + responses: + '200': + description: successful operation + schema: + $ref: '#/definitions/ClusterVitalsStatusCodesWithMetadata' + '400': + description: Invalid query params + /vitals/nodes: + get: + tags: + - health + summary: Get health stats for all nodes + description: '' + operationId: getAllNodeStats + produces: + - application/json + parameters: + - name: interval + in: query + description: Granularity of the time series (days, minutes or seconds) + required: true + type: string + - name: start_ts + in: query + description: Requested start of the time series, in Unix epoch format (seconds) + required: false + type: string + - name: end_ts + in: query + description: Requested end of the time series, in Unix epoch format (seconds) + required: false + type: string + responses: + '200': + description: successful operation + schema: + $ref: '#/definitions/NodeVitalsTimeSeriesWithMetadata' + '400': + description: Invalid query params + '/vitals/nodes/{node_id}': + get: + tags: + - health + summary: Get stats for a specific node by UUID + description: '' + operationId: getNodeStatsByID + produces: + - application/json + parameters: + - name: node_id + type: string + in: path + description: Node to retrieve stats for + required: true + - name: interval + in: query + description: Granularity of the time series (days, minutes or seconds) + required: true + type: string + - name: start_ts + in: query + description: Requested start of the time series, in Unix epoch format (seconds) + required: false + type: string + - name: end_ts + in: query + description: Requested end of the time series, in Unix epoch format (seconds) + required: false + type: string + responses: + '200': + description: successful operation + schema: + $ref: '#/definitions/NodeVitalsTimeSeriesWithMetadata' + '400': + description: Invalid query params + '404': + description: Unable to find requested node + '/{workspace_name}/vitals/consumers/{consumer_id}/cluster': + get: + tags: + - traffic + deprecated: true + summary: Get count of requests for the given consumer across entire cluster + description: This operation is deprecated. Use /vitals/status_codes/by_consumer_and_route + operationId: getConsumerClusterStats + produces: + - application/json + parameters: + - name: workspace_name + type: string + in: path + description: Workspace containing the requested consumer. + required: true + - name: consumer_id + type: string + in: path + description: Consumer to retrieve stats for + required: true + - name: interval + type: string + in: query + description: Granularity of the time series (days, minutes or seconds) + required: true + - name: start_ts + in: query + description: Requested start of the time series, in Unix epoch format (seconds) + required: false + type: string + - name: end_ts + in: query + description: Requested end of the time series, in Unix epoch format (seconds) + required: false + type: string + responses: + '200': + description: successful operation + schema: + $ref: '#/definitions/ClusterConsumersTimeSeriesWithMetadata' + '400': + description: Invalid query params + '404': + description: Unable to find requested consumer + /{workspace_name}/vitals/status_code_classes: + get: + tags: + - traffic + summary: Get status code classes for a cluster or workspace. + description: '' + operationId: getStatusCodeClassesByWorkspace + produces: + - application/json + parameters: + - name: workspace_name + type: string + in: path + description: >- + Optional parameter. If provided, returns status code classes for the + workspace; otherwise, returns them for the cluster + required: true + - name: interval + type: string + in: query + description: Granularity of the time series (days, minutes or seconds) + required: true + - name: start_ts + in: query + description: Requested start of the time series, in Unix epoch format (seconds) + required: false + type: string + - name: end_ts + in: query + description: Requested end of the time series, in Unix epoch format (seconds) + required: false + type: string + responses: + '200': + description: successful operation + schema: + $ref: '#/definitions/StatusCodesByEntityMetadata' + '400': + description: Invalid query params + '404': + description: Unable to find requested consumer + /{workspace_name}/vitals/status_codes/by_service: + get: + tags: + - traffic + summary: Get a time series of status codes returned by a given service + description: '' + operationId: getStatusCodesByService + produces: + - application/json + parameters: + - name: service_id + type: string + in: query + description: Service to retrieve status codes for + required: true + - name: interval + type: string + in: query + description: Granularity of the time series (days, minutes or seconds) + required: true + - name: start_ts + in: query + description: Requested start of the time series, in Unix epoch format (seconds) + required: true + type: string + - name: end_ts + in: query + description: Requested end of the time series, in Unix epoch format (seconds) + required: true + type: string + - name: workspace_name + type: string + in: path + description: Workspace containing the requested service. + required: true + responses: + '200': + description: successful operation + schema: + $ref: '#/definitions/StatusCodesByEntityTimeSeriesWithMetadata' + '400': + description: Invalid query params + '404': + description: Unable to find requested service + /{workspace_name}/vitals/status_codes/by_route: + get: + tags: + - traffic + summary: Get cluster-wide count of status for a given route + description: '' + operationId: getStatusCodesByRoute + produces: + - application/json + parameters: + - name: route_id + type: string + in: query + description: Route to retrieve status codes for + required: true + - name: interval + type: string + in: query + description: Granularity of the time series (days, minutes or seconds) + required: true + - name: start_ts + in: query + description: Requested start of the time series, in Unix epoch format (seconds) + required: true + type: string + - name: end_ts + in: query + description: Requested end of the time series, in Unix epoch format (seconds) + required: true + type: string + - name: workspace_name + type: string + in: path + description: Workspace containing the requested route. + required: true + responses: + '200': + description: successful operation + schema: + $ref: '#/definitions/StatusCodesByEntityTimeSeriesWithMetadata' + '400': + description: Invalid query params + '404': + description: Unable to find requested route + /{workspace_name}/vitals/status_codes/by_consumer: + get: + tags: + - traffic + summary: Get cluster-wide count of status for a given consumer + description: '' + operationId: getStatusCodesByRoute + produces: + - application/json + parameters: + - name: consumer_id + type: string + in: query + description: Route to retrieve status codes for + required: true + - name: interval + type: string + in: query + description: Granularity of the time series (days, minutes or seconds) + required: true + - name: start_ts + in: query + description: Requested start of the time series, in Unix epoch format (seconds) + required: true + type: string + - name: end_ts + in: query + description: Requested end of the time series, in Unix epoch format (seconds) + required: true + type: string + - name: workspace_name + type: string + in: path + description: Workspace containing the requested consumer. + required: true + responses: + '200': + description: successful operation + schema: + $ref: '#/definitions/StatusCodesByEntityTimeSeriesWithMetadata' + '400': + description: Invalid query params + '404': + description: Unable to find requested route + '/{workspace_name}/vitals/status_codes/by_consumer_and_route': + get: + tags: + - traffic + summary: >- + Get status codes for all the routes called by the given consumer in the + given timeframe + description: '' + operationId: getStatusCodesByConsumerAndRoute + produces: + - application/json + parameters: + - name: consumer_id + type: string + in: query + description: Consumer to retrieve status codes for + required: true + - name: interval + type: string + in: query + description: Granularity of the time series (days, minutes or seconds) + required: true + - name: start_ts + in: query + description: Requested start of the time series, in Unix epoch format (seconds) + required: false + type: string + - name: end_ts + in: query + description: Requested end of the time series, in Unix epoch format (seconds) + required: false + type: string + - name: workspace_name + type: string + in: path + description: Workspace containing the requested consumer and route. + required: true + responses: + '200': + description: successful operation + schema: + $ref: '#/definitions/StatusCodesByEntityTimeSeriesWithMetadata' + '400': + description: Invalid query params + '404': + description: Unable to find requested consumer +definitions: + ClusterVitalsMetadata: + properties: + level: + type: string + example: cluster + enum: + - cluster + - node + workspace_id: + type: string + description: UUID of workspace this time series is for + interval: + type: string + example: seconds + enum: + - seconds + - minutes + - days + interval_width: + type: number + example: 60 + earliest_ts: + type: integer + example: 1514508300 + latest_ts: + type: integer + example: 1514508480 + stat_labels: + type: array + items: + type: string + example: + - cache_datastore_hits_total + - cache_datastore_misses_total + - latency_proxy_request_min_ms + - latency_proxy_request_max_ms + - latency_upstream_min_ms + - latency_upstream_max_ms + - requests_proxy_total + - latency_proxy_request_avg_ms + - latency_upstream_avg_ms + StatusCodesByEntityMetadata: + properties: + entity_type: + type: string + example: service|route + entity_id: + type: string + example: + level: + type: string + example: cluster + enum: + - cluster + workspace_id: + type: string + description: UUID of the workspace this time series is for + interval: + type: string + example: seconds + enum: + - seconds + - minutes + - days + interval_width: + type: number + example: 60 + earliest_ts: + type: integer + example: 1514508300 + latest_ts: + type: integer + example: 1514508480 + stat_labels: + type: array + items: + type: string + example: + - status_codes_service|route_total + StatusCodesByEntityTimeSeriesWithMetadata: + type: object + properties: + meta: + $ref: '#/definitions/StatusCodesByEntityMetadata' + stats: + $ref: '#/definitions/StatusCodesByEntityStats' + ClusterVitalsStatusCodesMetadata: + properties: + level: + type: string + example: cluster + enum: + - cluster + interval: + type: string + example: seconds + enum: + - seconds + - minutes + - days + interval_width: + type: number + example: 60 + earliest_ts: + type: integer + example: 1514508300 + latest_ts: + type: integer + example: 1514508480 + stat_labels: + type: array + items: + type: string + example: + - status_code_classes_total + ClusterVitalsStats: + properties: + cluster: + type: object + properties: + : + type: array + items: + type: integer + description: >- + List of stat values collected at "timestamp_n", in same order as + "meta.stat_labels" + example: + - 999 + - 130 + - 0 + - 35 + - 142 + - 528 + - 1146 + - 110 + - 156 + StatusCodesByEntityStats: + properties: + cluster: + type: object + description: Vitals status codes data available at the cluster level + properties: + : + type: object + properties: + : + type: integer + description: >- + The total count of a particular status code for the time + period + example: 1824 + ClusterVitalsStatusCodesStats: + properties: + cluster: + type: object + description: Vitals status codes data available at the cluster level + properties: + : + type: object + properties: + : + type: integer + description: >- + The total count of a particular status code class for the time + period + example: 1824 + ClusterVitalsTimeSeriesWithMetadata: + type: object + properties: + meta: + $ref: '#/definitions/ClusterVitalsMetadata' + stats: + $ref: '#/definitions/ClusterVitalsStats' + ClusterVitalsStatusCodesWithMetadata: + type: object + properties: + meta: + $ref: '#/definitions/ClusterVitalsStatusCodesMetadata' + stats: + $ref: '#/definitions/ClusterVitalsStatusCodesStats' + ClusterConsumersMetadata: + properties: + level: + type: string + example: cluster + enum: + - cluster + - node + interval: + type: string + example: seconds + enum: + - seconds + - minutes + - days + interval_width: + type: number + example: 60 + earliest_ts: + type: integer + example: 1514508300 + latest_ts: + type: integer + example: 1514508480 + stat_labels: + type: array + items: + type: string + example: + - requests_consumer_total + ClusterConsumersStats: + properties: + cluster: + type: object + properties: + : + type: integer + description: >- + List of stat values collected at "timestamp_n", in same order as + "meta.stat_labels" + example: 47 + ClusterConsumersTimeSeriesWithMetadata: + type: object + properties: + meta: + $ref: '#/definitions/ClusterConsumersMetadata' + stats: + $ref: '#/definitions/ClusterConsumersStats' + NodeVitalsMetadata: + properties: + level: + type: string + example: node + enum: + - cluster + - node + workspace_id: + type: string + description: UUID of the workspace this time series is for + interval: + type: string + example: seconds + enum: + - seconds + - minutes + - days + interval_width: + type: number + example: 60 + earliest_ts: + type: integer + example: 1514508300 + latest_ts: + type: integer + example: 1514508480 + stat_labels: + type: array + items: + type: string + example: + - cache_datastore_hits_total + - cache_datastore_misses_total + - latency_proxy_request_min_ms + - latency_proxy_request_max_ms + - latency_upstream_min_ms + - latency_upstream_max_ms + - requests_proxy_total + - latency_proxy_request_avg_ms + - latency_upstream_avg_ms + nodes: + type: object + description: >- + table of node ids that contributed to this time series. This element + is not included on cluster-level requests. + properties: + : + type: object + description: The id of a node included in this time series. + properties: + hostname: + type: string + description: The name of the host where this node runs + NodeVitalsStats: + properties: + : + type: object + description: >- + The node this time series is for, or "cluster" if it's a cluster-level + time series. + properties: + : + type: array + items: + type: integer + description: >- + List of stat values collected at "timestamp_n", in same order as + "meta.stat_labels" + example: + - 999 + - 130 + - 0 + - 35 + - 142 + - 528 + - 1146 + - 110 + - 156 + NodeVitalsTimeSeriesWithMetadata: + type: object + properties: + meta: + $ref: '#/definitions/NodeVitalsMetadata' + stats: + $ref: '#/definitions/NodeVitalsStats' + VitalsInfo: + type: object + example: + stats: + cache_datastore_hits_total: + levels: + cluster: + intervals: + days: + retention_period_seconds: 63072000 + minutes: + retention_period_seconds: 90000 + seconds: + retention_period_seconds: 3600 + nodes: + intervals: + days: + retention_period_seconds: 63072000 + minutes: + retention_period_seconds: 90000 + seconds: + retention_period_seconds: 3600 + properties: + stats: + type: object + properties: + : + type: object + properties: + levels: + type: object + description: >- + Vitals data is tracked and aggregated at different levels (per + cluster, per node) + properties: + cluster: + type: object + description: Vitals data available at the cluster level + properties: + intervals: + type: object + description: >- + Vitals data is available at different intervals + (seconds, minutes, days) + properties: + days: + type: object + properties: + retention_period_seconds: + type: integer + description: >- + Configured retention period (in seconds) for + the days interval + minutes: + type: object + properties: + retention_period_seconds: + type: integer + description: >- + Configured retention period (in seconds) for + the minutes interval + seconds: + type: object + properties: + retention_period_seconds: + type: integer + description: >- + Configured retention period (in seconds) for + the seconds interval + nodes: + type: object + description: Vitals data available at the node level + properties: + intervals: + type: object + description: >- + Vitals data is available at different intervals + (seconds, minutes, days) + properties: + days: + type: object + properties: + retention_period_seconds: + type: integer + description: >- + Configured retention period (in seconds) for + the days interval + minutes: + type: object + properties: + retention_period_seconds: + type: integer + description: >- + Configured retention period (in seconds) for + the minutes interval + seconds: + type: object + properties: + retention_period_seconds: + type: integer + description: >- + Configured retention period (in seconds) for + the seconds interval diff --git a/src/gateway/kong-enterprise/audit-log.md b/src/gateway/kong-enterprise/audit-log.md new file mode 100644 index 000000000000..b96527d5b022 --- /dev/null +++ b/src/gateway/kong-enterprise/audit-log.md @@ -0,0 +1,497 @@ +--- +title: Admin API Audit Log +badge: enterprise +--- + +{{site.base_gateway}} provides a granular logging facility on its Admin API. This +allows cluster administrators to keep detailed track of changes made to the +cluster configuration throughout its lifetime, aiding in compliance efforts and +providing valuable data points during forensic investigations. Generated audit +log trails are [Workspace](/gateway/{{page.kong_version}}/admin-api/workspaces/reference) and [RBAC](/gateway/{{page.kong_version}}/admin-api/rbac/reference)-aware, +providing Kong operators a deep and wide look into changes happening within +the cluster. + +## Getting Started + +Audit logging is disabled by default. It is configured via the Kong configuration (e.g. `kong.conf`): + +```bash +audit_log = on # audit logging is enabled +audit_log = off # audit logging is disabled +``` + +or via environment variables: + +```bash +export KONG_AUDIT_LOG=on +export KONG_AUDIT_LOG=off +``` + +As with other Kong configurations, changes take effect on `kong reload` or `kong +restart`. + +## Request Audits + +### Generating and Viewing Audit Logs + +Audit logging provides granular details of each HTTP request that was handled by +Kong's Admin API. Audit log data is written to Kong's back database. As a result, +request audit logs are available via the Admin API (in addition to via direct +database query). For example, consider a query to the Admin API to the `/status` +endpoint: + +``` +vagrant@ubuntu-xenial:/kong$ http :8001/status +HTTP/1.1 200 OK +Access-Control-Allow-Origin: * +Connection: keep-alive +Content-Type: application/json; charset=utf-8 +Date: Tue, 13 Nov 2018 17:32:47 GMT +Server: kong/0.34-enterprise-edition +Transfer-Encoding: chunked +X-Kong-Admin-Request-ID: ZuUfPfnxNn7D2OTU6Xi4zCnQkavzMUNM + +{ + "database": { + "reachable": true + }, + "server": { + "connections_accepted": 1, + "connections_active": 1, + "connections_handled": 1, + "connections_reading": 0, + "connections_waiting": 0, + "connections_writing": 1, + "total_requests": 1 + } +} +``` + +The above interaction with the Admin API generates a correlating entry in +the audit log table. Querying the audit log via Admin API returns the details of the interaction above: + +``` +http :8001/audit/requests +HTTP/1.1 200 OK +Access-Control-Allow-Origin: * +Connection: keep-alive +Content-Type: application/json; charset=utf-8 +Date: Tue, 13 Nov 2018 17:35:24 GMT +Server: kong/0.34-enterprise-edition +Transfer-Encoding: chunked +X-Kong-Admin-Request-ID: VXgMG1Y3rZKbjrzVYlSdLNPw8asVwhET + +{ + "data": [ + { + "client_ip": "127.0.0.1", + "method": "GET", + "path": "/status", + "payload": null, + "request_id": "ZuUfPfnxNn7D2OTU6Xi4zCnQkavzMUNM", + "request_timestamp": 1581617463, + "signature": null, + "status": 200, + "ttl": 2591995, + "workspace": "0da4afe7-44ad-4e81-a953-5d2923ce68ae" + } + ], + "total": 1 +} +``` + +Note the value of the `request_id` field. This is tied to the +`X-Kong-Admin-Request-ID` response header received in the first transaction. +This allows close association of client requests and audit log records within +the Kong cluster. + +Because every audit log entry is made available via Kong's Admin API, it is +possible to transport audit log entries into existing logging warehouses, SIEM +solutions, or other remote services for duplication and inspection. + +### Workspaces and RBAC + +Audit log entries are written with an awareness of the requested Workspace, and +the RBAC user (if present). When RBAC is enforced, the RBAC user's UUID will be +written to the `rbac_user_id` field in the audit log entry: + +``` +{ + "data": [ + { + "client_ip": "127.0.0.1", + "method": "GET", + "path": "/status", + "payload": null, + "rbac_user_id": "2e959b45-0053-41cc-9c2c-5458d0964331", + "request_id": "QUtUa3RMbRLxomqcL68ilOjjl68h56xr", + "request_timestamp": 1581617463, + "signature": null, + "status": 200, + "ttl": 2591995, + "workspace": "0da4afe7-44ad-4e81-a953-5d2923ce68ae" + } + ], + "total": 1 +} +``` + +Note also the presence of the `workspace` field. This is the UUID of the Workspace with which the request was associated. + +### Limiting Audit Log Generation + +It may be desirable to ignore audit log generation for certain Admin API +requests such as innocuous requests to the `/status` endpoint for +healthchecking or to ignore requests for a given path prefix (e.g. a given +Workspace). To this end, the `audit_log_ignore_methods` and +`audit_log_ignore_paths` configuration options are presented: + +```bash +audit_log_ignore_methods = GET,OPTIONS +# do not generate an audit log entry for GET or OPTIONS HTTP requests +audit_log_ignore_paths = /foo,/status,^/services,/routes$,/one/.+/two,/upstreams/ +# do not generate an audit log entry for requests that match the above regular expressions +``` + +The values of `audit_log_ignore_paths` are matched via a Perl-compatible regular expression. + +For example, when `audit_log_ignore_paths = /foo,/status,^/services,/routes$,/one/.+/two,/upstreams/`, the following request paths do not generate an audit-log entry in the databse: + +- `/status` +- `/status/` +- `/foo` +- `/foo/` +- `/services` +- `/services/example/` +- `/one/services/two` +- `/one/test/two` +- `/routes` +- `/plugins/routes` +- `/one/routes/two` +- `/upstreams/` +- `bad400request` + +The following request paths generate an audit log entry in the database: + +- `/example/services` +- `/routes/plugins` +- `/one/two` +- `/routes/` +- `/upstreams` + +### Audit Log Retention + +Request audit records are kept in the database for a duration defined by the +`audit_log_record_ttl` [Kong configuration property](/gateway/{{page.kong_version}}/reference/configuration/#audit_log_record_ttl). +Records in the database older than `audit_log_record_ttl` seconds are automatically +purged. In Cassandra databases, record deletion is handled automatically via the +Cassandra TTL mechanism. In Postgres databases, records are purged via the stored +procedure that is executed on insert into the record database. Thus, request +audit records may exist in the database longer than the configured TTL, if no new +records are inserted to the audit table following the expiration timestamp. + +## Database Audits + +### Generating and Viewing Audit Logs + +In addition to Admin API request data, Kong will generate granular audit log +entries for all insertions, updates, and deletions to the cluster database. +Database update audit logs are also associated with Admin API request unique +IDs. Consider the following request to create a Consumer: + +``` +http :8001/consumers username=bob +HTTP/1.1 201 Created +Access-Control-Allow-Origin: * +Connection: keep-alive +Content-Type: application/json; charset=utf-8 +Date: Tue, 13 Nov 2018 17:50:18 GMT +Server: kong/0.34-enterprise-edition +Transfer-Encoding: chunked +X-Kong-Admin-Request-ID: 59fpTWlpUtHJ0qnAWBzQRHRDv7i5DwK2 + +{ + "created_at": 1542131418000, + "id": "16787ed7-d805-434a-9cec-5e5a3e5c9e4f", + "type": 0, + "username": "bob" +} + +``` + +As seen before, a request audit log is generated with details about the request. +Note the presence of the `payload` field, recorded when the request body is +present: + +``` +http :8001/audit/requests +HTTP/1.1 200 OK +Access-Control-Allow-Origin: * +Connection: keep-alive +Content-Type: application/json; charset=utf-8 +Date: Tue, 13 Nov 2018 17:52:41 GMT +Server: kong/0.34-dev-enterprise-edition +Transfer-Encoding: chunked +X-Kong-Admin-Request-ID: SpPaxLTkDNndzKaYiWuZl3xrxDUIiGRR + +{ + "data": [ + { + "client_ip": "127.0.0.1", + "method": "POST", + "path": "/consumers", + "payload": "{\"username\": \"bob\"}", + "request_id": "59fpTWlpUtHJ0qnAWBzQRHRDv7i5DwK2", + "request_timestamp": 1581617463, + "signature": null, + "status": 201, + "ttl": 2591995, + "workspace": "fd51ce6e-59c0-4b6b-b991-aa708a9ff4d2" + } + ], + "total": 1 +} +``` + +Additionally, audit logs are generated to track the creation of the +database entity: + +``` +http :8001/audit/objects +HTTP/1.1 200 OK +Access-Control-Allow-Origin: * +Connection: keep-alive +Content-Type: application/json; charset=utf-8 +Date: Tue, 13 Nov 2018 17:53:27 GMT +Server: kong/0.34-dev-enterprise-edition +Transfer-Encoding: chunked +X-Kong-Admin-Request-ID: ZKra3QT0d3eJKl96jOUXYueLumo0ck8c + +{ + "data": [ + { + "dao_name": "consumers", + "entity": "{\"created_at\":1542131418000,\"id\":\"16787ed7-d805-434a-9cec-5e5a3e5c9e4f\",\"username\":\"bob\",\"type\":0}", + "entity_key": "16787ed7-d805-434a-9cec-5e5a3e5c9e4f", + "expire": 1544723418009, + "id": "7ebabee7-2b09-445d-bc1f-2092c4ddc4be", + "operation": "create", + "request_id": "59fpTWlpUtHJ0qnAWBzQRHRDv7i5DwK2", + "request_timestamp": 1581617463, + }, + ], + "total": 1 +} +``` + +Object audit entries contain information about the entity updated, including the +entity body itself, its database primary key, and the type of operation +performed (`create`, `update`, or `delete`). Note also the associated + `request_id` field. + +### Limiting Audit Log Generation + +As with request audit logs, it may be desirable to skip generation of audit logs +for certain database tables. This is configurable via the +`audit_log_ignore_tables` Kong config option: + +``` +audit_log_ignore_tables = consumers +# do not generate database audit logs for changes to the consumers table +``` + +### Audit Log Retention + +Database audit records are kept in the database for a duration defined by the +`audit_log_record_ttl` [Kong configuration property](/gateway/{{page.kong_version}}/reference/configuration/#audit_log_record_ttl). +Records in the database older than `audit_log_record_ttl` seconds are automatically +purged. In Cassandra databases, record deletion is handled automatically via the +Cassandra TTL mechanism. In Postgres databases, records are purged via the stored +procedure that is executed on insert into the record database. Thus, database +audit records may exist in the database longer than the configured TTL, if no new +records are inserted to the audit table following the expiration timestamp. + +## Digital Signatures + +To provide non-repudiation, audit logs may be signed with a private RSA key. When +enabled, a lexically sorted representation of each audit log entry is signed by +the defined private key; the signature is stored in an additional field within +the record itself. The public key should be stored elsewhere and can be used +later to validate the signature of the record. + +### Setting Up Log Signing + +Generate a private key via the `openssl` tool: + +```bash +openssl genrsa -out private.pem 2048 +``` + +Extract the public key for future audit verification: + +``` +openssl rsa -in private.pem -outform PEM -pubout -out public.pem +``` + +Configure Kong to sign audit log records: + +``` +audit_log_signing_key = /path/to/private.pem +``` + +Audit log entries will now contain a field `signature`: + +``` +{ + "client_ip": "127.0.0.1", + "method": "GET", + "path": "/status", + "payload": null, + "request_id": "Ka2GeB13RkRIbMwBHw0xqe2EEfY0uZG0", + "request_timestamp": 1581617463, + "signature": "l2LWYaRIHfXglFa5ehFc2j9ijfERazxisKVtJnYa+QUz2ckcytxfOLuA4VKEWHgY7cCLdn5C7uRJzE6es5V2SoOV59NOpskkr5lTt9kzao64UEw5UNOdeZYZKwyhG9Ge7IsxTK6haW0iG3a9dHqlKlwvnHZTbFM8TUV/umg8sJ1QJ/5ivXecbyHYtD5luKAI6oEgIdZPtQexRkwxlzvfR8lzeC/dDc2slSrjWRbBxNFlgfRKhDdVzVzgu8pEucgKggu67PKLkJ+bQEkxX1+Yg3czIpJyC3t6cgoggb0UNtBq1uUpswe0wdueKh6G5Gzz6XrmOjlv7zSz4gtVyEHZgg==", + "status": 200, + "ttl": 2591995, + "workspace": "fd51ce6e-59c0-4b6b-b991-aa708a9ff4d2" +} +``` + +### Validating Signatures + +To verify record signatures, use the `openssl` utility, or other cryptographic +tools that are capable of validating RSA digital signatures. + +Signatures are generated using a 256-bit SHA digest. The following example +demonstrates how to verify the audit log record shown above. First, store the +record signature on disk after stripping the Base64 +encoding: + +```bash +cat < record_signature +> l2LWYaRIHfXglFa5ehFc2j9ijfERazxisKVtJnYa+QUz2ckcytxfOLuA4VKEWHgY7cCLdn5C7uRJzE6es5V2SoOV59NOpskkr5lTt9kzao64UEw5UNOdeZYZKwyhG9Ge7IsxTK6haW0iG3a9dHqlKlwvnHZTbFM8TUV/umg8sJ1QJ/5ivXecbyHYtD5luKAI6oEgIdZPtQexRkwxlzvfR8lzeC/dDc2slSrjWRbBxNFlgfRKhDdVzVzgu8pEucgKggu67PKLkJ+bQEkxX1+Yg3czIpJyC3t6cgoggb0UNtBq1uUpswe0wdueKh6G5Gzz6XrmOjlv7zSz4gtVyEHZgg== +> EOF +``` + +Next, the audit record must be transformed into its canonical format used for +signature generation. This transformation requires serializing the record into +a string format that can be verified. The format is a lexically-sorted, +pipe-delimited string of each audit log record part, _without_ the `signature`, +`ttl`, or `expire` fields. The following is a canonical +implementation written in Lua: + +```lua +local cjson = require "cjson" +local pl_sort = require "pl.tablex".sort + +local function serialize(data) + local p = {} + + data.signature = nil + data.expire = nil + data.ttl = nil + + for k, v in pl_sort(data) do + if type(v) == "table" then + p[#p + 1] = serialize(v) + elseif v ~= cjson.null then + p[#p + 1] = v + end + end + + return p +end + +table.concat(serialize(data), "|") +``` + +For example, the canonical format of the audit record above is: + +``` +cat canonical_record.txt +127.0.0.1|1544724298663|GET|/status|Ka2GeB13RkRIbMwBHw0xqe2EEfY0uZG0|1542132298664|200|fd51ce6e-59c0-4b6b-b991-aa708a9ff4d2 +``` + +
      +Ensure that the contents of the canonical record file on disk match the expected +canonical record format exactly. The presence of any addditional bytes, such as +a trailing newline `\n`, will cause a validation failure in the next step. +
      + +Once these two elements are in place, the signature can be verified: + +```bash +openssl dgst -sha256 -verify public.pem -signature record_signature canonical_record.txt +Verified OK +``` + +--- + +## Reference + +### API Reference + +#### List Request Audit Logs + +##### Endpoint + +
      /audit/requests
      + +##### Response + +``` +HTTP 200 OK +``` + +```json +{ + "data": [ + { + "client_ip": "127.0.0.1", + "method": "GET", + "path": "/status", + "payload": null, + "request_id": "ZuUfPfnxNn7D2OTU6Xi4zCnQkavzMUNM", + "request_timestamp": 1581617463, + "signature": null, + "status": 200, + "ttl": 2591995, + "workspace": "0da4afe7-44ad-4e81-a953-5d2923ce68ae" + } + ], + "total": 1 +} +``` + +#### List Database Audit Logs + +##### Endpoint + +
      /audit/objects
      + +##### Response + +``` +HTTP 200 OK +``` + +```json +{ + "data": [ + { + "dao_name": "consumers", + "entity": "{\"created_at\":1542131418000,\"id\":\"16787ed7-d805-434a-9cec-5e5a3e5c9e4f\",\"username\":\"bob\",\"type\":0}", + "entity_key": "16787ed7-d805-434a-9cec-5e5a3e5c9e4f", + "expire": 1544723418009, + "id": "7ebabee7-2b09-445d-bc1f-2092c4ddc4be", + "operation": "create", + "request_id": "59fpTWlpUtHJ0qnAWBzQRHRDv7i5DwK2" + }, + ], + "total": 1 +} +``` + +### Configuration Reference + +See the [Data & Admin Audit](/gateway/{{page.kong_version}}/reference/configuration/#data--admin-audit) +section of the Configuration Property Reference. diff --git a/src/gateway/kong-enterprise/consumer-groups/index.md b/src/gateway/kong-enterprise/consumer-groups/index.md new file mode 100644 index 000000000000..e3b657697bf3 --- /dev/null +++ b/src/gateway/kong-enterprise/consumer-groups/index.md @@ -0,0 +1,745 @@ +--- +title: Consumer Groups Examples +badge: enterprise +--- + +With consumer groups, you can define any number of rate limiting tiers and +apply them to subsets of consumers, instead of managing each consumer +individually. + +For example, you could define three consumer groups: +* A "gold tier" with 1000 requests per minute +* A "silver tier" with 10 requests per second +* A "bronze tier" with 6 requests per second + +The `consumer_groups` endpoint works together with the [Rate Limiting Advanced plugin](/hub/kong-inc/rate-limiting-advanced). + +Consumers that are not in a consumer group default to the Rate Limiting advanced +plugin’s configuration, so you can define tier groups for some users and +have a default behavior for consumers without groups. + +To use consumer groups for rate limiting, you need to: +* Create one or more consumer groups +* Create consumers +* Assign consumers to groups +* Configure the Rate Limiting Advanced plugin with the `enforce_consumer_groups` +and `consumer_groups` parameters, setting up the list of consumer groups that +the plugin accepts +* Configure rate limiting for each consumer group, overriding the plugin's +configuration + +For all possible requests, see the +[Consumer Groups reference](/gateway/{{page.kong_version}}/admin-api/consumer-groups/reference). + +{:.note} +> **Note:** Consumer groups are not supported in declarative configuration with +decK. If you have consumer groups in your configuration, decK will ignore them. + +## Set up consumer group + +1. Create a consumer group named `JL`: + +{% capture create_consumer_group %} +{% navtabs codeblock %} +{% navtab cURL %} +```bash +curl -i -X POST http://{HOSTNAME}:8001/consumer_groups \ + --data name=JL +``` +{% endnavtab %} +{% navtab HTTPie %} +```bash +http POST :8001/consumer_groups name=JL +``` +{% endnavtab %} +{% endnavtabs %} +{% endcapture %} + +{{ create_consumer_group | indent | replace: " ", "" }} + + Response: + + ```json + { + "created_at": 1638915521, + "id": "8a4bba3c-7f82-45f0-8121-ed4d2847c4a4", + "name": "JL" + } + ``` + +1. Create a consumer, `DianaPrince`: + +{% capture create_consumer %} +{% navtabs codeblock %} +{% navtab cURL %} +```bash +curl -i -X POST http://{HOSTNAME}:8001/consumers \ + --data username=DianaPrince +``` +{% endnavtab %} +{% navtab HTTPie %} +```bash +http POST :8001/consumers username=DianaPrince +``` +{% endnavtab %} +{% endnavtabs %} +{% endcapture %} + +{{ create_consumer | indent | replace: " ", "" }} + + Response: + + ```json + { + "created_at": 1638915577, + "custom_id": null, + "id": "8089a0e6-1d31-4e00-bf51-5b902899b4cb", + "tags": null, + "type": 0, + "username": "DianaPrince", + "username_lower": "dianaprince" + } + ``` + +1. Add `DianaPrince` to the `JL` consumer group: + +{% capture add_consumer %} +{% navtabs codeblock %} +{% navtab cURL %} +```bash +curl -i -X POST http://{HOSTNAME}:8001/consumer_groups/JL/consumers \ + --data consumer=DianaPrince +``` +{% endnavtab %} +{% navtab HTTPie %} +```bash +http POST :8001/consumer_groups/JL/consumers consumer=DianaPrince +``` +{% endnavtab %} +{% endnavtabs %} +{% endcapture %} + +{{ add_consumer | indent | replace: " ", "" }} + + Response: + + ```json + { + "consumer_group": { + "created_at": 1638915521, + "id": "8a4bba3c-7f82-45f0-8121-ed4d2847c4a4", + "name": "JL" + }, + "consumers": [ + { + "created_at": 1638915577, + "id": "8089a0e6-1d31-4e00-bf51-5b902899b4cb", + "type": 0, + "username": "DianaPrince", + "username_lower": "dianaprince" + } + ] + } + ``` + +## Set up Rate Limiting Advanced config for consumer group + +1. Enable the [Rate Limiting Advanced plugin](/hub/kong-inc/rate-limiting-advanced), +setting the rate limit to five requests (`config.limit`) for every +30 seconds (`config.window_size`): + +{% capture add_plugin %} +{% navtabs codeblock %} +{% navtab cURL %} +```bash +curl -i -X POST http://{HOSTNAME}:8001/plugins/ \ + --data name=rate-limiting-advanced \ + --data config.limit=5 \ + --data config.window_size=30 \ + --data config.window_type=sliding \ + --data config.retry_after_jitter_max=0 \ + --data config.enforce_consumer_groups=true \ + --data config.consumer_groups=JL +``` +{% endnavtab %} +{% navtab HTTPie %} +```bash +http -f :8001/plugins/ \ + name=rate-limiting-advanced \ + config.limit=5 \ + config.window_size=30 \ + config.window_type=sliding \ + config.retry_after_jitter_max=0 \ + config.enforce_consumer_groups=true \ + config.consumer_groups=JL +``` +{% endnavtab %} +{% endnavtabs %} +{% endcapture %} + +{{ add_plugin | indent | replace: " ", "" }} + + For consumer groups, the following parameters are required: + * `config.enforce_consumer_groups=true`: enables consumer groups for this plugin. + * `config.consumer_groups=JL`: specifies a list of groups that this plugin allows overrides for. + + {:.note} + > **Note:** In this example, you're configuring the plugin globally, so it + applies to all entities (Services, Routes, and Consumers) in the + {{site.base_gateway}} instance. You can also apply it to a + [specific Service or Route](/hub/kong-inc/rate-limiting-advanced) + for more granular control. + +1. The plugin you just set up applies to all consumers in the cluster. Change +the rate limiting configuration for the `JL` consumer group only, setting +the limit to ten requests for every ten seconds: + +{% capture override %} +{% navtabs codeblock %} +{% navtab cURL %} +```bash +curl -i -X PUT http://{HOSTNAME}:8001/consumer_groups/JL/overrides/plugins/rate-limiting-advanced \ + --data config.limit=10 \ + --data config.window_size=10 \ + --data config.retry_after_jitter_max=1 +``` +{% endnavtab %} +{% navtab HTTPie %} +```bash +http PUT :8001/consumer_groups/JL/overrides/plugins/rate-limiting-advanced \ + config.limit=10 \ + config.window_size=10 \ + config.retry_after_jitter_max=1 +``` +{% endnavtab %} +{% endnavtabs %} +{% endcapture %} + +{{ override | indent | replace: " ", "" }} + + Response: + + ```json + { + "config": { + "limit": [ + 10 + ], + "retry_after_jitter_max": 1, + "window_size": [ + 10 + ] + }, + "consumer_group": "JL", + "plugin": "rate-limiting-advanced" + } + ``` + +1. Check that it worked by looking at the `JL` consumer group object: + +{% capture check_group1 %} +{% navtabs codeblock %} +{% navtab cURL %} +```bash +curl -i -X GET http://{HOSTNAME}:8001/consumer_groups/JL +``` +{% endnavtab %} +{% navtab HTTPie %} +```bash +http :8001/consumer_groups/JL +``` +{% endnavtab %} +{% endnavtabs %} +{% endcapture %} + +{{ check_group1 | indent | replace: " ", "" }} + + Notice the `plugins` object in the response, along with the parameters that you + just set for the Rate Limiting Advanced plugin: + + ```json + { + "consumer_group": { + "created_at": 1638915521, + "id": "8a4bba3c-7f82-45f0-8121-ed4d2847c4a4", + "name": "JL" + }, + "consumers": [ + { + "created_at": 1638915577, + "id": "8089a0e6-1d31-4e00-bf51-5b902899b4cb", + "type": 0, + "username": "DianaPrince", + "username_lower": "dianaprince" + } + ], + "plugins": [ + { + "config": { + "limit": [ + 10 + ], + "retry_after_jitter_max": 1, + "window_size": [ + 10 + ], + "window_type": "sliding" + }, + "consumer_group": { + "id": "8a4bba3c-7f82-45f0-8121-ed4d2847c4a4" + }, + "created_at": 1638916518, + "id": "b7c426a2-6fcc-4bfd-9b7a-b66e8f1ad260", + "name": "rate-limiting-advanced" + } + ] + } + ``` + +## Remove consumer from group - group view + +You can remove a consumer from a group by accessing `/consumers` or +`/consumer_groups`. The following steps use `/consumer_groups`. + +1. Check the `JL` consumer group for the consumer name: + +{{ check_group1 | indent | replace: " ", "" }} + + Response: + + ```json + { + "consumer_group": { + "created_at": 1638915521, + "id": "8a4bba3c-7f82-45f0-8121-ed4d2847c4a4", + "name": "JL" + }, + "consumers": [ + { + "created_at": 1638915577, + "id": "8089a0e6-1d31-4e00-bf51-5b902899b4cb", + "type": 0, + "username": "DianaPrince", + "username_lower": "dianaprince" + } + ] + } + ``` + +1. Using the username or ID of the consumer (`DianaPrince` in this example), +remove the consumer from the group: + +{% capture delete_consumer1 %} +{% navtabs codeblock %} +{% navtab cURL %} +```bash +curl -i -X DELETE http://{HOSTNAME}:8001/consumer_groups/JL/consumers/DianaPrince +``` +{% endnavtab %} +{% navtab HTTPie %} +```bash +http DELETE :8001/consumer_groups/JL/consumers/DianaPrince +``` +{% endnavtab %} +{% endnavtabs %} +{% endcapture %} + +{{ delete_consumer1 | indent | replace: " ", "" }} + + If successful, you receive the following response: + ``` + HTTP/1.1 204 No Content + ``` + +1. To verify, check the consumer group configuration again: + +{{ check_group1 | indent | replace: " ", "" }} + + Response, with no consumers assigned: + + ```json + { + "consumer_group": { + "created_at": 1638917780, + "id": "be4bcfca-b1df-4fac-83cc-5cf6774bf48e", + "name": "JL" + } + } + ``` + +## Remove consumer from group - consumer view + +You can remove a consumer from a group by accessing `/consumers` or +`/consumer_groups`. The following steps use `/consumers`. + +1. If you know the consumer name and not the consumer group name, +you can look up the group through the consumer: + +{% capture check_group2 %} +{% navtabs codeblock %} +{% navtab cURL %} +```bash +curl -i -X GET http://{HOSTNAME}:8001/consumers/DianaPrince/consumer_groups +``` +{% endnavtab %} +{% navtab HTTPie %} +```bash +http :8001/consumers/DianaPrince/consumer_groups +``` +{% endnavtab %} +{% endnavtabs %} +{% endcapture %} + +{{ check_group2 | indent | replace: " ", "" }} + + Response: + + ```json + { + "consumer_groups": [ + { + "created_at": 1638915521, + "id": "8a4bba3c-7f82-45f0-8121-ed4d2847c4a4", + "name": "JL" + } + ] + } + ``` + +1. Using the username or ID of the group (`JL` in this example), +remove the consumer from the group: + +{% capture delete_consumer2 %} +{% navtabs codeblock %} +{% navtab cURL %} +```bash +curl -i -X DELETE http://{HOSTNAME}:8001/consumers/DianaPrince/consumer_groups/JL +``` +{% endnavtab %} +{% navtab HTTPie %} +```bash +http DELETE :8001/consumers/DianaPrince/consumer_groups/JL +``` +{% endnavtab %} +{% endnavtabs %} +{% endcapture %} + +{{ delete_consumer2 | indent | replace: " ", "" }} + + If successful, you receive the following response: + ``` + HTTP/1.1 204 No Content + ``` + +1. To verify, check the consumer object configuration: + +{{ check_group1 | indent | replace: " ", "" }} + + Response, with no consumers assigned: + + ```json + { + "consumer_group": { + "created_at": 1638917780, + "id": "be4bcfca-b1df-4fac-83cc-5cf6774bf48e", + "name": "JL" + } + } + ``` + + +## Delete consumer group + +If you don't need a consumer group anymore, you can delete it. This removes +all consumers from the group, and deletes the group itself. The consumers in +the group are not deleted. + +1. Delete a consumer group using the following request: + +{% capture delete_consumer2 %} +{% navtabs codeblock %} +{% navtab cURL %} +```bash +curl -i -X DELETE http://{HOSTNAME}:8001/consumer_groups/JL +``` +{% endnavtab %} +{% navtab HTTPie %} +```bash +http DELETE :8001/consumer_groups/JL +``` +{% endnavtab %} +{% endnavtabs %} +{% endcapture %} + +{{ delete_consumer2 | indent | replace: " ", "" }} + + If successful, you receive see the following response: + ``` + HTTP/1.1 204 No Content + ``` + +1. Check the list of consumer groups to verify that the `JL` group is gone: + +{% capture check_all_groups %} +{% navtabs codeblock %} +{% navtab cURL %} +```bash +curl -i -X GET http://{HOSTNAME}:8001/consumer_groups +``` +{% endnavtab %} +{% navtab HTTPie %} +```bash +http :8001/consumer_groups +``` +{% endnavtab %} +{% endnavtabs %} +{% endcapture %} + +{{ check_all_groups | indent | replace: " ", "" }} + + Response: + ```json + { + "data": [], + "next": null + } + ``` + +1. Check a consumer that was in the group to make sure it still exists: + +{% capture check_consumer %} +{% navtabs codeblock %} +{% navtab cURL %} +```bash +curl -i -X GET http://{HOSTNAME}:8001/consumers/DianaPrince +``` +{% endnavtab %} +{% navtab HTTPie %} +```bash +http :8001/consumers/DianaPrince +``` +{% endnavtab %} +{% endnavtabs %} +{% endcapture %} + +{{ check_consumer | indent | replace: " ", "" }} + + An `HTTP/1.1 200 OK` response means the consumer exists. + + +## Manage multiple consumers + +You can perform many `/consumer_groups` operations in bulk. + +1. Assuming you deleted the group `JL` in the previous section, create it again, +along with another group named `Speedsters`: + +{% capture create_consumer_group2 %} +{% navtabs codeblock %} +{% navtab cURL %} +```bash +curl -i -X POST http://{HOSTNAME}:8001/consumer_groups \ + --data name=JL + +curl -i -X POST http://{HOSTNAME}:8001/consumer_groups \ + --data name=Speedsters +``` +{% endnavtab %} +{% navtab HTTPie %} +```bash +http POST :8001/consumer_groups name=JL + +http POST :8001/consumer_groups name=Speedsters +``` +{% endnavtab %} +{% endnavtabs %} +{% endcapture %} + +{{ create_consumer_group2 | indent | replace: " ", "" }} + +1. Create two consumers, `BarryAllen` and `WallyWest`: + +{% capture create_two_consumers %} +{% navtabs codeblock %} +{% navtab cURL %} +```bash +curl -i -X POST http://{HOSTNAME}:8001/consumers \ + --data username=BarryAllen + +curl -i -X POST http://{HOSTNAME}:8001/consumers \ + --data username=WallyWest +``` +{% endnavtab %} +{% navtab HTTPie %} +```bash +http POST :8001/consumers username=BarryAllen + +http POST :8001/consumers username=WallyWest +``` +{% endnavtab %} +{% endnavtabs %} +{% endcapture %} + +{{ create_two_consumers | indent | replace: " ", "" }} + +1. Add both consumers to the `Speedsters` group: +{% capture add_two_consumers %} +{% navtabs codeblock %} +{% navtab cURL %} +```bash +curl -i -X POST http://{HOSTNAME}:8001/consumer_groups/Speedsters/consumers \ + --data consumer=BarryAllen \ + --data consumer=WallyWest +``` +{% endnavtab %} +{% navtab HTTPie %} +```bash +http POST :8001/consumer_groups/Speedsters/consumers \ + consumer:='["BarryAllen", "WallyWest"]' +``` +{% endnavtab %} +{% endnavtabs %} +{% endcapture %} + +{{ add_two_consumers | indent | replace: " ", "" }} + + {{site.base_gateway}} validates the provided list of consumers before assigning + them to the consumer group. To pass validation, consumers must exist and must + not be in the group already. + + If any consumer fails validation, no consumers are assigned to the group. + + Response, if everything is successful: + + ```json + { + "consumer_group": { + "created_at": 1639432267, + "id": "a905151a-5767-40e8-804e-50eec4d0235b", + "name": "Speedsters" + }, + "consumers": [ + { + "created_at": 1639432286, + "id": "ea904e1d-1f0d-4d5a-8391-cae60cb21d61", + "type": 0, + "username": "BarryAllen", + "username_lower": "barryallen" + }, + { + "created_at": 1639432288, + "id": "065d8249-6fe6-4d80-a0ae-f159caef7af0", + "type": 0, + "username": "WallyWest", + "username_lower": "wallywest" + } + ] + } + ``` + +1. You can clear all consumers from a group with one request. This may be useful +if you need to cycle the group for a new batch of users. + + For example, delete all consumers from the `Speedsters` group: + +{% capture delete_all_consumers %} +{% navtabs codeblock %} +{% navtab cURL %} +```bash +curl -i -X DELETE http://{HOSTNAME}:8001/consumer_groups/Speedsters/consumers +``` +{% endnavtab %} +{% navtab HTTPie %} +```bash +http DELETE :8001/consumer_groups/Speedsters/consumers +``` +{% endnavtab %} +{% endnavtabs %} +{% endcapture %} + +{{ delete_all_consumers | indent | replace: " ", "" }} + + Response: + ``` + HTTP/1.1 204 No Content + ``` + +1. You can also add a consumer to multiple groups: + * If all groups are allowed by the Rate Limiting Advanced plugin, + only the first group's settings apply. + * Otherwise, whichever group is specified in the Rate Limiting Advanced + plugin becomes active. + + Add `BarryAllen` to two groups, `JL` and `Speedsters`: + +{% capture add_consumer_many_groups %} +{% navtabs codeblock %} +{% navtab cURL %} +```bash +curl -i -X POST http://{HOSTNAME}:8001/consumers/BarryAllen/consumer_groups \ + --data group=JL \ + --data group=Speedsters +``` +{% endnavtab %} +{% navtab HTTPie %} +```bash +http POST :8001/consumers/BarryAllen/consumer_groups \ + group:='["JL", "Speedsters"]' +``` +{% endnavtab %} +{% endnavtabs %} +{% endcapture %} + +{{ add_consumer_many_groups | indent | replace: " ", "" }} + + The response should look something like this: + + ```json + { + "consumer": { + "created_at": 1639436091, + "custom_id": null, + "id": "6098d577-6741-4cf8-9c86-e68057b8f970", + "tags": null, + "type": 0, + "username": "BarryAllen", + "username_lower": "barryallen" + }, + "consumer_groups": [ + { + "created_at": 1639432267, + "id": "a905151a-5767-40e8-804e-50eec4d0235b", + "name": "JL" + }, + { + "created_at": 1639436107, + "id": "2fd2bdd6-690c-4e49-8296-31f55015496d", + "name": "Speedsters" + } + ] + } + ``` + +1. Finally, you can also remove a consumer from all groups: + +{% capture add_consumer_many_groups %} +{% navtabs codeblock %} +{% navtab cURL %} +```bash +curl -i -X DELETE http://{HOSTNAME}:8001/consumers/BarryAllen/consumer_groups +``` +{% endnavtab %} +{% navtab HTTPie %} +```bash +http DELETE :8001/consumers/BarryAllen/consumer_groups +``` +{% endnavtab %} +{% endnavtabs %} +{% endcapture %} + +{{ add_consumer_many_groups | indent | replace: " ", "" }} + + Response: + ``` + HTTP/1.1 204 No Content + ``` diff --git a/src/gateway/kong-enterprise/db-encryption.md b/src/gateway/kong-enterprise/db-encryption.md new file mode 100644 index 000000000000..1e04a630c04f --- /dev/null +++ b/src/gateway/kong-enterprise/db-encryption.md @@ -0,0 +1,415 @@ +--- +title: Keyring and Data Encryption +badge: enterprise +--- + +{{site.base_gateway}} provides a mechanism to store sensitive data fields, such as consumer secrets, in an encrypted format within the database. This provides for encryption-at-rest security controls in a Kong cluster. + +This functionality provides transparent, symmetric encryption of sensitive data fields at rest. _Transparency_ refers to the fact that, when enabled, encryption/decryption of data is done on-the-fly by Kong immediately before writing/immediately after reading from the database. Responses generated by the Admin API containing sensitive fields continue to show data as plaintext, and runtime elements of Kong (such as plugins) that require access to sensitive fields do so transparently, without requiring additional configuration. + +## Getting Started + +This document provides a brief introduction to leveraging {{site.base_gateway}} symmetric database encryption to store sensitive configuration data in a Kong cluster. This document covers necessary Kong configuration settings and key management lifecycle procedures when using database encryption in `cluster` mode. This mode offers the simplest method to getting started, as it requires no external dependencies. + +### Generate a Management RSA Key Pair + +Before enabling database encryption, we strongly recommend you generate an RSA key pair for use in exporting and recovering keyring material. If keyring material is lost, it is impossible to recover any sensitive data fields written to the database with a key on that keyring. + +Generating an RSA key pair is straightforward via the `openssl` CLI: + +```bash +openssl genrsa -out key.pem 2048 +openssl rsa -in key.pem -pubout -out cert.pem +``` + +This key pair will be provided to Kong in order to facilitate recovering, exporting, and re-importing the keyring. The public `cert.pem` and private `key.pem` should be stored securely in accordance with your existing secrets management policies. Details on secure storage of RSA key pairs are outside the scope of this documentation. + +### Configure Kong for database encryption + +Enabling data encryption in Kong requires modifying the Kong configuration. Set the following values in `kong.conf`: + +``` +keyring_enabled = on +keyring_strategy = cluster +keyring_recovery_public_key = /path/to/generated/cert.pem +``` + +Or via environmental variables: + +``` +export KONG_KEYRING_ENABLED=on +export KONG_KEYRING_STRATEGY=cluster +export KONG_KEYRING_RECOVERY_PUBLIC_KEY=/path/to/generated/cert.pem +``` + +All nodes in the Kong cluster should share the same `keyring_enabled` and `keyring_strategy` configuration values. +The generated private key `key.pem` is not required to configure Kong, or to start Kong. Please refer to the [disaster recovery](#disaster-recovery) section for more information on how to use private keys in keyring management. + +### Start Kong + +Once all Kong nodes in the cluster have been configured, start each node: + +```bash +kong start +``` + +When encryption is enabled on a Kong node, it checks the status of the cluster keyring on boot. If it detects that no keys are present in the keyring, it will generate a key automatically. This process allows encryption/decryption operations to begin immediately. + +For all other nodes, the generated key will be automatically distributed within a few seconds. + +Note that encryption keys are held _only_ in memory, and do not persist past a restart of the Kong process (e.g., running `kong restart`). Because of this limitation, you must [recover](#recover-the-keyring) or [import](#import-the-keyring) the keyring following initialization. Otherwise, if all Kong nodes in a cluster restart simultaneously, any sensitive fields written with the keyring become unrecoverable. Key material still persists after a soft reload of Kong (i.e., `kong reload`). + +### Verify the Cluster Keyring + +With the keyring enabled and Kong started, verify the contents of the keyring: + + +```bash +curl -s localhost:8001/keyring | jq +``` + +Response: +```json +{ + "ids": [ + "LaW1urRQ" + ], + "active": "LaW1urRQ" +} +``` + +Note that in this example, the value `LaW1urRQ` is the _ID_ of the key, not the key material itself. + + +### Exercise the Encryption Routines + +Create a Consumer with a basic-auth credential. At this point, the `password` field of the basic-auth credential will be symmetrically encrypted before it is written to the database (in addition to being hashed by the basic-auth plugin, which is done by the plugin regardless of whether keyring encryption is enabled): + +```bash +curl -s localhost:8001/consumers -d username=bob | jq +``` + +Response: +```json +{ + "custom_id": null, + "created_at": 1576518610, + "id": "6375b5fd-9c95-4822-b2dd-80ffbccb7ec9", + "tags": null, + "username": "bob", + "type": 0 +} +``` + +```bash +curl -s localhost:8001/consumers/bob/basic-auth -d username=bob -d password=supersecretpassword | jq +``` + +Response: +```json +{ + "created_at": 1576518704, + "consumer": { + "id": "6375b5fd-9c95-4822-b2dd-80ffbccb7ec9" + }, + "id": "fc46ce48-c1d6-4078-9f51-5a777350a8a2", + "password": "da61c0083b6d19ef3db2490d0da96a71572da0fa", + "username": "bob" +} +``` + +Note that the returned `password` field in the API response is not the encrypted value; database encryption does not modify responses generated by the Admin API. This allows existing workflows to continue in the same form, while providing encryption at rest security under the hood. We can verify this by examining the value stored in the database: + +``` +kong=# select id,password from basicauth_credentials; + id | password +--------------------------------------+--------------------------------------------------------------------------------------------------------------------------- + fc46ce48-c1d6-4078-9f51-5a777350a8a2 | $ke$1$-LaW1urRQ-0f5b1ee8ddeefca1a1d75125-53f158a5f619133a2113692a7057e2b91fa947321de4480d452dd42c36bc9ef8aa6499cd429db6d7 +(1 row) +``` + +We can also verify that reading back the credential after it has been created behaves as expected: + +```bash +curl -s localhost:8001/consumers/bob/basic-auth/fc46ce48-c1d6-4078-9f51-5a777350a8a2 | jq +``` + +Response: +```json +{ + "created_at": 1576518704, + "consumer": { + "id": "6375b5fd-9c95-4822-b2dd-80ffbccb7ec9" + }, + "id": "fc46ce48-c1d6-4078-9f51-5a777350a8a2", + "password": "da61c0083b6d19ef3db2490d0da96a71572da0fa", + "username": "bob" +} +``` + +### Rotating Key Material + +As noted above, Kong supports rotating keys by allowing for multiple keys to exist on the keyring at the same time. This allows for data fields written by one key to be read back, while a fresher encryption key is used for write operations. Rotating keys is a matter of importing or generating a new key into the keyring, and marking it as active. Arbitrary key material can be imported via the `/keyring/import` material, or Kong can generate a new key via `/keyring/generate` endpoint: + +```bash +curl -XPOST -s localhost:8001/keyring/generate +``` + +Response: +```json +{ + "key": "t6NWgbj3g9cbNVC3/D6oZ2Md1Br5gWtRrqb1T2FZy44=", + "id": "8zgITLQh" +} +``` + +Note that as a convenience the raw key material is returned from this endpoint call. + +Once a new key is present in the keyring, activate the key's ID: + +```bash +curl -s localhost:8001/keyring/activate -d key=8zgITLQh +``` + +Kong can write new sensitive data fields with the current `active` key, and read previously written fields in the database with the prior key, provided that key is in the keyring. Kong automatically selects the appropriate key to use when decrypting fields from the database. + +At this point, it is encouraged to take another backup of the keyring via the `/keyring/export` Admin API endpoint. + +### Rotating Encrypted Data Fields + +Once the keyring has updated, existing encrypted fields can rotate to use the new active key. To accomplish this rotation, issue a PATCH request to the entity in question: + +```bash +curl -XPATCH -s localhost:8001/consumers/bob/basic-auth/fc46ce48-c1d6-4078-9f51-5a777350a8a2 -d password=adifferentsecretpassword | jq +``` + +Response: +```json +{ + "created_at": 1576518704, + "consumer": { + "id": "6375b5fd-9c95-4822-b2dd-80ffbccb7ec9" + }, + "id": "fc46ce48-c1d6-4078-9f51-5a777350a8a2", + "password": "cc7274e94e41f3e00c238ff8712d1a83693f2a89", + "username": "bob" +} +``` + +Again, note that the encryption behavior is transparent to the Admin API response. Under the hood, Kong reads the entity's `password` field with a read-only encryption key. As part of the PATCH process, Kong writes the `password` field back to the database with the new `active` key. To verify this process, examine the raw contents of the database: + +``` +kong=# select id,password from basicauth_credentials; + id | password +--------------------------------------+--------------------------------------------------------------------------------------------------------------------------- + fc46ce48-c1d6-4078-9f51-5a777350a8a2 | $ke$1$-8zgITLQh-b8d28531252241e6b95907e4-0768a9a4baaa2c777d9406d4e3098d813be55ae82c4c849182b06b9c5954704c6290c9e677bcd693 +(1 row) +``` + +Note that the key identifier within the password data blob has been updated. This rotation mechanism allows organizations to meet specific compliance needs around key management rotation and retention policies. + +Currently, encrypted fields must undergo a direct write operation in order to rotate the encrypted field. Future releases of Kong may contain helper API operations to automate this process. + +### Exploring Missing Keyring Material Behavior + +As a test, stop all Kong nodes in the cluster, and restart one Kong node again, but do not import the keyring material. The behavior of attempting to read an entity with an encrypted field now changes: + +```bash +time curl -s localhost:8001/consumers/bob/basic-auth/fc46ce48-c1d6-4078-9f51-5a777350a8a2 +``` + +Response: +``` +{"message":"An unexpected error occurred"} +real 0m24.811s +user 0m0.017s +sys 0m0.006s +``` + +When the Kong node restarts, it sends a broadcast request for the keyring, but as no other nodes are present in the cluster (or no other nodes had the keyring available), Kong is unable to decrypt the `password` field on the credential. Because Kong has an eventually-consistent clustering model, it makes several attempts to request the keyring and allows for delays in hearing responses from another cluster node; thus, the request takes several seconds to complete before finally failing. + +## Disaster Recovery + +`cluster` strategy supports two disaster recovery strategies. + +### Automatic backup and manual recovery +To use automatic backups for keyring materials, configure `keyring_recovery_public_key`: + +``` +keyring_recovery_public_key = /path/to/generated/cert.pem +``` + +Or via environmental variables: + +``` +export KONG_KEYRING_RECOVERY_PUBLIC_KEY=/path/to/generated/cert.pem +``` + +#### Recover the Keyring + +The keyring material is then encrypted with the public RSA key defined with the `keyring_recovery_public_key` +Kong configuration value in the database. The corresponding private key can be used to decrypt the keyring material in the database: + +```bash +curl -X POST localhost:8001/keyring/recover -F recovery_private_key=@/path/to/generated/key.pem +``` + +Response: +```json +{ + "message": "successfully recovered 1 keys", + "recovered": [ + "RfsDJ2Ol" + ], + "not_recovered": [ + "xSD219lH" + ] +} +``` + +The response contains a list of keys that were successfully recovered and that could not be recovered. The Kong error log will contain the detailed reason why the keys could not be recovered. + +### Manual export and manual import + +**Use of this method is deprecated in Kong 3.0 and will be removed in a future release.** + +``` +keyring_public_key = /path/to/generated/cert.pem +keyring_private_key = /path/to/generated/key.pem +``` + +Or via environmental variables: + +``` +export KONG_KEYRING_PUBLIC_KEY=/path/to/generated/cert.pem +export KONG_KEYRING_PRIVATE_KEY=/path/to/generated/key.pem +``` + +Not every node needs to be provided the management RSA key pair, as that key pair is only used for backup and recovery processes. It does not need to be present for regular database read/write operations. + +The user that the Kong worker process is running under must have read access to the public and private keys in order to be able to import and export keyrings. This user is defined with the `nginx_user` Kong configuration option. We recommend restricting access to these files, for example: + +```bash +chown : /path/to/generated/cert.pem /path/to/generated/key.pem +chmod 400 /path/to/generated/cert.pem /path/to/generated/key.pem +``` + +When testing, you can set `keyring_blob_path` in kong.conf or `KONG_KEYRING_BLOB_PATH` +using environmental variables to specify a path to dump known keys. The dumped keys are +encrypted with the public RSA key defined in the `keyring_public_key` Kong configuration +value, and are automatically loaded when Kong starts. + +#### Export the Keyring + +Export the keyring. The exported material can be re-imported to the cluster in the event of an outage or to restore a previously-deleted key: + +```bash +curl -XPOST -s localhost:8001/keyring/export | jq +``` + +Response: +```json +{ + "data": "eyJrIjoiV1JZeTdubDlYeFZpR3VVQWtWTXBcL0JiVW1jMWZrWHluc0dKd3N4M1c0MlIxWE5XM05lZ05sdFdIVmJ1d0ZnaVZSTnFSdmM1WERscGY3b0NIZ1ZDQ3JvTFJ4czFnRURhOXpJT0tVV0prM2lhd0VLMHpKTXdwRDd5ZjV2VFYzQTY0Y2UxcVl1emJoSTI4VUZ1ZExRZWljVjd2T3BYblVvU3dOY3IzblhJQWhyWlcxc1grWXE3aHM1RzhLRXY2OWlRamJBTXAwbHZmTWNFWWxTOW9NUjdnSm5xZWlST0J1Q09iMm5tSXg0Qk1uaTJGalZzQzBtd2R2dmJyYWxYa3VLYXhpRWZvQm9EODk3MEtVcDYzY05lWGdJclpjang4YmJDV1lDRHlEVmExdGt5c0g1TjBJM0hTNDRQK1dyT2JkcElCUk5vSVZVNis1QWdcLzdZM290RUdzN1E9PSIsImQiOiIxWEZJOXZKQ05CTW5uVTB5c0hQenVjSG5nc2c5UURxQmcxZ3g1VVYxNWNlOEVTTlZXTmthYm8zdlUzS2VRTURcL0RUYXdzZCtJWHB5SllBTkRtanZNcytqU2lrVTFiRkpyMEVcLzBSRlg2emJrT0oybTR2bXlxdVE9PSIsIm4iOiJUUmRLK01Qajh6MkdHTmtyIn0=" +} + +``` + +The response generated is an opaque blob containing the keyring. This blob is encrypted with +a randomly-generated symmetric key, which is encrypted with the public +RSA key defined via the `keyring_public_key` Kong configuration value. + +The exported keyring should be stored in a safe location for disaster recovery +purposes. It is not designed to be modified or decrypted before being used during +a disaster recovery process. + +#### Import the Keyring + +Restart Kong and re-import the previously exported keyring: + +```bash +kong restart +``` + +```bash +curl localhost:8001/keyring/import -d data= +``` + +This operation requires that the `keyring_private_key` point to the private RSA +key associated with the public key used during the initial keyring export. Once +this is complete, Admin API operations that require the keyring for encryption/ +decryption can be verified: + +```bash +curl -s localhost:8001/consumers/bob/basic-auth/fc46ce48-c1d6-4078-9f51-5a777350a8a2 | jq +``` + +Response: +```json +{ + "created_at": 1576518704, + "consumer": { + "id": "6375b5fd-9c95-4822-b2dd-80ffbccb7ec9" + }, + "id": "fc46ce48-c1d6-4078-9f51-5a777350a8a2", + "password": "da61c0083b6d19ef3db2490d0da96a71572da0fa", + "username": "bob" +} +``` + + +## Implementation Details + +### Encryption/Decryption + +{{site.base_gateway}} uses 256-bit AES encryption in GCM mode. Cryptographic nonce values for each encryption routine execution are derived from the kernel CSPRNG (`/dev/urandom`). The AES routines used by Kong are provided by the OpenSSL library bundled with the {{site.base_gateway}} package. + +### Key Generation and Lifecycle + +{{site.base_gateway}}'s keyring handling mechanisms allow for more than one key to be present on any given Kong node at a time. Each key may be used to read encrypted fields from the database, but one and only one key at any given time is used to write encrypted fields back to the data store. This process allows for a key rotation mechanism wherein new keyring material is introduced, and older keys may be present for a time to allow rotating previously-encrypted fields. + +Through the kernel CSPRNG, Kong derives keyring material generated through the `/keyring/generate` Admin API endpoint. Kong stores keyring material in a shared memory zone that all Kong worker processes access. To prevent key material from being written to disk as part of memory paging operations, we recommend that swap be disabled on systems running Kong + +When operating in `cluster` mode, keyring material propagates automatically among all nodes in the Kong cluster. Because Kong nodes do not have a notion of direct peer-to-peer communication, the underlying datastore serves as a communication channel to transmit messages. When a Kong node starts, it generates an ephemeral RSA key pair. The node's public keys propagate to all other active nodes in the cluster. When an active node sees a message request for keyring material, it wraps the in-memory keyring material in the presented public key, and transmits the payload back over the central messaging channel provided by the underlying data store. This process allows each node in the cluster to broadcast keyring material to new nodes, without sending key material in plaintext over the wire. This model requires that at least one node be running at all times within the cluster; a failure of all nodes requires manually re-importing the keyring to one node during an outage recovery. + +### Encrypted Fields + +The keyring module encrypts the following fields at rest: + +* `key` fields of `certificate` objects (corresponding to the private key of a TLS certificate). +* Certain configuration parameters in plugins and plugin-related authentication +objects. For information on which plugin fields are encrypted, see +[each individual plugin's documentation](/hub/). + +## Vault Integration + +Kong's keyring mechanism can integrate directly with [HashiCorp Vault](https://www.vaultproject.io/) for keyring storage and versioning. In this model, Kong nodes read keyring material directly from a Vault KV secrets engine, rather than generating and disseminating keyring material around the cluster. + +To configure Kong to use Vault for keyring storage, set the `keyring_strategy` configuration value to `vault`. Leveraging Vault also requires defining a host, mount point, and token for Vault access. See the Kong configuration reference for more details. + +### Key Format + +Kong leverages version 2 of the [Vault KV secrets engine](https://www.vaultproject.io/docs/secrets/kv/kv-v2.html). This process allows for the same versioning and key rotation mechanisms that the `cluster` keyring strategy provides. Each version of a KV secrets entry must contain both an `id` field, and a `key` field, e.g.: + +```json +{ + "key": "t6NWgbj3g9cbNVC3/D6oZ2Md1Br5gWtRrqb1T2FZy44=", + "id": "8zgITLQh" +} +``` + +To provide consistent consumption of all Vault KV secrets, the underlying symmetric key is derived as the SHA256 of the `key` component of the secret value. Take note of this derivation when extending or re-using symmetric encryption keys from other systems. This derivation also implies that the `key` field can contain any arbitrary data, as Kong hashes the contents before importing the material into the keyring. + +To provide a new key, add a new version to the Vault secrets engine at the configured path. The `current_version` of the Vault secret denotes the active key in the keyring. See the [KV v2 documentation](https://www.vaultproject.io/docs/secrets/kv/kv-v2.html) for more detail. + +### Vault Permissions + +In order to communicate with Vault, Kong must be provided a Vault token for access. The token must be associated with a policy that allows the `read` and `list` actions on the path where keyring secrets are stored. Kong does not write keyring material to the Vault cluster. + +### Syncing the Keyring + +Kong reads the keyring material from Vault when the Kong process starts. Any changes to the Vault KV store are not reflected on the Kong node until Kong syncs with Vault via the `/keyring/vault/sync` Admin API endpoint. This allows Kong to receive a Vault token with a low TTL, as the list and read operation only occur once. + +### Keyring on hybrid mode + +Because Keyring encrypts the data in the database, it means it doesn't encrypt data on Kong data plane nodes that run without a database and get data from the control plane. However, one can turn on `declarative_config_encryption_mode` within the Kong configuration, or use secrets management to securely store sensitive data on the data plane nodes. diff --git a/src/gateway/kong-enterprise/dev-portal/applications/auth-provider-strategy.md b/src/gateway/kong-enterprise/dev-portal/applications/auth-provider-strategy.md new file mode 100644 index 000000000000..5fd288672c72 --- /dev/null +++ b/src/gateway/kong-enterprise/dev-portal/applications/auth-provider-strategy.md @@ -0,0 +1,103 @@ +--- +title: Authorization Provider Strategy for Application Registration +badge: enterprise +--- + +## Supported Authentication Plugins + +OAuth2 plugins for use with the Application Registration plugin: + +- When {{site.base_gateway}} is the system of record, the Application Registration plugin works + in conjunction with the OAuth2 or the Key Authentication plugin. + +
      + Important: The OAuth2 plugin does not support + hybrid mode. Since the Key Authentication plugin is using the `kong-oauth2` strategy + and client ID credential, hybrid mode is also not supported for the Key + Authentication plugin. If your organization uses hybrid mode, you must use an external identity + provider and configure the OpenID Connect plugin. +
      + +- When an external OAuth2 is the system of record, the Application Registration + plugin works in conjunction with the OpenID Connect plugin. + +The third-party authorization strategy (`external-oauth2`) applies to all +applications across all Workspaces (Dev Portals) in a {{site.base_gateway}} cluster. + +## Authorization provider strategy configuration for Application Registration {#portal-app-auth} + +The `portal_app_auth` configuration option must be set in `kong.conf` to enable +the Dev Portal Application Registration plugin with your chosen +authorization strategy. The default setting (`kong-oauth2`) accommodates the +OAuth2 or Key Authentication plugins. + +Available options: + +* `kong-oauth2`: Default. {{site.base_gateway}} is the system of record. The Application + Registration plugin is used in conjunction with the OAuth2 or + Key Authentication plugin. The `kong-oauth2` option can only be used with + classic (traditional) deployments. Because the OAuth2 plugin requires a database + for every gateway instance, the `kong-oauth2` option cannot be used with hybrid mode + deployments. +* `external-oauth2`: An external IdP is the system of record. The + Portal Application Registration plugin is used in conjunction with the + OIDC plugin. The `external-oauth2` option can be used with any deployment type. + The `external-oauth2` option must be used with + [hybrid mode](/gateway/{{page.kong_version}}/production/deployment-topologies/hybrid-mode/) + deployments because hybrid mode does not support `kong-oauth2`. + +### Set external portal authentication {#set-external-oauth2} + +If you are using an external IdP, follow these steps. + +1. Open `kong.conf.default` and set the `portal_app_auth` option to your chosen + strategy. The example configuration below switches from the default + (`kong-oauth2`) to an external IdP (`external-oauth2`). + + ``` + portal_app_auth = external-oauth2 + # Dev Portal application registration + # auth provider and strategy. Must be set to configure + # authentication in conjunction with the application_registration plugin. + # Currently accepts kong-oauth2 or external-oauth2. + ``` + +2. [Restart](/gateway/{{page.kong_version}}/reference/cli/#kong-restart) your {{site.base_gateway}} + instance. + +## Next Steps + +1. Enable the [Application Registration plugin](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/applications/enable-application-registration) on a Service. + +2. Enable a supported authentication plugin on the same Service as the Application Registration plugin, + as appropriate for your authorization strategy. + + Strategy `kong-oauth2`: + + * If using the `kong-oauth2` authorization strategy with the OAuth2 plugin, configure the + [OAuth2](/hub/kong-inc/oauth2/) plugin on the same Service as the Application Registration plugin. + You can use either the Kong Manager GUI or cURL commands as documented on the [Plugin Hub](/hub/). + The OAuth2 plugin cannot be used in hybrid mode. + * If using the `kong-oauth2` authorization strategy with key authentication, configure the + [Key Auth](/hub/kong-inc/key-auth/) plugin on the same Service as the Application + Registration plugin. You can use either the + [Kong Manager GUI](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/applications/enable-key-auth-plugin) + or cURL commands as documented on the Plugin Hub. The Key Auth plugin + cannot be used in hybrid mode. + + Strategy `external-oauth2`: + + 1. If you plan to use external OAuth2, review the + [recommended workflows](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/authentication/3rd-party-oauth#supported-oauth-flows). + + 2. If using the third-party authorization strategy + (`external-oauth2`), configure the OIDC plugin on the same Service as the + Application Registration plugin. You can use the Kong Manager GUI + or cURL commands as documented on the [Plugin Hub](/hub/kong-inc/openid-connect). + When your deployment is hybrid mode, the OIDC plugin must be configured to handle + authentication for the Portal Application Registration plugin. + + 3. Configure the identity provider for your application, configure your + application in {{site.base_gateway}}, and associate them with each other. See the + [Okta](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/authentication/okta-config) + or the [Azure](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/authentication/azure-oidc-config) setup examples. diff --git a/src/gateway/kong-enterprise/dev-portal/applications/enable-application-registration.md b/src/gateway/kong-enterprise/dev-portal/applications/enable-application-registration.md new file mode 100644 index 000000000000..f914ac4129c8 --- /dev/null +++ b/src/gateway/kong-enterprise/dev-portal/applications/enable-application-registration.md @@ -0,0 +1,91 @@ +--- +title: Enable Application Registration +badge: enterprise +--- + +Application Registration allows registered developers on the Kong Dev Portal to +authenticate with supported Authentication plugins against a Service on Kong. Either {{site.base_gateway}} or +external identity provider admins can selectively admit access to Services using Kong Manager. + +## Prerequisites + +* Dev Portal is enabled on the same Workspace as the Service. +* The Service is created and enabled with HTTPS. +* Authentication is enabled on the Dev Portal. +* Logged in as an admin with read and write roles on applications, services, and + developers. +* The `portal_app_auth` configuration option is configured for your OAuth provider + and strategy (`kong-oauth2` default or `external-oauth2`). See +[Configure the Authorization Provider Strategy](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/applications/auth-provider-strategy) for the Portal Application Registration plugin. +* Authorization provider configured if using a supported third-party + identity provider with the OIDC plugin: + * For example instructions using Okta as an identity provider, refer to the + [Okta example](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/authentication/okta-config). + * For example instructions using Azure AD as an identity provider, refer to the + [Azure example](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/authentication/azure-oidc-config). + +## Enable Application Registration on a Service using Kong Manager {#enable-app-reg-plugin} + +To use Application Registration on a Service, the Portal Application Registration +Plugin must be enabled on a Service. + +In Kong Manager, access the Service for which you want to enable Application Registration: + +1. From your Workspace, in the left navigation pane, go to **API Gateway > Services**. +2. On the Services page, select the Service and click **View**. +3. In the Plugins pane in the Services page, click **Add a Plugin**. +4. On the Add New Plugin page in the Authentication section, find the + **Portal Application Registration** Plugin and click **Enable**. + + ![Portal Application Registration](/assets/images/docs/dev-portal/app-reg-plugin-panel.png) + +5. Enter the configuration settings. Use the parameters in the next section, + [Application Registration Configuration Parameters](#application-registration-configuration-parameters), + to complete the fields. + + ![Create application-registration plugin](/assets/images/docs/dev-portal/create-app-reg-plugin-form.png) + + **Important:** Exposing + the Issuer URL is essential for the + [Authorization Code Flow](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/authentication/3rd-party-oauth/#ac-flow) + workflow configured for third-party identity providers. + + ![Issuer URL](/assets/images/docs/dev-portal/dev-portal-issuer-url.png) + +6. Click **Create**. + +### Application Registration Configuration Parameters {#app-reg-params} + +| Form Parameter | Description | +|:---------------|:----------------------------------------------------------------------------------| +| `Service` | The Service that this plugin configuration will target. Required. | +| `Tags` | A set of strings for grouping and filtering, separated by commas. Optional. | +| `Auto Approve` | If enabled, all new Service contract requests are automatically approved. Otherwise, Dev Portal admins must manually approve requests. Default: `false`. | +| `Description` | Description displayed in the information about a Service in the Dev Portal. Optional. | +| `Display Name` | Unique name displayed in the information about a Service in the Dev Portal. Required. | +| `Show Issuer` | Displays the Issuer URL in the Service Details page. Default: `false`. **Important:** Exposing the **Issuer URL** is essential for the [Authorization Code Flow](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/authentication/3rd-party-oauth/#ac-flow) workflow configured for third-party identity providers. | + +## Next steps + +Kong OAuth2 strategy: + +* If using the Kong-managed authorization strategy +(`kong-oauth2`) with the OAuth2 plugin, configure the Kong [OAuth2](/hub/kong-inc/oauth2/) +plugin as appropriate for your authorization requirements. You can use either the +Kong Manager GUI or cURL commands as documented on the [Plugin Hub](/hub/). +The OAuth2 plugin cannot be used in hybrid mode. +* If using the Kong-managed authorization strategy +(`kong-oauth2`) with key authentication, configure the Kong +[Key Auth](/hub/kong-inc/key-auth/) plugin as appropriate for your authorization +requirements. You can use either the +[Kong Manager GUI](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/applications/enable-key-auth-plugin) +or cURL commands as documented on the Plugin Hub. The Key Auth plugin +cannot be used in hybrid mode. + +External OAuth2 strategy: + +* If using the third-party authorization strategy +(`external-oauth2`), configure the OIDC plugin. You can use the Kong Manager GUI +or cURL commands as documented on the [Plugin Hub](/hub/kong-inc/openid-connect). +When your deployment is hybrid mode, the OIDC plugin must be configured to handle +authentication for the Portal Application Registration plugin. diff --git a/src/gateway/kong-enterprise/dev-portal/applications/enable-key-auth-plugin.md b/src/gateway/kong-enterprise/dev-portal/applications/enable-key-auth-plugin.md new file mode 100644 index 000000000000..e52e76cd0414 --- /dev/null +++ b/src/gateway/kong-enterprise/dev-portal/applications/enable-key-auth-plugin.md @@ -0,0 +1,137 @@ +--- +title: Enable Key Authentication for Application Registration +badge: enterprise +--- + +You can use the Key Authentication plugin for authentication in conjunction with +the Application Registration plugin. + +The key auth plugin uses the same Client ID as generated for the Kong OAuth2 plugin. +You can use the same Client ID credential for a Service that has the OAuth2 plugin enabled. + +## Prerequisites + +* Create a Service. +* Enable the [Application Registration plugin](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/applications/enable-application-registration) on a Service. +* Activate your application for a Service if you have not already done so. The +Service Contract must be approved by an Admin if auto approve is not enabled. +* [Generate a credential](#gen-client-id-cred) if you don't want to use the default credential initially created for you. + +## Enable Key Authentication in Kong Manager + +In Kong Manager, access the Service for which you want to enable key authentication for +use with application registration: + +1. From your Workspace, in the left navigation pane, go to **API Gateway > Services**. +2. On the Services page, select the Service and click **View**. +3. In the Plugins pane in the Services page, click **Add a Plugin**. +4. On the Add New Plugin page in the Authentication section, find the + **Key Authentication** Plugin and click **Enable**. + + ![Key Authentication plugin panel](/assets/images/docs/dev-portal/key-auth-plugin-panel.png) + +5. Complete the fields as appropriate for your application. In this example, the Service is already + prepopulated. Refer to the parameters described in the next section, + [Key Authentication Configuration Parameters](#key-auth-params), + to complete the fields. + +6. Click **Create**. + +### Key Authentication Configuration Parameters {#key-auth-params} + +| Form Parameter | Description | +|:---------------|:----------------------------------------------------------------------------------| +| `Service` | The Service that this plugin configuration will target. Required. | +| `Anonymous` | An optional string (Consumer UUID) value to use as an anonymous Consumer if authentication fails. If empty (default), the request fails with an `4xx`. Note that this value must refer to the Consumer `id` attribute that is internal to Kong, and **not** its `custom_id`. | +| `Hide Credentials` | Whether to show or hide the credential from the Upstream service. If `true`, the plugin strips the credential from the request (i.e., the header, query string, or request body containing the key) before proxying it. Default: `false`. | +| `Key in Body` | If enabled, the plugin reads the request body (if said request has one and its MIME type is supported) and tries to find the key in it. Supported MIME types: `application/www-form-urlencoded`, `application/json`, and `multipart/form-data`. Default: `false`. | +| `Key in Header` | If enabled (default), the plugin reads the request header and tries to find the key in it. Default: true. | +| `Key in Query` | If enabled (default), the plugin reads the query parameter in the request and tries to find the key in it. Default: true. | +| `Key Names` | Describes an array of parameter names where the plugin will look for a key. The client must send the authentication key in one of those key names, and the plugin will try to read the credential from a header, request body, or query string parameter with the same name. The key names may only contain [a-z], [A-Z], [0-9], [_] underscore, and [-] hyphen. Required. Default: `apikey`. | +| `Run on Preflight` | Indicates whether the plugin should run (and try to authenticate) on `OPTIONS` preflight requests. Default: `true`. | + +## Generate a Credential {#gen-client-id-cred} + +Generate a Client ID credential to use as an API key. You can generate multiple +credentials. + +1. In the **Dev Portal > My Apps** page, click **View** for an application. + +2. In the **Authentication** pane, click **Generate Credential**. + + ![Application Authentication Pane](/assets/images/docs/dev-portal/generate-cred-dev-portal.png) + + Now you can make requests using the Client ID as an API Key. + +## Make Requests with an API Key (Client Identifier) + +The Client ID of your credentials can be used as an API key to make authenticated requests to a Service. + +**Tip:** You can also access key request instructions directly within the user interface from the +information icon in the Services details area of your application. Click the **i** icon to open the Service Details page. + +![Services Pane](/assets/images/docs/dev-portal/portal-info-modal-key-auth.png) + +Scroll to view all of the available examples. + +![Service Details Page Embedded Key Usage Instructions](/assets/images/docs/dev-portal/service-details-key-auth-usage.png) + +### About API Key Locations in a Request + +{% include /md/plugins-hub/api-key-locations.md %} + +### Make a request with the key as a query string parameter + +{% navtabs codeblock %} +{% navtab cURL %} +```bash +curl -X POST {proxy}/{route}?apikey={CLIENT_ID} +``` +{% endnavtab %} +{% navtab HTTPie %} +```bash +http {proxy}/{route}?apikey={CLIENT_ID} +``` +{% endnavtab %} +{% endnavtabs %} + +Response (will be the same for all valid requests regardless of key location): + +```bash +HTTP/1.1 200 OK +... +``` + +### Make a request with the key in a header + +{% navtabs codeblock %} +{% navtab cURL %} +```bash +curl -X POST {proxy}/{route} \ +--header "apikey: {CLIENT_ID}" +``` +{% endnavtab %} +{% navtab HTTPie %} +```bash +http {proxy}/{route} apikey:{CLIENT_ID} +``` +{% endnavtab %} +{% endnavtabs %} + +### Make a request with the key in the body + +{% navtabs codeblock %} +{% navtab cURL %} +```bash +curl -X POST {proxy}/{route} \ +--data "apikey:={CLIENT_ID}" +``` +{% endnavtab %} +{% navtab HTTPie %} +```bash +http {proxy}/{route} apikey={CLIENT_ID} +``` +{% endnavtab %} +{% endnavtabs %} + +**Note:** The `key_in_body` parameter must be set to `true`. diff --git a/src/gateway/kong-enterprise/dev-portal/applications/managing-applications.md b/src/gateway/kong-enterprise/dev-portal/applications/managing-applications.md new file mode 100644 index 000000000000..275bcb6276f9 --- /dev/null +++ b/src/gateway/kong-enterprise/dev-portal/applications/managing-applications.md @@ -0,0 +1,58 @@ +--- +title: Manage Applications +badge: enterprise +--- + +Developers can create applications from the Kong Dev Portal. An application can apply to any number of Services. This is called a Service Contract. To use an application with a Service, the Service Contract must have an Approved status. To enable automatic approval for all new Service Contracts, enable Auto-approve for the Portal Application Registration plugin. + +## Create an Application + +1. Log in to the Kong Dev Portal. +2. Click **My Apps** in the top navigation bar. +3. Click **New Application**. +4. Complete the **Create Application** dialog: + 1. Enter a unique `Application Name`. + 2. Enter a `Redirect URI`. + 3. Enter a `Description`. +5. Click **Create**. The Application Dashboard is displayed. From the +dashboard, you can view details about your application, view your credentials, +generate more credentials, and view your application status against a list of +Services. +6. Before you can use your application, you must activate it to create a Service +Contract for the Service. In the Services section of the Application Dashboard, +click **Activate** on the Service you want to use. If [Auto-approve](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/applications/enable-application-registration##aa) is not +enabled, your application will remain pending until an admin approves your +request. + +## View all Service Contracts for an Application + +A list of all applications in a Workspace can be accessed from the left navigation pane. + +1. Click **Applications** to view the list of applications. +2. From the Applications list, click an application to view all Service Contracts for the application; including contracts in Approved, Revoked, and Rejected status. +3. In the Service Contracts section, click the **Requested Access** tab to view Service Contracts requests for the application. Approve, revoke, or reject +requests. + +## View all Application Contracts for a Service + +View all Application Contracts and their status for a Service from the +**Service** page. + +1. Click **Services** in the left navigation pane. +2. Select the Service for which you have Application Registration enabled. +3. From the Service Contracts tab, view all Approved, Revoked, Rejected, and Requested Access for the Service. + +## Add a Document to your Service +When using Application Registration, it is recommended to link documentation +(OAS/Swagger spec) to your Service. Doing so allows Dev Portal users to easily +register Application Contracts for their applications from the documentation +page, and view a list of all documentation from the Catalog page. + +Add a document from the Service **View** page: +1. From your Workspace, in the left navigation pane, go to **API Gateway > Services**. +2. On the Services page, select the Service for which you want to add a document and click **View**. +3. In the Documents section, click **Add a Document**. +4. Choose a method to add the document to the Service: + - Use **Document Spec Path** to select an existing spec in the Portal. + - Use **Upload Document** to upload a new spec to the Portal. +5. Click **Add Document**. diff --git a/src/gateway/kong-enterprise/dev-portal/authentication/3rd-party-oauth.md b/src/gateway/kong-enterprise/dev-portal/authentication/3rd-party-oauth.md new file mode 100644 index 000000000000..15c09c5cb276 --- /dev/null +++ b/src/gateway/kong-enterprise/dev-portal/authentication/3rd-party-oauth.md @@ -0,0 +1,151 @@ +--- +title: Third-party OAuth2 Support for Application Registration +badge: enterprise +--- + +Third-party OAuth2 support allows developers to centralize application +credentials management with the [supported Identity Provider](#idps) of their +choice. To use the external IdP feature, set the `portal_app_auth` +configuration option to `external-oauth2` in the +`kong.conf.default` configuration file. For more information, see setting the +[Authorization Provider Strategy](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/applications/auth-provider-strategy). + +The Kong [OIDC](/hub/kong-inc/openid-connect/) and +[Portal Application Registration](/hub/kong-inc/application-registration/) +plugins are used in conjunction with each other on a Service: + +* The OIDC plugin handles all aspects of the OAuth2 handshake, including +looking up the Consumer via +[custom claim](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/authentication/okta-config#auth-server-cclaim) +(the `custom_id` matches the identity provider `client_id` claim). + +* The Application Registration plugin is responsible for checking the mapped +Consumer and ensuring the Consumer has the correct ACL (Access Control List) +permissions to access the Route. + +## Supported identity providers {#idps} + +The Kong OIDC plugin supports many identity providers out of the box. The +following providers have been tested for the current version of the Kong +Portal Application Registration plugin used in tandem with the Kong OIDC plugin: + +* [Okta](https://developer.okta.com/). See the + [Okta setup example](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/authentication/okta-config). +* [Azure](https://azure.microsoft.com/). See the + [Azure setup example](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/authentication/azure-oidc-config). +* [Ping Identity](https://www.pingidentity.com/). + +### Resources + +How you authenticate with a Service depends on its underlying OAuth2 +implementation. For more information, reference the documentation below for +your implemented identity provider and OAuth flow. + +- Okta + - [Authorization Code Flow](https://developer.okta.com/docs/guides/implement-auth-code/overview/) + - [Authorization Code Flow (PKCE)](https://developer.okta.com/docs/guides/implement-auth-code-pkce/overview/) + - [Client Credentials Flow](https://developer.okta.com/docs/guides/implement-client-creds/overview/) + - [Implicit Grant Flow](https://developer.okta.com/docs/guides/implement-implicit/overview/) + +- Azure + - [Authorization Code Flow](https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow) + - [Client Credentials Flow](https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow) + - [Implicit Grant Flow](https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-implicit-grant-flow) + +- Ping Identity + - [Oauth2 Developers Guide](https://www.pingidentity.com/developer/en/resources/oauth-2-0-developers-guide.html) + +## Supported OAuth flows + +* Client Credentials ([RFC 6742 Section 4.4](https://tools.ietf.org/html/rfc6749#section-4.4)) +* Authorization Code ([RFC 6742 Section 4.1](https://tools.ietf.org/html/rfc6749#section-4.1)) +* Implicit Grant ([RFC 6742 Section 4.2](https://tools.ietf.org/html/rfc6749#section-4.2)) +* Password Grant ([RFC 6742 Section 4.3](https://tools.ietf.org/html/rfc6749#section-4.3)) + +Password Grant and [Implicit Grant flows](https://developer.okta.com/blog/2019/05/01/is-the-oauth-implicit-flow-dead) are available but not recommended +because they are less secure than the Authorization Code and Client Credentials +flows. + +### Client Credentials Flow {#cc-flow} + +The OIDC plugin makes authenticating using Client Credentials very +straightforward. This flow should be used for server-side and secure +machine-to-machine communication. The Client Credentials flow requires the +authorizing party to store and send the application's `client_secret`. + +In this flow, a developer makes a request against the Service with the OIDC and Application +Registration plugins applied. This request should contain the `client_id` and +`client_secret` as a Basic Auth authentication header: + +`Authorization: Basic client_id:client_secret` + +The `client_id:client_secret` should be base64-encoded. + +The following sequence diagram illustrates the Client Credentials flow through +the OIDC and Application Registration plugins. Click on the image to expand its + view. + +![Client Credentials Flow](/assets/images/docs/dev-portal/dp-appreg-3rdparty-ccflow.png) + +| Step | Explanation | +|:------|:---------------------------------------------------------------------| +| a | Developer sends the Okta application's `client_id` and `client_secret` to the Route. The OIDC plugin proxies this request to the Okta auth server's endpoint.| +| b | Okta reads the `client_id` and `client_secret` and generates an access token. The auth server is configured to insert a custom claim `application_id`, which is a key/value pair with the Okta application's `client_id`. | +| c | Okta returns the access token to Kong. | +| d | The OIDC plugin reads the resulting access token and associates the request with the application via the `application_id` custom claim. | +| e | If the resolved application has permission to consume the Service via its Portal Application Registration plugin, Kong forwards the request to the Upstream. | + +### Authorization Code Flow {#ac-flow} + +Due to limitations of the OIDC plugin, a single plugin instance cannot handle +dynamic `client_id's` provisioned from multiple sources (applications). +To circumvent this issue, the IdP Issuer URL is exposed to developers on the +Dev Portal application show page when +[`show_issuer`](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/applications/enable-application-registration#app-reg-params) is enabled in the +Application Registration plugin. Developers can hit the Issuer URL directly to +provision an access token. After getting the access token, requests can be made +against the proxy. + +1. Set up the application to secure an access token against the IdP directly. +For more information about implementing the Authorization Code flow with Okta, +refer to the +[Okta developer guide](https://developer.okta.com/docs/guides/implement-auth-code/overview/). + +2. After the initial access token handshake has been completed, make subsequent +requests to the Kong service using that access token as a +[bearer token](https://tools.ietf.org/html/rfc6750#section-2.1). After +the first successful request, the OIDC plugin will establish a session with the +client so that the access token does not need to be continually passed with +every request. + +The following sequence diagram illustrates the Authorization Code flow through +the OIDC and Application Registration plugins. Click on the image to expand its + view. + +![Authorization Code Flow](/assets/images/docs/dev-portal/dp-appreg-3rdparty-authcodeflow.png) + +| Step | Explanation | +|:------|:--------------------------------------------------------------------| +| a | A developer copies the target Service's `issuer_id`, which can be exposed in the Dev Portal application view Service Details page. Developers can configure their application to make a request to this endpoint to authenticate the user and retrieve an access token. | +| b | Okta redirects the user to a login page. | +| c | The user inputs their Single Sign-On (SSO) information. | +| d | The user submits the SSO form that contains their Okta username and password. | +| e | Upon a successful login, the application is given an access token to make against calls for all subsequent requests. | +| f | The user makes a request to the protected Service and Route.| +| g | The OIDC plugin takes the access token and runs introspection, consulting the Okta authorization server if necessary. After the access token has been verified, the plugin matches the custom claim to find the associated application Consumer via its `custom_id`. | +| h | The request is passed to the Application Registration plugin, which checks to make sure the Consumer has the appropriate ACL (Access Control List) permissions. | +| i | The request is proxied to the Upstream. | + +### Implicit Grant Flow + +The Implicit Grant flow is not recommended if the Authorization Code flow is +possible. + +1. Set up the application to secure an access token against the IdP directly. +For more information about implementing the Implicit Grant flow with Okta, refer to +the [Okta developer guide](https://developer.okta.com/docs/guides/implement-implicit/use-flow/). + +2. After the access token handshake has been completed, make subsequent requests +to the Kong service using that access token as a bearer token. After the first +successful request, the OIDC plugin will establish a session with the client so +that the access token does not need to be passed continuously. diff --git a/src/gateway/kong-enterprise/dev-portal/authentication/adding-registration-fields.md b/src/gateway/kong-enterprise/dev-portal/authentication/adding-registration-fields.md new file mode 100644 index 000000000000..9488632184f0 --- /dev/null +++ b/src/gateway/kong-enterprise/dev-portal/authentication/adding-registration-fields.md @@ -0,0 +1,24 @@ +--- +title: Adding Dev Portal Registration Fields +badge: enterprise +--- + +When authentication is enabled for a Dev Portal, the only required +fields by default are **full name**, **email**, and **password**. However, you +can add custom fields to this form and indicate whether the fields are +required. Adding custom required fields will not affect existing registered +users until they choose to edit their profile. + +### Adding Custom Registration Fields + +1. In Kong Manager, navigate to the Workspace's Dev Portal **Settings** page. + +2. Click the **Developer Meta Fields** tab. + +3. Click **+ Add Field** to add a new field object to the form. + +4. Enter a label, field name, and select the type of input. + +5. Select the **Required** checkbox to require the new field for registration. + +6. Click **Save Changes**. The field is automatically added to the registration form. diff --git a/src/gateway/kong-enterprise/dev-portal/authentication/azure-oidc-config.md b/src/gateway/kong-enterprise/dev-portal/authentication/azure-oidc-config.md new file mode 100644 index 000000000000..0b1a8b6a2655 --- /dev/null +++ b/src/gateway/kong-enterprise/dev-portal/authentication/azure-oidc-config.md @@ -0,0 +1,265 @@ +--- +title: Set Up External Portal Application Authentication with Azure AD and OIDC +badge: enterprise +--- + +These instructions help you set up Azure AD as your third-party identity provider +for use with the Kong OIDC and Portal Application Registration plugins. + +## Prerequisites + +- The `portal_app_auth` configuration option is configured for your OAuth provider + and strategy (`kong-oauth2` or `external-oauth2`). See + [Configure the Authorization Provider Strategy](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/applications/auth-provider-strategy) for the Portal Application Registration plugin. + +## Create an Application in Azure + +1. Within Azure, go to the **App registrations** service and register a new application. + +2. In **Certificates & secrets**, create a Client secret and save it in a + secure location. You can only view the secret once. + +3. Under **Manifest**, update `accessTokenAcceptedVersion=2` (default is null). + The JSON for your application should look similar to this example: + +## Create a Service in Kong + +{% navtabs %} +{% navtab Using cURL %} + +```bash +curl -i -X PUT http://:8001/services/httpbin-service-azure \ + --data 'url=https://httpbin.org/anything' +``` + +{% endnavtab %} +{% navtab Using HTTPie %} + +```bash +http PUT :8001/services/httpbin-service-azure \ + url=https://httpbin.org/anything +``` +{% endnavtab %} +{% endnavtabs %} + +## Create a Route in Kong + +{% navtabs %} +{% navtab Using cURL %} + +```bash +curl -i -X PUT http://:8001/services/httpbin-service-azure/routes/httpbin-route-azure \ + --data 'paths=/httpbin-azure' +``` +{% endnavtab %} +{% navtab Using HTTPie %} + +```bash +http -f PUT :8001/services/httpbin-service-azure/routes/httpbin-route-azure \ + paths=/httpbin-azure +``` + +{% endnavtab %} +{% endnavtabs %} + +## Map the OIDC and Application Registration Plugins to the Service + +Map the OpenID Connect and Application Registration plugins to the **Service**. +The plugins must be applied to a Service to work properly. + +### Step 1: Configure the OIDC plugin for the Service + + +{% navtabs %} +{% navtab Using cURL %} + + ```bash +curl -X POST http://:8001/services/httpbin-service-azure/plugins \ + --data name=openid-connect \ + --data config.issuer="https://login.microsoftonline.com//v2.0" \ + --data config.display_errors="true" \ + --data config.client_id="" \ + --data config.client_secret="" \ + --data config.redirect_uri="https://example.com/api" \ + --data config.consumer_claim=aud \ + --data config.scopes="openid" \ + --data config.scopes="YOUR_CLIENT_ID/.default" \ + --data config.verify_parameters="false" +``` + +{% endnavtab %} +{% navtab Using HTTPie %} + +```bash +http -f :8001/services/httpbin-service-azure/plugins \ + name=openid-connect \ + config.issuer=https://login.microsoftonline.com//v2.0 \ + config.display_errors=true \ + config.client_id= \ + config.client_secret="" \ + config.redirect_uri="https://example.com/api" \ + config.consumer_claim=aud \ + config.scopes=openid \ + config.scopes=/.default \ + config.verify_parameters=false +``` +{% endnavtab %} +{% endnavtabs %} + +For more information, see [OIDC plugin](/hub/kong-inc/openid-connect/). + + +### Step 2: Configure the Application Registration plugin for the Service + +{% navtabs %} +{% navtab Using cURL %} + +```bash +curl -X POST http://:8001/services/httpbin-service-azure/plugins \ + --data "name=application-registration" \ + --data "config.auto_approve=true" \ + --data "config.description=Uses consumer claim with various values (sub, aud, etc.) as registration id to support different flows and use cases." \ + --data "config.display_name=For Azure" \ + --data "config.show_issuer=true" +``` + +{% endnavtab %} +{% navtab Using HTTPie %} + +```bash +http -f :8001/services/httpbin-service-azure/plugins \ + name=application-registration \ + config.auto_approve=true \ + config.display_name="For Azure" \ + config.description="Uses consumer claim with various values (sub, aud, etc.) as registration id to support different flows and use cases." \ + config.show_issuer=true +``` +{% endnavtab %} +{% endnavtabs %} + +### Step 3: Get an access token from Azure + +Get an access token using the Client Credential workflow and convert the token +into a JSON Web Token (JWT). Replace the placeholder values with your values for +``, ``,``, and +``. + +Get an access token from Azure: + +{% navtabs %} +{% navtab Using cURL %} + +```bash +curl -X POST https://login.microsoftonline.com//oauth2/v2.0/token \ + --data scope="/.default" \ + --data grant_type="client_credentials" \ + --data client_id="" \ + --data client_secret="" \ +``` + +{% endnavtab %} +{% navtab Using HTTPie %} + +```bash +https -f POST "https://login.microsoftonline.com//oauth2/v2.0/token" \ + scope=/.default \ + grant_type=client_credentials \ + -a : +``` +{% endnavtab %} +{% endnavtabs %} + +### Step 4: Convert an access token into a JWT token + +1. Paste the access token obtained from the previous step into +[JWT](https://jwt.io). + +1. Click **Share JWT** to copy the value for the +[aud (audience)](https://tools.ietf.org/html/rfc7519#section-4.1.3) claim to +your clipboard. You will use the `aud` value as your **Reference ID** in the +next procedure. + +## Create an Application in Kong + +1. Log in to your Dev Portal and create a new application: + 1. Select the **My Apps** menu -> **New Application**. + 2. Enter the **Name** of your Azure application. + 3. Paste the `aud` value generated in JWT in the **Reference ID** field. + 4. (Optional) Enter a **Description**. + +2. Click **Create**. + +3. After you create your application, make sure you activate the Service. In the + Services section of the Application Dashboard, click **Activate** on the Service + you want to use. + + Because you enabled + [Auto-approve](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/applications/enable-application-registration##aa) + on the associated Application Registration Plugin, an admin won't need to + approve the request. + +## Test your Authentication Flows with your Azure Application + +Follow these instructions to test your client credentials or authorization code +flows with your Azure AD implementation. + +### Test Client Credentials Flow + +#### Step 1: Get a token + +{% navtabs %} +{% navtab Using cURL %} + +```bash +curl -X POST "https://login.microsoftonline.com//oauth2/v2.0/token" \ +--data scope="/.default" \ +--data grant_type="client_credentials" \ +--data client_id="" \ +--data client_secret="" +``` + +{% endnavtab %} +{% navtab Using HTTPie %} + +```bash +https -f POST "https://login.microsoftonline.com//oauth2/v2.0/token" \ + scope=/.default \ + grant_type=client_credentials \ + -a : \ + --verify NO +``` +{% endnavtab %} +{% endnavtabs %} + +#### Step 2: Use the token in an authorization header to retrieve the data + +{% navtabs %} +{% navtab Using cURL %} + +```bash +curl --header 'Authorization: bearer ' ':8000/httpbin-azure' +``` + +{% endnavtab %} +{% navtab Using HTTPie %} + +```bash +http :8000/httpbin-azure Authorization:'bearer ' +``` +{% endnavtab %} +{% endnavtabs %} + + Replace `` with the bearer token you generated in the previous step. + +### Test Authorization Code Flow + +In your browser, go to `http://:8000/httpbin-azure`. + +You should be guided through a log in process within Azure and then the results +delivered in your browser. + +## Troubleshoot + +If you encounter any issues, review your data plane logs. Because you +enabled `display_errors=true` on the OpenID Connect Plugin, you will receive +more verbose error messages that can help pinpoint any issues. diff --git a/src/gateway/kong-enterprise/dev-portal/authentication/basic-auth.md b/src/gateway/kong-enterprise/dev-portal/authentication/basic-auth.md new file mode 100644 index 000000000000..01d30d6ef966 --- /dev/null +++ b/src/gateway/kong-enterprise/dev-portal/authentication/basic-auth.md @@ -0,0 +1,84 @@ +--- +title: Enable Basic Auth in the Dev Portal +badge: enterprise +--- + +The Kong Dev Portal can be fully or partially authenticated using HTTP protocol's Basic Authentication scheme. Requests are sent with an Authorization header that +contains the word `Basic` followed by the base64-encoded `username:password` string. + +Basic Authentication for the Dev Portal can be enabled using any of the following ways: + +- [Kong Manager](#enable-basic-auth-using-kong-manager) +- [Command line](#enable-basic-auth-using-the-command-line) +- [Kong configuration file](#enable-basic-auth-using-kongconf) + +**Warnings:** + +- Enabling authentication in the Dev Portal requires use of the +Sessions plugin. Developers will not be able to log in if this is not properly set. +For more information, see +[Sessions in the Dev Portal](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/authentication/sessions). + +- When Dev Portal Authentication is enabled, content files remain unauthenticated until a role is applied to them. The exceptions are `settings.txt` and `dashboard.txt`, which begin with the `*` role. For more information, see +[Developer Roles and Content Permissions](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/authentication/developer-permissions). + + +## Enable Portal Session Config + +In the Kong configuration file, set the `portal_session_conf` property: + +``` +portal_session_conf={ "cookie_name":"portal_session","secret":"","storage":"kong"} +``` + +If using HTTP while testing, include `"cookie_secure": false` in the config: + +``` +portal_session_conf={ "cookie_name":"portal_session","secret":"","storage":"kong","cookie_secure":false} +``` + +Or, if you have different subdomains for the `portal_api_url` and `portal_gui_host`, set the `cookie_domain` +and `cookie_samesite` properties as follows: + +``` +portal_session_conf={ "cookie_name":"portal_session","secret":"","storage":"kong","cookie_secure":false,"cookie_domain":"<.your_subdomain.com>","cookie_samesite":"off" } +``` + +### See Also + +- For more information about portal session configuration, see +[Sessions](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/authentication/sessions#portal-session-conf). + +- For more information about domains and cookies in Dev Portal sessions, see +[Domains](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/authentication/sessions#domains). + +## Enable Basic Auth Using Kong Manager + +1. Navigate to the Dev Portal's **Settings** page. +2. Find **Authentication plugin** under the **Authentication** tab. +3. Select **Basic Authentication**. +4. Click **Save Changes**. + +![Authentication plugin](/assets/images/docs/dev-portal/portal-settings-auth-plugin.png) + +## Enable Basic Auth Using the Command Line + +To patch a Dev Portal's authentication property directly, run: + +```bash +curl -X PATCH http://localhost:8001/workspaces/ \ + --data "config.portal_auth=basic-auth" +``` + +## Enable Basic Auth Using `kong.conf` + +Kong allows for a default authentication plugin to be set in the Kong +configuration file with the `portal_auth` property. + +In your `kong.conf` file, set the property as follows: + +``` +portal_auth="basic-auth" +``` + +This sets all Dev Portals to use Basic Authentication by default when initialized. diff --git a/src/gateway/kong-enterprise/dev-portal/authentication/developer-permissions.md b/src/gateway/kong-enterprise/dev-portal/authentication/developer-permissions.md new file mode 100644 index 000000000000..feda31bb51bc --- /dev/null +++ b/src/gateway/kong-enterprise/dev-portal/authentication/developer-permissions.md @@ -0,0 +1,87 @@ +--- +title: Developer Roles and Content Permissions +badge: enterprise +--- + +Access to the Dev Portal can be fine-tuned with the use of Developer +Roles and Content Permissions, managed through the Dev Portal Permissions page +of Kong Manager. This page can be found by clicking the **Permissions** link +under **Dev Portal** in the Kong Manager navigation bar. + +## Roles + +The Roles Tab contains a list of available developer roles as well as providing +the ability to create and edit roles. + +Selecting Create Role allows you to enter a unique role name, as well as a +comment to provide context for the nature of the role. You can assign the role +to existing developers from within the role creation page. Clicking Create +saves the role and returns you to the Roles List view. There you can see your +newly created role as well as any other previously defined roles. + +Clicking View displays the Role Details page with a list of developers assigned. + +From the Role Details page, click the Edit button to make changes to the role. You can also access this page from the Roles List Edit button. Here you can change the name and comment of the role, assign or remove developers, or delete the role. + +Deleting a role will remove it from any developers assigned the role and remove +the role restriction from any content files it is applied to. + +## Content + +The Content Tab shows the list of content files used by the Dev Portal. You can +apply roles to your content files, restricting access only to developers who +possess certain roles. Selecting an individual content file displays a +dropdown of available developer roles where you can choose which role has +access to the file. Unchecking all available roles will leave the file +unauthenticated. + +An additional option, the `*` role, is preset in the list. This predefined role +behaves differently from other roles. When a content file has the `*` role +attached to it, any developer may view the page as long as they are +authenticated. Additionally, the `*` role may not be used in conjunction with +other user-defined roles and will deselect those roles when `*` is selected. + +{:.important} +> **Important:** The `dashboard.txt` and `settings.txt` content files are +assigned the `*` role by default. All other content files have no roles by +default. This means that until a role is added, the file is unauthenticated +even if Dev Portal Authentication is enabled. Content Permissions are ignored +when Dev Portal Authentication is disabled. + +## readable_by attribute + +When a role is applied to a content file using the Content Tab, a special +attribute `readable_by` is added to the headmatter of the file. + +``` +--- +readable_by: + - role_name + - another_role_name +--- +``` + + In the case of spec files, `readable_by` is applied under the key `x-headmatter` or `X-headmatter`. + +``` +x-headmatter: + readable_by: + - role_name + - another_role_name +``` + +The value of `readable_by` is an array of string role names that have access to +view the content file. An exception is when the `*` role is applied to the +file. In this case, the value of `readable_by` is no longer an array, because +it contains the single string character `*`. + +``` +readable_by: "*" +``` + +⚠️**Important:** If you manually remove or edit the `readable_by` attribute, it +will modify the permissions of the file. Attempting to save a content file with +a `readable_by` array containing a nonexistent role name will result in an +error. Additionally, if you make changes to permissions in the Content Tab or +the Portal Editor, be sure to sync any local files so that permissions are not +overwritten the next time you push changes. diff --git a/src/gateway/kong-enterprise/dev-portal/authentication/key-auth.md b/src/gateway/kong-enterprise/dev-portal/authentication/key-auth.md new file mode 100644 index 000000000000..c6ad8d90ac05 --- /dev/null +++ b/src/gateway/kong-enterprise/dev-portal/authentication/key-auth.md @@ -0,0 +1,64 @@ +--- +title: Enable Key Auth in the Dev Portal +badge: enterprise +--- + +The Kong Dev Portal can be fully or partially authenticated using API keys or **Key +Authentication**. Users provide a unique key upon registering and use this key +to log into the Dev Portal. + +Key Authentication for the Dev Portal can be enabled in three ways: + +- via the [Kong Manager](#enable-key-auth-via-kong-manager) +- via the [the command line](#enable-key-auth-via-the-command-line) +- via the [the Kong configuration file](#enable-key-auth-via-the-kongconf) + +>**Warning** Enabling authentication in the Dev Portal requires use of the +> Sessions plugin. Developers will not be able to login if this is not set +> properly. More information about [Sessions in the Dev Portal](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/authentication/sessions) + +## Enable Portal Session Config + +``` +portal_session_conf={ "cookie_name": "portal_session", "secret": "CHANGE_THIS", "storage": "kong" } +``` + +If using HTTP while testing, include `"cookie_secure": false` in the config: + +``` +portal_session_conf={ "cookie_name": "portal_session", "secret": "CHANGE_THIS", "storage": "kong", "cookie_secure": false } +``` + +## Enable Key Auth via Kong Manager + +1. Navigate to the Dev Portal's **Settings** page. +2. Find **Authentication plugin** under the **Authentication** tab. +3. Select **Key Authentication** from the drop down. +4. Click **Save Changes**. + +>**Warning** When Dev Portal Authentication is enabled, content files will remain unauthenticated until a role is applied to them. The exception to this is `settings.txt` and `dashboard.txt` which begin with the `*` role. Please visit the Developer Roles and Content Permissions section for more info. + +## Enable Key Auth via the Command Line + +To patch a Dev Portal's authentication property directly, run: + +``` +curl -X PATCH http://localhost:8001/workspaces/ \ + --data "config.portal_auth=key-auth" +``` + +>**Warning** When Dev Portal Authentication is enabled, content files will remain unauthenticated until a role is applied to them. The exception to this is `settings.txt` and `dashboard.txt` which begin with the `*` role. Please visit the Developer Roles and Content Permissions section for more info. + +## Enable Key Auth via the Kong.conf + +Kong allows for a `default authentication plugin` to be set in the Kong +configuration file with the `portal_auth` property. + +In your `kong.conf` file, set the property as follows: + +``` +portal_auth="key-auth" +``` + +This will set every Dev Portal to use Key Authentication by default when +initialized, regardless of Workspace. diff --git a/src/gateway/kong-enterprise/dev-portal/authentication/managing-developers.md b/src/gateway/kong-enterprise/dev-portal/authentication/managing-developers.md new file mode 100644 index 000000000000..4a88c700d556 --- /dev/null +++ b/src/gateway/kong-enterprise/dev-portal/authentication/managing-developers.md @@ -0,0 +1,66 @@ +--- +title: Managing Developers +badge: enterprise +--- + +## Developer Status + +A status represents the state of a developer and the access they have to the Dev + Portal and APIs: + +* **Approved** + * A developer who can access the Dev Portal. Approved developers can create + credentials & access **all** APIs that allow those credentials. +* **Requested** + * A developer who has requested access but has not yet been Approved. +* **Rejected** + * A developer who has had their request denied by a Kong admin. +* **Revoked** + * A developer who once had access to the Dev Portal but has since had access + Revoked. + + +![Managing Developers](https://konghq.com/wp-content/uploads/2018/05/gui-developer-tabs.png) + +## Approving Developers + +Developers who have requested access to a Dev Portal will appear under the +**Requested Access** tab. From this tab, you can choose to *Accept* or *Reject* +the developer from the actions in the table row. After selecting an action, the +corresponding tab is updated. + + +## View Approved Developers + +To view all currently approved developers, click the **Approved** tab. From here, you can choose to *Revoke* or *Delete* a particular developer. Additionally, you can use this view to send an email to a developer with the **Email Developer** `mailto` link. See [Emailing Developers](#emailing-developers) for more info. + + +## View Revoked Developers + +To view all currently revoked developers, click the **Revoked** tab. From here, you can choose to *Re-approve* or *Delete* a developer. + + +### View Rejected Developers + +To view all currently rejected developers, click the **Rejected** tab. Rejected developers completed the registration flow on your Dev Portal but were rejected from the **Request Access** tab. You may *Approve* or *Delete* a developer from this tab. + + +## Email Developers + +### Invite Developers to Register + +To invite a single or multiple developers: + +1. Click **Invite Developers**. +2. Use the popup modal to enter email addresses separated by commas. +3. After all emails have been added, click **Invite**. A pre-filled message +opens in your default email client with a link to the registration page for +your Dev Portal. + +Each developer is bcc'd by default for privacy. You may choose to edit the message or send as is. + +![Invite Developers](https://konghq.com/wp-content/uploads/2018/05/invite-developers.png) + +## Developer Management Property Reference + +For comprehensive documentation on developer management properties, see [Default Developer Portal Authentication](/gateway/{{page.kong_version}}/reference/configuration/#default-developer-portal-authentication-section). diff --git a/src/gateway/kong-enterprise/dev-portal/authentication/oidc.md b/src/gateway/kong-enterprise/dev-portal/authentication/oidc.md new file mode 100644 index 000000000000..62725d4cfa53 --- /dev/null +++ b/src/gateway/kong-enterprise/dev-portal/authentication/oidc.md @@ -0,0 +1,146 @@ +--- +title: Enable OpenID Connect in the Dev Portal +badge: enterprise +--- + +The [OpenID Connect Plugin](/hub/kong-inc/openid-connect/) (OIDC) +allows the Kong Dev Portal to hook into existing authentication setups using third-party +*Identity Providers* (IdP) such as Google, Okta, Microsoft Azure AD, +[Curity](/gateway/{{page.kong_version}}/kong-plugins/authentication/oidc/curity/#kong-dev-portal-authentication), etc. + +[OIDC](/hub/kong-inc/openid-connect/) must be used with +the `session` method, utilizing cookies for Dev Portal File API requests. + +In addition, a configuration object is required to enable OIDC. Refer to the +[Sample Configuration Object](#/sample-configuration-object) section of this +document for more information. + +{:.note} +> **Note**: The Dev Portal does not automatically create developer accounts on login via OIDC. +A developer account matching the `consumer_claim` configuration parameter has to be +created and approved (if auto approve is not enabled) beforehand. +>

      +> During the registration flow, users must enter their login information in their +IDP-redirected login page. The user is then brought to the Dev Portal +registration page and their email is pre-populated in the registration form. +Users cannot change their email in the registration form. +The user may be asked for additional fields, as set by the account admin. + +OIDC for the Dev Portal can be enabled in one of the following ways: + +- [Portal Session Plugin Config](#portal-session-plugin-config) +- [Sample Configuration Object](#sample-configuration-object) +- [Enable OIDC using Kong Manager](#enable-oidc-using-kong-manager) +- [Enable OIDC using the Command Line](#enable-oidc-using-the-command-line) +- [Enable OIDC using kong.conf](#enable-oidc-using-kongconf) + +## Portal Session Plugin Config + +Session Plugin Config does not apply when using OpenID Connect. + +## Sample Configuration Object + +Below is a sample configuration JSON object for using *Google* as the Identity +Provider: + +``` +{ + "consumer_by": ["username","custom_id","id"], + "leeway": 1000, + "scopes": ["openid","profile","email","offline_access"], + "logout_query_arg": "logout", + "client_id": [""], + "login_action": "redirect", + "logout_redirect_uri": ["http://localhost:8003"], + "ssl_verify": false, + "consumer_claim": ["email"], + "forbidden_redirect_uri": ["http://localhost:8003/unauthorized"], + "client_secret": [""], + "issuer": "https://accounts.google.com/", + "logout_methods": ["GET"], + "login_redirect_uri": ["http://localhost:8003"], + "login_redirect_mode": "query" +} +``` + +The placeholders above should be replaced with your actual values: + + - `` - Client ID provided by IdP + - `` - Client secret provided by IdP + +See the [documentation of the OpenID Connect plugin](/hub/kong-inc/openid-connect/) +for more information. + +**Important:** The `redirect_uri` needs to be configured as an allowed URI in the IdP. +If not set explicitly in the configuration object, the URI default is +`http://localhost:8004//auth`. + +If `portal_gui_host` and `portal_api_url` are set to share a domain but differ +with regard to subdomain, `redirect_uri` and `session_cookie_domain` need to be +configured to allow OpenID Connect to apply the session correctly. + +Example: + +``` +{ + "consumer_by": ["username","custom_id","id"], + "leeway": 1000, + "scopes": ["openid","profile","email","offline_access"], + "logout_query_arg": "logout", + "client_id": [""], + "login_redirect_uri": ["https://example.portal.com"], + "login_action": "redirect", + "logout_redirect_uri": ["https://example.portal.com"], + "ssl_verify": false, + "consumer_claim": ["email"], + "redirect_uri": ["https://exampleapi.portal.com/auth"], + "session_cookie_domain": ".portal.com", + "forbidden_redirect_uri": ["https://example.portal.com/unauthorized"], + "client_secret": ["**Warning** When Dev Portal Authentication is enabled, content files will remain unauthenticated until a role is applied to them. The exception to this is `settings.txt` and `dashboard.txt` which begin with the `*` role. Please visit the Developer Roles and Content Permissions section for more info. + +## Enable OIDC using the Command Line + +You can use the Kong Admin API to set up Dev Portal Authentication. +To patch a Dev Portal's authentication property directly, run: + +``` +curl -X PATCH http://localhost:8001/workspaces/ \ + --data "config.portal_auth=openid-connect" + "config.portal_auth_conf= +``` + +>**Warning** When Dev Portal Authentication is enabled, content files will remain unauthenticated until a role is applied to them. The exception to this is `settings.txt` and `dashboard.txt` which begin with the `*` role. Please visit the Developer Roles and Content Permissions section for more info. + +## Enable OIDC using kong.conf + +Kong allows for a `default authentication plugin` to be set in the Kong +configuration file with the `portal_auth` property. + +In your `kong.conf` file, set the property as follows: + +``` +portal_auth="openid-connect" +``` + +Then set the `portal_auth_conf` property to your +customized [**Configuration JSON Object**](#sample-configuration-object). + +This will set every Dev Portal to use OIDC by default when initialized, regardless of Workspace. diff --git a/src/gateway/kong-enterprise/dev-portal/authentication/okta-config.md b/src/gateway/kong-enterprise/dev-portal/authentication/okta-config.md new file mode 100644 index 000000000000..04b59f8da39c --- /dev/null +++ b/src/gateway/kong-enterprise/dev-portal/authentication/okta-config.md @@ -0,0 +1,108 @@ +--- +title: Set Up External Portal Application Authentication with Okta and OIDC +badge: enterprise +--- + +These instructions help you set up Okta as your third-party identity provider +for use with the Kong OIDC and Portal Application Registration plugins. + +## Define an authorization server and create a custom claim in Okta {#auth-server-cclaim} + +Follow these steps to set up an authorization server in Okta for all authorization types. + +1. Sign in to the [Developer Okta site](https://developer.okta.com/). +1. Click **Security > API > Authorization Servers**. + + Notice that you already have an authorization server set up named `default`. + This example uses the default auth server. You can also create as many + custom authorization servers as necessary to fulfill your requirements. For + more information, refer to the + [Okta developer documentation](https://developer.okta.com/docs/guides/customize-authz-server/overview/). + +2. Click **default** to view the details for the default auth server. Take note +of the `Issuer` URL, which you will use to associate Kong with your authorization server. + +1. Click the **Claims** tab. + +2. Click **Add Claim**. Add a custom claim called `application_id` that will attach any successfully authenticated application's `id` to the access token. + 1. Enter `application_id` in the **Name** field. + 2. Ensure the `Include in token type` selection is **Access Token**. + 3. Enter `app.clientId` in the **Value** field. + 4. Click **Create**. + + Now that you have created a custom claim, you can associate the `client_id` + with a Service via the Application Registration plugin. Start by creating a Service in Kong Manager. + +3. Create a Service and a Route and instantiate an OIDC plugin on that Service. + You can allow most options to use their defaults. + + 1. In the `Config.Issuer` field, enter the Issuer URL of the Authorization server from your identity provider. + + ![OIDC with Okta Issuer URL](/assets/images/docs/dev-portal/oidc-issuer-url.png) + + 2. In the `Config.Consumer Claim` field, enter your ``. + + **Tip:** Because Okta's discovery document does not include all supported + auth types by default, ensure the + `config.verify_parameters` option is disabled. + + ![Clear Config Verify Parameters for OIDC with Okta](/assets/images/docs/dev-portal/oidc-clear-verify-params-app-reg.png) + + The core configuration should be: + + ```json + { + "issuer": "", + "verify_credentials": false, + "consumer_claim": "", + } + + ``` + +4. Configure a Portal Application Registration plugin on the Service as well. See +[Application Registration](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/applications/enable-application-registration#config-app-reg-plugin). + +## Register an application in Okta + +Follow these steps to register an application in Okta and associate the Okta +application with an application in the Kong Dev Portal. + +1. Sign in to the [Developer Okta site](https://developer.okta.com/). +2. Click **Applications** > **Applications**. +3. Depending on which authentication flow you want to implement, the setup of +your Okta application will vary: + + - **Create a new app integration**: Select `API Services` when prompted for an application type. In the **New API Services App Integration** modal, enter your app integration name. + + You will need your `client_id` and `client_secret` later on when you [authenticate with the proxy](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/authentication/3rd-party-oauth#cc-flow). + + - **Implicit Grant**: Select `Single-Page App`, `Native`, or `Web` when + prompted for an application type. Make sure `Implicit` is selected for + `Allowed grant types`. Enter the `Login redirect URIs`, `Logout redirect URIs`, and `Initiate login URI` fields with the correct values, depending on your application's routing. The Implicit Grant flow is not recommended if the Authorization Code flow is possible. + + - **Authorization Code**: Select `Single-Page App`, `Native`, or `Web` when + prompted for an application type. Make sure `Authorization Code` is selected for `Allowed grant types`. Enter the `Login redirect URIs`, `Logout redirect URIs`, and `Initiate login URI` fields with the correct values, depending on your application's routing. + +## Associate the identity provider application with your Kong application + +Now that the application has been configured in Okta, you need to associate the +Okta application with the corresponding application in Kong's Dev Portal. + +
      + Note: Each developer should have their own application in both Okta and Kong. + Each Okta application has its own `client_id` that maps to its respective application in Kong. + Essentially, this maps identity provider applications to portal applications. +
      + +This example assumes Client Credentials is the chosen OAuth flow. + +1. In the Kong Dev Portal, create an account if you haven't already. +2. After you've logged in, click `My Apps`. +3. On the Applications page, click `+ New Application`. +4. Complete the **Name** and **Description** fields. Paste the `client_id` of your corresponding Okta (or other identity provider) application into the **Reference Id** field. + + ![Kong Create Application with Reference Id](/assets/images/docs/dev-portal/create-app-ref-id.png) + +Now that the application has been created, developers can authenticate with the +endpoint using the supported and recommended +[third-party OAuth flows](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/authentication/3rd-party-oauth). diff --git a/src/gateway/kong-enterprise/dev-portal/authentication/sessions.md b/src/gateway/kong-enterprise/dev-portal/authentication/sessions.md new file mode 100644 index 000000000000..0cda8123d6c1 --- /dev/null +++ b/src/gateway/kong-enterprise/dev-portal/authentication/sessions.md @@ -0,0 +1,116 @@ +--- +title: Sessions in the Dev Portal +--- + +{:.important} +> **Important**: Portal Session Configuration does not apply when using [OpenID Connect](/hub/kong-inc/openid-connect) for Dev Portal authentication. The following information assumes that the Dev Portal is configured with `portal_auth` other than `openid-connect`; for example, `key-auth` or `basic-auth`. + +## How does the Sessions Plugin work in the Dev Portal? + +When a user logs in to the Dev Portal with their credentials, the Sessions Plugin will create a session cookie. The cookie is used for all subsequent requests and is valid to authenticate the user. The session has a limited duration and renews at a configurable interval, which helps prevent an attacker from obtaining and using a stale cookie after the session has ended. + +The Session configuration is secure by default, which may [require alteration](#session-security) if using HTTP or different domains for [portal_api_url](/gateway/{{page.kong_version}}/reference/configuration/#portal_api_url) and [portal_gui_host](/gateway/{{page.kong_version}}/reference/configuration/#portal_gui_host). Even if an attacker were to obtain a stale cookie, it would not benefit them since the cookie is encrypted. The encrypted session data may be stored either in Kong or the cookie itself. + +## Configuration to Use the Sessions Plugin with the Dev Portal + +To enable sessions authentication, configure the following: + +``` +portal_auth = +portal_session_conf = { + "secret":"", + "cookie_name":"", + "storage":"kong", + "cookie_lifetime":, + "cookie_renew":, + "cookie_secure":, + "cookie_domain":"", + "cookie_samesite":"" +} +``` + +* `"cookie_name":""`: The name of the cookie + * For example, `"cookie_name":"portal_cookie"` +* `"secret":""`: The secret used in keyed HMAC generation. Although + the **Session Plugin's** default is a random string, the `secret` _must_ be + manually set for use with the Dev Portal since it must be the same across all + Kong workers/nodes. +* `"storage":"kong"`: Where session data is stored. This value _must_ be set to `kong` for use with the Dev Portal. +* `"cookie_lifetime":`: The duration (in seconds) that the session will remain open; 3600 by default. +* `"cookie_renew":`: The duration (in seconds) of a session remaining at which point + the Plugin renews the session; 600 by default. +* `"cookie_secure":`: `true` by default. See [Session Security](#session-security) for + exceptions. +* `"cookie_domain"::` Optional. See [Session Security](#session-security) for exceptions. +* `"cookie_samesite":""`: `"Strict"` by default. See [Session Security](#session-security) for + exceptions. + +⚠️**Important:** +*The following properties must not be altered from default for use with the Dev Portal:* +* `logout_methods` +* `logout_query_arg` +* `logout_post_arg` + +For detailed descriptions of each configuration property, see the [Session Plugin documentation](/hub/kong-inc/session). + +## Session Security + +The Session configuration is secure by default, so the cookie uses the [Secure, HttpOnly](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#Secure_and_HttpOnly_cookies), and [SameSite](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#SameSite_cookies) directives. + +⚠️**Important:** The following properties must be altered depending on the protocol and domains in use: +* If using HTTP instead of HTTPS: `"cookie_secure": false` +* If using different subdomains for the [portal_api_url](/gateway/{{page.kong_version}}/reference/configuration/#portal_api_url) and [portal_gui_host](/gateway/{{page.kong_version}}/reference/configuration/#portal_gui_host), see the example below for [Domains](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/authentication/sessions/#domains). + +{:.important} +> **Important:** Sessions are not invalidated when a user logs out if `"storage": "cookie"` +(the default) is used. In that case, the cookie is deleted client-side. Only when session data is +stored server-side with `"storage": "kong"` set is the session actively invalidated. + +## Example Configurations + +### HTTPS with the same domain for API and GUI + +If using HTTPS and hosting Dev Portal API and the Dev Portal GUI from the same domain, the following configuration could be used for Basic Auth: + +``` +portal_auth = basic-auth +portal_session_conf = { + "cookie_name":"$4m04$" + "secret":"change-this-secret" + "storage":"kong" + "cookie_secure":true +} +``` + +In testing, if using HTTP, the following configuration could be used instead: + +``` +portal_auth = basic-auth +portal_session_conf = { + "cookie_name":"04tm34l" + "secret":"change-this-secret" + "storage":"kong" + "cookie_secure":false +} +``` + +### Domains + +The dev portal `portal_gui_host` and the dev +portal api `portal_api_url` must share a domain or subdomain. The following +example assumes subdomains of `portal.xyz.com` and `portalapi.xyz.com`. +Set a subdomain such as ``"cookie_domain": ".xyz.com"`` and set +`cookie_samesite` to `off`. + +``` +portal_auth = basic-auth +portal_session_conf = { + "storage":"kong" + "cookie_name":"portal_session" + "cookie_domain": ".xyz.com" + "secret":"super-secret" + "cookie_secure":false + "cookie_lifetime":31557600, + "cookie_samesite":"off" +} +``` diff --git a/src/gateway/kong-enterprise/dev-portal/cli.md b/src/gateway/kong-enterprise/dev-portal/cli.md new file mode 100644 index 000000000000..9a1860f1bd30 --- /dev/null +++ b/src/gateway/kong-enterprise/dev-portal/cli.md @@ -0,0 +1,70 @@ +--- +title: Developer Portal CLI +badge: enterprise +--- + +The Kong Developer Portal CLI is used to manage your Developer Portals from the +command line. It is built using [clipanion][clipanion]. + +This is the next generation TypeScript based Developer Portal CLI. The goal of +this project is to make a higher quality CLI tool over the initial sync script. + + +## Install + +``` +> npm install -g kong-portal-cli +``` + +## Usage + +The easiest way to start is by cloning the [portal-templates repo][templates] +master branch locally. + +Next, edit `workspaces/default/cli.conf.yaml` to set workspace `name` and `rbac_token` +to match your setup. + +Make sure Kong is running and portal is on. + +Now, from the root folder of the templates repo, you can run: + +```portal [-h,--help] [--config PATH] [-v,--verbose] ``` + +Where `` is one of: + +* `config` Output or change configuration of the portal on the given +`workspace`, locally. +* `deploy` Deploy changes made locally under the given workspace upstream. +* `disable` Disable the portal on the given workspace. +* `enable` Enable the portal on the given workspace. +* `fetch` Fetches content and themes from the given workspace. +* `wipe` Deletes all content and themes from upstream workspace + +Where indicates the directory/workspace pairing you would like to operate on. + +#### For `deploy` +- Add `-W` or `--watch` to make changes reactive. +- Add `-P` or `--preserve` to avoid deleting files upstream that you do not have locally. +- Add `-D` or `--disable-ssl-verification` to disable SSL verification and use self-signed certs. +- Add `-I` or `--ignore-specs` to ignore the `/specs` directory. + +#### For `fetch` +- Add `-K` or `--keep-encode` to keep binary assets as base64-encoded strings locally. +- Add `-D` or `--disable-ssl-verification` to disable SSL verification and use self-signed certs. +- Add `-I` or `--ignore-specs` to ignore the `/specs` directory. + +#### For `wipe` +- Add `-D` or `--disable-ssl-verification` to disable SSL verification and use self-signed certs. +- Add `-I` or `--ignore-specs` to ignore the `/specs` directory. + +#### For `enable` and `disable` +- Add `-D` or `--disable-ssl-verification` to disable SSL verification and use self-signed certs. + + +[clipanion]: https://github.com/arcanis/clipanion +[sync-script]: https://github.com/Kong/kong-portal-templates/blob/81382f2c7887cf57bb040a6af5ca716b83cc74f3/bin/sync.js +[cli-support]: https://github.com/Kong/kong-portal-cli/issues/new +[cli-license]: https://github.com/Kong/kong-portal-cli/blob/master/LICENSE +[cli-contributors]: (https://github.com/Kong/kong-portal-cli/contributors) +[kong-support]: https://support.konghq.com/support/s/ +[templates]: https://github.com/Kong/kong-portal-templates diff --git a/src/gateway/kong-enterprise/dev-portal/customize/adding-javascript-assets.md b/src/gateway/kong-enterprise/dev-portal/customize/adding-javascript-assets.md new file mode 100644 index 000000000000..d2e04336b0aa --- /dev/null +++ b/src/gateway/kong-enterprise/dev-portal/customize/adding-javascript-assets.md @@ -0,0 +1,55 @@ +--- +title: Adding and Using JavaScript Assets in Kong Dev Portal +badge: enterprise +--- + +The Kong Developer Portal ships with Vue, React, and jQuery already loaded. +You may want to make use of these libraries to write custom interactive +webpages or load additional JavaScript. + +> Note: This guide is for adding/using JavaScript assets without changing server-side routing. [Learn more about a SPA to the Dev Portal](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/customize/single-page-app). + +## Prerequisites + +* Portal Legacy is turned off +* The Kong Developer Portal is enabled and running +* The [kong-portal-cli tool](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/cli) is installed locally + + +## Adding JS Assets +> Warning: Due to compatibility issues, avoid using any React version other than React 15 on the `layouts/system/spec-render.html` layout. We recommend using the version of React included by the default base theme. + +To add JavaScript assets: +1. Clone the [kong-portal-templates](https://github.com/Kong/kong-portal-templates) repo. +2. Add any JavaScript files to the `themes/base/js` folder. +3. Deploy using the [kong-portal-cli-tool](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/cli). + + +## Loading JS Assets + +You can make use of the existing Vue and jQuery in any layout/partial that includes `partials/theme/required-scripts.html` where these scripts are loaded. + +By default, React is only loaded on `layouts/system/spec-render.html`. + +If you want to load React or any custom JavaScript asset on all pages, you can edit `themes/partial/foot.html`. + + +{% raw %} +``` +{% layout = "layouts/_base.html" %} + +{-main-} + {(partials/header.html)} + +
      + {* blocks.content *} +
      + + {(partials/footer.html)} + + +{-main-} +``` +{% endraw %} + +Alternatively, you can load the script you need on the specific layout for each content page as needed. diff --git a/src/gateway/kong-enterprise/dev-portal/customize/alternate-openapi-renderer.md b/src/gateway/kong-enterprise/dev-portal/customize/alternate-openapi-renderer.md new file mode 100644 index 000000000000..753b30b5aff5 --- /dev/null +++ b/src/gateway/kong-enterprise/dev-portal/customize/alternate-openapi-renderer.md @@ -0,0 +1,22 @@ +--- +title: Alternate OpenAPI Renderer +badge: enterprise +--- + +Through Kong Manager, use the Dev Portal [Editor](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/using-the-editor) to customize how your API specs render in your Dev Portal. + +To do this, add some custom code and update your config, as follows: + +1. In Kong Manager, navigate to the Dev Portal Editor from the left sidebar. + +1. Navigate to **Themes** > **base** > **layout** > **system** > **`spec.renderer.html`**. + +1. In `spec.renderer.html`, replace all of the current content with the content from this [spec-renderer.html](/code-snippets/spec-renderer.html) file. Doing so adds options for [Stoplight](https://meta.stoplight.io/docs/platform/ZG9jOjIwNjk2MQ-welcome-to-the-stoplight-docs) and [Redoc](https://github.com/Redocly/redoc) layouts. + +1. In `theme.conf.yaml`, add the parameter `spec_render_type` and the value `stoplight` or `redoc`. For example: + + ```yaml + spec_render_type: "stoplight" + ``` + +1. Refresh your Dev Portal to see that the change has taken effect. diff --git a/src/gateway/kong-enterprise/dev-portal/customize/emails.md b/src/gateway/kong-enterprise/dev-portal/customize/emails.md new file mode 100644 index 000000000000..3b3947b60e80 --- /dev/null +++ b/src/gateway/kong-enterprise/dev-portal/customize/emails.md @@ -0,0 +1,208 @@ +--- +title: Customizing Portal Emails +badge: enterprise +--- + +You can manage the message and appearance of emails being sent by the Kong Developer Portal. +Editable email templates are loaded as files similar to content files for portal rendering. +Email files can be managed in the same way as other files for rendering, via editor or via the Portal CLI Tool. +This feature is **not** supported on legacy portal mode. + +If no email templates are loaded, Kong will fall back to the same emails as {{site.base_gateway}} 1.3.0.0. +Enabling a non-legacy portal on new workspaces loads default editable email templates. +For existing non-legacy Portals, editable email templates must be loaded manually. + +Email-specific values are templated in tokens that work similarly to templating in portal layouts and partials. +Not all tokens are supported on all emails. + +## Prerequisites + +* The Kong Developer Portal is not running in **Legacy Mode** +* The Kong Developer Portal is enabled and running +* [The emails you want are enabled in kong](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/smtp/#portal_invite_email) +* If using CLI tool, kong-portal-cli tool 1.1 or later is installed locally and git installed + +## Understanding Email Files + +Portal templates use a combination of HTML, markdown, and [`tokens`](#token-descriptions). + +The follow example is the `emails/approved-access.txt` template: + + +{% raw %} +```yaml +--- +layout: emails/email_base.html + +subject: Developer Portal access approved {{portal.url}} +heading: Hello {{email.developer_name}}! +--- +You have been approved to access {{portal.url}}. +
      +Please visit {{portal.url}}/login to login. +``` +{% endraw %} + +Like other content files, these files have a headmatter between the two `---` . The layout is set by `layout` attribute, this is the layout file this email will render with. + +- `subject` sets the subject line for email. +- `heading` is an optional value that by default is rendered as a h3 + +The body of the email is HTML content. You can reference the tokens allowed for the email in the table below. In this case, {% raw %}`{{portal.url}}`{% endraw %} is used to access the portal url + +## Supported Emails and Tokens + +{% raw %} +|Path |Supported Tokens |Required Tokens |Description| +|--- |--- |--- |--- | +|emails/invite.txt | `{{portal.gui_url}}` `{{email.developer_email}}` | `{{portal.gui_url}}` |email sent to developer who is invited to a portal from the manager | +|--- |--- |--- |--- | +|emails/request-access.txt |`{{portal.gui_url}}` `{{email.developer_email}}` `{{email.developer_name}}` `{{email.developer_meta.*}}` `{{email.admin_url}}` |`{{portal.gui_url}}` `{{email.developer_email}}` |email sent to admin when a developer signs up for portal, in order to approve the developer | +|emails/approved-access.txt |`{{portal.url}}` `{{email.developer_email}}` `{{email.developer_name}}` `{{email.developer_meta.*}}` |`{{portal.gui_url}}` |email sent to developer when their account is approved | +|emails/password-reset.txt |`{{portal.url}}` `{{email.developer_email}}` `{{email.developer_name}}` `{{email.developer_meta.*}}` `{{email.token}}` `{{email.token_exp}}` `{{email.reset_url}}` |`{{portal.url}}` `{{email.token}}` or `{{email.reset_url}}` |email sent to developer when a password reset is requested (basic-auth only) | +|emails/password-reset-success.txt |`{{portal.url}}` `{{email.developer_email}}` `{{email.developer_name}}` `{{email.developer_meta.*}}` |`{{portal.url}}` |email sent to developer when a password reset is successful (basic-auth only) | +|emails/account-verification.txt |`{{portal.url}}` `{{email.developer_email}}` `{{email.developer_name}}` `{{email.developer_meta.*}}` `{{email.token}}` `{{email.verify_url}}` `{{email.invalidate_url}}` |`{{portal.url}}` `{{email.token}}` or both `{{email.verify_url}}` and `{{email.invalidate_url}} ` |email sent to developer when portal_email_verification is on to verify developer email (basic-auth only) | +|emails/account-verification-approved.txt |`{{portal.url}}` `{{email.developer_email}}` `{{email.developer_name}}` `{{email.developer_meta.*}}` |`{{portal.url}}` |email sent to developer when portal_email_verification is on and developer has verified email and developer has been approved by admin/auto-approve is on (basic-auth only) | +|emails/account-verification-pending.txt |`{{portal.url}}` `{{email.developer_email}}` `{{email.developer_name}}` `{{email.developer_meta.*}}` |`{{portal.url}}` |email sent to developer when portal_email_verification is on and developer has verified email and developer has yet to be approved by admin (basic-auth only) | +{% endraw %} + +## Token Descriptions + +{% raw %} +|Token |Description | +|--- |--- | +|`{{portal.url}}` |Dev Portal URL for the workspace | +|--- |--- | +|`{{email.developer_email}}` |Developer's email | +|`{{email.developer_name}}` |Developer's full name, this value is collected as part of registration by default. If meta-fields are edited to not include full_name then this will fallback to email | +|`{{email.developer_meta.*}}` |Developer's meta-fields, these value are collected as part of registration. They must be configured prior to registration. If the value doesn't exist or is optional and blank, it will display as an empty string. If the `developer_meta` configuration doesn't specify the field, it will appear as-is without replacement, e.g. `{{email.developer_meta.preferred_name}}`| +|`{{email.admin_url}}` |Kong Manager URL | +|`{{email.reset_url}}` |Dev Portal full URL for resetting password (assumes default path for password reset) | +|`{{email.token_exp}}` |Human readable string for amount of time from sending of email, password reset token/url is valid. | +|`{{email.verify_url}}` |Link to verify account (assumes default path for account verification)) | +|`{{email.invalidate_url}}` |Link to invalidate account verification request (assumes default path for account verification)) | +|`{{email.token}}` |Can be used in combination with `{{portal.url}}` to manually build url string for password reset and account verification/invalidation. **Not recommended for use**, unless custom path for password reset or account verification has been set. | +{% endraw %} + +## Editing Email Templates + +The default email templates will be automatically loaded into the Kong Developer Portal's file system when the Dev Portal is activated. These templates can now be edited in Kong Manager via the **Portal Editor** or via the **Portal CLI** tool. +**Note:** If you are using a Dev Portal initiated in a {{site.base_gateway}} version prior to 1.3.0.1, you will need to manually load the email templates into the file system. Follow the steps in [Loading Email Templates on Existing Dev Portals](#loading-email-templates-on-existing-dev-portals). + +### Editing via the Portal Editor + +Email templates can now be edited in the Portal Editor along with the rest of the files in the Kong Developer Portal file system. To view and edit these files: + +1. Log into Kong Manager and navigate to the Workspace whose Dev Portal you wish to edit. +2. Select the **Editor** from the sidebar under **Dev Portal**. + +The email templates can be found under the **Emails** section in the Portal Editor sidebar. + +### Editing via the Portal CLI Tool + +1. Clone [https://github.com/Kong/kong-portal-templates] master branch, and navigate into its directory. +2. If you have any customizations or permissions changes that you want to keep: + Run `portal fetch ` This will pull in your modifications locally. +3. After making any changes, `portal deploy ` to deploy all files. + +## Editing Email Appearance + +To edit the appearance of emails, you can change the layout file emails use. +By default, emails are set to use the layout `emails/email_base.html`. If this file does not exist inside your theme (default theme is `base`), then a hardcoded fallback will be used. + +You can edit the layout this layout file via the Portal Editor or locally with the Portal CLI tool. Follow the instructions for the editing email text, but modifying the layout file instead. + +If you want different emails to have a different appearance, you can set different layout files for each email file. + +The default email layout looks like: + +{% raw %} +```html + + + + + + + {{portal.name}} +

      {{page.heading}}

      +

      + {*page.body*} +

      + + +``` +{% endraw %} + +The `img` tag loads the logo that can be set in the appearance tab in the manager. If you do not want to display a logo, remove the `` tag. If you want to set different sizing for your logo, you can change the inline style attribute. + +> Note: Logo will not render for many email clients that pre-fetch images if portal is not set to be accessible from a public url (for example if you are testing the Portal with a localhost) + +By modifying the html of this file, you can change the appearance of your emails. For example if you wanted to add a footer that would show on all emails, add it under the `

      ` tag + +Be sure to keep in mind the html support limitations of the email clients you plan to support. + +## Loading Email Templates on Existing Dev Portals + +**Note:** This is only necessary for existing Dev Portals created on {{site.base_gateway}} 1.3.0. New Portals created in 1.3.0.1 and later will have these files already loaded, unless manually deleted. + +Editable email templates can be loaded either via the editor or via the `kong-portal-cli` tool. + +### Load Email Templates via the Portal Editor + +1. Log into Kong Manager and navigate to the workspace you want to edit. Click on **Editor** in the sidebar. +2. Click **New File+**. +3. Select Content type `email`. +4. Type in one of the supported paths from above. +5. Click **Create File** to generate a default email template that is valid for that email. +6. Do this for emails you want to edit. + + Note: By default, these emails you create will have layout key set: `layout: emails/email_base.html`. + If you don’t create this layout file, all emails fallback to a default layout. + You will want to create this layout if you want to customize the Appearance of emails in addition to message. + +To create an email layout: + +1. Click **New File+**. +2. Select Content type `theme`. +3. Type in the path for the layout, `themes//layouts/email_base.html`. The default theme name is base. + The layout that loads in the new portals in 1.3.0.1 is the following (this adds the logo image that can be set in the appearance tab in the manager): + +{% raw %} +```html + + + + + + + {{portal.name}} +

      {{page.heading}}

      +

      + {*page.body*} +

      + + +``` +{% endraw %} + +Find out more about customizing the email layout in the section below. + +### Load Email Templates via the Portal CLI Tool + +1. Clone the [portal templates master branch](https://github.com/Kong/kong-portal-templates) and + navigate into the folder you cloned. +2. If you have any customizations or permissions changes that you want to keep: + + 1. Run `portal fetch `. This pulls in your modifications locally. + + 2. Merge in the portal templates master branch + to apply changes for 1.3.0.1, including emails. + +3. Run `portal deploy `. This deploys all files. diff --git a/src/gateway/kong-enterprise/dev-portal/customize/markdown-extended.md b/src/gateway/kong-enterprise/dev-portal/customize/markdown-extended.md new file mode 100644 index 000000000000..c08447692f57 --- /dev/null +++ b/src/gateway/kong-enterprise/dev-portal/customize/markdown-extended.md @@ -0,0 +1,43 @@ +--- +title: Markdown Rendering Module +badge: enterprise +--- + +The Kong Developer Portal supports +[Github-flavored markdown](https://github.github.com/gfm/) (GFM) that can be +used in lieu of the [templates](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/working-with-templates). Instead of having to +create an HTML layout and partials for your templates, you can use custom CSS +with the improved markdown rendering module. The extended markdown support +improves rendering significantly, especially for tables. + +## Prerequisites + +* Access to Kong Manager +* The Developer Portal is enabled and running + +## Specify the markdown rendering module in a document + +1. Create a markdown file for your Dev Portal documentation. +2. Call the markdown module using the `layout` parameter. +3. Specify the `.css` file you want to use. You can use the default Github `.css` as shown, or specify your own custom `.css`. + + - All markdown CSS classes should be prepended by `.markdown-body`. This is + to ensure that markdown styles do not bleed into other areas of the portal. + - The `.css` file should be placed in the current theme's `/assets` directory. + - The renderer assumes the `.css` path will begin from the `/assets` + directory. See the example below. + - Other classes defined in any other Dev Portal CSS external to the + `markdown.css` may pollute your rendered markdown. If you want to unset + particular styles, you can do so using the + `/assets/style/markdown-fixes.css` file. + +### Example + +`/content/markdown-example.md` + +``` +--- +layout: system/markdown.html +css: assets/style/markdown.css +--- +``` diff --git a/src/gateway/kong-enterprise/dev-portal/customize/migrating-templates.md b/src/gateway/kong-enterprise/dev-portal/customize/migrating-templates.md new file mode 100644 index 000000000000..5558ad8aefdf --- /dev/null +++ b/src/gateway/kong-enterprise/dev-portal/customize/migrating-templates.md @@ -0,0 +1,46 @@ +--- +title: Migrating Templates Between Workspaces +badge: enterprise +--- + +The template styling from your default Dev Portal doesn't automatically apply to new Dev Portals you create in other workspaces. However, with the [Portal CLI](/gateway/latest/kong-enterprise/dev-portal/cli/), you can move over templates in a few steps. + +## Prerequisites + +* Install [Portal CLI](/gateway/latest/kong-enterprise/dev-portal/cli/) and set up the [configuration](/gateway/latest/kong-enterprise/dev-portal/cli/#usage). + +## Apply customization from default Dev Portal + +To apply customizations from one Dev Portal to another, do the following: + +1. From your Kong Manager, create a new Workspace and enable a new Dev Portal. In the rest of this document, the new Workspace name will be referred to as `{WORKSPACE_NAME}`. + +1. Clone the Kong Portal Templates repository: + + ```bash + git clone https://github.com/Kong/kong-portal-templates + ``` + +1. Move into `kong-portal-templates`: + + ```bash + cd kong-portal-templates + ``` + +1. Fetch the default workspace: + + ```bash + portal fetch default + ``` + +1. Copy the templates from the default workspace to another workspace: + + ```bash + cp workspaces/default workspaces/{WORKSPACE_NAME} + ``` + +1. Deploy the templates to the new workspace: + + ```bash + portal deploy {WORKSPACE_NAME} + ``` diff --git a/src/gateway/kong-enterprise/dev-portal/customize/single-page-app.md b/src/gateway/kong-enterprise/dev-portal/customize/single-page-app.md new file mode 100644 index 000000000000..765b47119c72 --- /dev/null +++ b/src/gateway/kong-enterprise/dev-portal/customize/single-page-app.md @@ -0,0 +1,144 @@ +--- +title: Hosting Single Page App out of Kong Dev Portal +badge: enterprise +--- + +The Kong Developer Portal ships with a default server-side rendered theme; however, it is possible to replace this with a Single Page App (SPA). This example is in Angular using the Angular CLI Tool, but you can follow along with any other JavaScript framework with just a few tweaks. + +To view the basic example Angular template from this guide, visit the [`example/spa-angular`](https://github.com/Kong/kong-portal-templates/tree/example/spa-angular) branch from the `kong-portal-templates branch`. + +## Prerequisites + +* Portal Legacy is turned off +* The Developer Portal is enabled and running +* kong-portal-cli tool is installed locally + +## What is a SPA + +A Single Page App (SPA) is a website that loads all HTML, JavaScript, and CSS on the first load. Instead of loading subsequent pages from the server, JavaScript is used to dynamically change the page content. You may want to use an SPA in Dev Portal if you have a preexisting SPA you want to integrate with the portal, or you are trying to achieve a more application-like experience across many pages. An SPA takes control of routing from the server, and handles it client-side instead. + +Custom JavaScript can also be added to run only on specific layouts, allowing you to maintain server-side rendering. [Learn more](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/customize/adding-javascript-assets) about adding JavaScript to a layout without implementing an SPA. + +## Making Choices + + +We recommend Catalog and Spec routes not be handled by SPA. +If you are using Authentication, then you probably also want to leave server-side rendering for any account pages. + +## Getting Started + +Clone the [portal-templates](https://github.com/Kong/kong-portal-templates) repo + +Create a file called `router.conf.yaml` in `workspaces/default` This file will override the default routing, allowing you to control routing via JavaScript. + +`router.conf.yaml` must be a yaml file, where the key is each route, and the value a content or spec path. `/*` Is a catch-all wildcard for all routes not specified in `router.conf.yaml`, it will overwrite all default routing set by collections or set in headmatter. + +In the `router.conf.yaml` example below, we are hardcoding routing for all kong related functionality and deferring to SPA routing for all other routes. The `/*` route at the bottom of the file is a wildcard route. The wildcard route, in this case, tells Kong to serve `content/index.txt` for any request that is not handled by the route declarations above. + +``` +/login: content/login.txt +/logout: content/logout.txt +/register: content/register.txt +/settings: content/settings.txt +/reset-password: content/reset-password.txt +/account/invalidate-verification: content/account/invalidate-verification.txt +/account/resend-verification: content/account/resend-verification.txt +/account/verify: content/account/resend-verification.txt +/documentation: content/documentation/index.txt +/documentation/httpbin: specs/httpbin.json +/documentation/petstore: specs/petstore.yaml +/*: content/index.txt + +``` + +### Create your SPA + +Create an SPA app in the JavaScript framework of your choice. This +example uses angular. + +``` +ng new +``` + +Make sure to include a 404 route, as well as all routes you want to have on the Portal (excluding the routes handled by server-side rendering excluded above). + +Run the build process + +For angular: + +``` +ng build +``` + +Copy the build output JS and CSS files to a folder inside `workspaces/default/themes/assets/js`. + +For this example, place the angular build inside a `workspaces/default/themes/assets/js/ng`. + +### Mounting an SPA + +To load our JS, we need to mount it. Let's create a new layout page. + +Create a file called `spa.html` in `workspaces/default/themes/layouts`. + +This file will need to contain the html element that the SPA will mount to as well as the scripts necessary to do this. +For reference, view the `index.html` inside the build folder created by the build step of the SPA. + +The example uses `layouts/_base.html` as the base for the layout template. +By doing so, the element is handled the same way as other pages in the portal, as well as the same CSS and scripts. + +If you want to have the top nav bar and bottom nav bar, be sure to include them in your layout. + +This is the resulting layout: + +{% raw %} +``` +{% layout = "layouts/_base.html" %} +{-main-} + + {(partials/header.html)} +
      + +
      + {(partials/footer.html)} + + + + + + + + + + + + + +{-main-} +``` +{% endraw %} + +If the SPA build process creates a css file, edit the `head.html` partial to include your css file. + +### Loading your layout + +Modify `workspaces/default/content/index.txt` to use your layout. +The title you set here will be the one that displays until the JS set title loads. + +{% raw %} +``` +--- +layout: spa.html +title: Home +--- +``` +{% endraw %} + +### Deploy the Portal + +Now using the kong-portal-cli tool, deploy the portal. + +From the root folder of the templates repo: + +``` +portal deploy default +``` diff --git a/src/gateway/kong-enterprise/dev-portal/customize/theme-editing.md b/src/gateway/kong-enterprise/dev-portal/customize/theme-editing.md new file mode 100644 index 000000000000..bd64c2e32f2d --- /dev/null +++ b/src/gateway/kong-enterprise/dev-portal/customize/theme-editing.md @@ -0,0 +1,29 @@ +--- +title: Theme Editing in Kong Manager +badge: enterprise +--- + +The Kong Developer Portal ships with a default theme, including preset images, background colors, fonts, and button styles. These settings can be edited quickly and easily from within Kong Manager, without the need to edit code. + +## Prerequisites + +* Access to Kong Manager +* The Developer Portal is enabled and running + +## The Appearance Tab + +{:.note} +> **Note**: Styling does not automatically carry over from the default Dev Portal to different Dev Portals in other workspaces. See [Migrating Templates Between Workspaces](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/customize/migrating-templates) to learn how to manually copy templates to workspaces where you want to duplicate the styling. + +From the **Workspace** dashboard in **Kong Manager**, click on the **Appearance** tab under **Dev Portal** on the left side bar. +This will open the Developer Portals theme editor. From this page, the header logo, background colors, font colors, and button styles can be edited using the color picker interface. + +The predefined variables refer to the following elements: + +![Appearance Tab - Variables](/assets/images/docs/dev-portal/appearance-dev-portal.png) + +Hovering over an element will show a color picker, as well as a list of predefined colors. These colors are defined by the current template and can be edited in the [theme.conf.yaml](#editing-theme-files-with-the-editor) file + +## Editing Theme Files with the Editor + +The Dev Portal Editor within Kong Manager exposes the default Dev Portal theme files. The theme files can be found at the bottom of the file list under *Themes*. The variables exposed in the *Appearance* tab can be edited in the `theme.conf.yaml` file. See [Using the Editor](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/using-the-editor) for more information on how to edit, preview, and save files in the Editor. diff --git a/src/gateway/kong-enterprise/dev-portal/enable.md b/src/gateway/kong-enterprise/dev-portal/enable.md new file mode 100644 index 000000000000..9d4ce690035d --- /dev/null +++ b/src/gateway/kong-enterprise/dev-portal/enable.md @@ -0,0 +1,62 @@ +--- +title: How To Enable the Dev Portal +badge: enterprise +--- + +Enable Dev Portal in the Kong Configuration or within a Docker container for Docker installations. + +## Enable Dev Portal in the Kong Configuration + +1. To enable the Dev Portal, the following properties must be set in the Kong +configuration file (`kong.conf`): + + ```bash + portal = on + ``` + + {{site.base_gateway}} must be **restarted** for this value to take effect. + +2. Enable the default Workspace Dev Portal via Kong Manager: + + 1. Navigate to the default Workspace in Kong Manager + 2. Click the **Settings** link under **Dev Portal** + 3. Toggle the **Dev Portal Switch** + + It may take a few seconds for the Settings page to populate. + + To enable the default Workspace's Dev portal via the command line: + + ```bash + curl -X PATCH http://localhost:8001/workspaces/default --data "config.portal=true" + ``` + + - This will expose the **default Dev Portal** at [http://localhost:8003/default](http://localhost:8003/default) + - The **Dev Portal Files endpoint** can be accessed at `:8001/files` + - The **Public Dev Portal Files API** can be accessed at `:8004/files` + +## Enable Dev Portal with Docker installation + +{:.note} +> This feature is only available with a [{{site.konnect_product_name}} Enterprise](/gateway/{{page.kong_version}}/licenses) subscription. + +1. [Deploy a license](/gateway/{{page.kong_version}}/licenses/deploy). + +2. In your Docker container, set the Portal URL and set `KONG_PORTAL` to `on`: + + ```plaintext + echo "KONG_PORTAL_GUI_HOST=localhost:8003 KONG_PORTAL=on kong reload exit" \ + | docker exec -i kong /bin/sh + ``` + + {:.note} + > The `HOSTNAME` for `KONG_PORTAL_GUI_HOST` should not be preceded by a protocol, for example, `http://`. + +3. Execute the following command: + +
      curl -X PATCH --url http://
      {HOSTNAME}
      :8001/workspaces/default \ + --data "config.portal=true"
      + +4. Access the Dev Portal for the default workspace using the URL specified +in the `KONG_PORTAL_GUI_HOST` variable: + +
      http://
      {HOSTNAME}
      :8003/default
      diff --git a/src/gateway/kong-enterprise/dev-portal/index.md b/src/gateway/kong-enterprise/dev-portal/index.md new file mode 100644 index 000000000000..93938c235ed5 --- /dev/null +++ b/src/gateway/kong-enterprise/dev-portal/index.md @@ -0,0 +1,12 @@ +--- +title: Kong Dev Portal +badge: enterprise +--- + +The Kong Dev Portal provides a single source of truth for all developers +to locate, access, and consume services. With intuitive content management for +documentation, streamlined developer onboarding, and role-based access control +(RBAC), Kong’s Dev Portal provides a comprehensive solution for creating +and customizing a unified developer experience. + +![Dev Portal](/assets/images/docs/dev-portal/dev-portal-homepage.png) diff --git a/src/gateway/kong-enterprise/dev-portal/portal-api.md b/src/gateway/kong-enterprise/dev-portal/portal-api.md new file mode 100644 index 000000000000..906953f82e85 --- /dev/null +++ b/src/gateway/kong-enterprise/dev-portal/portal-api.md @@ -0,0 +1,15 @@ +--- +title: Portal API +no_version: true +toc: false +layout: default +--- + + + + + + diff --git a/src/gateway/kong-enterprise/dev-portal/publish-spec.md b/src/gateway/kong-enterprise/dev-portal/publish-spec.md new file mode 100644 index 000000000000..3e082cca484c --- /dev/null +++ b/src/gateway/kong-enterprise/dev-portal/publish-spec.md @@ -0,0 +1,26 @@ +--- +title: Publish an API Spec to the Dev Portal +badge: enterprise +content_type: how-to +--- + +The Dev Portal provides a single source of truth for all developers to locate, access, and consume services. With intuitive content management for documentation, streamlined developer onboarding, and role-based access control (RBAC), the Dev Portal provides a comprehensive solution for creating and customizing a unified developer experience. + + +1. In Kong Manager, navigate to **Dev Portal** > **Editor** and open the link in a new tab. + +2. Click **New File** to add a new spec. + +3. Select **spec** from the drop-down menu. + +4. Click **Create File**. + +6. Paste the contents of your API spec. + +7. Click **Save Changes**. + +## More information + +* [Customizing the look and feel of the site and editor](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/customize/theme-editing) +* [Managing access](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/authentication/managing-developers/) +* [Enable the Dev Portal](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/enable/) \ No newline at end of file diff --git a/src/gateway/kong-enterprise/dev-portal/smtp.md b/src/gateway/kong-enterprise/dev-portal/smtp.md new file mode 100644 index 000000000000..e28b5c2fa093 --- /dev/null +++ b/src/gateway/kong-enterprise/dev-portal/smtp.md @@ -0,0 +1,19 @@ +--- +title: Dev Portal SMTP Configuration +badge: enterprise +--- + +Dev Portal enables SMTP configuration via email variables, which are used by the Dev Portal to send emails to Kong admins and developers. + +For comprehensive documentation on SMTP configuration properties, see [Default Portal SMTP Configuration](/gateway/{{page.kong_version}}/reference/configuration/#default-portal-smtp-configuration-section). + +These settings can be modified in the `Kong Manager` under the Dev Portal `Settings / Email` tab, or by running the following command: + +```bash +curl http://localhost:8001/workspaces/ \ + --data "config.=off" +``` + +If they are not modified manually, the Dev Portal will use the default value defined in the Kong Configuration file. + +Dev Portal email content and styling can be customized via [template files](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/customize/emails/). diff --git a/src/gateway/kong-enterprise/dev-portal/structure-and-file-types.md b/src/gateway/kong-enterprise/dev-portal/structure-and-file-types.md new file mode 100644 index 000000000000..2e7c335ab9e4 --- /dev/null +++ b/src/gateway/kong-enterprise/dev-portal/structure-and-file-types.md @@ -0,0 +1,319 @@ +--- +title: Developer Portal Structure and File Types +badge: enterprise +--- + +The Kong Portal templates have been completely revamped to allow for easier customization, clearer separation of concerns between content and layouts, and more powerful hooks into Kong lifecycle/data. Under the hood, we have implemented a flat file CMS built on top of the `https://github.com/bungle/lua-resty-template` library. This system should feel familiar for anyone who has worked with projects like `jekyll`, `kirby cms`, or `vuepress` in the past. + +{:.note} +>Note: To follow along with this guide, it is best to clone the [kong-portal-templates repo](https://github.com/Kong/kong-portal-templates) and check out the `master` branch. This guide makes the assumption that you are working within a single workspace (the templates repo can host many different sets of portal files per workspace). Navigate to the `workspaces/default` directory from root to view the default workspaces portal files. + +## Directory Structure + +Navigate to `workspaces/default` from the `kong-portal-templates` root directory to access the default portals template files. The relative file structure in this directory directly maps to the file `path` schema attribute. (`content/homepage.txt` here maps to `content/homepage.txt` in Kong). + +From `workspaces/default`, you can see the different elements that make up a single instance of the kong developer portal: +- **content/** + - The content directory contains files that determine both site structure of the Kong Dev Portal as well as the dynamic content that renders within each page. +- **specs/** + - Specs are similar to content in that they contain the data needed to render dynamic content on the page. In the case of `specs`, the files contain valid OAS or Swagger to be rendered as a spec. +- **themes/** + - The theme directory contains different themes to be applied to the content of the portal. Each theme contains html templates, assets, and a config file that sets global styles available to the theme. +- **portal.conf.yaml** + - This config file determines which theme the portal uses to render, the name of the portal, as well configuration for special behavior such as redirect paths for user actions like login/logout. +- **router.conf.yaml (optional)** + - This optional config file overrides the portals default routing system with hardcoded values. This is useful for implementing single page applications, as well as for setting a static site structure. + +## Portal Configuration File + +### Path +- **format:** `portal.conf.yaml` +- **file extensions:** `.yaml` + +### Description +The Portal Configuration File determines which theme the portal uses to render, the name of the portal, as well as configuration for special behavior such as redirect paths for user actions like login/logout. It is required in the root of every portal. There can only be one Portal Configuration File, it must be named `portal.conf.yaml`, and it must be a direct child of the root directory. + +### Example + +```yaml +name: Kong Portal +theme: + name: light-theme +redirect: + unauthenticated: login + unauthorized: unauthorized + login: dashboard + logout: '' + pending_approval: '' + pending_email_verification: '' +collections: + posts: + output: true + route: /:stub/:collection/:name + layout: post.html +``` + +- `name`: + - **required**: true + - **type**: `string` + - **description**: The name attribute is used for meta information, such as setting a title for your portal in the browser tab. + - **example**: `Kong Portal` +- `theme` + - **required**: true + - **type**: `object` + - **description**: The theme object is used for declaring which theme you would like your portal to render, as well as theme style overrides. While the overrides are not required, declaring which theme you would like to use is. +- `redirect` + - **required**: true + - **type**: `object` + - **description**: The redirect object informs kong how to redirect the user after certain actions. If one of these values is not set, Kong serves a default template based off of the action. Each key represents the name of the action taking place, the value represents the route to which the application redirects the user. +- `collections` + - **required**: false + - **type**: `object` + - **description**: Collections are a powerful tool enabling you to render sets of content as a group. Content rendered as a collection share a configurable route pattern, as well as a layout. For more information check out the [collections](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/working-with-templates/#collections) section of our [Working with Templates](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/working-with-templates) guide. + + +## Router Configuration File (Optional) + +### Path +- **format:** `router.conf.yaml` +- **file extensions:** `.yaml` + +### Description +This optional config file overrides the portals default routing system with hardcoded values. This is useful for implementing single page applications, as well as for setting a static site structure. There can only be one Router Configuration File, it must be named `router.conf.yaml`, and it must be a direct child of the root directory. + +### Example +The `router.conf.yaml` file expects sets of key-value pairs. The key should be the route you want to set; the value should be the content file path you want that route to resolve to. Routes should begin with a backslash. `/*` is a reserved route and acts as a catchall/wildcard. If the requested route is not explicitly defined in the config file, the portal will resolve to the wildcard route if present. + +```yaml +/*: content/index.txt +/about: content/about/index.txt +/dashboard: content/dashboard.txt +``` + +## Content Files + +### Path +- **format:** `content/**/*` +- **file extensions:** `.txt`, `.md`, `.html`, `.yaml`, `.json` + +### Description +Content files establish portal site structure, as well as provide its accompanying HTML layout with metadata and dynamic content at the time of render. Content files can be nested in as many subdirectories as desired as long as the parent directory is `content/`. + +In addition to providing metainfo and content for the current page at time of render, content files determine the path at which a piece of content can be accessed in the browser. + +| Content Path | Portal URL | +|-------------|---------------------------| +| `content/index.txt` | `http://portal_gui_url/` | +| `content/about.txt` | `http://portal_gui_url/about` | +| `content/documentation/index.txt` | `http://portal_gui_url/documentation` | +| `content/documentation/spec_one.txt` | `http://portal_gui_url/documentation/spec_one` | + +### Contents +``` +--- +title: homepage +layout: homepage.html +readable_by: [red, blue] +--- + +Welcome to the homepage! +``` + +File contents can be broken down into two parts: `headmatter` and `body`. + +### headmatter + +The first thing to notice in the example files contents are the two sets of `---` delimiters at the start. The text contained within these markers is called `headmatter` and always gets parsed and validated as valid `yaml`. `headmatter` contains information necessary for a file to render successfully, as well as any information you would like to access within a template. Kong parses any valid `yaml` key-value pair and becomes available within the content's corresponding HTML template. There are a few reserved attributes that have special meaning to Kong at the time of render: + +- `title`: + - **required**: false + - **type**: `string` + - **description**: The title attribute is not necessary but is recommended. When set, this will set the title of a page in the browser tab. + - **example**: `homepage` +- `layout` + - **required**: true + - **type**: `string` + - **description**: The layout attribute is required for each piece of content, and determines what html layout to use in order to render the page. This attribute assumes a root of the current themes layout directory (`themes//layouts`). + - **example**: `bio.html` or `team/about.html` +- `readable_by` + - **required**: false + - **type**: `array` (multiple), `string` (singular) + - **description**: The optional `readable_by` attribute determines which developers can access a piece of content. In the case of the example above, only developers with rbac roles of "red" or "blue" may access the `/homepage` route. + - **example**: `[red, blue]` (multiple), `red` (singular) + +- `route` + - **required**: false + - **type**: `string` + - **description**: This optional attribute overrides the generated route Kong assigns to content, and replaces it with the route included here. + - **example**: `route: /example/dog` renders the example page above at `/example/dog` instead of the autogenerated `/homepage` route. +- `output` + - **required**: false + - **type**: `boolean` + - **default**: `true` + - **description**: This optional attribute is `true` by default and determines whether a piece of content should be rendered. No route or page gets created when this value is set to `false`. +- `stub` + - **required**: false + - **type**: `string` + - **description**: Used by `collection` config to determine custom routing. You can read more about Collections in the collections section of the _working with templates_ guide. + +#### body +The information located under headmatter represents the content body. Body content is freeform and gets parsed as by the file extension included in the file path. In the case of the example above, the file is `.txt` and is available in the template as such. + +## Spec Files + +### Path +- **format:** `specs/**/*` +- **file extensions:** `.yaml`, `.json` + +### Description +Specs are similar to `content` files in that they provide the dynamic data needed to render a page, as well as any metadata a user wants to provide as `headmatter`. The format in which these are provided to the Portal differs from `content` files, which can be seen in the example below. + +>It is recommended to keep spec folder structure flat. Spec files must be valid OAS or Swagger `.yaml`/`.yml` or `.json` files. + +### Contents + +``` +swagger: "2.0" +info: + version: 1.0.0 + title: Swagger Petstore + license: + name: MIT +host: petstore.swagger.io +basePath: /v1 +x-headmatter + - key1: val1 + - key2: val2 +... +``` + +Spec file contents themselves should be valid OAS or Swagger specifications. If you want +to inject headmatter into the specification, you can do so by including an `x-headmatter` +key to the root of the spec object. This may be useful if you wanted to, for example, +provide your own renderer template via `x-headmatter.layout` or override the spec's default +route via `x-headmatter.route`. + +Example: +``` +swagger: "2.0" +info: + version: 1.0.0 + title: Swagger Petstore + license: + name: MIT +host: petstore.swagger.io +basePath: /v1 +x-headmatter: + layout: custom/my-spec-renderer.html <- Custom Layout + route: my-special-route/myfirstspec <- Custom Route +... +``` + +Specs are a collection, meaning their `layout` and `route` are determined by the +portal configuration and not the file itself. Specs are rendered by default with +the `system/spec-renderer.html` layout, under the route pattern `/documentation/:name`, +where `:name` is the name of the particular spec file. So a spec with a path of +`specs/myfirstspec.json` renders in the portal as `/documentation/myfirstspec`. +If you want to overwrite the hardcoded spec collection config, you can do so by +including your own in `portal.conf.yaml`. Check out the Collections section of +our `Working with Templates` guide to learn more. + +You can also use the [Portal Files API](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/portal-api/) +to `POST`, `GET`, `PATCH`, and `DELETE` content, spec, and theme files. + +## Theme Files +### Themes Directory Structure +The theme directory contains different instances of portal themes, each one of which determines the look and feel of the developer portal via html/css/js. Which theme is used at time of render is determined by setting `theme.name` within `portal.conf.yaml`. Setting `theme.name` to `best-theme` causes the portal to load theme files under `themes/best-theme/**`. + +Each theme file is composed of a few different folders: +- **assets/** + - The assets directory contains static assets that layouts/partials will reference at time of render. Includes CSS, JS, font, and image files. +- **layouts/** + - The layouts directory contains html page templates that `content` reference via the `layout` attribute in headmatter (see `content` section). +- **partials/** + - The partials directory contains html partials to be referenced by layouts. Can be compared to how layouts and partials interacted in the legacy portal. +- **theme.conf.yaml** + - This config file sets color and font defaults available to templates for reference as css variables. It also determines what options are available in the Kong Manager Appearance page. + +### Theme Assets + +#### Path +- **format:** `theme/*/assets/**/*` + +#### Description +The asset folder contains css/js/fonts/images for your templates to reference. + +To access asset files from your templates, keep in mind that Kong assumes a path from the root of your selected theme. + +| Asset Path | Href Element | +|--------------------------|---------------------------| +| `themes/light-theme/assets/images/image1.jpeg` | `` | +| `themes/light-theme/assets/js/my-script.js` | `` | +| `themes/light-theme/assets/styles/my-styles.css` | `` | + +>Note: Image files uploaded to the `theme/*/assets/` directory should either be a svg text string or `base64` encoded, `base64` images will be decoded when served. + +### Theme Layouts + +#### Path +- **format:** `theme/*/layouts/**/*` +- **file extensions:** `.html` + +#### Description +Layouts act as the html skeleton of the page you want to render. Each file within the layouts directory must have an `html` filetype. They can exist as vanilla `html`, or can reference partials and parent layouts via the portals templating syntax. Layouts also have access to the `headmatter` and `body` attributes set in `content`. + +The example below shows what a typical layout could look like. + +{% raw %} +```html +
      + {(partials/header.html)} <- syntax for calling a partial within a template +
      +
      +

      {{page.title}}

      <- 'title' retrieved from page headmatter +
      +
      +

      {{page.body}}

      <- 'body' retrieved from page body +
      +
      + {(partials/footer.html)} +
      +``` +{% endraw %} + +To learn more about the templating syntax used in this example, check out our [templating guide](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/working-with-templates). + +### Theme Partials + +#### Path +- **format:** `theme/*/partials/**/*` +- **file extensions:** `.html` + +#### Description +Partials are very similar to layouts: they share the same syntax, can call other partials within themselves, and have access to the same data/helpers at time of render. The thing that differentiates partials from layouts it that layouts call on partials to build the page, but partials cannot call on layouts. + +The example below shows the `header.html` partial referenced from the example above: + +{% raw %} +```html +
      +
      +
      + <- can access the same page data the parent layout +
      +
      + {(partials/header_nav.html)} <- partials can call other partials +
      +
      +
      +``` +{% endraw %} + +### Theme Configuration File + +#### Path +- **format:** `theme/*/theme.conf.yaml` +- **file extensions:** `.yaml` + +#### Description +The Theme Configuration File determines color/font/image values a theme makes available for templates/CSS at the time of render. It is required in the root of every theme. There can only be one Theme Configuration File, it must be named `theme.conf.yaml`, and it must be a direct child of the themes root directory. diff --git a/src/gateway/kong-enterprise/dev-portal/themes.md b/src/gateway/kong-enterprise/dev-portal/themes.md new file mode 100644 index 000000000000..5e86cde57450 --- /dev/null +++ b/src/gateway/kong-enterprise/dev-portal/themes.md @@ -0,0 +1,98 @@ +--- +title: Themes Files +content-type: reference +--- + +## Theme files +### Themes directory structure +Theme files allow you to determine the look and feel of the Dev Portal using HTML, CSS, and JavaScript. The theme directory contains different instances of portal themes. The theme that is used during rendering is determined by configuring the `theme.name` in the `portal.conf.yaml` file. For example, if you set `theme.name` to `best-theme`, the Dev Portal loads theme files in `themes/best-theme/**`. + +A theme file is composed of the following directories: +- **assets/**: Contains static assets that layouts and partials reference during rendering. Includes CSS, JS, font, and image files. +- **layouts/**: Contains HTML page templates that `content` references via the `layout` attribute in `headmatter` +- **partials/**: Contains HTML partials that are referenced by layouts. +- **theme.conf.yaml**: Sets the color and font defaults that are available to templates as CSS variables. It also determines which options are available on the Kong Manager appearance page. + +## Theme assets + +### Path +- **format:** `theme/*/assets/**/*` + +### Description +The asset directory contains CSS, JavaScript, fonts, and images for your templates to reference. + +To access asset files from your templates, keep in mind that {{site.base_gateway}} assumes a path from the root of your selected theme. + +| Asset Path | HREF Element | +|--------------------------|---------------------------| +| `themes/light-theme/assets/images/image1.jpeg` | `` | +| `themes/light-theme/assets/js/my-script.js` | `` | +| `themes/light-theme/assets/styles/my-styles.css` | `` | + +{:.note} +> **Note:** Image files uploaded to the `theme/*/assets/` directory should either be a `svg` text string or `base64` encoded. `base64` images are decoded when served. + +## Theme layouts + +### Path +- **format:** `theme/*/layouts/**/*` +- **file extensions:** `.html` + +### Description +Layouts act as the HTML skeleton of the page you want to render. Each file in the layouts directory must have an `html` file type. They can exist as vanilla `html` or reference partials and parent layouts via the portals templating syntax. Layouts also have access to the `headmatter` and `body` attributes set in `content`. + +This example shows what a typical layout can look like: + +{% raw %} +```html +
      + {(partials/header.html)} <- syntax for calling a partial within a template +
      +
      +

      {{page.title}}

      <- 'title' retrieved from page headmatter +
      +
      +

      {{page.body}}

      <- 'body' retrieved from page body +
      +
      + {(partials/footer.html)} +
      +``` +{% endraw %} + +To learn more about the templating syntax used in this example, see the [template guide](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/working-with-templates/). + +## Theme partials + +### Path +- **format:** `theme/*/partials/**/*` +- **file extensions:** `.html` + +### Description +Partials are very similar to layouts: they share the same syntax, can call other partials within themselves, and have access to the same data/helpers during rendering. Partials are differentiated from layouts in that layouts call on partials to build the page, but partials cannot call on layouts. + +This example shows the `header.html` partial referenced from previous example: + +{% raw %} +```html +
      +
      +
      + <- can access the same page data the parent layout +
      +
      + {(partials/header_nav.html)} <- partials can call other partials +
      +
      +
      +``` +{% endraw %} + +## Theme configuration file + +### Path +- **format:** `theme/*/theme.conf.yaml` +- **file extensions:** `.yaml` + +### Description +The theme configuration file determines color, font, and image values that a theme makes available to templates and CSS during rendering. It is required in the root of every theme. There can only be one theme configuration file. It must be named `theme.conf.yaml` and it must be a direct child of the themes root directory. diff --git a/src/gateway/kong-enterprise/dev-portal/using-the-editor.md b/src/gateway/kong-enterprise/dev-portal/using-the-editor.md new file mode 100644 index 000000000000..7cfb095cd626 --- /dev/null +++ b/src/gateway/kong-enterprise/dev-portal/using-the-editor.md @@ -0,0 +1,51 @@ +--- +title: Using the Editor through Kong Manager +badge: enterprise +--- + +Kong Manager offers a robust file editor for editing the template files of the Dev Portal from within the browser. + +## Prerequisites + +* Access to Kong Manager +* The Kong Developer Portal is **enabled** and **running** + +>NOTE: Editor Mode is *not* available when running the Dev Portal in **legacy** mode. + +## Enter Editor Mode + +From the **Kong Manager** dashboard of your **Workspace**, click **Editor** under **Dev Portal** in the sidebar. + +This will launch the **Editor Mode**. +## Navigating the Editor + +When enabled, the Dev Portal is pre-populated with Kong's default theme. The file editor exposes these files to the UI, allowing them to be edited quickly and easily from inside the browser. When you first open the editor, you will be presented with a list of files on the left, and a blank editing form. + +1. Create new files for the Dev Portal right from the Editor by clicking `New File+`. +1. List of all exposed template files in the Dev Portal, separated by Content / Spec / Themes. +1. Code View - Select a file from the sidebar to show the code here. +1. Portal Preview - View a live preview of the selected Dev Portal file. +1. Toggle View - Choose between three different views: full screen code, split view, and full screen preview mode. + +![Dev Portal with Numbers](/assets/images/docs/dev-portal/editor-mode-numbered.png) + +## Editing Files + +Select a file from the sidebar to open it for editing. This will expose the file to the Code View and show a live update in the Portal Preview. Clicking Save in the top right corner will save the updates to the database and update the file on the Dev Portal. + +## Adding new files + +Clicking the `New File +` button opens the New File Dialog. + +Once created, files will immediately be available from within the Editor. + +## Authenticating files + +Authentication is handled by `readable_by` value on content pages (for gui view, go to permissions page) + - set readable_by: '*' to equal old authenticated + - to restrict access to certain roles, set readable_by to an array of accepted roles (you must first create roles on the permissions page) + - on specs, readable_by is set inside "x-headmatter" object + +## Deleting files + +To _permanently_ delete a file from within the Editor, right click on the file name and select **Delete** from the popup menu. diff --git a/src/gateway/kong-enterprise/dev-portal/working-with-templates.md b/src/gateway/kong-enterprise/dev-portal/working-with-templates.md new file mode 100644 index 000000000000..a27be4f4ab96 --- /dev/null +++ b/src/gateway/kong-enterprise/dev-portal/working-with-templates.md @@ -0,0 +1,1416 @@ +--- +title: Working with Templates +badge: enterprise +--- + +Kong Portal is built on top of the `lua-resty-template` templating library, which can be viewed here: [https://github.com/bungle/lua-resty-template](https://github.com/bungle/lua-resty-template). Basic usage of the library will be described below. Refer to the source documentation for a more in-depth look at what it can accomplish. + +## Syntax +***(excerpt from lua-resty-templates documentation)*** + +You may use the following tags in templates: +{% raw %} +* `{{expression}}`, writes result of expression - HTML escaped +* `{*expression*}`, writes result of expression +* `{% lua code %}`, executes Lua code +* `{(path-to-partial)}`, include `partial` file by path, you may also supply context for the file `{(partials/header.html, { message = "Hello, World" } )}` + +* `{-block-}...{-block-}`, wraps inside of a `{-block-}` to a value stored in a `blocks` table with a key `block` (in this case), see [using blocks](https://github.com/bungle/lua-resty-template#using-blocks). Don't use predefined block names `verbatim` and `raw`. +* `{-verbatim-}...{-verbatim-}` and `{-raw-}...{-raw-}` are predefined blocks whose inside is not processed by the `lua-resty-template` but the content is outputted as is. +* `{# comments #}` everything between `{#` and `#}` is considered to be commented out (i.e., not outputted or executed). +{% endraw %} + +## Show custom properties + +You may work with custom properties in your OpenAPI spec. To expose custom properties in Dev Portal, change the property `showExtensions` to `true` in the `spec-renderer.html` file. By default, `showExtensions` is `false`. + +## Partials + +Partials are snippets of HTML that layouts can reference. Partials have access to all the same data that its layout does, and can even call other partials. Breaking your code into partials can help organize large pages, as well as allow different layouts share common page elements. + +### content/index.txt + +{% raw %} +``` +--- +layout: index.html +title: Partials +header_logo: assets/images/example.jpeg +header_nav_items: + about: + href: /about + guides: + href: /guides +hero_title: Partials Info +hero_description: Partials are wicked sick! +--- +``` +{% endraw %} + +### layouts/index.html + +{% raw %} +```html +{(partials/header.html)} +
      + {(partials/hero.html)} +
      +{(partials/footer.html)} +``` +{% endraw %} + +### partials/header.html + +{% raw %} +```html +
      +
      + +
      +
      + {(partials/header_nav.html)} +
      +
      +``` +{% endraw %} + +### partials/header_nav.html + +{% raw %} +``` html +
        + {% for title, href in each(page.header_nav_items) do %} +
      • {{title}}
      • + {% end %} +
      +``` +{% endraw %} + +### partials/hero.html + +{% raw %} +``` html +

      {{page.hero_title}}

      +

      {{page.hero_description}}

      +``` +{% endraw %} + + +### partials/hero.html + +{% raw %} +``` html +
      +

      footer

      +
      +``` +{% endraw %} + + +Output: + +{% raw %} +```html +
      +
      + +
      +
      + +
      +
      +

      Partials Info

      +

      Partials are wicked sick!

      +
      +

      footer

      +
      +``` +{% endraw %} + +## Blocks + +Blocks can be used to embed a view or partial into another template. Blocks are particularly useful when you want different templates to share a common wrapper. + +In the example below, notice that the content file is referencing `index.html`, and not `wrapper.html`. + +### content/index.txt + +{% raw %} +```markdown +--- +layout: index.html +title: Blocks +description: Blocks are the future! +--- +``` +{% endraw %} + + +### layouts/index.html + +{% raw %} +```html +{% layout = "layouts/wrapper.html" %} <- syntax declaring where to find the block + +{-main-} <- delimiter describing what content renders in block +
      +

      {{page.title}}

      +

      {{page.description}}

      +

      +{-main-} +``` +{% endraw %} + +### layouts/wrapper.html + +{% raw %} +```html + + + + Testing lua-resty-template blocks + + +
      +

      header

      +
      + {*main*} <- syntax indicating where to place the block +
      +

      footer

      +
      + + +``` +{% endraw %} + +Output: + +{% raw %} +```html + + + + Testing lua-resty-template blocks + + +
      +

      header

      +
      +
      +

      Blocks

      +

      Blocks are the future!

      +

      +
      +

      footer

      +
      + + +``` +{% endraw %} + +## Collections +Collections are a powerful tool enabling you to render sets of content as a group. Content rendered as a collection share a configurable route pattern, as well as a layout. Collections are configured in your portals `portal.conf.yaml` file. + +The example below shows all the necessary configuration/files needed to render a basic `blog` collection made up of individual `posts`. + +#### portal.conf.yaml + +{% raw %} +``` +name: Kong Portal +theme: + name: base +collections: + posts: + output: true + route: /:stub/:collection/:name + layout: post.html +``` +{% endraw %} + +Above you can see a `collections` object was declared, which is made up of individual collection configurations. In this example, you are configuring a collection called `posts`. The renderer looks for a root directory called `_posts` within the `content` folder for individual pages to render. If you created another collection conf called `animals`, the renderer would look for a directory called `_animals` for content files to render. + +Each configuration item is made up of a few parts: +- `output` + - **required**: false + - **type**: `boolean` + - **description**: This optional attribute determines whether the collections should render or not. When set to `false`, virtual routes for the collection are not created. +- `route` + - **required**: true + - **type**: `string` + - **default**: `none` + - **description**: The `route` attribute is required and tells the renderer what pattern to generate collection routes from. A collection route should always include at least one valid dynamic namespace that uniquely identifies each collection member. + - Any namespace in the route declaration which begins with `:` is considered dynamic. + - Only certain dynamic namespaces are recognized by Kong as valid: + - `:title`: Replaces namespace with a contents `title`, declared in headmatter. + - `:name`: Replaces namespace with the filename of a piece of content. + - `:collection`: Replaces namespace with name of current collection. + - `:stub`: Replaces namespace with value of `headmatter.stub` in each contents headmatter. +- `layout` + - **required**: true + - **type**: `string` + - **description**: The `layout` attribute determines what HTML layout the collections use to render. The path root is accessed from within the current themes `layouts` directory. + +### content/_posts/post1.md + +{% raw %} +``` +--- +title: Post One +stub: blog +--- + +This is my first post! +``` +{% endraw %} + + +### content/_posts/post2.md + +{% raw %} +``` +--- +title: Post Two +stub: blog +--- + +This is my second post! +``` +{% endraw %} + +### themes/base/layouts/post.html + +{% raw %} +```html +

      {{ page.title }}

      +

      {* page.body *}

      +``` +{% endraw %} + +Output: + +From `/blog/posts/post1`: + +```html +

      Post One

      +

      This is my first post!

      +``` + +From `/blog/posts/post2`: + +```html +

      Post Two

      +

      This is my second post!

      +``` + + +## Kong Template Helpers - Lua API +Kong Template Helpers are a collection of objects that give access to your portal data at the time of render and provide powerful integrations into Kong. + +Global: + +- [`l`](#lkey-fallback) - Locale helper, first version, gets values from the currently active page. +- [`each`](#eachlist_or_table) - Commonly used helper to iterate over lists or tables. +- [`print`](#printany) - Commonly used helper to print lists / tables. +- [`markdown`](#printany) - Commonly used helper to print lists / tables. +- [`json_decode`](#json_decode) - Decode JSON to Lua table. +- [`json_encode`](#json_encode) - Encode Lua table to JSON. + +Objects: + +- [`portal`](#portal) - The portal object refers to the current workspace portal being accessed. +- [`page`](#page) - The page object refers to the currently active page and its contents. +- [`user`](#user) - The user object represents the currently logged in developer accessing the Kong Portal. +- [`theme`](#theme) - The theme object represents the currently active theme and its variables. +- [`tbl`](#tbl) = Table helper methods. Examples: `map`, `filter`, `find`, `sort`. +- [`str`](#str) = String helper methods. Examples: `lower`, `upper`, `reverse`, `endswith`. +- [`helpers`](#helpers) - Helper functions simplify common tasks or provide easy shortcuts to Kong Portal methods. + + +Terminology / Definitions: + +- `list` - Also referred to commonly as an array (`[1, 2, 3]`) in Lua is a table-like object (`{1, 2, 3}`). Lua list index starts at `1` not `0`. Values can be accessed by array notation (`list[1]`). +- `table` - Also commonly known as an object or HashMap (`{1: 2}`) in Lua looks like (`{1 = 2}`). Values can be accessed by array or dot notation (`table.one or table["one"]`). + +### l(key, fallback) + +Returns the current translation by key from the currently active page. + +#### Return Type +{% raw %} + +```lua +string +``` +{% endraw %} + +#### Usage + +Using `content/en/example.txt`: + +{% raw %} +```yaml +--- +layout: example.html + +locale: + title: Welcome to {{portal.name}} + slogan: The best developer portal ever created. +--- +``` +{% endraw %} + + +Using `content/es/example.txt`: + +{% raw %} +```yaml +--- +layout: example.html + +locale: + title: Bienvenido a {{portal.name}} + slogan: El mejor portal para desarrolladores jamás creado. +--- +``` +{% endraw %} + + +Using `layouts/example.html`: + +{% raw %} +```lua +

      {* l("title", "Welcome to" .. portal.name) *}

      +

      {* l("slogan", "My amazing developer portal!") *}

      +

      {* l("powered_by", "Powered by Kong.") *}

      +``` +{% endraw %} + + +Output: + +For `en/example`: + +{% raw %} +```html +

      Welcome to Kong Portal

      +

      The best developer portal ever created.

      +

      Powered by Kong.

      +``` +{% endraw %} + + +For `es/example`: + +{% raw %} +```html +

      Bienvenido a Kong Portal

      +

      El mejor portal para desarrolladores jamás creado.

      +

      Powered by Kong.

      +``` +{% endraw %} + + +#### Notes + +- `l(...)` is a helper from the `page` object. It can be also accessed via `page.l`. However, `page.l` does not support template interpolation (for example, `{{portal.name}}` will not work.) + +### each(list_or_table) + +Returns the appropriate iterator depending on what type of argument is passed. + +#### Return Type + +```lua +Iterator +``` + +#### Usage + +Template (List): + +{% raw %} +```lua +{% for index, value in each(table) do %} +
        +
      • Index: {{index}}
      • +
      • Value: {{ print(value) }}
      • +
      +{% end %} +``` +{% endraw %} + + +Template (Table): + +{% raw %} +```lua +{% for key, value in each(table) do %} +
        +
      • Key: {{key}}
      • +
      • Value: {{ print(value) }}
      • +
      +{% end %} +``` +{% endraw %} + +### print(any) + +Returns the output of an input value as a string. + +#### Return Type + +```lua +string +``` + +#### Usage + +Template (Table): + +{% raw %} +```lua +
      {{print(page)}}
      +``` +{% endraw %} + +### markdown(string) + +Returns HTML from the markdown string passed as an argument. If a string argument is not valid markdown, the function will return the string as is. To render properly, the helper should be used with raw `{* *}` delimiters. + +#### Return Type + +```lua +string +``` + +#### Usage + +Template (string as an argument): + +{% raw %} +```lua +
      {* markdown("##This is Markdown") *}
      +``` +{% endraw %} + +Template (content val as an argument): + +{% raw %} +```lua +
      {* markdown(page.description) *}
      +``` +{% endraw %} + +### json_encode(object) + +JSON encodes Lua table passed as argument + +#### Return Type + +```lua +string +``` + +#### Usage + +Template: + +{% raw %} +```lua +
      {{ json_encode({ dog = cat }) }}
      +``` +{% endraw %} + +### json_decode(string) + +Decodes JSON string argument to Lua table + +#### Return Type + +```lua +table +``` + +#### Usage + +Template: + +{% raw %} +```lua +
      {{ print(json_encode('{"dog": "cat"}')) }}
      +``` +{% endraw %} + +### portal + +`portal` gives access to data relating to the current portal, this includes things like portal configuration, content, specs, and layouts. + + - [`portal.workspace`](#portalworkspace) + - [`portal.url`](#portalurl) + - [`portal.api_url`](#portalapi_url) + - [`portal.auth`](#portalauth) + - [`portal.specs`](#portalspecs) + - [`portal.specs_by_tag`](#portalspecs_by_tag) + - [`portal.developer_meta_fields`](#portaldeveloper_meta_fields) + +You can access the current workspace portal config directly on the `portal` object like so: + +```lua +portal[config_key] or portal.config_key +``` + +For example `portal.auth` is a portal config value. You can find a list of config values by reading the portal section of `kong.conf`. + +#### From kong.conf + +The portal only exposes config values that start with `portal_`, and they can be access by removing the `portal_` prefix. + +Some configuration values are modified or customized, these customizations are documented under the [Portal Members](#portal-members) section. + +##### portal.workspace + +Returns the current portal's workspace. + +##### Return Type + +```lua +string +``` + +##### Usage + +Template: + +{% raw %} +```hbs +{{portal.workspace}} +``` +{% endraw %} + +Output: + +```html +default +``` + +#### portal.url + +Returns the current portal's url with workspace. + +##### Return Type + +```lua +string +``` + +##### Usage + +Template: + +{% raw %} +```hbs +{{portal.url}} +``` +{% endraw %} + +Output: + +```html +http://127.0.0.1:8003/default +``` + +#### portal.api_url + +Returns the configuration value for `portal_api_url` with +the current workspace appended. + +##### Return Type + +```lua +string or nil +``` + +##### Usage + +Template: + +{% raw %} +```hbs +{{portal.api_url}} +``` +{% endraw %} + +Output when `portal_api_url = http://127.0.0.1:8004`: + +```html +http://127.0.0.1:8004/default +``` + +#### portal.auth + +Returns the current portal's authentication type. + +##### Return Type + +```lua +string +``` + +##### Usage + +**Printing a value** + +Input: + +{% raw %} +```hbs +{{portal.auth}} +``` +{% endraw %} + +Output when `portal_auth = basic-auth`: + +```html +basic-auth +``` + +**Checking if authentication is enabled** + +Input: + +{% raw %} +```hbs +{% if portal.auth then %} + Authentication is enabled! +{% end %} +``` +{% endraw %} + +Output when `portal_auth = basic-auth`: + +```html +Authentication is endabled! +``` + +#### portal.specs + +Returns an array of specification files contained within the current portal. + +##### Return type + +```lua +array +``` + +##### Usage + +**Viewing a content value** + +Template: + +{% raw %} +```hbs +
      {{ print(portal.specs) }}
      +``` +{% endraw %} + +Output: + +```lua +{ + { + "path" = "content/example1_spec.json", + "content" = "..." + }, + { + "path" = "content/documentation/example1_spec.json", + "content" = "..." + }, + ... +} +``` + +**Looping through values** + +Template: + +{% raw %} +```hbs +{% for _, spec in each(portal.specs) %} +
    • {{spec.path}}
    • +{% end %} +``` +{% endraw %} + +Output: + +```hbs +
    • content/example1_spec.json
    • +
    • content/documentation/example1_spec.json
    • +``` + +**Filter by path** + +Template: + +{% raw %} +```hbs +{% for _, spec in each(helpers.filter_by_path(portal.specs, "content/documentation")) %} +
    • {{spec.path}}
    • +{% end %} +``` +{% endraw %} + +Output: + +```hbs +
    • content/documentation/example1_spec.json
    • +``` + +#### portal.developer_meta_fields + +Returns an array of developer meta fields available/required by Kong to register a developer. + +#### Return Type + +```lua +array +``` + +##### Usage + +**Printing a value** + +Template: + +{% raw %} +```hbs +{{ print(portal.developer_meta_fields) }} +``` +{% endraw %} + +Output: + +{% raw %} +```lua +{ + { + label = "Full Name", + name = "full_name", + type = "text", + required = true, + }, + ... +} +``` +{% endraw %} + +**Looping through values** + +Template: + +{% raw %} +```hbs +{% for i, field in each(portal.developer_meta_fields) do %} +
        +
      • Label: {{field.label}}
      • +
      • Name: {{field.name}}
      • +
      • Type: {{field.type}}
      • +
      • Required: {{field.required}}
      • +
      +{% end %} +``` +{% endraw %} + +Output: + +```html +
        +
      • Label: Full Name
      • +
      • Name: full_name
      • +
      • Type: text
      • +
      • Required: true
      • +
      +... +``` + +### page + +`page` gives access to data relating to the current page, which includes things like page url, path, breadcrumbs, and more. + + - [`page.route`](#pageroute) + - [`page.url`](#pageurl) + - [`page.breadcrumbs`](#pagebreadcrumbs) + - [`page.body`](#pagebody) + +When you create a new content page, you are able to define key-values. Here you are going to learn how to access those values and a few other interesting things. + +You can access the key-values you define directly on the `page` object like so: + +{% raw %} +```lua +page[key_name] or page.key_name +``` +{% endraw %} + +You can also access nested keys like so: + +```lua +page.key_name.nested_key +``` +{% raw %} +Be careful! To avoid output errors, make sure that the `key_name` exists before accessing `nested_key` as shown below: +```hbs +{{page.key_name and page.key_name.nested_key}} +``` +{% endraw %} + +#### page.route + +Returns the current page's route/path. + +##### Return Type + +```lua +string +``` + +##### Usage + +Template: + +{% raw %} +```hbs +{{page.route}} +``` +{% endraw %} + +Output, given url is `http://127.0.0.1:8003/default/guides/getting-started`: + +```html +guides/getting-started +``` + +#### page.url + +Returns the current page's url. + +##### Return Type + +```lua +string +``` + +##### Usage + +Template: + +{% raw %} +```hbs +{{page.url}} +``` +{% endraw %} + +Output, given url is `http://127.0.0.1:8003/default/guides/getting-started`: + +```html +http://127.0.0.1:8003/default/guides/getting-started +``` + +#### page.breadcrumbs + +Returns the current page's breadcrumb collection. + +##### Return Type + +```lua +table[] +``` + +##### Item Properties + +- `item.path` - Full path to item, no forward-slash prefix. +- `item.display_name` - Formatted name. +- `item.is_first` - Is this the first item in the list? +- `item.is_last` - Is this the last item in the list? + +##### Usage + +Template: + +{% raw %} +```hbs + +``` +{% endraw %} + +#### page.body + +Returns the body of the current page as a string. If the route's content file has a `.md` or `.markdown` extension, the body will be parsed from markdown to HTML. + +##### Return Type + +```lua +string +``` + +##### Usage for .txt, .json, .yaml, .yml templates + +`index.txt`: + +```hbs +This is text content. +``` + +Template: +{% raw %} +```hbs +

      This is a title

      +

      {{ page.body) }}

      +``` +{% endraw %} + +Output: +``` +> # This is a title +> This is text content. +``` + +##### Usage for .md, .markdown templates + +Template (markdown): +Use the raw delimiter syntax `{* *}` to render markdown within a template. + +`index.txt` +```hbs +# This is a title +This is text content. +``` + +Template: +```hbs +{* page.body *} +``` + +Output: +``` +> # This is a title +> This is text content. +``` + +### user + +`user` gives access to data relating to the currently authenticated user. User object is only applicable when `KONG_PORTAL_AUTH` is enabled. + + - [`user.is_authenticated`](#useris_authenticated) + - [`user.has_role`](#userhas_role) + - [`user.get`](#userget) + + +#### user.is_authenticated + +Returns `boolean` value as to the current user's authentication status. + +##### Return Type + +```lua +boolean +``` + +##### Usage + +Template: + +{% raw %} +```hbs +{{print(user.is_authenticated)}} +``` +{% endraw %} + +Output: + +```html +true +``` + +#### user.has_role + +Returns `true` if a user has a role given as an argument. + +##### Return Type + +```lua +boolean +``` + +##### Usage + +Template: + +{% raw %} +```hbs +{{print(user.has_role("blue"))}} +``` +{% endraw %} + +Output: + +```html +true +``` + +#### user.get + +Takes developer attribute as an argument and returns value if present. + +##### Return Type + +```lua +any +``` + +##### Usage + +Template: + +{% raw %} +```hbs +{{user.get("email")}} +{{print(user.get("meta"))}} +``` +{% endraw %} + +Output: + +```html +example123@konghq.com +{ "full_name" = "example" } +``` + + +### theme + +The `theme` object exposes values set in your `theme.conf.yaml` file. In addition, any variable overrides contained in `portal.conf.yaml` will be included as well. + + - [`theme.colors`](#usercolors) + - [`theme.color`](#usercolor) + - [`theme.fonts`](#userfonts) + - [`theme.font`](#userfont) + + +#### theme.colors + +Returns a table of color variables and their values as key-value pairs. + +##### Return Type + +```lua +table +``` + +##### Usage + +`theme.conf.yaml`: + +```yaml +name: Kong +colors: + primary: + value: '#FFFFFF' + description: 'Primary Color' + secondary: + value: '#000000' + description: 'Secondary Color' + tertiary: + value: '#1DBAC2' + description: 'Tertiary Color' +``` + +Template: + +{% raw %} +```lua +{% for k,v in each(theme.colors) do %} +

      {{k}}: {{v}}

      +{% end %} +``` +{% endraw %} + +Output: + +```html +

      primary: #FFFFFF

      +

      secondary: #000000

      +

      tertiary: #1DBAC2

      +``` + +#### theme.color + +Description + +Takes color var by string argument, returns value. + +##### Return Type + +```lua +string +``` + +##### Usage + +`theme.conf.yaml`: + +```yaml +name: Kong +colors: + primary: + value: '#FFFFFF' + description: 'Primary Color' + secondary: + value: '#000000' + description: 'Secondary Color' + tertiary: + value: '#1DBAC2' + description: 'Tertiary Color' +``` + +Template: + +{% raw %} +```lua +

      primary: {{theme.color("primary")}}

      +

      secondary: {{theme.color("secondary")}}

      +

      tertiary: {{theme.color("tertiary")}}

      +``` +{% endraw %} + +Output: + +```html +

      primary: #FFFFFF

      +

      secondary: #000000

      +

      tertiary: #1DBAC2

      +``` + + +#### theme.fonts + +Returns table of font vars and their values as key-value pairs. + +##### Return Type + +```lua +table +``` + +##### Usage + +`theme.conf.yaml`: + +```yaml +name: Kong +fonts: + base: Roboto + code: Roboto Mono + headings: Lato +``` + +Template: + +{% raw %} +```lua +{% for k,v in each(theme.fonts) do %} +

      {{k}}: {{v}}

      +{% end %} +``` +{% endraw %} + +Output: + +```html +

      base: Roboto

      +

      code: Roboto Mono

      +

      headings: Lato

      +``` + +#### theme.font + +Takes font name by string argument, returns value. + +##### Return Type + +```lua +string +``` + +##### Usage + +`theme.conf.yaml`: + +```yaml +name: Kong +fonts: + base: Roboto + code: Roboto Mono + headings: Lato +``` + +Template: + +{% raw %} +```lua +

      base: {{theme.font("base")}}

      +

      code: {{theme.font("code")}}

      +

      headings: {{theme.font("headings")}}

      +``` +{% endraw %} + +Output: + +```html +

      base: #FFFFFF

      +

      code: #000000

      +

      headings: #1DBAC2

      +``` + +### str + +Table containing useful string helper methods. + +#### Usage + +`.upper()` example: + +{% raw %} +```lua +
      {{ str.upper("dog") }}
      +``` +{% endraw %} + +#### Methods + +##### str.[byte](https://www.gammon.com.au/scripts/doc.php?lua=string.byte) +##### str.[char](https://www.gammon.com.au/scripts/doc.php?lua=string.char) +##### str.[dump](https://www.gammon.com.au/scripts/doc.php?lua=string.dump) +##### str.[find](https://www.gammon.com.au/scripts/doc.php?lua=string.find) +##### str.[format](https://www.gammon.com.au/scripts/doc.php?lua=string.format) +##### str.[gfind](https://www.gammon.com.au/scripts/doc.php?lua=string.gfind) +##### str.[gmatch](https://www.gammon.com.au/scripts/doc.php?lua=string.gmatch) +##### str.[gsub](https://www.gammon.com.au/scripts/doc.php?lua=string.gsub) +##### str.[len](https://www.gammon.com.au/scripts/doc.php?lua=string.len) +##### str.[lower](https://www.gammon.com.au/scripts/doc.php?lua=string.lower) +##### str.[match](https://www.gammon.com.au/scripts/doc.php?lua=string.match) +##### str.[rep](https://www.gammon.com.au/scripts/doc.php?lua=string.rep) +##### str.[reverse](https://www.gammon.com.au/scripts/doc.php?lua=string.reverse) +##### str.[sub](https://www.gammon.com.au/scripts/doc.php?lua=string.sub) +##### str.[upper](https://www.gammon.com.au/scripts/doc.php?lua=string.upper) +##### str.[isalpha](https://stevedonovan.github.io/Penlight/api/libraries/pl.stringx.html#isalpha) +##### str.[isdigit](https://stevedonovan.github.io/Penlight/api/libraries/pl.stringx.html#isdigit) +##### str.[isalnum](https://stevedonovan.github.io/Penlight/api/libraries/pl.stringx.html#isalnum) +##### str.[isspace](https://stevedonovan.github.io/Penlight/api/libraries/pl.stringx.html#isspace) +##### str.[islower](https://stevedonovan.github.io/Penlight/api/libraries/pl.stringx.html#islower) +##### str.[isupper](https://stevedonovan.github.io/Penlight/api/libraries/pl.stringx.html#isupper) +##### str.[startswith](https://stevedonovan.github.io/Penlight/api/libraries/pl.stringx.html#startswith) +##### str.[endswith](https://stevedonovan.github.io/Penlight/api/libraries/pl.stringx.html#endswith) +##### str.[join](https://stevedonovan.github.io/Penlight/api/libraries/pl.stringx.html#join) +##### str.[splitlines](https://stevedonovan.github.io/Penlight/api/libraries/pl.stringx.html#splitlines) +##### str.[split](https://stevedonovan.github.io/Penlight/api/libraries/pl.stringx.html#split) +##### str.[expandtabs](https://stevedonovan.github.io/Penlight/api/libraries/pl.stringx.html#expandtabs) +##### str.[lfind](https://stevedonovan.github.io/Penlight/api/libraries/pl.stringx.html#lfind) +##### str.[rfind](https://stevedonovan.github.io/Penlight/api/libraries/pl.stringx.html#rfind) +##### str.[replace](https://stevedonovan.github.io/Penlight/api/libraries/pl.stringx.html#replace) +##### str.[count](https://stevedonovan.github.io/Penlight/api/libraries/pl.stringx.html#count) +##### str.[ljust](https://stevedonovan.github.io/Penlight/api/libraries/pl.stringx.html#ljust) +##### str.[rjust](https://stevedonovan.github.io/Penlight/api/libraries/pl.stringx.html#rjust) +##### str.[center](https://stevedonovan.github.io/Penlight/api/libraries/pl.stringx.html#center) +##### str.[lstrip](https://stevedonovan.github.io/Penlight/api/libraries/pl.stringx.html#lstrip) +##### str.[rstrip](https://stevedonovan.github.io/Penlight/api/libraries/pl.stringx.html#rstrip) +##### str.[strip](https://stevedonovan.github.io/Penlight/api/libraries/pl.stringx.html#strip) +##### str.[splitv](https://stevedonovan.github.io/Penlight/api/libraries/pl.stringx.html#splitv) +##### str.[partition](https://stevedonovan.github.io/Penlight/api/libraries/pl.stringx.html#partition) +##### str.[rpartition](https://stevedonovan.github.io/Penlight/api/libraries/pl.stringx.html#rpartition) +##### str.[at](https://stevedonovan.github.io/Penlight/api/libraries/pl.stringx.html#at) +##### str.[lines](https://stevedonovan.github.io/Penlight/api/libraries/pl.stringx.html#lines) +##### str.[title](https://stevedonovan.github.io/Penlight/api/libraries/pl.stringx.html#title) +##### str.[shorten](https://stevedonovan.github.io/Penlight/api/libraries/pl.stringx.html#shorten) +##### str.[quote_string](https://stevedonovan.github.io/Penlight/api/libraries/pl.stringx.html#quote_string) + + +### tbl + +Table containing useful table helper methods + +#### Usage + +`.map()` example: +{% raw %} +```lua +{% tbl.map({"dog", "cat"}, function(item) %} + {% if item ~= "dog" then %} + {% return true %} + {% end %} +{% end) %} +``` +{% endraw %} + +#### Methods + +##### tbl.[getn](https://www.gammon.com.au/scripts/doc.php?lua=table.getn) +##### tbl.[setn](https://www.gammon.com.au/scripts/doc.php?lua=table.setn) +##### tbl.[maxn](https://www.gammon.com.au/scripts/doc.php?lua=table.maxn) +##### tbl.[insert](https://www.gammon.com.au/scripts/doc.php?lua=table.insert) +##### tbl.[remove](https://www.gammon.com.au/scripts/doc.php?lua=table.remove) +##### tbl.[concat](https://www.gammon.com.au/scripts/doc.php?lua=table.concat) +##### tbl.[map](https://stevedonovan.github.io/Penlight/api/libraries/pl.tablex.html#map) +##### tbl.[foreach](https://stevedonovan.github.io/Penlight/api/libraries/pl.tablex.html#foreach) +##### tbl.[foreachi](https://stevedonovan.github.io/Penlight/api/libraries/pl.tablex.html#foreachi) +##### tbl.[sort](https://stevedonovan.github.io/Penlight/api/libraries/pl.tablex.html#sort) +##### tbl.[sortv](https://stevedonovan.github.io/Penlight/api/libraries/pl.tablex.html#sortv) +##### tbl.[filter](https://stevedonovan.github.io/Penlight/api/libraries/pl.tablex.html#filter) +##### tbl.[size](https://stevedonovan.github.io/Penlight/api/libraries/pl.tablex.html#size) +##### tbl.[index_by](https://stevedonovan.github.io/Penlight/api/libraries/pl.tablex.html#index_by) +##### tbl.[transform](https://stevedonovan.github.io/Penlight/api/libraries/pl.tablex.html#transform) +##### tbl.[range](https://stevedonovan.github.io/Penlight/api/libraries/pl.tablex.html#range) +##### tbl.[reduce](https://stevedonovan.github.io/Penlight/api/libraries/pl.tablex.html#reduce) +##### tbl.[index_map](https://stevedonovan.github.io/Penlight/api/libraries/pl.tablex.html#index_map) +##### tbl.[makeset](https://stevedonovan.github.io/Penlight/api/libraries/pl.tablex.html#makeset) +##### tbl.[union](https://stevedonovan.github.io/Penlight/api/libraries/pl.tablex.html#union) +##### tbl.[intersection](https://stevedonovan.github.io/Penlight/api/libraries/pl.tablex.html#intersection) +##### tbl.[count_map](https://stevedonovan.github.io/Penlight/api/libraries/pl.tablex.html#count_map) +##### tbl.[set](https://stevedonovan.github.io/Penlight/api/libraries/pl.tablex.html#set) +##### tbl.[new](https://stevedonovan.github.io/Penlight/api/libraries/pl.tablex.html#new) +##### tbl.[clear](https://stevedonovan.github.io/Penlight/api/libraries/pl.tablex.html#clear) +##### tbl.[removevalues](https://stevedonovan.github.io/Penlight/api/libraries/pl.tablex.html#removevalues) +##### tbl.[readonly](https://stevedonovan.github.io/Penlight/api/libraries/pl.tablex.html#readonly) +##### tbl.[update](https://stevedonovan.github.io/Penlight/api/libraries/pl.tablex.html#update) +##### tbl.[copy](https://stevedonovan.github.io/Penlight/api/libraries/pl.tablex.html#copy) +##### tbl.[deepcopy](https://stevedonovan.github.io/Penlight/api/libraries/pl.tablex.html#deepcopy) +##### tbl.[icopy](https://stevedonovan.github.io/Penlight/api/libraries/pl.tablex.html#icopy) +##### tbl.[move](https://stevedonovan.github.io/Penlight/api/libraries/pl.tablex.html#move) +##### tbl.[insertvalues](https://stevedonovan.github.io/Penlight/api/libraries/pl.tablex.html#insertvalues) +##### tbl.[deepcompare](https://stevedonovan.github.io/Penlight/api/libraries/pl.tablex.html#deepcompare) +##### tbl.[compare](https://stevedonovan.github.io/Penlight/api/libraries/pl.tablex.html#compare) +##### tbl.[compare_no_order](https://stevedonovan.github.io/Penlight/api/libraries/pl.tablex.html#compare_no_order) +##### tbl.[find](https://stevedonovan.github.io/Penlight/api/libraries/pl.tablex.html#find) +##### tbl.[find_if](https://stevedonovan.github.io/Penlight/api/libraries/pl.tablex.html#find_if) +##### tbl.[search](https://stevedonovan.github.io/Penlight/api/libraries/pl.tablex.html#search) +##### tbl.[keys](https://stevedonovan.github.io/Penlight/api/libraries/pl.tablex.html#keys) +##### tbl.[values](https://stevedonovan.github.io/Penlight/api/libraries/pl.tablex.html#values) +##### tbl.[sub](https://stevedonovan.github.io/Penlight/api/libraries/pl.tablex.html#sub) +##### tbl.[merge](https://stevedonovan.github.io/Penlight/api/libraries/pl.tablex.html#merge) +##### tbl.[difference](https://stevedonovan.github.io/Penlight/api/libraries/pl.tablex.html#difference) +##### tbl.[zip](https://stevedonovan.github.io/Penlight/api/libraries/pl.tablex.html#zip) + diff --git a/src/gateway/kong-enterprise/dev-portal/workspaces.md b/src/gateway/kong-enterprise/dev-portal/workspaces.md new file mode 100644 index 000000000000..926ed863574d --- /dev/null +++ b/src/gateway/kong-enterprise/dev-portal/workspaces.md @@ -0,0 +1,79 @@ +--- +title: Running Multiple Dev Portals with Workspaces +badge: enterprise +--- + +Kong supports running multiple instances of the Dev Portal with the use of +[**Workspaces**](/gateway/{{page.kong_version}}/admin-api/workspaces/reference). This allows each Workspace to enable +and maintain separate Dev Portals (complete with separate files, settings, and +authorization) from within a single instance of Kong. + +## Manage Multiple Dev Portals within Kong Manager + +A snapshot of every Dev Portal within an instance of Kong can be viewed via +the Kong Manager's **Dev Portals** top navigation tab. + +This page details: + +- Whether a Dev Portal in a given Workspace is enabled or disabled +- A link to set up the Dev Portal if it is not enabled +- A link to each Dev Portal's homepage +- A link to each Dev Portal's individual overview page within Kong Manager +- Whether or not each Dev Portal is authenticated (indicated by a lock icon +in the upper right corner of each card) + +## Enable a Workspace's Dev Portal + +As with the **default** Workspace, when an additional Workspace is created, +its associated Dev Portal is `disabled` until it's manually enabled. + +This can be done from the Kong Manager by clicking the **Set up Dev Portal** +button located on the **Dev Portals** Overview page, or by navigating directly +to a Workspace's **Dev Portal Settings** page via the sidebar and toggling the +`Dev Portal Switch`, or by sending the following cURL request: + +```bash +curl -X PATCH http://localhost:8001/workspaces/ \ + --data "config.portal=true" +``` + +On initialization, Kong will populate the new Dev Portal with the [**Default Settings**](/gateway/{{page.kong_version}}/reference/configuration/#dev-portal) defined in Kong's configuration file. + +>*Note* A Workspace can only enable a Dev Portal if the Dev Portal feature has been enabled in Kong's configuration. + + +## Define the Dev Portal's URL structure + +The URL of each Dev Portal is automatically configured on initialization and +is determined by four properties: + +1. The `portal_gui_protocol` property +2. The `portal_gui_host` property +3. Whether the `portal_gui_use_subdomains` property is enabled or disabled +4. The `name` of the Workspace + +Example URL with subdomains disabled: `http://localhost:8003/example-workspace` + +Example URL with subdomains enabled: `http://example-workspace.localhost:8003` + +The first three properties are controlled by Kong's configuration file and +cannot be edited via the Kong Manager. + +## Override Default Settings + +On initialization, the Dev Portal will be configured using the [**Default Portal Settings**](/gateway/{{page.kong_version}}/reference/configuration/#dev-portal) defined in Kong's configuration file. + +{:.note} +> **Note**: You can only enable a Dev Portal for a Workspace if the +Dev Portal feature has been [enabled for Kong Gateway](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/enable). + +These settings can be manually overridden in the Dev Portals **Settings** tab +in the Kong Manager or by patching the setting directly. + +## Workspace Files + +On initialization of a Workspace's Dev Portal, a copy of the **default** Dev Portal files will be made and inserted into the new Dev Portal. This allows for the easy transference of a customized Dev Portal theme and allows **default** to act as a 'master template' -- however, the Dev Portal will not continue to sync changes from the **default** Dev Portal after it is first enabled. + +## Developer Access + +Access is not synced between Dev Portals. If an Admin or Developer wants access to multiple Dev Portals, they must sign up for each Dev Portal individually. diff --git a/src/gateway/kong-enterprise/event-hooks/index.md b/src/gateway/kong-enterprise/event-hooks/index.md new file mode 100644 index 000000000000..9fcad562d9a7 --- /dev/null +++ b/src/gateway/kong-enterprise/event-hooks/index.md @@ -0,0 +1,389 @@ +--- +title: Event Hooks Examples +badge: enterprise +--- + +{% include_cached /md/enterprise/event-hooks-intro.md %} + +## Webhook + +Webhook event hooks make JSON POST requests to a provided URL with the event data as a payload. +For this example, we will use a site that is helpful for testing webhooks: [https://webhook.site](https://webhook.site). + +To create a webhook event hook: + +1. Generate a URL by navigating to [https://webhook.site](https://webhook.site) in your web browser. +2. Select **Copy to clipboard** next to **Your unique URL**. +3. Create a webhook event hook on the `consumers` event (Kong entity the event hook will listen to for events), + on the `crud` source (action that triggers logging), and the URL you copied from step 2 using the following HTTP request: +{% capture the_code %} +{% navtabs codeblock %} +{% navtab cURL %} + +
      curl -i -X POST http://
      {HOSTNAME}
      :8001/event-hooks \ +-d source=crud \ +-d event=consumers \ +-d handler=webhook \ +-d config.url=
      {WEBHOOK_URL}
      + +{% endnavtab %} +{% navtab HTTPie %} + +
      http -f :8001/event-hooks \
      +source=crud \
      +event=consumers \
      +handler=webhook \
      +config.url=
      {WEBHOOK_URL}
      + +{% endnavtab %} +{% endnavtabs %} +{% endcapture %} +{{ the_code | indent }} + +4. Navigate to the URL from step 2. You should see a POST request, of type `ping`, notifying our webhook endpoint + about the creation of this webhook. +5. In Kong Manager or Kong Admin API, add a consumer from any workspace. + +{% capture the_code2 %} +{% navtabs %} +{% navtab Kong Manager %} + +1. Select the workspace. +2. Select **Consumers** in the left navigation. +3. Select the **New Consumer** button. +4. Enter a **Username**. +5. (Optional) Enter a **Custom ID** and any **Tags**. +6. Select the **Create** button. + +{% endnavtab %} +{% navtab Admin API %} + +Create a consumer, Ada Lovelace, by making the following HTTP request to your instance of the Kong Admin API: + +{% navtabs codeblock %} +{% navtab cURL %} + +
      curl -i -X POST http://
      {HOSTNAME}
      :8001/consumers \ +-d username="Ada Lovelace"
      + +{% endnavtab %} +{% navtab HTTPie %} + +
      http -f :8001/consumers \
      +username="Ada Lovelace"
      + +{% endnavtab %} +{% endnavtabs %} + +{% endnavtab %} +{% endnavtabs %} +{% endcapture %} +{{ the_code2 | indent }} + +6. Check the URL from the [https://webhook.site](https://webhook.site) page. + You should see an entry with data for the new consumer in its payload. + + ```json + { + "source": "crud", + "entity": { + "created_at": 1627581878, + "type": 0, + "username": "Ada Lovelace", + "id": "0fd2319f-13ea-4582-a448-8d11893026a8" + }, + "event": "consumers", + "operation": "create", + "schema": "consumers" + } + ``` + +## Custom webhook + +Custom webhook event hooks are fully customizable requests. Custom webhooks are useful for building direct +integration with a service. Because custom webhooks are fully configurable, they have more complex configurations. +Custom webhooks support Lua templating on a configurable body, form payload, and headers. For a list of +possible fields for templating, see the [sources](/gateway/{{ page.kong_version }}/admin-api/event-hooks/reference/#list-all-sources) endpoint. + +The following example sends a message to Slack any time a new administrator is invited to Kong Gateway. +Slack allows for [incoming webhooks](https://slack.com/help/articles/115005265063-Incoming-webhooks-for-Slack#set-up-incoming-webhooks) +and we can use these to build an integration with Kong's event hooks features. + +To create a custom webhook event hook: + +1. [Create an app in Slack.](https://api.slack.com/apps?new_app=1) +2. Activate incoming webhooks in the settings for your new app. +3. Select to **Add New Webhook to Workspace**, select the channel where you wish to receive notices, and select **Allow**. +4. Copy the **Webhook URL**, for example `https://hooks.slack.com/services/foo/bar/baz`. +5. Create a webhook event hook on the `admins` event (Kong entity the event hook will listen to for events), + and the `crud` source (action that triggers logging), and format the payload as, {% raw %}"Admin account \`{{ entity.username }}\` {{ operation }}d; e-mail address set to \`{{ entity.email }}\`"{% endraw %}, using the following HTTP request: + +{% capture the_code3 %} +{% navtabs codeblock %} +{% navtab cURL %} + +
      curl -i -X POST http://
      {HOSTNAME}
      :8001/event-hooks \ +-d source=crud \ +-d event=admins \ +-d handler=webhook-custom \ +-d config.method=POST \ +-d config.url=
      {WEBHOOK_URL}
      \ +-d config.headers.content-type="application/json" \ +-d config.payload.text={% raw %}"Admin account \`{{ entity.username }}\` {{ operation}}d; email address set to \`{{ entity.email }}\`"{% endraw %}
      + +{% endnavtab %} +{% navtab HTTPie %} + +
      http -f :8001/event-hooks \
      +source=crud \
      +event=admins \
      +handler=webhook-custom \
      +config.method=POST \
      +config.url=
      {WEBHOOK_URL}
      \ +config.headers.content-type="application/json" \ +config.payload.text={% raw %}"Admin account \`{{ entity.username }}\` {{ operation}}d; email address set to \`{{ entity.email }}\`"{% endraw %}
      + +{% endnavtab %} +{% endnavtabs %} +{% endcapture %} +{{ the_code3 | indent }} + +6. Turn on RBAC. + +{% capture anInclude %} +{% include_cached /md/enterprise/turn-on-rbac.md %} +{% endcapture %} +{{ anInclude | indent }} + +7. Invite an Admin using Kong Manager or the Kong Admin API. + +{% capture the_code2 %} +{% navtabs %} +{% navtab Kong Manager %} + +1. Go to Kong Manager, or reload the page if you already have it open and you will see a login screen. +2. Log in to Kong Manager with the built-in Super Admin account, `kong_admin`, and its password. + This is the initial `KONG_PASSWORD` you used when you ran migrations during installation. +3. From the **Teams > Admins** tab, click **Invite Admin**. +4. Enter the new administrator's **Email** address and **Username**. +5. Click **Invite Admin** to send the invite. + At this point in the getting started guide, you likely haven’t set up SMTP yet, so no email will be sent. + +{% endnavtab %} +{% navtab Admin API %} + +Create an admin, Arya Stark, by making the following HTTP request to your instance of the Kong Admin API: + +{:.note} +> **Note:** Replace `{KONG_ADMIN_PASSWORD`} with your `kong_admin` password. This is the initial + `KONG_PASSWORD` you used when you ran migrations during installation. + +{% navtabs codeblock %} +{% navtab cURL %} + +
      curl -i -X POST http://
      {HOSTNAME}
      :8001/admins \ +-d username="Arya Stark" \ +-d email=arya@gameofthrones.com \ +-H Kong-Admin-Token:{KONG_ADMIN_PASSWORD}
      + +{% endnavtab %} +{% navtab HTTPie %} + +
      http -f :8001/admins \
      +username="Arya Stark" \
      +email=arya@gameofthrones.com \
      +Kong-Admin-Token={KONG_ADMIN_PASSWORD}
      + +{% endnavtab %} +{% endnavtabs %} + +{% endnavtab %} +{% endnavtabs %} +{% endcapture %} +{{ the_code2 | indent }} + +Afterwards, you should receive a message in the Slack channel you selected with the message you included as the +`config.payload.text`. + +## Log + +Log event hooks log the specified event and content of the payload into the Kong Gateway logs. + +To create a log event hook: + +1. Create a log event hook on the `consumers` event (Kong entity the event hook will listen to for events) + and on the `crud` source (action that triggers logging) using the following HTTP request: + +{% capture the_code5 %} +{% navtabs codeblock %} +{% navtab cURL %} + +
      curl -i -X POST http://
      {HOSTNAME}
      :8001/event-hooks \ +-d source=crud \ +-d event=consumers \ +-d handler=log
      + +{% endnavtab %} +{% navtab HTTPie %} + +
      http -f :8001/event-hooks \
      +source=crud \
      +event=consumers \
      +handler=log
      + +{% endnavtab %} +{% endnavtabs %} +{% endcapture %} +{{ the_code5 | indent }} + +2. In Kong Manager or Kong Admin API, add a consumer from any workspace. + +{% capture the_code6 %} +{% navtabs %} +{% navtab Kong Manager %} + +1. Select the workspace. +2. Select **Consumers** in the left navigation. +3. Select the **New Consumer** button. +4. Enter a **Username**. +5. (Optional) Enter a **Custom ID** and any **Tags**. +6. Select the **Create** button. + +{% endnavtab %} +{% navtab Admin API %} + +Create a consumer, Elizabeth Bennet, by making the following HTTP request to your instance of the Kong Admin API: + +{% navtabs codeblock %} +{% navtab cURL %} + +
      curl -i -X POST http://
      {HOSTNAME}
      :8001/consumers \ +-d username="Elizabeth Bennet"
      + +{% endnavtab %} +{% navtab HTTPie %} + +
      http -f :8001/consumers \
      +username="Elizabeth Bennet"
      + +{% endnavtab %} +{% endnavtabs %} + +{% endnavtab %} +{% endnavtabs %} +{% endcapture %} +{{ the_code6 | indent }} + +3. You should see an entry with data for the new consumer in the payload in Kong's error log, + which is typically accessible at `/usr/local/kong/logs/error.log`. + + ```log + 172.19.0.1 - - [29/Jul/2021:15:57:15 +0000] "POST /consumers HTTP/1.1" 409 147 "-" "HTTPie/2.4.0" + 2021/07/29 15:57:26 [notice] 68854#0: *819021 +--------------------------------------------------+, context: ngx.timer, client: 172.19.0.1, server: 0.0.0.0:8001 + 2021/07/29 15:57:26 [notice] 68854#0: *819021 |[kong] event_hooks.lua:?:452 "log callback: " { "consumers", "crud", {|, context: ngx.timer, client: 172.19.0.1, server: 0.0.0.0:8001 + 2021/07/29 15:57:26 [notice] 68854#0: *819021 | entity = { |, context: ngx.timer, client: 172.19.0.1, server: 0.0.0.0:8001 + 2021/07/29 15:57:26 [notice] 68854#0: *819021 | created_at = 1627574246, |, context: ngx.timer, client: 172.19.0.1, server: 0.0.0.0:8001 + 2021/07/29 15:57:26 [notice] 68854#0: *819021 | id = "4757bd6b-8d54-4b08-bf24-01e346a9323e",|, context: ngx.timer, client: 172.19.0.1, server: 0.0.0.0:8001 + 2021/07/29 15:57:26 [notice] 68854#0: *819021 | type = 0, |, context: ngx.timer, client: 172.19.0.1, server: 0.0.0.0:8001 + 2021/07/29 15:57:26 [notice] 68854#0: *819021 | username = "Elizabeth Bennet" |, context: ngx.timer, client: 172.19.0.1, server: 0.0.0.0:8001 + 2021/07/29 15:57:26 [notice] 68854#0: *819021 | }, |, context: ngx.timer, client: 172.19.0.1, server: 0.0.0.0:8001 + 2021/07/29 15:57:26 [notice] 68854#0: *819021 | operation = "create", |, context: ngx.timer, client: 172.19.0.1, server: 0.0.0.0:8001 + 2021/07/29 15:57:26 [notice] 68854#0: *819021 | schema = "consumers" |, context: ngx.timer, client: 172.19.0.1, server: 0.0.0.0:8001 + 2021/07/29 15:57:26 [notice] 68854#0: *819021 | }, 68854 } |, context: ngx.timer, client: 172.19.0.1, server: 0.0.0.0:8001 + 2021/07/29 15:57:26 [notice] 68854#0: *819021 +--------------------------------------------------+, context: ngx.timer, client: 172.19.0.1, server: 0.0.0.0:8001 + + ``` + +## Lambda + +The lambda event hook allows you to write completely custom logic in Lua code and +hook it into a variety of Kong events. The following example writes a log entry +any time a consumer changes, but conditionally and with custom formatting. + +{:.important} +> The lambda event hook type is extremely powerful: you can write completely custom logic to handle any use case you want. +However, it’s [restricted by default through the sandbox.](/gateway/{{ page.kong_version }}/reference/configuration/#untrusted_lua). This +sandbox is put in place to keep users safe: it’s easy to inadvertently add unsafe libraries/objects into the sandbox +and leave the Kong Gateway exposed to security vulnerabilities. Use caution before modifying these sandbox settings. + +To create a lambda event hook: + +1. Create a Lua script to load into the lambda event hook and save it to a file named `lambda.lua` on your home directory. + + ```lua + return function (data, event, source, pid) + local user = data.entity.username + error("Event hook on consumer " .. user .. "") + end + ``` +2. Create a lambda event hook on the `consumers` event (Kong entity the event hook will listen to for events) + and on the `crud` source (action that triggers logging) using the following HTTP request: + +{% capture the_code7 %} +{% navtabs codeblock %} +{% navtab cURL %} + +
      curl -i -X POST http://
      {HOSTNAME}
      :8001/event-hooks \ +-d source=crud \ +-d event=consumers \ +-d handler=lambda \ +-F config.functions='return function (data, event, source, pid) local user = data.entity.username error("Event hook on consumer " .. user .. "")end'
      + +{% endnavtab %} +{% navtab HTTPie %} + +
      http -f :8001/event-hooks \
      +source=crud \
      +event=consumers \
      +handler=lambda \
      +config.functions[]=@~/lambda.lua
      + +{% endnavtab %} +{% endnavtabs %} +{% endcapture %} +{{ the_code7 | indent }} + +3. In Kong Manager or Kong Admin API, add a consumer to any workspace. + +{% capture the_code8 %} +{% navtabs %} +{% navtab Kong Manager %} + +1. Select the workspace. +2. Select **Consumers** in the left navigation. +3. Select the **New Consumer** button. +4. Enter a **Username**. +5. (Optional) Enter a **Custom ID** and any **Tags**. +6. Select the **Create** button. + +{% endnavtab %} +{% navtab Admin API %} + +Create a consumer, Lois Lane, by making the following HTTP request to your instance of the Kong Admin API: + +{% navtabs codeblock %} +{% navtab cURL %} + +
      curl -i -X POST http://
      {HOSTNAME}
      :8001/consumers \ +-d username="Lois Lane"
      + +{% endnavtab %} +{% navtab HTTPie %} + +
      http -f :8001/consumers \
      +username="Lois Lane"
      + +{% endnavtab %} +{% endnavtabs %} + +{% endnavtab %} +{% endnavtabs %} +{% endcapture %} +{{ the_code8 | indent }} + +3. You should see an entry "Event hook on consumer Lois Lane" in Kong's error log, + which is typically accessible at `/usr/local/kong/logs/error.log`. + + ```log + 2021/07/29 21:52:54 [error] 114#0: *153047 [kong] event_hooks.lua:190 [string "return function (data, event, source, pid)..."]:3: Event hook on consumer Lois Lane, context: ngx.timer, client: 172.19.0.1, server: 0.0.0.0:8001 + ``` diff --git a/src/gateway/kong-enterprise/index.md b/src/gateway/kong-enterprise/index.md new file mode 100644 index 000000000000..d0c0b8871435 --- /dev/null +++ b/src/gateway/kong-enterprise/index.md @@ -0,0 +1,104 @@ +--- +title: Overview +badge: enterprise +content_type: explanation +--- + +In addition to the {{site.base_gateway}} open source, free, and plus features, users with an Enterprise plan also have access to Enterprise-only features. These features enhance the security, monitoring, and management capabilities of {{site.base_gateway}}. + +The following sections describe key Kong Enterprise features. + +## Monitoring and analytics + +Use [Vitals](/gateway/{{page.kong_version}}/kong-enterprise/analytics/) to gain deep insights into service, route, and application usage and health monitoring data. Keep your finger on the pulse of the health of your API products with custom reports and contextual dashboards. In addition, you can enhance the native monitoring and analytics capabilities with {{site.base_gateway}} plugins that enable streaming monitoring metrics to third-party analytics providers, such as Datadog and Prometheus. + +[Start monitoring with Vitals →](/gateway/{{page.kong_version}}/kong-enterprise/analytics/) + +## Secrets management + +Application secrets include sensitive data like passwords, keys, certifications, tokens, and other items +which must be secured. {{site.base_gateway}} supports +[secrets management](/gateway/{{page.kong_version}}/kong-enterprise/secrets-management/), +which allows you to store secrets in a vault to help you protect them from accidental exposure. By storing sensitive values as secrets, you ensure that they are not +visible in plaintext throughout the platform, in places such as `kong.conf`, +in declarative configuration files, logs, or in the Kong Manager UI. + +[Secure your application secrets →](/gateway/{{page.kong_version}}/kong-enterprise/secrets-management/) + +## Dynamic plugin ordering + +By default, the execution order of {{site.base_gateway}} plugins is static. [Dynamic plugin ordering](/gateway/{{page.kong_version}}/kong-enterprise/plugin-ordering/) allows you to override the priority for any {{site.base_gateway}} plugin using each plugin's `ordering` field. +This determines plugin ordering during the `access` phase, +and lets you create _dynamic_ dependencies between plugins. + +[Get started with dynamic plugin ordering →](/gateway/{{page.kong_version}}/kong-enterprise/plugin-ordering/) + +## Dev Portal + +Streamline developer onboarding with the [Dev Portal](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/), which offers a self-service developer experience to discover, register, and consume published services from your Service Hub catalog. This customizable experience can be used to match your own unique branding and highlights the documentation and interactive API specifications of your services. Enable application registration to automatically secure your APIs with a variety of authorization providers. + +[Learn more about Dev Portal →](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/) + +## Audit logging + +{{site.base_gateway}} provides a granular logging facility on its Admin API. This +allows cluster administrators to keep detailed track of changes made to the +cluster configuration throughout its lifetime, aiding in compliance efforts and +providing valuable data points during forensic investigations. Generated audit +log trails are [workspace](/gateway/{{page.kong_version}}/admin-api/workspaces/reference) and [RBAC](/gateway/{{page.kong_version}}/admin-api/rbac/reference)-aware, +providing {{site.base_gateway}} operators a deep and wide look into changes happening within +the cluster. + +[Get started with audit logging →](/gateway/{{page.kong_version}}/kong-enterprise/audit-log/) + +## Keyring and data encryption + +{{site.base_gateway}} allows you to store sensitive data fields, such as consumer secrets, in an encrypted format within the database. This provides encryption-at-rest security controls in a {{site.base_gateway}} cluster. + +This functionality provides transparent, symmetric encryption of sensitive data fields at rest. Transparency refers to the fact that, when enabled, encryption and decryption of data is done by {{site.base_gateway}} immediately before writing, or immediately after reading from the database. Responses generated by the Admin API containing sensitive fields continue to show data as plaintext, and runtime elements of {{site.base_gateway}} (such as plugins) that require access to sensitive fields do so transparently, without requiring additional configuration. + +[Set up keyring and data encryption →](/gateway/{{page.kong_version}}/kong-enterprise/db-encryption/) + +## Roles-based access control (RBAC) + +You can configure {{site.base_gateway}} users, roles, and permissions with role-based access control (RBAC), either through the [Admin API](/gateway/{{page.kong_version}}/admin-api/rbac/reference/) or with [Kong Manager](/gateway/{{page.kong_version}}/kong-manager/auth/rbac). RBAC lets you manage access to resources in {{site.base_gateway}}. + +[Manage teams with RBAC →](/gateway/{{page.kong_version}}/kong-manager/auth/rbac) + +## Workspaces + +[Workspaces](/gateway/{{page.kong_version}}/kong-enterprise/workspaces/) provide a way to segment or group {{site.base_gateway}} entities. Entities in a workspace are isolated from those in other workspaces. + +[Learn more about workspaces →](/gateway/{{page.kong_version}}/kong-manager/workspaces/) + +## Consumer groups + +You can use [consumer groups](/gateway/{{page.kong_version}}/admin-api/consumer-groups/reference/) to manage custom rate limiting configuration for subsets of consumers. With consumer groups, you can define any number of rate limiting tiers and +apply them to subsets of consumers, instead of managing each consumer +individually. + +For example, you could define three consumer groups: +* A "gold tier" with 1000 requests per minute +* A "silver tier" with 10 requests per second +* A "bronze tier" with 6 requests per second + +[Set up consumer groups →](/gateway/{{page.kong_version}}/admin-api/consumer-groups/reference/) + +## Event hooks + +Event hooks are outbound calls from {{site.base_gateway}}. With event hooks, the {{site.base_gateway}} can communicate with target services or resources, letting the target know that an event was triggered. When an event is triggered in the {{site.base_gateway}}, it calls a URL with information about that event. Event hooks add a layer of configuration for subscribing to worker events using the admin interface. Worker events are integrated into {{site.base_gateway}} to communicate within the gateway context. For example, when an entity is created, the {{site.base_gateway}} fires an event with information about the entity. Parts of the {{site.base_gateway}} codebase can subscribe to these events, then process the events using callbacks. + +In {{site.base_gateway}}, these callbacks can be defined using one of the following handlers: + +* webhook +* webhook-custom +* log +* lambda + +You can configure event hooks through the Admin API. + +[Learn more about event hooks →](/gateway/{{page.kong_version}}/admin-api/event-hooks/reference/) + +## More information + +See [Plugin Compatibility](/hub/plugins/compatibility/) for more information about Enterprise-only plugins. diff --git a/src/gateway/kong-enterprise/plugin-ordering/get-started.md b/src/gateway/kong-enterprise/plugin-ordering/get-started.md new file mode 100644 index 000000000000..c38729f3f59d --- /dev/null +++ b/src/gateway/kong-enterprise/plugin-ordering/get-started.md @@ -0,0 +1,201 @@ +--- +title: Get Started with Dynamic Plugin Ordering +badge: enterprise +content_type: how-to +--- + +Here are some common use cases for [dynamic plugin ordering](/gateway/{{page.kong_version}}/kong-enterprise/plugin-ordering/). + +## Rate limiting before authentication + +Let's say you want to limit the amount of requests against your service and route +*before* Kong requests authentication. You can describe this dependency with the +token `before`. + +The following example uses the [Rate Limiting Advanced](/hub/kong-inc/rate-limiting-advanced) +plugin with the [Key Authentication](/hub/kong-inc/key-auth) plugin as the +authentication method. + +{% navtabs %} +{% navtab Admin API %} + +Call the Admin API on port `8001` and enable the +`rate-limiting` plugin, configuring it to run before `key-auth`: + + +{% navtabs codeblock %} +{% navtab cURL %} +```sh +curl -i -X POST http://:8001/plugins \ + --data name=rate-limiting \ + --data config.minute=5 \ + --data config.policy=local \ + --data config.limit_by=ip \ + --data ordering.before.access=key-auth +``` +{% endnavtab %} +{% navtab HTTPie %} +```sh +http -f post :8001/plugins \ + name=rate-limiting \ + config.minute=5 \ + config.policy=local \ + config.limit_by=ip \ + ordering.before.access=key-auth +``` +{% endnavtab %} +{% endnavtabs %} + + +{% endnavtab %} +{% navtab decK (YAML) %} + +1. Add a new `plugins` section to the bottom of your `kong.yaml` file. Enable +`rate-limiting` and set the plugin to run before `key-auth`: + + ``` yaml + plugins: + - name: rate-limiting + config: + minute: 5 + policy: local + limit_by: ip + ordering: + before: + access: + - key-auth + ``` + + Your file should now look like this: + + ``` yaml + _format_version: "3.0" + services: + - host: mockbin.org + name: example_service + port: 80 + protocol: http + routes: + - name: mocking + paths: + - /mock + strip_path: true + plugins: + - name: rate-limiting + config: + minute: 5 + policy: local + limit_by: ip + ordering: + before: + access: + - key-auth + ``` + + This plugin will be applied globally, which means the rate limiting + applies to all requests, including every Service and Route in the Workspace. + + If you pasted the plugin section under an existing Service, Route, or + Consumer, the rate limiting would only apply to that specific + entity. + + {:.note} + > **Note**: By default, `enabled` is set to `true` for the plugin. You can + disable the plugin at any time by setting `enabled: false`. + +2. Sync the configuration: + + ``` bash + deck sync + ``` + +{% endnavtab %} +{% endnavtabs %} + +## Authentication after request transformation + +The following example is similar to running [rate limiting before authentication](#rate-limiting-before-authentication). + +For example, you may want to first transform a request, then request authentication +*after* transformation. You can describe this dependency with the token `after`. + +Instead of changing the order of the [Request Transformer](/hub/kong-inc/request-transformer) +plugin, you can change the order of the authentication plugin +([Basic Authentication](/hub/kong-inc/basic-auth), in this example). + +{% navtabs %} +{% navtab Admin API %} + +Call the Admin API on port `8001` and enable the +`basic-auth` plugin, configuring it to run after `request-transformer`: + + +{% navtabs codeblock %} +{% navtab cURL %} +```sh +curl -i -X POST http://:8001/plugins \ + --data name=basic-auth \ + --data ordering.after.access=request-transformer +``` +{% endnavtab %} +{% navtab HTTPie %} +```sh +http -f post :8001/plugins \ + name=basic-auth \ + ordering.after.access=request-transformer +``` +{% endnavtab %} +{% endnavtabs %} + + +{% endnavtab %} +{% navtab decK (YAML) %} + +1. Add a new `plugins` section to the bottom of your `kong.yaml` file. Enable +`basic-auth` and set the plugin to run after `request-transformer`: + + ``` yaml + plugins: + - name: basic-auth + config: {} + ordering: + after: + access: + - request-transformer + ``` + + Your file should now look like this: + + ``` yaml + _format_version: "3.0" + services: + - host: mockbin.org + name: example_service + port: 80 + protocol: http + routes: + - name: mocking + paths: + - /mock + strip_path: true + plugins: + - name: basic-auth + config: {} + ordering: + after: + access: + - request-transformer + ``` + + {:.note} + > **Note**: By default, `enabled` is set to `true` for the plugin. You can + disable the plugin at any time by setting `enabled: false`. + +2. Sync the configuration: + + ``` bash + deck sync + ``` + +{% endnavtab %} +{% endnavtabs %} diff --git a/src/gateway/kong-enterprise/plugin-ordering/index.md b/src/gateway/kong-enterprise/plugin-ordering/index.md new file mode 100644 index 000000000000..b25d3a2fce21 --- /dev/null +++ b/src/gateway/kong-enterprise/plugin-ordering/index.md @@ -0,0 +1,100 @@ +--- +title: Dynamic Plugin Ordering +badge: enterprise +content_type: explanation +--- + +The order in which plugins are executed in Kong is determined by their +`static priority`. As the name suggests, this value is _static_ and can't be + easily changed by the user. + +You can override the priority for any Kong plugin using each plugin's +`ordering` field. This determines plugin ordering during the `access` phase, +and lets you create _dynamic_ dependencies between plugins. + +## Concepts + +### Dependency tokens + +Use one of the following tokens to describe a dependency to a plugin: + +* `before`: The plugin will be executed _before_ a specified plugin or list of plugins. +* `after`: The plugin will be executed _after_ a specified plugin or list of plugins. + +### Phases + +When a request is processed by {{site.base_gateway}}, it goes through various +[phases](/gateway/latest/plugin-development/custom-logic/#available-contexts), +depending on the configured plugins. You can influence the order in which +plugins are executed for each phase. + +Currently, {{site.base_gateway}} supports dynamic plugin ordering in the +`access` phase. + +### API + +You can use the following API to express dependencies for plugins within a +certain request phase (examples are in decK-formatted YAML): + +```yaml +ordering: + $dependency_token: + $supported_phase: + - pluginA + - ... +``` + +For example, if you want to express that PluginA's `access` phase should +run _before_ PluginB's `access` phase, you would write something like this: + +```yaml +PluginA: + ordering: + before: + access: + - PluginB +``` + +## Known limitations + +### Consumer scoping + +Consumer-scoped plugins don't support dynamic ordering because consumer mapping +also runs in the access phase. The order of the plugins must be determined +after consumer mapping has happened. {{site.base_gateway}} can't reliably +change the order of the plugins in relation to consumer mapping. + +### Cascading deletes & updates + +There is no support to detect if a plugin has a dependency to +a deleted plugin, so handle your configuration with care. + +### Performance implications + +Dynamic plugin ordering requires sorting plugins during a request. This naturally +adds latency to the request. In some cases, this might be compensated for when +you run rate limiting before an expensive authentication plugin. + +Re-ordering _any_ plugin in a workspace has performance implications to all +other plugins within the same workspace. If possible, consider offloading plugin +ordering to a separate workspace. + +### Validation + +Validating dynamic plugin ordering is a non-trivial task and would require +insight into the user's business logic. {{site.base_gateway}} tries to catch +basic mistakes but it can't detect all potentially dangerous configurations. + +If using dynamic ordering, manually test all configurations, and handle this +feature with care. + +### Kong Manager + +Kong Manager doesn't support dynamic plugin ordering configuration through the +UI. Use the Kong Admin API or a declarative configuration file to set +plugin ordering. + +## See also + +Check out the examples in the +[getting started guide for dynamic plugin ordering](/gateway/{{page.kong_version}}/kong-enterprise/plugin-ordering/get-started). diff --git a/src/gateway/kong-enterprise/secrets-management/advanced-usage.md b/src/gateway/kong-enterprise/secrets-management/advanced-usage.md new file mode 100644 index 000000000000..9f4ecd49845c --- /dev/null +++ b/src/gateway/kong-enterprise/secrets-management/advanced-usage.md @@ -0,0 +1,118 @@ +--- +title: Advanced Secrets Configuration +--- + +Vault implementations offer a variety of advanced configuration options. + +## Query arguments + +You can configure your vault backend with query arguments. + +For example, the following query uses an option called `prefix` with the value `SECURE_`: + +```bash +{vault://env/my-secret-config-value?prefix=SECURE_} +``` + +For more information on available configuration options, +refer to respective [vault backend documentation](/gateway/{{page.kong_version}}/kong-enterprise/secrets-management/backends). + +## Environment Variables + +You can configure your vault backend with `KONG_VAULT__` environment variables. + +For example, {{site.base_gateway}} might look for an environment variable that matches `KONG_VAULT_ENV_PREFIX`: + +```bash +export KONG_VAULT_ENV_PREFIX=SECURE_ +``` + +## Vaults entity + +You can configure your vault backend using the `vaults` entity. + +```bash +http -f PUT :8001/vaults/my-env-vault \ + name=env \ + description="ENV vault for secrets" \ + config.prefix=SECURE_ +``` + +This lets you drop the configuration from environment variables and query arguments and use the entity name in the reference. + +```bash +{vault://my-env-vault/my-secret-config-value} +``` + +For more information, see the section on the [Vaults entity](#vaults-entity). + +## Vaults CLI + +```text +Usage: kong vault COMMAND [OPTIONS] + +Vault utilities for {{site.base_gateway}}. + +Example usage: + TEST=hello kong vault get env/test + +The available commands are: + get Retrieves a value for + +Options: + -c,--conf (optional string) configuration file + -p,--prefix (optional string) override prefix directory + --v verbose + --vv debug +``` + +## Vaults Entity + +{:.warning} +> Kong Manager currently doesn't support configuring vault entities. + +The Vault entity can only be used once the database is initialized. Secrets for values that are used _before_ the database is initialized can't make use of the Vaults entity. + +Create a Vault entity: + +{% navtabs codeblock %} +{% navtab cURL %} + +```bash +curl -i -X PUT http://HOSTNAME:8001/vaults/my-env-vault-1 \ + --data name=env \ + --data description='ENV vault for secrets' \ + --data config.prefix=SECRET_ +``` + +{% endnavtab %} +{% navtab HTTPie %} + +```bash +http -f PUT :8001/vaults/my-env-vault-1 \ + name=env \ + description="ENV vault for secrets" \ + config.prefix=SECRET_ +``` + +{% endnavtab %} +{% endnavtabs %} + +Result: + +```json +{ + "config": { + "prefix": "SECRET_" + }, + "created_at": 1644929952, + "description": "ENV vault for secrets", + "id": "684ff5ea-7f65-4377-913b-880857f39251", + "name": "env", + "prefix": "my-env-vault-1", + "tags": null, + "updated_at": 1644929952 +} +``` + +Config options depend on the associated [backend](/gateway/{{page.kong_version}}/kong-enterprise/secrets-management/backends) used. diff --git a/src/gateway/kong-enterprise/secrets-management/backends/aws-sm.md b/src/gateway/kong-enterprise/secrets-management/backends/aws-sm.md new file mode 100644 index 000000000000..97361e3fe9b2 --- /dev/null +++ b/src/gateway/kong-enterprise/secrets-management/backends/aws-sm.md @@ -0,0 +1,108 @@ +--- +title: AWS Secrets Manager +badge: enterprise +--- + +## Configuration + +[AWS Secrets Manager](https://aws.amazon.com/secrets-manager/) can be configured in multiple ways. The current version of {{site.base_gateway}} implementation only supports +configuring via environment variables. + +```bash +export AWS_ACCESS_KEY_ID= +export AWS_SECRET_ACCESS_KEY= +export AWS_REGION= +``` + +Region used by default with references, can also be specified with: + +```bash +export KONG_VAULT_AWS_REGION= +``` + +## Examples + +For example, let's use an AWS Secrets Manager Secret with the name `my-secret-name`. + +In this object, you have multiple key=value pairs. + +```json +{ + "foo": "bar", + "snip": "snap", +} +``` + +Access these secrets from `my-secret-name` like this: + +```bash +{vault://aws/my-secret-name/foo} +{vault://aws/my-secret-name/snip} +``` + +## Entity + +The Vault entity can only be used once the database is initialized. Secrets for values that are used _before_ the database is initialized can't make use of the Vaults entity. + +{% navtabs codeblock %} +{% navtab cURL %} + +```bash +curl -i -X PUT http://HOSTNAME:8001/vaults/my-aws-sm-vault \ + --data name=aws \ + --data description="Storing secrets in AWS Secrets Manager" \ + --data config.region="us-east-1" +``` + +{% endnavtab %} +{% navtab HTTPie %} + +```bash +http -f PUT :8001/vaults/my-aws-sm-vault name="aws" \ + description="Storing secrets in AWS Secrets Manager" \ + config.region="us-east-1" +``` + +{% endnavtab %} +{% endnavtabs %} + +Result: + +```json +{ + "config": { + "region": "us-east-1" + }, + "created_at": 1644942689, + "description": "Storing secrets in AWS Secrets Manager", + "id": "2911e119-ee1f-42af-a114-67061c3831e5", + "name": "aws", + "prefix": "my-aws-sm-vault", + "tags": null, + "updated_at": 1644942689 +} +``` + +With the Vault entity in place, you can now reference the secrets. This allows you to drop the `AWS_REGION` +environment variable. + +```bash +{vault://my-aws-sm-vault/my-secret-name/foo} +{vault://my-aws-sm-vault/my-secret-name/snip} +``` + +## Advanced Examples + +You can create multiple entities, which lets you have secrets in different regions: + +```bash +curl -X PUT http://HOSTNAME:8001/vaults/aws-eu-central-vault -d name=aws -d config.region="eu-central-1" +curl -X PUT http://HOSTNAME:8001/vaults/aws-us-west-vault -d name=aws -d config.region="us-west-1" +``` + +This lets you source secrets from different regions: + +```bash +{vault://aws-eu-central-vault/my-secret-name/foo} +{vault://aws-us-west-vault/my-secret-name/snip} +``` diff --git a/src/gateway/kong-enterprise/secrets-management/backends/env.md b/src/gateway/kong-enterprise/secrets-management/backends/env.md new file mode 100644 index 000000000000..9f246a7352dd --- /dev/null +++ b/src/gateway/kong-enterprise/secrets-management/backends/env.md @@ -0,0 +1,87 @@ +--- +title: Environment Variables Vault +badge: free +content-type: how-to +--- + +## Configuration + +Storing secrets in environment variables is a common way as they can be injected at build time. +There is no prior configuration needed. + +## Examples + +Define a secret in a environment variable: + +```bash +export MY_SECRET_VALUE=EXAMPLE_VALUE +``` + +We can now reference this secret + +```text +{vault://env/my-secret-value} +``` + +You can also define a `json` string if you want to store multiple secrets +in a single environment variable. + +```bash +export PG_CREDS='{"username":"user", "password":"pass"}' +``` + +This allows you to do + +```text +{vault://env/pg-creds/username} +{vault://env/pg-creds/password} +``` + +## Entity + +{:.note} +> The Vault entity can only be used once the database is initialized. Secrets for values that are used _before_ the database is initialized can't make use of the Vaults entity. + +{% navtabs codeblock %} +{% navtab cURL %} + +```bash +curl -i -X PUT http://HOSTNAME:8001/vaults/my-env-vault \ + --data name=env \ + --data description="Store secrets in environment variables" +``` + +{% endnavtab %} +{% navtab HTTPie %} + +```bash +http -f PUT :8001/vaults/my-env-vault \ + name="env" \ + description="Store secrets in environment variables" +``` + +{% endnavtab %} +{% endnavtabs %} + +Result: + +```json +{ + "config": { + "prefix": null + }, + "created_at": 1644942689, + "description": "Store secrets in environment variables", + "id": "2911e119-ee1f-42af-a114-67061c3831e5", + "name": "env", + "prefix": "my-env-vault", + "tags": null, + "updated_at": 1644942689 +} +``` + +With the entity in place you can reference secrets like this: + +```bash +{vault://my-env-vault/my-secret-value} +``` diff --git a/src/gateway/kong-enterprise/secrets-management/backends/gcp-sm.md b/src/gateway/kong-enterprise/secrets-management/backends/gcp-sm.md new file mode 100644 index 000000000000..502de879b74c --- /dev/null +++ b/src/gateway/kong-enterprise/secrets-management/backends/gcp-sm.md @@ -0,0 +1,125 @@ +--- +title: GCP Secrets Manager +badge: enterprise +content-type: how-to +--- + +## Configuration + +The current version of {{site.base_gateway}}'s implementation supports +configuring +[GCP Secrets Manager](https://cloud.google.com/secret-manager/) in two +ways: + +* Environment variables +* Workload Identity + +To configure GCP Secrets Manager, the `GCP_SERVICE_ACCOUNT` +environment variable must be set to the JSON document referring to the +[credentials for your service account](https://cloud.google.com/iam/docs/creating-managing-service-account-keys): + +```bash +export GCP_SERVICE_ACCOUNT=$(cat gcp-my-project-c61f2411f321.json) +``` + +{{site.base_gateway}} uses the key to automatically authenticate +with the GCP API and grant you access. + +To use GCP Secrets Manager with +[Workload Identity](https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity) +on a GKE cluster, update your pod spec so that the service account is +attached to the pod. For configuration information, read the [Workload +Identity configuration +documentation](https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity#authenticating_to). + +{:.note} +> With Workload Identity, setting the `GCP_SERVICE_ACCOUNT` isn't necessary. + +## Examples + +To use a GCP Secret Manager +[secret](https://cloud.google.com/secret-manager/docs/reference/rest/v1/projects.secrets) +with the name `my-secret-name`, create a JSON object in GCP that +contains one or more properties: + +```json +{ + "foo": "bar", + "snip": "snap" +} +``` + +You can now reference the secret's individual resources like this: + +```bash +{vault://gcp/my-secret-name/foo?project_id=my_project_id} +{vault://gcp/my-secret-name/snip?project_id=my_project_id} +``` + +Note that both the provider (`gcp`) as well as the GCP project ID +(`my_project_id`) need to be specified. You can configure the project ID +with an environment variable before starting {{site.base_gateway}}: + +```bash +export KONG_VAULT_GCP_PROJECT_ID=my_project_id +``` + +Then you don't need to repeat it in references: + +```bash +{vault://gcp/my-secret-name/foo} +{vault://gcp/my-secret-name/snip} +``` + +## Entity + +Once the database is initialized, a Vault entity can be created +that encapsulates the provider and the GCP project ID: + +{% navtabs codeblock %} +{% navtab cURL %} + +```bash +curl -i -X PUT http://HOSTNAME:8001/vaults/my-gcp-sm-vault \ + --data name=gcp \ + --data description="Storing secrets in GCP Secrets Manager" \ + --data config.project_id="my_project_id" +``` + +{% endnavtab %} +{% navtab HTTPie %} + +```bash +http -f PUT http://HOSTNAME:8001/vaults/my-gcp-sm-vault \ + name="gcp" \ + description="Storing secrets in GCP Secrets Manager" \ + config.project_id="my_project_id" +``` + +{% endnavtab %} +{% endnavtabs %} + +Result: + +```json +{ + "config": { + "project_id": "my_project_id" + }, + "created_at": 1657874961, + "description": "Storing secrets in GCP Secrets Manager", + "id": "90e200be-cf84-4ce9-a1d6-a41c75c79f31", + "name": "gcp", + "prefix": "my-gcp-sm-vault", + "tags": null, + "updated_at": 1657874961 +} +``` + +With the Vault entity in place, you can reference the GCP secrets +through it: + +```bash +{vault://my-gcp-sm-vault/my-secret-name/foo} +{vault://my-gcp-sm-vault/my-secret-name/snip} +``` diff --git a/src/gateway/kong-enterprise/secrets-management/backends/hashicorp-vault.md b/src/gateway/kong-enterprise/secrets-management/backends/hashicorp-vault.md new file mode 100644 index 000000000000..a465d34814a9 --- /dev/null +++ b/src/gateway/kong-enterprise/secrets-management/backends/hashicorp-vault.md @@ -0,0 +1,109 @@ +--- +title: Hashicorp Vault +badge: enterprise +--- + +## Configuration + +[HashiCorp Vault](https://www.vaultproject.io/) can be configured with environment variables or with a Vault entity. + +## Environment variables + +```bash +export KONG_VAULT_HCV_PROTOCOL= +export KONG_VAULT_HCV_HOST= +export KONG_VAULT_HCV_PORT= +export KONG_VAULT_HCV_MOUNT= +export KONG_VAULT_HCV_KV= +export KONG_VAULT_HCV_TOKEN= +``` + +You can also store this information in an entity. + +## Entity + +{:.note} +The Vault entity can only be used once the database is initialized. Secrets for values that are used _before_ the database is initialized can't make use of the Vaults entity. + +{% navtabs codeblock %} +{% navtab cURL %} + +```bash +curl -i -X PUT http://HOSTNAME:8001/vaults/my-hashicorp-vault \ + --data name="hcv" \ + --data description="Storing secrets in Hashicorp Vault" \ + --data config.protocol="https" \ + --data config.host="localhost" \ + --data config.port="8200" \ + --data config.mount="secret" \ + --data config.kv="v2" \ + --data config.token="" +``` + +{% endnavtab %} +{% navtab HTTPie %} + +```bash +http -f PUT :8001/vaults/my-hashicorp-vault \ + name="hcv" \ + description="Storing secrets in Hashicorp Vault" \ + config.protocol="https" \ + config.host="localhost" \ + config.port="8200" \ + config.mount="secret" \ + config.kv="v2" \ + config.token="" +``` + +{% endnavtab %} +{% endnavtabs %} + +Result: + +```json +{ + "config": { + "host": "localhost", + "kv": "v2", + "mount": "vault", + "port": 8200, + "protocol": "https", + "token": "" + }, + "created_at": 1645008893, + "description": "Storing secrets in Hashicorp Vault", + "id": "0b43d867-05db-4bed-8aed-0fccb6667837", + "name": "hcv", + "prefix": "my-hashicorp-vault", + "tags": null, + "updated_at": 1645008893 +} +``` + +## Examples + +For example, let's say you've configured a HashiCorp Vault with a path of `secret/hello` and a key=value pair of `foo=world`: + +```text +vault kv put secret/hello foo=world + +Key Value +--- ----- +created_time 2022-01-15T01:40:03.740833Z +custom_metadata +deletion_time n/a +destroyed false +version 1 +``` + +Access these secrets like this: + +```bash +{vault://hcv/hello/foo} +``` + +Or if you configured an entity + +```bash +{vault://my-hashicorp-vault/hello/foo} +``` diff --git a/src/gateway/kong-enterprise/secrets-management/backends/index.md b/src/gateway/kong-enterprise/secrets-management/backends/index.md new file mode 100644 index 000000000000..b472f43bb804 --- /dev/null +++ b/src/gateway/kong-enterprise/secrets-management/backends/index.md @@ -0,0 +1,12 @@ +--- +title: Supported Vault Backends +--- + +The following Vault implementations are supported: + +| | Tier | +|---------------------------------------------------------------------------------------------------------------|------------| +| [AWS Secrets Manager](/gateway/{{page.kong_version}}/kong-enterprise/secrets-management/backends/aws-sm) | Enterprise | +| [GCP Secrets Manager](/gateway/{{page.kong_version}}/kong-enterprise/secrets-management/backends/gcp-sm) | Enterprise | +| [HashiCorp Vault](/gateway/{{page.kong_version}}/kong-enterprise/secrets-management/backends/hashicorp-vault) | Enterprise | +| [Environment Variable](/gateway/{{page.kong_version}}/kong-enterprise/secrets-management/backends/env) | Free | diff --git a/src/gateway/kong-enterprise/secrets-management/getting-started.md b/src/gateway/kong-enterprise/secrets-management/getting-started.md new file mode 100644 index 000000000000..da35e797d0a1 --- /dev/null +++ b/src/gateway/kong-enterprise/secrets-management/getting-started.md @@ -0,0 +1,69 @@ +--- +title: Get Started with Secrets Management +--- + +Secrets are generally confidential values that should not appear in plain text in the application. +There are several products that help you store, retrieve, and rotate these secrets securely as well as +audit the access to them. {{site.base_gateway}} offers a mechanism to set up references to these +secrets which makes your {{site.base_gateway}} installation more secure. + +## Getting started + +The following example uses the most basic form of secrets management: storing secrets in environment variables. +In this example, you will replace a plaintext password to your PostgreSQL database with a reference to an environment variable. + +You can also store secrets in a secure vault backend. For a list of supported vault backend implementations, see the [Backends Overview](/gateway/{{page.kong_version}}/kong-enterprise/secrets-management/backends). + +In this example we'll replace our plaintext password to our PostgreSQL database with a reference. To do so, define your environment variable and assign a secret value to it. + +### Define a reference + +Define your environment variable and assign a secret value to it: + +```bash +export MY_SECRET_POSTGRES_PASSWORD="opensesame" +``` + +Next, set up a reference to this environment variable so that {{site.base_gateway}} can find this secret. We use a Uniform Resource Locator (URL) format for this. + +In this case, the reference would look like this: + +```bash +{vault://env/my-secret-postgres-password} +``` + +Where: + +* `vault` is the scheme (protocol) that we use to indicate that this is a secret. +* `env` is the name of the backend [(Environment Variables)](/gateway/{{page.kong_version}}/kong-enterprise/secrets-management/backends/env), since we're storing the secret in a ENV variable. +* `my-secret-postgres-password` corresponds to the environment variable that you just defined. + +Note that the reference is wrapped in curly braces. + +### Using the reference + +You can specify configuration options using environment variables or by directly updating the `kong.conf` configuration file. + +#### Environment variable + +Set the `KONG_PG_PASSWORD` environment variable to the following, adjusting `my-secret-postgres-password` to your own password object name: + +```bash +KONG_PG_PASSWORD={vault://env/my-secret-postgres-password} +``` + +#### Configuration file + +The `kong.conf` file contains the property `pg_password`. +Replace the original value with the following, adjusting `my-secret-postgres-password` to your own password object name: + +```bash +pg_password={vault://env/my-secret-postgres-password} +``` + +Upon startup, {{site.base_gateway}} tries to detect and transparently resolve references. + +{:.note} +> For quick debugging or testing, you can use the [CLI for vaults](/gateway/{{page.kong_version}}/kong-enterprise/secrets-management/advanced-usage/#vaults-cli). + +See the [Advanced Usage](/gateway/{{page.kong_version}}/kong-enterprise/secrets-management/advanced-usage) documentation for more information on the configuration options for each vault backend. diff --git a/src/gateway/kong-enterprise/secrets-management/how-to/aws-secrets-manager.md b/src/gateway/kong-enterprise/secrets-management/how-to/aws-secrets-manager.md new file mode 100644 index 000000000000..406513e193c4 --- /dev/null +++ b/src/gateway/kong-enterprise/secrets-management/how-to/aws-secrets-manager.md @@ -0,0 +1,177 @@ +--- +title: "Securing Kong Gateway database credentials with AWS Secrets Manager" +content_type: how-to +description: "How to keep your {{site.base_gateway}} database credentials secure using AWS Secrets Manager and vault integrations." +--- + +Application secrets include sensitive data like passwords, keys, certifications, tokens, and other items +which must be secured. [{{site.base_gateway}}](/gateway/{{page.kong_version}}/) supports +[Secrets Management](/gateway/{{page.kong_version}}/kong-enterprise/secrets-management/) +which allows you to store secrets in various secure backend systems and helps you protect them from accidental +exposure. + +Traditionally, {{site.base_gateway}} is configured with static credentials for connecting +to its external database. This guide will show you how to configure {{site.base_gateway}} to use +[AWS Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/auth-and-access.html) to +read database credentials securely instead the conventional file or environment variable based solutions. + +For this guide, you will run the PostgreSQL and {{site.base_gateway}} locally on Docker. +You will create a secret in the AWS Secrets Manager and deploy {{site.base_gateway}} using a vault reference +to read the value securely. + +### Prerequisites + +* An [AWS account](https://aws.amazon.com/). Your account must have the proper IAM permissions to allow access to the AWS Secrets Manager service. Permission policy examples can be found in the [AWS Secrets Manager documentation](https://docs.aws.amazon.com/secretsmanager/latest/userguide/auth-and-access_examples.html). Additionally, you must have the following permissions: + * `secretsmanager:CreateSecret` + * `secretsmanager:PutSecretValue` + * `secretsmanager:GetSecretValue` +* The [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) installed and configured. You must be able to configure the gateway environment with [AWS CLI environment variables](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html) because this is the method that {{site.base_gateway}} uses to connect to the Secrets Manager service. + +* [Docker](https://docs.docker.com/get-docker/) installed. +* [`curl`](https://curl.se/) is required on your system to send +requests to the gateway for testing. Most systems come with `curl` pre-installed. + +### Configure {{site.base_gateway}} to use AWS Secrets Manager + +1. Create a Docker network for {{site.base_gateway}} and the database to communicate over: + + ```sh + docker network create kong-net + ``` + +1. Configure and run the database: + + ```sh + docker run -d --name kong-database \ + --network=kong-net \ + -p 5432:5432 \ + -e "POSTGRES_USER=admin" \ + -e "POSTGRES_PASSWORD=password" \ + postgres:9.6 + ``` + + The username and password used above are the PostgreSQL master credentials, *not* the + username and password you will use to authorize {{site.base_gateway}} with the database. + + {:.note} + > **Note:** A production deployment can use [AWS RDS for PostgreSQL](https://aws.amazon.com/rds/postgresql/) + which supports direct integration with AWS Secrets Manager. + +1. Create a username and password for {{site.base_gateway}}'s database and store +them in environment variables to use in this guide: + + ```sh + KONG_PG_USER=kong + KONG_PG_PASSWORD=KongFTW + ``` + +1. Create the {{site.base_gateway}} database user inside the PostgreSQL server container: + + ```sh + docker exec -it kong-database psql -U admin -c \ + "CREATE USER ${KONG_PG_USER} WITH PASSWORD '${KONG_PG_PASSWORD}'" + ``` + + You should see: + ```sh + CREATE ROLE + ``` + +1. Create a database named `kong` inside the PostgreSQL container: + + ```sh + docker exec -it kong-database psql -U admin -c "CREATE DATABASE kong OWNER ${KONG_PG_USER};" + ``` + + You should see: + ```sh + CREATE DATABASE + ``` + +1. Create a new AWS secret: + + ```sh + aws secretsmanager create-secret --name kong-gateway-database \ + --description "Kong GW Database credentials" + ``` + +1. Update the secret value with the username and password from the variables assigned above. +If you want to update the secret values later, this is the command you would use: + + ```sh + aws secretsmanager put-secret-value --secret-id kong-gateway-database \ + --secret-string '{"pg_user":"'${KONG_PG_USER}'","pg_password":"'${KONG_PG_PASSWORD}'"}' + ``` + +1. Before launching {{site.base_gateway}}, run the following command to perform the database migrations: + + {:.note} + > **Note:** Currently, the `kong migrations` tool does not support Secrets Management, so this + step must be done with traditional {{site.base_gateway}} configuration options. In this example, + we are passing the secrets to Docker via the environment. + + ```sh + docker run --rm \ + --network=kong-net \ + -e "KONG_DATABASE=postgres" \ + -e "KONG_PG_HOST=kong-database" \ + -e "KONG_PG_USER=$KONG_PG_USER" \ + -e "KONG_PG_PASSWORD=$KONG_PG_PASSWORD" \ + kong/kong-gateway:latest kong migrations bootstrap + ``` + +1. Launch {{site.base_gateway}} configured to use values it can reference for the +database username and password. To authorize {{site.base_gateway}} to connect to AWS Secrets Manager, +you need to provide IAM security credentials via environment variables. + + You specify the database credentials using the standard `KONG_` + [environment variable names](/gateway/{{page.kong_version}}/reference/configuration/#environment-variables), + but instead of providing a static value you use a + [reference value](/gateway/{{page.kong_version}}/kong-enterprise/secrets-management/reference-format/). + + The format looks like this: `{vault://aws/kong-gateway-database/pg_user}`. In this example, + the reference format contains `aws` as the backend vault type, `kong-gateway-database` matches + the name of the secret created earlier, and `pg_user` is the JSON field name you want to reference + in the secret value. + + See the + [AWS Secrets Manager documentation](/gateway/{{page.kong_version}}/kong-enterprise/secrets-management/backends/aws-sm/) + for more details. + + Assuming you have set `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, and `AWS_REGION` in the current + environment, start {{site.base_gateway}} like this: + + ```sh + docker run --rm \ + --network=kong-net \ + -e "KONG_DATABASE=postgres" \ + -e "KONG_PG_HOST=kong-database" \ + -e "AWS_ACCESS_KEY_ID" \ + -e "AWS_SECRET_ACCESS_KEY" \ + -e "AWS_REGION" \ + -e "KONG_PG_USER={vault://aws/kong-gateway-database/pg_user}" \ + -e "KONG_PG_PASSWORD={vault://aws/kong-gateway-database/pg_password}" \ + kong/kong-gateway:{{page.kong_version}} + ``` + + After a moment, {{site.base_gateway}} should be running, which you can verify with the Admin API: + + ```sh + curl -s localhost:8001 + ``` + + You should receive a JSON response with various information from {{site.base_gateway}}. + +The [Secrets Management documentation](/gateway/{{page.kong_version}}/kong-enterprise/secrets-management/) +contains more information about available backends and configuration details. + +### More information + +* See the following documentation for supported vault backends that {{site.base_gateway}} can integrate with: + * [Environment Variables Vault](/gateway/{{page.kong_version}}/kong-enterprise/secrets-management/backends/env/) + * [AWS Secrets Manager](/gateway/{{page.kong_version}}/kong-enterprise/secrets-management/backends/aws-sm/) + * [Hashicorp Vault](/gateway/{{page.kong_version}}/kong-enterprise/secrets-management/backends/hashicorp-vault/) + * [Google Secrets Management](/gateway/{{page.kong_version}}/kong-enterprise/secrets-management/backends/gcp-sm/) +* See [Starting Kong Securely](/gateway/{{page.kong_version}}/production/access-control/start-securely/) for more +security practices with {{site.base_gateway}} + diff --git a/src/gateway/kong-enterprise/secrets-management/index.md b/src/gateway/kong-enterprise/secrets-management/index.md new file mode 100644 index 000000000000..4a8b70a98ecd --- /dev/null +++ b/src/gateway/kong-enterprise/secrets-management/index.md @@ -0,0 +1,111 @@ +--- +title: Secrets Management +--- + +A secret is any sensitive piece of information required for API gateway +operations. Secrets may be part of the core {{site.base_gateway}} configuration, +they may be used in plugins, or they might be part of configuration associated +with APIs serviced by the gateway. + +Some of the most common types of secrets used by {{site.base_gateway}} include: + +* Data store usernames and passwords, used with PostgreSQL and Redis +* Private X.509 certificates +* API keys +* Sensitive plugin configuration fields, generally used for authentication, + hashing, signing, or encryption. + +{{site.base_gateway}} lets you store certain values in a vault. +By storing sensitive values as secrets, you ensure that they are not +visible in plaintext throughout the platform, in places such as `kong.conf`, +in declarative configuration files, logs, or in the Kong Manager UI. Instead, +you can reference each secret with a `vault` reference. + +For example, the following reference resolves to the environment variable `MY_SECRET_POSTGRES_PASSWORD`: + +``` +{vault://env/my-secret-postgres-password} +``` + +In this way, secrets management becomes centralized. + +## Referenceable values + +A secret reference points to a string value. No other data types are currently supported. + +The vault backend may store multiple related secrets inside an object, but the reference +should always point to a key that resolves to a string value. For example, the following reference: + +``` +{vault://hcv/pg/username} +``` + +Would point to a secret object called `pg` inside a HashiCorp Vault, which may return the following value: + +```json +{ + "username": "john", + "password": "doe" +} +``` + + +Kong receives the payload and extracts the `"username"` value of `"john"` for the secret reference of +`{vault://hcv/pg/username}`. + + +### What can be stored as a secret? + +Most of the [Kong configuration](/gateway/{{page.kong_version}}/reference/configuration/) values +can be stored as a secret, such as [pg_user](/gateway/{{page.kong_version}}/reference/configuration/#postgres-settings) and +[pg_password](/gateway/{{page.kong_version}}/reference/configuration/#postgres-settings). + +{:.note} +> **Limitation:** {{site.base_gateway}} doesn't currently support storing certificate key content into vaults or environment variables for `kong.conf` settings that use file paths. For example, [ssl_cert_key](/gateway/{{page.kong_version}}/reference/configuration/#ssl_cert_key) configures a certificate key `file path` which can't be stored as a reference. + +The [Kong license](/gateway/{{page.kong_version}}/licenses/), usually configured with +a `KONG_LICENSE_DATA` environment variable, can be stored as a secret. + +The Kong Admin API [certificate object](/gateway/{{page.kong_version}}/admin-api/#certificate-object) +can be stored as a secret. + +The following plugins have fields that can be stored as secrets in a +vault backend. These fields are labelled as `referenceable`. See the +documentation for each plugin to identify the referenceable fields: + +* [ACME](/hub/kong-inc/acme/) +* [AWS Lambda](/hub/kong-inc/aws-lambda/) +* [Azure Functions](/hub/kong-inc/azure-funtions/) +* [Forward Proxy](/hub/kong-inc/forward-proxy/) +* [GraphQL Rate Limiting Advanced](/hub/kong-inc/graphql-rate-limiting-advanced/) +* [Kafka Log](/hub/kong-inc/kafka-log/) +* [Kafka Upstream](/hub/kong-inc/kafka-upstream/) +* [LDAP Authentication Advanced](/hub/kong-inc/ldap-auth-advanced/) +* [Loggly](/hub/kong-inc/loggly/) +* [OpenID Connect](/hub/kong-inc/openid-connect/) +* [Proxy Cache Advanced](/hub/kong-inc/proxy-cache-advanced/) +* [Rate Limiting](/hub/kong-inc/rate-limiting/) +* [Rate Limiting Advanced](/hub/kong-inc/rate-limiting-advanced/) +* [Response Rate Limiting](/hub/kong-inc/response-ratelimiting/) +* [Request Transformer Advanced](/hub/kong-inc/request-transformer-advanced/) +* [Session](/hub/kong-inc/session/) +* [Vault Authentication](/hub/kong-inc/vault-auth/) + +## Supported backends + +{{site.base_gateway}} supports the following vault backends: +* Environment variables +* AWS Secrets Manager +* GCP Secrets Manager +* HashiCorp Vault + +See the [backends overview](/gateway/{{page.kong_version}}/kong-enterprise/secrets-management/backends/) +for more information about each option. + +## Get started + +For further information on secrets management, see the following topics: +* [Get started with secrets management](/gateway/{{page.kong_version}}/kong-enterprise/secrets-management/getting-started/) +* [Backends overview](/gateway/{{page.kong_version}}/kong-enterprise/secrets-management/backends/) +* [Reference format](/gateway/{{page.kong_version}}/kong-enterprise/secrets-management/reference-format/) +* [Advanced usage](/gateway/{{page.kong_version}}/kong-enterprise/secrets-management/advanced-usage/) diff --git a/src/gateway/kong-enterprise/secrets-management/reference-format.md b/src/gateway/kong-enterprise/secrets-management/reference-format.md new file mode 100644 index 000000000000..c3a389166537 --- /dev/null +++ b/src/gateway/kong-enterprise/secrets-management/reference-format.md @@ -0,0 +1,59 @@ +--- +title: Reference Format +--- + +We use the [URL syntax](https://en.wikipedia.org/wiki/URL) to describe references to a secret store. + +```text +{vault:///[//[//[/[/[/", \ + "bind_dn":"", \ + "base_dn":"", \ + "cache_ttl": 2, \ + "consumer_by":["username", "custom_id"], \ + "header_type":"Basic", \ + "keepalive":60000, \ + "ldap_host":"", \ + "ldap_password":"", \ + "ldap_port":389, \ + "start_tls":false, \ + "timeout":10000, \ + "verify_ldap_host":true \ +} +``` + +Attribute | Description +----------|------------- +`attribute` | The attribute used to identify LDAP users.
      For example, to map LDAP users to admins by their username, set `uid`. +`bind_dn` | LDAP Bind DN (Distinguished Name). Used to perform LDAP search for the user. This `bind_dn` should have permissions to search for the user being authenticated.
      For example, `uid=einstein,ou=scientists,dc=ldap,dc=com`. +`base_dn` | LDAP Base DN (Distinguished Name).
      For example, `ou=scientists,dc=ldap,dc=com`. +`ldap_host`| LDAP host domain.
      For example, `ec2-XX-XXX-XX-XXX.compute-1.amazonaws.com`. +`ldap_port`| The default LDAP port is 389. 636 is the port required for SSL LDAP and AD. If `ldaps` is configured, you must use port 636. For more complex Active Directory (AD) environments, instead of Domain Controller and port 389, consider using a Global Catalog host and port, which is port 3268 by default. +`ldap_password` | LDAP password.
      As with any configuration property, sensitive information may be set as an environment variable instead of being written directly in the configuration file. + +The **Sessions plugin** (configured with `admin_gui_session_conf`) requires a secret and is configured securely by default. +* Under all circumstances, the `secret` must be manually set to a string. +* If using HTTP instead of HTTPS, `cookie_secure` must be manually set to `false`. +* If using different domains for the Admin API and Kong Manager, `cookie_samesite` must be set to `off`. +Learn more about these properties in [Session Security in Kong Manager](/gateway/{{page.kong_version}}/kong-manager/auth/sessions/#session-security), and see [example configurations](/gateway/{{page.kong_version}}/kong-manager/auth/sessions/#example-configurations). + +After starting Kong with the desired configuration, you can create new *Admins* +whose usernames match those in the AD. Those users will then be able to accept +invitations to join Kong Manager and log in with their LDAP credentials. + +### Using Service Directory Mapping on the CLI + +{% include_cached /md/gateway/ldap-service-directory-mapping.md %} diff --git a/src/gateway/kong-manager/auth/ldap/service-directory-mapping.md b/src/gateway/kong-manager/auth/ldap/service-directory-mapping.md new file mode 100644 index 000000000000..542b1f825f10 --- /dev/null +++ b/src/gateway/kong-manager/auth/ldap/service-directory-mapping.md @@ -0,0 +1,142 @@ +--- +title: Mapping LDAP Service Directory Groups to Kong Roles +badge: enterprise +--- + +Service directory mapping allows organizations to use their LDAP Directory for authentication and authorization in {{site.base_gateway}}. + +After starting {{site.base_gateway}} with the desired configuration, you can create new admins whose usernames match those in your LDAP directory. Those users will then be able to accept invitations to join Kong Manager and log in with their LDAP credentials. + +How service directory mapping works in Kong: +* Roles are created in {{site.base_gateway}} using the Admin API or Kong Manager. +* Groups are created and roles are associated with the groups. +* When users log in to Kong Manager, they get permissions based on the group(s) they belong to. + +For example, if a user's group changes in the service directory, their Kong admin account's associated role also changes in {{site.base_gateway}} the next time they log in to Kong Manager. The mapping removes the task of manually managing access in {{site.base_gateway}}, as it makes the service directory the system of record. + +## Prerequisites + +* {{site.base_gateway}} installed and configured +* Kong Manager access +* A local LDAP directory + +## Enable LDAP authentication + +Configure service directory mapping to use your LDAP directory for authentication and authorization. + +1. Start {{site.base_gateway}}. From the shell, enter: + + ``` + kong start [-c /path/to/kong/conf] + ``` + +2. To enable LDAP Authentication and enforce RBAC for Kong Manager, configure Kong through [`kong.conf`](/gateway/{{page.kong_version}}/reference/configuration) with the following properties: + + ``` + enforce_rbac = on + admin_gui_auth = ldap-auth-advanced + admin_gui_session_conf = { "secret":"set-your-string-here" } + ``` + + Kong Manager also uses the Sessions plugin in the background. + This plugin (configured with `admin_gui_session_conf`) requires a secret and is configured securely by default. + + * Under all circumstances, the `secret` must be manually set to a string. + * If using HTTP instead of HTTPS, `cookie_secure` must be manually set to `false`. + * If using different domains for the Admin API and Kong Manager, `cookie_samesite` must be set to `off`. + Learn more about these properties in [Session Security in Kong Manager](/gateway/{{page.kong_version}}/kong-manager/auth/sessions/#session-security), and see [example configurations](/gateway/{{page.kong_version}}/kong-manager/auth/sessions/#example-configurations). + +## Configure LDAP authentication + +Configure LDAP authentication for Kong Manager with the following properties. Note the attribute variables defined below: + +``` +admin_gui_auth_conf = { + "anonymous":"", \ + "attribute":"", \ + "bind_dn":"", \ + "base_dn":"", \ + "cache_ttl": 2, \ + "header_type":"Basic", \ + "keepalive":60000, \ + "ldap_host":"", \ + "ldap_password":"", \ + "ldap_port":389, \ + "start_tls":false, \ + "timeout":10000, \ + "verify_ldap_host":true, \ + "consumer_by":["username", "custom_id"], \ + "group_base_dn":"", + "group_name_attribute":"", + "group_member_attribute":"", +} +``` + +Attribute | Description +----------|------------- +`attribute` | The attribute used to identify LDAP users.
      For example, to map LDAP users to admins by their username, set `uid`. +`bind_dn` | LDAP Bind DN (Distinguished Name). Used to perform LDAP search for the user. This `bind_dn` should have permissions to search for the user being authenticated.
      For example, `uid=einstein,ou=scientists,dc=ldap,dc=com`. +`base_dn` | LDAP Base DN (Distinguished Name).
      For example, `ou=scientists,dc=ldap,dc=com`. +`ldap_host`| LDAP host domain.
      For example, `ec2-XX-XXX-XX-XXX.compute-1.amazonaws.com`. +`ldap_port`| The default LDAP port is 389. 636 is the port required for SSL LDAP and AD. If `ldaps` is configured, you must use port 636. For more complex Active Directory (AD) environments, instead of Domain Controller and port 389, consider using a Global Catalog host and port, which is port 3268 by default. +`ldap_password` | LDAP password.
      As with any configuration property, sensitive information may be set as an environment variable instead of being written directly in the configuration file. +`group_base_dn` | Sets a distinguished name for the entry where LDAP searches for groups begin.
      The default is the value from `conf.base_dn`. +`group_name_attribute` | Sets the attribute holding the name of a group, typically called `name` (in Active Directory) or `cn` (in OpenLDAP).
      The default is the value from `conf.attribute`. +`group_member_attribute` | Sets the attribute holding the members of the LDAP group.
      The default is `memberOf`. + +## Define roles with permissions + +Define roles with permissions in {{site.base_gateway}}, using the Admin API's [RBAC endpoints](/gateway/{{page.kong_version}}/admin-api/rbac/reference/#update-or-create-a-role) or using Kong Manager's [Teams page](/gateway/{{page.kong_version}}/kong-manager/auth/rbac/add-user/). You must manually define which Kong roles correspond to each of the service directory's groups using either of the following: + +* In Kong Manager's directory mapping section. Find it under **Teams** > **Groups** tab. +* With the Admin API's directory mapping endpoints. + +{{site.base_gateway}} will not write to the service directory. For example, a {{site.base_gateway}} admin cannot create users or groups in the directory. You must create users and groups independently before mapping them to {{site.base_gateway}}. + +## User-admin mapping + +To map a service directory user to a Kong admin, map the admin's username to the **name** value corresponding to the attribute configured in `admin_gui_auth_conf`. Create an admin account in [Kong Manager](/gateway/{{page.kong_version}}/kong-manager/auth/rbac/add-admin) or use the [Admin API](/gateway/{{page.kong_version}}/admin-api/admins/reference/#invite-an-admin). + +For instructions on how to pair the bootstrapped super admin with a directory user, see [Set up a directory user as the first super admin](#set-up-a-directory-user-as-the-first-super-admin). + +If you already have admins with assigned roles and want to use group mapping instead, it is necessary to first remove all of their roles. The service directory will serve as the system of record for user privileges. Assigned roles will affect a user's privileges in addition to any roles mapped from groups. + +## Group-role assignment + +Using service directory mapping, groups are mapped to roles. When a user logs in, they are identified with their admin username and authenticated with the matching user credentials in the service directory. +The groups in the service directory are then automatically matched to the associated roles that the organization has defined. + +### Example + +1. Example Corp maps the service directory group, `T1-Mgmt`, to the Kong role super-admin. +2. Example Corp maps a service directory user, named `example-user`, to a Kong admin account with the same name, `example-user`. +3. The user, `example-user`, is assigned to the group `T1-Mgmt` in the LDAP Directory. + + +When `example-user` logs in as an admin to Kong Manager, they will automatically have the role of super-admin as a result of the mapping. + +If Example Corp decides to revoke `example-user`'s privileges by removing their assignment to `T1-Mgmt`, they will no longer have the super-admin role when they attempt to log in. + +## Set up a directory user as the first super admin + +Setting up a directory user as the first super admin is recommended by Kong. + +The example shows an attribute configured with a unique identifier (UID), and the directory user you want to make the super admin has a distinguished name (DN) entry of `UID=example-user`: + +```sh +curl -i -X PATCH https://localhost:8001/admins/kong_admin \ + --header 'Kong-Admin-Token: ' \ + --header 'Content-Type: application/json' \ + --data '{"username":"example-user"}' +``` + +This user will be able to log in, but until you map a group belonging to `example-user` to a role, the user will only use the directory for authentication. Once you map the super-admin role to a group that `example-user` is in, then you can delete the super-admin role from the `example-user` admin. The group you pick needs to be “super” in your directory, otherwise as other admins log in with a generic group, for example the “employee” group, they will also become super-admins. + +{:.important} +> **Important**: If you delete the super-admin role from your only admin, and have not yet mapped the super-admin role to a group that admin belongs to, then you will not be able to log in to Kong Manager. + +Alternatives: + +* Start Kong with RBAC turned off, map a group to the super-admin role, and then create an admin to correspond to a user belonging to that group. Doing so ensures that the super admin's privileges are entirely tied to the directory group, whereas bootstrapping a super admin only uses the directory for authentication. + +* Create all admin accounts for matching directory users and ensure that their existing groups map to appropriate roles before enforcing RBAC. diff --git a/src/gateway/kong-manager/auth/oidc/configure.md b/src/gateway/kong-manager/auth/oidc/configure.md new file mode 100644 index 000000000000..376239346160 --- /dev/null +++ b/src/gateway/kong-manager/auth/oidc/configure.md @@ -0,0 +1,98 @@ +--- +title: Enable OIDC for Kong Manager +badge: enterprise +--- + +{{site.base_gateway}} offers the ability to bind authentication for Kong +Manager admins to an organization's OpenID Connect Identity +Provider using the +[OpenID Connect Plugin](/hub/kong-inc/openid-connect/). + +{:.note} +> **Note**: By using the configuration below, it is unnecessary to +manually enable the plugin. The configuration alone will enable +OIDC for Kong Manager. + +## Set up RBAC with OIDC + +The following is an example using Google as the IdP and serving Kong Manager +from its default URL, `http://127.0.0.1:8002`. + +The `admin_gui_auth_config` value must be valid JSON. + +``` +enforce_rbac = on +admin_gui_auth=openid-connect +admin_gui_session_conf = { "secret":"set-your-string-here" } +admin_gui_auth_conf={ \ + "issuer": "https://accounts.google.com/", \ + "client_id": [""], \ + "client_secret": [""], \ + "consumer_by": ["username","custom_id"], \ + "ssl_verify": false, \ + "consumer_claim": ["email"], \ + "leeway": 60, \ + "redirect_uri": ["http://localhost:8002"], \ + "login_redirect_uri": ["http://localhost:8002"], \ + "logout_methods": ["GET", "DELETE"], \ + "logout_query_arg": "logout", \ + "logout_redirect_uri": ["http://localhost:8002"], \ + "scopes": ["openid","profile","email","offline_access"], \ + "auth_methods": ["authorization_code"] \ +} +``` + +The **Sessions plugin** (configured with `admin_gui_session_conf`) requires a secret and is configured securely by default. +* Under all circumstances, the `secret` must be manually set to a string. +* If using HTTP instead of HTTPS, `cookie_secure` must be manually set to `false`. +* If using different domains for the Admin API and Kong Manager, `cookie_samesite` must be set to `off`. +Learn more about these properties in [Session Security in Kong Manager](/gateway/{{page.kong_version}}/kong-manager/auth//sessions/#session-security), and see [example configurations](/gateway/{{page.kong_version}}/kong-manager/auth/sessions/#example-configurations). + +Replace the entries surrounded by `<>` with values that are valid for your IdP. +For example, Google credentials can be found here: +[https://console.cloud.google.com/projectselector/apis/credentials](https://console.cloud.google.com/projectselector/apis/credentials) + +## Create an admin + +Create an admin that has a username matching the email returned from +the identity provider upon successful login: + +```bash +curl -i -X POST http://localhost:8001/admins \ + --data username="" \ + --data email="" \ + --header Kong-Admin-Token: +``` + +For example, if a user has the email address `example_user@example.com`: + +```bash +curl -i -X POST http://localhost:8001/admins \ + --data username="example_user@example_com" \ + --data email="example_user@example.com" \ + --header Kong-Admin-Token: +``` + +{:.note} +> **Note:** The email entered for the admin in the request is used to +ensure the admin receives an email invitation, whereas username is the +attribute that the plugin uses with the IdP. + +## Assign a role to the admin + +Assign the new admin at least one role so they can log in and access +Kong entities: + +```bash +curl -i -X POST http://localhost:8001/admins//roles \ + --data roles="" \ + --header Kong-Admin-Token: +``` + +For example, to grant `example_user@example.com` the role of super admin: + +```bash +curl -i -X POST http://localhost:8001/admins/example_user@example.com/roles \ + --data roles="super-admin" \ + --header Kong-Admin-Token: +``` diff --git a/src/gateway/kong-manager/auth/oidc/mapping.md b/src/gateway/kong-manager/auth/oidc/mapping.md new file mode 100644 index 000000000000..0b9bcbef6b16 --- /dev/null +++ b/src/gateway/kong-manager/auth/oidc/mapping.md @@ -0,0 +1,194 @@ +--- +title: OIDC Authenticated Group Mapping +badge: enterprise +--- + +Using Kong's [OpenID Connect plugin](/hub/kong-inc/openid-connect) (OIDC), you can map identity provider (IdP) +groups to Kong roles. Adding a user to Kong in this way gives them access to +Kong based on their group in the IdP. + +Admin accounts are now created automatically +when you map your identity provider (IdP) groups to Kong roles. You do +not need to create the users, groups, and roles separately. These users then accept invitations to join +Kong Manager and log in with their IdP credentials. + +{:.important} +> **Important:** In v2.7.x, the `admin_claim` parameter replaces the `consumer_claim` parameter required by +previous versions. + +If an admin's group changes in the IdP, their Kong admin account's associated +role also changes in {{site.base_gateway}} the next time they log in to Kong +Manager. The mapping removes the task of manually managing access in +{{site.base_gateway}}, because it makes the IdP the system of record. + +## Prerequisites + +* An IdP with an authorization server and users with groups assigned +* [{{site.base_gateway}} installed and configured](/gateway/{{page.kong_version}}/get-started) +* Kong Manager enabled +* RBAC enabled +* (Kubernetes) [Helm](https://helm.sh/docs/intro/install/) installed + +## Apply OIDC auth mapping to {{site.base_gateway}} + +### Review important values + +In the following examples, you specify the `admin_claim` and `authenticated_groups_claim` parameters +to identify which admin value and role name to map from the IdP to {{site.base_gateway}}, as well as +the `admin_auto_create_rbac_token_disabled` to specify whether an RBAC token is created for admins in Kong. + +* The `admin_claim` value specifies which IdP username value should map to Kong Manager. +The username and password are required for the user to log into the IdP. + +* The `authenticated_groups_claim` value specifies which IdP claim should be used to assign {{site.base_gateway}} roles to the +specified {{site.base_gateway}} admin. + + This value depends on your IdP -- for example, Okta configures claims for `groups`, and another IdP might configure them as `roles`. + + In the IdP, the group claim value must follow the format `:`. + + For example, if `"authenticated_groups_claim": ["groups"]` is specified, and in the IdP `groups:["default:super-admin"]` is specified, the administrators specified in `admin_claim` are assigned to the super-admin role in the default {{site.base_gateway}} workspace. + + If the mapping does not work as expected, decode the JWT that's created by your IdP, and make sure that the admin ID token includes the key:value pair `groups:["default:super-admin"]` for the case of this example, or the appropriate claim name and claim value as set in your IdP. + +* The `admin_auto_create_rbac_token_disabled` boolean enables or disables RBAC token +creation when automatically creating admins with OpenID Connect. The default is +`false`. + * Set to `true` to disable automatic token creation for admins + * Set to `false` to enable automatic token creation for admins + + +### Set up mapping + +{% navtabs %} +{% navtab Kubernetes with Helm %} + +1. Create a configuration file for the OIDC plugin and save it as +`admin_gui_auth_conf`. + + Provide your own values for all fields indicated by curly braces (`{}`): + + ```json + { + "issuer": "{YOUR_IDP_URL}", + "admin_claim": "email", + "client_id": ["{CLIENT_ID}"], + "client_secret": ["{CLIENT_SECRET}"], + "authenticated_groups_claim": ["{CLAIM_NAME}"], + "ssl_verify": false, + "leeway": 60, + "redirect_uri": ["{YOUR_REDIRECT_URI}"], + "login_redirect_uri": ["{YOUR_LOGIN_REDIRECT_URI}"], + "logout_methods": ["GET", "DELETE"], + "logout_query_arg": "logout", + "logout_redirect_uri": ["{YOUR_LOGOUT_REDIRECT_URI}"], + "scopes": ["openid","profile","email","offline_access"], + "auth_methods": ["authorization_code"], + "admin_auto_create_rbac_token_disabled": false + } + ``` + + For detailed descriptions of all OIDC parameters, see the + [OpenID Connect parameter reference](/hub/kong-inc/openid-connect/#configuration-parameters). + +2. Create a secret from the file you just created: + + ```sh + kubectl create secret generic kong-idp-conf --from-file=admin_gui_auth_conf -n kong + ``` + +3. Update the RBAC section of the deployment `values.yml` file with the +following parameters: + + ```yaml + rbac: + enabled: true + admin_gui_auth: openid-connect + session_conf_secret: kong-session-conf + admin_gui_auth_conf_secret: kong-idp-conf + ``` + +4. Using Helm, upgrade the deployment with your YAML filename: + + ```sh + helm upgrade --install kong-ee kong/kong -f ./myvalues.yaml -n kong + ``` +{% endnavtab %} +{% navtab Docker %} + +If you have a Docker installation, run the following command to set the needed +environment variables and reload the {{site.base_gateway}} configuration. + + Provide your own values for all fields indicated by curly braces (`{}`): + +```sh +echo " + KONG_ENFORCE_RBAC=on \ + KONG_ADMIN_GUI_AUTH=openid-connect \ + KONG_ADMIN_GUI_AUTH_CONF='{ + \"issuer\": \"{YOUR_IDP_URL}\", + \"admin_claim\": \"email\", + \"client_id\": [\"\"], + \"client_secret\": [\"\"], + \"authenticated_groups_claim\": [\"{CLAIM_NAME}\"],, + \"ssl_verify\": false, + \"leeway\": 60, + \"redirect_uri\": [\"{YOUR_REDIRECT_URI}\"], + \"login_redirect_uri\": [\"{YOUR_LOGIN_REDIRECT_URI}\"], + \"logout_methods\": [\"GET\", \"DELETE\"], + \"logout_query_arg\": \"logout\", + \"logout_redirect_uri\": [\"{YOUR_LOGOUT_REDIRECT_URI}\"], + \"scopes\": [\"openid\",\"profile\",\"email\",\"offline_access\"], + \"auth_methods\": [\"authorization_code\"], + \"admin_auto_create_rbac_token_disabled\": false + }' kong reload exit" | docker exec -i {KONG_CONTAINER_ID} /bin/sh +``` + +Replace `{KONG_CONTAINER_ID}` with the ID of your container. + +For detailed descriptions of all the parameters used here, and many other customization options, +see the [OpenID Connect parameter reference](/hub/kong-inc/openid-connect/#configuration-parameters). + +{% endnavtab %} +{% navtab kong.conf %} + +1. Navigate to your `kong.conf` file. + +2. With RBAC enabled, add the `admin_gui_auth` and `admin_gui_auth_conf` +properties to the file. + + Provide your own values for all fields indicated by curly braces (`{}`): + + ``` + enforce_rbac = on + admin_gui_auth = openid-connect + admin_gui_auth_conf = { + "issuer": "{YOUR_IDP_URL}", + "admin_claim": "email", + "client_id": ["{CLIENT_ID}"], + "client_secret": ["{CLIENT_SECRET}"], + "authenticated_groups_claim": ["{CLAIM_NAME}"], + "ssl_verify": false, + "leeway": 60, + "redirect_uri": ["{YOUR_REDIRECT_URI}"], + "login_redirect_uri": ["{YOUR_LOGIN_REDIRECT_URI}"], + "logout_methods": ["GET", "DELETE"], + "logout_query_arg": "logout", + "logout_redirect_uri": ["{YOUR_LOGOUT_REDIRECT_URI}"], + "scopes": ["openid","profile","email","offline_access"], + "auth_methods": ["authorization_code"], + "admin_auto_create_rbac_token_disabled": false + } + ``` + + For detailed descriptions of all the parameters used here, and many other + customization options, see the [OpenID Connect parameter reference](/hub/kong-inc/openid-connect/#configuration-parameters). + +3. Restart {{site.base_gateway}} to apply the file. + + ```sh + kong restart -c /path/to/kong.conf + ``` + +{% endnavtab %} +{% endnavtabs %} diff --git a/src/gateway/kong-manager/auth/rbac/add-admin.md b/src/gateway/kong-manager/auth/rbac/add-admin.md new file mode 100644 index 000000000000..e33b5901a4cc --- /dev/null +++ b/src/gateway/kong-manager/auth/rbac/add-admin.md @@ -0,0 +1,93 @@ +--- +title: Invite an Admin +badge: enterprise +--- + +An admin is any user in Kong Manager. They may access +Kong entities within their assigned workspaces based +on the permissions of their roles. + +This guide describes how to invite an admin in Kong +Manager. As an alternative, if a super admin wants to +invite an admin with the Admin API, it is possible to +do so using +[`/admins`](/gateway/{{page.kong_version}}/admin-api/admins/reference/#invite-an-admin). + +## Prerequisites + +* Authentication and RBAC are [enabled](/gateway/{{page.kong_version}}/kong-manager/auth/rbac/enable) +* You have [super admin permissions](/gateway/{{page.kong_version}}/kong-manager/auth/super-admin) +or a user that has `/admins` and `/rbac` read and write access + +## Invite an admin + +1. Navigate to the **Teams** page in Kong Manager. + +2. From the **Admins** tab, select **Invite Admin**. + +3. Fill out the username and email address. When a new admin receives an +invitation, they will only be able to log in with that email address. Assign any appropriate roles and click **Invite Admin** to send the invitation. + + Super admins can invite users to multiple workspaces, and + assign them any role available within workspaces, including roles that exist by default (for example, `super-admin`, `read-only`) and roles with customized permissions. + + The super admin can see all available roles across + workspaces on the **Roles** tab of the **Teams** page. + + +4. On the **Teams** page, the new invitee will appear on the **Admins** list in the **Invited** section. +Once they accept the invitation, the user will be listed in the main **Admins** list. + + By default, the registration link will expire after 259,200 + seconds (3 days). This time frame can be configured in the `kong.conf` + file using the [`admin_invitation_expiry`](/gateway/{{page.kong_version}}/reference/configuration) property. + + If an email fails to send, either due to an incorrect email + address or an external error, you can resend the invitation. + + If SMTP is not enabled or the invitation email fails to send, + the super admin can copy and provide a registration link directly. + +5. The newly invited admin will have the ability to set a password. If the admin ever forgets the password, they can reset it through a recovery email. + +## Copy and send a registration link + +If a mail server is not yet set up, it is still possible to invite admins to register and log in. + +1. Invite an admin as described in the section above. + +2. Open the admin's info page. Next to `register_url`, click the **Generate registration link** button. + + Copy and directly send this link to the invited admin so that they may set + up their credentials and log in. + +If `admin_gui_auth` is `ldap-auth-advanced`, credentials are not stored in Kong, and the admin will be directed to log in. + +## Grant an admin access with LDAP + +1. Pick a user in the LDAP directory that will be the super admin. + +2. Change the super admin’s username in Kong by making a `PATCH` request to +`admins/kong_admin` and setting the value of `username` to the corresponding +LDAP `attribute`. + + For example, if the LDAP user's attribute is `einstein`, + the `PATCH` to `/admins/kong_admin` should have a `username` set to `einstein`. + +3. Log in to Kong Manager using the LDAP credentials associated with the super +admin. + +4. Invite admins from the **Admins** page in Kong Manager, ensuring that the +`username` of each Admin is mapped to the `attribute` value set in the LDAP +directory. + + To enable the admins to log in, it is still necessary + to assign a role to them. + +5. Once an admin has logged in successfully and accesses the Admin API using +their LDAP credentials, they will be marked as `approved` on the Admins list +in Kong Manager. + + The new admins will still receive an email, but all + credentials will be handled through the LDAP server, not Kong Manager + or the Admin API. diff --git a/src/gateway/kong-manager/auth/rbac/add-role.md b/src/gateway/kong-manager/auth/rbac/add-role.md new file mode 100644 index 000000000000..07497a19ad02 --- /dev/null +++ b/src/gateway/kong-manager/auth/rbac/add-role.md @@ -0,0 +1,52 @@ +--- +title: Add a Role and Permissions +badge: enterprise +--- + +Roles make it easy to logically group and apply the same +set of permissions to admins. Permissions may be +customized in detail, down to individual actions and endpoints. + +{{site.base_gateway}} includes default roles for standard +use cases, e.g. inviting additional super admins, +inviting admins that may only `read` endpoints. + +This guide describes how to create a custom role in Kong +Manager for a unique use case. As an alternative, if a +super admin wants to create a role with the Admin API, +it is possible to do so using +[`/rbac/roles`](/gateway/{{page.kong_version}}/admin-api/rbac/reference/#add-a-role). +To add permissions to the new role, use +[`/rbac/roles/{name_or_id}/endpoints`](/gateway/{{page.kong_version}}/admin-api/rbac/reference/#add-a-role-endpoint-permission) +for endpoints or +[`/rbac/roles/{name_or_id}/entities`](/gateway/{{page.kong_version}}/admin-api/rbac/reference/#add-a-role-entity-permission) +for specific entities. + +## Prerequisites + +* Authentication and RBAC are [enabled](/gateway/{{page.kong_version}}/kong-manager/auth/rbac/enable) +* You have [super admin permissions](/gateway/{{page.kong_version}}/kong-manager/auth/super-admin) +or a user that has `/admins` and `/rbac` read and write access + +## Add a role and permissions + +1. From the **Admins** page, click the +**Add Role** button. + +1. On the **Add Role** form, name the **Role** according to the +**Permissions** you want to grant. + + It may be helpful for future reference to include + a brief comment describing the reason for the permissions or + a summary of the role. + +1. Click the **Add Permissions** button and fill out the form. +Add the endpoint permissions by marking the appropriate checkbox. + +1. Click **Add Permission to Role** to see the permissions listed on the form. + +1. To forbid access to certain endpoints, click **Add Permission** +again and use the **negative** checkbox. + +1. Submit the form to see the new roles appear on the +admins page. diff --git a/src/gateway/kong-manager/auth/rbac/add-user.md b/src/gateway/kong-manager/auth/rbac/add-user.md new file mode 100644 index 000000000000..ca83ff127ee7 --- /dev/null +++ b/src/gateway/kong-manager/auth/rbac/add-user.md @@ -0,0 +1,56 @@ +--- +title: Create an RBAC User +badge: enterprise +--- + +## Admins vs. RBAC users + +| | Admin API | Kong Manager | +|------------|-----------|--------------| +| Admins | ✔️ | ✔️ | +| RBAC users | ✔️ | X | + + +An RBAC user has the ability to access the {{site.base_gateway}} Admin API. The permissions assigned to their role will define the types of actions they can perform with various Admin API objects. + +An [admin](/gateway/{{page.kong_version}}/kong-manager/auth//), like an RBAC user, has the ability to access the {{site.base_gateway}} Admin API. The admin also has the ability log in to Kong Manager. Like an RBAC user, an admin’s role determines the types of actions it can perform, except that they also have the ability to benefit from Kong Manager’s interface and visualizations. + +If creating a *service account* for {{site.base_gateway}}, e.g., for a machine as part of an automated process, then an RBAC User is adequate. + +If creating a *personal account* for {{site.base_gateway}}, then admin may be preferable since it also has access to Kong Manager. + +## Prerequisites + +* Authentication and RBAC are [enabled](/gateway/{{page.kong_version}}/kong-manager/auth/rbac/enable) +* You have [super admin permissions](/gateway/{{page.kong_version}}/kong-manager/auth/super-admin) +or a user that has `/admins` and `/rbac` read and write access + +## Add an RBAC user in Kong Manager + +1. From the dashboard, click the **Teams** tab. + +2. On the **Teams** page, click the **RBAC Users** tab. + +3. Using the dropdown menu, select which **Workspace** the new user has access to. + + {:.note} + > **Note:** The **Default Workspace** is global, meaning the RBAC user with access to default has access to entities across all other Workspaces. This workspace assignment is useful for administrative and auditing accounts, but not for members of specific teams. + +4. Click the **Add New User** button to open the registration form. + +5. Fill out the **Add New User** registration form. + + * The name of the RBAC user must be globally unique, even if two users are in different workspaces, and it can't have the same name as an admin account. + These naming conventions are important if using OIDC, LDAP, or another external method of identity and access management. + * The RBAC user account is enabled by default. If you want the RBAC user account to start in a disabled state and enable it later, uncheck the **Enabled** box. + +6. Click the **Add/Edit Roles** button. Select the role (or roles) desired for the new RBAC User. + + * If the RBAC user has no roles assigned, it will not have permission to access any objects. + * An RBAC user’s role assignments may be altered later if needed. + * The roles can only belong to one workspace, as selected in Step 3. + * To provide an RBAC user with access to objects in multiple workspaces, see Step 3. + +7. Click **Create User** to complete the user registration. + + The page will automatically redirect back to the **Teams** page, where the new user is listed. diff --git a/src/gateway/kong-manager/auth/rbac/enable.md b/src/gateway/kong-manager/auth/rbac/enable.md new file mode 100644 index 000000000000..b874b29d9dac --- /dev/null +++ b/src/gateway/kong-manager/auth/rbac/enable.md @@ -0,0 +1,8 @@ +--- +title: Enable RBAC in Kong Manager +--- + +Enable role-based access control (RBAC) to secure Kong Manager. +When RBAC is enabled, Kong Manager will no longer be publicly accessible, and users will need to log in to Kong Manager. + +{% include_cached /md/enterprise/turn-on-rbac.md %} diff --git a/src/gateway/kong-manager/auth/rbac/index.md b/src/gateway/kong-manager/auth/rbac/index.md new file mode 100644 index 000000000000..6cde696aba1f --- /dev/null +++ b/src/gateway/kong-manager/auth/rbac/index.md @@ -0,0 +1,54 @@ +--- +title: RBAC in Kong Manager +badge: enterprise +--- + +In addition to authenticating admins and segmenting workspaces, +{{site.base_gateway}} has the ability to enforce Role-Based Access Control +(RBAC) for all resources with the use of roles assigned to admins. + +As the super admin (or any role with read and write +access to the `/admins` and `/rbac` endpoints), it is possible to +create new roles and customize permissions. + +In Kong Manager, RBAC affects how admins are able to navigate +through the application. + +## Default roles + +Kong includes Role-Based Access Control (RBAC). Every admin using Kong Manager +needs an assigned role based on the resources they have permission to access. + +When a super admin starts Kong for the first time, the `default` workspace +includes three default roles: `read-only`, `admin`, and `super-admin`. The three +roles have permissions related to every workspace in the cluster. + +Similarly, if a role is confined to certain workspaces, the admin assigned to it +will not be able to see either the overview or links to other workspaces. + +If a role does not have permission to access entire endpoints, +the admin assigned to the role will not be able to see the related navigation links. + +{:.important} +> Important: Although a default admin has full permissions to every +endpoint in Kong, only a super admin has the ability to assign and modify RBAC permissions. +An admin is not able to modify their own permissions or delimit a super admin's permissions. + +## RBAC in workspaces + +If RBAC roles and permissions are assigned from within a workspace, they are specific to that workspace. +For example, if there are two workspaces, Payments and +Deliveries, an admin created in Payments doesn't have access to any +endpoints in Deliveries. + +When a super admin creates a new workspace, there are three default roles that +mirror the cluster-level roles, and a fourth unique to each workspace: +`workspace-read-only`, `workspace-admin`, `workspace-super-admin`, and +`workspace-portal-admin`. + +These roles can be viewed in the **Teams** > **Roles** tab in Kong Manager. + +{:.important} +> Important: Any role assigned in the `default` workspace will have +permissions applied to all subsequently created workspaces. A super admin +in `default` has RBAC Permissions across all workspaces. diff --git a/src/gateway/kong-manager/auth/reset-password.md b/src/gateway/kong-manager/auth/reset-password.md new file mode 100644 index 000000000000..8b5df76f01b6 --- /dev/null +++ b/src/gateway/kong-manager/auth/reset-password.md @@ -0,0 +1,56 @@ +--- +title: Reset Passwords and RBAC Tokens in Kong Manager +badge: enterprise +--- + +For authentication, Kong uses two different credentials for admins: + +1. An admin uses a **password** to log in to Kong Manager. +2. An admin uses an **RBAC token** to make requests to the Kong Admin API. + +If using [basic authentication](/gateway/{{page.kong_version}}/kong-manager/auth/basic), an admin may reset their password from within Kong Manager. Since **LDAP** and **OIDC Authentication** imply that an organization stores and manages passwords outside of Kong, password reset is not possible with either type. + +Each RBAC token is stored in Kong as a hash. Regardless of the authentication option selected, an admin may reset their RBAC token from within Kong Manager. Note that to support confidentiality, RBAC tokens are hashed and cannot be retrieved after they are created. If a user forgets the token, the only recourse is to reset it. + +## Reset a forgotten password in Kong Manager + +### Prerequisites + +* Authentication and RBAC are [enabled](/gateway/{{page.kong_version}}/kong-manager/auth/rbac/enable) with [basic authentication](/gateway/{{page.kong_version}}/kong-manager/auth/basic) +* [SMTP](/gateway/{{page.kong_version}}/kong-manager/configuring-to-send-email) is configured to send emails + +### Steps + +1. At the login page, click **Forgot Password**. +2. Enter the email address associated with the account. +3. Click the link from the email. +4. Reset the password. Note that you will need to provide it again immediately after the reset is complete. +5. Log in with the new password. + +## Change a password from within Kong Manager + +### Prerequisites + +* Authentication and RBAC are [enabled](/gateway/{{page.kong_version}}/kong-manager/auth/rbac/enable) with [basic authentication](/gateway/{{page.kong_version}}/kong-manager/auth/basic) +* You have [super admin permissions](/gateway/{{page.kong_version}}/kong-manager/auth/super-admin) +or a user that has `/admins` and `/rbac` read and write access + +### Steps + +1. Open the dropdown from your **account name**, then select **Profile**. +2. In the **Reset Password** section, fill in the fields and click the **Reset Password** button. + +## Reset an RBAC token in Kong Manager + +### Prerequisites + +* Authentication and RBAC are [enabled](/gateway/{{page.kong_version}}/kong-manager/auth/rbac/enable) +* You have [super admin permissions](/gateway/{{page.kong_version}}/kong-manager/auth/super-admin) +or a user that has `/admins` and `/rbac` read and write access + +### Steps + +1. Open the dropdown from your **account name**, then select **Profile**. +2. In the **Reset RBAC Token** section, click **Reset Token** and confirm the reset. +3. Type in a new token and click **Reset**. +4. To copy the token, click the **Copy** button. diff --git a/src/gateway/kong-manager/auth/sessions.md b/src/gateway/kong-manager/auth/sessions.md new file mode 100644 index 000000000000..6372a6fbf580 --- /dev/null +++ b/src/gateway/kong-manager/auth/sessions.md @@ -0,0 +1,96 @@ +--- +title: Sessions in Kong Manager +badge: enterprise +--- + +When a user logs in to Kong Manager with their credentials, the Sessions Plugin +will create a session cookie. The cookie is used for all subsequent requests and +is valid to authenticate the user. The session has a limited duration and renews +at a configurable interval, which helps prevent an attacker from obtaining and + using a stale cookie after the session has ended. + +The Session configuration is secure by default, which may +[require alteration](#session-security) if using HTTP or different domains for +the Admin API and Kong Manager. Even if an attacker were to obtain a stale +cookie, it would not benefit them since the cookie is encrypted. The encrypted +session data may be stored either in Kong or the cookie itself. + +## Configuration the Sessions plugin for Kong Manager + +To enable sessions authentication, configure the following: + +``` +enforce_rbac = on +admin_gui_auth = +admin_gui_session_conf = { + "secret":"", + "cookie_name":"", + "storage":"", + "cookie_lifetime":, + "cookie_renew": + "cookie_secure": + "cookie_samesite":"" +} +``` + +Attribute | Description +----------|------------ +`cookie_name` | A name for the cookie.
      For example, `"cookie_name":"kong_cookie"` +`secret` | The secret used in keyed HMAC generation. Although the Session plugin's default is a random string, the `secret` _must_ be manually set for use with Kong Manager since it must be the same across all Kong workers/nodes. +`storage` | The location where session data is stored.
      The default value is `cookie`. It may be more secure if set to `kong`, since access to the database would be required. +`cookie_lifetime` | The duration (in seconds) that the session will remain open.
      The default value is `3600`. +`cookie_renew` | The duration (in seconds) of a session remaining at which point the plugin renews the session.
      The default value is `600`. +`cookie_secure` | Applies the Secure directive so that the cookie may be sent to the server only with an encrypted request over the HTTPS protocol. See [Session Security](#session-security) for exceptions.
      The default value is `true`. +`cookie_samesite`| Determines whether and how a cookie may be sent with cross-site requests. See [Session Security](#session-security) for exceptions.
      The default value is `strict`. + +{:.important} +> **Important:** The following properties must **not** be altered from default for use with Kong Manager: +* `logout_methods` +* `logout_query_arg` +* `logout_post_arg` + +For detailed descriptions of each configuration property, learn more in the +[Session plugin documentation](/hub/kong-inc/session). + +## Session security + +The Session configuration is secure by default, so the cookie uses the +[Secure, HttpOnly](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#Secure_and_HttpOnly_cookies), +and [SameSite](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#SameSite_cookies) +directives. + +The following properties must be altered depending on the protocol and domains in use: +* If using HTTP instead of HTTPS: `"cookie_secure": false` +* If using different domains for the Admin API and Kong Manager: `"cookie_samesite": "off"` + +{:.important} +> **Important:** Sessions are not invalidated when a user logs out if `"storage": "cookie"` (the default) is used. In that case, the cookie is deleted client-side. Only when session data is stored server-side with `"storage": "kong"` set is the session actively invalidated. + + +## Example configurations + +If using HTTPS and hosting Kong Manager and the Admin API from the same domain, +the following configuration could be used for Basic Auth: + +``` +enforce_rbac = on +admin_gui_auth = basic-auth +admin_gui_session_conf = { + "cookie_name":"$4m04$", + "secret":"change-this-secret", + "storage":"kong" +} +``` + +In testing, if using HTTP, the following configuration could be used instead: + +``` +enforce_rbac = on +admin_gui_auth = basic-auth +admin_gui_session_conf = { + "cookie_name":"04tm34l", + "secret":"change-this-secret", + "storage":"kong", + "cookie_secure":false +} +``` diff --git a/src/gateway/kong-manager/auth/super-admin.md b/src/gateway/kong-manager/auth/super-admin.md new file mode 100644 index 000000000000..93b0c453eb1c --- /dev/null +++ b/src/gateway/kong-manager/auth/super-admin.md @@ -0,0 +1,58 @@ +--- +title: Create a Super Admin +badge: enterprise +--- + +If you seeded a super admin at the time of running +migrations by passing `KONG_PASSWORD`, you can log in to Kong Manager +with the `kong_admin` username. + +Otherwise, if `enforce_rbac=off`, you can create your first +super admin within Kong Manager itself. + +You can also use this guide to create additional super admins once +you have an account and `enforce_rbac=on`. + +## Create a super admin + +If you have a super admin account already and need to create additional super admins, +follow these steps: + +1. Go to the **Teams** tab in Kong Manager. + +2. Click the **Invite Admin** button and fill out the form. + +3. Give the user the `super-admin` role in the `default` workspace. + +4. Return to the Admins page, and in the **Invited** section, +click the email address of the user in order to view them. + +5. Click **Generate Registration Link**. + +6. Copy the link for later use after completing the account setup. + +{:.important} +> **Important:** Kong Manager does not support entity-level RBAC. Run Kong +Manager on a node where `enforce_rbac` is set to `on` or `off`, but not `both`. + + +## Create your first super admin account post-installation + +In the event that the default `kong_admin` super admin was not seeded +during the initial database preparation step as defined in +[How To Start {{site.base_gateway}} Securely](/gateway/{{page.kong_version}}/production/access-control/start-securely/), +the following steps outline how to create and enable a new super admin post +installation. + +1. Follow the instructions to [create a new super admin](#create-a-super-admin) user +account and generate a registration link. + +2. Before the link generated above can be used, RBAC and GUI authentication must +be enabled. Follow the instructions for +[enabling basic authentication on Kong Manager](/gateway/{{page.kong_version}}/kong-manager/auth/basic). + +3. Paste the URL in your browser. You will be asked to create a password for +the newly defined super admin user. + +4. Go to the Kong Manager homepage to login with the +new super admin credentials. diff --git a/src/gateway/kong-manager/auth/workspaces-and-teams.md b/src/gateway/kong-manager/auth/workspaces-and-teams.md new file mode 100644 index 000000000000..2a8834afc7cd --- /dev/null +++ b/src/gateway/kong-manager/auth/workspaces-and-teams.md @@ -0,0 +1,133 @@ +--- +title: Access Control with Workspaces and Teams +badge: enterprise +--- + +In this topic, you’ll learn how to manage and configure user authorization using workspaces and teams in {{site.base_gateway}} with Kong Manager. + +## Securing your Gateway installation + +At a high level, securing {{site.base_gateway}} administration is a two-step process: + +1. Turn on RBAC. +2. Create a workspace and an admin for segregated administration. + +In the following sections, you will need the `kong_admin` account’s password to log in to {{site.base_gateway}}, and the `kong_admin_uri` needs to be configured to avoid getting CORS errors. + +## Prerequisites + +* RBAC is [enabled](/gateway/{{page.kong_version}}/kong-manager/auth/rbac/enable) +* You are [logged in as the super admin](/gateway/{{page.kong_version}}/kong-manager/auth/super-admin) +or a user that has `/admins` and `/rbac` read and write access. + +## Create a workspace + +For this example, start by creating a simple workspace called `SecureWorkspace`. + +### Log into Kong Manager + +1. Go to Kong Manager, or reload the page if you already have it open to see a login screen. +2. Log in to Kong Manager with the built-in Super Admin account, `kong_admin`, and its password. + + Remember, this is the initial `KONG_PASSWORD` you used when you ran migrations during installation. + +3. If you have logged in successfully, then you can start administering your {{site.base_gateway}} cluster. + + If this step did not work, and you know the credentials are correct, then something is likely wrong with your {{site.base_gateway}} configuration. Double-check the settings. If the cause of the problem still isn’t clear, work with your {{site.konnect_product_name}} account team and [Kong Support](https://support.konghq.com/) for assistance. + +### Create the workspace + +1. Access your Kong Manager instance. +2. On the workspaces tab, click on **New Workspace**. +3. Create a workspace named `SecureWorkspace` and select a color or image for the workspace avatar. + + Each workspace name should be unique, regardless of letter case. For example, naming one workspace “Payments” and another one “payments” will create two different workspaces that appear identical. + + {:.important} + > Do not give a workspace the same name as any of these major routes in Kong Manager: + > + |---------|-----------|--------------|---------------| + | Admins | APIs | Certificates | Consumers | + | Plugins | Portal | Routes | Services | + | SNIs | Upstreams | Vitals | PermalinkStep | + +4. Click **Create New Workspace**. +5. In the new workspace, click **Teams**. +6. From the Teams page, click the **Roles** tab to view the default roles that come with {{site.base_gateway}}. +7. Select SecureWorkspace to see its assigned roles. + + By default, each new workspace has the following roles and privileges: + + | Role | Description | + |--------------------------|----------------------------------------------------------------------------------------------| + | *workspace-admin* | Can administer the objects in a workspace but can’t add new administrators to the workspace. | + | *workspace-portal-admin* | Can manage the Dev Portal. | + | *workspace-read-only* | Can view anything in the workspace, but can’t make any changes. | + | *workspace-super-admin* | Can do anything inside the workspace. | + +**Notes:** + +* **Caution** Granting access to the **default** workspace gives access to all workspaces in the organization. + +* The **default** workspace only has three roles: *workspace-admin*, *workspace-super-admin*, and *workspace-read-only*. Every other workspace will have the four roles mentioned above. + +* You can also create custom roles by clicking on the **Add Role** button and specifying the endpoints that the administrator with the role will be able to interact with. + +## Create an admin + +Next, create an admin for the SecureWorkspace, granting them permissions to manage only that workspace. + +### Invite a new admin + +1. From the **Teams** > **Admins** tab, click **Invite Admin**. +2. Enter the new administrator’s **Email address** , **Username**, and **Custom Id**. +3. Ensure that **Enable RBAC Token** is enabled. + + This setting lets the admin use the Admin API as well as Kong Manager. + If you don’t want this user to access the Admin API, uncheck this box. + +4. Click **Add/Edit Roles**. +5. In the Workspace Access dialog, select the **SecureWorkspace**. +6. Select the **workspace-admin** role, which makes this user the workspace administrator for the SecureWorkspace. + + When you are done adding roles, you are redirected back to the **Invite Admin** dialog. + + {:.important} + > **Important:** Before you move on, make sure the **Enable RBAC Token** checkbox is checked. The RBAC token is what allows the new admin to send a token to the Admin API to configure the system programmatically. + +7. Click **Invite Admin** to send the invite. + + If you have [SMTP](/gateway/{{page.kong_version}}/kong-manager/configuring-to-send-email) set up, Kong Manager sends an email with a registration link. + + If you don't have SMTP enabled, you can generate a registration link for the new administrator manually. + +### Register the admin manually + +1. Back on the **Teams** page, click the administrator you just created. +2. Click the **Generate registration link** button. + + Using this link, the new administrator can go to a web browser and paste it in to initiate his/her account and create an initial password. Again, normally, this would happen through SMTP, and the user would get this link through an email. + +3. Click the **copy icon** to copy the registration link, then save it. + +4. Send the registration link to the new administrator, or use it yourself to test the login in the following steps. + +5. Open a different browser or an incognito tab in the current browser. +6. Enter the registration link you copied previously into the browser to log in with the new administrator. + + If the registration link has expired, you can generate a new one by logging in with your `kong_admin` administrator and generating a new link. + +7. Enter a new password for your new administrator (save this in a secure place) and click the **Register** button. + + If everything went well, you should see an “Account Setup Success” message. + +## Verify the new admin + +1. Click the **Login** button to be taken to a new screen to log in with your new administrator. +2. Enter the **Username** and **Password** of your new administrator and click **Login** again. + + Once you log in, you’ll notice that you can only see the SecureWorkspace. + +3. You can also verify that this user’s administration rights are limited. As this user, if you open the Teams tab and try to add new administrators, Admin API users (RBAC users), groups, or roles, you won’t have the permissions to do so. + +You are now controlling access to {{site.base_gateway}} administration with RBAC. diff --git a/src/gateway/kong-manager/configuring-to-send-email.md b/src/gateway/kong-manager/configuring-to-send-email.md new file mode 100644 index 000000000000..1b80d8faea44 --- /dev/null +++ b/src/gateway/kong-manager/configuring-to-send-email.md @@ -0,0 +1,23 @@ +--- +title: Configuring Kong Manager to Send Email +badge: enterprise +--- + +A **Super Admin** can invite other **Admins** to register in Kong Manager, and **Admins** +can reset their passwords using the "Forgot Password" functionality. Both of these +workflows use email to communicate with the user. + +Emails from Kong Manager require the following configuration through `kong.conf`: + +* [`admin_emails_from`](/gateway/{{page.kong_version}}/reference/configuration/#admin_emails_from) +* [`admin_emails_reply_to`](/gateway/{{page.kong_version}}/reference/configuration/#admin_emails_reply_to) +* [`admin_invitation_expiry`](/gateway/{{page.kong_version}}/reference/configuration/#admin_invitation_expiry) + +Kong does not check for the validity of email +addresses set in the configuration. If the SMTP settings are +configured incorrectly, for example if they point to a non-existent +email address, Kong Manager will _not_ display an error message. + +For additional information about SMTP, refer to the +[general SMTP configuration](/gateway/{{page.kong_version}}/reference/configuration/#general-smtp-configuration) +shared by Kong Manager and Dev Portal. diff --git a/src/gateway/kong-manager/enable.md b/src/gateway/kong-manager/enable.md new file mode 100644 index 000000000000..486442062a65 --- /dev/null +++ b/src/gateway/kong-manager/enable.md @@ -0,0 +1,51 @@ +--- +title: Enable Kong Manager +badge: free +--- + +If you're running {{site.base_gateway}} with a database (either in traditional +or hybrid mode), you can enable {{site.base_gateway}}'s graphical user interface +(GUI), Kong Manager. + +{% navtabs %} +{% navtab Docker %} + +1. Set the [`KONG_ADMIN_GUI_URL`](/gateway/{{page.kong_version}}/reference/configuration/#admin_gui_url) property in the `kong.conf` configuration file to the DNS, or IP address, of your system, then restart Kong for the setting to take effect. For example: + + ```bash + echo "-e 'KONG_ADMIN_GUI_URL=http://localhost:8002' \ + kong reload exit" | docker exec -i KONG_CONTAINER_ID /bin/sh + ``` + + Replace `KONG_CONTAINER_ID` with the ID of your Docker container. + +2. Access Kong Manager on port `8002`. + +{% endnavtab %} +{% navtab Linux (kong.conf) %} + +1. Update the [`admin_gui_url`](/gateway/{{page.kong_version}}/reference/configuration/#admin_gui_url) property + in the `kong.conf` configuration file to the DNS, or IP address, of your system. For example: + + ``` + admin_gui_url = http://localhost:8002 + ``` + + This setting needs to resolve to a network path that can reach the operating system (OS) host. + +2. Restart {{site.base_gateway}} for the setting to take effect, using the following command: + + ```bash + kong restart -c {PATH_TO_KONG.CONF_FILE} + ``` + +3. Access Kong Manager on port `8002`. + +{% endnavtab %} +{% endnavtabs %} + +## Next steps + +* [Get started with managing {{site.base_gateway}}](/gateway/{{page.kong_version}}/kong-manager/get-started/services-and-routes) +* [Set up authentication for Kong Manager](/gateway/{{page.kong_version}}/kong-manager/auth/) +* [Set up role-based access control to {{site.base_gateway}} resources](/gateway/{{page.kong_version}}/kong-manager/auth/rbac/) diff --git a/src/gateway/kong-manager/get-started/consumers.md b/src/gateway/kong-manager/get-started/consumers.md new file mode 100644 index 000000000000..43b6235b9ed3 --- /dev/null +++ b/src/gateway/kong-manager/get-started/consumers.md @@ -0,0 +1,53 @@ +--- +title: Authentication with Consumers +badge: free +--- + +In this example, you’re going to enable the **Key Authentication plugin**, then create a consumer that uses key authentication. API key authentication is one of the most popular ways to conduct API authentication and can be implemented to create and delete access keys as required. + +If you prefer to use the Admin API, check out the [{{site.base_gateway}} getting started guide](/gateway/latest/get-started/key-authentication). + +## Set up the Key Authentication Plugin + +From the **Workspaces** tab in Kong Manager: + +1. Open the **default** workspace. +2. From the menu, open **Routes** and select the **mocking** route you created. +4. From the sub-menu, select the **Plugins** tab, then click **Install Plugin**. +5. Find the **Key Authentication** plugin and click **Enable**. +6. On the **Install plugin: key-auth** page, the plugin fields are automatically scoped to the route because the plugin is selected from the mocking route's page. + + For this example, this means that you can use all of the default values. +7. Click **Create**. + +Now, if you try to access the route without providing an API key, the request will fail, and you’ll see the message `"No API key found in request".` + +Before Kong proxies requests for this route, it needs an API key. For this example, since you installed the Key Authentication plugin, you need to create a consumer with an associated key first. + + +## Set up Consumers and Credentials + +From the **Workspaces** tab in Kong Manager: + +1. Open the **default** workspace. +2. From the menu, open **Consumers**, then click **New Consumer**. +3. Enter a **Username** and **Custom ID**. For this example, you can use `consumer` for each field. +4. Click **Create**. +5. On the Consumers page, open your new consumer. +6. Open **Credentials** from the sub-menu. +7. Click **New Key Auth Credential**. +8. Set the key to `apikey` and click **Create**. + +The new Key Authentication ID displays on the **Consumers** page under the **Credentials** tab. + +## Validate Key Authentication + +To validate the Key Authentication plugin, access your route through your browser by appending `?apikey=apikey` to the url: + +``` +http://localhost:8000/mock?apikey=apikey +``` + +## Next steps + +Next, you’ll learn about [load balancing upstream services using targets](/gateway/{{page.kong_version}}/kong-manager/get-started/load-balancing). diff --git a/src/gateway/kong-manager/get-started/load-balancing.md b/src/gateway/kong-manager/get-started/load-balancing.md new file mode 100644 index 000000000000..f2b45d8fa0b3 --- /dev/null +++ b/src/gateway/kong-manager/get-started/load-balancing.md @@ -0,0 +1,46 @@ +--- +title: Load balancing in Kong Manager +badge: free +--- + +This tutorial walks you through setting up load balancing across targets in Kong Manager. + +For Admin API instructions, check out the [{{site.base_gateway}} getting started guide](/gateway/latest/get-started/load-balancing/). + +## Prerequisites + +You need a {{site.base_gateway}} instance with Kong Manager [enabled](/gateway/{{page.kong_version}}/kong-manager/enable). + +## Set up upstreams and targets + +In this tutorial, you will create an upstream named `example_upstream` and add two targets to it. + +From the **Workspaces** tab in Kong Manager: + +1. Open the **default** workspace. +2. From the menu, open **Upstreams**, then click **New Upstream**. +3. For this example, enter `example_upstream` in the **Name** field, then click **Create**. +4. Click on your new upstream to open its detail page. +5. From the sub-menu, open **Targets**, then click **New Target**. +6. In the target field, set the value `httpbin.org:80`, and click **Create**. +7. Create another target, this time for `mockbin.org:80`. +8. Open the **Services** page. +9. Open your `example_service`, then click **Edit**. +10. Change the **Host** field to `example_upstream`, then click **Update**. + +You now have an upstream with two targets, `httpbin.org` and `mockbin.org`, and a service pointing to that upstream. + +## Validate the upstream services + +To test that {{site.base_gateway}} is load balancing traffic across the two targets: + +1. With the upstream configured, validate that it’s working by visiting the route `http://localhost:8000/mock` using a web browser or the shell. + +2. Refresh the page a few times. The site should change back and forth from `httpbin` to `mockbin`. + +## Next steps + +Next, check out some guides on what else you can do in Kong Manager: +* [Set up authentication for Kong Manager](/gateway/{{page.kong_version}}/kong-manager/auth) +* [Manage workspaces and teams with role-based access control (RBAC)](/gateway/{{page.kong_version}}/kong-manager/auth/workspaces-and-teams) +* [Create custom workspaces](/gateway/{{page.kong_version}}/kong-manager/workspaces) diff --git a/src/gateway/kong-manager/get-started/proxy-caching.md b/src/gateway/kong-manager/get-started/proxy-caching.md new file mode 100644 index 000000000000..9c373c0e2e78 --- /dev/null +++ b/src/gateway/kong-manager/get-started/proxy-caching.md @@ -0,0 +1,38 @@ +--- +title: Proxy Caching +badge: free +--- + +This tutorial walks you through setting up proxy caching in Kong Manager. + +Use proxy caching so that upstream services are not bogged down with repeated requests. With proxy caching, {{site.base_gateway}} can respond with cached results for better performance. + +If you prefer to use the Admin API, check out the [{{site.base_gateway}} getting started guide](/gateway/latest/get-started/proxy-caching). + +## Prerequisites + +You need a {{site.base_gateway}} instance with Kong Manager [enabled](/gateway/{{page.kong_version}}/kong-manager/enable). + +## Set up the Proxy Caching plugin + +From the **Workspaces** tab in Kong Manager: + +1. Open the **default** workspace. +2. From the menu, open **Plugins**, then click **Install Plugin**. +3. Find the **Proxy Caching** plugin, then click **Enable**. +4. Select to apply the plugin as **Global**. This means that proxy caching applies to all requests. +5. Scroll down and complete only the following fields with the parameters listed. + 1. config.cache_ttl: `30` + 2. config.content_type: `application/json` and `charset=utf-8` + 3. config.strategy: `memory` + + Besides the above fields, there may be others populated with default values. For this example, leave the rest of the fields as they are. +6. Click **Install**. + + + +## Next Steps + +Next, you’ll learn about [securing services](/gateway/{{page.kong_version}}/kong-manager/get-started/consumers) through Kong Manager. diff --git a/src/gateway/kong-manager/get-started/rate-limiting.md b/src/gateway/kong-manager/get-started/rate-limiting.md new file mode 100644 index 000000000000..1a3eb5369c01 --- /dev/null +++ b/src/gateway/kong-manager/get-started/rate-limiting.md @@ -0,0 +1,44 @@ +--- +title: Rate Limiting +badge: free +--- + +This tutorial walks you through setting up rate limiting for a service in Kong Manager. + +If you prefer to use the Admin API, check out the [{{site.base_gateway}} getting started guide](/gateway/latest/get-started/rate-limiting). + +## Prerequisites + +You need a {{site.base_gateway}} instance with Kong Manager [enabled](/gateway/{{page.kong_version}}/kong-manager/enable). + +## Set up the Rate Limiting plugin + +On the Workspaces tab in Kong Manager: + +1. Open the **default** workspace. +2. From the menu, open **Plugins**, then click **Install Plugin**. +3. Find the **Rate Limiting** plugin, then click **Enable**. +4. Apply the plugin as **Global**, which means the rate limiting applies to all requests, including every service and route in the workspace. + + If you switched it to **Scoped**, the rate limiting would apply the plugin to only one service, route, or consumer. + + By default, the plugin is automatically enabled when the form is submitted. + You can also toggle the **This plugin is Enabled** button to configure the plugin without enabling it. + For this example, keep the plugin enabled. +5. Complete only the following fields with the following parameters. + 1. config.limit: `5` + 2. config.sync_rate: `-1` + 3. config.window_size: `30` + + Besides the above fields, there may be others populated with default values. For this example, leave the rest of the fields as they are. +6. Click **Install**. + +## Validate rate limiting + +1. Enter `https://localhost:8000/mock` in your browser address bar, then refresh your browser six times. + After the 6th request, you’ll receive an error message. + +2. Wait at least 30 seconds and try again. + The service will be accessible until the sixth (6th) access attempt within a 30-second window. + +Next, head on to learn about [proxy caching](/gateway/{{page.kong_version}}/kong-manager/get-started/proxy-caching). diff --git a/src/gateway/kong-manager/get-started/services-and-routes.md b/src/gateway/kong-manager/get-started/services-and-routes.md new file mode 100644 index 000000000000..46fa1536ceb5 --- /dev/null +++ b/src/gateway/kong-manager/get-started/services-and-routes.md @@ -0,0 +1,68 @@ +--- +title: Services and Routes +badge: free +--- + +This tutorial walks you through creating services and routes in Kong Manager. + +If you prefer to use the Admin API, check out the [{{site.base_gateway}} getting started guide](/gateway/latest/get-started/configure-services-and-routes/). + +## Prerequisites + +You need a {{site.base_gateway}} instance with Kong Manager [enabled](/gateway/{{page.kong_version}}/kong-manager/enable). + +## Add a service + +In this tutorial, you’ll create a service pointing to the Mockbin +API. Mockbin is an “echo” type public website that returns requests back to the +requester as responses. + +On the Workspaces tab in Kong Manager: + +1. Open the **default** workspace. + + This example uses the default workspace, but you can also create a new + workspace, or use an existing workspace. + +2. From the **Services** section, click **New Service**. + +3. In the **Create service** dialog, enter the name `example_service` and the +URL `http://mockbin.org`. + +4. Click **Create**. + +The service is created, and the page automatically redirects back to the +`example_service` overview page. + +## Add a route + +For the service to be accessible through the API gateway, you need to add a +route to it. + +1. From the `example_service` overview page, open **Routes** from the sub-menu +and click **New Route**. +2. On the **Create route** page, the **Service** field is auto-populated with + the service name and ID number. This field is required. + + If the Service field is not automatically populated, click + **Services** in the left navigation pane. Find your service, click the + clipboard icon next to the ID field, then go back to the **Create Route** + page and paste it into the **Service field**. +3. Enter a name for the route, and at least one of the following fields: Host, +Methods, or Paths. For this example, use the following: + 1. For **Name**, enter `mocking`. + 2. For **Path(s)**, click **Add Path** and enter `/mock`. +4. Click **Create**. + +Kong automatically redirects you to the `example_service` overview page. +The new route appears under the Routes section. + +## Verify the route is forwarding requests to the service + +By default, {{site.base_gateway}} handles proxy requests on port `8000`. + +From a web browser, navigate to `http://localhost:8000/mock/request`. + +## Next steps + +Next, you can learn about [enforcing rate limiting on a service](/gateway/{{page.kong_version}}/kong-manager/get-started/rate-limiting) through Kong Manager. diff --git a/src/gateway/kong-manager/index.md b/src/gateway/kong-manager/index.md new file mode 100644 index 000000000000..6fc0be10adf9 --- /dev/null +++ b/src/gateway/kong-manager/index.md @@ -0,0 +1,55 @@ +--- +title: Kong Manager +toc: false +badge: free +--- + +Kong Manager is the graphical user interface (GUI) for {{site.base_gateway}}. +It uses the Kong Admin API under the hood to administer and control {{site.base_gateway}}. + +Here are some of the things you can do with Kong Manager: + +* Manage all workspaces in one place +* Create new routes and services +* Activate or deactivate plugins +* Group your teams, services, plugins, consumer management, and everything else exactly how you want them +* Manage users and roles for both {{site.base_gateway}} and for the Dev Portal +* Configure Dev Portals: customize appearance, manage developers and applications, and edit Dev Portal layouts, specs, and documentation +* Monitor performance: visualize cluster-wide, workspace-level, or even object-level health using intuitive, customizable dashboards + +{:.note} +> **Note**: If you are running Kong in [traditional mode](/gateway/{{page.kong_version}}/production/deployment-topologies/traditional), increased traffic could lead to potential performance issues for the Kong proxy. +> Server-side sorting and filtering large quantities of entities can also cause increased CPU usage in both {{site.base_gateway}} and its database. + +## Kong Manager interface + +![Kong Manager interface](/assets/images/docs/gateway/km_workspace.png) +> Figure 1: Kong Manager individual workspace dashboard + +### Top menu + +Number | Item | Description +-------|------|------------ +1 | **Workspaces** | Dashboard for all the workspaces in the cluster. +2 | **Dev Portals** | Overview of all Dev Portals in the cluster. At a glance, see which workspaces have active Dev Portals and access their URLs, or set up a Dev Portal instance. +3 | **Vitals** | Dashboard for cluster-wide monitoring. Use the dashboard to:
        • View request activity
        • Track proxy and upstream latency over time
        • See when the data store cache was accessed and whether the attempts to access it were successful or not +4 | **Teams** | Manage team roles and permissions with RBAC, or map groups to your IdP. +5 | **Account settings** | Manage your password and RBAC token. + +### Side menu + +Number | Item | Description +-------|------|------------ +6 | **Change workspace** | Shortcut to quickly change between workspaces. +7 | **API Gateway** | Manage the {{site.base_gateway}} entities in the current workspace. +8 | **Dev Portal** | Workspace-specific Dev Portal configuration. If you enable Dev Portal for the current workspace, the menu will have additional items:
        • Settings: General settings for the Dev Portal instance in this workspace
        • Appearance: Customize your Dev Portal colors, fonts, and branding
        • Developers: Manage developer requests and access
        • Applications: Manage application requests and access
        • Permissions: Manage roles and content permissions
        • Editor: Access the Dev Portal files editor to configure layouts, documentation, and specs +9 | **Vitals** | Monitor requests by access code for all services in the workspace. + +### Workspace dashboard + +Number | Item | Description +-------|------|------------ +10 | **Settings** | Edit the workspace avatar or delete the workspace. +11 | **Overview panel** | Overview of key statistics for the workspace: number of services, consumers, and API requests, as well as the license validity information. +12 | **Total traffic graph** | Total traffic in the workspace by status code within a selected time frame. +13 | **Time frame selector** | Choose the time frame for the traffic graph, from the last 5 minutes to the last 12 hours. diff --git a/src/gateway/kong-manager/networking.md b/src/gateway/kong-manager/networking.md new file mode 100644 index 000000000000..043dbcb2ee88 --- /dev/null +++ b/src/gateway/kong-manager/networking.md @@ -0,0 +1,108 @@ +--- +title: Networking Configuration for Kong Manager +badge: enterprise +--- + +## Default configuration + +By default, Kong Manager starts up without authentication (see +[`admin_gui_auth`]), and it assumes that the Admin API is available +on port 8001 (see [Default Ports](/gateway/{{page.kong_version}}/production/networking/default-ports) of the same host that serves Kong Manager. + +## Custom configuration + +Here are some common configuration scenarios for Kong Manager. + +### Serving Kong Manager from a dedicated Kong node + +When Kong Manager is on a dedicated Kong node, it must make +external calls to the Admin API. Set [`admin_api_uri`] to the +location of your Admin API. + +### Securing Kong Manager through an authentication plugin + +When Kong Manager is secured through an authentication plugin +and is _not_ on a dedicated node, it makes calls to the Admin API on +the same host. By default, the Admin API listens on ports 8001 and +8444 on localhost. Change [`admin_listen`] if necessary, or set +[`admin_api_uri`]. + +{% include_cached /md/admin-listen.md desc='short' kong_version=page.kong_version %} + +### Securing Kong Manager and serving it from a dedicated node + +When Kong Manager is **secured and served from a dedicated node**, +set [`admin_api_uri`] to the location of the Admin API. + +### Connecting to the Admin API +The table below summarizes which properties to set (or defaults to +verify) when configuring Kong Manager connectivity to the Admin API. + +| authentication enabled | local API | remote API | auth settings | +|------------------------|--------------|---------------|---------------------------------------------------| +| yes | [`admin_listen`] | [`admin_api_uri`] | [`admin_gui_auth`], [`enforce_rbac`], [`admin_gui_auth_conf`], [`admin_gui_session_conf`] | +| no | [`admin_listen`] | [`admin_api_uri`] | n/a | + +### Enable authentication + +To enable authentication, configure the following properties: + +* [`admin_gui_auth`] set to the desired plugin +* [`admin_gui_auth_conf`] (optional) +* [`admin_gui_session_conf`] set to the desired configuration +* [`enforce_rbac`] set to `on` + +{:.important} +> **Important:** When Kong Manager authentication is enabled, RBAC must be turned +on to enforce authorization rules. Otherwise, whoever can log in +to Kong Manager can perform any operation available on the Admin API. + +## TLS Certificates + +By default, if Kong Manager’s URL is accessed over HTTPS _without_ a certificate issued by a CA, it will +receive a self-signed certificate that modern web browsers will not trust, preventing the application +from accessing the Admin API. + +In order to serve Kong Manager over HTTPS, use a trusted certificate authority to issue TLS certificates, +and have the resulting `.crt` and `.key` files ready for the next step. + +1) Move `.crt` and `.key` files into the desired directory of the Kong node. + +2) Point [`admin_gui_ssl_cert`] and [`admin_gui_ssl_cert_key`] at the absolute paths of the certificate and key. + +``` +admin_gui_ssl_cert = /path/to/test.crt +admin_gui_ssl_cert_key = /path/to/test.key +``` + +3) Ensure that `admin_gui_url` is prefixed with `https` to use TLS, e.g., + +``` +admin_gui_url = https://test.com:8445 +``` + +### Using https://localhost + +If serving Kong Manager on localhost, it may be preferable to use HTTP as the protocol. If also using RBAC, +set `cookie_secure=false` in `admin_gui_session_conf`. The reason to use HTTP for `localhost` is that +creating TLS certificates for `localhost` requires more effort and configuration, and there may not be any +reason to use it. The adequate use cases for TLS are (1) when data is in transit between hosts, or (2) +when testing an application with [mixed content](https://developer.mozilla.org/en-US/docs/Web/Security/Mixed_content) +(which Kong Manager does not use). + +External CAs cannot provide a certificate since no one uniquely owns `localhost`, nor is it rooted in a top-level +domain (e.g., `.com`, `.org`). Likewise, self-signed certificates will not be trusted in modern browsers. Instead, +it is necessary to use a private CA that allows you to issue your own certificates. Also ensure that the SSL state +is cleared from the browser after testing to prevent stale certificates from interfering with future access to +`localhost`. + + +[`admin_gui_auth`]: /gateway/{{page.kong_version}}/reference/configuration/#admin_gui_auth +[`admin_gui_ssl_cert`]: /gateway/{{page.kong_version}}/reference/configuration/#admin_gui_ssl_cert +[`admin_gui_ssl_cert_key`]: /gateway/{{page.kong_version}}/reference/configuration/#admin_gui_ssl_cert_key +[`default_ports`]: /gateway/{{page.kong_version}}/plan-and-deploy/default-ports +[`admin_api_uri`]: /gateway/{{page.kong_version}}/reference/configuration/#admin_api_uri +[`admin_gui_auth_conf`]: /gateway/{{page.kong_version}}/reference/configuration/#admin_gui_auth_conf +[`enforce_rbac`]: /gateway/{{page.kong_version}}/reference/configuration/#enforce_rbac +[`admin_listen`]: /gateway/{{page.kong_version}}/reference/configuration/#admin_listen +[`admin_gui_session_conf`]: /gateway/{{page.kong_version}}/reference/configuration/#admin_gui_session_conf diff --git a/src/gateway/kong-manager/workspaces.md b/src/gateway/kong-manager/workspaces.md new file mode 100644 index 000000000000..879ac8fff183 --- /dev/null +++ b/src/gateway/kong-manager/workspaces.md @@ -0,0 +1,197 @@ +--- +title: Configure Workspaces in Kong Manager +badge: enterprise +--- + +Workspaces enable an organization to segment traffic so that +teams of admins sharing the same Kong cluster are only able to +interact with entities from their groups. Within a workspace, +it is possible to invite admins to a particular team and to +enforce RBAC with roles and permissions that further +delimit the types of actions and entities available to an admin. + +## Prerequisites + +* Authentication and RBAC are [enabled](/gateway/{{page.kong_version}}/kong-manager/auth/rbac/) +* You are logged into Kong Manager as a [super admin](/gateway/{{page.kong_version}}/kong-manager/auth/super-admin) +or a user that has `/admins` and `/rbac` read and write access + +## Default workspace + +When the first Super Admin logs in, they begin in the workspace +named **default**. From here, they may invite admins to manage the default or +any other workspaces. + +## Navigating across workspaces in Kong Manager + +To navigate between workspaces from the **Overview** page, click on any +workspace displayed beneath the **Vitals** chart. + +The list of workspaces may be rendered as cards or a table, +depending on preference. + +## Create a Workspace + +This guide describes how to create workspaces in Kong +Manager. You can also use the Admin API [`/workspaces/` route](/gateway/{{page.kong_version}}/admin-api/workspaces/reference/#add-workspace) to create a workspace. + +1. Log in as the **Super Admin**. On the **Workspaces** page, click the **New Workspace** +button to see the **Create Workspace** form. Name and choose a +color / icon for the new Workspace. + + Each workspace name should be unique, + regardless of letter case. For example, naming one + workspace "Payments" and another one "payments" will + create two different workspaces that appear identical. + + Do not name workspaces the same as these major API names (paths) + in Admin API: + + ``` + • Admins + • Certificates + • Consumers + • Plugins + • Portal + • Routes + • Services + • SNIs + • Upstreams + • Vitals + ``` + +2. Click the **Create New Workspace** button. Upon creation, the application will +navigate to the new Workspace's dashboard. + +## Edit a workspace + +1. In the workspace you want to edit, navigate to the **Dashboard** page. + +1. Click the **Settings** button. This button takes you to the **Edit Workspace** page. + +1. Here, you can edit the workspace avatar and avatar background color. + +1. Click **Update Workspace** to save. + +## Delete a workspace + +### Wipe workspace data +To delete a workspace, *all data* must first be deleted from the workspace. +Choose one of the following methods. + +{% navtabs %} +{% navtab Kong Manager %} +Using Kong Manager, complete the following: + +1. Manually delete all files via **Dev Portal** > **Editor**. You cannot delete folders at this time, but deleting +all files from a folder will remove the folder. +1. Turn off the Dev Portal. Go to Dev Portal **Settings** > **Advanced** > **Turn Off**. +1. Remove all roles from the workspace: + 1. Go to the **Teams** tab. + 1. Navigate to the **Roles** tab. + 1. Click **View** on the workspace you want to delete. + 1. Go to each role entry and click **Edit**. + 1. In the entry detail page, click **Delete Role**. A confirmation modal will appear. Click **Delete Role** again. + +{% endnavtab %} +{% navtab Admin API %} + +1. Delete all Dev Portal files associated with the workspace: + + ```bash + curl -i -X DELETE http://localhost:8001/{WORKSPACE_NAME}/files + ``` + +1. Turn off the Dev Portal for the workspace: + + ```bash + curl -X PATCH http://localhost:8001/workspaces/{WORKSPACE_NAME} \ + --data "config.portal=false" + ``` + +1. [Delete each role](/gateway/{{page.kong_version}}/admin-api/rbac/reference/#delete-a-role) +from the workspace: + + ```bash + curl -i -X DELETE http://localhost:8001/{WORKSPACE_NAME}/rbac/roles/{ROLE_NAME|ROLE_ID} + ``` +{% endnavtab %} +{% navtab Portal CLI %} + +1. Delete all Dev Portal files associated with the workspace: + + ```sh + portal wipe WORKSPACE_NAME + ``` + +2. Turn off the Dev Portal for the workspace: + + ```sh + portal disable WORKSPACE_NAME + ``` + +3. Delete each role from the workspace. You can't complete this step using the +Portal CLI, so switch to either the *Kong Manager* or *Admin API* tab and complete +step 3. + +{% endnavtab %} +{% endnavtabs %} + +### Delete a clean workspace + +If your workspace is clean, you can delete it using the Kong Manager GUI or the +Kong Admin API. If not, see the previous section to [wipe workspace data](#wipe-workspace-data). + +{% navtabs %} +{% navtab Kong Manager %} + +1. In the workspace you want to delete, navigate to the **Dashboard** page. + +1. Click the **Settings** button to open the **Edit Workspace** page. + +1. Click **Delete**. + + The deletion will fail if you have any data in your workspace. + +{% endnavtab %} +{% navtab Admin API %} + +Send a `DELETE` request to the Kong Admin API: + +```sh +curl -i -X DELETE http://localhost/workspaces/{WORKSPACE_NAME|WORKSPACE_ID} +``` + +The deletion will fail if you have any data in your workspace. + +If it is successful, you should see the following response: + +``` +HTTP 204 No Content +``` + +{% endnavtab %} +{% endnavtabs %} + +## Workspace Access + +If a role does not have permission to access entire endpoints within +a workspace, the admin assigned to that role will not be +able to see the related navigation links. + +To set up access: +1. Open Kong Manager. +2. Click the **Admins** link in the +**Security** section. + + If the sidebar is collapsed, hover over + the **security badge icon** and click + **Admins**. + +The Admins page displays a list of current admins and +roles. Four default roles specific to the new +workspace are already visible, and new roles specific +to the workspace can be assigned from this page. + +For more information about admins and roles, see +[RBAC in Kong Manager](/gateway/{{page.kong_version}}/kong-manager/auth/rbac/). diff --git a/src/gateway/kong-plugins/authentication/allowing-multiple-authentication-methods.md b/src/gateway/kong-plugins/authentication/allowing-multiple-authentication-methods.md new file mode 100644 index 000000000000..e3b91e0c4ee9 --- /dev/null +++ b/src/gateway/kong-plugins/authentication/allowing-multiple-authentication-methods.md @@ -0,0 +1,108 @@ +--- +title: Allowing Multiple Authentication Methods +--- + +The default behavior for Kong authentication plugins is to require credentials +for all requests without regard for whether a request has been authenticated +via some other plugin. Configuring an anonymous consumer on your authentication +plugins allows you to offer clients multiple options for authentication. + +To begin, [create a Service](/gateway/{{page.kong_version}}/admin-api/#service-object) and then create three consumers: + +```bash +curl -sX POST localhost:8001/consumers \ + -H "Content-Type: application/json" \ + --data '{"username": "anonymous"}' + +# {"created_at":1517528237000,"username":"anonymous","id":"d955c0cb-1a6e-4152-9440-414ebb8fee8a"} + +curl -sX POST localhost:8001/consumers \ + -H "Content-Type: application/json" \ + --data '{"username": "medvezhonok"}' + +# {"created_at":1517528259000,"username":"medvezhonok","id":"b3c95318-a932-4bb2-9d74-1298a3ffc87c"} + +curl -sX POST kong-admin:8001/consumers \ + -H "Content-Type: application/json" \ + --data '{"username": "ezhik"}' + +# {"created_at":1517528266000,"username":"ezhik","id":"47e74a17-dc08-4786-a8cf-d8e4f38a5459"} +``` + +The `anonymous` consumer does not correspond to any real user, and will only serve as a fallback. + +Next, we add both Key Auth and Basic Auth plugins to our service, and set the anonymous fallback to the consumer we created earlier. + +```bash +curl -sX POST kong-admin:8001/services/example-service/plugins/ \ + -H "Content-Type: application/json" \ + --data '{"name": "key-auth", "config": { "hide_credentials": true, "anonymous": "d955c0cb-1a6e-4152-9440-414ebb8fee8a"} }' + +# {"created_at":1517528304000,"config":{"key_in_body":false,"hide_credentials":true,"anonymous":"d955c0cb-1a6e-4152-9440-414ebb8fee8a","run_on_preflight":true,"key_names":["apikey"]},"id":"bb884f7b-4e48-4166-8c80-c858b5a4c357","name":"key-auth","service_id":"a2a168a8-4491-4fe1-9426-cde3b5fcd45b","enabled":true} + +curl -sX POST kong-admin:8001/services/example-service/plugins/ \ + -H "Content-Type: application/json" \ + --data '{"name": "basic-auth", "config": { "hide_credentials": true, "anonymous": "d955c0cb-1a6e-4152-9440-414ebb8fee8a"} }' + +# {"created_at":1517528499000,"config":{"hide_credentials":true,"anonymous":"d955c0cb-1a6e-4152-9440-414ebb8fee8a"},"id":"e5a40543-debe-4225-a879-a54901368e6d","name":"basic-auth","service_id":"a2a168a8-4491-4fe1-9426-cde3b5fcd45b","enabled":true} +``` + +If using [OpenID Connect](/hub/kong-inc/openid-connect), you must also set `config.consumer_claim` along with `anonymous`, as setting `anonymous` alone will not map that consumer. + +At this point unauthenticated requests and requests with invalid credentials are still allowed. The anonymous consumer is allowed, and will be applied to any request that does not pass a set of credentials associated with some other consumer. + +```bash +curl -s example.com:8000/user-agent + +# {"user-agent": "curl/7.58.0"} + +curl -s example.com:8000/user-agent?apikey=nonsense + +# {"user-agent": "curl/7.58.0"} +``` + +We'll now add a Key Auth credential for one consumer, and a Basic Auth credential for another. + +```bash +curl -sX POST kong-admin:8001/consumers/medvezhonok/basic-auth \ + -H "Content-Type: application/json" \ + --data '{"username": "medvezhonok", "password": "hunter2"}' + +# {"created_at":1517528647000,"id":"bb350b87-f0d2-4605-b997-e28a116d8b6d","username":"medvezhonok","password":"f239a0404351d7170201e7f92fa9b3159e47bb01","consumer_id":"b3c95318-a932-4bb2-9d74-1298a3ffc87c"} + +curl -sX POST kong-admin:8001/consumers/ezhik/key-auth \ + -H "Content-Type: application/json" \ + --data '{"key": "hunter3"}' + +# {"id":"06412d6e-8d41-47f7-a911-3c821ec98f1b","created_at":1517528730000,"key":"hunter3","consumer_id":"47e74a17-dc08-4786-a8cf-d8e4f38a5459"} +``` + +Lastly, we add a Request Terminator to the anonymous consumer. + +```bash +curl -sX POST kong-admin:8001/consumers/d955c0cb-1a6e-4152-9440-414ebb8fee8a/plugins/ \ + -H "Content-Type: application/json" \ + --data '{"name": "request-termination", "config": { "status_code": 401, "content_type": "application/json; charset=utf-8", "body": "{\"error\": \"Authentication required\"}"} }' + +# {"created_at":1517528791000,"config":{"status_code":401,"content_type":"application\/json; charset=utf-8","body":"{\"error\": \"Authentication required\"}"},"id":"21fc5f6f-363f-4d79-b533-ce26d4478879","name":"request-termination","enabled":true,"consumer_id":"d955c0cb-1a6e-4152-9440-414ebb8fee8a"} +``` + +Requests with missing or invalid credentials are now rejected, whereas authorized requests using either authentication method are allowed. + +```bash +curl -s example.com:8000/user-agent?apikey=nonsense + +# {"error": "Authentication required"} + +curl -s example.com:8000/user-agent + +# {"error": "Authentication required"} + +curl -s example.com:8000/user-agent?apikey=hunter3 + +# {"user-agent": "curl/7.58.0"} + +curl -s example.com:8000/user-agent -u medvezhonok:hunter2 + +# {"user-agent": "curl/7.58.0"} +``` diff --git a/src/gateway/kong-plugins/authentication/oidc/auth0.md b/src/gateway/kong-plugins/authentication/oidc/auth0.md new file mode 100644 index 000000000000..ea7b1a7192f1 --- /dev/null +++ b/src/gateway/kong-plugins/authentication/oidc/auth0.md @@ -0,0 +1,49 @@ +--- +title: OpenID Connect with Auth0 +badge: enterprise +--- + +This guide covers an example OpenID Connect plugin configuration to authenticate headless service consumers using Auth0's identity provider. + +## Auth0 IDP Configuration + +This configuration will use a [client credentials grant][client-credentials-grant] as it is non-interactive, and because we expect clients to authenticate on behalf of themselves, not an end-user. To do so, you will need to [create an Auth0 API][create-auth0-api] and a [non-interactive client][non-interactive-client]. + +### API Configuration + +When creating your API, you will need to specify an Identifier. Using the URL that your consumer makes requests to is generally appropriate, so this will typically be the hostname/path combination configured as an API in Kong. + +After creating your API, you will also need to add the `openid` scope at `https://manage.auth0.com/#/apis//scopes`. + +### Client Configuration + +You will need to authorize your client to access your API. Auth0 will prompt you to do so after client creation if you select the API you created previously from the client's Quick Start menu. After toggling the client to Authorized, expand its authorization settings and enable the `openid` scope. + +## Kong Configuration + +If you have not done so already, [create a **Service**][add-service] to protect. The `url` configuration should match the Identifier you used when configuring Auth0. + +Add an OpenID plugin configuration using the parameters in the example below using an HTTP client or Kong Manager. Auth0's token endpoint [requires passing the API identifier in the `audience` parameter][audience-required], which must be added as a custom argument: + +```bash +curl -i -X POST http://kong:8001/kong-admin/services/{SERVICE_NAME}/plugins \ + --data name="openid-connect" \ + --data config.auth_methods="client_credentials" \ + --data config.issuer="https://.auth0.com/.well-known/openid-configuration" \ + --data config.token_post_args_names="audience" \ + --data config.token_post_args_values="https://example.com/" +``` + +## Downstream configuration + +The service accessing your resource will need to pass its credentials to Kong. It can do so via HTTP basic authentication, query string arguments, or parameters in the request body. Basic authentication is generally preferable, as credentials in a query string will be present in Kong's access logs (and possibly in other infrastructure's access logs, if you have HTTP-aware infrastructure in front of Kong) and credentials in request bodies are limited to request methods that expect +client payloads. + +For basic authentication, use your client ID as the username and your client secret as the password. For the other methods, pass them as parameters named `client_id` and `client_secret`, respectively. + + +[client-credentials-grant]: https://auth0.com/docs/api-auth/tutorials/client-credentials +[create-auth0-api]: https://auth0.com/docs/apis#how-to-configure-an-api-in-auth0 +[non-interactive-client]: https://auth0.com/docs/clients +[add-service]: /gateway/{{page.kong_version}}/admin-api/#service-object +[audience-required]: https://auth0.com/docs/api/authentication#client-credentials diff --git a/src/gateway/kong-plugins/authentication/oidc/azure-ad.md b/src/gateway/kong-plugins/authentication/oidc/azure-ad.md new file mode 100644 index 000000000000..5ae49aa05ac3 --- /dev/null +++ b/src/gateway/kong-plugins/authentication/oidc/azure-ad.md @@ -0,0 +1,135 @@ +--- +title: OpenID Connect with Azure AD +badge: enterprise +--- + +This guide covers an example OpenID Connect plugin configuration to authenticate +browser clients using an Azure AD identity provider. + +For information about configuring OIDC using Azure as an Identity provider +in conjunction with the Application Registration plugin, see +[Set Up External Portal Application Authentication with Azure AD and OIDC](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/authentication/azure-oidc-config). + +## Prerequisites + +Because OpenID Connect deals with user credentials, all transactions should take place over HTTPS. +Although user passwords for third party identity providers are only submitted to +those providers and not Kong, authentication tokens do grant access to a subset of +user account data and protected APIs, and should be secured. As such, you should +make Kong's proxy available via a fully-qualified domain name and [add a certificate][add-certificate] for it. + +## Kong Configuration + +If you have not yet [added a **Route** and a **Service**][add-service], go ahead +and do so. Again, note that you should be able to secure this route with HTTPS, +so use a hostname you have a certificate for. Add a location handled by your +Route as an authorized redirect URI in Azure (under the **Authentication** section of your app registration). + +## Azure AD IdP Configuration + +You must [register an app][azure-create-app] in your Azure AD configuration and [add a client secret credential][azure-client-secret] that Kong will use to access it. You must also configure a redirect URI that is handled by your Route. + +Azure AD provides two interfaces for its OAuth2/OIDC-related endpoints: v1.0 and v2.0. +Support for some legacy v1.0 behavior is still available on v2.0, including use of v1.0 tokens by +default, which is not compatible with Kong's OIDC implementation. To force Azure AD to use v2.0 tokens, +[edit your application manifest][azure-manifest] and set `accessTokenAcceptedVersion` to `2` and +include a `YOUR_CLIENT_ID/.default` scope in your plugin configuration as shown below. + +## Plugin Configuration + +Add a plugin with the configuration below to your Route using an HTTP client or [Kong Manager][enable-plugin]. + +```bash +curl -i -X POST https://admin.kong.example/routes/ROUTE_ID/plugins --data name="openid-connect" \ + --data config.issuer="https://login.microsoftonline.com/YOUR_DIRECTORY_ID/v2.0/.well-known/openid-configuration" \ + --data config.client_id="YOUR_CLIENT_ID" \ + --data config.client_secret="YOUR_CLIENT_SECRET" \ + --data config.redirect_uri="https://example.com/api" \ + --data config.scopes="openid" \ + --data config.scopes="email" \ + --data config.scopes="profile" \ + --data config.scopes="YOUR_CLIENT_ID/.default" \ + --data config.verify_parameters="false" +``` + +Some of the configurations above must use values specific to your environment: + +* The `issuer` URL can be retrieved by clicking the **Endpoints** button on your app registration's **Overview** page. +* `redirect_uri` should be the URI you specified earlier when configuring your app. You can +add one via the **Authentication** section of the app settings if you did not add one initially. +* For `client_id` and `scopes`, replace `YOUR_CLIENT_ID` with the client ID shown on the app **Overview** page. +* For `client_secret`, replace `YOUR_CLIENT_SECRET` with the URL-encoded representation of the +secret you created earlier in the **Certificates & secrets** section. Azure AD secrets +often include reserved URL characters, which cURL might handle incorrectly if they are not URL-encoded. + +Visiting a URL matched by that route in a browser will now redirect to Microsoft's +authentication site and return you to the redirect URI after authenticating. + +### Access Restrictions + +The configuration above allows users to authenticate and access the Route even though no +Consumer was created for them: any user with a valid account in the directory +will have access to the Route. The OIDC plugin allows this as the simplest +authentication option, but you might want to restrict access further. There are several options for this: + +- Domain Restrictions +- Consumer Mapping +- Pseudo-Consumer Mapping + +#### Domain Restrictions + +Azure AD does not provide identity tokens with the `hd` claim, and as such, the +OIDC plugin's `domains` configuration cannot restrict users based on their domain. +Using a [single-tenant][azure-tenant] application will restrict access to users +in your directory only. Multi-tenant apps allow users with Microsoft accounts +from other directories and optionally any Microsoft account (e.g., live.com or Xbox accounts) to sign in. + +#### Consumer Mapping + +If you need to interact with other Kong plugins using Consumer information, you can +add configuration that maps account data received from the identity provider to a Kong Consumer. +For this example, the user's Azure AD account GUID is mapped to a Consumer by setting +it as the `custom_id` on their Consumer: + +```bash +curl -i -X POST http://admin.kong.example/consumers/ \ + --data username="Yoda" \ + --data custom_id="e5634b31-d67f-4661-a6fb-b6cb77849bcf" +``` + +```bash +curl -i -X PATCH http://admin.kong.example/plugins/OIDC_PLUGIN_ID \ + --data config.consumer_by="custom_id" \ + --data config.consumer_claim="oid" +``` + +Now, if a user logs into an Azure AD account with the GUID `e5634b31-d67f-4661-a6fb-b6cb77849bcf`, +Kong will apply configuration associated with the Consumer `Yoda` to their requests. + +This also requires that clients login using an account mapped to some Consumer, +which may not be desirable (e.g., you apply OpenID Connect to a Service, but only +use plugins requiring a Consumer on some routes). To deal with this, you can set +the `anonymous` parameter in your OIDC plugin configuration to the ID of a generic +Consumer, which will then be used for all authenticated users that cannot be mapped +to some other Consumer. You can alternately set `consumer_optional` to `true` to allow +similar logins without mapping an anonymous Consumer. + +#### Pseudo-Consumer Mapping + +For plugins that typically require Consumers, the OIDC plugin can provide a consumer ID +based on the value of a claim without mapping to an actual Consumer. Setting `credential_claim` +to a claim [in your plugin configuration][credential-claim] will extract the value +of that claim and use it where Kong would normally use a consumer ID. Note that this +may not work with all consumer-related functionality. + +Similarly, setting `authenticated_groups_claim` will extract that claim's value and use it as a group for the ACL plugin. + +[azure-client-secret]: https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-configure-app-access-web-apis#add-credentials-to-your-web-application +[azure-create-app]: https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app +[azure-manifest]: https://docs.microsoft.com/en-us/azure/active-directory/develop/reference-app-manifest#configure-the-app-manifest +[azure-tenants]: https://docs.microsoft.com/en-us/azure/active-directory/develop/single-and-multi-tenant-apps +[add-certificate]: /gateway/{{page.kong_version}}/admin-api/#add-certificate +[add-service]: /gateway/{{page.kong_version}}/admin-api/#service-object +[oidc-id-token]: http://openid.net/specs/openid-connect-core-1_0.html#IDToken +[credential-claim]: https://docs.konghq.com/hub/kong-inc/openid-connect/#configcredential_claim +[enable-plugin]: /gateway/{{page.kong_version}}/admin-api/#plugin-object diff --git a/src/gateway/kong-plugins/authentication/oidc/cognito.md b/src/gateway/kong-plugins/authentication/oidc/cognito.md new file mode 100644 index 000000000000..1d922dd60e93 --- /dev/null +++ b/src/gateway/kong-plugins/authentication/oidc/cognito.md @@ -0,0 +1,216 @@ +--- +title: OpenID Connect with Amazon Cognito +badge: enterprise +--- + +## Amazon Cognito Configuration + +Amazon Cognito has two significant components: Identity Pools and User Pools. Identity Pools are the original functionality deployed in 2014; they mainly use proprietary AWS interfaces and libraries to accomplish the task of authenticating users. Furthermore, Identity Pools have no concept of claims (standard or custom) stored in the system; it is entirely a federated identity construct. User Pools are the more recent addition to the Cognito feature set; User Pools are a multi-tenant LDAP-like user repository combined with an OAuth2 and an OpenID Connect interface. + +In this configuration, we use User Pools. + +1. Log in to AWS Console. +1. Navigate to the Amazon Cognito Service. + + +1. Click on **Manage User Pools**. + + +1. Click the **Create a user pool** button on the right-hand side. + + +1. Enter a pool name; we use “test-pool” for this example. + + +1. Click **Step Through Settings**. + + +1. Select **Email address or phone number**, and under that, select **Allow email addresses**. Select the following standard attributes as required: email, family name, given name. + + +1. Click **Next step**. +1. Accept the defaults for **Password settings**, then click **Next step**. +1. Accept the defaults for **MFA and verifications**, then click **Next step**. +1. Accept the defaults for **Message customizations**, click **Next step**. +1. On the next screen, we are not going to create any tags. Click **Next step**. +1. Select **No** for **Do you want to remember your user’s devices**, then click **Next step**. +1. We can create an application definition later. Keep things simple for now and click **Next step**. +1. We don’t have any need for Triggers or customized Sign Up/Sign In behavior for this example. Scroll down and click **Save Changes**. + + +1. Click **Create pool**. Wait a moment for the success message. +1. Make a note of the **Pool ID**. You will need this when configuring the application later. + +## Application Definition + +You need to add an OAuth2 application definition to the User Pool we just created. + +1. Go to the App clients screen in the AWS Cognito management screen for the User Pool we just created. + + +1. Click “Add an app client”. + + +1. Enter an App client name. This demo is using “kong-api” + + +1. Enter a Refresh token expiration (in days). We will use the default of 30 days. +1. Do not select “Generate client secret”. This example will use a public client. + + +1. Do not select any other checkboxes. + + +1. Click the “Set attribute read and write permissions” button. + + + +1. Let’s make this simple and only give the user read and write access to the required attributes. So, uncheck everything except the email, given name, and family name fields. + + +1. Click “Create app client” + + +1. Click “Show Details”. + + +1. Take note of the App client ID. We will need that later. +1. Go to the App integration -> App client settings screen. +1. Click the “Cognito User Pool” checkbox under Enabled Identity Providers. +1. Add the following to the Callback URLs field: + + ``` + “https://kong-ee:8446/default, https://kong-ee:8447/default/, https://kong-ee:8447/default/auth, https://kong-ee:8443/cognito” + ``` + + Note that AWS Cognito doesn’t support HTTP callback URLs. This field should + include the API and Dev Portal URLs that you want to secure using AWS Cognito. + + +1. Click the “Authorization code grant” checkbox under Allowed OAuth Flows. + + +1. Click the checkboxes next to email, OpenID, aws.cognito.signin.user.admin, and profile. +1. Click the “Save changes” button. +1. Click on the domain name tab. +1. Add a sub-domain name. +1. Click the Check Availability button. +1. As long as it reports “This domain is available”, the name you have chosen will work. + + +1. Click the “Save changes” button. + +Now that you have created an Amazon Cognito User Pool and Application Definition, we can configure the OpenID Connect plugin in Kong. We can then test integration between Dev Portal and Amazon Cognito. + +Amazon’s OIDC discovery endpoint is available from: +``` +https://cognito-idp..amazonaws.com/ +``` + +For example, in this demo, the OIDC discovery endpoint is: + +``` +https://cognito-idp.ap-southeast-1.amazonaws.com/ap-southeast-1_ie577myCv/.well-known/openid-configuration +``` + +The OAuth + OIDC debugger is a handy utility that you may use to test the authorization flow before configurations in Kong. + +## OIDC Plugin Configuration + +Identify the Route or Service to be secured. In our example, we created a new route called /cognito to which we added the OpenID Connect plug-in. +The number of options in the plug-in can seem overwhelming but the configuration is rather simple. All you need to do is configure: +* `issuer` - You can use the OIDC discovery endpoint here, e.g. + ``` + https://cognito-idp.ap-southeast-1.amazonaws.com/ap-southeast-1_ie577myCv/.well-known/openid-configuration + ``` +* `config.client_id` - This is the client ID noted when the application was created +* `config.client_secret` - This is the client secret noted when the application was created. In this demo we are leaving this blank as we didn’t create a client secret. +* `config.auth_methods` - If this is left blank, all flows will be enabled. If only specific flows are in scope, configure the appropriate flows accordingly. + +## Validating the Flows + +You can test the route by accessing URL “https://kong-ee:8443/cognito/anything”, and you should redirect to the Amazon Cognito login page. You need to click “Sign up” link to create a user first using your email address. The application sends a verification code to your email. Once you enter the verification code, Amazon Cognito acknowledges the account. + +You can verify the confirmed user from the Cognito page under “General settings” -> “Users and groups”. + +## Dev Portal Integration + +{% include_cached /md/admin-listen.md desc='long' kong_version=page.kong_version %} + +Since AWS Cognito only supports the HTTPS protocol, when you start {{site.base_gateway}}, ensure that HTTPS protocol for Dev Portal is enabled. For example: + +``` +docker run -d --name kong-ee --link kong-ee-database:kong-ee-database \ + -e "KONG_DATABASE=postgres" \ + -e "KONG_PG_HOST=kong-ee-database" \ + -e "KONG_CASSANDRA_CONTACT_POINTS=kong-ee-database" \ + -e "KONG_PROXY_ACCESS_LOG=/dev/stdout" \ + -e "KONG_ADMIN_ACCESS_LOG=/dev/stdout" \ + -e "KONG_PROXY_ERROR_LOG=/dev/stderr" \ + -e "KONG_ADMIN_ERROR_LOG=/dev/stderr" \ + -e "KONG_ADMIN_LISTEN=0.0.0.0:8001 , 0.0.0.0:8444 ssl" \ + -e "KONG_PORTAL=on" \ + -e "KONG_ENFORCE_RBAC=off" \ + -e "KONG_ADMIN_GUI_URL=http://kong-ee:8002" \ + -e "KONG_AUDIT_LOG=on" \ + -e "KONG_PORTAL_GUI_PROTOCOL=https" \ + -e "KONG_PORTAL_GUI_HOST=kong-ee:8446" \ + -e "KONG_LICENSE_DATA=$KONG_LICENSE_DATA" \ + -p 8000-8004:8000-8004 \ + -p 8443-8447:8443-8447 \ + kong-ee +``` + +Under Dev Portal settings, select “Open ID Connect” as the authentication plugin. + +Copy and paste the following Auth Config JSON object: + +``` +{ + "leeway": 100, + "consumer_by": [ + "username", + "custom_id", + "id" + ], + "scopes": [ + "openid", + "profile", + "email" + ], + "logout_query_arg": "logout", + "client_id": [ + "1pf00c5or942c2hm37mgv0u509" + ], + "login_action": "redirect", + "logout_redirect_uri": [ + "https://kongdemo.auth.ap-southeast-1.amazoncognito.com/logout?client_id=1pf00c5or942c2hm37mgv0u509&logout_uri=kong-ee:8446/default" + ], + "login_tokens": {}, + "login_redirect_uri": [ + "https://kong-ee:8446/default" + ], + "forbidden_redirect_uri": [ + "https://kong-ee:8446/default/unauthorized" + ], + "ssl_verify": false, + "issuer": "https://cognito-idp.ap-southeast-1.amazonaws.com/ap-southeast-1_ie577myCv/.well-known/openid-configuration", + "logout_methods": [ + "GET" + ], + "consumer_claim": [ + "email" + ], + "login_redirect_mode": "query", + "redirect_uri": [ + "https://kong-ee:8447/default/auth" + ] +} +``` + +To log out the user completely, we need to use the logout endpoint provided by Cognito (https://docs.aws.amazon.com/cognito/latest/developerguide/logout-endpoint.html). Therefore, in the above configuration, we have passed in Cognito logout endpoint of logout redirect URL. + +Please also note that the developer signed up from Dev Portal doesn’t get created in Cognito automatically. Therefore, developer signup is a two-step process: +* The developer signs up from Dev Portal itself, so a Kong Admin needs to approve the developer access. +* The developer signs up from Amazon Cognito. Please make sure that you use the _same email address_ for both signups. +Now you should be able to login to Developer Portal using the Amazon Cognito user and credential. diff --git a/src/gateway/kong-plugins/authentication/oidc/curity.md b/src/gateway/kong-plugins/authentication/oidc/curity.md new file mode 100644 index 000000000000..0c2514e4c422 --- /dev/null +++ b/src/gateway/kong-plugins/authentication/oidc/curity.md @@ -0,0 +1,213 @@ +--- +title: OpenID Connect with Curity +badge: enterprise +--- + +## Phantom Token Integration + +This guide describes how to integrate {{site.ee_product_name}} and the Curity Identity Server using the Kong [OpenID Connect](/hub/kong-inc/openid-connect/) plugin. + +This guide focuses on configuring the plugin for introspection, and especially as it relates to the introspection using the [Phantom Token pattern][curity-phantom-token-pattern]. Some tweaks are made so that a phantom token is provided in the introspection response and then passed on to the upstream API. + +Configuring the Curity Identity Server to provide a Phantom Token in the introspection response is outlined in more detail in this [Introspection and Phantom Tokens][curity-phantom-token-introspection] article. + +### Prerequisites + +* An installation of the [Curity Identity Server][curity-getting-started] +* An introspection endpoint configured with the [Token Procedure Approach][curity-phantom-token-introspection] + +### Configure Kong + +The Kong OpenID Connect plugin is configured to introspect an incoming opaque access token and in return receive a JWT in the introspection response from the Curity Identity Server. The plugin is enabled for a [service or a route][kong-add-service]. + +As part of the introspection, the OpenID Connect plugin also has the ability to validate that required scopes are available in the introspected token. Access to the requested API are denied if the correct scopes are missing. + +If access is granted, the JWT from the introspection response is added to a header and forwarded to the upstream API where it can be consumed. + +#### Create a service + +Create a service that can be used to test the integration. + +```bash +curl -i -X POST http://kong:8001/services/ \ + --data name="httpbin" \ + --data protocol="http" \ + --data url="http://httpbin.org" +``` + +#### Create a route + +Add a route to the service. + +```bash +curl -i -X POST http://kong:8001/services/httpbin/routes \ + --data "paths[]=/httpbin" +``` + +#### Configure the plugin + +The Kong OpenID Connect plugin is enabled for the previously created service. In the example below, the `openid` scope is required in order for access to be granted. As noted by the `config.upstream_headers_claims` configuration, the plugin looks for the `JWT` (the phantom token) claim in the introspection response. The `config.upstream_headers_names` configuration extracts the `JWT` from the introspection response and adds it to a `phantom_token` header in the call to the upstream API. + +```bash +curl -X POST http://kong:8001/services/httpbin/plugins \ +--data name="openid-connect" \ +--data config.issuer="https://idsvr.example.com/oauth/v2/oauth-anonymous" \ +--data config.client_id="gateway-client" \ +--data config.client_secret="Password1" \ +--data config.scopes_required="openid" \ +--data config.hide_credentials="true" \ +--data config.upstream_access_token_header= \ +--data config.upstream_headers_claims="phantom_token" \ +--data config.upstream_headers_names="phantom_token" \ +--data config.auth_methods="introspection" +``` + +Parameter | Description | Example | Required for integration +--- |--- |--- |--- +`config.issuer` | Used for discovery. Kong appends `/.well-known/openid-configuration`. Should be set to the `realm` or `iss` if no discovery endpoint is available. | `https://idsvr.example.com/oauth/v2/oauth-anonymous` | Yes +`config.client_id` | The ID of a client with the introspection capability | `gateway-client`| Yes +`config.client_secret` | Secret of the client used for introspection| `Password1` | Yes +`config.scopes_required`| Optional scopes required in introspection result for coarse grained authorization. By default the plugin looks for the scopes in the `scopes` claim in the introspection result. This could be overridden with the `config.scopes_claim` configuration. | `openid email records_read` | No +`config.hide_credentials` | Boolean value. This will prevent the incoming Access Token from being forwarded to the upstream API. |`true` | No +`config.upstream_access_token_header` | In order to prevent the plugin from adding the Access Token back in the upstream request, actively set this value to nothing (aka, `nil`) by setting `config.upstream_access_token_header=` as in the example above . This configuration works in conjunction with `config.hide_credentials` to prevent the incoming Access Token from being passed to the upstream API. | `authorization:bearer` | No +`config.upstream_headers_claims` | Contains claim that holds Phantom Token in the introspection result. | `phantom_token` | Yes +`config.upstream_headers_names` | Contains upstream header name that will hold the Phantom Token from the introspection result. | `phantom_token` | Yes +`config.auth_methods` | Several methods are supported for authenticating the request. For this use case, this should be limited to `introspection`. |`introspection` | No +`config.cache_introspection` | Boolean value that controls whether an introspection result should be cached. | `true` | No +`config.introspect_jwt_tokens` | Boolean value that controls if JWTs sent in an Authorization header should also be introspected. | `false` | No +`config.introspection_endpoint` | Endpoint for introspection. Might be needed if discovery is not possible. | `https://idsvr.example.com/oauth/v2/oauth-introspect` | No + +### Test the configuration + +Any supported OAuth/OIDC flow can be used to obtain an opaque access token from the Curity Identity Server. Several approaches for obtaining a token are outlined in the [Curity Getting Started Guide][curity-getting-started]. Make sure that the token issued contains the `openid` scope. + +Call the exposed service created earlier and pass the opaque access token in the `Authorization` header. + +```bash +curl -X GET http://kong:8000/httpbin/get \ +--header "Authorization: Bearer /auth`). + +{:.note} +> **NOTE:** There is an issue with short-lived access tokens that is under investigation. Increase the `Access Token Time to Live` in the client configuration to `3000` as a temporary workaround. + +More information is available in the [Code Flow][curity-code-flow-tutorial] tutorial. + +### Configure OpenID Connect in the Kong Developer Portal + +Enabling the Kong Developer Portal is outlined in the [Kong Dev Portal Documentation][kong-dev-portal-doc] and not covered in this article. The documentation also covers how to configure the [OpenID Connect Plugin][kong-dev-portal-doc-oidc]. + +#### Example Configuration Object + +Below is an example configuration object that is used to configure the OIDC plugin for the Dev Portal. + +```json +{ + "redirect_uri": ["https://kong-dev-portal:8004/default/auth"], + "consumer_by": ["username","custom_id","id"], + "leeway": 1000, + "scopes": ["openid","profile","email"], + "logout_query_arg": "logout", + "login_redirect_uri": ["https://kong-dev-portal:8003"], + "login_action": "redirect", + "logout_redirect_uri": ["https://kong-dev-portal:8003"], + "ssl_verify": false, + "client_id": ["kong-dev-portal-client"], + "forbidden_redirect_uri": ["https://kong-dev-portal:8003/unauthorized"], + "client_secret": ["Pa$$w0rd!"], + "issuer": "https://idsvr.example.com/oauth/v2/oauth-anonymous/", + "logout_methods": ["GET"], + "consumer_claim": ["email"], + "login_redirect_mode": "query" +} +``` + +![Enable OIDC in Kong Dev Portal](/assets/images/docs/dev-portal/curity/kong-dev-portal.png) + +### Curity Authentication Action + +An Authentication Action to automatically provision the user to the Kong Developer Portal is available in the Curity GitHub repository. Using the Action is not mandatory as the user could be provisioned in other ways, such as manually through the Kong Developer portal login page. However, using the Authentication Action would streamline the user flow since the Action takes the user's full name and the email from the Curity Authenticator and automatically provision that to the Kong Developer Portal using the exposed API. + +The [The Kong Developer Portal User Provisioner][curity-kong-dev-portal-user-provisioner] action is available as open source and can be forked to fit the needs of the environment as needed. + +#### Configuration + +This Action is straightforward to configure. An HTTP Client is needed to communicate with the Kong Dev Portal API. By default, the **HTTP Authentication** can be left out. Only a correct scheme needs to be configured (HTTP or HTTPS). + +The Action also configures the URL to the registration endpoint of the Kong Developer Portal. Here the scheme needs to match what's configured in the HTTP Client used. + +![Kong Dev Portal User Provisioner](/assets/images/docs/dev-portal/curity/kong-dev-portal-action.png) + +When the action is created, it can be assigned to the Authenticators used in the client configured in the Curity Identity Server as described above. + +#### Action to Resolve Additional User Information + +Depending on the Authenticator used, an additional Action may be needed to resolve additional information. By default, The Kong Developer portal provisioning requires `Full Name` and `email`. If the Authenticator does not provide this, it's possible to use an Action to resolve the data. This could be as simple as a **Data Source** action configured to use a Data Source that provides the information. + +![Chain Actions](/assets/images/docs/dev-portal/curity/authentication-and-actions.png) + +By default, the Kong Developer Portal Provisioner Action works on the default account table schema of the Curity Identity Server database. This provides `email` as a column, but the `Full Name` is not readily available. The Action operates on the `attributes` column and parse the information to pass the user's Full Name to the Kong Dev Portal. + +The attributes column contains this structure: + +```json +{"emails":[{"value":"alice@example.com","primary":true}],"phoneNumbers":[{"value":"555-123-1234","primary":true}],"name":{"givenName":"alice","familyName":"anderson"},"agreeToTerms":"on","urn:se:curity:scim:2.0:Devices":[]} +``` + +The data source used to resolve additional information needs to be configured with an appropriate **Attribute Query**. This would look similar to this: + +```sql +select * from "accounts" where "username"= :subject +``` + +### Conclusion + +With relatively simple configurations in both the Curity Identity Server and the Kong Developer Portal, it's possible to leverage Curity as the Identity Provider for the Kong Dev Portal. This provides a very seamless flow for user authentication to the Kong Dev Portal. With the added capability of an Authentication Action, it is possible to automatically provision the user to the Kong Dev Portal for an even more streamlined experience. + +[kong-add-service]: /gateway/{{page.kong_version}}/admin-api/#service-object +[curity-phantom-token-introspection]: https://curity.io/resources/learn/introspect-with-phantom-token +[curity-getting-started]: https://curity.io/resources/getting-started +[curity-phantom-token-pattern]: https://curity.io/resources/learn/phantom-token-pattern +[curity-code-flow-tutorial]: https://curity.io/resources/learn/code-flow +[curity-kong-dev-portal-user-provisioner]: https://curity.io/resources/learn/provision-kong-dev-portal-user +[kong-dev-portal-doc]: /gateway/{{page.kong_version}}/kong-enterprise/dev-portal +[kong-dev-portal-doc-oidc]: /gateway/{{page.kong_version}}/kong-enterprise/dev-portal/authentication/oidc diff --git a/src/gateway/kong-plugins/authentication/oidc/google.md b/src/gateway/kong-plugins/authentication/oidc/google.md new file mode 100644 index 000000000000..347977561cd2 --- /dev/null +++ b/src/gateway/kong-plugins/authentication/oidc/google.md @@ -0,0 +1,67 @@ +--- +title: OpenID Connect with Google +badge: enterprise +--- + +This guide covers an example OpenID Connect plugin configuration to authenticate browser clients using Google's identity provider. + +## Prerequisites + +Because OpenID Connect deals with user credentials, all transactions should take place over HTTPS. Although user passwords for third party identity providers are only submitted to those providers and not Kong, authentication tokens do grant access to a subset of user account data and protected APIs, and should be secured. As such, you should make Kong's proxy available via a fully-qualified domain name and [add a certificate][add-certificate] for it. + +## Google IDP Configuration + +Before configuring Kong, you'll need to set up a Google APIs project and create a credential set. Following [Google's instructions][google-oidc], [create a new set of OAuth client ID credentials][google-create-credentials] with the Web application class. Add an authorized redirect URI for part of the API you wish to protect (more complex applications may redirect to a resource that sets additional +application-specific state on the client, but for our purposes, any protected URI will work). Authorized JavaScript origins can be left blank. + +You can optionally customize the consent screen to inform clients who/what application is requesting authentication, but this is not required for testing. All steps after can be ignored, as Kong handles the server-side authentication request and token validation. + +## Kong Configuration + +If you have not yet [added a **Service**][add-service], go ahead and do so. Again, note that you should be able to secure this Service with HTTPS, so if you are configuring a host, use a hostname you have a certificate for. + +### Basic Plugin Configuration + +Add a plugin with the configuration below to your Service using an HTTP client or Kong Manager. Make sure to use the same redirect URI as configured earlier: + +```bash +curl -i -X POST http://kong:8001/services/{SERVICE_NAME}/plugins \ + --data name="openid-connect" \ + --data config.issuer="https://accounts.google.com/.well-known/openid-configuration" \ + --data config.client_id="YOUR_CLIENT_ID" \ + --data config.client_secret="YOUR_CLIENT_SECRET" \ + --data config.redirect_uri="https://example.com/api" \ + --data config.scopes="openid,email" +``` + +Visiting a URL matched by that Service in a browser will now redirect to Google's authentication site and return you to the redirect URI after authenticating. You'll note, however, that we did not configure anything to map authentication to consumers and that no consumer is associated with the subsequent request. Indeed, if you have configured other plugins that rely on consumer information, such as the ACL plugin, you will not have access. At present, the plugin configuration confirms that +users have a Google account, but doesn't do anything with that information. + +Depending on your needs, it may not be necessary to associate clients with a consumer. You can, for example, configure the `domains` parameter to limit access to a internal users if you have a G Suite hosted domain, or configure `upstream_headers_claims` to send information about the user upstream (e.g. their email, a profile picture, their name, etc.) for use in your applications or for analytics. + +### Consumer Mapping + +If you need to interact with other Kong plugins using consumer information, you must add configuration that maps account data received from the identity provider to a Kong consumer. For this example, we'll map the user's Google account email by setting a `custom_id` on their consumer, e.g. + +```bash +curl -i -X POST http://kong:8001/consumers/ \ + --data username="Yoda" \ + --data custom_id="user@example.com" + +curl -i -X PATCH http://kong:8001/services/{SERVICE_NAME}/plugins/{OIDC_PLUGIN_ID} \ + --data config.consumer_by="custom_id" \ + --data config.consumer_claim="email" +``` + +Now, if a user logs into a Google account with the email `user@example.com`, Kong will apply configuration associated with the consumer `Yoda` to their requests. Note that while Google provides account emails, not all identity providers will. OpenID Connect does not have many required claims--the [only required user identity claim][oidc-id-token] is `sub`, a unique subscriber ID. Many optional claims [are +standardized][oidc-standard-claims], however--if a provider returns an `email` claim, the contents will always be an email address. + +This also requires that clients login using an account mapped to some consumer, which may not be desirable (e.g. you apply OpenID Connect to a service, but only use plugins requiring a consumer on some routes). To deal with this, you can set the `anonymous` parameter in your OIDC plugin configuration to the ID of a generic consumer, which will then be used for all authenticated users that cannot be mapped to some other consumer. + + +[add-certificate]: /gateway/{{page.kong_version}}/admin-api/#add-certificate +[google-oidc]: https://developers.google.com/identity/protocols/OpenIDConnect +[google-create-credentials]: https://console.developers.google.com/apis/credentials +[add-service]: /gateway/{{page.kong_version}}/admin-api/#service-object +[oidc-id-token]: http://openid.net/specs/openid-connect-core-1_0.html#IDToken +[oidc-standard-claims]: http://openid.net/specs/openid-connect-core-1_0.html#StandardClaims diff --git a/src/gateway/kong-plugins/authentication/oidc/index.md b/src/gateway/kong-plugins/authentication/oidc/index.md new file mode 100644 index 000000000000..052c38700c6b --- /dev/null +++ b/src/gateway/kong-plugins/authentication/oidc/index.md @@ -0,0 +1,35 @@ +--- +title: OpenID Connect +breadcrumb: Overview +badge: enterprise +--- + +## What does OpenID Connect do? + +OpenID Connect provides a way to form a *federation* with *identity providers*. Identity providers are third parties that store account credentials. If the identity provider authenticates a user, the application trusts that provider and allows access to the user. The *identity provider* bears some responsibility for protecting the user’s credentials and ensuring authenticity, so applications no longer need to on their own. + +Besides delegating responsibility to an identity provider, OpenID Connect also makes single sign-on possible without storing any credentials on a user’s local machine. + +Finally, enterprises may want to manage access control for many applications from one central system of record. For example, they may want employees to be able to access many different applications using their email address and password. They may want to also change access (e.g. if an employee separates or changes roles) from one central point. OpenID Connect addresses this challenge by providing a way for many different applications to authenticate users through the same third-party identity provider. + +## What does Kong’s OpenID Connect plugin do? + +Just as OpenID Connect enables developers to offload authentication to another party, Kong enables developers to separate entire processes from their applications. Rather than needing to hand write the code for OpenID Connect *within* a service, developers can place Kong in front of the service and have Kong handle authentication. This separation allows developers to focus on the business logic within their application. It also allows them to easily swap out services while preserving authentication at the front door, and to effortlessly spread the same authentication to *new* services. + +Kong users may prefer OpenID Connect to other authentication types, such as Key Auth and Basic Auth, because they will not need to manage the database storing passwords. Instead, they can offload the task to a trusted identity provider of their choice. + +While the OpenID Connect Plugin can suit many different use cases and extends to other Plugins such as JWT (JSON Web Token) and 0Auth 2.0, the most common use case is the Authorization Code flow. + +## References +See our series of integration guides to configure the OIDC plugin for your +identity provider: + + - [Auth0](/gateway/{{page.kong_version}}/kong-plugins/authentication/oidc/auth0) + - [Amazon AWS Cognito](/gateway/{{page.kong_version}}/kong-plugins/authentication/oidc/cognito/) + - [Curity](/gateway/{{page.kong_version}}/kong-plugins/authentication/oidc/curity/) + - [Google](/gateway/{{page.kong_version}}/kong-plugins/authentication/oidc/google/) + - [Microsoft Azure Active Directory (Azure AD)](/gateway/{{page.kong_version}}/kong-plugins/authentication/oidc/azure-ad) + - [Okta](/gateway/{{page.kong_version}}/kong-plugins/authentication/oidc/okta) + + For a full list of tested providers and all available configuration options, + see the [OpenID Connect plugin reference](/hub/kong-inc/openid-connect). diff --git a/src/gateway/kong-plugins/authentication/oidc/okta.md b/src/gateway/kong-plugins/authentication/oidc/okta.md new file mode 100644 index 000000000000..ed113f5de5d0 --- /dev/null +++ b/src/gateway/kong-plugins/authentication/oidc/okta.md @@ -0,0 +1,258 @@ +--- +title: OpenID Connect with Okta +badge: enterprise +--- + +This guide covers an example OpenID Connect plugin configuration to authenticate browser clients using an Okta identity provider. + +For information about configuring OIDC using Okta as an Identity provider +in conjunction with the Application Registration plugin, see +[Set Up External Portal Application Authentication with Okta and OIDC](/gateway/{{page.kong_version}}/kong-enterprise/dev-portal/authentication/okta-config). + +## Authorization code flow with the OpenID Connect plugin and Okta + +### Sign-in flow + +![OIDC signin flow](/assets/images/docs/ee/plugins/oidc-use-case/OIDCsignin.png) + +1. If the client does not have a session cookie, it initiates sign in with Kong. +2. Kong responds to the client with an **authorization cookie** and a location to redirect (with Okta as the header). +3. the client redirects to Okta so the user can sign in. +4. Okta responds with an **authorization code** and a location to redirect (with Kong as the header). + +At this point, the client has successfully signed in and has an **authorization code** (from Okta) and an **authorization cookie** (from Kong). + +### Access flow + +![OIDC access flow](/assets/images/docs/ee/plugins/oidc-use-case/OIDCaccess.png) + +1. The client redirects to Kong and automatically sends the **authorization code** (from Okta) and an **authorization cookie** (from Kong). +2. Kong verifies the **authorization code** with Okta. +3. Okta sends and **access token** and **ID token** to Kong. +4. Kong proxies the client request with the **access token** from Okta. +5. Kong receives a service response. +6. Kong sends the service response to the client, along with a **session cookie** for future access. + +At this point, the client now has a **session** with Kong that allows mediated access to the service. + +### Session flow + +![OIDC session flow](/assets/images/docs/ee/plugins/oidc-use-case/OIDCsession.png) + +1. The client sends requests with a **session cookie**. +2. Kong matches the session cookie to the associate **access token** and proxies the request. +3. Kong gets a response from the service. +4. Kong sends the response to the client. + +Kong’s session with the client ensures that the client does not need to make constant requests to Okta. The duration of the session can be configured. + +## Example of configuring the OIDC plugin with Okta + +### Prerequisites + +The steps in the guide offer an example of configuring OIDC with Okta on a specific route. To follow this guide, you need the following: + +* A [developer account](https://developer.okta.com) with Okta. +* A running version of {{site.base_gateway}}. +* Access to the [OpenID Connect plugin](/hub/kong-inc/openid-connect). +* A [service](/gateway/{{page.kong_version}}/admin-api/#service-object) +and [route](/gateway/{{page.kong_version}}/admin-api/#route-object) in +{{site.base_gateway}} whose access you want to protect with Okta. For this +guide, assume the route is in the default workspace. +* If using {{site.base_gateway}} locally, you need Internet access. +* Any network access control to your Kong node must allow traffic to and from Okta, the upstream service, and the client. + + For security reasons, make sure all requests are sent over HTTPS, and make the Kong proxy available + with a fully-qualified domain name and [properly configured certificate](/gateway/{{page.kong_version}}/admin-api/#certificate-object). + Authorization tokens should also be stored securely. + +### Configure Okta + +1. [Register](https://developer.okta.com/docs/guides/add-an-external-idp/openidconnect/register-app-in-okta/) the application you are using Kong to proxy. +1. From the left menu, select **Applications**, then **Create App Integration**. +1. Select the application type: + + 1. Under **Sign-in method**, select **OIDC - OpenID Connect**. + 1. Under **Application Type**, select **Web Application**. + +1. Select **Next**. Configure the application: + 1. Create a unique name for your application. + 1. Under **Grant Type**, select **Authorization Code**. + 1. In both the **Sign-in redirect URIs** and + **Sign-out redirect URIs** fields, enter a location handled by your Route + in Kong Gateway. + + For this example, you can enter `https://kong.com/api`. + + 1. In the Assigments section, for **Controlled access**, choose your + preferred access level for this application. This preferred access level sets the permissions for + Okta admins. + +1. Save your settings to generate connection details. + + Leave this page open. You'll need the details here to configure the Kong OIDC plugin. + +1. Add an Authorization Server. From the left sidebar, go to +**Security > API > Authorization Server** and create a server named + **Kong API Management** with an audience and description. Click **Save**. + + On the page that appears, note the **Issuer** address. You need this address + to configure the Kong OIDC Plugin. + +### Configure the OIDC plugin in {{site.base_gateway}} + +#### Minimum configuration requirements + +Configure the following parameters: + +* **issuer**: The issuer `url` from which OpenID Connect configuration can be discovered. Using Okta, specify the domain and server in the path: + * `https://YOUR_OKTA_DOMAIN/oauth2/YOUR_AUTH_SERVER/.well-known/openid-configuration` +* **auth_method**: A list of authentication methods to use with the plugin, such as passwords, introspection tokens, etc. The majority of cases use `authorization_code`, and {{site.base_gateway}} will accept all methods if no methods are specified. +* **client_id**: The `client_id` of the OpenID Connect client registered in OpenID Connect Provider. Okta provides one to identify itself. +* **client_secret**: The `client_secret` of the OpenID Connect client registered in OpenID Connect Provider. These credentials should never be publicly exposed. +* **redirect_uri**: The `redirect_uri` of the client defined with `client_id` (also used as a redirection URI for the authorization code flow). +* **scopes**: The scope of what OpenID Connect checks. `openid` by default; set to `email` and `profile` for this example. + +{% navtabs %} +{% navtab Configure plugin with Kong Manager %} + +1. In Kong Manager, from the Workspaces tab, select the workspace where your +route is configured. + +1. Click **Routes** in the left navigation. + +1. On the Routes page, select the route you have configured to protect with +Okta and click **View**. + +1. Scroll to the bottom of the page and click **Add Plugin**. + +1. Select the **OpenID Connect** plugin. + +1. On the plugin's configuration, in the **Common** tab, configure the +following, at minimum: + + 1. **Issuer (Discovery Document URI)**: + + ``` + https://{YOUR_OKTA_DOMAIN}/oauth2/{YOUR_AUTH_SERVER}/.well-known/openid-configuration + ``` + + The `issuer` URL can be found in your Authorization Server settings. + + 1. **Client ID**: `{YOUR_CLIENT_ID}` + + Replace `YOUR_CLIENT_ID` with the client ID shown in your Okta + application's **General** page. + + 1. **Client Secret**: `{YOUR_CLIENT_SECRET}` + + Replace `YOUR_CLIENT_SECRET` with the client secret shown in your Okta + application's **General** page. + + 1. **Auth Methods**: `Authorization code flow` + + This parameter lists of all the authentication methods + that you want the plugin to accept. If you don't select an auth method, + all auth methods are allowed by default. + +1. Switch to the **Authorization** tab and fill out **config.scopes required** with +`openid, email, profile`. + +1. Switch to the **Advanced** tab and fill out **config.redirect_uri** with + `https://kong.com/api`. + + The `redirect_uri` should be the URI you specified earlier when configuring + your app. + +1. Click **Create** to save and apply the plugin to the Route. + +For a list of all available configuration parameters and what they do, see the +[OIDC plugin reference](/hub/kong-inc/openid-connect). + +{% endnavtab %} +{% navtab Configure plugin with Admin API %} + +Configure the OpenID Connect plugin using the following sample values: + +```bash +curl -i -X POST https://KONG_ADMIN_URL/routes/ROUTE_ID/plugins \ + --data name="openid-connect" \ + --data config.issuer="https://YOUR_OKTA_DOMAIN/oauth2/YOUR_AUTH_SERVER/.well-known/openid-configuration" \ + --data config.client_id="YOUR_CLIENT_ID" \ + --data config.client_secret="YOUR_CLIENT_SECRET" \ + --data config.redirect_uri="https://kong.com/api" \ + --data config.scopes="openid" \ + --data config.scopes="email" \ + --data config.scopes="profile" +``` + +For a list of all available configuration parameters and what they do, see the +[OIDC plugin reference](/hub/kong-inc/openid-connect). + +{% endnavtab %} +{% endnavtabs %} + +Visiting a URL matched by that route in a browser will now redirect to Okta's authentication +site and return you to the redirect URI after authenticating. + +### Test Your Configuration + +Test the following conditions to ensure a successful integration of the OIDC plugin with Okta: + +* Unauthorized access to a route is blocked +* Authorized access is allowed after login/providing first set of credentials + * Ensure the identity is registered with the IdP + * Steps for debugging +* Authorized access is allowed on immediate subsequent attempts + * Perhaps highlight where the cookie is stored +* Previously authorized access is no longer allowed after cookie terminates + * Set a very short TTL on the session to ensure the tester doesn’t need to wait long to get locked out + +### Access Restrictions + +The example configuration allows users to authenticate and access the Route even though +no Consumer was created for them. Any user with a valid account in the directory +will have access to the Route. The OIDC plugin allows this as the simplest authentication option, +but you may wish to restrict access further. There are several options for this: + +- Consumer Mapping +- Pseudo-Consumer Mapping + +#### Consumer Mapping + +If you need to interact with other Kong plugins using consumer information, you +can add configuration that maps account data received from the identity provider to a Kong consumer. +For this example, the user's Okta's AD account GUID is mapped to a Consumer by setting it +as the `custom_id` on their consumer: + +```bash +curl -i -X POST http://admin.kong.example/consumers/ \ + --data username="Yoda" \ + --data custom_id="e5634b31-d67f-4661-a6fb-b6cb77849bcf" +``` + +```bash +curl -i -X PATCH http://admin.kong.example/plugins/OIDC_PLUGIN_ID \ + --data config.consumer_by="custom_id" \ + --data config.consumer_claim="sub" +``` + +Now, if a user logs into an Okta account with the GUID `e5634b31-d67f-4661-a6fb-b6cb77849bcf`, Kong will apply configuration associated with the Consumer `Yoda` to their requests. + +This also requires that clients login using an account mapped to some Consumer, which might +not be desirable (e.g., you apply OpenID Connect to a service, but only use plugins +requiring a Consumer on some Routes). To deal with this, you can set the `anonymous` parameter +in your OIDC plugin configuration to the ID of a generic Consumer, which will +then be used for all authenticated users that cannot be mapped to some other Consumer. +You can alternately set `consumer_optional` to `true` to allow similar logins +without mapping an anonymous Consumer. + +#### Pseudo-consumers + +For plugins that typically require consumers, the OIDC plugin can provide a consumer ID based on the value of a claim without mapping to an actual Consumer. Setting `credential_claim` to a claim [in your plugin configuration][credential-claim] will extract the value of that claim and use it where Kong would normally use a consumer ID. Note that this may not work with all consumer-related functionality. + +Similarly, setting `authenticated_groups_claim` will extract that claim's value and use it as a group for the ACL plugin. + +[okta-authorization-server]: https://developer.okta.com/docs/guides/customize-authz-server/create-authz-server/ +[okta-register-app]: https://developer.okta.com/docs/guides/add-an-external-idp/openidconnect/register-app-in-okta/ +[credential-claim]: https://docs.konghq.com/hub/kong-inc/openid-connect/#configcredential_claim diff --git a/src/gateway/kong-plugins/authentication/reference.md b/src/gateway/kong-plugins/authentication/reference.md new file mode 100644 index 000000000000..2c1a6e33188b --- /dev/null +++ b/src/gateway/kong-plugins/authentication/reference.md @@ -0,0 +1,213 @@ +--- +title: Authentication Reference +--- + +Traffic to your Upstream services (APIs or microservices) is typically controlled by the application and +configuration of various Kong [authentication plugins][plugins]. Because Kong's Service entity represents +a 1-to-1 mapping of your own upstream services, the simplest scenario is to configure authentication +plugins on the Services of your choosing. + +## Generic authentication + +The most common scenario is to require authentication and to not allow access for any unauthenticated request. +To achieve this, any of the authentication plugins can be used. The generic scheme/flow of those plugins +works as follows: + +1. Apply an auth plugin to a Service, or globally (you cannot apply one on consumers) +2. Create a `consumer` entity +3. Provide the consumer with authentication credentials for the specific authentication method +4. Now whenever a request comes in, Kong will check the provided credentials (depends on the auth type) and +it will either block the request if it cannot validate, or add consumer and credential details +in the headers and forward the request. + +The generic flow above does not always apply, for example when using external authentication like LDAP, +then there is no consumer to be identified, and only the credentials will be added in the forwarded headers. + +The authentication method specific elements and examples can be found in each [plugin's documentation][plugins]. + +## Consumers + +The easiest way to think about consumers is to map them one-on-one to users. Yet, to Kong this does not matter. +The core principle for consumers is that you can attach plugins to them, and hence customize request behavior. +So you might have mobile apps, and define one consumer for each app, or version of it. Or have a consumer per +platform, e.g. an android consumer, an iOS consumer, etc. + +It is an opaque concept to Kong and hence they are called "consumers" and not "users". + +## Anonymous Access + +Kong has the ability to configure a given Service to allow **both** authenticated **and** anonymous access. +You might use this configuration to grant access to anonymous users with a low rate limit, and grant access +to authenticated users with a higher rate limit. + +To configure a Service like this, you first apply your selected authentication plugin, then create a new +consumer to represent anonymous users, then configure your authentication plugin to allow anonymous +access. Here is an example, which assumes you have already configured a Service named `example-service` and +the corresponding Route: + +1. **Create an example Service and a Route** + + Issue the following cURL request to create `example-service` pointing to `mockbin.org`, which will echo + the request: + + ```bash + curl -i -X POST \ + --url http://localhost:8001/services/ \ + --data 'name=example-service' \ + --data 'url=http://mockbin.org/request' + ``` + + Add a Route to the Service: + + ```bash + curl -i -X POST \ + --url http://localhost:8001/services/example-service/routes \ + --data 'paths[]=/auth-sample' + ``` + + The url `http://localhost:8000/auth-sample` will now echo whatever is being requested. + +2. **Configure the key-auth Plugin for your Service** + + Issue the following cURL request to add a plugin to a Service: + + ```bash + curl -i -X POST \ + --url http://localhost:8001/services/example-service/plugins/ \ + --data 'name=key-auth' + ``` + + Be sure to note the created Plugin `id` - you'll need it in step 5. + +3. **Verify that the key-auth plugin is properly configured** + + Issue the following cURL request to verify that the [key-auth][key-auth] + plugin was properly configured on the Service: + + ```bash + curl -i -X GET \ + --url http://localhost:8000/auth-sample + ``` + + Since you did not specify the required `apikey` header or parameter, and you have not yet + enabled anonymous access, the response should be `403 Forbidden`: + + ```http + HTTP/1.1 403 Forbidden + ... + + { + "message": "No API key found in headers or querystring" + } + ``` + +4. **Create an anonymous Consumer** + + Every request proxied by Kong must be associated with a Consumer. You'll now create a Consumer + named `anonymous_users` (that Kong will utilize when proxying anonymous access) by issuing the + following request: + + ```bash + curl -i -X POST \ + --url http://localhost:8001/consumers/ \ + --data "username=anonymous_users" + ``` + + You should see a response similar to the one below: + + ```http + HTTP/1.1 201 Created + Content-Type: application/json + Connection: keep-alive + + { + "username": "anonymous_users", + "created_at": 1428555626000, + "id": "bbdf1c48-19dc-4ab7-cae0-ff4f59d87dc9" + } + ``` + + Be sure to note the Consumer `id` - you'll need it in the next step. + +5. **Enable anonymous access** + + You'll now re-configure the key-auth plugin to permit anonymous access by issuing the following + request (**replace the sample uuids below by the `id` values from step 2 and 4**): + + ```bash + curl -i -X PATCH \ + --url http://localhost:8001/plugins/ \ + --data "config.anonymous=" + ``` + + The `config.anonymous=` parameter instructs the key-auth plugin on this Service to permit + anonymous access, and to associate such access with the Consumer `id` we received in the previous step. It is + required that you provide a valid and pre-existing Consumer `id` in this step - validity of the Consumer `id` + is not currently checked when configuring anonymous access, and provisioning of a Consumer `id` that doesn't already + exist will result in an incorrect configuration. + +6. **Check anonymous access** + + Confirm that your Service now permits anonymous access by issuing the following request: + + ```bash + curl -i -X GET \ + --url http://localhost:8000/auth-sample + ``` + + This is the same request you made in step #3; however, this time the request should succeed because you + enabled anonymous access in step #5. + + The response (which is the request as Mockbin received it) should have these elements: + + ```json + { + ... + "headers": { + ... + "x-consumer-id": "713c592c-38b8-4f5b-976f-1bd2b8069494", + "x-consumer-username": "anonymous_users", + "x-anonymous-consumer": "true", + ... + }, + ... + } + ``` + + It shows the request was successful, but anonymous. + +## Multiple Authentication + +Kong supports multiple authentication plugins for a given Service, allowing +different clients to utilize different authentication methods to access a given Service or Route. + +The behaviour of the auth plugins can be set to do either a logical `AND`, or a logical `OR` when evaluating +multiple authentication credentials. The key to the behaviour is the `config.anonymous` property. + +- `config.anonymous` not set
      + If this property is not set (empty), then the auth plugins will always perform authentication and return + a `40x` response if not validated. This results in a logical `AND` when multiple auth plugins are being + invoked. +- `config.anonymous` set to a valid consumer id
      + In this case, the auth plugin will only perform authentication if it was not already authenticated. When + authentication fails, it will not return a `40x` response, but set the anonymous consumer as the consumer. This + results in a logical `OR` + 'anonymous access' when multiple auth plugins are being invoked. + +**NOTE 1**: Either all or none of the auth plugins must be configured for anonymous access. The behaviour is +undefined if they are mixed. + +**NOTE 2**: When using the `AND` method, the last plugin executed will be the one setting the credentials +passed to the upstream service. With the `OR` method, it will be the first plugin that successfully authenticates +the consumer, or the last plugin that will set its configured anonymous consumer. + +**NOTE 3**: When using the OAuth2 plugin in an `AND` fashion, then also the OAuth2 endpoints for requesting +tokens and so forth will require authentication by the other configured auth plugins. + +
      + When multiple authentication plugins are enabled in an OR fashion on a given Service, and it is desired that + anonymous access be forbidden, then the request-termination plugin should be + configured on the anonymous consumer. Failure to do so will allow unauthorized requests. +
      + +[plugins]: https://konghq.com/plugins/ +[key-auth]: /hub/kong-inc/key-auth diff --git a/src/gateway/kong-plugins/configuring-a-grpc-service.md b/src/gateway/kong-plugins/configuring-a-grpc-service.md new file mode 100644 index 000000000000..30ac849d8df3 --- /dev/null +++ b/src/gateway/kong-plugins/configuring-a-grpc-service.md @@ -0,0 +1,285 @@ +--- +title: Configuring a gRPC Service +content_type: how-to +--- + +Note: this guide assumes familiarity with gRPC; for learning how to set up +Kong with an upstream REST API, check out the [Configuring a Service guide][conf-service]. + +Starting with version 1.3, gRPC proxying is natively supported in Kong. In this +section, you'll learn how to configure Kong to manage your gRPC services. For the +purpose of this guide, we'll use [grpcurl][grpcurl] and [grpcbin][grpcbin] - they +provide a gRPC client and gRPC services, respectively. + +We will describe two setups: Single gRPC Service and Route and single gRPC Service +with multiple Routes. In the former, a single catch-all Route is configured, which +proxies all matching gRPC traffic to an upstream gRPC service; the latter demonstrates +how to use a Route per gRPC method. + +In Kong 1.3, gRPC support assumes gRPC over HTTP/2 framing. As such, make sure +you have at least one HTTP/2 proxy listener (check out the [Configuration Reference][configuration-reference] +for how to). In this guide, we will assume Kong is listening for HTTP/2 proxy +requests on port 9080. + +## Before you start + +You have installed and started {{site.base_gateway}}, either through the [Docker quickstart](/gateway/{{page.kong_version}}/get-started) or a more [comprehensive installation](/gateway/{{page.kong_version}}/install). + +## 1. Single gRPC Service and Route + +Issue the following request to create a gRPC Service (assuming your gRPC +server is listening in localhost, port 15002): + +```bash +curl -XPOST localhost:8001/services \ + --data name=grpc \ + --data protocol=grpc \ + --data host=localhost \ + --data port=15002 +``` + +Issue the following request to create a gRPC route: + +```bash +curl -XPOST localhost:8001/services/grpc/routes \ + --data protocols=grpc \ + --data name=catch-all \ + --data paths=/ +``` + +Using the [grpcurl][grpcurl] command line client, issue the following gRPC +request: + +```bash +grpcurl -v -d '{"greeting": "Kong 1.3!"}' \ + -plaintext localhost:9080 hello.HelloService.SayHello +``` + +The response should resemble the following: + +``` +Resolved method descriptor: +rpc SayHello ( .hello.HelloRequest ) returns ( .hello.HelloResponse ); + +Request metadata to send: +(empty) + +Response headers received: +content-type: application/grpc +date: Tue, 16 Jul 2019 21:37:36 GMT +server: openresty/1.15.8.1 +via: kong/1.2.1 +x-kong-proxy-latency: 0 +x-kong-upstream-latency: 0 + +Response contents: +{ + "reply": "hello Kong 1.3!" +} + +Response trailers received: +(empty) +Sent 1 request and received 1 response +``` + +Notice that Kong response headers, such as `via` and `x-kong-proxy-latency`, were +inserted in the response. + +## 2. Single gRPC Service with Multiple Routes + +Building on top of the previous example, let's create a few more routes, for +individual gRPC methods. + +The gRPC "HelloService" service being used in this example exposes a few different +methods, as can be seen in [its protobuf file][protobuf]. We will create individual +routes for its "SayHello" and LotsOfReplies methods. + +Create a Route for "SayHello": + +```bash +curl -X POST localhost:8001/services/grpc/routes \ + --data protocols=grpc \ + --data paths=/hello.HelloService/SayHello \ + --data name=say-hello +``` + +Create a Route for "LotsOfReplies": + +```bash +curl -X POST localhost:8001/services/grpc/routes \ + --data protocols=grpc \ + --data paths=/hello.HelloService/LotsOfReplies \ + --data name=lots-of-replies +``` + +With this setup, gRPC requests to the "SayHello" method will match the first +Route, while requests to "LotsOfReplies" will be routed to the latter. + +Issue a gRPC request to the "SayHello" method: + +```bash +grpcurl -v -d '{"greeting": "Kong 1.3!"}' \ + -H 'kong-debug: 1' -plaintext \ + localhost:9080 hello.HelloService.SayHello +``` + +(Notice we are sending a header `kong-debug`, which causes Kong to insert +debugging information in response headers.) + +The response should look like: + +``` +Resolved method descriptor: +rpc SayHello ( .hello.HelloRequest ) returns ( .hello.HelloResponse ); + +Request metadata to send: +kong-debug: 1 + +Response headers received: +content-type: application/grpc +date: Tue, 16 Jul 2019 21:57:00 GMT +kong-route-id: 390ef3d1-d092-4401-99ca-0b4e42453d97 +kong-service-id: d82736b7-a4fd-4530-b575-c68d94c3493a +kong-service-name: s1 +server: openresty/1.15.8.1 +via: kong/1.2.1 +x-kong-proxy-latency: 0 +x-kong-upstream-latency: 0 + +Response contents: +{ + "reply": "hello Kong 1.3!" +} + +Response trailers received: +(empty) +Sent 1 request and received 1 response +``` + +Notice the Route ID should refer to the first route we created. + +Similarly, let's issue a request to the "LotsOfReplies" gRPC method: + +```bash +grpcurl -v -d '{"greeting": "Kong 1.3!"}' \ + -H 'kong-debug: 1' -plaintext \ + localhost:9080 hello.HelloService.LotsOfReplies +``` + +The response should look like the following: + +``` +Resolved method descriptor: +rpc LotsOfReplies ( .hello.HelloRequest ) returns ( stream .hello.HelloResponse ); + +Request metadata to send: +kong-debug: 1 + +Response headers received: +content-type: application/grpc +date: Tue, 30 Jul 2019 22:21:40 GMT +kong-route-id: 133659bb-7e88-4ac5-b177-bc04b3974c87 +kong-service-id: 31a87674-f984-4f75-8abc-85da478e204f +kong-service-name: grpc +server: openresty/1.15.8.1 +via: kong/1.2.1 +x-kong-proxy-latency: 14 +x-kong-upstream-latency: 0 + +Response contents: +{ + "reply": "hello Kong 1.3!" +} + +Response contents: +{ + "reply": "hello Kong 1.3!" +} + +Response contents: +{ + "reply": "hello Kong 1.3!" +} + +Response contents: +{ + "reply": "hello Kong 1.3!" +} + +Response contents: +{ + "reply": "hello Kong 1.3!" +} + +Response contents: +{ + "reply": "hello Kong 1.3!" +} + +Response contents: +{ + "reply": "hello Kong 1.3!" +} + +Response contents: +{ + "reply": "hello Kong 1.3!" +} + +Response contents: +{ + "reply": "hello Kong 1.3!" +} + +Response contents: +{ + "reply": "hello Kong 1.3!" +} + +Response trailers received: +(empty) +Sent 1 request and received 10 responses +``` + +Notice that the `kong-route-id` response header now carries a different value +and refers to the second Route created in this page. + +**Note:** +Some gRPC clients (typically CLI clients) issue ["gRPC Reflection Requests"][grpc-reflection] +as a means of determining what methods a server exports and how those methods are called. +Said requests have a particular path; for example, `/grpc.reflection.v1alpha.ServerReflection/ServerReflectionInfo` +is a valid reflection path. As with any proxy request, Kong needs to know how to +route these; in the current example, they would be routed to the catch-all route +(whose path is `/`, matching any path). If no route matches the gRPC reflection +request, Kong will respond, as expected, with a `404 Not Found` response. + +## 3. Enabling Plugins + +Kong 1.3 gRPC support is compatible with Logging and Observability plugins; for +example, let's try out the [File Log][file-log] plugin with gRPC. + +Issue the following request to enable File Log on the "SayHello" route: + +```bash +curl -X POST localhost:8001/routes/say-hello/plugins \ + --data name=file-log \ + --data config.path=grpc-say-hello.log +``` + +Follow the output of the log as gRPC requests are made to "SayHello": + +``` +tail -f grpc-say-hello.log +{"latencies":{"request":8,"kong":5,"proxy":3},"service":{"host":"localhost","created_at":1564527408,"connect_timeout":60000,"id":"74a95d95-fbe4-4ddb-a448-b8faf07ece4c","protocol":"grpc","name":"grpc","read_timeout":60000,"port":15002,"updated_at":1564527408,"write_timeout":60000,"retries":5},"request":{"querystring":{},"size":"46","uri":"\/hello.HelloService\/SayHello","url":"http:\/\/localhost:9080\/hello.HelloService\/SayHello","headers":{"host":"localhost:9080","content-type":"application\/grpc","kong-debug":"1","user-agent":"grpc-go\/1.20.0-dev","te":"trailers"},"method":"POST"},"client_ip":"127.0.0.1","tries":[{"balancer_latency":0,"port":15002,"balancer_start":1564527732522,"ip":"127.0.0.1"}],"response":{"headers":{"kong-route-id":"e49f2df9-3e8e-4bdb-8ce6-2c505eac4ab6","content-type":"application\/grpc","connection":"close","kong-service-name":"grpc","kong-service-id":"74a95d95-fbe4-4ddb-a448-b8faf07ece4c","kong-route-name":"say-hello","via":"kong\/1.2.1","x-kong-proxy-latency":"5","x-kong-upstream-latency":"3"},"status":200,"size":"298"},"route":{"id":"e49f2df9-3e8e-4bdb-8ce6-2c505eac4ab6","updated_at":1564527431,"protocols":["grpc"],"created_at":1564527431,"service":{"id":"74a95d95-fbe4-4ddb-a448-b8faf07ece4c"},"name":"say-hello","preserve_host":false,"regex_priority":0,"strip_path":false,"paths":["\/hello.HelloService\/SayHello"],"https_redirect_status_code":426},"started_at":1564527732516} +{"latencies":{"request":3,"kong":1,"proxy":1},"service":{"host":"localhost","created_at":1564527408,"connect_timeout":60000,"id":"74a95d95-fbe4-4ddb-a448-b8faf07ece4c","protocol":"grpc","name":"grpc","read_timeout":60000,"port":15002,"updated_at":1564527408,"write_timeout":60000,"retries":5},"request":{"querystring":{},"size":"46","uri":"\/hello.HelloService\/SayHello","url":"http:\/\/localhost:9080\/hello.HelloService\/SayHello","headers":{"host":"localhost:9080","content-type":"application\/grpc","kong-debug":"1","user-agent":"grpc-go\/1.20.0-dev","te":"trailers"},"method":"POST"},"client_ip":"127.0.0.1","tries":[{"balancer_latency":0,"port":15002,"balancer_start":1564527733555,"ip":"127.0.0.1"}],"response":{"headers":{"kong-route-id":"e49f2df9-3e8e-4bdb-8ce6-2c505eac4ab6","content-type":"application\/grpc","connection":"close","kong-service-name":"grpc","kong-service-id":"74a95d95-fbe4-4ddb-a448-b8faf07ece4c","kong-route-name":"say-hello","via":"kong\/1.2.1","x-kong-proxy-latency":"1","x-kong-upstream-latency":"1"},"status":200,"size":"298"},"route":{"id":"e49f2df9-3e8e-4bdb-8ce6-2c505eac4ab6","updated_at":1564527431,"protocols":["grpc"],"created_at":1564527431,"service":{"id":"74a95d95-fbe4-4ddb-a448-b8faf07ece4c"},"name":"say-hello","preserve_host":false,"regex_priority":0,"strip_path":false,"paths":["\/hello.HelloService\/SayHello"],"https_redirect_status_code":426},"started_at":1564527733554} +``` + +[enabling-plugins]: /gateway/{{page.kong_version}}/get-started/enabling-plugins +[conf-service]: /gateway/{{page.kong_version}}/get-started/services-and-routes +[configuration-reference]: /gateway/{{page.kong_version}}/reference/configuration/ +[grpc-reflection]: https://github.com/grpc/grpc/blob/master/doc/server_reflection_tutorial.md +[grpcbin]: https://github.com/moul/grpcbin +[grpcurl]: https://github.com/fullstorydev/grpcurl +[protobuf]: https://raw.githubusercontent.com/moul/pb/master/hello/hello.proto +[file-log]: /hub/kong-inc/file-log +[zipkin]: /hub/kong-inc/zipkin diff --git a/src/gateway/kong-plugins/graphql.md b/src/gateway/kong-plugins/graphql.md new file mode 100644 index 000000000000..b07238c02ece --- /dev/null +++ b/src/gateway/kong-plugins/graphql.md @@ -0,0 +1,65 @@ +--- +title: Getting Started with GraphQL and Kong Gateway +badge: enterprise +--- + +GraphQL decouples apps from services by introducing a flexible query language. Instead of a custom API for each screen, app developers describe the data they need, service developers describe what they can supply, and GraphQL automatically matches the two together. Teams ship faster across more platforms, with new levels of visibility and control over the use of their data. To learn more about how teams benefit, read why [GraphQL is important](https://www.apollographql.com/why-graphql/). + +{{site.base_gateway}} is an API gateway and platform. That means it is a form of middleware between computing clients and your API-based applications. {{site.base_gateway}} quickly and consistently extends the features of your APIs. Some of the popular features deployed through {{site.base_gateway}} include authentication, security, traffic control, serverless, analytics & monitoring, request/response transformations, and logging. To learn more about these features, see the [Hub page](/hub/) for plugins. For more about the benefits of Kong in general, please see the [FAQ](https://konghq.com/faqs). + +The GraphQL paradigm differs from traditional API-based systems. Depending on the resolver implementation details, one query can potentially generate an arbitrary number of requests. Proxy caching and rate limiting on top of GraphQL is key but usually overlooked as a hard problem to solve, since traditional proxy-caching and rate-limiting is not a good fit for GraphQL. + +Kong easily integrates with existing GraphQL infrastructure out of the box. By introspecting the GraphQL schema and queries, Kong provides enterprise-grade proxy-caching and rate-limiting specifically tailored for GraphQL. + +## Existing GraphQL infrastructure + +Use {{site.base_gateway}} to protect and manage an existing GraphQL endpoint. The following will set up a {{site.base_gateway}} instance on top of a GraphQL upstream and set up key-auth, proxy-caching and rate-limiting. + +### Add your Service and Route on Kong + +After installing and starting {{site.base_gateway}}, use the Admin API on port 8001 to add a new Service and Route. In this example, {{site.base_gateway}} will reverse proxy every incoming request with the specified incoming host to the associated upstream URL. You can implement very complex routing mechanisms beyond simple host matching. + + +```sh +curl -i -X POST \ + --url http://localhost:8001/services/ \ + --data 'name=graphql-service' \ + --data 'url=http://example.com' +``` + +```sh +curl -i -X POST \ + --url http://localhost:8001/services/example-service/routes \ + --data 'hosts[]=example.com' \ +``` + +### Add GraphQL Plugins on the Service + +Proxy caching for GraphQL provides advanced caching over queries. + +```sh +curl -i -X POST \ + --url http://localhost:8001/services/example-service/plugins/ \ + --data 'name=graphql-proxy-cache-advanced' \ + --data 'config.strategy=memory' +``` + +Protect your upstream GraphQL service with rate limiting. By introspecting your schema, it will analyze query costs and provide an enterprise-grade rate-limiting strategy. + +```sh +curl -i -X POST http://kong:8001/services/example-service/plugins \ + --data name=graphql-rate-limiting-advanced \ + --data config.limit=100,10000 \ + --data config.window_size=60,3600 \ + --data config.sync_rate=10 +``` + +The GraphQL Rate Limiting Advanced plugin supports two rate-limiting strategies. The default strategy will try to estimate cost on queries by counting the nesting of nodes. The default strategy is meant as a good middle ground for general GraphQL queries, where it's difficult to assert a clear cost strategy, so every operation has a cost of 1. + +A more advanced strategy is available for GraphQL schemas that enforce quantifier arguments on any connection, providing a good approximation on the number of nodes visited for satisfying a query. Any query without decorated quantifiers has a cost of 1. It is roughly based on [GitHub's GraphQL resource limits](https://developer.github.com/v4/guides/resource-limitations/). + +Read more about rate-limiting here: [GraphQL Rate Limiting Advanced Plugin](/hub/kong-inc/graphql-rate-limiting-advanced) + +### New upstream + +We have prepared a [quickstart guide](https://github.com/Kong/kong-apollo-quickstart) that will help you build your new GraphQL service on top of Kong and Apollo. diff --git a/src/gateway/kong-plugins/grpc.md b/src/gateway/kong-plugins/grpc.md new file mode 100644 index 000000000000..bad81c061f12 --- /dev/null +++ b/src/gateway/kong-plugins/grpc.md @@ -0,0 +1,170 @@ +--- +title: Introduction to Kong gRPC Plugins +--- + +Before going into the specifics of configuring Kong's gRPC plugins, let's +discuss the advantages of the gRPC protocol. Unlike JSON, +[gRPC](https://en.wikipedia.org/wiki/GRPC) +is a binary protocol, using [protobuf](https://en.wikipedia.org/wiki/Protocol_Buffers) +definitions to instruct how the data is marshalled and unmarshalled. Because +binary data is used instead of text, it's a more efficient way to transmit data +over a network. However, this also makes gRPC harder to work with, because inspecting +what went wrong is more challenging. Additionally, few clients natively handle gRPC. + +To help alleviate the challenges of working with gRPC, Kong has two plugins: +- [gRPC-Gateway](/hub/kong-inc/grpc-gateway) +- [gRPC-Web](/hub/kong-inc/grpc-web) + +The gRPC-Gateway plugin allows you to send JSON requests to a gRPC service. A +specially configured `.proto` file handles the conversion of the JSON request +into one that the gRPC service can handle. This allows you to expose RESTful-style +interfaces that talk to a gRPC service. + +The gRPC-Web plugin allows you to interact with a gRPC service from a browser. +Instead of presenting a RESTful-type call, you POST data to the same +gRPC service endpoint that the protobuf defines. + +For flexibility and compatibility with RESTful expectations, the gRPC-Gateway +plugin offers more configurability, whereas the gRPC-Web plugin adheres more +directly to the protobuf specification. + +Let's walk through setting up each plugin so you can see how they work. + +## gRPC-Gateway plugin configuration + +Set up a Service: + +``` +curl -X POST kong-cp-host:8001/services \ +--data 'name=grpcbin-service' \ +--data 'url=grpc://grpcb.in:9000' +``` + +Set up the Route to the Service: + +``` +curl -X POST kong-cp-host:8001/services/grpcbin-service/routes \ +--data 'name=grpcbin-get-route' \ +--data 'paths=/' \ +--data 'methods=GET' \ +--data 'headers.x-grpc=true' +``` + +Set up the gRPC-Web plugin: + +``` +curl -X POST kong-cp-host:8001/routes/grpcbin-get-route/plugins \ +--data 'name=grpc-gateway' \ +--data 'config.proto=/usr/local/kong/hello-gateway.proto' +``` + +Protobuf definition (`hello-gateway.proto`): + +``` +syntax = "proto3"; + +package hello; + +service HelloService { + rpc SayHello(HelloRequest) returns (HelloResponse) { + option (google.api.http) = { + get: "/v1/messages/{name}" + additional_bindings { + get: "/v1/messages/legacy/{name=**}" + } + post: "/v1/messages/" + body: "*" + } + } +} + + +// The request message containing the user's name. +message HelloRequest { + string name = 1; +} + +// The response message containing the greetings +message HelloResponse { + string message = 1; +} +``` + +Upload the protobuf definition to your Kong Node: + +``` +docker cp hello-gateway.proto kong-dp-host:/usr/local/kong/ +``` + +Test your setup: + +``` +curl -X GET kong-dp-host:8000/v1/messages/kong2.1 \ +--header 'x-grpc: true' +``` + +## gRPC-Web plugin configuration + +Set up a Service: + +``` +curl -X POST kong-cp-host:8001/services \ +--data 'name=grpcbin-service' \ +--data 'url=grpc://grpcb.in:9000' +``` + +Set up the Route to the Service: + +``` +curl -X POST kong-cp-host:8001/services/grpcbin-service/routes \ +--data 'name=grpcbin-post-route' \ +--data 'paths=/' \ +--data 'methods=POST' \ +--data 'headers.x-grpc=true' +``` + +Set up the gRPC-Web plugin: + +``` +curl -X POST kong-cp-host:8001/routes/grpcbin-post-route/plugins \ +--data 'name=grpc-web' \ +--data 'config.proto=/usr/local/kong/hello.proto' +``` + +Protobuf definition (`hello.proto`): + +``` +syntax = "proto2"; + +package hello; + +service HelloService { + rpc SayHello(HelloRequest) returns (HelloResponse); + rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse); + rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse); + rpc BidiHello(stream HelloRequest) returns (stream HelloResponse); +} + +message HelloRequest { + optional string greeting = 1; +} + +message HelloResponse { + required string reply = 1; +} +``` + +Upload the protobuf definition to your Kong Node: + +``` +docker cp hello.proto kong-dp-host:/usr/local/kong/ +``` + +Test your setup: + +``` +curl -X POST kong-dp-host:8000/hello.HelloService/SayHello \ +--header 'x-grpc: true' \ +--header 'Content-Type: application/json' \ +--data '{"greeting":"kong2.1"}' +``` diff --git a/src/gateway/kong-plugins/index.md b/src/gateway/kong-plugins/index.md new file mode 100644 index 000000000000..0537824dae81 --- /dev/null +++ b/src/gateway/kong-plugins/index.md @@ -0,0 +1,6 @@ +--- +title: About Kong Plugins +content_type: explanation +--- + +{% include_cached /md/about-plugins.md %} \ No newline at end of file diff --git a/src/gateway/kong-plugins/rate-limiting/algorithms/fixed-bucket.md b/src/gateway/kong-plugins/rate-limiting/algorithms/fixed-bucket.md new file mode 100644 index 000000000000..bb8d387bbec0 --- /dev/null +++ b/src/gateway/kong-plugins/rate-limiting/algorithms/fixed-bucket.md @@ -0,0 +1,6 @@ +--- +title: fixed bucket + +--- + +## place holder \ No newline at end of file diff --git a/src/gateway/kong-plugins/rate-limiting/algorithms/rate-limiting.md b/src/gateway/kong-plugins/rate-limiting/algorithms/rate-limiting.md new file mode 100644 index 000000000000..ae5d9c7c2836 --- /dev/null +++ b/src/gateway/kong-plugins/rate-limiting/algorithms/rate-limiting.md @@ -0,0 +1,142 @@ +--- +title: Rate Limiting Library +badge: enterprise +--- + +## Overview + + +{% include_cached /md/enterprise/cassandra-deprecation.md %} + + +This library is designed to provide an efficient, scalable, eventually-consistent sliding window rate limiting library. It relies on atomic operations in shared ngx memory zones to track window counters within a given node, periodically syncing this data to a central data store. + +A sliding window rate limiting implementation tracks the number of hits assigned to a specific key (such as an IP address, Consumer, Credential, etc) within a given time window, taking into account previous hit rates to smooth out a calculated rate, while still providing a familiar windowing interface that modern developers are used to (e.g., n hits per second/minute/hour). This is similar to a fixed window implementation, in which request rates reset at the beginning of the window, but without the "reset bump" from which fixed window implementations suffer, while providing a more intuitive interface beyond what leaky bucket or token bucket implementations can offer. Note that we use the term "hit" instead of "request" when referring to incrementing values for rate limit keys, because this library provides an abstract rate limiting interface; a sliding window implementation may have uses outside of HTTP request rate limiting, thus, we describe this library in a more abstract sense. + +A sliding window takes into account a weighted value of the previous window when calculating the current rate for a given key. A window is defined as a period of time, starting at a given "floor" timestamp, where the floor is calculated based on the size of the window. For window sizes of 60 seconds, the floor always falls at the 0th second (e.g., at the beginning of any given minute). Likewise, windows with a size of 30 seconds will begin at the 0th and 30th seconds of each minute. + +Consider a rate limit of 10 hits per minute. In this configuration, this library will calculate the hit rate of a given key based on the number of hits for the current window (starting at the beginning of the current minute), and a weighted percentage of all hits of the previous window (e.g., the previous minute). This weight is calculated based on the current timestamp with respect to the window size in question; the farther away the current time is from the start of the previous window, the lower the weight percentage. This value is best expressed through an example: + +``` +current window rate: 10 +previous window rate: 40 +window size: 60 +window position: 30 (seconds past the start of the current window) +weight = .5 (60 second window size - 30 seconds past the window start) + +rate = 'current rate' + 'previous weight' * 'weight' + = 10 + 40 * ('window size' - 'window position') / 'window size' + = 10 + 40 * (60 - 30) / 60 + = 10 + 40 * .5 + = 30 +``` +Strictly speaking, the formula used to define the weighting percentage is as follows: + +`weight = (window_size - (time() % window_size)) / window_size` + +Where `time()` is the value of the current Unix timestamp. + +Each node in the Kong cluster relies on its own in-memory data store as the source of truth for rate limiting counters. Periodically, each node pushes a counter increment for each key it saw to the cluster, which is expected to atomically apply this diff to the appropriate key. The node then retrieves this key's value from the data store, along with other relevant keys for this data sync cycle. In this manner, each node shares the relevant portions of data with the cluster, while relying on a very high-performance method of tracking data during each request. This cycle of converge -> diverge -> reconverge among nodes in the cluster provides our eventually-consistent model. + +The periodic rate at which nodes converge is configurable; shorter sync intervals will result in less divergence of data points when traffic is spread across multiple nodes in the cluster (e.g., when sitting behind a round robin balancer), whereas longer sync intervals put less r/w pressure on the datastore, and less overhead on each node to calculate diffs and fetch new synced values. The desirable value here depends on use case; when using cluster syncing to refresh nodes periodically (e.g., to inform new cluster nodes of counter data), a value of 10-30 seconds may be desirable, to minimize data store traffic. Contrarily, environments demanding stronger consistency between nodes (such as orchestrated deployments involving a high churn rate among cluster membership, or cases where strict rate limiting policies must be applied to node sitting behind a non-hashing load balancer) should use a lower sync period, on the order of milliseconds. The minimum possible value is 0.001 (1 millisecond), though practically this value is limited by network performance between Kong nodes and the configured data store. + +In addition to periodic data sync behavior, this library can implement rate limiting counter in a synchronous pattern by defining its `sync_rate` as `0`. In such a case, the given counter will be applied directly to the datastore. This behavior is desirable in cases where stronger consistency among the cluster is desired; such a configuration comes with the cost of needing to communicate with the datastore (or Redis) on every request, which can induce noticeable latency into the request ("noticeable" being a relative term of typically a few milliseconds, depending on the performance of the storage mechanism in question; for comparison, Kong typically processes requests on the order of tens of microseconds). + +This library can also forgo syncing counter data entirely, and only apply incremental counters to its local memory zone, by defining a `sync_rate` value of less than `0`. This behavior is useful when cluster-wide syncing of data is unnecessary, such as environments using only a single Kong node, or where Kong nodes live behind a hashing load balancer and are treated as isolated instances. + +Module configuration data, such as sync rate, shared dictionary name, storage policy, etc, is kept in a per-worker public configuration table. Multiple configurations can be defined as stored as arbitrary `namespaces` (more on this below). + +## Developer Notes +### Public Functions +The following public functions are provided by this library: + +`ratelimiting.new` + +_syntax: ok = ratelimiting.new(opts)_ + +Define configurations for a new namespace. The following options are accepted: + +- dict: Name of the shared dictionary to use +- sync_rate: Rate, in seconds, to sync data diffs to the storage server. +- strategy: Storage strategy to use. currently cassandra, postgres, and redis are supported. Strategies must provide several public—functions defined below. +- strategy_opts: A table of options used by the storage strategy. Currently only applicable for the 'redis' strategy. +- namespace: String defining these config values. A namespace may only be defined once; if a namespace has already been defined on this worker, an error is thrown. If no namespace is defined, the literal string "default" will be used. +- window_sizes: A list of window sizes used by this configuration. + +`ratelimiting.increment` + +_syntax: rate = ratelimiting.increment(key, window_size, value, namespace?)_ + +Increment a given key for window_size by value. If namespace is undefined, the "default" namespace is used. value can be any number Lua type (but ensure that the storage strategy in use for this namespace can support decimal values if a non-integer value is provided). This function returns the sliding rate for this key/window_size after the increment of value has been applied. + +`ratelimit.sliding_window` + +_syntax: rate = ratelimit.sliding_window(key, window_size, cur_diff?, namespace?)_ + +Return the current sliding rate for this key/window_size. An optional cur_diff value can be provided that overrides the current stored diff for this key. If `namespace` is undefined, the "default" namespace is used. + +`ratelimiting.sync` + +_syntax: ratelimiting.sync(premature, namespace?)_ + +Sync all currently stored key diffs in this worker with the storage server, and retrieve the newly synced value. If namespace is undefined, the "default" `namespace` is used. Before the diffs are pushed, another sync call for the given namespace is scheduled at `sync_rate` seconds in the future. Given this, this function should typically be called during the `init_worker` phase to initialize the recurring timer. This function is intended to be called in an `ngx.timer` context; hence, the first variable represents the injected `premature` param. + +`ratelimiting.fetch` + +_syntax: ratelimiting.fetch(premature, namespace, time, timeout?)_ + +Retrieve all relevant counters for the given namespace at the given time. This +function establishes a shm mutex such that only one worker will fetch and +populate the shm per execution. If timeout is defined, the mutex will expire +based on the given timeout value; otherwise, the mutex is unlocked immediately +following the dictionary update. This function can be called in an `ngx.timer` +context; hence, the first variable represents the injected `premature` param. + +### Strategy Functions + +Storage strategies must provide the following interfaces: + +#### strategy_class.new +_syntax: strategy = strategy_class.new(dao_factory, opts)_ + +Implement a new strategy object. `opts` is expected to be a table type, and can be used to pass opaque/arbitrary options to the strategy class. + +#### strategy:push_diffs +_syntax: strategy:push_diffs(diffs)_ + +Push a table of key diffs to the storage server. diffs is a table provided in the following format: + +``` +[1] = { + key = "1.2.3.4", + windows = { + { + window = 12345610, + size = 60, + diff = 5, + namespace = foo, + }, + { + window = 12345670, + size = 60, + diff = 5, + namespace = foo, + }, + } + }, + ... + ["1.2.3.4"] = 1, + ... + ``` + +#### strategy:get_counters + +_syntax: rows = strategy:get_counters(namespace, window_sizes, time?)_ + +Return an iterator for each key stored in the datastore/redis for a given `namepsace` and list of window sizes. 'time' is an optional unix second- precision timestamp; if not provided, this value will be set via `ngx.time()`. It is encouraged to pass this via a previous defined timestamp, depending on the context (e.g., if previous calls in the same thread took a nontrivial amount of time to run). + +#### strategy:get_window + +_syntax: window = strategy:get_window(key, namespace, window_start, window_size)_ + +Retrieve a single key from the data store based on the values provided. diff --git a/src/gateway/kong-plugins/rate-limiting/index.md b/src/gateway/kong-plugins/rate-limiting/index.md new file mode 100644 index 000000000000..5df77dc551b3 --- /dev/null +++ b/src/gateway/kong-plugins/rate-limiting/index.md @@ -0,0 +1,6 @@ +--- +title: Overview for Rate-limiting + +--- + +## place holder \ No newline at end of file diff --git a/src/gateway/kong-plugins/request-transformer/add-body-value.md b/src/gateway/kong-plugins/request-transformer/add-body-value.md new file mode 100644 index 000000000000..6c04db07c48c --- /dev/null +++ b/src/gateway/kong-plugins/request-transformer/add-body-value.md @@ -0,0 +1,111 @@ +--- +title: "Adding attributes to HTTP requests with Kong Gateway" +description: "A no-code solution to modifying requests for your APIs" +--- + +It's very common to have an HTTP service which accepts requests expecting a JSON document in the body. +Let's assume that the development team of your service plans to change the request API in the near future, +and will eventually begin to require a new field in the JSON body of the requests. +Eventually your client applications will need to upgrade their requests to support this new value, +but how could you provide a default value for your services in the meantime? + +[{{site.base_gateway}}](/gateway/{{page.kong_version}}/) supports a [Plugin](/hub/) +architecture including a [Request Transformer Plugin](/hub/kong-inc/request-transformer/) +that can modify incoming requests before proxying them to your upstream service. +This can all be accomplished using a no-code solution and managed with no downtime using +Kong's dynamic administrative capabilities. + +This guide will show you how to configure the Request Transformer plugin using +the [Kong Admin API](/gateway/{{page.kong_version}}/admin-api/) to modify incoming +requests with a static constant value. Then you will test the feature with a mock +request to verify the transformation process. + +### Prerequisites + +* This document is best used after following the companion +[{{site.base_gateway}} in minutes](/gateway/latest/get-started/) guide, which +walks you through running a local {{site.base_gateway}} in Docker, setting up +a mock [service](/gateway/latest/admin-api/#service-object), and the necessary connection details. +If you'd like to use an existing {{site.base_gateway}} or a different service, you will need to adjust the +commands in this guide as necessary. +* You have [`curl`](https://curl.se/) installed on your system, which is used to send +requests to the gateway. Most systems come with `curl` pre-installed. +* This guide uses the [`jq`](https://stedolan.github.io/jq/) command line JSON processing tool. While +this tool is not necessary to complete the tasks, it's helpful for processing JSON responses from +the gateway. If you do not have `jq` or do not wish to install it, you can modify the commands to remove +`jq` processing. + +### Steps + +There are a large number of Kong plugins, many of which need to +be [custom installed](/gateway/{{page.kong_version}}/plugin-development/distribution/) +prior to utilization. Kong ships prepackaged with a number of useful plugins including +the Request Transformer you will use in this guide. + +First verify the Request Transformer plugin is available on your gateway by querying the Admin API and using `jq` to filter the response looking at the plugins available on the server. + +```sh +curl -s $KONG_ADMIN_API | \ + jq -r '.plugins.available_on_server."request-transformer"' +``` + +The command output should be: +``` +true +``` + +Now, assign a new instance of the Request Transformer plugin to +the mock service by sending a `POST` request to the Admin API. +In this command, the `config.add.body` value instructs the plugin to add a new +field to the body of incoming requests before forwarding them to the `mock` service. +In this example, we are instructing the plugin to add a field named `new-field` and +give it a static value of `defaultValue`. + +```sh +curl -i -X POST $KONG_ADMIN_API/services/mock/plugins \ + --data "name=request-transformer" \ + --data "config.add.body=new-field:defaultValue" +``` + +If successful the API will return a `201 Created` HTTP response code with a +JSON body including information about the new plugin instance. + +{:.note} +> **Note:** The Request Transformer can perform more complex transformations than +shown here, see the [full documentation](/hub/kong-inc/request-transformer/) for the details. + +Next, use the `mock` service's `/requests` endpoint to test the behavior of the plugin. +The `/requests` API will echo back helpful information from the request we send it, including +headers and the request body. + +```sh +curl -s -XPOST $KONG_PROXY/mock/requests \ + -H 'Content-Type: application/json' \ + -d '{"existing-field": "abc123"}' +``` + +The JSON response will contain the `postData` field which includes the +JSON body sent to the service. You can use `jq` to fully extract the request body +returned from the `mock` service, as follows: + +```sh +curl -s -XPOST $KONG_PROXY/mock/requests \ + -H 'Content-Type: application/json' \ + -d '{"existing-field": "Kong FTW!"}' | \ + jq -r '.postData.text' +``` + +This will output the following text indicating `new-field` has been added to the request body. + +```txt +{"existing-field":"Kong FTW!","new-field":"defaultValue"} +``` + +### What's next? + +* More advanced transformations can be accomplished with the +[Request Transformer Advanced](/hub/kong-inc/request-transformer-advanced/) +plugin. +* If no standard plugin is available to satisfy your use case, the +[Plugin Development Guide](/gateway/{{page.kong_version}}/plugin-development/) +can help you with developing your own plugin. diff --git a/src/gateway/licenses/deploy.md b/src/gateway/licenses/deploy.md new file mode 100644 index 000000000000..745036c3461d --- /dev/null +++ b/src/gateway/licenses/deploy.md @@ -0,0 +1,9 @@ +--- +title: Deploy an Enterprise License +badge: enterprise +--- + +Deploy an enterprise license to a {{site.base_gateway}} installation to gain access +to [Enterprise-specific features](/gateway/{{page.kong_version}}/licenses). + +{% include_cached /md/enterprise/deploy-license.md heading="##" kong_version=page.kong_version %} diff --git a/src/gateway/licenses/download.md b/src/gateway/licenses/download.md new file mode 100644 index 000000000000..e5e588aa57c9 --- /dev/null +++ b/src/gateway/licenses/download.md @@ -0,0 +1,22 @@ +--- +title: Download Your Kong Gateway License +badge: enterprise +--- + +To enable Enterprise features, {{site.base_gateway}} requires a license file. +You will receive this file from Kong when you sign up for a +{{site.konnect_product_name}} Enterprise subscription. + +[Contact Kong](https://konghq.com/get-started) for more information. + +
      +Note: The free mode does not require a license. See +Kong Gateway Licensing +for a feature comparison. +
      + +Once a license has been deployed to a {{site.base_gateway}} node, retrieve it +using the [`/licenses` Admin API endpoint](/gateway/{{page.kong_version}}/licenses/examples). + +If you have purchased a subscription but haven't received a license file, +contact your sales representative. diff --git a/src/gateway/licenses/examples.md b/src/gateway/licenses/examples.md new file mode 100644 index 000000000000..5b42bc6ce49d --- /dev/null +++ b/src/gateway/licenses/examples.md @@ -0,0 +1,201 @@ +--- +title: Licenses Examples +badge: enterprise +--- +
      +Note: The /licenses endpoint does not override standard +license configuration. +
      + +The `/licenses` endpoint provides a way to configure your {{site.base_gateway}} +without using environment variables or placing a plaintext file +in your system directories. In a hybrid mode deployment, the Admin API +`/licenses` endpoint also configures all data planes in the cluster, simplifying +the configuration process. + +## Prerequisites +Remove all standard license configurations from traditional deployments, control +planes, and data planes. + +If you deploy a license using environmental variables or a plaintext +file, this configuration takes precedence over the +`/licenses` endpoint and **does not** communicate any changes to the Admin API. +If you try to use the `/licenses` endpoint while having a license configured +in some other way, the new license will not apply. + +## List all licenses + +Submit the following request: + +```bash +http GET :8001/licenses +``` + +{% navtabs codeblock %} +{% navtab Response when license exists %} +```json +{ + "data": [ + { + "payload": "{\"license\":{\"payload\":{\"admin_seats\":\"1\",\"customer\":\"Example Company, Inc\",\"dataplanes\":\"1\",\"license_creation_date\":\"2017-07-20\",\"license_expiration_date\":\"2017-07-20\",\"license_key\":\"00141000017ODj3AAG_a1V41000004wT0OEAU\",\"product_subscription\":\"Konnect Enterprise\",\"support_plan\":\"None\"},\"signature\":\"6985968131533a967fcc721244a979948b1066967f1e9cd65dbd8eeabe060fc32d894a2945f5e4a03c1cd2198c74e058ac63d28b045c2f1fcec95877bd790e1b\",\"version\":\"1\"}}", + "created_at": 1500508800, + "id": "30b4edb7-0847-4f65-af90-efbed8b0161f", + "updated_at": 1500508800 + }, + ], + "next": null, +} +``` +{% endnavtab %} +{% navtab Response if there is no license %} + +```json +{ + "data": [], + "next": null +} +``` +{% endnavtab %} +{% endnavtabs %} + +## List a license + +Using the ID of the license, submit the following request: + +```bash +http GET :8001/licenses/30b4edb7-0847-4f65-af90-efbed8b0161f +``` + +```json +{ + "created_at": 1500508800, + "id": "30b4edb7-0847-4f65-af90-efbed8b0161f", + "payload": "{\"license\":{\"payload\":{\"admin_seats\":\"1\",\"customer\":\"Example Company, Inc\",\"dataplanes\":\"1\",\"license_creation_date\":\"2017-07-20\",\"license_expiration_date\":\"2017-07-20\",\"license_key\":\"00141000017ODj3AAG_a1V41000004wT0OEAU\",\"product_subscription\":\"Konnect Enterprise\",\"support_plan\":\"None\"},\"signature\":\"6985968131533a967fcc721244a979948b1066967f1e9cd65dbd8eeabe060fc32d894a2945f5e4a03c1cd2198c74e058ac63d28b045c2f1fcec95877bd790e1b\",\"version\":\"1\"}}", + "updated_at": 1500508800 +} +``` + +## Add a license + +### Auto-generated ID + +To generate an ID automatically, submit a `POST` request directly to `/licenses`: + +```bash +http POST :8001/licenses \ + payload='{"license":{"payload":{"admin_seats":"1","customer":"Example Company, Inc","dataplanes":"1","license_creation_date":"2017-07-20","license_expiration_date":"2017-07-20","license_key":"00141000017ODj3AAG_a1V41000004wT0OEAU","product_subscription":"Konnect Enterprise","support_plan":"None"},"signature":"6985968131533a967fcc721244a979948b1066967f1e9cd65dbd8eeabe060fc32d894a2945f5e4a03c1cd2198c74e058ac63d28b045c2f1fcec95877bd790e1b","version":"1"}}' +``` + +Response: +```json +{ + "created_at": 1500508800, + "id": "30b4edb7-0847-4f65-af90-efbed8b0161f", + "payload": "{\"license\":{\"payload\":{\"admin_seats\":\"1\",\"customer\":\"Example Company, Inc\",\"dataplanes\":\"1\",\"license_creation_date\":\"2017-07-20\",\"license_expiration_date\":\"2017-07-20\",\"license_key\":\"00141000017ODj3AAG_a1V41000004wT0OEAU\",\"product_subscription\":\"Konnect Enterprise\",\"support_plan\":\"None\"},\"signature\":\"6985968131533a967fcc721244a979948b1066967f1e9cd65dbd8eeabe060fc32d894a2945f5e4a03c1cd2198c74e058ac63d28b045c2f1fcec95877bd790e1b\",\"version\":\"1\"}}", + "updated_at": 1500508800 +} +``` + +### Manually provided ID + +To create a license with a custom ID, submit a `PUT` request to +`/licenses/`: + +```bash +http PUT :8001/licenses/e8201120-4ee3-43ca-9e92-3fed08b1a15d \ + payload='{"license":{"payload":{"admin_seats":"1","customer":"Example Company, Inc","dataplanes":"1","license_creation_date":"2017-07-20","license_expiration_date":"2017-07-20","license_key":"00141000017ODj3AAG_a1V41000004wT0OEAU","product_subscription":"Konnect Enterprise","support_plan":"None"},"signature":"6985968131533a967fcc721244a979948b1066967f1e9cd65dbd8eeabe060fc32d894a2945f5e4a03c1cd2198c74e058ac63d28b045c2f1fcec95877bd790e1b","version":"1"}}' +``` + +Response: +```json +{ + "created_at": 1500508800, + "id": "e8201120-4ee3-43ca-9e92-3fed08b1a15d", + "payload": "{\"license\":{\"payload\":{\"admin_seats\":\"1\",\"customer\":\"Example Company, Inc\",\"dataplanes\":\"1\",\"license_creation_date\":\"2017-07-20\",\"license_expiration_date\":\"2017-07-20\",\"license_key\":\"00141000017ODj3AAG_a1V41000004wT0OEAU\",\"product_subscription\":\"Konnect Enterprise\",\"support_plan\":\"None\"},\"signature\":\"6985968131533a967fcc721244a979948b1066967f1e9cd65dbd8eeabe060fc32d894a2945f5e4a03c1cd2198c74e058ac63d28b045c2f1fcec95877bd790e1b\",\"version\":\"1\"}}", + "updated_at": 1500508800 +} +``` + +**Note**: If the provided ID exists, the request will perform + an update to the license for the given ID instead of creating a new + `license` entity. + +## Update a license + +To update a license, submit a `PATCH` request to an existing license ID: + +```bash +http PATCH :8001/licenses/30b4edb7-0847-4f65-af90-efbed8b0161f \ + payload='{"license":{"payload":{"admin_seats":"1","customer":"Example Company, Inc","dataplanes":"1","license_creation_date":"2017-07-20","license_expiration_date":"2017-07-21","license_key":"00141000017ODj3AAG_a1V41000004wT0OEAU","product_subscription":"Konnect Enterprise","support_plan":"None"},"signature":"24cc21223633044c15c300be19cacc26ccc5aca0dd9a12df8a7324a1970fe304bc07b8dcd7fb08d7b92e04169313377ae3b550ead653b951bc44cd2eb59f6beb","version":"1"}}' +``` + +Response: +```json +{ + "created_at": 1500595200, + "id": "30b4edb7-0847-4f65-af90-efbed8b0161f", + "payload": "{\"license\":{\"payload\":{\"admin_seats\":\"1\",\"customer\":\"Example Company, Inc\",\"dataplanes\":\"1\",\"license_creation_date\":\"2017-07-20\",\"license_expiration_date\":\"2017-07-21\",\"license_key\":\"00141000017ODj3AAG_a1V41000004wT0OEAU\",\"product_subscription\":\"Konnect Enterprise\",\"support_plan\":\"None\"},\"signature\":\"24cc21223633044c15c300be19cacc26ccc5aca0dd9a12df8a7324a1970fe304bc07b8dcd7fb08d7b92e04169313377ae3b550ead653b951bc44cd2eb59f6beb\",\"version\":\"1\"}}", + "updated_at": 1500595200 +} +``` + +## Generate license report + +To generate a report, submit a `GET` request directly to `/license/report`: + +```bash +http GET :8001/license/report +``` + +{% navtabs codeblock %} +{% navtab Response when license exists %} +```json +{ + "counters": [ + { + "bucket": "2021-12", + "request_count": 0 + } + ], + "db_version": "postgres 9.6.19", + "kong_version": "2.7.0.0", + "license_key": "ASDASDASDASDASDASDASDASDASD_ASDASDA", + "rbac_users": 0, + "services_count": 0, + "system_info": { + "cores": 4, + "hostname": "13b867agsa008", + "uname": "Linux x86_64" + }, + "workspaces_count": 1 +} +``` +{% endnavtab %} +{% navtab Response if there is no license %} + +```json +{ + "counters": [ + { + "bucket": "2021-12", + "request_count": 0 + } + ], + "db_version": "postgres 9.6.19", + "kong_version": "2.7.0.0", + "license_key": "UNLICENSED", + "rbac_users": 0, + "services_count": 0, + "system_info": { + "cores": 4, + "hostname": "13b867agsa008", + "uname": "Linux x86_64" + }, + "workspaces_count": 1 +} +``` +{% endnavtab %} +{% endnavtabs %} + + +[services]: /gateway/{{page.kong_version}}/admin-api/#service-object diff --git a/src/gateway/licenses/index.md b/src/gateway/licenses/index.md new file mode 100644 index 000000000000..561c0b08d1d8 --- /dev/null +++ b/src/gateway/licenses/index.md @@ -0,0 +1,103 @@ +--- +title: Kong Gateway Licensing +badge: enterprise +--- + +{{site.base_gateway}} can be used with or without a license. For Enterprise +functionality, {{site.base_gateway}} enforces the presence and validity of a +{{site.konnect_product_name}} license file. + +| Feature | Free Mode | Enterprise Subscription | +|--------------------|:---------:|:-----------------------:| +| Manager | | | +| Admin API | | | +| Vitals | | | +| Dev Portal | | | +| Enterprise plugins | | | + +## Deploying the license file + +* **Hybrid mode deployment:** The license file only needs to be deployed to +control plane nodes, which distribute the license to the data planes in their +clusters. +* **Traditional deployment with no separate control plane:** License files must +be deployed to each node running {{site.base_gateway}}. + +License file checking is done independently by each node as the Kong process starts; no network connectivity is necessary to execute the license validation process. + +There are multiple ways to configure a license file on a {{site.base_gateway}} node. These are defined below, in the order in which they are checked by Kong: + +1. If present, the contents of the environmental variable `KONG_LICENSE_DATA` are used. +2. Kong will search in the default location `/etc/kong/license.json`. +3. If present, the contents of the file defined by the environment variable `KONG_LICENSE_PATH` is used. +4. Directly deploy a license using the `/licenses` Admin API endpoint. + +In this manner, the license file can be deployed either as a file on the node +filesystem, as an environmental variable, or through the `/licenses` Admin API +endpoint. The simplest method is using the Admin API. + +Note that unlike most other `KONG_*` environmental variables, the +`KONG_LICENSE_DATA` and `KONG_LICENSE_PATH` cannot be defined in-line as part +of any `kong` CLI commands. License file environmental variables must be +exported to the shell in which the Nginx process will run, ahead of the `kong` +CLI tool. + +For more information, see [Deploy Your License](/gateway/{{page.kong_version}}/licenses/deploy). + +## Examining the license data on a Kong Gateway node + +Retrieve license data using the Admin API's `/licenses` endpoint, or through +the Admin GUI in Kong Manager. + +## License expiration + +When a license expires, you will still have access to your {{site.base_gateway}} +and its configuration. Any Enterprise-specific features will be locked, and +the Admin API will not be accessible until the license is either renewed or the +subscription is downgraded to the free mode. + +In the event of a downgrade, the Admin API will be unlocked, but Enterprise +features such Dev Portal, Enterprise plugins, and others will no +longer be accessible. + +### License expiration logs + +{{site.base_gateway}} logs the license expiration date on the following schedule: +* 90 days before: `WARN` log entry once a day +* 30 days before: `ERR` log entry once a day +* At and after expiration: `CRIT` log entry once a day + +## Troubleshooting + +When a valid license file is properly deployed, license file validation is a transparent operation; no additional output or logging data is written or provided. If an error occurs when attempting to validate the license, or the license data is not valid, an error message will be written to the console and logged to the Kong error log, followed by the process quitting. Below are possible error messages and troubleshooting steps to take: + +`license path environment variable not set` +: Neither the `KONG_LICENSE_DATA` nor the `KONG_LICENSE_PATH` environmental variables were defined, and no license file could be opened at the default license location (`/etc/kong/license.json`) + +`internal error` +: An internal error has occurred while attempting to validate the license. Such cases are extremely unlikely; contact Kong support to further troubleshoot. + +`error opening license file` +: The license file defined either in the default location, or using the `KONG_LICENSE_PATH` env variable, could not be opened. Check that the user executing the Nginx process (e.g., the user executing the Kong CLI utility) has permissions to read this file. + +`error reading license file` +: The license file defined either in the default location, or using the `KONG_LICENSE_PATH` env variable, could be opened, but an error occurred while reading. Confirm that the file is not corrupt, that there are no kernel error messages reported (e.g., out of memory conditions, etc). This is a generic error and is extremely unlikely to occur if the file could be opened. + +`could not decode license json` +: The license file data could not be decoded as valid JSON. Confirm that the file is not corrupt and has not been altered since you received it from Kong Inc. Try re-downloading and installing your license file from Kong Inc. +: If you still receive this error after reinstallation, contact Kong support. + +`invalid license format` +: The license file data is missing one or more key/value pairs. Confirm that the file is not corrupt and has not been altered since you received it from Kong Inc. Try re-downloading and installing your license file from Kong Inc. +: If you still receive this error after reinstallation, contact Kong support. + +`validation failed` +: The attempt to verify the payload of the license with the license's signature failed. Confirm that the file is not corrupt and has not been altered since you received it from Kong Inc. Try re-downloading and installing your license file from Kong Inc. +: If you still receive this error after reinstallation, contact Kong support. + +`license expired` +: The system time is past the license's `license_expiration_date`. + +`invalid license expiration date` +: The data in the `license_expiration_date` field is incorrectly formatted. Try re-downloading and installing your license file from Kong Inc. +: If you still receive this error after reinstallation, contact Kong support. diff --git a/src/gateway/licenses/report.md b/src/gateway/licenses/report.md new file mode 100644 index 000000000000..dac8e47ecc2d --- /dev/null +++ b/src/gateway/licenses/report.md @@ -0,0 +1,110 @@ +--- +title: Monitor License Usage +badge: enterprise +--- + +Obtain information about your {{site.base_gateway}} deployment, including license usage and deployment information using the **License Report** module. Share this information with Kong to perform a health-check analysis of product utilization and overall deployment performance to ensure your organization is optimized with the best license and deployment plan for your needs. + +How the license report module works: +* The license report module manually generates a report containing usage and deployment data by sending a request to an endpoint, as defined below. +* Share this report with your Kong representative to perform an analysis of your deployment. + +What the license report module **does not** do: +* The license report module does not automatically generate a report or send any data to any Kong servers. +* The license report module does not track or generate any data other than the data that is returned in the response after you send a request to the endpoint. + +## Generate a License Report +Run the license report module and share the output information with your Kong representative for a deployment analysis. + +**Prerequisites**: You must have Admin privileges to generate a license report. + +To generate a license report, from an HTTP client: + +{% navtabs %} +{% navtab JSON response %} + +For a JSON response, send an HTTP request to the Kong node endpoint +`/license/report`. For example, use this cURL command: + +```bash +curl {ADMIN_API_URL}/license/report +``` + +A JSON response returns, similar to the example below: + +```json +HTTP/1.1 200 OK +Access-Control-Allow-Credentials: true +Access-Control-Allow-Origin: http://localhost:8002 +Connection: keep-alive +Content-Length: 814 +Content-Type: application/json; charset=utf-8 +Date: Mon, 06 Dec 2021 12:04:28 GMT +Server: kong/2.7.0.1-enterprise-edition +Vary: Origin +X-Kong-Admin-Request-ID: R1jmopI6fjkOLdOuPJVLEmGh4sCLMpSY +{ + "counters": [ + { + "bucket": "2021-09", + "request_count": 30 + }, + { + "bucket": "2020-10", + "request_count": 42 + }, + + { + "bucket": "2021-11", + "request_count": 296 + }, + { + "bucket": "2021-12", + "request_count": 58 + }, + { + "bucket": "UNKNOWN", + "request_count": 50 + } + ], + "db_version": "postgres 9.6.24", + "kong_version": "2.7.0.1-enterprise-edition", + "license_key": "KONGLICENSEKEY_NOTVALIDFORREAL_USAGE", + "rbac_users": 0, + "services_count": 27, + "system_info": { + "cores": 6, + "hostname": "akongnode", + "uname": "Linux x86_64" + }, + "workspaces_count":1 +} +``` + +{% endnavtab %} +{% navtab TAR file %} + +For a TAR file, enter the following cURL command to make a call to the +Kong Admin API: + +```bash +curl {ADMIN_API_URL}/license/report -o response.json && tar -cf report-$(date +"%Y_%m_%d_%I_%M_%p").tar response.json +``` + +A license report file is generated and archived to a `*.tar` file. + +{% endnavtab %} +{% endnavtabs %} + +## Report Structure + +Field | Description +------|------------ +`counters` | Counts the number of requests made in a given month.

      • `bucket`: Year and month when the requests were processed. If the value in `bucket` is `UNKNOWN`, then the requests were processed before Kong Gateway 2.7.0.1.
      • `request_count`: Number of requests processed in the given month and year. +`db_version` | The type and version of the datastore Kong Gateway is using. +`kong_version` | The version of the Kong Gateway instance. +`license_key` | An encrypted identifier for the current license key. If no license is present, the field displays as `UNLICENSED`. +`rbac_users` | The number of users registered with through RBAC. +`services_count` | The number of configured services in the Kong Gateway instance. +`system_info` | Displays information about the system running Kong Gateway.

      • `cores`: Number of CPU cores on the node
      • `hostname`: Encrypted system hostname
      • `uname`: Operating system +`workspaces_count` | The number of workspaces configured in the Kong Gateway instance. diff --git a/src/gateway/migrate-ce-to-ke.md b/src/gateway/migrate-ce-to-ke.md new file mode 100644 index 000000000000..b40576c958a6 --- /dev/null +++ b/src/gateway/migrate-ce-to-ke.md @@ -0,0 +1,37 @@ +--- +title: Migrating from Kong Gateway (OSS) to Kong Gateway +toc: true +--- + +Run `kong migrations` commands to migrate from an open-source {{site.base_gateway}} installation to an Enterprise one. + +You can only migrate to a {{site.ee_product_name}} version that +supports the same {{site.ce_product_name}} version. + +## Prerequisites + +{:.warning} +> **Warning:** This action is irreversible, therefore it is strongly + recommended to back up your production data before migrating from + {{site.ce_product_name}} to {{site.ee_product_name}}. + +If running a version of {{site.ce_product_name}} earlier than 3.0.x, +[upgrade to {{site.ce_product_name}} 3.0.x](/gateway/{{page.kong_version}}/upgrade/) before migrating +{{site.ce_product_name}} to {{site.ee_product_name}} 3.0.x. + +## Migration steps + +The following steps guide you through the migration process. + +1. [Download](/gateway/{{page.kong_version}}/install) the {{site.base_gateway}} +3.0.x Enterprise package and configure it to point to the same data store as your +{{site.ce_product_name}} 2.8.x node. The migration command expects the data store +to be up to date on any pending migration: + + ```shell + kong migrations up [-c configuration_file] + kong migrations finish [-c configuration_file] + ``` + +2. Confirm that all of the entities are now available on your + {{site.ee_product_name}} node. diff --git a/src/gateway/plugin-development/access-the-datastore.md b/src/gateway/plugin-development/access-the-datastore.md new file mode 100644 index 000000000000..722db479fbc0 --- /dev/null +++ b/src/gateway/plugin-development/access-the-datastore.md @@ -0,0 +1,69 @@ +--- +title: Accessing the Datastore +book: plugin_dev +chapter: 5 +--- + +Kong interacts with the model layer through classes we refer to as "DAOs". This +chapter will detail the available API to interact with the datastore. + +Kong supports two primary datastores: [Cassandra +{{site.data.kong_latest.dependencies.cassandra}}](http://cassandra.apache.org/) +and [PostgreSQL +{{site.data.kong_latest.dependencies.postgres}}](http://www.postgresql.org/). + +{% include_cached /md/enterprise/cassandra-deprecation.md %} + +## kong.db + +All entities in Kong are represented by: + +- A schema that describes which table the entity relates to in the datastore, + constraints on its fields such as foreign keys, non-null constraints etc. + This schema is a table described in the [plugin configuration]({{page.book.chapters.plugin-configuration}}) + chapter. +- An instance of the `DAO` class mapping to the database currently in use. + This class' methods consume the schema and expose + methods to insert, update, select and delete entities of that type. + +The core entities in Kong are: Services, Routes, Consumers and Plugins. +All of them are accessible as Data Access Objects (DAOs), +through the `kong.db` global singleton: + + +```lua +-- Core DAOs +local services = kong.db.services +local routes = kong.db.routes +local consumers = kong.db.consumers +local plugins = kong.db.plugins +``` + +Both core entities from Kong and custom entities from plugins are +available through `kong.db.*`. + +## The DAO Lua API + +The DAO class is responsible for the operations executed on a given table in +the datastore, generally mapping to an entity in Kong. All the underlying +supported databases (currently Cassandra and Postgres) comply to the same +interface, thus making the DAO compatible with all of them. + +For example, inserting a Service and a Plugin is as easy as: + +```lua +local inserted_service, err = kong.db.services:insert({ + name = "mockbin", + url = "http://mockbin.org", +}) + +local inserted_plugin, err = kong.db.plugins:insert({ + name = "key-auth", + service = inserted_service, +}) +``` + +For a real-life example of the DAO being used in a plugin, see the +[Key-Auth plugin source code](https://github.com/Kong/kong/blob/master/kong/plugins/key-auth/handler.lua). + +[plugin development kit]: /gateway/{{page.kong_version}}/plugin-development/pdk diff --git a/src/gateway/plugin-development/admin-api.md b/src/gateway/plugin-development/admin-api.md new file mode 100644 index 000000000000..8340fc04b7f6 --- /dev/null +++ b/src/gateway/plugin-development/admin-api.md @@ -0,0 +1,168 @@ +--- +title: Extending the Admin API +book: plugin_dev +chapter: 8 +--- + +{:.note} +> **Notes:** +> * This chapter assumes that you have a relative + knowledge of [Lapis](http://leafo.net/lapis/). +> * The Admin API extensions are available only + for HTTP plugins, not Stream plugins. + +Kong can be configured using a REST interface referred to as the [Admin API]. +Plugins can extend it by adding their own endpoints to accommodate custom +entities or other personalized management needs. A typical example of this is +the creation, retrieval, and deletion (commonly referred to as "CRUD +operations") of API keys. + +The Admin API is a [Lapis](http://leafo.net/lapis/) application, and Kong's +level of abstraction makes it easy for you to add endpoints. + +## Module + +``` +kong.plugins..api +``` + +## Add endpoints to the Admin API + +Kong will detect and load your endpoints if they are defined in a module named: + +``` +"kong.plugins..api" +``` + +This module is bound to return a table with one or more entries with the following structure: + +``` lua +{ + [""] = { + schema = , + methods = { + before = function(self) ... end, + on_error = function(self) ... end, + GET = function(self) ... end, + PUT = function(self) ... end, + ... + } + }, + ... +} +``` + +Where: + +- `` should be a string representing a route like `/users` (See [Lapis routes & URL + Patterns](http://leafo.net/lapis/reference/actions.html#routes--url-patterns)) for details. + Notice that the path can contain interpolation parameters, like `/users/:users/new`. +- `` is a schema definition. Schemas for core and custom plugin entities are available + via `kong.db..schema`. The schema is used to parse certain fields according to their + types; for example if a field is marked as an integer, it will be parsed as such when it is + passed to a function (by default form fields are all strings). +- The `methods` subtable contains functions, indexed by a string. + - The `before` key is optional and can hold a function. If present, the function will be executed + on every request that hits `path`, before any other function is invoked. + - One or more functions can be indexed with HTTP method names, like `GET` or `PUT`. These functions + will be executed when the appropriate HTTP method and `path` is matched. If a `before` function is + present on the `path`, it will be executed first. Keep in mind that `before` functions can + use `kong.response.exit` to finish early, effectively cancelling the "regular" http method function. + - The `on_error` key is optional and can hold a function. If present, the function will be executed + when the code from other functions (either from a `before` or a "http method") throws an error. If + not present, then Kong will use a default error handler to return the errors. + +For example: + +``` lua +local endpoints = require "kong.api.endpoints" + +local credentials_schema = kong.db.keyauth_credentials.schema +local consumers_schema = kong.db.consumers.schema + +return { + ["/consumers/:consumers/key-auth"] = { + schema = credentials_schema, + methods = { + GET = endpoints.get_collection_endpoint( + credentials_schema, consumers_schema, "consumer"), + + POST = endpoints.post_collection_endpoint( + credentials_schema, consumers_schema, "consumer"), + }, + }, +} +``` + +This code will create two Admin API endpoints in `/consumers/:consumers/key-auth`, to +obtain (`GET`) and create (`POST`) credentials associated to a given consumer. On this example +the functions are provided by the `kong.api.endpoints` library. + +The `endpoints` module currently contains the default implementation for the most usual CRUD +operations used in Kong. This module provides you with helpers for any insert, retrieve, +update or delete operations and performs the necessary DAO operations and replies with +the appropriate HTTP status codes. It also provides you with functions to retrieve parameters from +the path, such as an Service's name or id, or a Consumer's username or id. + +If `endpoints`-provided are functions not enough, a regular Lua function can be used instead. From there you can use: + +- Several functions provided by the `endpoints` module. +- All the functionality provided by the [PDK](/gateway/{{page.kong_version}}/plugin-development/pdk) +- The `self` parameter, which is the [Lapis request object](http://leafo.net/lapis/reference/actions.html#request-object). +- And of course you can `require` any Lua modules if needed. Make sure they are compatible with OpenResty if you choose this route. + +``` lua +local endpoints = require "kong.api.endpoints" + +local credentials_schema = kong.db.keyauth_credentials.schema +local consumers_schema = kong.db.consumers.schema + +return { + ["/consumers/:consumers/key-auth/:keyauth_credentials"] = { + schema = credentials_schema, + methods = { + before = function(self, db, helpers) + local consumer, _, err_t = endpoints.select_entity(self, db, consumers_schema) + if err_t then + return endpoints.handle_error(err_t) + end + if not consumer then + return kong.response.exit(404, { message = "Not found" }) + end + + self.consumer = consumer + + if self.req.method ~= "PUT" then + local cred, _, err_t = endpoints.select_entity(self, db, credentials_schema) + if err_t then + return endpoints.handle_error(err_t) + end + + if not cred or cred.consumer.id ~= consumer.id then + return kong.response.exit(404, { message = "Not found" }) + end + self.keyauth_credential = cred + self.params.keyauth_credentials = cred.id + end + end, + GET = endpoints.get_entity_endpoint(credentials_schema), + PUT = function(self, db, helpers) + self.args.post.consumer = { id = self.consumer.id } + return endpoints.put_entity_endpoint(credentials_schema)(self, db, helpers) + end, + }, + }, +} +``` + +On the previous example, the `/consumers/:consumers/key-auth/:keyauth_credentials` path gets +three functions: +- The `before` function is a custom Lua function which uses several `endpoints`-provided utilities + (`endpoints.handle_error`) as well as PDK functions (`kong.response.exit`). It also populates + `self.consumer` for the subsequent functions to use. +- The `GET` function is built entirely using `endpoints`. This is possible because the `before` has + "prepared" things in advance, like `self.consumer`. +- The `PUT` function populates `self.args.post.consumer` before calling the `endpoints`-provided + `put_entity_endpoint` function. + +[Admin API]: /gateway/{{page.kong_version}}/admin-api/ diff --git a/src/gateway/plugin-development/configuration.md b/src/gateway/plugin-development/configuration.md new file mode 100644 index 000000000000..15cb13bf0cbc --- /dev/null +++ b/src/gateway/plugin-development/configuration.md @@ -0,0 +1,380 @@ +--- +title: Plugin Configuration +book: plugin_dev +chapter: 4 +--- + +Most of the time, it makes sense for your plugin to be configurable to answer +all of your users' needs. Your plugin's configuration is stored in the +data store for Kong to retrieve it and pass it to your +[handler.lua]({{page.book.chapters.custom-logic}}) methods when the plugin is +being executed. + +The configuration consists of a Lua table in Kong that we call a **schema**. It +contains key/value properties that the user will set when enabling the plugin +through the [Admin API]. Kong provides you with a way of validating the user's +configuration for your plugin. + +Your plugin's configuration is being verified against your schema when a user +issues a request to the [Admin API] to enable or update a plugin on a given +Service, Route, or Consumer. + +For example, a user performs the following request: + +```bash +curl -X POST http://kong:8001/services//plugins \ + -d "name=my-custom-plugin" \ + -d "config.foo=bar" +``` + +If all properties of the `config` object are valid according to your schema, +then the API would return `201 Created` and the plugin would be stored in the +database along with its configuration: +```lua +{ + foo = "bar" +} + ``` + +If the configuration is not valid, the Admin API would return `400 Bad Request` +and the appropriate error messages. + +## Module + +``` +kong.plugins..schema +``` + +## schema.lua specifications + +This module is to return a Lua table with properties that will define how your +plugins can later be configured by users. Available properties are: + +| Property name | Lua type | Description +|-----------------|------------|------------ +| `name` | `string` | Name of the plugin, e.g. `key-auth`. +| `fields` | `table` | Array of field definitions. +| `entity_checks` | `function` | Array of conditional entity level validation checks. + + +All the plugins inherit some default fields which are: + +| Field name | Lua type | Description +|-----------------|------------|------------ +| `id` | `string` | Auto-generated plugin id. +| `name` | `string` | Name of the plugin, e.g. `key-auth`. +| `created_at` | `number` | Creation time of the plugin configuration (seconds from epoch). +| `route` | `table` | Route to which plugin is bound, if any. +| `service` | `table` | Service to which plugin is bound, if any. +| `consumer` | `table` | Consumer to which plugin is bound when possible, if any. +| `protocols` | `table` | The plugin will run on specified protocol(s). +| `enabled` | `boolean` | Whether or not the plugin is enabled. +| `tags` | `table` | The tags for the plugin. + +In most of the cases you can ignore most of those and use the defaults. Or let the user +specify value when enabling a plugin. + +Here is an example of a potential `schema.lua` file (with some overrides applied): + +```lua +local typedefs = require "kong.db.schema.typedefs" + + +return { + name = "", + fields = { + { + -- this plugin will only be applied to Services or Routes + consumer = typedefs.no_consumer + }, + { + -- this plugin will only run within Nginx HTTP module + protocols = typedefs.protocols_http + }, + { + config = { + type = "record", + fields = { + -- Describe your plugin's configuration's schema here. + }, + }, + }, + }, + entity_checks = { + -- Describe your plugin's entity validation rules + }, +} +``` + +## Describing your configuration schema + +The `config.fields` property of your `schema.lua` file describes the schema of your +plugin's configuration. It is a flexible array of field definitions where each field +is a valid configuration property for your plugin, describing the rules for that +property. For example: + +```lua +{ + name = "", + fields = { + config = { + type = "record", + fields = { + { + some_string = { + type = "string", + required = false, + }, + }, + { + some_boolean = { + type = "boolean", + default = false, + }, + }, + { + some_array = { + type = "array", + elements = { + type = "string", + one_of = { + "GET", + "POST", + "PUT", + "DELETE", + }, + }, + }, + }, + }, + }, + }, +} +``` + +Here is the list of some common (not all) accepted rules for a property (see the fields table above for examples): + +| Rule | Description +|--------------------|---------------------------- +| `type` | The type of a property. +| `required` | Whether or not the property is required +| `default` | The default value for the property when not specified +| `elements` | Field definition of `array` or `set` elements. +| `keys` | Field definition of `map` keys. +| `values` | Field definition of `map` values. +| `fields` | Field definition(s) of `record` fields. + +There are many more, but the above are commonly used. + +You can also add field validators, to mention a few: + +| Rule | Description +|--------------------|---------------------------- +| `between` | Checks that the input number is between allowed values. +| `eq` | Checks the equality of the input to allowed value. +| `ne` | Checks the inequality of the input to allowed value. +| `gt` | Checks that the number is greater than given value. +| `len_eq` | Checks that the input string length is equal to the given value. +| `len_min` | Checks that the input string length is at least the given value. +| `len_max` | Checks that the input string length is at most the given value. +| `match` | Checks that the input string matches the given Lua pattern. +| `not_match` | Checks that the input string doesn't match the given Lua pattern. +| `match_all` | Checks that the input string matches all the given Lua patterns. +| `match_none` | Checks that the input string doesn't match any of the given Lua patterns. +| `match_any` | Checks that the input string matches any of the given Lua patterns. +| `starts_with` | Checks that the input string starts with a given value. +| `one_of` | Checks that the input string is one of the accepted values. +| `contains` | Checks that the input array contains the given value. +| `is_regex` | Checks that the input string is a valid regex pattern. +| `custom_validator` | A custom validation function written in Lua. + +There are some additional validators, but you get a good idea how you can specify validation +rules on fields from the above table. + + +### Examples + +This `schema.lua` file is for the [key-auth](/hub/kong-inc/key-auth/) plugin: + +```lua +-- schema.lua +local typedefs = require "kong.db.schema.typedefs" + + +return { + name = "key-auth", + fields = { + { + consumer = typedefs.no_consumer + }, + { + protocols = typedefs.protocols_http + }, + { + config = { + type = "record", + fields = { + { + key_names = { + type = "array", + required = true, + elements = typedefs.header_name, + default = { + "apikey", + }, + }, + }, + { + hide_credentials = { + type = "boolean", + default = false, + }, + }, + { + anonymous = { + type = "string", + uuid = true, + }, + }, + { + key_in_body = { + type = "boolean", + default = false, + }, + }, + { + run_on_preflight = { + type = "boolean", + default = true, + }, + }, + }, + }, + }, + }, +} +``` + +Hence, when implementing the `access()` function of your plugin in +[handler.lua]({{page.book.chapters.custom-logic}}) and given that the user +enabled the plugin with the default values, you'd have access to: + +```lua +-- handler.lua + +local CustomHandler = { + VERSION = "1.0.0", + PRIORITY = 10, +} + +local kong = kong + +function CustomHandler:access(config) + + kong.log.inspect(config.key_names) -- { "apikey" } + kong.log.inspect(config.hide_credentials) -- false +end + + +return CustomHandler +``` + +Note that the above example uses the +[kong.log.inspect](/gateway/{{page.kong_version}}/plugin-development/pdk/kong.log/#kong_log_inspect) +function of the [Plugin Development Kit] to print out those values to the Kong +logs. + +--- + +A more complex example, which could be used for an eventual logging plugin: + +```lua +-- schema.lua +local typedefs = require "kong.db.schema.typedefs" + + +return { + name = "my-custom-plugin", + fields = { + { + config = { + type = "record", + fields = { + { + environment = { + type = "string", + required = true, + one_of = { + "production", + "development", + }, + }, + }, + { + server = { + type = "record", + fields = { + { + host = typedefs.host { + default = "example.com", + }, + }, + { + port = { + type = "number", + default = 80, + between = { + 0, + 65534 + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, +} +``` + +Such a configuration will allow a user to post the configuration to your plugin +as follows: + +```bash +curl -X POST http://kong:8001/services//plugins \ + -d "name=my-custom-plugin" \ + -d "config.environment=development" \ + -d "config.server.host=http://localhost" +``` + +And the following will be available in +[handler.lua]({{page.book.chapters.custom-logic}}): + +```lua +-- handler.lua + +local CustomHandler = { + VERSION = "1.0.0", + PRIORITY = 10, +} + +local kong = kong + +function CustomHandler:access(config) + + kong.log.inspect(config.environment) -- "development" + kong.log.inspect(config.server.host) -- "http://localhost" + kong.log.inspect(config.server.port) -- 80 +end + + +return CustomHandler +``` + +You can also see a real-world example of schema in [the Key-Auth plugin source code]. + +[Admin API]: /gateway/{{page.kong_version}}/admin-api +[Plugin Development Kit]: /gateway/{{page.kong_version}}/plugin-development/pdk +[the Key-Auth plugin source code]: https://github.com/Kong/kong/blob/master/kong/plugins/key-auth/schema.lua diff --git a/src/gateway/plugin-development/custom-entities.md b/src/gateway/plugin-development/custom-entities.md new file mode 100644 index 000000000000..0701060af619 --- /dev/null +++ b/src/gateway/plugin-development/custom-entities.md @@ -0,0 +1,677 @@ +--- +title: Storing Custom Entities +book: plugin_dev +chapter: 6 +--- + +While not all plugins need it, your plugin might need to store more than +its configuration in the database. In that case, Kong provides you with +an abstraction on top of its primary datastores which allows you to store +custom entities. + +As explained in the [previous chapter]({{page.book.previous.url}}), Kong interacts +with the model layer through classes we refer to as "DAOs", and available on a +singleton often referred to as the "DAO Factory". This chapter will explain how +to to provide an abstraction for your own entities. + +## Modules + +``` +kong.plugins..daos +kong.plugins..migrations.init +kong.plugins..migrations.000_base_ +kong.plugins..migrations.001__to_ +kong.plugins..migrations.002__to_ +``` + +## Create the migrations folder + +Once you have defined your model, you must create your migration modules which +will be executed by Kong to create the table in which your records of your +entity will be stored. + + +{% include_cached /md/enterprise/cassandra-deprecation.md %} + + +If your plugin is intended to support both Cassandra and Postgres, then both +migrations must be written. + +If your plugin doesn't have it already, you should add a `/migrations` +folder to it. If there is no `init.lua` file inside already, you should create one. +This is where all the migrations for your plugin will be referenced. + +The initial version of your `migrations/init.lua` file will point to a single migration. + +In this case we have called it `000_base_my_plugin`. + +``` lua +-- `migrations/init.lua` +return { + "000_base_my_plugin", +} +``` + +This means that there will be a file in `/migrations/000_base_my_plugin.lua` +containing the initial migrations. We'll see how this is done in a minute. + +## Add a new migration to an existing plugin + +Sometimes it is necessary to introduce changes after a version of a plugin has already been +released. A new functionality might be needed. A database table row might need changing. + +When this happens, *you must* create a new migrations file. You *must not* of modify the +existing migration files once they are published (you can still make them more robust and +bulletproof if you want, e.g. always try to write the migrations reentrant). + +While there is no strict rule for naming your migration files, there is a convention that the +initial one is prefixed by `000`, the next one by `001`, and so on. + +Following with our previous example, if we wanted to release a new version of the plugin with +changes in the database (for example, a table was needed called `foo`) we would insert it by +adding a file called `/migrations/001_100_to_110.lua`, and referencing it on the +migrations init file like so (where `100` is the previous version of the plugin `1.0.0` and +`110` is the version to which plugin is migrated to `1.1.0`: + + +``` lua +-- `/migrations/init.lua` +return { + "000_base_my_plugin", + "001_100_to_110", +} +``` + +## Migration file syntax + + +{% include_cached /md/enterprise/cassandra-deprecation.md %} + +While Kong's core migrations support both Postgres and Cassandra, custom plugins +can choose to support either both of them or just one. + +A migration file is a Lua file which returns a table with the following structure: + +``` lua +-- `/migrations/000_base_my_plugin.lua` +return { + postgresql = { + up = [[ + CREATE TABLE IF NOT EXISTS "my_plugin_table" ( + "id" UUID PRIMARY KEY, + "created_at" TIMESTAMP WITHOUT TIME ZONE, + "col1" TEXT + ); + + DO $$ + BEGIN + CREATE INDEX IF NOT EXISTS "my_plugin_table_col1" + ON "my_plugin_table" ("col1"); + EXCEPTION WHEN UNDEFINED_COLUMN THEN + -- Do nothing, accept existing state + END$$; + ]], + }, + + cassandra = { + up = [[ + CREATE TABLE IF NOT EXISTS my_plugin_table ( + id uuid PRIMARY KEY, + created_at timestamp, + col1 text + ); + + CREATE INDEX IF NOT EXISTS ON my_plugin_table (col1); + ]], + } +} + +-- `/migrations/001_100_to_110.lua` +return { + postgresql = { + up = [[ + DO $$ + BEGIN + ALTER TABLE IF EXISTS ONLY "my_plugin_table" ADD "cache_key" TEXT UNIQUE; + EXCEPTION WHEN DUPLICATE_COLUMN THEN + -- Do nothing, accept existing state + END; + $$; + ]], + teardown = function(connector, helpers) + assert(connector:connect_migrations()) + assert(connector:query([[ + DO $$ + BEGIN + ALTER TABLE IF EXISTS ONLY "my_plugin_table" DROP "col1"; + EXCEPTION WHEN UNDEFINED_COLUMN THEN + -- Do nothing, accept existing state + END$$; + ]]) + end, + }, + + cassandra = { + up = [[ + ALTER TABLE my_plugin_table ADD cache_key text; + CREATE INDEX IF NOT EXISTS ON my_plugin_table (cache_key); + ]], + teardown = function(connector, helpers) + assert(connector:connect_migrations()) + assert(connector:query("ALTER TABLE my_plugin_table DROP col1")) + end, + } +} +``` + +If a plugin only supports Postgres or Cassandra, only the section for one strategy is +needed. Each strategy section has two parts, `up` and `teardown`. + +* `up` is an optional string of raw SQL/CQL statements. Those statements will be executed + when `kong migrations up` is executed. +* `teardown` is an optional Lua function, which takes a `connector` parameter. Such connector + can invoke the `query` method to execute SQL/CQL queries. Teardown is triggered by + `kong migrations finish` + +It is recommended that all the non-destructive operations, such as creation of new tables and +addition of new records is done on the `up` sections, while destructive operations (such as +removal of data, changing row types, insertion of new data) is done on the `teardown` sections. + +In both cases, it is recommended that all the SQL/CQL statements are written so that they are +as reentrant as possible. `DROP TABLE IF EXISTS` instead of `DROP TABLE`, +`CREATE INDEX IF NOT EXIST` instead of `CREATE INDEX`, etc. If a migration fails for some +reason, it is expected that the first attempt at fixing the problem will be simply +re-running the migrations. + +While Postgres does, Cassandra does not support constraints such as "NOT +NULL", "UNIQUE" or "FOREIGN KEY", but Kong provides you with such features when +you define your model's schema. Bear in mind that this schema will be the same +for both Postgres and Cassandra, hence, you might trade-off a pure SQL schema +for one that works with Cassandra too. + +**IMPORTANT**: if your `schema` uses a `unique` constraint, then Kong will +enforce it for Cassandra, but for Postgres you must set this constraint in +the migrations. + +To see a real-life example, give a look at the [Key-Auth plugin migrations](https://github.com/Kong/kong/tree/master/kong/plugins/key-auth/migrations/). + + +## Define a schema + +The first step to using custom entities in a custom plugin is defining one +or more *schemas*. + +A schema is a Lua table which describes entities. There's structural information +like how are the different fields of the entity named and what are their types, +which is similar to the fields describing your [plugin +configuration]({{page.book.chapters.plugin-configuration}})). +Compared to plugin configuration schemas, custom entity schemas require +additional metadata (e.g. which field, or fields, constitute the entities' +primary key). + +Schemas are to be defined in a module named: + +``` +kong.plugins..daos +``` + +Meaning that there should be a file called `/daos.lua` inside your +plugin folder. The `daos.lua` file should return a table containing one or more +schemas. For example: + +```lua +-- daos.lua +local typedefs = require "kong.db.schema.typedefs" + + +return { + -- this plugin only results in one custom DAO, named `keyauth_credentials`: + { + name = "keyauth_credentials", -- the actual table in the database + endpoint_key = "key", + primary_key = { "id" }, + cache_key = { "key" }, + generate_admin_api = true, + admin_api_name = "key-auths", + admin_api_nested_name = "key-auth", + fields = { + { + -- a value to be inserted by the DAO itself + -- (think of serial id and the uniqueness of such required here) + id = typedefs.uuid, + }, + { + -- also interted by the DAO itself + created_at = typedefs.auto_timestamp_s, + }, + { + -- a foreign key to a consumer's id + consumer = { + type = "foreign", + reference = "consumers", + default = ngx.null, + on_delete = "cascade", + }, + }, + { + -- a unique API key + key = { + type = "string", + required = false, + unique = true, + auto = true, + }, + }, + }, + }, +} +``` + +This example `daos.lua` file introduces a single schema called `keyauth_credentials`. + +Here is a description of some top-level properties: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameTypeDescription
      namestring (required)It will be used to determine the DAO name (kong.db.[name]).
      primary_keytable (required) + Field names forming the entity's primary key. + Schemas support composite keys, even if most Kong core entities currently use an UUID named + id. If you are using Cassandra and need a composite key, it should have the same + fields as the partition key. +
      endpoint_keystring (optional) + The name of the field used as an alternative identifier on the Admin API. + On the example above, key is the endpoint_key. This means that a credential with + id = 123 and key = "foo" could be referenced as both + /keyauth_credentials/123 and /keyauth_credentials/foo. +
      cache_keytable (optional) + Contains the name of the fields used for generating the cache_key, a string which must + unequivocally identify the entity inside Kong's cache. A unique field, like key in your example, + is usually good candidate. In other cases a combination of several fields is preferable. +
      generate_admin_apiboolean (optional) + Whether to auto-generate admin api for the entity or not. By default the admin api is generated for all + daos, including custom ones. If you want to create a fully customized admin api for the dao or + want to disable auto-generation for the dao altogether, set this option to false. +
      admin_api_nameboolean (optional) + When generate_admin_api is enabled the admin api auto-generator uses the name + to derive the collection urls for the auto-generated admin api. Sometimes you may want to name the + collection urls differently from the name. E.g. with DAO keyauth_credentials + we actually wanted the auto-generator to generate endpoints for this dao with alternate and more + url-friendly name key-auths, e.g. http://<KONG_ADMIN>/key-auths instead of + http://<KONG_ADMIN>/keyauth_credentials). +
      admin_api_nested_nameboolean (optional) + Similar to admin_api_name the admin_api_nested_name specifies the name for + a dao that admin api auto-generator creates in nested contexts. You only need to use this parameter + if you are not happy with name or admin_api_name. Kong for legacy reasons + have urls like http://<KONG_ADMIN>/consumers/john/key-auth where key-auth + does not follow plural form of http://<KONG_ADMIN>/key-auths. admin_api_nested_name + enables you to specify different name in those cases. +
      fieldstable + Each field definition is a table with a single key, which is the field's name. The table value is + a subtable containing the field's attributes, some of which will be explained below. +
      + +Many field attributes encode *validation rules*. When attempting to insert or update entities using +the DAO, these validations will be checked, and an error returned if the provided input doesn't conform +to them. + +The `typedefs` variable (obtained by requiring `kong.db.schema.typedefs`) is a table containing +a lot of useful type definitions and aliases, including `typedefs.uuid`, the most usual type for the primary key, +and `typedefs.auto_timestamp_s`, for `created_at` fields. It is used extensively when defining fields. + +Here's a non-exhaustive explanation of some of the field attributes available: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Attribute nametypeDescription
      typestring + Schemas support the following scalar types: "string", "integer", "number" and + "boolean". Compound types like "array", "record", or "set" are + also supported.

      + + In additon to these values, the type attribute can also take the special "foreign" value, + which denotes a foreign relationship.

      + + Each field will need to be backed by database fields of appropriately similar types, created via migrations.

      + + type is the only required attribute for all field definitions. +
      defaultany (matching with type attribute) + Specifies the value the field will have when attempting to insert it, if no value was provided. + Default values are always set via Lua, never by the underlying database. It is thus not recommended to set + any default values on fields in migrations. +
      requiredboolean + When set to true on a field, an error will be thrown when attempting to insert an entity lacking a value + for said field (unless the field in question has a default value). +
      uniqueboolean +

      When set to true on a field, an error will be thrown when attempting to insert an entity on the database, + but another entity already has the given value on said field.

      + +

      This attribute must be backed up by declaring fields as UNIQUE in migrations when using + PostgreSQL. The Cassandra strategy does a check in Lua before attempting inserts, so it doesn't require any special treatment. +

      +
      autoboolean + When attempting to insert an entity without providing a value for this a field where auto is set to true, +

      +
        +
      • If type == "uuid", the field will take a random UUID as value.
      • +
      • If type == "string", the field will take a random string.
      • +
      • If the field name is created_at or updated_at, the field will take the current time when + inserting / updating, as appropriate.
      • +
      +
      referencestringRequired for fields of type foreign. The given string must be the name of an existing schema, + to which the foreign key will "point to". This means that if a schema B has a foreign key pointing to schema A, + then A needs to be loaded before B. +
      on_deletestring + Optional and exclusive for fields of type foreign. It dictates what must happen + with entities linked by a foreign key when the entity being referenced is deleted. It can have three possible + values:

      + +
        +
      • "cascade": When the linked entity is deleted, all the dependent entities must also be deleted.
      • +
      • "null": When the linked entity is deleted, all the dependent entities will have their foreign key + field set to null.
      • +
      • "restrict": Attempting to delete an entity with linked entities will result in an error.
      • +
      + +

      + In Cassandra this is handled with pure Lua code, but in PostgreSQL it will be necessary to declare the references + as ON DELETE CASCADE/NULL/RESTRICT in a migration. +
      + + +To learn more about schemas, see: + +* The source code of [typedefs.lua](https://github.com/Kong/kong/blob/release/3.0.x/kong/db/schema/typedefs.lua) + to get an idea of what's provided there by default. +* [The Core Schemas](https://github.com/Kong/kong/tree/release/3.0.x/kong/db/schema/entities) + to see examples of some other field attributes not discussed here. +* [All the `daos.lua` files for embedded plugins](https://github.com/search?utf8=%E2%9C%93&q=repo%3Akong%2Fkong+path%3A%2Fkong%2Fplugins+filename%3Adaos.lua), + especially [the key-auth one](https://github.com/Kong/kong/blob/release/3.0.x/kong/plugins/key-auth/daos.lua), + which was used for this guide as an example. + + +## The custom DAO + +The schemas are not used directly to interact with the database. Instead, a DAO +is built for each valid schema. A DAO takes the name of the schema it wraps, and is +accessible through the `kong.db` interface. + +For the example schema above, the DAO generated would be available for plugins +via `kong.db.keyauth_credentials`. + +### Select an entity + +``` lua +local entity, err, err_t = kong.db.:select(primary_key) +``` + +Attempts to find an entity in the database and return it. Three things can happen: + +* The entity was found. In this case, it is returned as a regular Lua table. +* An error occurred - for example the connection with the database was lost. In that + case the first returned value will be `nil`, the second one will be a string + describing the error, and the last one will be the same error in table form. +* An error does not occur but the entity is not found. Then the function will + just return `nil`, with no error. + +Example of usage: + +``` lua +local entity, err = kong.db.keyauth_credentials:select({ + id = "c77c50d2-5947-4904-9f37-fa36182a71a9" +}) + +if err then + kong.log.err("Error when inserting keyauth credential: " .. err) + return nil +end + +if not entity then + kong.log.err("Could not find credential.") + return nil +end +``` + +### Iterate over all the entities + +``` lua +for entity, err on kong.db.:each(entities_per_page) do + if err then + ... + end + ... +end +``` + +This method efficiently iterates over all the entities in the database by making paginated +requests. The `entities_per_page` parameter, which defaults to `100`, controls how many +entities per page are returned. + +On each iteration, a new `entity` will be returned or, if there is any error, the `err` +variable will be filled up with an error. The recommended way to iterate is checking `err` first, +and otherwise assume that `entity` is present. + +Example of usage: + +``` lua +for credential, err on kong.db.keyauth_credentials:each(1000) do + if err then + kong.log.err("Error when iterating over keyauth credentials: " .. err) + return nil + end + + kong.log("id: " .. credential.id) +end +``` + +This example iterates over the credentials in pages of 1000 items, logging their ids unless +an error happens. + +### Insert an entity + +``` lua +local entity, err, err_t = kong.db.:insert() +``` + +Inserts an entity in the database, and returns a copy of the inserted entity, or +`nil`, an error message (a string) and a table describing the error in table form. + +When the insert is successful, the returned entity contains the extra values produced by +`default` and `auto`. + +The following example uses the `keyauth_credentials` DAO to insert a credential for a given +Consumer, setting its `key` to `"secret"`. Notice the syntax for referencing foreign keys. + +``` lua +local entity, err = kong.db.keyauth_credentials:insert({ + consumer = { id = "c77c50d2-5947-4904-9f37-fa36182a71a9" }, + key = "secret", +}) + +if not entity then + kong.log.err("Error when inserting keyauth credential: " .. err) + return nil +end +``` + +The returned entity, assuming no error happened will have `auto`-filled fields, like `id` and `created_at`. + +### Update an entity + +``` lua +local entity, err, err_t = kong.db.:update(primary_key, ) +``` + +Updates an existing entity, provided it can be found using the provided primary key and a set of values. + +The returned entity will be the entity after the update takes place, or `nil` + an error message + an error table. + +The following example modifies the `key` field of an existing credential given the credential's id: + +``` lua +local entity, err = kong.db.keyauth_credentials:update( + { id = "2b6a2022-770a-49df-874d-11e2bf2634f5" }, + { key = "updated_secret" }, +) + +if not entity then + kong.log.err("Error when updating keyauth credential: " .. err) + return nil +end +``` + +Notice how the syntax for specifying a primary key is similar to the one used to specify a foreign key. + +### Upsert an entity + +``` lua +local entity, err, err_t = kong.db.:upsert(primary_key, ) +``` + +`upsert` is a mixture of `insert` and `update`: + +* When the provided `primary_key` identifies an existing entity, it works like `update`. +* When the provided `primary_key` does not identify an existing entity, it works like `insert` + +Given this code: + +``` lua +local entity, err = kong.db.keyauth_credentials:upsert( + { id = "2b6a2022-770a-49df-874d-11e2bf2634f5" }, + { consumer = { id = "a96145fb-d71e-4c88-8a5a-2c8b1947534c" } } +) + +if not entity then + kong.log.err("Error when upserting keyauth credential: " .. err) + return nil +end +``` + +Two things can happen: + +* If a credential with id `2b6a2022-770a-49df-874d-11e2bf2634f5` exists, + then this code will attempt to set its Consumer to the provided one. +* If the credential does not exist, then this code is attempting to create + a new credential, with the given id and Consumer. + +### Delete an entity + +``` lua +local ok, err, err_t = kong.db.:delete(primary_key) +``` + +Attempts to delete the entity identified by `primary_key`. It returns `true` +if the entity *doesn't exist* after calling this method, or `nil` + error + +error table if an error is detected. + +Notice that calling `delete` will succeed if the entity didn't exist *before +calling it*. This is for performance reasons - we want to avoid doing a +read-before-delete if we can avoid it. If you want to do this check, you +must do it manually, by checking with `select` before invoking `delete`. + +Example: + +``` lua +local ok, err = kong.db.keyauth_credentials:delete({ + id = "2b6a2022-770a-49df-874d-11e2bf2634f5" +}) + +if not ok then + kong.log.err("Error when deleting keyauth credential: " .. err) + return nil +end +``` + +## Cache custom entities + +Sometimes custom entities are required on every request/response, which in turn +triggers a query on the datastore every time. This is very inefficient because +querying the datastore adds latency and slows the request/response down, and +the resulting increased load on the datastore could affect the datastore +performance itself and, in turn, other Kong nodes. + +When a custom entity is required on every request/response it is good practice +to cache it in-memory by leveraging the in-memory cache API provided by Kong. + +The next chapter will focus on caching custom entities, and invalidating them +when they change in the datastore: [Caching custom entities]({{page.book.next.url}}). + +[Admin API]: /gateway/{{page.kong_version}}/admin-api/ +[Plugin Development Kit]: /gateway/{{page.kong_version}}/plugin-development/pdk diff --git a/src/gateway/plugin-development/custom-logic.md b/src/gateway/plugin-development/custom-logic.md new file mode 100644 index 000000000000..08044fb77805 --- /dev/null +++ b/src/gateway/plugin-development/custom-logic.md @@ -0,0 +1,533 @@ +--- +title: Implementing Custom Logic +book: plugin_dev +chapter: 3 +--- + +{:.note} +> **Note**: This chapter assumes that you are familiar with +[Lua](http://www.lua.org/). + +A {{site.base_gateway}} plugin allows you to inject custom logic (in Lua) at several +entry-points in the life-cycle of a request/response or a tcp stream +connection as it is proxied by {{site.base_gateway}}. To do so, the file +`kong.plugins..handler` must return a table with one or +more functions with predetermined names. Those functions will be +invoked by {{site.base_gateway}} at different phases when it processes traffic. + +The first parameter they take is always `self`. All functions except `init_worker` +can receive a second parameter which is a table with the plugin configuration. + +## Module + +``` +kong.plugins..handler +``` + +## Available contexts + +If you define any of the following functions in your `handler.lua` +file you'll implement custom logic at various entry-points +of {{site.base_gateway}}'s execution life-cycle: + +- **[HTTP Module]** *is used for plugins written for HTTP/HTTPS requests* + +| Function name | Phase | Request Protocol | Description +|---------------------|-------------------|-------------------------|------------ +| `init_worker` | [init_worker] | * | Executed upon every Nginx worker process's startup. +| `certificate` | [ssl_certificate] | `https`, `grpcs`, `wss` | Executed during the SSL certificate serving phase of the SSL handshake. +| `rewrite` | [rewrite] | * | Executed for every request upon its reception from a client as a rewrite phase handler.
      In this phase, neither the `Service` nor the `Consumer` have been identified, hence this handler will only be executed if the plugin was configured as a global plugin. +| `access` | [access] | `http(s)`, `grpc(s)`, `ws(s)` | Executed for every request from a client and before it is being proxied to the upstream service. +| `ws_handshake` | [access] | `ws(s)` | Executed for every request to a WebSocket service just before completing the WebSocket handshake. +| `response` | [access] | `http(s)`, `grpc(s)` | Replaces both `header_filter()` and `body_filter()`. Executed after the whole response has been received from the upstream service, but before sending any part of it to the client. +| `header_filter` | [header_filter] | `http(s)`, `grpc(s)` | Executed when all response headers bytes have been received from the upstream service. +| `ws_client_frame` | [content] | `ws(s)` | Executed for each WebSocket message received from the client. +| `ws_upstream_frame` | [content] | `ws(s)` | Executed for each WebSocket message received from the upstream service. +| `body_filter` | [body_filter] | `http(s)`, `grpc(s)` | Executed for each chunk of the response body received from the upstream service. Since the response is streamed back to the client, it can exceed the buffer size and be streamed chunk by chunk. This function can be called multiple times if the response is large. See the [lua-nginx-module] documentation for more details. +| `log` | [log] | `http(s)`, `grpc(s)` | Executed when the last response byte has been sent to the client. +| `ws_close` | [log] | `ws(s)` | Executed after the WebSocket connection has been terminated. + +{:.note} +> **Note:** If a module implements the `response` function, {{site.base_gateway}} will automatically activate the "buffered proxy" mode, as if the [`kong.service.request.enable_buffering()` function][enable_buffering] had been called. Because of a current Nginx limitation, this doesn't work for HTTP/2 or gRPC upstreams. + +To reduce unexpected behaviour changes, {{site.base_gateway}} does not start if a plugin implements both `response` and either `header_filter` or `body_filter`. + +- **[Stream Module]** *is used for Plugins written for TCP and UDP stream connections* + +| Function name | Phase | Description +|-----------------|------------------------------------------------------------------------------|------------ +| `init_worker` | [init_worker] | Executed upon every Nginx worker process's startup. +| `preread` | [preread] | Executed once for every connection. +| `log` | [log](https://github.com/openresty/stream-lua-nginx-module#log_by_lua_block) | Executed once for each connection after it has been closed. +| `certificate` | [ssl_certificate] | Executed during the SSL certificate serving phase of the SSL handshake. + +All of those functions, except `init_worker`, take one parameter which is given +by {{site.base_gateway}} upon its invocation: the configuration of your plugin. This parameter +is a Lua table, and contains values defined by your users, according to your +plugin's schema (described in the `schema.lua` module). More on plugins schemas +in the [next chapter]({{page.book.next.url}}). + +Note that UDP streams don't have real connections. {{site.base_gateway}} will consider all +packets with the same origin and destination host and port as a single +connection. After a configurable time without any packet, the connection is +considered closed and the `log` function is executed. + +## handler.lua specifications + +{{site.base_gateway}} processes requests in **phases**. A plugin is a piece of code that gets +activated by {{site.base_gateway}} as each phase is executed while the request gets proxied. + +Phases are limited in what they can do. For example, the `init_worker` phase +does not have access to the `config` parameter because that information isn't +available when kong is initializing each worker. + +A plugin's `handler.lua` must return a table containing the functions it must +execute on each phase. + +{{site.base_gateway}} can process HTTP and stream traffic. Some phases are executed +only when processing HTTP traffic, others when processing stream, +and some (like `init_worker` and `log`) are invoked by both kinds of traffic. + +In addition to functions, a plugin must define two fields: + +* `VERSION` is an informative field, not used by {{site.base_gateway}} directly. It usually + matches the version defined in a plugin's Rockspec version, when it exists. +* `PRIORITY` is used to sort plugins before executing each of their phases. + Plugins with a higher priority are executed first. See the + [plugin execution order](#plugins-execution-order) below + for more info about this field. + +The following example `handler.lua` file defines custom functions for all +the possible phases, in both http and stream traffic. It has no functionality +besides writing a message to the log every time a phase is invoked. Note +that a plugin doesn't need to provide functions for all phases. + +```lua +local CustomHandler = { + VERSION = "1.0.0", + PRIORITY = 10, +} + +function CustomHandler:init_worker() + -- Implement logic for the init_worker phase here (http/stream) + kong.log("init_worker") +end + + +function CustomHandler:preread(config) + -- Implement logic for the preread phase here (stream) + kong.log("preread") +end + + +function CustomHandler:certificate(config) + -- Implement logic for the certificate phase here (http/stream) + kong.log("certificate") +end + +function CustomHandler:rewrite(config) + -- Implement logic for the rewrite phase here (http) + kong.log("rewrite") +end + +function CustomHandler:access(config) + -- Implement logic for the access phase here (http) + kong.log("access") +end + +function CustomHandler:ws_handshake(config) + -- Implement logic for the WebSocket handshake here + kong.log("ws_handshake") +end + +function CustomHandler:header_filter(config) + -- Implement logic for the header_filter phase here (http) + kong.log("header_filter") +end + +function CustomHandler:ws_client_frame(config) + -- Implement logic for WebSocket client messages here + kong.log("ws_client_frame") +end + +function CustomHandler:ws_upstream_frame(config) + -- Implement logic for WebSocket upstream messages here + kong.log("ws_upstream_frame") +end + +function CustomHandler:body_filter(config) + -- Implement logic for the body_filter phase here (http) + kong.log("body_filter") +end + +function CustomHandler:log(config) + -- Implement logic for the log phase here (http/stream) + kong.log("log") +end + +function CustomHandler:ws_close(config) + -- Implement logic for WebSocket post-connection here + kong.log("ws_close") +end + +-- return the created table, so that Kong can execute it +return CustomHandler +``` + +Note that in the example above we are using Lua's `:` shorthand syntax for +functions taking `self` as a first parameter. An equivalent non-shorthand version +of the `access` function would be: + +``` lua +function CustomHandler.access(self, config) + -- Implement logic for the rewrite phase here (http) + kong.log("access") +end +``` + +The plugin's logic doesn't need to be all defined inside the `handler.lua` file. +It can be split into several Lua files (also called *modules*). +The `handler.lua` module can use `require` to include other modules in your plugin. + +For example, the following plugin splits the functionality into three files. +`access.lua` and `body_filter.lua` return functions. They are in the same +folder as `handler.lua`, which requires and uses them to build the plugin: + +```lua +-- handler.lua +local access = require "kong.plugins.my-custom-plugin.access" +local body_filter = require "kong.plugins.my-custom-plugin.body_filter" + +local CustomHandler = { + VERSION = "1.0.0", + PRIORITY = 10 +} + +CustomHandler.access = access +CustomHandler.body_filter = body_filter + +return CustomHandler +``` + +```lua +-- access.lua +return function(self, config) + kong.log("access phase") +end +``` + +```lua +-- body_filter.lua +return function(self, config) + kong.log("body_filter phase") +end +``` + +See [the source code of the Key-Auth Plugin](https://github.com/Kong/kong/blob/master/kong/plugins/key-auth/handler.lua) +for an example of a real-life handler code. + +### Migrating from BasePlugin module + +The `BasePlugin` module is deprecated and has been removed from +{{site.base_gateway}}. If you have an old plugin that uses this module, replace +the following section: + +```lua +-- DEPRECATED -- +local BasePlugin = require "kong.plugins.base_plugin" +local CustomHandler = BasePlugin:extend() +CustomHandler.VERSION = "1.0.0" +CustomHandler.PRIORITY = 10 +``` + +with the current equivalent: +```lua +local CustomHandler = { + VERSION = "1.0.0", + PRIORITY = 10, +} +``` + +You don't need to add a `:new()` method or call any of the `CustomHandler.super.XXX:(self)` +methods. + +## WebSocket Plugin Development +{:.badge .enterprise} + +
      + Warning: The WebSocket PDK is under active development and is + considered unstable at this time. Backwards-incompatible changes may be made + to these functions. +
      + +### Handler Functions + +Requests to services with the `ws` or `wss` protocol take a different path through +the proxy than regular http requests. Therefore, there are some differences in behavior +that must be accounted for when developing plugins for them. + +The following handlers are _not_ executed for WebSocket services: + - `access` + - `response` + - `header_filter` + - `body_filter` + - `log` + +The following handlers are _unique to_ WebSocket services: + - `ws_handshake` + - `ws_client_frame` + - `ws_upstream_frame` + - `ws_close` + +The following handlers are executed for both WebSocket _and_ non-Websocket services: + - `init_worker` + - `certificate` (TLS/SSL requests only) + - `rewrite` + +Even with these differences, it is possible to develop plugins that support both WebSocket +and non-WebSocket services. For example: + +```lua +-- handler.lua +-- +-- I am a plugin that implements both WebSocket and non-WebSocket handlers. +-- +-- I can be enabled for ws/wss services, http/https/grpc/grpcs services, or +-- even as global plugin. +local MultiProtoHandler = { + VERSION = "0.1.0", + PRIORITY = 1000, +} + +function MultiProtoHandler:access() + kong.ctx.plugin.request_type = "non-WebSocket" +end + +function MultiProtoHandler:ws_handshake() + kong.ctx.plugin.request_type = "WebSocket" +end + + +function MultiProtoHandler:log() + kong.log("finishing ", kong.ctx.plugin.request_type, " request") +end + +-- the `ws_close` handler for this plugin does not implement any WebSocket-specific +-- business logic, so it can simply be aliased to the `log` handler +MultiProtoHandler.ws_close = MultiProtoHandler.log + +return MultiProtoHandler +``` + +As seen above, the `log` and `ws_close` handlers are parallel to each other. In +many cases, one can be aliased to the other without having to write any +additional code. The `access` and `ws_handshake` handlers are also very similar in +this regard. The notable difference lies in which PDK functions are/aren't available +in each context. For instance, the `kong.request.get_body()` PDK function cannot be +used in an `access` handler because it is fundamentally incompatible with this kind +of request. + + +### WebSocket requests to non-WebSocket services + +When WebSocket traffic is proxied via an http/https service, it is treated as a +non-WebSocket request. Therefore, the http handlers (`access`, `header_filter`, etc) +will be executed and _not_ the WebSocket handlers (`ws_handshake`, `ws_close`, etc). + +## Plugin Development Kit + +Logic implemented in those phases will most likely have to interact with the +request/response objects or core components (e.g. access the cache, and +database). {{site.base_gateway}} provides a [Plugin Development Kit][pdk] (or "PDK") for such +purposes: a set of Lua functions and variables that can be used by Plugins to +execute various gateway operations in a way that is guaranteed to be +forward-compatible with future releases of {{site.base_gateway}}. + +When you are trying to implement some logic that needs to interact with {{site.base_gateway}} +(e.g. retrieving request headers, producing a response from a plugin, logging +some error or debug information), you should consult the [Plugin Development +Kit Reference][pdk]. + + +## Plugins execution order + +Some plugins might depend on the execution of others to perform some +operations. For example, plugins relying on the identity of the consumer have +to run **after** authentication plugins. Considering this, {{site.base_gateway}} defines +**priorities** between plugins execution to ensure that order is respected. + +Your plugin's priority can be configured via a property accepting a number in +the returned handler table: + +```lua +CustomHandler.PRIORITY = 10 +``` + +The higher the priority, the sooner your plugin's phases will be executed in +regard to other plugins' phases (such as `:access()`, `:log()`, etc.). + +### Kong plugins + +All of the plugins bundled with {{site.base_gateway}} have a static priority. +This can be adjusted dynamically using the `ordering` option. See +[Dynamic Plugin Ordering](/gateway/{{page.kong_version}}/kong-enterprise/plugin-ordering/) +for more information. + +{% navtabs %} +{% navtab Open-source or Free mode %} + +The following list includes all plugins bundled with open-source +{{site.base_gateway}} or {{site.base_gateway}} running in Free mode. + +{:.note} +> **Note:** The correlation-id plugin's execution order is different depending +on whether you're running {{site.base_gateway}} in Free mode or using the +open-source package. + +The current order of execution for the bundled plugins is: + + + +Plugin | Priority +----------------------------|---------- +pre-function | 1000000 +correlation-id | 100001 +zipkin | 100000 +bot-detection | 2500 +cors | 2000 +session | 1900 +acme | 1705 +jwt | 1450 +oauth2 | 1400 +key-auth | 1250 +ldap-auth | 1200 +basic-auth | 1100 +hmac-auth | 1030 +grpc-gateway | 998 +ip-restriction | 990 +request-size-limiting | 951 +acl | 950 +rate-limiting | 910 +response-ratelimiting | 900 +request-transformer | 801 +response-transformer | 800 +aws-lambda | 750 +azure-functions | 749 +upstream-timeout | 400 +opentelemetry | 14 +prometheus | 13 +http-log | 12 +statsd | 11 +datadog | 10 +file-log | 9 +udp-log | 8 +tcp-log | 7 +loggly | 6 +syslog | 4 +grpc-web | 3 +request-termination | 2 +correlation-id | 1 +post-function | -1000 + + + +{% endnavtab %} +{% navtab Enterprise %} +The following list includes all plugins bundled with a {{site.base_gateway}} +Enterprise subscription. + +The current order of execution for the bundled plugins is: + + + +Plugin | Priority +----------------------------|---------- +pre-function | 1000000 +correlation-id | 100001 +zipkin | 100000 +exit-transformer | 9999 +bot-detection | 2500 +cors | 2000 +session | 1900 +oauth2-introspection | 1700 +acme | 1705 +mtls-auth | 1600 +jwt | 1450 +degraphql | 1500 +oauth2 | 1400 +vault-auth | 1350 +key-auth | 1250 +key-auth-enc | 1250 +ldap-auth | 1200 +ldap-auth-advanced | 1200 +basic-auth | 1100 +openid-connect | 1050 +hmac-auth | 1030 +jwt-signer | 1020 +request-validator | 999 +websocket-size-limit | 999 +websocket-validator | 999 +grpc-gateway | 998 +tls-handshake-modifier | 997 +tls-metadata-headers | 996 +application-registration | 995 +ip-restriction | 990 +request-size-limiting | 951 +acl | 950 +opa | 920 +rate-limiting | 910 +rate-limiting-advanced | 910 +graphql-rate-limiting-advanced | 902 +response-ratelimiting | 900 +route-by-header | 850 +jq | 811 +request-transformer-advanced | 802 +request-transformer | 801 +response-transformer-advanced | 800 +response-transformer | 800 +route-transformer-advanced | 780 +kafka-upstream | 751 +aws-lambda | 750 +azure-functions | 749 +upstream-timeout | 400 +proxy-cache-advanced | 100 +proxy-cache | 100 +graphql-proxy-cache-advanced | 99 +forward-proxy | 50 +canary | 20 +opentelemetry | 14 +prometheus | 13 +http-log | 12 +statsd | 11 +statsd-advanced | 11 +datadog | 10 +file-log | 9 +udp-log | 8 +tcp-log | 7 +loggly | 6 +kafka-log | 5 +syslog | 4 +grpc-web | 3 +request-termination | 2 +mocking | -1 +post-function | -1000 + +{% endnavtab %} +{% endnavtabs %} + +[lua-nginx-module]: https://github.com/openresty/lua-nginx-module +[pdk]: /gateway/{{page.kong_version}}/plugin-development/pdk +[HTTP Module]: https://github.com/openresty/lua-nginx-module +[Stream Module]: https://github.com/openresty/stream-lua-nginx-module +[init_worker]: https://github.com/openresty/lua-nginx-module#init_worker_by_lua_by_lua_block +[ssl_certificate]: https://github.com/openresty/lua-nginx-module#ssl_certificate_by_lua_block +[rewrite]: https://github.com/openresty/lua-nginx-module#rewrite_by_lua_block +[access]: https://github.com/openresty/lua-nginx-module#access_by_lua_block +[header_filter]: https://github.com/openresty/lua-nginx-module#header_filter_by_lua_block +[body_filter]: https://github.com/openresty/lua-nginx-module#body_filter_by_lua_block +[log]: https://github.com/openresty/lua-nginx-module#log_by_lua_block +[preread]: https://github.com/openresty/stream-lua-nginx-module#preread_by_lua_block +[enable_buffering]: /gateway/{{page.kong_version}}/plugin-development/pdk/kong.service.request/#kongservicerequestenable_buffering +[content]: https://github.com/openresty/lua-nginx-module#content_by_lua_block + + diff --git a/src/gateway/plugin-development/distribution.md b/src/gateway/plugin-development/distribution.md new file mode 100644 index 000000000000..635abfb0d572 --- /dev/null +++ b/src/gateway/plugin-development/distribution.md @@ -0,0 +1,309 @@ +--- +title: (un)Installing your plugin +book: plugin_dev +chapter: 10 +--- + +Custom plugins for Kong consist of Lua source files that need to be in the file +system of each of your Kong nodes. This guide will provide you with +step-by-step instructions that will make a Kong node aware of your custom +plugin(s). + +These steps should be applied to each node in your Kong cluster, to ensure the +custom plugin(s) are available on each one of them. + +## Packaging sources + +You can either use a regular packing strategy (e.g. `tar`), or use the LuaRocks +package manager to do it for you. We recommend LuaRocks as it is installed +along with Kong when using one of the official distribution packages. + +When using LuaRocks, you must create a `rockspec` file, which specifies the +package contents. For an example, see the [Kong plugin +template][plugin-template]. For more info about the format, see the LuaRocks +[documentation on rockspecs][rockspec]. + +Pack your rock using the following command (from the plugin repo): + +1. Install it locally (based on the `.rockspec` in the current directory): + ```sh + luarocks make + ``` + +2. Pack the installed rock: + ```sh + luarocks pack + ``` + + Assuming your plugin rockspec is called + `kong-plugin-my-plugin-0.1.0-1.rockspec`, the above would become; + + ```sh + luarocks pack kong-plugin-my-plugin 0.1.0-1 + ``` + +The LuaRocks `pack` command has now created a `.rock` file (this is simply a +zip file containing everything needed to install the rock). + +If you do not or cannot use LuaRocks, then use `tar` to pack the +`.lua` files of which your plugin consists into a `.tar.gz` archive. You can +also include the `.rockspec` file if you do have LuaRocks on the target +systems. + +The contents of this archive should be close to the following: + +``` +tree + +├── INSTALL.txt +├── README.md +├── kong +│ └── plugins +│ └── +│ ├── handler.lua +│ └── schema.lua +└── -.rockspec +``` + +## Install the plugin + +For a Kong node to be able to use the custom plugin, the custom plugin's Lua +sources must be installed on your host's file system. There are multiple ways +of doing so: via LuaRocks, or manually. Choose one of the following paths. + +Reminder: regardless of which method you are using to install your plugin's +sources, you must still do so for each node in your Kong cluster. + +### Via LuaRocks from the created 'rock' + +The `.rock` file is a self contained package that can be installed locally +or from a remote server. + +If the `luarocks` utility is installed in your system (this is likely the +case if you used one of the official installation packages), you can +install the 'rock' in your LuaRocks tree (a directory in which LuaRocks +installs Lua modules). + +It can be installed by doing: +```sh +luarocks install +``` + +The filename can be a local name, or any of the supported methods, eg. +`http://myrepository.lan/rocks/my-plugin-0.1.0-1.all.rock` + +### Via LuaRocks from the source archive + +If the `luarocks` utility is installed in your system (this is likely the +case if you used one of the official installation packages), you can +install the Lua sources in your LuaRocks tree (a directory in which +LuaRocks installs Lua modules). + +You can do so by changing the current directory to the extracted archive, +where the rockspec file is: + +```sh +cd +``` + +And then run the following: + +```sh +luarocks make +``` + +This will install the Lua sources in `kong/plugins/` in your +system's LuaRocks tree, where all the Kong sources are already present. + +### Manually + +A more conservative way of installing your plugin's sources is +to avoid "polluting" the LuaRocks tree, and instead, point Kong +to the directory containing them. + +This is done by tweaking the `lua_package_path` property of your Kong +configuration. Under the hood, this property is an alias to the `LUA_PATH` +variable of the Lua VM, if you are familiar with it. + +Those properties contain a semicolon-separated list of directories in +which to search for Lua sources. It should be set like so in your Kong +configuration file: + +``` +lua_package_path = //?.lua;; +``` + +Where: + +* `/` is the path to the directory containing the + extracted archive. It should be the location of the `kong` directory + from the archive. +* `?` is a placeholder that will be replaced by + `kong.plugins.` when Kong will try to load your plugin. Do + not change it. +* `;;` a placeholder for the "the default Lua path". Do not change it. + +For example, if the plugin `something` is located on the file system and the +handler file is in the following directory: + +``` +/usr/local/custom/kong/plugins//handler.lua +``` + +The location of the `kong` directory is `/usr/local/custom`, so the +proper path setup would be: + +``` +lua_package_path = /usr/local/custom/?.lua;; +``` + +#### Multiple plugins + +If you want to install two or more custom plugins this way, you can set +the variable to something like: + +``` +lua_package_path = /path/to/plugin1/?.lua;/path/to/plugin2/?.lua;; +``` + +* `;` is the separator between directories. +* `;;` still means "the default Lua path". + +You can also set this property via its environment variable +equivalent: `KONG_LUA_PACKAGE_PATH`. + + +## Load the plugin + +1. Add the custom plugin's name to the `plugins` list in your +Kong configuration (on each Kong node): + + ``` + plugins = bundled, + ``` + + Or, if you don't want to include the bundled plugins: + + ``` + plugins = + ``` + + If you are using two or more custom plugins, insert commas in between, like so: + + ``` + plugins = bundled,plugin1,plugin2 + ``` + Or: + ``` + plugins = plugin1,plugin2 + ``` + + You can also set this property via its environment variable equivalent: + `KONG_PLUGINS`. + +1. Update the `plugins` directive for each node in your Kong cluster. + +1. Restart Kong to apply the plugin: + + ``` + kong restart + ``` + Or, if you want to apply a plugin without stopping Kong, you can use this: + + ``` + kong prepare + kong reload + ``` + +## Verify loading the plugin + +You should now be able to start Kong without any issue. Consult your custom +plugin's instructions on how to enable/configure your plugin +on a Service, Route, or Consumer entity. + +1. To make sure your plugin is being loaded by Kong, you can start Kong with a +`debug` log level: + + ``` + log_level = debug + ``` + or: + ``` + KONG_LOG_LEVEL=debug + ``` +2. Then, you should see the following log for each plugin being loaded: + + ``` + [debug] Loading plugin + ``` + +## Remove a plugin + +There are three steps to completely remove a plugin. + +1. Remove the plugin from your Kong Service or Route configuration. Make sure + that it is no longer applied globally nor for any Service, Route, or + consumer. This has to be done only once for the entire Kong cluster, no + restart/reload required. This step in itself will make that the plugin is + no longer in use. But it remains available and it is still possible to + re-apply the plugin. + +2. Remove the plugin from the `plugins` directive (on each Kong node). + Make sure to have completed step 1 before doing so. After this step + it will be impossible for anyone to re-apply the plugin to any Kong + Service, Route, Consumer, or even globally. This step requires to + restart/reload the Kong node to take effect. + +3. To remove the plugin thoroughly, delete the plugin-related files from + each of the Kong nodes. Make sure to have completed step 2, including + restarting/reloading Kong, before deleting the files. If you used LuaRocks + to install the plugin, you can do `luarocks remove ` to remove + it. + + + +## Distribute your plugin + +The preferred way to do so is to use [LuaRocks](https://luarocks.org/), a +package manager for Lua modules. It calls such modules "rocks". **Your module +does not have to live inside the Kong repository**, but it can be if that's +how you'd like to maintain your Kong setup. + +By defining your modules (and their eventual dependencies) in a [rockspec] +file, you can install those modules on your platform via LuaRocks. You can +also upload your module on LuaRocks and make it available to everyone! + +Here is an [example rockspec][example-rockspec] using the `builtin` +build type to define modules in Lua notation and their corresponding file. + +For more information about the format, see the LuaRocks +[documentation on rockspecs][rockspec]. + + +## Troubleshooting + +Kong can fail to start because of a misconfigured custom plugin for several +reasons: + +`plugin is in use but not enabled` +: You configured a custom plugin from + another node, and that the plugin configuration is in the database, but the + current node you are trying to start does not have it in its `plugins` + directive. To resolve, add the plugin's name to the node's `plugins` + directive. + +`plugin is enabled but not installed` +: The plugin's name is present in the `plugins` directive, but Kong can't load +the `handler.lua` source file from the file system. To resolve, make sure that +the [lua_package_path](/gateway/{{page.kong_version}}/reference/configuration/#development-miscellaneous-section) +directive is properly set to load this plugin's Lua sources. + +`no configuration schema found for plugin` +: The plugin is installed and enabled in the `plugins` directive, but Kong is +unable to load the `schema.lua` source file from the file system. To resolve, +make sure tha the `schema.lua` file is present alongside the plugin's +`handler.lua` file. + +[rockspec]: https://github.com/keplerproject/luarocks/wiki/Creating-a-rock +[plugin-template]: https://github.com/Kong/kong-plugin +[example-rockspec]: https://github.com/Kong/kong-plugin/blob/master/kong-plugin-myplugin-0.1.0-1.rockspec diff --git a/src/gateway/plugin-development/entities-cache.md b/src/gateway/plugin-development/entities-cache.md new file mode 100644 index 000000000000..a271e9eba230 --- /dev/null +++ b/src/gateway/plugin-development/entities-cache.md @@ -0,0 +1,333 @@ +--- +title: Caching Custom Entities +book: plugin_dev +chapter: 7 +--- + +Your plugin may need to frequently access custom entities (explained in the +[previous chapter]({{page.book.previous.url}})) on every request and/or response. +Usually, loading them once and caching them in-memory dramatically improves +the performance while making sure the datastore is not stressed with an +increased load. + +Think of an api-key authentication plugin that needs to validate the api-key on +every request, thus loading the custom credential object from the datastore on +every request. When the client provides an api-key along with the request, +normally you would query the datastore to check if that key exists, and then +either block the request or retrieve the Consumer ID to identify the user. This +would happen on every request, and it would be very inefficient: + +* Querying the datastore adds latency on every request, making the request + processing slower. +* The datastore would also be affected by an increase of load, potentially + crashing or slowing down, which in turn would affect every Kong + node. + +To avoid querying the datastore every time, we can cache custom entities +in-memory on the node, so that frequent entity lookups don't trigger a +datastore query every time (only the first time), but happen in-memory, which +is much faster and reliable that querying it from the datastore (especially +under heavy load). + +## Modules + +``` +kong.plugins..daos +``` + +## Cache custom entities + +Once you have defined your custom entities, you can cache them in-memory in +your code by using the [kong.cache](/gateway/{{page.kong_version}}/plugin-development/pdk/#kong-cache) +module provided by the [Plugin Development Kit]: + +``` +local cache = kong.cache +``` + +There are 2 levels of cache: + +1. L1: Lua memory cache - local to an Nginx worker process. + This can hold any type of Lua value. +2. L2: Shared memory cache (SHM) - local to an Nginx node, but shared between + all the workers. This can only hold scalar values, and hence requires + (de)serialization of a more complex types such as Lua tables. + +When data is fetched from the database, it will be stored in both caches. +If the same worker process requests the data again, it will retrieve the +previously deserialized data from the Lua memory cache. If a different +worker within the same Nginx node requests that data, it will find the data +in the SHM, deserialize it (and store it in its own Lua memory cache) and +then return it. + +This module exposes the following functions: + +Function name | Description +----------------------------------------------|--------------------------- +`value, err = cache:get(key, opts?, cb, ...)` | Retrieves the value from the cache. If the cache does not have value (miss), invokes `cb` in protected mode. `cb` must return one (and only one) value that will be cached. It *can* throw errors, as those will be caught and properly logged by Kong, at the `ngx.ERR` level. This function **does** cache negative results (`nil`). As such, one must rely on its second argument `err` when checking for errors. +`ttl, err, value = cache:probe(key)` | Checks if a value is cached. If it is, returns its remaining ttl. It not, returns `nil`. The value being cached can also be a negative caching. The third return value is the value being cached itself. +`cache:invalidate_local(key)` | Evicts a value from the node's cache. +`cache:invalidate(key)` | Evicts a value from the node's cache **and** propagates the eviction events to all other nodes in the cluster. +`cache:purge()` | Evicts **all** values from the node's cache. + +Bringing back our authentication plugin example, to look up a credential with a +specific API key, we would write something similar to: + +```lua +-- handler.lua + +local CustomHandler = { + VERSION = "1.0.0", + PRIORITY = 10, +} + +local kong = kong + +local function load_credential(key) + local credential, err = kong.db.keyauth_credentials:select_by_key(key) + if not credential then + return nil, err + end + return credential +end + + +function CustomHandler:access(config) + + -- retrieve the apikey from the request querystring + local key = kong.request.get_query_arg("apikey") + + local credential_cache_key = kong.db.keyauth_credentials:cache_key(key) + + -- We are using cache.get to first check if the apikey has been already + -- stored into the in-memory cache. If it's not, then we lookup the datastore + -- and return the credential object. Internally cache.get will save the value + -- in-memory, and then return the credential. + local credential, err = kong.cache:get(credential_cache_key, nil, + load_credential, credential_cache_key) + if err then + kong.log.err(err) + return kong.response.exit(500, { + message = "Unexpected error" + }) + end + + if not credential then + -- no credentials in cache nor datastore + return kong.response.exit(401, { + message = "Invalid authentication credentials" + }) + end + + -- set an upstream header if the credential exists and is valid + kong.service.request.set_header("X-API-Key", credential.apikey) +end + + +return CustomHandler +``` + +Note that in the above example, we use various components from the [Plugin +Development Kit] to interact with the request, cache module, or even produce a +response from our plugin. + +Now, with the above mechanism in place, once a Consumer has made a request with +their API key, the cache will be considered warm and subsequent requests won't +result in a database query. + +The cache is used in several places in the [Key-Auth plugin handler](https://github.com/Kong/kong/blob/master/kong/plugins/key-auth/handler.lua). +Give that file a look in order to see how an official plugin uses the cache. + +### Update or delete a custom entity + +Every time a cached custom entity is updated or deleted in the datastore (i.e. +using the Admin API), it creates an inconsistency between the data in the +datastore, and the data cached in the Kong nodes' memory. To avoid this +inconsistency, we need to evict the cached entity from the in-memory store and +force Kong to request it again from the datastore. We refer to this process as +cache invalidation. + + +## Cache invalidation for your entities + +If you want your cached entities to be invalidated upon a CRUD operation +rather than having to wait for them to reach their TTL, you have to follow a +few steps. This process can be automated for most entities, but manually +subscribing to some CRUD events might be required to invalidate some entities +with more complex relationships. + +### Automatic cache invalidation + +Cache invalidation can be provided out of the box for your entities if you rely +on the `cache_key` property of your entity's schema. For example, in the +following schema: + +```lua +local typedefs = require "kong.db.schema.typedefs" + + +return { + -- this plugin only results in one custom DAO, named `keyauth_credentials`: + keyauth_credentials = { + name = "keyauth_credentials", -- the actual table in the database + endpoint_key = "key", + primary_key = { "id" }, + cache_key = { "key" }, + generate_admin_api = true, + admin_api_name = "key-auths", + admin_api_nested_name = "key-auth", + fields = { + { + -- a value to be inserted by the DAO itself + -- (think of serial id and the uniqueness of such required here) + id = typedefs.uuid, + }, + { + -- also interted by the DAO itself + created_at = typedefs.auto_timestamp_s, + }, + { + -- a foreign key to a consumer's id + consumer = { + type = "foreign", + reference = "consumers", + default = ngx.null, + on_delete = "cascade", + }, + }, + { + -- a unique API key + key = { + type = "string", + required = false, + unique = true, + auto = true, + }, + }, + }, + }, +} +``` + +We can see that we declare the cache key of this API key entity to be its +`key` attribute. We use `key` here because it has a unique constraints +applied to it. Hence, the attributes added to `cache_key` should result in +a unique combination, so that no two entities could yield the same cache key. + +Adding this value allows you to use the following function on the DAO of that +entity: + +```lua +cache_key = kong.db.:cache_key(arg1, arg2, arg3, ...) +``` + +Where the arguments must be the attributes specified in your schema's +`cache_key` property, in the order they were specified. This function then +computes a string value `cache_key` that is ensured to be unique. + +For example, if we were to generate the cache_key of an API key: + +```lua +local cache_key = kong.db.keyauth_credentials:cache_key("abcd") +``` + +This would produce a cache_key for the API key `"abcd"` (retrieved from one +of the query's arguments) that we can the use to retrieve the key from the +cache (or fetch from the database if the cache is a miss): + +```lua +local key = kong.request.get_query_arg("apikey") +local cache_key = kong.db.keyauth_credentials:cache_key(key) + +local credential, err = kong.cache:get(cache_key, nil, load_entity_key, apikey) +if err then + kong.log.err(err) + return kong.response.exit(500, { message = "Unexpected error" }) +end + +if not credential then + return kong.response.exit(401, { message = "Invalid authentication credentials" }) +end + + +-- do something with the credential +``` + +If the `cache_key` is generated like so and specified in an entity's schema, +cache invalidation will be an automatic process: every CRUD operation that +affects this API key will be make Kong generate the affected `cache_key`, and +broadcast it to all of the other nodes on the cluster so they can evict +that particular value from their cache, and fetch the fresh value from the +datastore on the next request. + +When a parent entity is receiving a CRUD operation (e.g. the Consumer owning +this API key, as per our schema's `consumer_id` attribute), Kong performs the +cache invalidation mechanism for both the parent and the child entity. + +**Note**: Be aware of the negative caching that Kong provides. In the above +example, if there is no API key in the datastore for a given key, the cache +module will store the miss just as if it was a hit. This means that a +"Create" event (one that would create an API key with this given key) is also +propagated by Kong so that all nodes that stored the miss can evict it, and +properly fetch the newly created API key from the datastore. + +See the [Clustering Guide](/gateway/{{page.kong_version}}/production/deployment-topologies/traditional) to ensure +that you have properly configured your cluster for such invalidation events. + +### Manual cache invalidation + +In some cases, the `cache_key` property of an entity's schema is not flexible +enough, and one must manually invalidate its cache. Reasons for this could be +that the plugin is not defining a relationship with another entity via the +traditional `foreign = "parent_entity:parent_attribute"` syntax, or because +it is not using the `cache_key` method from its DAO, or even because it is +somehow abusing the caching mechanism. + +In those cases, you can manually setup your own subscriber to the same +invalidation channels Kong is listening to, and perform your own, custom +invalidation work. + +To listen on invalidation channels inside of Kong, implement the following in +your plugin's `init_worker` handler: + +```lua +function MyCustomHandler:init_worker() + -- listen to all CRUD operations made on Consumers + kong.worker_events.register(function(data) + + end, "crud", "consumers") + + -- or, listen to a specific CRUD operation only + kong.worker_events.register(function(data) + kong.log.inspect(data.operation) -- "update" + kong.log.inspect(data.old_entity) -- old entity table (only for "update") + kong.log.inspect(data.entity) -- new entity table + kong.log.inspect(data.schema) -- entity's schema + end, "crud", "consumers:update") +end +``` + +Once the above listeners are in place for the desired entities, you can perform +manual invalidations of any entity that your plugin has cached. +For instance: + +```lua +kong.worker_events.register(function(data) + if data.operation == "delete" then + local cache_key = data.entity.id + kong.cache:invalidate("prefix:" .. cache_key) + end +end, "crud", "consumers") +``` + +## Extending the Admin API + +As you are probably aware, the [Admin API] is where Kong users communicate with +Kong to setup their APIs and plugins. It is likely that they also need to be +able to interact with the custom entities you implemented for your plugin (for +example, creating and deleting API keys). The way you would do this is by +extending the Admin API, which we will detail in the next chapter: +[Extending the Admin API]({{page.book.next.url}}). + +[Admin API]: /gateway/{{page.kong_version}}/admin-api/ +[Plugin Development Kit]: /gateway/{{page.kong_version}}/plugin-development/pdk diff --git a/src/gateway/plugin-development/file-structure.md b/src/gateway/plugin-development/file-structure.md new file mode 100644 index 000000000000..1de0647c81b6 --- /dev/null +++ b/src/gateway/plugin-development/file-structure.md @@ -0,0 +1,115 @@ +--- +title: File Structure +book: plugin_dev +chapter: 2 +--- + +{:.note} +> **Note**: This chapter assumes that you are familiar with +[Lua](http://www.lua.org/). + +Consider your plugin as a set of [Lua +modules](http://www.lua.org/manual/5.1/manual.html#6.3). Each file described in +this chapter is to be considered as a separate module. Kong will detect and +load your plugin's modules if their names follow this convention: + +``` +kong.plugins.. +``` + +Your modules need to be accessible through your +[package.path](http://www.lua.org/manual/5.1/manual.html#pdf-package.path) +variable, which can be tweaked to your needs via the +[lua_package_path](/gateway/{{page.kong_version}}/reference/configuration/#lua_package_path) +configuration property. +However, the preferred way of installing plugins is through +[LuaRocks](https://luarocks.org/), which Kong natively integrates with. +More on LuaRocks-installed plugins later in this guide. + +To make Kong aware that it has to look for your plugin's modules, you'll have +to add it to the +[plugins](/gateway/{{page.kong_version}}/reference/configuration/#plugins) property in +your configuration file, which is a comma-separated list. For example: + +```yaml +plugins = bundled,my-custom-plugin # your plugin name here +``` + +Or, if you don't want to load any of the bundled plugins: + +```yaml +plugins = my-custom-plugin # your plugin name here +``` + +Now, Kong will try to load several Lua modules from the following namespace: + +``` +kong.plugins.my-custom-plugin. +``` + +Some of these modules are mandatory (e.g. `handler.lua`), and some are +optional, and will allow the plugin to implement some extra-functionalities +(e.g. `api.lua` to extend the Admin API endpoints). + +Now let's describe exactly what are the modules you can implement and what +their purpose is. + + +## Basic plugin modules + +In its purest form, a plugin consists of two mandatory modules: + +``` +simple-plugin +├── handler.lua +└── schema.lua +``` + +- **[handler.lua]**: the core of your plugin. It is an interface to implement, in + which each function will be run at the desired moment in the lifecycle of a + request / connection. +- **[schema.lua]**: your plugin probably has to retain some configuration entered + by the user. This module holds the *schema* of that configuration and defines + rules on it, so that the user can only enter valid configuration values. + + +## Advanced plugin modules + +Some plugins might have to integrate deeper with Kong: have their own table in +the database, expose endpoints in the Admin API, etc. Each of those can be +done by adding a new module to your plugin. Here is what the structure of a +plugin would look like if it was implementing all of the optional modules: + +``` +complete-plugin +├── api.lua +├── daos.lua +├── handler.lua +├── migrations +│   ├── init.lua +│   └── 000_base_complete_plugin.lua +└── schema.lua +``` + +Here is the complete list of possible modules to implement and a brief +description of what their purpose is. This guide will go in details to let you +master each one of them. + +| Module name | Required | Description +|:-----------------------|------------|------------ +| **[api.lua]** | No | Defines a list of endpoints to be available in the Admin API to interact with the custom entities handled by your plugin. +| **[daos.lua]** | No | Defines a list of DAOs (Database Access Objects) that are abstractions of custom entities needed by your plugin and stored in the datastore. +| **[handler.lua]** | Yes | An interface to implement. Each function is to be run by Kong at the desired moment in the lifecycle of a request / connection. +| **[migrations/*.lua]** | No | The database migrations (e.g. creation of tables). Migrations are only necessary when your plugin has to store custom entities in the database and interact with them through one of the DAOs defined by [daos.lua]. +| **[schema.lua]** | Yes | Holds the schema of your plugin's configuration, so that the user can only enter valid configuration values. + +The [Key-Auth plugin] is an example of plugin with this file structure. +See [its source code] for more details. + +[api.lua]: {{page.book.chapters.admin-api}} +[daos.lua]: {{page.book.chapters.custom-entities}} +[handler.lua]: {{page.book.chapters.custom-logic}} +[schema.lua]: {{page.book.chapters.plugin-configuration}} +[migrations/*.lua]: {{page.book.chapters.custom-entities}} +[Key-Auth plugin]: /hub/kong-inc/key-auth/ +[its source code]: https://github.com/Kong/kong/tree/master/kong/plugins/key-auth diff --git a/src/gateway/plugin-development/index.md b/src/gateway/plugin-development/index.md new file mode 100644 index 000000000000..1d80a0ccfc37 --- /dev/null +++ b/src/gateway/plugin-development/index.md @@ -0,0 +1,31 @@ +--- +title: Introduction +book: plugin_dev +chapter: 1 +--- + +Before going further, it is necessary to briefly explain how Kong is built, +especially how it integrates with Nginx and what Lua has to do with it. + +[lua-nginx-module] enables Lua scripting capabilities in Nginx. Instead of +compiling Nginx with this module, Kong is distributed along with +[OpenResty](https://openresty.org/), which already includes lua-nginx-module. +OpenResty is *not* a fork of Nginx, but a bundle of modules extending its +capabilities. + +Hence, Kong is a Lua application designed to load and execute Lua modules +(which we more commonly refer to as *plugins*) and provides an entire +development environment for them, including an SDK, database abstractions, +migrations, and more. + +Plugins consist of Lua modules interacting with the request/response objects or +streams via the **Plugin Development Kit** (PDK) to implement arbitrary logic. +The PDK is a set of Lua functions that a plugin can use to facilitate interactions +between plugins and the core (or other components) of Kong. + +This guide will explore in detail the structure of plugins, what they can +extend, and how to distribute and install them. For a complete reference of the +PDK, see the [Plugin Development Kit] reference. + +[lua-nginx-module]: https://github.com/openresty/lua-nginx-module +[Plugin Development Kit]: /gateway/{{page.kong_version}}/plugin-development/pdk diff --git a/src/gateway/plugin-development/pdk/index.md b/src/gateway/plugin-development/pdk/index.md new file mode 100644 index 000000000000..984197a7e125 --- /dev/null +++ b/src/gateway/plugin-development/pdk/index.md @@ -0,0 +1,135 @@ +--- +# +# WARNING: this file was auto-generated by a script. +# DO NOT edit this file directly. Instead, send a pull request to change +# https://github.com/Kong/kong/tree/master/autodoc/pdk/ldoc/ldoc.ltp +# or its associated files +# +title: PDK +pdk: true +toc: true +source_url: https://github.com/Kong/kong/tree/master/kong/pdk +--- + +The Plugin Development Kit (PDK) is set of Lua functions and variables + that can be used by plugins to implement their own logic. The PDK is a + [Semantically Versioned](https://semver.org/) component, originally + released in Kong 0.14.0. The PDK is guaranteed to be forward-compatible + from its 1.0.0 release and onward. + + The Plugin Development Kit is accessible from the `kong` global variable, + and various functionalities are namespaced under this table, such as + `kong.request`, `kong.log`, etc. + + + + +## kong.version + +A human-readable string containing the version number of the currently + running node. + +**Usage** + +``` lua +print(kong.version) -- "2.0.0" +``` + + + +## kong.version_num + +An integral number representing the version number of the currently running + node, useful for comparison and feature-existence checks. + +**Usage** + +``` lua +if kong.version_num < 13000 then -- 000.130.00 -> 0.13.0 + -- no support for Routes & Services +end +``` + + + +## kong.configuration + +A read-only table containing the configuration of the current Kong node, + based on the configuration file and environment variables. + + See [kong.conf.default](https://github.com/Kong/kong/blob/master/kong.conf.default) + for details. + + Comma-separated lists in the `kong.conf` file get promoted to arrays of strings in this + table. + + +**Usage** + +``` lua +print(kong.configuration.prefix) -- "/usr/local/kong" +-- this table is read-only; the following throws an error: +kong.configuration.prefix = "foo" +``` + + + + + +## kong.db + +Instance of Kong's DAO (the `kong.db` module). Contains accessor objects + to various entities. + + A more thorough documentation of this DAO and new schema definitions is to + be made available in the future. + + +**Usage** + +``` lua +kong.db.services:insert() +kong.db.routes:select() +``` + + + +## kong.dns + +Instance of Kong's DNS resolver, a client object from the + [lua-resty-dns-client](https://github.com/kong/lua-resty-dns-client) module. + + **Note:** Usage of this module is currently reserved to the core or to + advanced users. + + + + +## kong.worker_events + +Instance of Kong's IPC module for inter-workers communication from the + [lua-resty-worker-events](https://github.com/Kong/lua-resty-worker-events) + module. + + **Note:** Usage of this module is currently reserved to the core or to + advanced users. + + + + +## kong.cluster_events + +Instance of Kong's cluster events module for inter-nodes communication. + + **Note:** Usage of this module is currently reserved to the core or to + advanced users. + + + + +## kong.cache + +Instance of Kong's database caching object, from the `kong.cache` module. + + **Note:** Usage of this module is currently reserved to the core or to + advanced users. diff --git a/src/gateway/plugin-development/pdk/kong.client.md b/src/gateway/plugin-development/pdk/kong.client.md new file mode 100644 index 000000000000..f0e140d74e8a --- /dev/null +++ b/src/gateway/plugin-development/pdk/kong.client.md @@ -0,0 +1,290 @@ +--- +# +# WARNING: this file was auto-generated by a script. +# DO NOT edit this file directly. Instead, send a pull request to change +# https://github.com/Kong/kong/tree/master/autodoc/pdk/ldoc/ldoc.ltp +# or its associated files +# +title: kong.client +pdk: true +toc: true +source_url: https://github.com/Kong/kong/tree/master/kong/pdk +--- + +Client information module. + + A set of functions to retrieve information about the client connecting to + Kong in the context of a given request. + + See also: + [nginx.org/en/docs/http/ngx_http_realip_module.html](http://nginx.org/en/docs/http/ngx_http_realip_module.html) + + + +## kong.client.get_ip() + +Returns the remote address of the client making the request. This module + **always** returns the address of the client directly connecting to Kong. + That is, in cases when a load balancer is in front of Kong, this function + returns the load balancer's address, and **not** that of the + downstream client. + + +**Phases** + +* certificate, rewrite, access, header_filter, response, body_filter, log + +**Returns** + +* `string`: The remote IP address of the client making the request. + + +**Usage** + +``` lua +-- Given a client with IP 127.0.0.1 making connection through +-- a load balancer with IP 10.0.0.1 to Kong answering the request for +-- https://example.com:1234/v1/movies +kong.client.get_ip() -- "10.0.0.1" +``` + + + +## kong.client.get_forwarded_ip() + +Returns the remote address of the client making the request. Unlike + `kong.client.get_ip`, this function will consider forwarded addresses in + cases when a load balancer is in front of Kong. Whether this function + returns a forwarded address or not depends on several Kong configuration + parameters: + + * [trusted\_ips](https://docs.konghq.com/gateway/latest/reference/configuration/#trusted_ips) + * [real\_ip\_header](https://docs.konghq.com/gateway/latest/reference/configuration/#real_ip_header) + * [real\_ip\_recursive](https://docs.konghq.com/gateway/latest/reference/configuration/#real_ip_recursive) + + +**Phases** + +* certificate, rewrite, access, header_filter, response, body_filter, log + +**Returns** + +* `string`: The remote IP address of the client making the request, + considering forwarded addresses. + + + +**Usage** + +``` lua +-- Given a client with IP 127.0.0.1 making connection through +-- a load balancer with IP 10.0.0.1 to Kong answering the request for +-- https://username:password@example.com:1234/v1/movies + +kong.client.get_forwarded_ip() -- "127.0.0.1" + +-- Note: This example assumes that 10.0.0.1 is one of the trusted IPs, and that +-- the load balancer adds the right headers matching with the configuration +-- of `real_ip_header`, e.g. `proxy_protocol`. +``` + + + +## kong.client.get_port() + +Returns the remote port of the client making the request. This + **always** returns the port of the client directly connecting to Kong. That + is, in cases when a load balancer is in front of Kong, this function + returns the load balancer's port, and **not** that of the downstream client. + +**Phases** + +* certificate, rewrite, access, header_filter, response, body_filter, log + +**Returns** + +* `number`: The remote client port. + + +**Usage** + +``` lua +-- [client]:40000 <-> 80:[balancer]:30000 <-> 80:[kong]:20000 <-> 80:[service] +kong.client.get_port() -- 30000 +``` + + + +## kong.client.get_forwarded_port() + +Returns the remote port of the client making the request. Unlike + `kong.client.get_port`, this function will consider forwarded ports in cases + when a load balancer is in front of Kong. Whether this function returns a + forwarded port or not depends on several Kong configuration parameters: + + * [trusted\_ips](https://docs.konghq.com/gateway/latest/reference/configuration/#trusted_ips) + * [real\_ip\_header](https://docs.konghq.com/gateway/latest/reference/configuration/#real_ip_header) + * [real\_ip\_recursive](https://docs.konghq.com/gateway/latest/reference/configuration/#real_ip_recursive) + +**Phases** + +* certificate, rewrite, access, header_filter, response, body_filter, log + +**Returns** + +* `number`: The remote client port, considering forwarded ports. + + +**Usage** + +``` lua +-- [client]:40000 <-> 80:[balancer]:30000 <-> 80:[kong]:20000 <-> 80:[service] +kong.client.get_forwarded_port() -- 40000 + +-- Note: This example assumes that [balancer] is one of the trusted IPs, and that +-- the load balancer adds the right headers matching with the configuration +-- of `real_ip_header`, e.g. `proxy_protocol`. +``` + + + +## kong.client.get_credential() + +Returns the credentials of the currently authenticated consumer. + If not set yet, it returns `nil`. + +**Phases** + +* access, header_filter, response, body_filter, log + +**Returns** + +* `string`: The authenticated credential. + + +**Usage** + +``` lua +local credential = kong.client.get_credential() +if credential then + consumer_id = credential.consumer_id +else + -- request not authenticated yet +end +``` + + + +## kong.client.load_consumer(consumer_id[, search_by_username]) + +Returns the consumer from the datastore. + Looks up the consumer by ID, and can optionally do a second search by name. + +**Phases** + +* access, header_filter, response, body_filter, log + +**Parameters** + +* **consumer_id** (`string`): The consumer ID to look up. +* **search_by_username** (`boolean`, _optional_): If truthy, + and if the consumer is not found by ID, + then a second search by username will be performed. + +**Returns** + +1. `table|nil`: Consumer entity or `nil`. + +1. `nil|err`: `nil` if successful, or an error message if it fails. + + +**Usage** + +``` lua +local consumer_id = "john_doe" +local consumer = kong.client.load_consumer(consumer_id, true) +``` + + + +## kong.client.get_consumer() + +Returns the `consumer` entity of the currently authenticated consumer. + If not set yet, it returns `nil`. + +**Phases** + +* access, header_filter, response, body_filter, log + +**Returns** + +* `table`: The authenticated consumer entity. + + +**Usage** + +``` lua +local consumer = kong.client.get_consumer() +if consumer then + consumer_id = consumer.id +else + -- request not authenticated yet, or a credential + -- without a consumer (external auth) +end +``` + + + +## kong.client.authenticate(consumer, credential) + +Sets the authenticated consumer and/or credential for the current request. + While both `consumer` and `credential` can be `nil`, + at least one of them must exist. Otherwise, this function will throw an + error. + +**Phases** + +* access + +**Parameters** + +* **consumer** (`table|nil`): The consumer to set. If no + value is provided, then any existing value will be cleared. +* **credential** (`table|nil`): The credential to set. If + no value is provided, then any existing value will be cleared. + +**Usage** + +``` lua +-- assuming `credential` and `consumer` have been set by some authentication code +kong.client.authenticate(consumer, credentials) +``` + + + +## kong.client.get_protocol([allow_terminated]) + +Returns the protocol matched by the current route (`"http"`, `"https"`, `"tcp"` or + `"tls"`), or `nil`, if no route has been matched, which can happen when dealing with + erroneous requests. + +**Phases** + +* access, header_filter, response, body_filter, log + +**Parameters** + +* **allow_terminated** (`boolean`, _optional_): If set, the `X-Forwarded-Proto` header is checked when checking for HTTPS. + +**Returns** + +1. `string|nil`: Can be one of `"http"`, `"https"`, `"tcp"`, `"tls"` or `nil`. + +1. `nil|err`: `nil` if successful, or an error message if it fails. + + +**Usage** + +``` lua +kong.client.get_protocol() -- "http" +``` diff --git a/src/gateway/plugin-development/pdk/kong.client.tls.md b/src/gateway/plugin-development/pdk/kong.client.tls.md new file mode 100644 index 000000000000..9cdc72e0d9dd --- /dev/null +++ b/src/gateway/plugin-development/pdk/kong.client.tls.md @@ -0,0 +1,147 @@ +--- +# +# WARNING: this file was auto-generated by a script. +# DO NOT edit this file directly. Instead, send a pull request to change +# https://github.com/Kong/kong/tree/master/autodoc/pdk/ldoc/ldoc.ltp +# or its associated files +# +title: kong.client.tls +pdk: true +toc: true +source_url: https://github.com/Kong/kong/tree/master/kong/pdk +--- + +Client TLS connection module. + + A set of functions for interacting with TLS connections from the client. + + + + +## kong.client.tls.request_client_certificate() + +Requests the client to present its client-side certificate to initiate mutual + TLS authentication between server and client. + + This function *requests*, but does not *require* the client to start + the mTLS process. The TLS handshake can still complete even if the client + doesn't present a client certificate. However, in that case, it becomes a + TLS connection instead of an mTLS connection, as there is no mutual + authentication. + + To find out whether the client honored the request, use + `get_full_client_certificate_chain` in later phases. + + +**Phases** + +* certificate + +**Returns** + +1. `true|nil`: Returns `true` if request is received, or `nil` if + request fails. + +1. `nil|err`: Returns `nil` if the handshake is successful, or an error + message if it fails. + + + +**Usage** + +``` lua +local res, err = kong.client.tls.request_client_certificate() +if not res then + -- do something with err +end +``` + + + +## kong.client.tls.disable_session_reuse() + +Prevents the TLS session for the current connection from being reused + by disabling the session ticket and session ID for the current TLS connection. + +**Phases** + +* certificate + +**Returns** + +1. `true|nil`: Returns `true` if successful, `nil` if it fails. + +1. `nil|err`: Returns `nil` if successful, or an error message if it fails. + + +**Usage** + +``` lua +local res, err = kong.client.tls.disable_session_reuse() +if not res then + -- do something with err +end +``` + + + +## kong.client.tls.get_full_client_certificate_chain() + +Returns the PEM encoded downstream client certificate chain with the + client certificate at the top and intermediate certificates + (if any) at the bottom. + +**Phases** + +* rewrite, access, balancer, header_filter, body_filter, log + +**Returns** + +1. `string|nil`: Returns a PEM-encoded client certificate if the mTLS + handshake was completed, or `nil` if an error occurred or the client did + not present its certificate. + +1. `nil|err`: Returns `nil` if successful, or an error message if it fails. + + +**Usage** + +``` lua +local cert, err = kong.client.get_full_client_certificate_chain() +if err then + -- do something with err +end + +if not cert then + -- client did not complete mTLS +end + +-- do something with cert +``` + + + +## kong.client.tls.set_client_verify() + +Overrides the client's verification result generated by the log serializer. + + By default, the `request.tls.client_verify` field inside the log + generated by Kong's log serializer is the same as the + [$ssl_client_verify](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#var_ssl_client_verify) + Nginx variable. + + Only `"SUCCESS"`, `"NONE"`, or `"FAILED:"` are accepted values. + + This function does not return anything on success, and throws a Lua error + in case of a failure. + + +**Phases** + +* rewrite, access, balancer + +**Usage** + +``` lua +kong.client.tls.set_client_verify("FAILED:unknown CA") +``` diff --git a/src/gateway/plugin-development/pdk/kong.cluster.md b/src/gateway/plugin-development/pdk/kong.cluster.md new file mode 100644 index 000000000000..64441df64f38 --- /dev/null +++ b/src/gateway/plugin-development/pdk/kong.cluster.md @@ -0,0 +1,50 @@ +--- +# +# WARNING: this file was auto-generated by a script. +# DO NOT edit this file directly. Instead, send a pull request to change +# https://github.com/Kong/kong/tree/master/autodoc/pdk/ldoc/ldoc.ltp +# or its associated files +# +title: kong.cluster +pdk: true +toc: true +source_url: https://github.com/Kong/kong/tree/master/kong/pdk +--- + +Cluster-level utilities. + + + +## kong.cluster.get_id() + +Returns the unique ID for this Kong cluster. If Kong + is running in DB-less mode without a cluster ID explicitly defined, + then this method returns `nil`. + + For hybrid mode, all control planes and data planes belonging to the same + cluster return the same cluster ID. For traditional database-based + deployments, all Kong nodes pointing to the same database also return + the same cluster ID. + + +**Returns** + +1. `string|nil`: The v4 UUID used by this cluster as its ID. + +1. `string|nil`: An error message. + + +**Usage** + +``` lua +local id, err = kong.cluster.get_id() +if err then + -- handle error +end + +if not id then + -- no cluster ID is available +end + +-- use id here +``` diff --git a/src/gateway/plugin-development/pdk/kong.ctx.md b/src/gateway/plugin-development/pdk/kong.ctx.md new file mode 100644 index 000000000000..1331ad7a5473 --- /dev/null +++ b/src/gateway/plugin-development/pdk/kong.ctx.md @@ -0,0 +1,110 @@ +--- +# +# WARNING: this file was auto-generated by a script. +# DO NOT edit this file directly. Instead, send a pull request to change +# https://github.com/Kong/kong/tree/master/autodoc/pdk/ldoc/ldoc.ltp +# or its associated files +# +title: kong.ctx +pdk: true +toc: true +source_url: https://github.com/Kong/kong/tree/master/kong/pdk +--- + +Contextual data for the current request. + + + +## kong.ctx.shared + +A table that has the same lifetime as the current request. This table is shared + between all plugins. It can be used to share data between several plugins in a + given request. + + This table is only relevant in the context of a request and cannot be + accessed from the top-level chunk of Lua modules. Instead, it can only be + accessed in request phases, which are represented by the `rewrite`, + `access`, `header_filter`, `response`, `body_filter`, `log`, and `preread` phases of + the plugin interfaces. Accessing this table in those functions (and their + callees) is fine. + + Values inserted in this table by a plugin are visible by all other + plugins. Be careful when interacting with values in this table, as a naming + conflict could result in the overwrite of data. + + +**Phases** + +* rewrite, access, header_filter, response, body_filter, log, preread + +**Usage** + +``` lua +-- Two plugins A and B, and if plugin A has a higher priority than B's +-- (it executes before B): + +-- plugin A handler.lua +function plugin_a_handler:access(conf) + kong.ctx.shared.foo = "hello world" + + kong.ctx.shared.tab = { + bar = "baz" + } +end + +-- plugin B handler.lua +function plugin_b_handler:access(conf) + kong.log(kong.ctx.shared.foo) -- "hello world" + kong.log(kong.ctx.shared.tab.bar) -- "baz" +end +``` + + + +## kong.ctx.plugin + +A table that has the same lifetime as the current request. Unlike + `kong.ctx.shared`, this table is **not** shared between plugins. + Instead, it is only visible for the current plugin instance. + For example, if several instances of the Rate Limiting plugin + are configured on different Services, each instance has its + own table for every request. + + Because of its namespaced nature, this table is safer for a plugin to use + than `kong.ctx.shared` since it avoids potential naming conflicts, which + could lead to several plugins unknowingly overwriting each other's data. + + This table is only relevant in the context of a request and cannot be + accessed from the top-level chunk of Lua modules. Instead, it can only be + accessed in request phases, which are represented by the `rewrite`, + `access`, `header_filter`, `body_filter`, `log`, and `preread` phases + of the plugin interfaces. Accessing this table in those functions (and + their callees) is fine. + + Values inserted in this table by a plugin are visible in successful + phases of this plugin's instance only. + + +**Phases** + +* rewrite, access, header_filter, response, body_filter, log, preread + +**Usage** + +``` lua +-- plugin handler.lua + +-- For example, if a plugin wants to +-- save some value for post-processing during the `log` phase: + +function plugin_handler:access(conf) + kong.ctx.plugin.val_1 = "hello" + kong.ctx.plugin.val_2 = "world" +end + +function plugin_handler:log(conf) + local value = kong.ctx.plugin.val_1 .. " " .. kong.ctx.plugin.val_2 + + kong.log(value) -- "hello world" +end +``` diff --git a/src/gateway/plugin-development/pdk/kong.ip.md b/src/gateway/plugin-development/pdk/kong.ip.md new file mode 100644 index 000000000000..743ae80e324e --- /dev/null +++ b/src/gateway/plugin-development/pdk/kong.ip.md @@ -0,0 +1,56 @@ +--- +# +# WARNING: this file was auto-generated by a script. +# DO NOT edit this file directly. Instead, send a pull request to change +# https://github.com/Kong/kong/tree/master/autodoc/pdk/ldoc/ldoc.ltp +# or its associated files +# +title: kong.ip +pdk: true +toc: true +source_url: https://github.com/Kong/kong/tree/master/kong/pdk +--- + +Trusted IPs module. + + This module can be used to determine whether or not a given IP address is + in the range of trusted IP addresses defined by the `trusted_ips` configuration + property. + + Trusted IP addresses are those that are known to send correct replacement + addresses for clients (as per the chosen header field, for example + X-Forwarded-*). + + See the [documentation on trusted IPs](https://docs.konghq.com/gateway/latest/reference/configuration/#trusted_ips). + + + + +## kong.ip.is_trusted(address) + +Depending on the `trusted_ips` configuration property, + this function returns whether a given IP is trusted or not. + + Both ipv4 and ipv6 are supported. + + +**Phases** + +* init_worker, certificate, rewrite, access, header_filter, response, body_filter, log + +**Parameters** + +* **address** (`string`): A string representing an IP address. + +**Returns** + +* `boolean`: `true` if the IP is trusted, `false` otherwise. + + +**Usage** + +``` lua +if kong.ip.is_trusted("1.1.1.1") then + kong.log("The IP is trusted") +end +``` diff --git a/src/gateway/plugin-development/pdk/kong.log.md b/src/gateway/plugin-development/pdk/kong.log.md new file mode 100644 index 000000000000..3886d570a952 --- /dev/null +++ b/src/gateway/plugin-development/pdk/kong.log.md @@ -0,0 +1,450 @@ +--- +# +# WARNING: this file was auto-generated by a script. +# DO NOT edit this file directly. Instead, send a pull request to change +# https://github.com/Kong/kong/tree/master/autodoc/pdk/ldoc/ldoc.ltp +# or its associated files +# +title: kong.log +pdk: true +toc: true +source_url: https://github.com/Kong/kong/tree/master/kong/pdk +--- + +This namespace contains an instance of a logging facility, which is a + table containing all of the methods described below. + + This instance is namespaced per plugin. Before + executing a plugin, Kong swaps this instance with a logging facility + dedicated to the plugin. This allows the logs to be prefixed with the + plugin's name for debugging purposes. + + + + +## kong.log(...) + +Writes a log line to the location specified by the current Nginx + configuration block's `error_log` directive, with the `notice` level (similar + to `print()`). + + The Nginx `error_log` directive is set via the `log_level`, `proxy_error_log` + and `admin_error_log` Kong configuration properties. + + Arguments given to this function are concatenated similarly to + `ngx.log()`, and the log line reports the Lua file and line number from + which it was invoked. Unlike `ngx.log()`, this function prefixes error + messages with `[kong]` instead of `[lua]`. + + Arguments given to this function can be of any type, but table arguments + are converted to strings via `tostring` (thus potentially calling a + table's `__tostring` metamethod if set). This behavior differs from + `ngx.log()` (which only accepts table arguments if they define the + `__tostring` metamethod) with the intent to simplify its usage and be more + forgiving and intuitive. + + Produced log lines have the following format when logging is invoked from + within the core: + + ``` plain + [kong] %file_src:%line_src %message + ``` + + In comparison, log lines produced by plugins have the following format: + + ``` plain + [kong] %file_src:%line_src [%namespace] %message + ``` + + Where: + + * `%namespace`: The configured namespace (in this case, the plugin name). + * `%file_src`: The filename the log was called from. + * `%line_src`: The line number the log was called from. + * `%message`: The message, made of concatenated arguments given by the caller. + + For example, the following call: + + ``` lua + kong.log("hello ", "world") + ``` + + would, within the core, produce a log line similar to: + + ``` plain + 2017/07/09 19:36:25 [notice] 25932#0: *1 [kong] some_file.lua:54 hello world, client: 127.0.0.1, server: localhost, request: "GET /log HTTP/1.1", host: "localhost" + ``` + + If invoked from within a plugin (for example, `key-auth`) it would include the + namespace prefix: + + ``` plain + 2017/07/09 19:36:25 [notice] 25932#0: *1 [kong] some_file.lua:54 [key-auth] hello world, client: 127.0.0.1, server: localhost, request: "GET /log HTTP/1.1", host: "localhost" + ``` + + +**Phases** + +* init_worker, certificate, rewrite, access, header_filter, response, body_filter, log + +**Parameters** + +* **...** : All params will be concatenated and stringified before being sent to the log. + +**Returns** + +* Nothing. Throws an error on invalid inputs. + + +**Usage** + +``` lua +kong.log("hello ", "world") -- alias to kong.log.notice() +``` + + + +## kong.log.LEVEL(...) + +Similar to `kong.log()`, but the produced log has the severity given by + ``, instead of `notice`. The supported levels are: + + * `kong.log.alert()` + * `kong.log.crit()` + * `kong.log.err()` + * `kong.log.warn()` + * `kong.log.notice()` + * `kong.log.info()` + * `kong.log.debug()` + + Logs have the same format as that of `kong.log()`. For + example, the following call: + + ``` lua + kong.log.err("hello ", "world") + ``` + + would, within the core, produce a log line similar to: + + ``` plain + 2017/07/09 19:36:25 [error] 25932#0: *1 [kong] some_file.lua:54 hello world, client: 127.0.0.1, server: localhost, request: "GET /log HTTP/1.1", host: "localhost" + ``` + + If invoked from within a plugin (for example, `key-auth`) it would include the + namespace prefix: + + ``` plain + 2017/07/09 19:36:25 [error] 25932#0: *1 [kong] some_file.lua:54 [key-auth] hello world, client: 127.0.0.1, server: localhost, request: "GET /log HTTP/1.1", host: "localhost" + ``` + + +**Phases** + +* init_worker, certificate, rewrite, access, header_filter, response, body_filter, log + +**Parameters** + +* **...** : All params will be concatenated and stringified before being sent to the log. + +**Returns** + +* Nothing. Throws an error on invalid inputs. + + +**Usage** + +``` lua +kong.log.warn("something require attention") +kong.log.err("something failed: ", err) +kong.log.alert("something requires immediate action") +``` + + + +## kong.log.deprecation(...) + +Write a deprecation log line (similar to `kong.log.warn`). + + Arguments given to this function can be of any type, but table arguments + are converted to strings via `tostring` (thus potentially calling a + table's `__tostring` metamethod if set). When the last argument is a table, + it is considered as a deprecation metadata. The table can include the + following properties: + + ``` lua + { + after = "2.5.0", -- deprecated after Kong version 2.5.0 (defaults to `nil`) + removal = "3.0.0", -- about to be removed with Kong version 3.0.0 (defaults to `nil`) + trace = true, -- writes stack trace along with the deprecation message (defaults to `nil`) + } + ``` + + For example, the following call: + + ``` lua + kong.log.deprecation("hello ", "world") + ``` + + would, within the core, produce a log line similar to: + + ``` plain + 2017/07/09 19:36:25 [warn] 25932#0: *1 [kong] some_file.lua:54 hello world, client: 127.0.0.1, server: localhost, request: "GET /log HTTP/1.1", host: "localhost" + ``` + + If invoked from within a plugin (for example, `key-auth`) it would include the + namespace prefix: + + ``` plain + 2017/07/09 19:36:25 [warn] 25932#0: *1 [kong] some_file.lua:54 [key-auth] hello world, client: 127.0.0.1, server: localhost, request: "GET /log HTTP/1.1", host: "localhost" + ``` + + And with metatable, the following call: + + ``` lua + kong.log.deprecation("hello ", "world", { after = "2.5.0", removal = "3.0.0" }) + ``` + + would, within the core, produce a log line similar to: + + ``` plain + 2017/07/09 19:36:25 [warn] 25932#0: *1 [kong] some_file.lua:54 hello world (deprecated after 2.5.0, scheduled for removal in 3.0.0), client: 127.0.0.1, server: localhost, request: "GET /log HTTP/1.1", host: "localhost" + ``` + + +**Phases** + +* init_worker, certificate, rewrite, access, header_filter, response, body_filter, log + +**Parameters** + +* **...** : all params will be concatenated and stringified before being sent to the log + (if the last param is a table, it is considered as a deprecation metadata) + +**Returns** + +* Nothing; throws an error on invalid inputs. + + +**Usage** + +``` lua +kong.log.deprecation("hello ", "world") +kong.log.deprecation("hello ", "world", { after = "2.5.0" }) +kong.log.deprecation("hello ", "world", { removal = "3.0.0" }) +kong.log.deprecation("hello ", "world", { after = "2.5.0", removal = "3.0.0" }) +kong.log.deprecation("hello ", "world", { trace = true }) +``` + + + +## kong.log.inspect(...) + +Like `kong.log()`, this function produces a log with a `notice` level + and accepts any number of arguments. If inspect logging is disabled + via `kong.log.inspect.off()`, then this function prints nothing, and is + aliased to a "NOP" function to save CPU cycles. + + This function differs from `kong.log()` in the sense that arguments will be + concatenated with a space(`" "`), and each argument is + pretty-printed: + + * Numbers are printed (e.g. `5` -> `"5"`) + * Strings are quoted (e.g. `"hi"` -> `'"hi"'`) + * Array-like tables are rendered (e.g. `{1,2,3}` -> `"{1, 2, 3}"`) + * Dictionary-like tables are rendered on multiple lines + + This function is intended for debugging, and usage + in production code paths should be avoided due to the expensive formatting + operations it can perform. Existing statements can be left in production code + but nopped by calling `kong.log.inspect.off()`. + + When writing logs, `kong.log.inspect()` always uses its own format, defined + as: + + ``` plain + %file_src:%func_name:%line_src %message + ``` + + Where: + + * `%file_src`: The filename the log was called from. + * `%func_name`: The name of the function the log was called from. + * `%line_src`: The line number the log was called from. + * `%message`: The message, made of concatenated, pretty-printed arguments + given by the caller. + + This function uses the [inspect.lua](https://github.com/kikito/inspect.lua) + library to pretty-print its arguments. + + +**Phases** + +* init_worker, certificate, rewrite, access, header_filter, response, body_filter, log + +**Parameters** + +* **...** : Parameters are concatenated with spaces between them and + rendered as described. + +**Usage** + +``` lua +kong.log.inspect("some value", a_variable) +``` + + + +## kong.log.inspect.on() + +Enables inspect logs for this logging facility. Calls to + `kong.log.inspect` will be writing log lines with the appropriate + formatting of arguments. + + +**Phases** + +* init_worker, certificate, rewrite, access, header_filter, response, body_filter, log + +**Usage** + +``` lua +kong.log.inspect.on() +``` + + + +## kong.log.inspect.off() + +Disables inspect logs for this logging facility. All calls to + `kong.log.inspect()` will be nopped. + + +**Phases** + +* init_worker, certificate, rewrite, access, header_filter, response, body_filter, log + +**Usage** + +``` lua +kong.log.inspect.off() +``` + + + +## kong.log.set_serialize_value(key, value, options) + +Sets a value to be used on the `serialize` custom table. + + Logging plugins use the output of `kong.log.serialize()` as a base for their logs. + This function lets you customize the log output. + + It can be used to replace existing values in the output, or to delete + existing values by passing `nil`. + + **Note:** The type-checking of the `value` parameter can take some time, so + it is deferred to the `serialize()` call, which happens in the log + phase in most real-usage cases. + + +**Phases** + +* certificate, rewrite, access, header_filter, response, body_filter, log + +**Parameters** + +* **key** (`string`): The name of the field. +* **value** (`number|string|boolean|table`): Value to be set. When a table is used, its keys must be numbers, strings, or booleans, and its values can be numbers, strings, or other tables like itself, recursively. +* **options** (`table`): Can contain two entries: options.mode can be `set` (the default, always sets), `add` (only add if entry does not already exist) and `replace` (only change value if it already exists). + +**Returns** + +* `table`: The request information table. + + +**Usage** + +``` lua +-- Adds a new value to the serialized table +kong.log.set_serialize_value("my_new_value", 1) +assert(kong.log.serialize().my_new_value == 1) + +-- Value can be a table +kong.log.set_serialize_value("my", { new = { value = 2 } }) +assert(kong.log.serialize().my.new.value == 2) + +-- It is possible to change an existing serialized value +kong.log.set_serialize_value("my_new_value", 3) +assert(kong.log.serialize().my_new_value == 3) + +-- Unset an existing value by setting it to nil +kong.log.set_serialize_value("my_new_value", nil) +assert(kong.log.serialize().my_new_value == nil) + +-- Dots in the key are interpreted as table accesses +kong.log.set_serialize_value("my.new.value", 4) +assert(kong.log.serialize().my.new_value == 4) +``` + + + +## kong.log.serialize() + +Generates a table with useful information for logging. + + This method can be used in the `http` subsystem. + + The following fields are included in the returned table: + * `client_ip` - client IP address in textual format. + * `latencies` - request/proxy latencies. + * `request.headers` - request headers. + * `request.method` - request method. + * `request.querystring` - request query strings. + * `request.size` - size of request. + * `request.url` and `request.uri` - URL and URI of request. + * `response.headers` - response headers. + * `response.size` - size of response. + * `response.status` - response HTTP status code. + * `route` - route object matched. + * `service` - service object used. + * `started_at` - timestamp this request came in, in milliseconds. + * `tries` - Upstream information; this is an array and if any balancer retries occurred, will contain more than one entry. + * `upstream_uri` - request URI sent to Upstream. + + The following fields are only present in an authenticated request (with consumer): + + * `authenticated_entity` - credential used for authentication. + * `consumer` - consumer entity accessing the resource. + + The following fields are only present in a TLS/HTTPS request: + * `request.tls.version` - TLS/SSL version used by the connection. + * `request.tls.cipher` - TLS/SSL cipher used by the connection. + * `request.tls.client_verify` - mTLS validation result. Contents are the same as described in [$ssl_client_verify](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#var_ssl_client_verify). + + **Warning:** This function may return sensitive data (e.g., API keys). + Consider filtering before writing it to unsecured locations. + + All fields in the returned table may be altered using `kong.log.set_serialize_value`. + + The following HTTP authentication headers are redacted by default, if they appear in the request: + * `request.headers.authorization` + * `request.headers.proxy-authorization` + + To see what content is present in your setup, enable any of the logging + plugins (e.g., `file-log`) and the output written to the log file is the table + returned by this function JSON-encoded. + + +**Phases** + +* log + +**Returns** + +* `table`: the request information table + + +**Usage** + +``` lua +kong.log.serialize() +``` diff --git a/src/gateway/plugin-development/pdk/kong.nginx.md b/src/gateway/plugin-development/pdk/kong.nginx.md new file mode 100644 index 000000000000..b26ef2c891e8 --- /dev/null +++ b/src/gateway/plugin-development/pdk/kong.nginx.md @@ -0,0 +1,70 @@ +--- +# +# WARNING: this file was auto-generated by a script. +# DO NOT edit this file directly. Instead, send a pull request to change +# https://github.com/Kong/kong/tree/master/autodoc/pdk/ldoc/ldoc.ltp +# or its associated files +# +title: kong.nginx +pdk: true +toc: true +source_url: https://github.com/Kong/kong/tree/master/kong/pdk +--- + +Nginx information module. + + A set of functions for retrieving Nginx-specific implementation + details and meta information. + + + +## kong.nginx.get_subsystem() + +Returns the current Nginx subsystem this function is called from. Can be + one of `"http"` or `"stream"`. + + +**Phases** + +* any + +**Returns** + +* `string`: Subsystem, either `"http"` or `"stream"`. + + +**Usage** + +``` lua +kong.nginx.get_subsystem() -- "http" +``` + + + +## kong.nginx.get_statistics() + +Returns various connection and request metrics exposed by + Nginx, similar to those reported by the + [ngx_http_stub_status_module](https://nginx.org/en/docs/http/ngx_http_stub_status_module.html#data). + + The following fields are included in the returned table: + * `connections_active` - the current number of active client connections including `connections_waiting`. + * `connections_reading` - the current number of connections where nginx is reading the request header. + * `connections_writing` - the current number of connections where nginx is writing the response back to the client. + * `connections_waiting` - the current number of idle client connections waiting for a request. + * `connections_accepted` - the total number of accepted client connections. + * `connections_handled` - the total number of handled connections. Same as `connections_accepted` unless some resource limits have been reached + (for example, the [`worker_connections`](https://nginx.org/en/docs/ngx_core_module.html#worker_connections) limit). + * `total_requests` - the total number of client requests. + + +**Returns** + +* `table`: Nginx connections and requests statistics + + +**Usage** + +``` lua +local nginx_statistics = kong.nginx.get_statistics() +``` diff --git a/src/gateway/plugin-development/pdk/kong.node.md b/src/gateway/plugin-development/pdk/kong.node.md new file mode 100644 index 000000000000..6227a3cf64aa --- /dev/null +++ b/src/gateway/plugin-development/pdk/kong.node.md @@ -0,0 +1,123 @@ +--- +# +# WARNING: this file was auto-generated by a script. +# DO NOT edit this file directly. Instead, send a pull request to change +# https://github.com/Kong/kong/tree/master/autodoc/pdk/ldoc/ldoc.ltp +# or its associated files +# +title: kong.node +pdk: true +toc: true +source_url: https://github.com/Kong/kong/tree/master/kong/pdk +--- + +Node-level utilities. + + + +## kong.node.get_id() + +Returns the ID used by this node to describe itself. + +**Returns** + +* `string`: The v4 UUID used by this node as its ID. + + +**Usage** + +``` lua +local id = kong.node.get_id() +``` + + + +## kong.node.get_memory_stats([unit[, scale]]) + +Returns memory usage statistics about this node. + +**Parameters** + +* **unit** (`string`, _optional_): The unit that memory is reported in. Can be + any of `b/B`, `k/K`, `m/M`, or `g/G` for bytes, kibibytes, mebibytes, + or gibibytes, respectively. Defaults to `b` (bytes). +* **scale** (`number`, _optional_): The number of digits to the right of the decimal + point. Defaults to 2. + +**Returns** + +* `table`: A table containing memory usage statistics for this node. + If `unit` is `b/B` (the default), reported values are Lua numbers. + Otherwise, reported values are strings with the unit as a suffix. + + +**Usage** + +``` lua +local res = kong.node.get_memory_stats() +-- res will have the following structure: +{ + lua_shared_dicts = { + kong = { + allocated_slabs = 12288, + capacity = 24576 + }, + kong_db_cache = { + allocated_slabs = 12288, + capacity = 12288 + } + }, + workers_lua_vms = { + { + http_allocated_gc = 1102, + pid = 18004 + }, + { + http_allocated_gc = 1102, + pid = 18005 + } + } +} + +local res = kong.node.get_memory_stats("k", 1) +-- res will have the following structure: +{ + lua_shared_dicts = { + kong = { + allocated_slabs = "12.0 KiB", + capacity = "24.0 KiB", + }, + kong_db_cache = { + allocated_slabs = "12.0 KiB", + capacity = "12.0 KiB", + } + }, + workers_lua_vms = { + { + http_allocated_gc = "1.1 KiB", + pid = 18004 + }, + { + http_allocated_gc = "1.1 KiB", + pid = 18005 + } + } +} +``` + + + +## kong.node.get_hostname() + +Returns the name used by the local machine. + +**Returns** + +* `string`: The local machine hostname. + + +**Usage** + +``` lua +local hostname = kong.node.get_hostname() +``` diff --git a/src/gateway/plugin-development/pdk/kong.request.md b/src/gateway/plugin-development/pdk/kong.request.md new file mode 100644 index 000000000000..ad18c1d65e03 --- /dev/null +++ b/src/gateway/plugin-development/pdk/kong.request.md @@ -0,0 +1,734 @@ +--- +# +# WARNING: this file was auto-generated by a script. +# DO NOT edit this file directly. Instead, send a pull request to change +# https://github.com/Kong/kong/tree/master/autodoc/pdk/ldoc/ldoc.ltp +# or its associated files +# +title: kong.request +pdk: true +toc: true +source_url: https://github.com/Kong/kong/tree/master/kong/pdk +--- + +Client request module. + + This module provides a set of functions to retrieve information about the + incoming requests made by clients. + + + + +## kong.request.get_scheme() + +Returns the scheme component of the request's URL. The returned value is + normalized to lowercase form. + + +**Phases** + +* rewrite, access, header_filter, response, body_filter, log, admin_api + +**Returns** + +* `string`: A string like `"http"` or `"https"`. + + +**Usage** + +``` lua +-- Given a request to https://example.com:1234/v1/movies + +kong.request.get_scheme() -- "https" +``` + + + +## kong.request.get_host() + +Returns the host component of the request's URL, or the value of the + "Host" header. The returned value is normalized to lowercase form. + + +**Phases** + +* rewrite, access, header_filter, response, body_filter, log, admin_api + +**Returns** + +* `string`: The hostname. + + +**Usage** + +``` lua +-- Given a request to https://example.com:1234/v1/movies + +kong.request.get_host() -- "example.com" +``` + + + +## kong.request.get_port() + +Returns the port component of the request's URL. The value is returned + as a Lua number. + + +**Phases** + +* certificate, rewrite, access, header_filter, response, body_filter, log, admin_api + +**Returns** + +* `number`: The port. + + +**Usage** + +``` lua +-- Given a request to https://example.com:1234/v1/movies + +kong.request.get_port() -- 1234 +``` + + + +## kong.request.get_forwarded_scheme() + +Returns the scheme component of the request's URL, but also considers + `X-Forwarded-Proto` if it comes from a trusted source. The returned + value is normalized to lowercase. + + Whether this function considers `X-Forwarded-Proto` or not depends on + several Kong configuration parameters: + + * [trusted\_ips](https://docs.konghq.com/gateway/latest/reference/configuration/#trusted_ips) + * [real\_ip\_header](https://docs.konghq.com/gateway/latest/reference/configuration/#real_ip_header) + * [real\_ip\_recursive](https://docs.konghq.com/gateway/latest/reference/configuration/#real_ip_recursive) + + **Note**: Kong does not offer support for the Forwarded HTTP Extension + (RFC 7239) since it is not supported by ngx_http_realip_module. + + +**Phases** + +* rewrite, access, header_filter, response, body_filter, log, admin_api + +**Returns** + +* `string`: The forwarded scheme. + + +**Usage** + +``` lua +kong.request.get_forwarded_scheme() -- "https" +``` + + + +## kong.request.get_forwarded_host() + +Returns the host component of the request's URL or the value of the "host" + header. Unlike `kong.request.get_host()`, this function also considers + `X-Forwarded-Host` if it comes from a trusted source. The returned value + is normalized to lowercase. + + Whether this function considers `X-Forwarded-Host` or not depends on + several Kong configuration parameters: + + * [trusted\_ips](https://docs.konghq.com/gateway/latest/reference/configuration/#trusted_ips) + * [real\_ip\_header](https://docs.konghq.com/gateway/latest/reference/configuration/#real_ip_header) + * [real\_ip\_recursive](https://docs.konghq.com/gateway/latest/reference/configuration/#real_ip_recursive) + + **Note**: Kong does not offer support for the Forwarded HTTP Extension + (RFC 7239) since it is not supported by ngx_http_realip_module. + + +**Phases** + +* rewrite, access, header_filter, response, body_filter, log, admin_api + +**Returns** + +* `string`: The forwarded host. + + +**Usage** + +``` lua +kong.request.get_forwarded_host() -- "example.com" +``` + + + +## kong.request.get_forwarded_port() + +Returns the port component of the request's URL, but also considers + `X-Forwarded-Host` if it comes from a trusted source. The value + is returned as a Lua number. + + Whether this function considers `X-Forwarded-Proto` or not depends on + several Kong configuration parameters: + + * [trusted\_ips](https://docs.konghq.com/gateway/latest/reference/configuration/#trusted_ips) + * [real\_ip\_header](https://docs.konghq.com/gateway/latest/reference/configuration/#real_ip_header) + * [real\_ip\_recursive](https://docs.konghq.com/gateway/latest/reference/configuration/#real_ip_recursive) + + **Note**: Kong does not offer support for the Forwarded HTTP Extension + (RFC 7239) since it is not supported by ngx_http_realip_module. + + When running Kong behind the L4 port mapping (or forwarding), you can also + configure: + * [port\_maps](https://docs.konghq.com/gateway/latest/reference/configuration/#port_maps) + + The `port_maps` configuration parameter enables this function to return the + port to which the port Kong is listening to is mapped to (in case they differ). + + +**Phases** + +* rewrite, access, header_filter, response, body_filter, log, admin_api + +**Returns** + +* `number`: The forwarded port. + + +**Usage** + +``` lua +kong.request.get_forwarded_port() -- 1234 +``` + + + +## kong.request.get_forwarded_path() + +Returns the path component of the request's URL, but also considers + `X-Forwarded-Path` if it comes from a trusted source. The value + is returned as a Lua string. + + Whether this function considers `X-Forwarded-Path` or not depends on + several Kong configuration parameters: + + * [trusted\_ips](https://docs.konghq.com/gateway/latest/reference/configuration/#trusted_ips) + * [real\_ip\_header](https://docs.konghq.com/gateway/latest/reference/configuration/#real_ip_header) + * [real\_ip\_recursive](https://docs.konghq.com/gateway/latest/reference/configuration/#real_ip_recursive) + + **Note**: Kong does not do any normalization on the request path. + + +**Phases** + +* rewrite, access, header_filter, response, body_filter, log, admin_api + +**Returns** + +* `string`: The forwarded path. + + +**Usage** + +``` lua +kong.request.get_forwarded_path() -- /path +``` + + + +## kong.request.get_forwarded_prefix() + +Returns the prefix path component of the request's URL that Kong stripped + before proxying to upstream. It also checks if `X-Forwarded-Prefix` comes + from a trusted source, and uses it as-is when given. The value is returned + as a Lua string. + + If a trusted `X-Forwarded-Prefix` is not passed, this function must be + called after Kong has run its router (`access` phase), + as the Kong router may strip the prefix of the request path. That stripped + path becomes the return value of this function, unless there is already + a trusted `X-Forwarded-Prefix` header in the request. + + Whether this function considers `X-Forwarded-Prefix` or not depends on + several Kong configuration parameters: + + * [trusted\_ips](https://docs.konghq.com/gateway/latest/reference/configuration/#trusted_ips) + * [real\_ip\_header](https://docs.konghq.com/gateway/latest/reference/configuration/#real_ip_header) + * [real\_ip\_recursive](https://docs.konghq.com/gateway/latest/reference/configuration/#real_ip_recursive) + + **Note**: Kong does not do any normalization on the request path prefix. + + +**Phases** + +* rewrite, access, header_filter, response, body_filter, log, admin_api + +**Returns** + +* `string|nil`: The forwarded path prefix or `nil` if the prefix was + not stripped. + + +**Usage** + +``` lua +kong.request.get_forwarded_prefix() -- /prefix +``` + + + +## kong.request.get_http_version() + +Returns the HTTP version used by the client in the request as a Lua + number, returning values such as `1`, `1.1`, `2.0`, or `nil` for + unrecognized values. + +**Phases** + +* rewrite, access, header_filter, response, body_filter, log, admin_api + +**Returns** + +* `number|nil`: The HTTP version as a Lua number. + + +**Usage** + +``` lua +kong.request.get_http_version() -- 1.1 +``` + + + +## kong.request.get_method() + +Returns the HTTP method of the request. The value is normalized to + uppercase. + + +**Phases** + +* rewrite, access, header_filter, response, body_filter, log, admin_api + +**Returns** + +* `string`: The request method. + + +**Usage** + +``` lua +kong.request.get_method() -- "GET" +``` + + + +## kong.request.get_path() + +Returns the normalized path component of the request's URL. The return + value is the same as `kong.request.get_raw_path()` but normalized according + to RFC 3986 section 6: + + * Percent-encoded values of unreserved characters are decoded (`%20` + becomes ` `). + * Percent-encoded values of reserved characters have their hexidecimal + value uppercased (`%2f` becomes `%2F`). + * Relative path elements (`/.` and `/..`) are dereferenced. + * Duplicate slashes are consolidated (`//` becomes `/`). + + +**Phases** + +* rewrite, access, header_filter, response, body_filter, log, admin_api + +**Returns** + +* `string`: the path + + +**Usage** + +``` lua +-- Given a request to https://example.com/t/Abc%20123%C3%B8%2f/parent/..//test/./ + +kong.request.get_path() -- "/t/Abc 123ø%2F/test/" +``` + + + +## kong.request.get_raw_path() + +Returns the path component of the request's URL. It is not normalized in + any way and does not include the query string. + + **NOTE:** Using the raw path to perform string comparision during request + handling (such as in routing, ACL/authorization checks, setting rate-limit + keys, etc) is widely regarded as insecure, as it can leave plugin code + vulnerable to path traversal attacks. Prefer `kong.request.get_path()` for + such use cases. + + +**Phases** + +* rewrite, access, header_filter, response, body_filter, log, admin_api + +**Returns** + +* `string`: The path. + + +**Usage** + +``` lua +-- Given a request to https://example.com/t/Abc%20123%C3%B8%2f/parent/..//test/./?movie=foo + +kong.request.get_raw_path() -- "/t/Abc%20123%C3%B8%2f/parent/..//test/./" +``` + + + +## kong.request.get_path_with_query() + +Returns the path, including the query string if any. No + transformations or normalizations are done. + + +**Phases** + +* rewrite, access, header_filter, response, body_filter, log, admin_api + +**Returns** + +* `string`: The path with the query string. + + +**Usage** + +``` lua +-- Given a request to https://example.com:1234/v1/movies?movie=foo + +kong.request.get_path_with_query() -- "/v1/movies?movie=foo" +``` + + + +## kong.request.get_raw_query() + +Returns the query component of the request's URL. It is not normalized in + any way (not even URL-decoding of special characters) and does not + include the leading `?` character. + + +**Phases** + +* rewrite, access, header_filter, response, body_filter, log, admin_api + +**Returns** + +* `string`: The query component of the request's URL. + + +**Usage** + +``` lua +-- Given a request to https://example.com/foo?msg=hello%20world&bla=&bar + +kong.request.get_raw_query() -- "msg=hello%20world&bla=&bar" +``` + + + +## kong.request.get_query_arg() + +Returns the value of the specified argument, obtained from the query + arguments of the current request. + + The returned value is either a `string`, a boolean `true` if an + argument was not given a value, or `nil` if no argument with `name` was + found. + + If an argument with the same name is present multiple times in the + query string, this function returns the value of the first occurrence. + + +**Phases** + +* rewrite, access, header_filter, response, body_filter, log, admin_api + +**Returns** + +* `string|boolean|nil`: The value of the argument. + + +**Usage** + +``` lua +-- Given a request GET /test?foo=hello%20world&bar=baz&zzz&blo=&bar=bla&bar + +kong.request.get_query_arg("foo") -- "hello world" +kong.request.get_query_arg("bar") -- "baz" +kong.request.get_query_arg("zzz") -- true +kong.request.get_query_arg("blo") -- "" +``` + + + +## kong.request.get_query([max_args]) + +Returns the table of query arguments obtained from the query string. Keys + are query argument names. Values are either a string with the argument + value, a boolean `true` if an argument was not given a value, or an array + if an argument was given in the query string multiple times. Keys and + values are unescaped according to URL-encoded escaping rules. + + Note that a query string `?foo&bar` translates to two boolean `true` + arguments, and `?foo=&bar=` translates to two string arguments containing + empty strings. + + By default, this function returns up to **100** arguments. The optional + `max_args` argument can be specified to customize this limit, but must be + greater than **1** and not greater than **1000**. + + +**Phases** + +* rewrite, access, header_filter, response, body_filter, log, admin_api + +**Parameters** + +* **max_args** (`number`, _optional_): Sets a limit on the maximum number of parsed + arguments. + +**Returns** + +* `table`: A table representation of the query string. + + +**Usage** + +``` lua +-- Given a request GET /test?foo=hello%20world&bar=baz&zzz&blo=&bar=bla&bar + +for k, v in pairs(kong.request.get_query()) do + kong.log.inspect(k, v) +end + +-- Will print +-- "foo" "hello world" +-- "bar" {"baz", "bla", true} +-- "zzz" true +-- "blo" "" +``` + + + +## kong.request.get_header(name) + +Returns the value of the specified request header. + + The returned value is either a `string`, or can be `nil` if a header with + `name` was not found in the request. If a header with the same name is + present multiple times in the request, this function returns the value + of the first occurrence of this header. + + Header names in are case-insensitive and are normalized to lowercase, and + dashes (`-`) can be written as underscores (`_`); that is, the header + `X-Custom-Header` can also be retrieved as `x_custom_header`. + + +**Phases** + +* rewrite, access, header_filter, response, body_filter, log, admin_api + +**Parameters** + +* **name** (`string`): the name of the header to be returned + +**Returns** + +* `string|nil`: the value of the header or nil if not present + + +**Usage** + +``` lua +-- Given a request with the following headers: + +-- Host: foo.com +-- X-Custom-Header: bla +-- X-Another: foo bar +-- X-Another: baz + +kong.request.get_header("Host") -- "foo.com" +kong.request.get_header("x-custom-header") -- "bla" +kong.request.get_header("X-Another") -- "foo bar" +``` + + + +## kong.request.get_headers([max_headers]) + +Returns a Lua table holding the request headers. Keys are header names. + Values are either a string with the header value, or an array of strings + if a header was sent multiple times. Header names in this table are + case-insensitive and are normalized to lowercase, and dashes (`-`) can be + written as underscores (`_`); that is, the header `X-Custom-Header` can + also be retrieved as `x_custom_header`. + + By default, this function returns up to **100** headers. The optional + `max_headers` argument can be specified to customize this limit, but must + be greater than **1** and not greater than **1000**. + + +**Phases** + +* rewrite, access, header_filter, response, body_filter, log, admin_api + +**Parameters** + +* **max_headers** (`number`, _optional_): Sets a limit on the maximum number of + parsed headers. + +**Returns** + +* `table`: The request headers in table form. + + +**Usage** + +``` lua +-- Given a request with the following headers: + +-- Host: foo.com +-- X-Custom-Header: bla +-- X-Another: foo bar +-- X-Another: baz +local headers = kong.request.get_headers() + +headers.host -- "foo.com" +headers.x_custom_header -- "bla" +headers.x_another[1] -- "foo bar" +headers["X-Another"][2] -- "baz" +``` + + + +## kong.request.get_raw_body() + +Returns the plain request body. + + If the body has no size (empty), this function returns an empty string. + + If the size of the body is greater than the Nginx buffer size (set by + `client_body_buffer_size`), this function fails and returns an error + message explaining this limitation. + + +**Phases** + +* rewrite, access, response, admin_api + +**Returns** + +* `string`: The plain request body. + + +**Usage** + +``` lua +-- Given a body with payload "Hello, Earth!": + +kong.request.get_raw_body():gsub("Earth", "Mars") -- "Hello, Mars!" +``` + + + +## kong.request.get_body([mimetype[, max_args]]) + +Returns the request data as a key/value table. + A high-level convenience function. + + The body is parsed with the most appropriate format: + + * If `mimetype` is specified, it decodes the body with the requested + content type (if supported). This takes precedence over any content type + present in the request. + + The optional argument `mimetype` can be one of the following strings: + * `application/x-www-form-urlencoded` + * `application/json` + * `multipart/form-data` + + Whether `mimetype` is specified or a request content type is otherwise + present in the request, each content type behaves as follows: + + * If the request content type is `application/x-www-form-urlencoded`: + * Returns the body as form-encoded. + * If the request content type is `multipart/form-data`: + * Decodes the body as multipart form data + (same as `multipart(kong.request.get_raw_body(), + kong.request.get_header("Content-Type")):get_all()` ). + * If the request content type is `application/json`: + * Decodes the body as JSON + (same as `json.decode(kong.request.get_raw_body())`). + * JSON types are converted to matching Lua types. + * If the request contains none of the above and the `mimetype` argument is + not set, returns `nil` and an error message indicating the + body could not be parsed. + + The optional argument `max_args` can be used to set a limit on the number + of form arguments parsed for `application/x-www-form-urlencoded` payloads. + + The third return value is string containing the mimetype used to parsed + the body (as per the `mimetype` argument), allowing the caller to identify + what MIME type the body was parsed as. + + +**Phases** + +* rewrite, access, response, admin_api + +**Parameters** + +* **mimetype** (`string`, _optional_): The MIME type. +* **max_args** (`number`, _optional_): Sets a limit on the maximum number of parsed + arguments. + +**Returns** + +1. `table|nil`: A table representation of the body. + +1. `string|nil`: An error message. + +1. `string|nil`: mimetype The MIME type used. + + +**Usage** + +``` lua +local body, err, mimetype = kong.request.get_body() +body.name -- "John Doe" +body.age -- "42" +``` + + + +## kong.request.get_start_time() + +Returns the request start time, in Unix epoch milliseconds. + +**Phases** + +* rewrite, access, header_filter, response, body_filter, log, admin_api + +**Returns** + +* `number`: The timestamp + + +**Usage** + +``` lua +kong.request.get_start_time() -- 1649960273000 +``` diff --git a/src/gateway/plugin-development/pdk/kong.response.md b/src/gateway/plugin-development/pdk/kong.response.md new file mode 100644 index 000000000000..e6329f6aef9d --- /dev/null +++ b/src/gateway/plugin-development/pdk/kong.response.md @@ -0,0 +1,631 @@ +--- +# +# WARNING: this file was auto-generated by a script. +# DO NOT edit this file directly. Instead, send a pull request to change +# https://github.com/Kong/kong/tree/master/autodoc/pdk/ldoc/ldoc.ltp +# or its associated files +# +title: kong.response +pdk: true +toc: true +source_url: https://github.com/Kong/kong/tree/master/kong/pdk +--- + +Client response module. + + The downstream response module contains a set of functions for producing and + manipulating responses sent back to the client (downstream). Responses can + be produced by Kong (for example, an authentication plugin rejecting a + request), or proxied back from an Service's response body. + + Unlike `kong.service.response`, this module allows mutating the response + before sending it back to the client. + + + + +## kong.response.get_status() + +Returns the HTTP status code currently set for the downstream response (as + a Lua number). + + If the request was proxied (as per `kong.response.get_source()`), the + return value is the response from the Service (identical to + `kong.service.response.get_status()`). + + If the request was _not_ proxied and the response was produced by Kong + itself (i.e. via `kong.response.exit()`), the return value is + returned as-is. + + +**Phases** + +* header_filter, response, body_filter, log, admin_api + +**Returns** + +* `number`: status The HTTP status code currently set for the + downstream response. + + +**Usage** + +``` lua +kong.response.get_status() -- 200 +``` + + + +## kong.response.get_header(name) + +Returns the value of the specified response header, as would be seen by + the client once received. + + The list of headers returned by this function can consist of both response + headers from the proxied Service _and_ headers added by Kong (e.g. via + `kong.response.add_header()`). + + The return value is either a `string`, or can be `nil` if a header with + `name` is not found in the response. If a header with the same name is + present multiple times in the request, this function returns the value + of the first occurrence of this header. + + +**Phases** + +* header_filter, response, body_filter, log, admin_api + +**Parameters** + +* **name** (`string`): The name of the header. + + Header names are case-insensitive and dashes (`-`) can be written as + underscores (`_`). For example, the header `X-Custom-Header` can also be + retrieved as `x_custom_header`. + + +**Returns** + +* `string|nil`: The value of the header. + + +**Usage** + +``` lua +-- Given a response with the following headers: +-- X-Custom-Header: bla +-- X-Another: foo bar +-- X-Another: baz + +kong.response.get_header("x-custom-header") -- "bla" +kong.response.get_header("X-Another") -- "foo bar" +kong.response.get_header("X-None") -- nil +``` + + + +## kong.response.get_headers([max_headers]) + +Returns a Lua table holding the response headers. Keys are header names. + Values are either a string with the header value, or an array of strings + if a header was sent multiple times. Header names in this table are + case-insensitive and are normalized to lowercase, and dashes (`-`) can be + written as underscores (`_`). For example, the header `X-Custom-Header` can + also be retrieved as `x_custom_header`. + + A response initially has no headers. Headers are added when a plugin + short-circuits the proxying by producing a header + (e.g. an authentication plugin rejecting a request), or if the request has + been proxied, and one of the latter execution phases is currently running. + + Unlike `kong.service.response.get_headers()`, this function returns *all* + headers as the client would see them upon reception, including headers + added by Kong itself. + + By default, this function returns up to **100** headers. The optional + `max_headers` argument can be specified to customize this limit, but must + be greater than **1** and equal to or less than **1000**. + + +**Phases** + +* header_filter, response, body_filter, log, admin_api + +**Parameters** + +* **max_headers** (`number`, _optional_): Limits the number of headers parsed. + +**Returns** + +1. `table`: headers A table representation of the headers in the + response. + + +1. `string`: err If more headers than `max_headers` were present, + returns a string with the error `"truncated"`. + + +**Usage** + +``` lua +-- Given an response from the Service with the following headers: +-- X-Custom-Header: bla +-- X-Another: foo bar +-- X-Another: baz + +local headers = kong.response.get_headers() + +headers.x_custom_header -- "bla" +headers.x_another[1] -- "foo bar" +headers["X-Another"][2] -- "baz" +``` + + + +## kong.response.get_source() + +This function helps determine where the current response originated + from. Since Kong is a reverse proxy, it can short-circuit a request and + produce a response of its own, or the response can come from the proxied + Service. + + Returns a string with three possible values: + + * `"exit"` is returned when, at some point during the processing of the + request, there has been a call to `kong.response.exit()`. This happens + when the request was short-circuited by a plugin or by Kong + itself (e.g. invalid credentials). + * `"error"` is returned when an error has happened while processing the + request. For example, a timeout while connecting to the upstream + service. + * `"service"` is returned when the response was originated by successfully + contacting the proxied Service. + + +**Phases** + +* header_filter, response, body_filter, log, admin_api + +**Returns** + +* `string`: The source. + + +**Usage** + +``` lua +if kong.response.get_source() == "service" then + kong.log("The response comes from the Service") +elseif kong.response.get_source() == "error" then + kong.log("There was an error while processing the request") +elseif kong.response.get_source() == "exit" then + kong.log("There was an early exit while processing the request") +end +``` + + + +## kong.response.set_status(status) + +Allows changing the downstream response HTTP status code before sending it + to the client. + +**Phases** + +* rewrite, access, header_filter, response, admin_api + +**Parameters** + +* **status** (`number`): The new status. + +**Returns** + +* Nothing; throws an error on invalid input. + + +**Usage** + +``` lua +kong.response.set_status(404) +``` + + + +## kong.response.set_header(name, value) + +Sets a response header with the given value. This function overrides any + existing header with the same name. + + Note: Underscores in header names are automatically transformed into dashes + by default. If you want to deactivate this behavior, set the + `lua_transform_underscores_in_response_headers` Nginx config option to `off`. + + This setting can be set in the Kong Config file: + + nginx_http_lua_transform_underscores_in_response_headers = off + + Be aware that changing this setting might break any plugins that + rely on the automatic underscore conversion. + You cannot set Transfer-Encoding header with this function. It will be ignored. + + +**Phases** + +* rewrite, access, header_filter, response, admin_api + +**Parameters** + +* **name** (`string`): The name of the header +* **value** (`string|number|boolean`): The new value for the header. + +**Returns** + +* Nothing; throws an error on invalid input. + + +**Usage** + +``` lua +kong.response.set_header("X-Foo", "value") +``` + + + +## kong.response.add_header(name, value) + +Adds a response header with the given value. Unlike + `kong.response.set_header()`, this function does not remove any existing + header with the same name. Instead, another header with the same name is + added to the response. If no header with this name already exists on + the response, then it is added with the given value, similarly to + `kong.response.set_header().` + + +**Phases** + +* rewrite, access, header_filter, response, admin_api + +**Parameters** + +* **name** (`string`): The header name. +* **value** (`string|number|boolean`): The header value. + +**Returns** + +* Nothing; throws an error on invalid input. + + +**Usage** + +``` lua +kong.response.add_header("Cache-Control", "no-cache") +kong.response.add_header("Cache-Control", "no-store") +``` + + + +## kong.response.clear_header(name) + +Removes all occurrences of the specified header in the response sent to + the client. + +**Phases** + +* rewrite, access, header_filter, response, admin_api + +**Parameters** + +* **name** (`string`): The name of the header to be cleared + +**Returns** + +* Nothing; throws an error on invalid input. + + +**Usage** + +``` lua +kong.response.set_header("X-Foo", "foo") +kong.response.add_header("X-Foo", "bar") + +kong.response.clear_header("X-Foo") +-- from here onwards, no X-Foo headers will exist in the response +``` + + + +## kong.response.set_headers(headers) + +Sets the headers for the response. Unlike `kong.response.set_header()`, + the `headers` argument must be a table in which each key is a string + corresponding to a header's name, and each value is a string, or an + array of strings. + + The resulting headers are produced in lexicographical order. The order of + entries with the same name (when values are given as an array) is + retained. + + This function overrides any existing header bearing the same name as those + specified in the `headers` argument. Other headers remain unchanged. + + You cannot set Transfer-Encoding header with this function. It will be ignored. + + +**Phases** + +* rewrite, access, header_filter, response, admin_api + +**Parameters** + +* **headers** (`table`): + +**Returns** + +* Nothing; throws an error on invalid input. + + +**Usage** + +``` lua +kong.response.set_headers({ + ["Bla"] = "boo", + ["X-Foo"] = "foo3", + ["Cache-Control"] = { "no-store", "no-cache" } +}) + +-- Will add the following headers to the response, in this order: +-- X-Bar: bar1 +-- Bla: boo +-- Cache-Control: no-store +-- Cache-Control: no-cache +-- X-Foo: foo3 +``` + + + +## kong.response.get_raw_body() + +Returns the full body when the last chunk has been read. + + Calling this function starts buffering the body in + an internal request context variable, and sets the current + chunk (`ngx.arg[1]`) to `nil` when the chunk is not the + last one. When it reads the last chunk, the function returns the full + buffered body. + + +**Phases** + +* `body_filter` + +**Returns** + +* `string`: body The full body when the last chunk has been read, + otherwise returns `nil`. + + +**Usage** + +``` lua +local body = kong.response.get_raw_body() +if body then + body = transform(body) + kong.response.set_raw_body(body) +end +``` + + + +## kong.response.set_raw_body(body) + +Sets the body of the response. + + The `body` argument must be a string and is not processed in any way. + This function can't change the `Content-Length` header if one was + added. If you decide to use this function, the `Content-Length` header + should also be cleared, for example in the `header_filter` phase. + + +**Phases** + +* `body_filter` + +**Parameters** + +* **body** (`string`): The raw body. + +**Returns** + +* Nothing; throws an error on invalid inputs. + + +**Usage** + +``` lua +kong.response.set_raw_body("Hello, world!") +-- or +local body = kong.response.get_raw_body() +if body then + body = transform(body) + kong.response.set_raw_body(body) +end +``` + + + +## kong.response.exit(status[, body[, headers]]) + +This function interrupts the current processing and produces a response. + It is typical to see plugins using it to produce a response before Kong + has a chance to proxy the request (e.g. an authentication plugin rejecting + a request, or a caching plugin serving a cached response). + + It is recommended to use this function in conjunction with the `return` + operator, to better reflect its meaning: + + ```lua + return kong.response.exit(200, "Success") + ``` + + Calling `kong.response.exit()` interrupts the execution flow of + plugins in the current phase. Subsequent phases will still be invoked. + For example, if a plugin calls `kong.response.exit()` in the `access` + phase, no other plugin is executed in that phase, but the + `header_filter`, `body_filter`, and `log` phases are still executed, + along with their plugins. Plugins should be programmed defensively + against cases when a request is **not** proxied to the Service, but + instead is produced by Kong itself. + + 1. The first argument `status` sets the status code of the response that + is seen by the client. + + In L4 proxy mode, the `status` code provided is primarily for logging + and statistical purposes, and is not visible to the client directly. + In this mode, only the following status codes are supported: + + * 200 - OK + * 400 - Bad request + * 403 - Forbidden + * 500 - Internal server error + * 502 - Bad gateway + * 503 - Service unavailable + + 2. The second, optional, `body` argument sets the response body. If it is + a string, no special processing is done, and the body is sent + as-is. It is the caller's responsibility to set the appropriate + `Content-Type` header via the third argument. + + As a convenience, `body` can be specified as a table. In that case, + the `body` is JSON-encoded and has the `application/json` Content-Type + header set. + + On gRPC, we cannot send the `body` with this function, so + it sends `"body"` in the `grpc-message` header instead. + * If the body is a table, it looks for the `message` field in the body, + and uses that as a `grpc-message` header. + * If you specify `application/grpc` in the `Content-Type` header, the + body is sent without needing the `grpc-message` header. + + In L4 proxy mode, `body` can only be `nil` or a string. Automatic JSON + encoding is not available. When `body` is provided, depending on the + value of `status`, the following happens: + + * When `status` is 500, 502 or 503, then `body` is logged in the Kong + error log file. + * When the `status` is anything else, `body` is sent back to the L4 client. + + 3. The third, optional, `headers` argument can be a table specifying + response headers to send. If specified, its behavior is similar to + `kong.response.set_headers()`. This argument is ignored in L4 proxy mode. + + Unless manually specified, this method automatically sets the + `Content-Length` header in the produced response for convenience. + +**Phases** + +* preread, rewrite, access, admin_api, header_filter (only if `body` is nil) + +**Parameters** + +* **status** (`number`): The status to be used. +* **body** (`table|string`, _optional_): The body to be used. +* **headers** (`table`, _optional_): The headers to be used. + +**Returns** + +* Nothing; throws an error on invalid input. + + +**Usage** + +``` lua +return kong.response.exit(403, "Access Forbidden", { + ["Content-Type"] = "text/plain", + ["WWW-Authenticate"] = "Basic" +}) + +--- + +return kong.response.exit(403, [[{"message":"Access Forbidden"}]], { + ["Content-Type"] = "application/json", + ["WWW-Authenticate"] = "Basic" +}) + +--- + +return kong.response.exit(403, { message = "Access Forbidden" }, { + ["WWW-Authenticate"] = "Basic" +}) + +--- + +-- In L4 proxy mode +return kong.response.exit(200, "Success") +``` + + + +## kong.response.error(status[, message[, headers]]) + +This function interrupts the current processing and produces an error + response. + + It is recommended to use this function in conjunction with the `return` + operator, to better reflect its meaning: + + ```lua + return kong.response.error(500, "Error", {["Content-Type"] = "text/html"}) + ``` + + 1. The `status` argument sets the status code of the response that + is seen by the client. The status code must an error code, that is, + greater than 399. + + 2. The optional `message` argument sets the message describing + the error, which is written in the body. + + 3. The optional `headers` argument can be a table specifying response + headers to send. If specified, its behavior is similar to + `kong.response.set_headers()`. + + This method sends the response formatted in JSON, XML, HTML or plaintext. + The actual format is determined using one of the following options, in + this order: + - Manually specified in the `headers` argument using the `Content-Type` + header. + - Conforming to the `Accept` header from the request. + - If there is no setting in the `Content-Type` or `Accept` header, the + response defaults to JSON format. Also see the `Content-Length` + header in the produced response for convenience. + +**Phases** + +* rewrite, access, admin_api, header_filter (only if `body` is nil) + +**Parameters** + +* **status** (`number`): The status to be used (>399). +* **message** (`string`, _optional_): The error message to be used. +* **headers** (`table`, _optional_): The headers to be used. + +**Returns** + +* Nothing; throws an error on invalid input. + + +**Usage** + +``` lua +return kong.response.error(403, "Access Forbidden", { + ["Content-Type"] = "text/plain", + ["WWW-Authenticate"] = "Basic" +}) + +--- + +return kong.response.error(403, "Access Forbidden") + +--- + +return kong.response.error(403) +``` diff --git a/src/gateway/plugin-development/pdk/kong.router.md b/src/gateway/plugin-development/pdk/kong.router.md new file mode 100644 index 000000000000..2198a443f975 --- /dev/null +++ b/src/gateway/plugin-development/pdk/kong.router.md @@ -0,0 +1,68 @@ +--- +# +# WARNING: this file was auto-generated by a script. +# DO NOT edit this file directly. Instead, send a pull request to change +# https://github.com/Kong/kong/tree/master/autodoc/pdk/ldoc/ldoc.ltp +# or its associated files +# +title: kong.router +pdk: true +toc: true +source_url: https://github.com/Kong/kong/tree/master/kong/pdk +--- + +Router module. + + A set of functions to access the routing properties of the request. + + + + +## kong.router.get_route() + +Returns the current `route` entity. The request is matched against this + route. + + +**Phases** + +* access, header_filter, response, body_filter, log + +**Returns** + +* `table`: The `route` entity. + + +**Usage** + +``` lua +local route = kong.router.get_route() +local protocols = route.protocols +``` + + + +## kong.router.get_service() + +Returns the current `service` entity. The request is targeted to this + upstream service. + + +**Phases** + +* access, header_filter, response, body_filter, log + +**Returns** + +* `table`: The `service` entity. + + +**Usage** + +``` lua +if kong.router.get_service() then + -- routed by route & service entities +else + -- routed by a route without a service +end +``` diff --git a/src/gateway/plugin-development/pdk/kong.service.md b/src/gateway/plugin-development/pdk/kong.service.md new file mode 100644 index 000000000000..a78446d97474 --- /dev/null +++ b/src/gateway/plugin-development/pdk/kong.service.md @@ -0,0 +1,247 @@ +--- +# +# WARNING: this file was auto-generated by a script. +# DO NOT edit this file directly. Instead, send a pull request to change +# https://github.com/Kong/kong/tree/master/autodoc/pdk/ldoc/ldoc.ltp +# or its associated files +# +title: kong.service +pdk: true +toc: true +source_url: https://github.com/Kong/kong/tree/master/kong/pdk +--- + +The service module contains a set of functions to manipulate the connection + aspect of the request to the Service, such as connecting to a given host, IP + address/port, or choosing a given Upstream entity for load-balancing and + healthchecking. + + + +## kong.service.set_upstream(host) + +Sets the desired Upstream entity to handle the load-balancing step for + this request. Using this method is equivalent to creating a Service with a + `host` property equal to that of an Upstream entity (in which case, the + request would be proxied to one of the Targets associated with that + Upstream). + + The `host` argument should receive a string equal to the name of one of the + Upstream entities currently configured. + + +**Phases** + +* access + +**Parameters** + +* **host** (`string`): + +**Returns** + +1. `boolean|nil`: `true` on success, or `nil` if no upstream entities + where found + +1. `string|nil`: An error message describing the error if there was + one. + + + +**Usage** + +``` lua +local ok, err = kong.service.set_upstream("service.prod") +if not ok then + kong.log.err(err) + return +end +``` + + + +## kong.service.set_target(host, port) + +Sets the host and port on which to connect to for proxying the request. + Using this method is equivalent to ask Kong to not run the load-balancing + phase for this request, and consider it manually overridden. + Load-balancing components such as retries and health-checks will also be + ignored for this request. + + The `host` argument expects a string containing the IP address of the + upstream server (IPv4/IPv6), and the `port` argument must contain a number + representing the port on which to connect to. + + +**Phases** + +* access + +**Parameters** + +* **host** (`string`): +* **port** (`number`): + +**Usage** + +``` lua +kong.service.set_target("service.local", 443) +kong.service.set_target("192.168.130.1", 80) +``` + + + +## kong.service.set_tls_cert_key(chain, key) + +Sets the client certificate used while handshaking with the Service. + + The `chain` argument is the client certificate and intermediate chain (if any) + returned by functions such as [ngx.ssl.parse\_pem\_cert](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md#parse_pem_cert). + + The `key` argument is the private key corresponding to the client certificate + returned by functions such as [ngx.ssl.parse\_pem\_priv\_key](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md#parse_pem_priv_key). + + +**Phases** + +* `rewrite`, `access`, `balancer` + +**Parameters** + +* **chain** (`cdata`): The client certificate chain +* **key** (`cdata`): The client certificate private key + +**Returns** + +1. `boolean|nil`: `true` if the operation succeeded, `nil` if an error occurred + +1. `string|nil`: An error message describing the error if there was one + + +**Usage** + +``` lua +local chain = assert(ssl.parse_pem_cert(cert_data)) +local key = assert(ssl.parse_pem_priv_key(key_data)) + +local ok, err = kong.service.set_tls_cert_key(chain, key) +if not ok then + -- do something with error +end +``` + + + +## kong.service.set_tls_verify(on) + +Sets whether TLS verification is enabled while handshaking with the Service. + + The `on` argument is a boolean flag, where `true` means upstream verification + is enabled and `false` disables it. + + This call affects only the current request. If the trusted certificate store is + not set already (via [proxy_ssl_trusted_certificate](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_trusted_certificate) + or [kong.service.set_upstream_ssl_trusted_store](#kongserviceset_upstream_ssl_trusted_store)), + then TLS verification will always fail with "unable to get local issuer certificate" error. + + +**Phases** + +* `rewrite`, `access`, `balancer` + +**Parameters** + +* **on** (`boolean`): Whether to enable TLS certificate verification for the current request + +**Returns** + +1. `boolean|nil`: `true` if the operation succeeded, `nil` if an error occurred + +1. `string|nil`: An error message describing the error if there was one + + +**Usage** + +``` lua +local ok, err = kong.service.set_tls_verify(true) +if not ok then + -- do something with error +end +``` + + + +## kong.service.set_tls_verify_depth(depth) + +Sets the maximum depth of verification when validating upstream server's TLS certificate. + + This call affects only the current request. For the depth to be actually used the verification + has to be enabled with either the [proxy_ssl_verify](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_verify) + directive or using the [kong.service.set_tls_verify](#kongserviceset_tls_verify) function. + + +**Phases** + +* `rewrite`, `access`, `balancer` + +**Parameters** + +* **depth** (`number`): Depth to use when validating. Must be non-negative + +**Returns** + +1. `boolean|nil`: `true` if the operation succeeded, `nil` if an error occurred + +1. `string|nil`: An error message describing the error if there was one + + +**Usage** + +``` lua +local ok, err = kong.service.set_tls_verify_depth(3) +if not ok then + -- do something with error +end +``` + + + +## kong.service.set_tls_verify_store(store) + +Sets the CA trust store to use when validating upstream server's TLS certificate. + + This call affects only the current request. For the store to be actually used the verification + has to be enabled with either the [proxy_ssl_verify](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_verify) + directive or using the [kong.service.set_tls_verify](#kongserviceset_tls_verify) function. + + The resty.openssl.x509.store object can be created by following + [examples](https://github.com/Kong/lua-kong-nginx-module#restykongtlsset_upstream_ssl_trusted_store) from the Kong/lua-kong-nginx-module repo. + + +**Phases** + +* `rewrite`, `access`, `balancer` + +**Parameters** + +* **store** (`table`): resty.openssl.x509.store object to use + +**Returns** + +1. `boolean|nil`: `true` if the operation succeeded, `nil` if an error occurred + +1. `string|nil`: An error message describing the error if there was one + + +**Usage** + +``` lua +local store = require("resty.openssl.x509.store") +local st = assert(store.new()) +-- st:add(...certificate) + +local ok, err = kong.service.set_tls_verify_store(st) +if not ok then + -- do something with error +end +``` diff --git a/src/gateway/plugin-development/pdk/kong.service.request.md b/src/gateway/plugin-development/pdk/kong.service.request.md new file mode 100644 index 000000000000..ebbf5c002df7 --- /dev/null +++ b/src/gateway/plugin-development/pdk/kong.service.request.md @@ -0,0 +1,479 @@ +--- +# +# WARNING: this file was auto-generated by a script. +# DO NOT edit this file directly. Instead, send a pull request to change +# https://github.com/Kong/kong/tree/master/autodoc/pdk/ldoc/ldoc.ltp +# or its associated files +# +title: kong.service.request +pdk: true +toc: true +source_url: https://github.com/Kong/kong/tree/master/kong/pdk +--- + +Module for manipulating the request sent to the Service. + + + +## kong.service.request.enable_buffering() + +Enables buffered proxying, which allows plugins to access Service body and + response headers at the same time. + +**Phases** + +* `rewrite`, `access` + +**Returns** + +* Nothing. + + +**Usage** + +``` lua +kong.service.request.enable_buffering() +``` + + + +## kong.service.request.set_scheme(scheme) + +Sets the protocol to use when proxying the request to the Service. + +**Phases** + +* `access` + +**Parameters** + +* **scheme** (`string`): The scheme to be used. Supported values are `"http"` or `"https"`. + +**Returns** + +* Nothing; throws an error on invalid inputs. + + +**Usage** + +``` lua +kong.service.request.set_scheme("https") +``` + + + +## kong.service.request.set_path(path) + +Sets the path component for the request to the service. + + The input accepts any valid *normalized* URI (including UTF-8 characters) + and this API will perform necessary escaping according to the RFC + to make the request valid. + + Input should **not** include the query string. + +**Phases** + +* `access` + +**Parameters** + +* **path** (`string`): The path string. Special characters and UTF-8 + characters are allowed, for example: `"/v2/movies"` or `"/foo/😀"`. + +**Returns** + +* Nothing; throws an error on invalid inputs. + + +**Usage** + +``` lua +kong.service.request.set_path("/v2/movies") +``` + + + +## kong.service.request.set_raw_query(query) + +Sets the query string of the request to the Service. The `query` argument is a + string (without the leading `?` character), and is not processed in any + way. + + For a higher-level function to set the query string from a Lua table of + arguments, see `kong.service.request.set_query()`. + +**Phases** + +* `rewrite`, `access` + +**Parameters** + +* **query** (`string`): The raw querystring. Example: + `"foo=bar&bla&baz=hello%20world"`. + +**Returns** + +* Nothing; throws an error on invalid inputs. + + +**Usage** + +``` lua +kong.service.request.set_raw_query("zzz&bar=baz&bar=bla&bar&blo=&foo=hello%20world") +``` + + + +## kong.service.request.set_method(method) + +Sets the HTTP method for the request to the service. + +**Phases** + +* `rewrite`, `access` + +**Parameters** + +* **method** (`string`): The method string, which must be in all + uppercase. Supported values are: `"GET"`, `"HEAD"`, `"PUT"`, `"POST"`, + `"DELETE"`, `"OPTIONS"`, `"MKCOL"`, `"COPY"`, `"MOVE"`, `"PROPFIND"`, + `"PROPPATCH"`, `"LOCK"`, `"UNLOCK"`, `"PATCH"`, or `"TRACE"`. + +**Returns** + +* Nothing; throws an error on invalid inputs. + + +**Usage** + +``` lua +kong.service.request.set_method("DELETE") +``` + + + +## kong.service.request.set_query(args) + +Set the query string of the request to the Service. + + Unlike `kong.service.request.set_raw_query()`, the `query` argument must be a + table in which each key is a string (corresponding to an argument's name), and + each value is either a boolean, a string, or an array of strings or booleans. + Additionally, all string values will be URL-encoded. + + The resulting query string contains keys in their lexicographical order. The + order of entries within the same key (when values are given as an array) is + retained. + + If further control of the query string generation is needed, a raw query + string can be given as a string with `kong.service.request.set_raw_query()`. + + +**Phases** + +* `rewrite`, `access` + +**Parameters** + +* **args** (`table`): A table where each key is a string (corresponding to an + argument name), and each value is either a boolean, a string, or an array of + strings or booleans. Any string values given are URL-encoded. + +**Returns** + +* Nothing; throws an error on invalid inputs. + + +**Usage** + +``` lua +kong.service.request.set_query({ + foo = "hello world", + bar = {"baz", "bla", true}, + zzz = true, + blo = "" +}) +-- Produces the following query string: +-- bar=baz&bar=bla&bar&blo=&foo=hello%20world&zzz +``` + + + +## kong.service.request.set_header(header, value) + +Sets a header in the request to the Service with the given value. Any existing header + with the same name will be overridden. + + If the `header` argument is `"host"` (case-insensitive), then this also + sets the SNI of the request to the Service. + + +**Phases** + +* `rewrite`, `access`, `balancer` + +**Parameters** + +* **header** (`string`): The header name. Example: "X-Foo". +* **value** (`string|boolean|number`): The header value. Example: "hello world". + +**Returns** + +* Nothing; throws an error on invalid inputs. + + +**Usage** + +``` lua +kong.service.request.set_header("X-Foo", "value") +``` + + + +## kong.service.request.add_header(header, value) + +Adds a request header with the given value to the request to the Service. Unlike + `kong.service.request.set_header()`, this function doesn't remove any existing + headers with the same name. Instead, several occurrences of the header will be + present in the request. The order in which headers are added is retained. + + +**Phases** + +* `rewrite`, `access` + +**Parameters** + +* **header** (`string`): The header name. Example: "Cache-Control". +* **value** (`string|number|boolean`): The header value. Example: "no-cache". + +**Returns** + +* Nothing; throws an error on invalid inputs. + + +**Usage** + +``` lua +kong.service.request.add_header("Cache-Control", "no-cache") +kong.service.request.add_header("Cache-Control", "no-store") +``` + + + +## kong.service.request.clear_header(header) + +Removes all occurrences of the specified header from the request to the Service. + +**Phases** + +* `rewrite`, `access` + +**Parameters** + +* **header** (`string`): The header name. Example: "X-Foo". + +**Returns** + +* Nothing; throws an error on invalid inputs. + The function does not throw an error if no header was removed. + + +**Usage** + +``` lua +kong.service.request.set_header("X-Foo", "foo") +kong.service.request.add_header("X-Foo", "bar") +kong.service.request.clear_header("X-Foo") +-- from here onwards, no X-Foo headers will exist in the request +``` + + + +## kong.service.request.set_headers(headers) + +Sets the headers of the request to the Service. Unlike + `kong.service.request.set_header()`, the `headers` argument must be a table in + which each key is a string (corresponding to a header's name), and each value + is a string, or an array of strings. + + The resulting headers are produced in lexicographical order. The order of + entries with the same name (when values are given as an array) is retained. + + This function overrides any existing header bearing the same name as those + specified in the `headers` argument. Other headers remain unchanged. + + If the `"Host"` header is set (case-insensitive), then this also sets + the SNI of the request to the Service. + +**Phases** + +* `rewrite`, `access` + +**Parameters** + +* **headers** (`table`): A table where each key is a string containing a header name + and each value is either a string or an array of strings. + +**Returns** + +* Nothing; throws an error on invalid inputs. + + +**Usage** + +``` lua +kong.service.request.set_header("X-Foo", "foo1") +kong.service.request.add_header("X-Foo", "foo2") +kong.service.request.set_header("X-Bar", "bar1") +kong.service.request.set_headers({ + ["X-Foo"] = "foo3", + ["Cache-Control"] = { "no-store", "no-cache" }, + ["Bla"] = "boo" +}) + +-- Will add the following headers to the request, in this order: +-- X-Bar: bar1 +-- Bla: boo +-- Cache-Control: no-store +-- Cache-Control: no-cache +-- X-Foo: foo3 +``` + + + +## kong.service.request.set_raw_body(body) + +Sets the body of the request to the Service. + + The `body` argument must be a string and will not be processed in any way. + This function also sets the `Content-Length` header appropriately. To set an + empty body, you can provide an empty string (`""`) to this function. + + For a higher-level function to set the body based on the request content type, + see `kong.service.request.set_body()`. + +**Phases** + +* `rewrite`, `access` + +**Parameters** + +* **body** (`string`): The raw body. + +**Returns** + +* Nothing; throws an error on invalid inputs. + + +**Usage** + +``` lua +kong.service.request.set_raw_body("Hello, world!") +``` + + + +## kong.service.request.set_body(args[, mimetype]) + +Sets the body of the request to the Service. Unlike + `kong.service.request.set_raw_body()`, the `args` argument must be a table, and + is encoded with a MIME type. The encoding MIME type can be specified in + the optional `mimetype` argument, or if left unspecified, is chosen based + on the `Content-Type` header of the client's request. + + Behavior based on MIME type in the `Content-Type` header: + * `application/x-www-form-urlencoded`: Encodes the arguments as + form-encoded. Keys are produced in lexicographical + order. The order of entries within the same key (when values are + given as an array) is retained. Any string values given are URL-encoded. + + * `multipart/form-data`: Encodes the arguments as multipart form data. + + * `application/json`: Encodes the arguments as JSON (same as + `kong.service.request.set_raw_body(json.encode(args))`). Lua types are + converted to matching JSON types. + + If the MIME type is none of the above, this function returns `nil` and + an error message indicating the body could not be encoded. + + If the `mimetype` argument is specified, the `Content-Type` header is + set accordingly in the request to the Service. + + If further control of the body generation is needed, a raw body can be given as + a string with `kong.service.request.set_raw_body()`. + + +**Phases** + +* `rewrite`, `access` + +**Parameters** + +* **args** (`table`): A table with data to be converted to the appropriate format + and stored in the body. +* **mimetype** (`string`, _optional_): can be one of: + +**Returns** + +1. `boolean|nil`: `true` on success, `nil` otherwise. + +1. `string|nil`: `nil` on success, an error message in case of error. + Throws an error on invalid inputs. + + +**Usage** + +``` lua +kong.service.set_header("application/json") +local ok, err = kong.service.request.set_body({ + name = "John Doe", + age = 42, + numbers = {1, 2, 3} +}) + +-- Produces the following JSON body: +-- { "name": "John Doe", "age": 42, "numbers":[1, 2, 3] } + +local ok, err = kong.service.request.set_body({ + foo = "hello world", + bar = {"baz", "bla", true}, + zzz = true, + blo = "" +}, "application/x-www-form-urlencoded") + +-- Produces the following body: +-- bar=baz&bar=bla&bar&blo=&foo=hello%20world&zzz +``` + + + +## kong.service.request.disable_tls() + +Disables the TLS handshake to upstream for [ngx\_stream\_proxy\_module](https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html). + This overrides the [proxy\_ssl](https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_ssl) directive, effectively setting it to `off` + for the current stream session. + + Once this function has been called, it is not possible to re-enable TLS handshake for the current session. + + +**Phases** + +* `preread`, `balancer` + +**Returns** + +1. `boolean|nil`: `true` if the operation succeeded, `nil` if an error occurred. + +1. `string|nil`: An error message describing the error if there was one. + + +**Usage** + +``` lua +local ok, err = kong.service.request.disable_tls() +if not ok then + -- do something with error +end +``` diff --git a/src/gateway/plugin-development/pdk/kong.service.response.md b/src/gateway/plugin-development/pdk/kong.service.response.md new file mode 100644 index 000000000000..6f390a397cd4 --- /dev/null +++ b/src/gateway/plugin-development/pdk/kong.service.response.md @@ -0,0 +1,187 @@ +--- +# +# WARNING: this file was auto-generated by a script. +# DO NOT edit this file directly. Instead, send a pull request to change +# https://github.com/Kong/kong/tree/master/autodoc/pdk/ldoc/ldoc.ltp +# or its associated files +# +title: kong.service.response +pdk: true +toc: true +source_url: https://github.com/Kong/kong/tree/master/kong/pdk +--- + +Module for manipulating the response from the Service. + + + +## kong.service.response.get_status() + +Returns the HTTP status code of the response from the Service as a Lua number. + +**Phases** + +* `header_filter`, `body_filter`, `log` + +**Returns** + +* `number|nil`: The status code from the response from the Service, or `nil` + if the request was not proxied (that is, if `kong.response.get_source()` returned + anything other than `"service"`). + + +**Usage** + +``` lua +kong.log.inspect(kong.service.response.get_status()) -- 418 +``` + + + +## kong.service.response.get_headers([max_headers]) + +Returns a Lua table holding the headers from the Service response. Keys are + header names. Values are either a string with the header value, or an array of + strings if a header was sent multiple times. Header names in this table are + case-insensitive and dashes (`-`) can be written as underscores (`_`); that is, + the header `X-Custom-Header` can also be retrieved as `x_custom_header`. + + Unlike `kong.response.get_headers()`, this function only returns headers that + are present in the response from the Service (ignoring headers added by Kong itself). + If the request is not proxied to a Service (e.g. an authentication plugin rejected + a request and produced an HTTP 401 response), then the returned `headers` value + might be `nil`, since no response from the Service has been received. + + By default, this function returns up to **100** headers. The optional + `max_headers` argument can be specified to customize this limit, but must be + greater than **1** and not greater than **1000**. + +**Phases** + +* `header_filter`, `body_filter`, `log` + +**Parameters** + +* **max_headers** (`number`, _optional_): Sets a limit on the maximum number of + headers that can be parsed. + +**Returns** + +1. `table`: The response headers in table form. + +1. `string`: If more headers than `max_headers` are present, returns + a string with the error `"truncated"`. + + +**Usage** + +``` lua +-- Given a response with the following headers: +-- X-Custom-Header: bla +-- X-Another: foo bar +-- X-Another: baz +local headers = kong.service.response.get_headers() +if headers then + kong.log.inspect(headers.x_custom_header) -- "bla" + kong.log.inspect(headers.x_another[1]) -- "foo bar" + kong.log.inspect(headers["X-Another"][2]) -- "baz" +end +``` + + + +## kong.service.response.get_header(name) + +Returns the value of the specified response header. + + Unlike `kong.response.get_header()`, this function only returns a header + if it is present in the response from the Service (ignoring headers added by Kong + itself). + + +**Phases** + +* `header_filter`, `body_filter`, `log` + +**Parameters** + +* **name** (`string`): The name of the header. + + Header names in are case-insensitive and are normalized to lowercase, and + dashes (`-`) can be written as underscores (`_`); that is, the header + `X-Custom-Header` can also be retrieved as `x_custom_header`. + + +**Returns** + +* `string|nil`: The value of the header, or `nil` if a header with + `name` is not found in the response. If a header with the same name is present + multiple times in the response, this function returns the value of the + first occurrence of this header. + + +**Usage** + +``` lua +-- Given a response with the following headers: +-- X-Custom-Header: bla +-- X-Another: foo bar +-- X-Another: baz + +kong.log.inspect(kong.service.response.get_header("x-custom-header")) -- "bla" +kong.log.inspect(kong.service.response.get_header("X-Another")) -- "foo bar" +``` + + + +## kong.service.response.get_raw_body() + +Returns the raw buffered body. + +**Phases** + +* `header_filter`, `body_filter`, `log` + +**Returns** + +* `string`: The raw buffered body. + + +**Usage** + +``` lua +-- Plugin needs to call kong.service.request.enable_buffering() on `rewrite` +-- or `access` phase prior calling this function. + +local body = kong.service.response.get_raw_body() +``` + + + +## kong.service.response.get_body([mimetype[, max_args]]) + +Returns the decoded buffered body. + +**Phases** + +* `header_filter`, `body_filter`, `log` + +**Parameters** + +* **mimetype** (`string`, _optional_): The MIME type of the response (if known). +* **max_args** (`number`, _optional_): Sets a limit on the maximum number of (what?) + that can be parsed. + +**Returns** + +* `string`: The raw buffered body + + +**Usage** + +``` lua +-- Plugin needs to call kong.service.request.enable_buffering() on `rewrite` +-- or `access` phase prior calling this function. + +local body = kong.service.response.get_body() +``` diff --git a/src/gateway/plugin-development/pdk/kong.table.md b/src/gateway/plugin-development/pdk/kong.table.md new file mode 100644 index 000000000000..a7f4539b5b2c --- /dev/null +++ b/src/gateway/plugin-development/pdk/kong.table.md @@ -0,0 +1,95 @@ +--- +# +# WARNING: this file was auto-generated by a script. +# DO NOT edit this file directly. Instead, send a pull request to change +# https://github.com/Kong/kong/tree/master/autodoc/pdk/ldoc/ldoc.ltp +# or its associated files +# +title: kong.table +pdk: true +toc: true +source_url: https://github.com/Kong/kong/tree/master/kong/pdk +--- + +Utilities for Lua tables. + + + +## kong.table.new([narr[, nrec]]) + +Returns a table with a pre-allocated number of slots in its array and hash + parts. + +**Parameters** + +* **narr** (`number`, _optional_): Specifies the number of slots to pre-allocate + in the array part. +* **nrec** (`number`, _optional_): Specifies the number of slots to pre-allocate in + the hash part. + +**Returns** + +* `table`: The newly created table. + + +**Usage** + +``` lua +local tab = kong.table.new(4, 4) +``` + + + +## kong.table.clear(tab) + +Clears all array and hash parts entries from a table. + +**Parameters** + +* **tab** (`table`): The table to be cleared. + +**Returns** + +* Nothing. + + +**Usage** + +``` lua +local tab = { + "hello", + foo = "bar" +} + +kong.table.clear(tab) + +kong.log(tab[1]) -- nil +kong.log(tab.foo) -- nil +``` + + + +## kong.table.merge([t1[, t2]]) + +Merges the contents of two tables together, producing a new one. + The entries of both tables are copied non-recursively to the new one. + If both tables have the same key, the second one takes precedence. + If only one table is given, it returns a copy. + +**Parameters** + +* **t1** (`table`, _optional_): The first table. +* **t2** (`table`, _optional_): The second table. + +**Returns** + +* `table`: The (new) merged table. + + +**Usage** + +``` lua +local t1 = {1, 2, 3, foo = "f"} +local t2 = {4, 5, bar = "b"} +local t3 = kong.table.merge(t1, t2) -- {4, 5, 3, foo = "f", bar = "b"} +``` diff --git a/src/gateway/plugin-development/pdk/kong.tracing.md b/src/gateway/plugin-development/pdk/kong.tracing.md new file mode 100644 index 000000000000..30ab2d4f8a98 --- /dev/null +++ b/src/gateway/plugin-development/pdk/kong.tracing.md @@ -0,0 +1,158 @@ +--- +# +# WARNING: this file was auto-generated by a script. +# DO NOT edit this file directly. Instead, send a pull request to change +# https://github.com/Kong/kong/tree/master/autodoc/pdk/ldoc/ldoc.ltp +# or its associated files +# +title: kong.tracing +pdk: true +toc: true +source_url: https://github.com/Kong/kong/tree/master/kong/pdk +--- + +Tracer module Application-level tracing for Kong. + + + + +## span:finish(end_time_ns) + +Ends a Span + Set the end time and release the span, + the span table MUST not being used after ended. + +**Parameters** + +* **end_time_ns** (`number|nil`): + +**Usage** + +``` lua +span:finish() + +local time = ngx.now() +span:finish(time * 100000000) +``` + + + +## span:set_attribute(key, value) + +Set an attribute to a Span + +**Parameters** + +* **key** (`string`): +* **value** (`string|number|boolean`): + +**Usage** + +``` lua +span:set_attribute("net.transport", "ip_tcp") +span:set_attribute("net.peer.port", 443) +span:set_attribute("exception.escaped", true) +``` + + + +## span:add_event(name, attributes, time_ns) + +Adds an event to a Span + +**Parameters** + +* **name** (`string`): Event name +* **attributes** (`table|nil`): Event attributes +* **time_ns** (`number|nil`): Event timestamp + + + +## span:record_error(err) + +Adds an error event to a Span + +**Parameters** + +* **err** (`string`): error string + + + +## span:set_status(status) + +Adds an error event to a Span + Status codes: + - `0` unset + - `1` ok + - `2` error + +**Parameters** + +* **status** (`number`): status code + + + +## kong.tracing.new_span() + +Get the active span + Returns the root span by default + +**Phases** + +* rewrite, access, header_filter, response, body_filter, log, admin_api + +**Returns** + +* `table`: span + + + + +## kong.tracing.new_span(span) + +Set the active span + +**Phases** + +* rewrite, access, header_filter, response, body_filter, log, admin_api + +**Parameters** + +* **span** (`table`): + + + +## kong.tracing.new_span(name, options) + +Create a new Span + +**Phases** + +* rewrite, access, header_filter, response, body_filter, log, admin_api + +**Parameters** + +* **name** (`string`): span name +* **options** (`table`): TODO(mayo) + +**Returns** + +* `table`: span + + + + +## kong.tracing.process_span(processor) + +Batch process spans + Please note that socket is not available in the log phase, use `ngx.timer.at` instead + +**Phases** + +* log + +**Parameters** + +* **processor** (`function`): a function that accecpt a span as the parameter + + diff --git a/src/gateway/plugin-development/pdk/kong.vault.md b/src/gateway/plugin-development/pdk/kong.vault.md new file mode 100644 index 000000000000..662425e15656 --- /dev/null +++ b/src/gateway/plugin-development/pdk/kong.vault.md @@ -0,0 +1,143 @@ +--- +# +# WARNING: this file was auto-generated by a script. +# DO NOT edit this file directly. Instead, send a pull request to change +# https://github.com/Kong/kong/tree/master/autodoc/pdk/ldoc/ldoc.ltp +# or its associated files +# +title: kong.vault +pdk: true +toc: true +source_url: https://github.com/Kong/kong/tree/master/kong/pdk +--- + +This module can be used to resolve, parse, and verify vault references. + + +## kong.vault.is_reference(reference) + +Checks if the passed in reference looks like a reference. + Valid references start with `{vault://` and end with `}`. + + If you need more thorough validation, + use `kong.vault.parse_reference`. + + +**Parameters** + +* **reference** (`string`): reference to check + +**Returns** + +* `boolean`: `true` is the passed in reference looks like a reference, otherwise `false` + + +**Usage** + +``` lua +kong.vault.is_reference("{vault://env/key}") -- true +kong.vault.is_reference("not a reference") -- false +``` + + + +## kong.vault.parse_reference(reference) + +Parses and decodes the passed in reference and returns a table + containing its components. + + Given a following resource: + ```lua + "{vault://env/cert/key?prefix=SSL_#1}" + ``` + + This function will return following table: + + ```lua + { + name = "env", -- name of the Vault entity or Vault strategy + resource = "cert", -- resource where secret is stored + key = "key", -- key to lookup if the resource is secret object + config = { -- if there are any config options specified + prefix = "SSL_" + }, + version = 1 -- if the version is specified + } + ``` + + +**Parameters** + +* **reference** (`string`): reference to parse + +**Returns** + +1. `table|nil`: a table containing each component of the reference, or `nil` on error + +1. `string|nil`: error message on failure, otherwise `nil` + + +**Usage** + +``` lua +local ref, err = kong.vault.parse_reference("{vault://env/cert/key?prefix=SSL_#1}") -- table +``` + + + +## kong.vault.get(reference) + +Resolves the passed in reference and returns the value of it. + +**Parameters** + +* **reference** (`string`): reference to resolve + +**Returns** + +1. `string|nil`: resolved value of the reference + +1. `string|nil`: error message on failure, otherwise `nil` + + +**Usage** + +``` lua +local value, err = kong.vault.get("{vault://env/cert/key}") +``` + + + +## kong.vault.try(callback, options) + +Helper function for automatic secret rotation. Currently experimental. + + +**Parameters** + +* **callback** (`function`): callback function +* **options** (`table`): options containing credentials and references + +**Returns** + +1. `string|nil`: return value of the callback function + +1. `string|nil`: error message on failure, otherwise `nil` + + +**Usage** + +``` lua +local function connect(options) + return database_connect(options) +end + +local connection, err = kong.vault.try(connect, { + username = "john", + password = "doe", + ["$refs"] = { + username = "{vault://aws/database-username}", + password = "{vault://aws/database-password}", + } +}) +``` diff --git a/src/gateway/plugin-development/pdk/kong.websocket.client.md b/src/gateway/plugin-development/pdk/kong.websocket.client.md new file mode 100644 index 000000000000..8d0293f720b5 --- /dev/null +++ b/src/gateway/plugin-development/pdk/kong.websocket.client.md @@ -0,0 +1,201 @@ +--- +# +# WARNING: this file was auto-generated by a script. +# DO NOT edit this file directly. Instead, send a pull request to change +# https://github.com/Kong/kong/tree/master/autodoc/pdk/ldoc/ldoc.ltp +# or its associated files +# +title: kong.websocket.client +content_type: reference +pdk: true +toc: true +--- + +Client WebSocket PDK functions. + + +
      + Warning: The WebSocket PDK is under active development and is + considered unstable at this time. Backwards-incompatible changes may be made + to these functions. +
      + + + +## kong.websocket.client.get_frame() + +Retrieve the current frame. + + This returns the payload, type, and status code (for close frames) of + the in-flight frame/message. + + This function is useful in contexts like the pre-function or post-function plugins + where execution is sandboxed and the caller has no access to these + variables in the plugin handler scope. + + +**Phases** + +* `ws_client_frame` + +**Returns** + +* `string`: The frame payload. + +* `string`: The frame type (one of "text", "binary", "ping", + "pong", or "close") + +* `number`: The frame status code (only returned for close frames) + + +**Usage** + +``` lua +local data, typ, status = kong.websocket.client.get_frame() +``` + + + +## kong.websocket.client.set_frame_data(data) + +Set the current frame's payload. + + This allows the caller to overwrite the contents of the in-flight + WebSocket frame before it is forwarded upstream. + + Plugin handlers that execute _after_ this has been called will see the + updated version of the frame. + + +**Phases** + +* `ws_client_frame` + +**Parameters** + +* **data** (`string`): The desired frame payload + +**Usage** + +``` lua +kong.websocket.client.set_frame_data("updated!") +``` + + + +## kong.websocket.client.set_status(status) + +Set the status code for a close frame. + + This allows the caller to overwrite the status code of close frame + before it is forwarded upstream. + + See the [WebSocket RFC](https://datatracker.ietf.org/doc/html/rfc6455#section-7.4.1) + for a list of valid status codes. + + Plugin handlers that execute _after_ this has been called will see the + updated version of the status code. + + Calling this function when the in-flight frame is not a close frame + will result in an exception. + + +**Parameters** + +* **status** (`number`): The desired status code + +**Usage** + +``` lua +-- overwrite the payload and status before forwarding +local data, typ, status = kong.websocket.client.get_frame() +if typ == "close" then + kong.websocket.client.set_frame_data("goodbye!") + kong.websocket.client.set_status(1000) +end +``` + + + +## kong.websocket.client.drop_frame() + +Drop the current frame. + + This causes the in-flight frame to be dropped, meaning it will not be + forwarded upstream. + + Plugin handlers that are set to execute _after_ this one will be + skipped. + + Close frames cannot be dropped. Calling this function for a close + frame will result in an exception. + +**Usage** + +``` lua +kong.websocket.client.drop_frame() +``` + + + +## kong.websocket.client.close([status[, message[, upstream_status[, upstream_payload]]]]) + +Close the WebSocket connection. + + Calling this function immediately sends a close frame to the client and + the upstream before terminating the connection. + + The in-flight frame will not be forwarded upstream, and plugin + handlers that are set to execute _after_ the current one will not be + executed. + + +**Parameters** + +* **status** (`number`, _optional_): Status code of the client close frame +* **message** (`string`, _optional_): Payload of the client close frame +* **upstream_status** (`number`, _optional_): Status code of the upstream close frame +* **upstream_payload** (`string`, _optional_): Payload of the upstream close frame + +**Usage** + +``` lua +kong.websocket.client.close(1009, "Invalid message", + 1001, "Client is going away") +``` + + + + + +## kong.set_max_payload_size + +Set the maximum allowed payload size for client frames, in bytes. + + This limit is applied to all data frame types: + * text + * binary + * continuation + + The limit is also assessed during aggregation of frames. For example, + if the limit is 1024, and a client sends 3 continuation frames of size + 500 each, the third frame will exceed the limit. + + If a client sends a message that exceeds the limit, a close frame with + status code `1009` is sent to the client, and the connection is closed. + + This limit does not apply to control frames (close/ping/pong). + +* **size** (`integer`): The limit (`0` resets to the default limit) + +**Usage** + +``` lua +-- set a max payload size of 1KB +kong.websocket.client.set_max_payload_size(1024) + +-- Restore the default limit +kong.websocket.client.set_max_payload_size(0) +``` + + diff --git a/src/gateway/plugin-development/pdk/kong.websocket.upstream.md b/src/gateway/plugin-development/pdk/kong.websocket.upstream.md new file mode 100644 index 000000000000..2c34c95ebe3c --- /dev/null +++ b/src/gateway/plugin-development/pdk/kong.websocket.upstream.md @@ -0,0 +1,200 @@ +--- +# +# WARNING: this file was auto-generated by a script. +# DO NOT edit this file directly. Instead, send a pull request to change +# https://github.com/Kong/kong/tree/master/autodoc/pdk/ldoc/ldoc.ltp +# or its associated files +# +title: kong.websocket.upstream +content_type: reference +pdk: true +toc: true +--- + +Upstream WebSocket PDK functions. + +
      + Warning: The WebSocket PDK is under active development and is + considered unstable at this time. Backwards-incompatible changes may be made + to these functions. +
      + + + +## kong.websocket.upstream.get_frame() + +Retrieve the current frame. + + This returns the payload, type, and status code (for close frames) of + the in-flight frame/message. + + This function is useful in contexts like the pre-function or post-function plugins + where execution is sandboxed, and the caller has no access to these + variables in the plugin handler scope. + + +**Phases** + +* `ws_upstream_frame` + +**Returns** + +* `string`: The frame payload. + +* `string`: The frame type (one of "text", "binary", "ping", + "pong", or "close") + +* `number`: The frame status code (only returned for close frames) + + +**Usage** + +``` lua +local data, typ, status = kong.websocket.upstream.get_frame() +``` + + + +## kong.websocket.upstream.set_frame_data(data) + +Set the current frame's payload. + + This allows the caller to overwrite the contents of the in-flight + WebSocket frame before it is forwarded to the client. + + Plugin handlers that execute _after_ this has been called will see the + updated version of the frame. + + +**Phases** + +* `ws_upstream_frame` + +**Parameters** + +* **data** (`string`): The desired frame payload + +**Usage** + +``` lua +kong.websocket.upstream.set_frame_data("updated!") +``` + + + +## kong.websocket.upstream.set_status(status) + +Set the status code for a close frame. + + This allows the caller to overwrite the status code of close frame + before it is forwarded to the client. + + See the [WebSocket RFC](https://datatracker.ietf.org/doc/html/rfc6455#section-7.4.1) + for a list of valid status codes. + + Plugin handlers that execute _after_ this has been called will see the + updated version of the status code. + + Calling this function when the in-flight frame is not a close frame + will result in an exception. + + +**Parameters** + +* **status** (`number`): The desired status code + +**Usage** + +``` lua +-- overwrite the payload and status before forwarding +local data, typ, status = kong.websocket.upstream.get_frame() +if typ == "close" then + kong.websocket.upstream.set_frame_data("goodbye!") + kong.websocket.upstream.set_status(1000) +end +``` + + + +## kong.websocket.upstream.drop_frame() + +Drop the current frame. + + This causes the in-flight frame to be dropped, meaning it will not be + forwarded to the client. + + Plugin handlers that are set to execute _after_ this one will be + skipped. + + Close frames cannot be dropped. Calling this function for a close + frame will result in an exception. + +**Usage** + +``` lua +kong.websocket.upstream.drop_frame() +``` + + + +## kong.websocket.upstream.close([status[, message[, client_status[, client_payload]]]]) + +Close the WebSocket connection. + + Calling this function immediately sends a close frame to the client and + the upstream before terminating the connection. + + The in-flight frame will not be forwarded to the client, and plugin + handlers that are set to execute _after_ the current one will not be + executed. + + +**Parameters** + +* **status** (`number`, _optional_): Status code of the upstream close frame +* **message** (`string`, _optional_): Payload of the upstream close frame +* **client_status** (`number`, _optional_): Status code of the client close frame +* **client_payload** (`string`, _optional_): Payload of the client close frame + +**Usage** + +``` lua +kong.websocket.upstream.close(1009, "Invalid message", + 1001, "Upstream is going away") +``` + + + + + +## kong.set_max_payload_size + +Set the maximum allowed payload size for upstream frames. + + This limit is applied to all data frame types: + * text + * binary + * continuation + + The limit is also assessed during aggregation of frames. For example, + if the limit is 1024, and a upstream sends 3 continuation frames of size + 500 each, the third frame will exceed the limit. + + If a upstream sends a message that exceeds the limit, a close frame with + status code `1009` is sent to the upstream, and the connection is closed. + + This limit does not apply to control frames (close/ping/pong). + +* **size** (`integer`): The limit (`0` resets to the default limit) + +**Usage** + +``` lua +-- set a max payload size of 1KB +kong.websocket.upstream.set_max_payload_size(1024) + +-- Restore the default limit +kong.websocket.upstream.set_max_payload_size(0) +``` + + diff --git a/src/gateway/plugin-development/pluginserver/external-plugins.md b/src/gateway/plugin-development/pluginserver/external-plugins.md new file mode 100644 index 000000000000..cde6defbf14f --- /dev/null +++ b/src/gateway/plugin-development/pluginserver/external-plugins.md @@ -0,0 +1,639 @@ +--- +title: Plugins in Other Languages + +--- + +## Introduction + +External plugins are those that run on a process separate from {{site.base_gateway}} itself, +enabling the use of any programming language for which an appropriate +plugin server is available. + +Each plugin server hosts one or more plugins and communicates with the +main {{site.base_gateway}} process through Unix sockets. If so configured, {{site.base_gateway}} can manage +those processes, starting, restarting and stopping as necessary. + +{{site.base_gateway}} currently maintains support for the following languages with +their respective Kong PDKs: +- Go language: [go-pdk] +- JavaScript language: [kong-js-pdk] +- Python language: [kong-python-pdk] + +## Kong Gateway plugin server configuration + +The `pluginserver_names` property is a comma-separated list of names, one +for each plugin server process. These names are used to group each process' +properties and to annotate log entries. + +For each name, other properties can be defined: + +Property | Description | Default +---------|-------------|-------- +`pluginserver__socket` | Unix socket path | `/usr/local/kong/.socket` +`pluginserver__start_cmd` | Command to start the plugin server process | `/usr/local/bin/` +`pluginserver__query_cmd` | Command to dump available plugins' info | `/usr/local/bin/query_` + + +For example, you could set Go and Python plugins like this (assuming +an hypothetical Python plugin server called `pypluginserver.py`): + +``` +pluginserver_names = go,python + +pluginserver_go_socket = /usr/local/kong/go_pluginserver.sock +pluginserver_go_start_cmd = /usr/local/bin/go-plugin -kong-prefix /usr/local/kong +pluginserver_go_query_cmd = /usr/local/bin/go-plugin -dump -kong-prefix /usr/local/kong + +pluginserver_python_socket = /usr/local/kong/python_pluginserver.sock +pluginserver_python_start_cmd = /usr/local/bin/kong-python-pluginserver +pluginserver_python_query_cmd = /usr/local/bin/kong-python-pluginserver --dump-all-plugins +``` + +To enable those plugins, add the each plugin name to the `plugins` config. Assume we have those hello plugins +in each language: + +``` +plugins = bundled, go-hello, js-hello, py-hello +``` + +{:.note} +> **Note:** The `pluginserver_XXX_start_cmd` and `pluginserver_XXX_query_cmd` commands use + a limited default `PATH` variable. In most cases, you have to specify the full executable + path instead. + +### Legacy configuration + +{{site.base_gateway}} versions 2.0.x to 2.2.x supported only Go external plugins and a single +plugin server using a different configuration style. Starting with {{site.base_gateway}} version 2.3, +the old style is recognized and internally transformed to the new style. + +{:.important} +> The legacy configuration is deprecated in {{site.base_gateway}} version 2.8.0 and +> planned to be removed in {{site.base_gateway}} version 3.0.0. + +If property `pluginserver_names` isn't defined, the legacy properties +`go_plugins_dir` and `go_pluginserver_exe` are transparently mapped to the new style: + +Property | Description | Default +---------|-------------|-------- +`go_plugins_dir` | Directory with Go plugins | `off`, meaning to disable Go plugins +`go_pluginserver_exe` | Path to the go-pluginserver executable | `/usr/local/bin/go-pluginserver` + +Notes: + +- Using the legacy style is discouraged; it is deprecated as of {{site.base_gateway}} version 2.8.0, +and planned to be removed in {{site.base_gateway}} version 3.0.0. +- The legacy configuration doesn't allow multiple plugin servers. +- Version 0.5.0 of [go-pluginserver] requires the old style configuration. +- The new configuration style requires v0.6.0 of [go-pluginserver]. + +#### Updating from legacy to embedded server style + +In embedded server mode, the plugin itself acts as the plugin server, +so the external `go-pluginserver` is no longer required. + +Update legacy configuration to embedded plugin server style configuration with +the following steps: + +1. Add a `main()` function that calls `server.StartServer(New, Version, Priority)`. +2. Ensure that properties `go_plugins_dir` and `go_pluginserver_exe` are not set +in your Kong configuration file or environment variable. +3. Set configuration according to [Kong Gateway plugin server configuration](#kong-gateway-plugin-server-configuration). + +Check out the [go-plugins](https://github.com/Kong/go-plugins/tree/v0.5.0) repository for an example of the required updates. Plugins with the `-lm` suffix correspond to the legacy method, while those without the suffix +correspond to the embedded plugin server approach. + +## Developing Go plugins + +{{site.base_gateway}} supports the Go language with the [go-pdk], a library that provides Go functions to access {{site.base_gateway}} features of the [PDK][kong-pdk]. + +Notes: + +The {{site.base_gateway}} version 2.3 allows multiple plugin servers; in particular +it's now possible to write single-plugin servers, in effect plugins as +microservices. To help with this, version v0.6.0 of the [go-pdk] package +includes an optional plugin server. See [Embedded Server](#embedded-server) +for more information. + +### Development + +To write a {{site.base_gateway}} plugin in Go, you need to: + +1. Define a structure type to hold configuration. +2. Write a `New()` function to create instances of your structure. +3. Add methods on that structure to handle phases. +4. Include the `go-pdk/server` sub-library. +5. Add a `main()` function that calls `server.StartServer(New, Version, Priority)`. +6. Compile as an executable with `go build`. + +**Note**: Check out [this repository](https://github.com/Kong/go-plugins) +for example Go plugins. + +#### 1. Configuration Structure + +Plugins written in Lua define a schema to specify how to read and validate +configuration data coming from the datastore or the Admin API. Since Go is a +statically-typed language, all that specification is handled by defining a +configuration structure: + +```go +type MyConfig struct { + Path string + Reopen bool +} +``` + +Public fields (that is, those starting with a capital letter) will be filled +with configuration data. If you want them to have a different name in the +datastore, add field tags as defined in the `encoding/json` package: + +```go +type MyConfig struct { + Path string `json:"my_file_path"` + Reopen bool `json:"reopen"` +} +``` + +#### 2. New() Constructor + +Your plugin must define a function called `New` that creates an instance of this type +and returns as an `interface{}`. In most cases, it’s just this: + +```go +func New() interface{} { + return &MyConfig{} +} +``` + +You can add more fields to the structure and they’ll be passed around, but +there are no guarantees about the lifetime or quantity of configuration +instances. + +#### 3. main() Function + +Each plugin is compiled as a standalone executable. Include `github.com/Kong/go-pdk/server` in +the imports list, and add a `main()` function: + +```go +func main () { + server.StartServer(New, Version, Priority) +} +``` + +The `main()` function must have a `package main` line at the +top of the file. + +Then, a standard Go build creates an executable. There is no extra `go-pluginserver`, +no plugin loading, and no compiler, library, or environment compatibility issues. + +The resulting executable can be placed somewhere in your path (for example, +`/usr/local/bin`). The common `-h` flag shows a usage help message: + +```sh +my-plugin -h +``` + +Output: +``` +Usage of my-plugin: + -dump + Dump info about plugins + -help + Show usage info + -kong-prefix string + Kong prefix path (specified by the -p argument commonly used in the Kong CLI) (default "/usr/local/kong") +``` + +When run without arguments, it creates a socket file within the +`kong-prefix` and the executable name, appending `.socket`. For example, +if the executable is `my-plugin`, it would be +`/usr/local/kong/my-plugin.socket` by default. + + +#### 4. Phase Handlers + +Similarly to {{site.base_gateway}} Lua plugins, you can implement custom logic to be executed at +various points of the request processing lifecycle. For example, to execute +custom Go code in the access phase, define a function named `Access`: +```go +func (conf *MyConfig) Access (kong *pdk.PDK) { + ... +} +``` + +The phases you can implement custom logic for are as follows, and the expected function +signature is the same for all of them: + +- `Certificate` +- `Rewrite` +- `Access` +- `Response` +- `Preread` +- `Log` + +Similar to Lua plugins, the presence of the `Response` handler automatically enables the buffered proxy mode. + +#### 4. Version and Priority + +Similarly to {{site.base_gateway}} Lua plugins, you can define the version number and priority of execution +by having following lines in plugin code: + +```go +const Version = "1.0.0" +const Priority = 1 +``` + +{{site.base_gateway}} executes plugins from highest priority to lowest ones. + +#### Example configuration + +Two standalone plugins, called `my-plugin` and `other-one`: + +``` +pluginserver_names = my-plugin,other-one + +pluginserver_my_plugin_socket = /usr/local/kong/my-plugin.socket +pluginserver_my_plugin_start_cmd = /usr/local/bin/my-plugin +pluginserver_my_plugin_query_cmd = /usr/local/bin/my-plugin -dump + +pluginserver_other_one_socket = /usr/local/kong/other-one.socket +pluginserver_other_one_start_cmd = /usr/local/bin/other-one +pluginserver_other_one_query_cmd = /usr/local/bin/other-one -dump + +``` + +Note that the socket and start command settings coincide with +their defaults, so they can be omitted: + +``` +pluginserver_names = my-plugin,other-one +pluginserver_my_plugin_query_cmd = /usr/local/bin/my-plugin -dump +pluginserver_other_one_query_cmd = /usr/local/bin/other-one -dump +``` + +## Developing JavaScript plugins + +{{site.base_gateway}} support for the JavaScript language is provided by [kong-js-pdk]. +The library provides a plugin server to provide runtime for JavaScript plugins, and +functions to access {{site.base_gateway}} features of the [PDK][kong-pdk]. + +TypeScript is also supported in the following ways: + +- [kong-js-pdk] includes type definitions for PDK functions that allow type checking +when developing plugins in TypeScript. +- Plugin written in TypeScript can be loaded directly and transpiled on the fly. + +### Example configuration + +[kong-js-pdk] can be installed using `npm`. To install the plugin server binary globally: + +``` +npm install kong-pdk -g +``` + +Assume the plugins are stored in `/usr/local/kong/js-plugins`: + +``` +pluginserver_names = js +pluginserver_js_socket = /usr/local/kong/js_pluginserver.sock +pluginserver_js_start_cmd = /usr/local/bin/kong-js-pluginserver --plugins-directory /usr/local/kong/js-plugins +pluginserver_js_query_cmd = /usr/local/bin/kong-js-pluginserver --plugins-directory /usr/local/kong/js-plugins --dump-all-plugins +``` + +### Development + +Install [kong-js-pdk] in your local development directory: + +``` +npm install kong-pdk --save +``` + +A valid JavaScript plugin implementation should export the following object: + +```javascript +module.exports = { + Plugin: KongPlugin, + Schema: [ + { message: { type: "string" } }, + ], + Version: '0.1.0', + Priority: 0, +} +``` + +`Plugin` attribute defines the class that implements this plugin. `Schema` defines the config +schema of plugin, it shares the same syntax as it's a Lua plugin. `Version` and `Priority` +defines the version number and priority of execution respectively. + +**Note**: Check out [this repository](https://github.com/Kong/kong-js-pdk/tree/master/examples) +for example JavaScript and TypeScript plugins. + +#### 1. Phase Handlers + +Similarly to {{site.base_gateway}} Lua plugins, you can implement custom logic to be executed at +various points of the request processing lifecycle. For example, to execute +custom JavaScript code in the access phase, define a function named `access`: + +```javascript +class KongPlugin { + constructor(config) { + this.config = config + } + async access(kong) { + // ... + } +} +``` + +The phases you can implement custom logic for are as follows, and the expected function +signature is the same for all of them: + +- `certificate` +- `rewrite` +- `access` +- `response` +- `preread` +- `log` + +Similar to Lua plugins, the presence of the `response` handler automatically enables the buffered proxy mode. + +#### 2. PDK functions + +[kong-js-pdk] invokes PDK functions in Kong through network-based IPC (inter-process communication). +So each function returns a Promise +instance; it's convenient to use `async`/`await` keywords in phase handlers for better readability. + +```javascript +class KongPlugin { + constructor(config) { + this.config = config + } + async access(kong) { + let host = await kong.request.getHeader("host") + // do something to host + } +} +``` + +Or consume Promise in a traditional way: + +```javascript +class KongPlugin { + constructor(config) { + this.config = config + } + async access(kong) { + kong.request.getHeader("host") + .then((host) => { + // do something to host + }) + } +} +``` + +#### 3. Plugin dependencies + +When using the plugin server, plugins are allowed to have extra dependencies, as long as the +directory that holds plugin source code also includes a `node_modules` directory. + +Assuming plugins are stored under `/usr/local/kong/js-plugins`, the extra dependencies are +then defined in `/usr/local/kong/js-plugins/package.json`. Developers also need to +run `npm install` under `/usr/local/kong/js-plugins` to install those dependencies locally +into `/usr/local/kong/js-plugins/node_modules`. + +Note in this case, the node version and architecture that runs the plugin server and +the one that runs `npm install` under plugins directory must match. For example, it may break +when you run `npm install` under macOS and mount the working directory into a Linux container. + +### Testing + +[kong-js-pdk] provides a mock framework to test plugin code correctness through `jest`. + +Install `jest` as a development dependency, and add the `test` script in `package.json`: + +``` +npm install jest --save-dev +``` + +The `package.json` has content similar to the following: + + { + "scripts": { + "test": "jest" + }, + "devDependencies": { + "jest": "^26.6.3", + "kong-pdk": "^0.3.2" + } + } + +Run the test through npm with: + +``` +npm test +``` + +**Note**: Check out [this repository](https://github.com/Kong/kong-js-pdk/tree/master/examples) +for examples on how to write test using `jest`. + +## Developing Python plugins + +{{site.base_gateway}} support for the Python language is provided by [kong-python-pdk]. +The library provides a plugin server to provide runtime for Python plugins, and +functions to access {{site.base_gateway}} features of the [PDK][kong-pdk]. + +### Example configuration + +[kong-python-pdk] can be installed using `pip`. To install the plugin server binary and PDK globally, use: + +``` +pip3 install kong-pdk +``` + +Assume the plugins are stored in `/usr/local/kong/python-plugins`: + +``` +pluginserver_names = python +pluginserver_python_socket = /usr/local/kong/python_pluginserver.sock +pluginserver_python_start_cmd = /usr/local/bin/kong-python-pluginserver --plugins-directory /usr/local/kong/python-plugins +pluginserver_python_query_cmd = /usr/local/bin/kong-python-pluginserver --plugins-directory /usr/local/kong/python-plugins --dump-all-plugins +``` + +### Development + +A valid Python plugin implementation has following attributes: + +```python +Schema = ( + { "message": { "type": "string" } }, +) +version = '0.1.0' +priority = 0 +class Plugin(object): + pass +``` + +A class named `Plugin` defines the class that implements this plugin. `Schema` defines the config +schema of plugin, it shares the same syntax as it's a Lua plugin. `version` and `priority` +defines the version number and priority of execution respectively. + +**Note**: Check out [this repository](https://github.com/Kong/kong-python-pdk/tree/master/examples) +for example Python plugins and [API reference](https://kong.github.io/kong-python-pdk/py-modindex.html). + +#### 1. Phase Handlers + +Similarly to {{site.base_gateway}} Lua plugins, you can implement custom logic to be executed at +various points of the request processing lifecycle. For example, to execute +custom Go code in the access phase, define a function named `access`: + +```python +class Plugin(object): + def __init__(self, config): + self.config = config + def access(self, kong): + pass +``` + +The phases you can implement custom logic for are as follows, and the expected function +signature is the same for all of them: + +- `certificate` +- `rewrite` +- `access` +- `response` +- `preread` +- `log` + +Similar to Lua plugins, the presence of the `response` handler automatically enables the buffered proxy mode. + +#### 2. Type hints + +[kong-python-pdk] supports [type hint](https://www.python.org/dev/peps/pep-0484/) in Python 3.x. To use type lint +and autocomplete in IDE, user can annotate the `kong` parameter in phase handler: + +```python +import kong_pdk.pdk.kong as kong +class Plugin(object): + def __init__(self, config): + self.config = config + def access(self, kong: kong.kong): + host, err = kong.request.get_header("host") +``` + +### Embedded server + +Each plugin can be a microservice. To use the embedded server, use the following code: + +```python +if __name__ == "__main__": + from kong_pdk.cli import start_dedicated_server + start_dedicated_server("py-hello", Plugin, version, priority) +``` + +Note the first argument to `start_dedicated_server` defines the plugin name and must +be unique across all languages. + +#### Example configuration + +Two standalone plugins, called `my-plugin` and `other-one`: + +``` +pluginserver_names = my-plugin,other-one +pluginserver_my_plugin_socket = /usr/local/kong/my-plugin.socket +pluginserver_my_plugin_start_cmd = /path/to/my-plugin.py +pluginserver_my_plugin_query_cmd = /path/to/my-plugin.py --dump +pluginserver_other_one_socket = /usr/local/kong/other-one.socket +pluginserver_other_one_start_cmd = /path/to/other-one.py +pluginserver_other_one_query_cmd = /path/to/other-one.py -dump +``` + +Note that the socket and start command settings coincide with +their defaults, so they can be omitted: + +``` +pluginserver_names = my-plugin,other-one +pluginserver_my_plugin_query_cmd = /path/to/my-plugin --dump +pluginserver_other_one_query_cmd = /path/to/other-one --dump +``` + +### Concurrency model + +Python plugin server and embedded server supports multiple concurrency model. By default, +the server starts in multi-threading mode. + +If your workload is IO intensive, consider the gevent model by adding `-g` to pluginserver's +start_cmd. +If your workload is CPU intensive, consider the multi-processing model by adding `-m` to pluginserver's +start_cmd. + + +## Performance for external plugins + +Depending on implementation details, Go plugins are able to use multiple CPU cores +and so perform best on a multi-core system. JavaScript plugins are currently +single-core only and there's no dedicated plugin server support. +Python plugins can use a dedicated plugin server to span workload to +multiple CPU cores as well. + +Unlike Lua plugins where invoking PDK functions are handled in local processes, +calling PDK functions in external plugins implies inter-process communications and so is a +relatively expensive operation. Because of the expense of calling PDK functions in external plugins, the performance of Kong using external plugins is +highly related to the number of IPC (inter-process communication) calls in each request. + +The following graph demonstrates the correlation between performance and count of IPC +calls per request. Numbers of RPS and latency are removed as they are dependent on +hardware and to avoid confusion. + +
      + +
      + +## Use external plugins in container and Kubernetes + +To use plugins requiring external plugin servers, both the plugin servers and the plugins themselves need to be installed inside the {{ site.base_gateway }} container. + +For plugins written in Golang, build external plugins in embedded server mode in a builder container +and copy or mount the binary artifacts into the {{ site.base_gateway }} container. +For plugins written in JavaScript, first install Node and `npm`, then use `npm` to install `kong-pdk`, and finally +copy or mount the plugins source code into the {{ site.base_gateway }} container. +For plugins written in Python, install Python and `pip`. Then use `pip` to install `kong-pdk`. Finally, +copy or mount the plugin's source code into the {{ site.base_gateway }} container. + +Refer to previous sections on how to configure {{ site.base_gateway }} after you build the image +or create the container. + +{:.note} +> **Note:** Official {{ site.base_gateway }} images are configured to run as the `nobody` user. When building a custom image, to copy files into +the {{ site.base_gateway }} image, you must temporarily set the user to `root`. + +```dockerfile +FROM kong +USER root +# Example for GO: +COPY your-go-plugin /usr/local/bin/your-go-plugin +# Example for JavaScript: +RUN apk update && apk add nodejs npm && npm install -g kong-pdk +COPY you-js-plugin /path/to/your/js-plugins/you-js-plugin +# Example for Python +# PYTHONWARNINGS=ignore is needed to build gevent on Python 3.9 +RUN apk update && \ + apk add python3 py3-pip python3-dev musl-dev libffi-dev gcc g++ file make && \ + PYTHONWARNINGS=ignore pip3 install kong-pdk +COPY you-py-plugin /path/to/your/py-plugins/you-py-plugin +# reset back the defaults +USER kong +ENTRYPOINT ["/docker-entrypoint.sh"] +EXPOSE 8000 8443 8001 8444 +STOPSIGNAL SIGQUIT +HEALTHCHECK --interval=10s --timeout=10s --retries=10 CMD kong health +CMD ["kong", "docker-start"] +``` +--- + +[go-pluginserver]: https://github.com/Kong/go-pluginserver +[go-plugins]: https://github.com/Kong/go-plugins +[go-pdk]: https://github.com/Kong/go-pdk +[kong-pdk]: /gateway/{{page.kong_version}}/plugin-development/pdk/ +[go-hello]: https://github.com/Kong/go-plugins/blob/master/go-hello.go +[kong-js-pdk]: https://github.com/Kong/kong-js-pdk +[kong-python-pdk]: https://github.com/Kong/kong-python-pdk diff --git a/src/gateway/plugin-development/pluginserver/go.md b/src/gateway/plugin-development/pluginserver/go.md new file mode 100644 index 000000000000..6f9353e21410 --- /dev/null +++ b/src/gateway/plugin-development/pluginserver/go.md @@ -0,0 +1,160 @@ +--- +title: Write plugins in Go +content-type: explanation +--- + +## Developing Go plugins + +{{site.base_gateway}} supports the Go language with the [Go PDK](https://pkg.go.dev/github.com/Kong/go-pdk), a library that provides Go bindings for {{site.base_gateway}}. + +## Overview + +To write a {{site.base_gateway}} plugin in Go, you need to: + +1. Define a `structure` type to hold configuration. +2. Write a `New()` function to create instances of your structure. +3. Add methods to that structure to handle phases. +4. Include the `go-pdk/server` sub-library. +5. Add a `main()` function that calls `server.StartServer(New, Version, Priority)`. +6. Compile as an executable with `go build`. + +{:.note} +> **Note**: [The Kong Go plugins repository](https://github.com/Kong/go-plugins) contains example Go plugins. + +## Configuration + +### `Struct` +The plugin you write needs a way to handle incoming configuration data from the data store or the Admin API. +You can use a `struct` to create a schema of the incoming data. + +```go +type MyConfig struct { + Path string + Reopen bool +} +``` +Because this plugin will be processing configuration data, you are going to want to control encoding using the `encoding/json` package. +Go fields that start with a capital letter can be exported, making them accessible outside of the current package, including by the `encoding/json` package. +If you want the fields to have a different name in the data store, add tags to the fields in your `struct`. + +```go +type MyConfig struct { + Path string `json:"my_file_path"` + Reopen bool `json:"reopen"` +} +``` + +### The `New()` constructor + +The plugin must define a function called `New`. +This function should instantiate the `MyConfig` struct and return it as an `interface`. + +```go +func New() interface{} { + return &MyConfig{} +} +``` + +### The `main()` function + +Each plugin is compiled as a standalone executable. Include `github.com/Kong/go-pdk` in +the imports list, and add a `main()` function: + +```go +func main () { + server.StartServer(New, Version, Priority) +} +``` + +Executables can be placed somewhere in your path (for example, +`/usr/local/bin`). The common `-h` flag shows a usage help message: + +```sh +my-plugin -h +``` + +Output: +``` +Usage of my-plugin: + -dump + Dump info about plugins + -help + Show usage info + -kong-prefix string + Kong prefix path (specified by the -p argument commonly used in the Kong CLI) (default "/usr/local/kong") +``` + +When you run the plugin without arguments, it creates a socket file within the +`kong-prefix` and the executable name, appending `.socket`. +For example, if the executable is `my-plugin`, the socket file would be +`/usr/local/kong/my-plugin.socket`. + + +### Phase handlers + +In {{site.base_gateway}} Lua plugins, you can implement custom logic to be executed at +various points of the request processing lifecycle. For example, to execute +custom Go code during the access phase, create a function named `Access` with the following function signature: + +```go +func (conf *MyConfig) Access (kong *pdk.PDK) { + ... +} +``` + +You can implement custom logic during the following phases using the same function signature: + +- `Certificate` +- `Rewrite` +- `Access` +- `Response` +- `Preread` +- `Log` + +The presence of the `Response` handler automatically enables the buffered proxy mode. + +### Version and priority + +You can define the version number and priority of execution +by declaring the following constants within the plugin code: + +```go +const Version = "1.0.0" +const Priority = 1 +``` + +{{site.base_gateway}} executes plugins from highest priority to lowest. + +## Example configuration + +To load plugins using the `kong.conf` [configuration file](/gateway/latest/production/kong-conf), you have to map existing {{site.base_gateway}} properties to aspects of your plugin. +Here are two examples of loading plugins within `kong.conf`: + +``` +pluginserver_names = my-plugin,other-one + +pluginserver_my_plugin_socket = /usr/local/kong/my-plugin.socket +pluginserver_my_plugin_start_cmd = /usr/local/bin/my-plugin +pluginserver_my_plugin_query_cmd = /usr/local/bin/my-plugin -dump + +pluginserver_other_one_socket = /usr/local/kong/other-one.socket +pluginserver_other_one_start_cmd = /usr/local/bin/other-one +pluginserver_other_one_query_cmd = /usr/local/bin/other-one -dump + +``` + +The socket and start command settings coincide with +their defaults and can be omitted: + +``` +pluginserver_names = my-plugin,other-one +pluginserver_my_plugin_query_cmd = /usr/local/bin/my-plugin -dump +pluginserver_other_one_query_cmd = /usr/local/bin/other-one -dump +``` + +## More information + +* [PDK Reference](/gateway/latest/plugin-development/pdk/) +* [Plugins with Containers](/gateway/latest/plugin-development/pluginserver/plugins-kubernetes) +* [Develop plugins with Python](/gateway/latest/plugin-development/pluginserver/python) +* [Develop plugins with JavaScript](/gateway/latest/plugin-development/pluginserver/javascript) diff --git a/src/gateway/plugin-development/pluginserver/javascript.md b/src/gateway/plugin-development/pluginserver/javascript.md new file mode 100644 index 000000000000..26f19042b6a5 --- /dev/null +++ b/src/gateway/plugin-development/pluginserver/javascript.md @@ -0,0 +1,154 @@ +--- +title: Plugins in Other Languages Javascript +content-type: explanation +--- + +{{site.base_gateway}} support for the JavaScript language is provided by the [JavaScript PDK](https://github.com/Kong/kong-js-pdk). +The library provides a plugin server that provides a runtime for JavaScript bindings for {{site.base_gateway}}. + +TypeScript is also supported in the following ways: + +- The PDK includes type definitions for PDK functions that allow type checking +when developing plugins in TypeScript. +- Plugins written in TypeScript can be loaded directly to {{site.base_gateway}} and transpiled. + +## Install + +[JavaScript PDK](https://github.com/Kong/kong-js-pdk) can be installed using `npm`. To install the plugin server binary globally: + +``` +npm install kong-pdk -g +``` + +## Development + +A valid JavaScript plugin implementation should export the following object: + +```javascript +module.exports = { + Plugin: KongPlugin, + Schema: [ + { message: { type: "string" } }, + ], + Version: '0.1.0', + Priority: 0, +} +``` + +* The `Plugin` attribute defines the class that implements this plugin. +* The `Schema` defines the configuration schema of the plugin. +* `Version` and `Priority` variables set to the version number and priority of execution. + +**Note**: [This repository](https://github.com/Kong/kong-js-pdk/tree/master/examples) contains examples of plugins built with JavaScript. + +## Phase handlers + +You can implement custom logic to be executed at +various points in the request processing lifecycle. To execute +custom JavaScript code in the access phase, define a function named `access`: + +```javascript +class KongPlugin { + constructor(config) { + this.config = config + } + async access(kong) { + // ... + } +} +``` + +You can implement custom logic during the following phases using the same function signature: + +- `certificate` +- `rewrite` +- `access` +- `response` +- `preread` +- `log` + +The presence of the `response` handler automatically enables the buffered proxy mode. + +## PDK functions + +Kong interacts with the PDK through network-based inter-rocess communication. +Each function returns a [promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) +instance. You can use `async`/`await` keywords in the phase handlers for better readability. + +```javascript +class KongPlugin { + constructor(config) { + this.config = config + } + async access(kong) { + let host = await kong.request.getHeader("host") + // do something to host + } +} +``` + +Alternatively, use the `then` method to resolve a promise: + +```javascript +class KongPlugin { + constructor(config) { + this.config = config + } + async access(kong) { + kong.request.getHeader("host") + .then((host) => { + // do something to host + }) + } +} +``` + +## Plugin dependencies + +When using the plugin server, plugins are allowed to have extra dependencies, as long as the +directory that holds plugin source code also includes a `node_modules` directory. + +Assuming plugins are stored under `/usr/local/kong/js-plugins`, the extra dependencies are +then defined in `/usr/local/kong/js-plugins/package.json`. Developers also need to +run `npm install` under `/usr/local/kong/js-plugins` to install those dependencies locally +into `/usr/local/kong/js-plugins/node_modules`. + +The Node.js version and architecture that runs the plugin server and +the one that runs `npm install` under plugins directory must match. + +### Testing + +The JavaScript PDK provides a mock framework to test plugin code using [`jest`](https://jestjs.io/). + +Install `jest` as a development dependency, then add the `test` script in `package.json`: + +``` +npm install jest --save-dev +``` + +The `package.json` contains information like this: + + { + "scripts": { + "test": "jest" + }, + "devDependencies": { + "jest": "^26.6.3", + "kong-pdk": "^0.3.2" + } + } + +Run the test through npm with: + +``` +npm test +``` + +[This repository](https://github.com/Kong/kong-js-pdk/tree/master/examples) +contains examples of writing tests with `jest`. + +## More Information +* [PDK Reference](/gateway/latest/plugin-development/pdk/) +* [Plugins with Containers](/gateway/latest/plugin-development/pluginserver/plugins-kubernetes) +* [Develop plugins with Python](/gateway/latest/plugin-development/pluginserver/python) +* [Develop plugins with Go](/gateway/latest/plugin-development/pluginserver/go) \ No newline at end of file diff --git a/src/gateway/plugin-development/pluginserver/plugins-kubernetes.md b/src/gateway/plugin-development/pluginserver/plugins-kubernetes.md new file mode 100644 index 000000000000..b749ae5473bf --- /dev/null +++ b/src/gateway/plugin-development/pluginserver/plugins-kubernetes.md @@ -0,0 +1,43 @@ +--- +title: Use Plugins With Containers +content-type: reference +--- + +## Use external plugins in container and Kubernetes + +To use plugins requiring external plugin servers, both the plugin servers and the plugins themselves need to be installed inside the {{ site.base_gateway }} container, copy or mount the plugin's source code into the {{ site.base_gateway }} container. + +{:.note} +> **Note:** Official {{ site.base_gateway }} images are configured to run as the `nobody` user. When building a custom image, to copy files into +the {{ site.base_gateway }} image, you must temporarily set the user to `root`. + +This is an example Dockerfile that explains how to mount your plugin in the {{ site.base_gateway }} image: + +```dockerfile +FROM kong +USER root +# Example for GO: +COPY your-go-plugin /usr/local/bin/your-go-plugin +# Example for JavaScript: +RUN apk update && apk add nodejs npm && npm install -g kong-pdk +COPY you-js-plugin /path/to/your/js-plugins/you-js-plugin +# Example for Python +# PYTHONWARNINGS=ignore is needed to build gevent on Python 3.9 +RUN apk update && \ + apk add python3 py3-pip python3-dev musl-dev libffi-dev gcc g++ file make && \ + PYTHONWARNINGS=ignore pip3 install kong-pdk +COPY you-py-plugin /path/to/your/py-plugins/you-py-plugin +# reset back the defaults +USER kong +ENTRYPOINT ["/docker-entrypoint.sh"] +EXPOSE 8000 8443 8001 8444 +STOPSIGNAL SIGQUIT +HEALTHCHECK --interval=10s --timeout=10s --retries=10 CMD kong health +CMD ["kong", "docker-start"] +``` + +## More information + +* [Develop plugins with Python](/gateway/latest/plugin-development/pluginserver/python) +* [Develop plugins with Go](/gateway/latest/plugin-development/pluginserver/go) +* [Develop plugins with JavaScript](/gateway/latest/plugin-development/pluginserver/javascript) \ No newline at end of file diff --git a/src/gateway/plugin-development/pluginserver/python.md b/src/gateway/plugin-development/pluginserver/python.md new file mode 100644 index 000000000000..2a5e1eb6b760 --- /dev/null +++ b/src/gateway/plugin-development/pluginserver/python.md @@ -0,0 +1,132 @@ +--- +title: Write plugins in Python +content-type: explanation +--- + +## The Python PDK + +{{site.base_gateway}} support for Python plugin development is provided by the [kong-python-pdk](https://github.com/Kong/kong-python-pdk) library. +The library provides a plugin server and Kong-specific +functions to interface with {{site.base_gateway}}. + +## Install + +To install the plugin server and PDK globally, use `pip`: + +``` +pip3 install kong-pdk +``` + +## Development + +A {{site.base_gateway}} Python plugin implementation has following attributes: + +```python +Schema = ( + { "message": { "type": "string" } }, +) +version = '0.1.0' +priority = 0 +class Plugin(object): + pass +``` + +* A class named `Plugin` defines the class that implements this plugin. +* A dictionary called `Schema` that defines expected values and data types of the plugin. +* The variables `version` and `priority` that define the version number and priority of execution respectively. + +{:.note} +>**Note**: [This repository](https://github.com/Kong/kong-python-pdk/tree/master/examples) contains example Python plugins and an [API reference](https://kong.github.io/kong-python-pdk/py-modindex.html). + +## Phase handlers + +You can implement custom logic to be executed at +various points of the request processing lifecycle. To execute +custom code during the access phase, define a function named `access`: + +```python +class Plugin(object): + def __init__(self, config): + self.config = config + def access(self, kong): + pass +``` + +You can implement custom logic during the following phases using the same function signature: + +- `certificate` +- `rewrite` +- `access` +- `response` +- `preread` +- `log` + +The presence of the `response` handler automatically enables the buffered proxy mode. + +### Type hints + +Support for [type hints](https://www.python.org/dev/peps/pep-0484/) is available. To use type hints +and autocomplete in an IDE, add the the `kong` parameter to the phase handler function: + +```python +import kong_pdk.pdk.kong as kong +class Plugin(object): + def __init__(self, config): + self.config = config + def access(self, kong: kong.kong): + host, err = kong.request.get_header("host") +``` + +## Embedded server + +To use the embedded server, use the following code: + +```python +if __name__ == "__main__": + from kong_pdk.cli import start_dedicated_server + start_dedicated_server("py-hello", Plugin, version, priority) +``` + +The first argument to `start_dedicated_server` defines the plugin name and must +be unique. + +## Example configuration + +To load plugins using the `kong.conf` [configuration file](/gateway/latest/production/kong-conf), you have to map existing {{site.base_gateway}} properties to aspects of your plugin. +Below are two examples of loading plugins within `kong.conf`. + +``` +pluginserver_names = my-plugin,other-one +pluginserver_my_plugin_socket = /usr/local/kong/my-plugin.socket +pluginserver_my_plugin_start_cmd = /path/to/my-plugin.py +pluginserver_my_plugin_query_cmd = /path/to/my-plugin.py --dump +pluginserver_other_one_socket = /usr/local/kong/other-one.socket +pluginserver_other_one_start_cmd = /path/to/other-one.py +pluginserver_other_one_query_cmd = /path/to/other-one.py -dump +``` + +The socket and start command settings coincide with +their defaults and can be omitted: + +``` +pluginserver_names = my-plugin,other-one +pluginserver_my_plugin_query_cmd = /path/to/my-plugin --dump +pluginserver_other_one_query_cmd = /path/to/other-one --dump +``` + +## Concurrency model + +The Python plugin server and the embedded server support concurrency. By default, +the server starts in multi-threading mode. + +If your workload is IO intensive, you can use the [Gevent](http://www.gevent.org/) model by passing the `-g` flag to +`start_cmd` in `kong.conf`. +If your workload is CPU intensive, consider the multi-processing model by by passing the `-m` flag to +`start_cmd` in `kong.conf`. + + +## More Information +* [PDK Reference](/gateway/latest/plugin-development/pdk/) +* [Plugins with Containers](/gateway/latest/plugin-development/pluginserver/plugins-kubernetes) +* [Develop plugins with Go](/gateway/latest/plugin-development/pluginserver/go) +* [Develop plugins with JavaScript](/gateway/latest/plugin-development/pluginserver/javascript) \ No newline at end of file diff --git a/src/gateway/plugin-development/tests.md b/src/gateway/plugin-development/tests.md new file mode 100644 index 000000000000..074dabbb72cb --- /dev/null +++ b/src/gateway/plugin-development/tests.md @@ -0,0 +1,102 @@ +--- +title: Writing tests +book: plugin_dev +chapter: 9 +--- + +If you are serious about your plugin, you probably want to write tests for it. +Unit testing Lua is easy, and [many testing +frameworks](http://lua-users.org/wiki/UnitTesting) are available. However, you +might also want to write integration tests. Again, Kong has your back. + +## Write integration tests + +The preferred testing framework for Kong is +[busted](https://github.com/lunarmodules/busted) running with the +[resty-cli](https://github.com/openresty/resty-cli) interpreter, though you are +free to use a different one. In the Kong repository, the busted +executable can be found at `bin/busted`. + +Kong provides you with a helper to start and stop it from Lua in your test +suite: `spec.helpers`. This helper also provides you with ways to insert +fixtures in your datastore before running your tests, as well as dropping it, +and various other helpers. + +If you are writing your plugin in your own repository, you will need to copy +the following files until the Kong testing framework is released: + +- `bin/busted`: the busted executable running with the resty-cli interpreter +- `spec/helpers.lua`: helper functions to start/stop Kong from busted +- `spec/kong_tests.conf`: a configuration file for your running your test Kong instances with the helpers module + +Assuming that the `spec.helpers` module is available in your `LUA_PATH`, you +can use the following Lua code in busted to start and stop Kong: + +```lua +local helpers = require "spec.helpers" + +for _, strategy in helpers.each_strategy() do + describe("my plugin", function() + + local bp = helpers.get_db_utils(strategy) + + setup(function() + local service = bp.services:insert { + name = "test-service", + host = "httpbin.org" + } + + bp.routes:insert({ + hosts = { "test.com" }, + service = { id = service.id } + }) + + -- start Kong with your testing Kong configuration (defined in "spec.helpers") + assert(helpers.start_kong( { plugins = "bundled,my-plugin" })) + + admin_client = helpers.admin_client() + end) + + teardown(function() + if admin_client then + admin_client:close() + end + + helpers.stop_kong() + end) + + before_each(function() + proxy_client = helpers.proxy_client() + end) + + after_each(function() + if proxy_client then + proxy_client:close() + end + end) + + describe("thing", function() + it("should do thing", function() + -- send requests through Kong + local res = proxy_client:get("/get", { + headers = { + ["Host"] = "test.com" + } + }) + + local body = assert.res_status(200, res) + + -- body is a string containing the response + end) + end) + end) +end +``` + +With the test Kong configuration file, Kong is running with +its proxy listening on port 9000 (HTTP), 9443 (HTTPS) +and Admin API on port 9001. + +For a real-world example, see the +[Key-Auth plugin specs](https://github.com/Kong/kong/tree/master/spec/03-plugins/09-key-auth). + diff --git a/src/gateway/production/access-control/enable-rbac.md b/src/gateway/production/access-control/enable-rbac.md new file mode 100644 index 000000000000..7611f0771592 --- /dev/null +++ b/src/gateway/production/access-control/enable-rbac.md @@ -0,0 +1,1042 @@ +--- +title: RBAC Examples +badge: enterprise +--- + +This chapter aims to provide a step-by-step tutorial on how to set up +RBAC and see it in action, with an end-to-end use case. The chosen +use case demonstrates how **RBAC with workspaces** can be coupled +to achieve a flexible organization of teams and users in complex +hierarchies. + +## Use Case + +For the sake of example, let's say a given company has a {{site.base_gateway}} +cluster to be shared with 3 teams: teamA, teamB, and teamC. While the Kong +cluster are shared among these teams, they want to be able to segment +their entities in such a way that management of entities in one team doesn't +disrupt operation in some other team. As shown in the +[Workspaces Page][workspaces-examples], such a use case is possible +with workspaces. On top of workspaces, though, each team wants to enforce +access control over their Workspace, which is possible with RBAC. **To sum up, +Workspaces and RBAC are complementary: Workspaces provide segmentation of +Admin API entities, while RBAC provides access control**. + +## Bootstrapping the first RBAC user—the Super Admin + +**Note:** It is possible to create the first Super Admin at the time +of migration as described in the [Getting Started Guide][getting-started-guide]. +If you chose this option, skip to [Enforcing RBAC](#enforcing-rbac). + +Before anything, we will assume the Kong Admin—or, more interestingly, +the KongOps Engineer—in charge of operating Kong, will create a Super Admin +user, before actually enforcing RBAC and restarting Kong with RBAC enabled. + +As Kong ships with a handy set of default RBAC Roles—the `super-admin`, +the `admin`, and `read-only`—the task of creating a Super Admin user is +quite easy: + +Create the RBAC user, named `super-admin`: + +``` +http :8001/rbac/users name=super-admin +{ + "user_token": "M8J5A88xKXa7FNKsMbgLMjkm6zI2anOY", + "id": "da80838d-49f8-40f6-b673-6fff3e2c305b", + "enabled": true, + "created_at": 1531009435000, + "name": "super-admin" +} +``` + +As the `super-admin` user name coincides with an existing `super-admin` +role, it gets automatically added to the `super-admin` role—which can be +confirmed with the following command: + +``` +http :8001/rbac/users/super-admin/roles +{ + "roles": [ + { + "comment": "Full access to all endpoints, across all workspaces", + "created_at": 1531009724000, + "name": "super-admin", + "id": "b924ac91-e83f-4136-a5a4-4a7ff92594a8" + } + ], + "user": { + "created_at": 1531009858000, + "id": "e6897cc0-0c34-4a9c-9f0b-cc65b4f04d68", + "name": "super-admin", + "enabled": true, + "user_token": "vajeOlkybsn0q0VD9qw9B3nHYOErgY7b8" + } +} + +``` + +## Enforcing RBAC + +As the `super-admin` user has just been created, the Kong Admin may now +restart Kong with RBAC enforced, with, e.g.: + +``` +KONG_ENFORCE_RBAC=on kong restart +``` + +**NOTE**: This is one of the possible ways of enforcing RBAC and restarting +Kong; another possibility is editing the Kong configuration file and +restarting. + +Before we move on, note that we will be using the Super Admin user, but we +could, in fact, be moving without RBAC enabled, and having our Kong Admin do +all the job of setting up the RBAC hierarchy. We want, however, to stress the +fact that RBAC is powerful enough to allow a flexible separation of tasks. To +summarize: + +- **Kong Admin**: this user has physical access to Kong infrastructure; her +task is to bootstrap the Kong cluster as well as its configuration, including +initial RBAC users; +- **RBAC Super Admin**: created by the Kong Admin, has the role of managing +RBAC users, roles, etc; this could all be done by the **Kong Admin**, but let's +give him a break. + +## Super Admin creates the teams Workspaces + +The Super Admin will now set up our 3 teams: teamA, teamB, and teamC, creating +one workspace for each, one admin for each. Enough talking. + +Creating workspaces for each team—this overlaps a bit with +[Workspaces Examples][workspaces-examples], yes, but it will make our +exploration of RBAC + Workspaces easier: + +**Team A**: + +``` +http :8001/workspaces name=teamA Kong-Admin-Token:vajeOlkbsn0q0VD9qw9B3nHYOErgY7b8 +{ + "name": "teamA", + "created_at": 1531014100000, + "id": "1412f3a6-4d9b-4b9d-964e-60d8d63a9d46" +} + +``` + +**Team B**: + +``` +http :8001/workspaces name=teamB Kong-Admin-Token:vajeOlkbsn0q0VD9qw9B3nHYOErgY7b8 +{ + "name": "teamB", + "created_at": 1531014143000, + "id": "7dee8c56-c6db-4125-b87a-b508baa33c66" +} +``` + +**Team C**: + +``` +http :8001/workspaces name=teamC Kong-Admin-Token:vajeOlkbsn0q0VD9qw9B3nHYOErgY7b8 +{ + "name": "teamC", + "created_at": 1531014171000, + "id": "542c8662-17cc-49eb-af50-6eb14f3b2e8a" +} +``` + +**NOTE**: this is the RBAC Super Admin creating workspaces—note his +token being passed in through the `Kong-Admin-Token` HTTP header. + +## Super Admin Creates one Admin for each Team + +**Team A**: + +``` +http :8001/teamA/rbac/users name=adminA Kong-Admin-Token:vajeOlkbsn0q0VD9qw9B3nHYOErgY7b8 +{ + "user_token": "qv1VLIpl8kHj7lC1QOKwRdCMXanqEDii", + "id": "4d315ff9-8c1a-4844-9ea2-21b16204a154", + "enabled": true, + "created_at": 1531015165000, + "name": "adminA" +} +``` + +**Team B**: + +``` +http :8001/teamB/rbac/users name=adminB Kong-Admin-Token:vajeOlkbsn0q0VD9qw9B3nHYOErgY7b8 +{ + "user_token": "IX5vHVgYqM40tLcctdmzRtHyfxB4ToYv", + "id": "49641fc0-8c9d-4507-bc7a-2acac8f2903a", + "enabled": true, + "created_at": 1531015221000, + "name": "adminB" +} +``` + +**Team C**: + +``` +http :8001/teamC/rbac/users name=adminC Kong-Admin-Token:vajeOlkbsn0q0VD9qw9B3nHYOErgY7b8 +{ + "user_token": "w2f7tsuUW4BerXocZIMRQHE84nK2ZAo7", + "id": "74643f69-8852-49f9-b363-21971bac4f52", + "enabled": true, + "created_at": 1531015304000, + "name": "teamC" +} +``` + +With this, all of the teams have one admin and each admin can only be seen +in his corresponding workspace. To verify: + +``` +http :8001/teamA/rbac/users Kong-Admin-Token:vajeOlkbsn0q0VD9qw9B3nHYOErgY7b8 +{ + "total": 1, + "data": [ + { + "created_at": 1531014784000, + "id": "1faaacd1-709f-4762-8c3e-79f268ec8faf", + "name": "adminA", + "enabled": true, + "user_token": "n5bhjgv0speXp4N7rSUzUj8PGnl3F5eG" + } + ] +} +``` + +Similarly, workspaces teamB and teamC only show their respective admins: + +``` +http :8001/teamB/rbac/users Kong-Admin-Token:vajeOlkbsn0q0VD9qw9B3nHYOErgY7b8 +{ + "total": 1, + "data": [ + { + "created_at": 1531014805000, + "id": "3a829408-c1ee-4764-8222-2d280a5de441", + "name": "adminB", + "enabled": true, + "user_token": "C8b6kTTN10JFyU63ORjmCQwVbvK4maeq" + } + ] +} +``` + +``` +http :8001/teamC/rbac/users Kong-Admin-Token:vajeOlkbsn0q0VD9qw9B3nHYOErgY7b8 +{ + "total": 1, + "data": [ + { + "created_at": 1531014813000, + "id": "84d43cdb-5274-4b74-ad22-615e50f005e3", + "name": "adminC", + "enabled": true, + "user_token": "zN5Nj8U1MiGR7vVQKvl8odaGBDI6mjgY" + } + ] +} +``` + +## Super Admin Creates Admin Roles for Teams + +Super Admin is now done creating RBAC Admin users for each team; his next +task is to create admin roles that will effectively grant permissions to admin +users. + +The admin role must have access to all of the Admin API, restricted to his +workspace. + +Setting up the Admin role—pay close attention to the request parameters: + +``` +http :8001/teamA/rbac/roles/ name=admin Kong-Admin-Token:vajeOlkbsn0q0VD9qw9B3nHYOErgY7b8 +{ + "created_at": 1531016728000, + "id": "d40e61ab-8dad-4ef2-a48b-d11379f7b8d1", + "name": "admin" +} +``` + +Creating role endpoint permissions: + +``` +http :8001/teamA/rbac/roles/admin/endpoints/ endpoint=* workspace=teamA actions=* Kong-Admin-Token:vajeOlkbsn0q0VD9qw9B3nHYOErgY7b8 +{ + "total": 1, + "data": [ + { + "endpoint": "*", + "created_at": 1531017322000, + "role_id": "d40e61ab-8dad-4ef2-a48b-d11379f7b8d1", + "actions": [ + "delete", + "create", + "update", + "read" + ], + "negative": false, + "workspace": "teamA" + } + ] +} +``` + +Next logical step is to add the adminA user—admin of Team A—to the Admin +role in his workspace: + +``` +http :8001/teamA/rbac/users/adminA/roles/ roles=admin Kong-Admin-Token:vajeOlkbsn0q0VD9qw9B3nHYOErgY7b8 +{ + "roles": [ + { + "comment": "Default user role generated for adminA", + "created_at": 1531014784000, + "id": "e2941b41-92a4-4f49-be89-f1a452bdecd0", + "name": "adminA" + }, + { + "created_at": 1531016728000, + "id": "d40e61ab-8dad-4ef2-a48b-d11379f7b8d1", + "name": "admin" + } + ], + "user": { + "created_at": 1531014784000, + "id": "1faaacd1-709f-4762-8c3e-79f268ec8faf", + "name": "adminA", + "enabled": true, + "user_token": "n5bhjgv0speXp4N7rSUzUj8PGnl3F5eG" + } +} +``` + +Note the admin role in the list above. + +With these steps, Team A's admin user is now able to manage his team. To +validate that, let's try to list RBAC users in Team B using Team A's admin +user token—and see that we are not allowed to do so: + +``` +http :8001/teamB/rbac/users Kong-Admin-Token:n5bhjgv0speXp4N7rSUzUj8PGnl3F5eG +{ + "message": "Invalid RBAC credentials" +} +``` + +Said admin is, however, allowed to list RBAC users in Team A's workspace: + +``` +http :8001/teamA/rbac/users Kong-Admin-Token:n5bhjgv0speXp4N7rSUzUj8PGnl3F5eG +{ + "total": 1, + "data": [ + { + "created_at": 1531014784000, + "id": "1faaacd1-709f-4762-8c3e-79f268ec8faf", + "name": "adminA", + "enabled": true, + "user_token": "n5bhjgv0speXp4N7rSUzUj8PGnl3F5eG" + } + ] +} +``` + +If the same procedure is repeated for Team B and Team C, they will end up with +a similar set up, with an admin role and an admin user, both restricted to the +team's workspace. + +And so Super Admin ends his participation; individual team admins are now able +to set up his teams users and entities! + +## Team Admins Create Team Regular Users + +From this point on, team admins are able to drive the process; the next logical +step is for Team users to be created; such team users could be, for example, +engineers that are part of Team A (or B or C). Let's go ahead and do that, +using Admin A's user token. + +Before regular users can be created, a role needs to be available for them. +Such a role needs to have permissions to all of Admin API endpoints, except +RBAC and Workspaces—regular users will not need access to these in general +and, if they do, the Admin can grant them. + +**Creating the regular users role**: + +``` +http :8001/teamA/rbac/roles/ name=users Kong-Admin-Token:n5bhjgv0speXp4N7rSUzUj8PGnl3F5eG +{ + "created_at": 1531020346000, + "id": "9846b92c-6820-4741-ac31-425b3d6abc5b", + "name": "users" +} +``` + +**Creating permissions in the regular users role**: + +First, permission to all of Admin API—positive permission on \*: + +``` +http :8001/teamA/rbac/roles/users/endpoints/ endpoint=* workspace=teamA actions=* Kong-Admin-Token:n5bhjgv0speXp4N7rSUzUj8PGnl3F5eG +{ + "endpoint": "*", + "created_at": 1531020573000, + "role_id": "9846b92c-6820-4741-ac31-425b3d6abc5b", + "actions": [ + "delete", + "create", + "update", + "read" + ], + "negative": false, + "workspace": "teamA" +} +``` + +Then, filter out RBAC and workspaces with negative permissions: + +``` +http :8001/teamA/rbac/roles/users/endpoints/ endpoint=/rbac/* workspace=teamA actions=* Kong-Admin-Token:n5bhjgv0speXp4N7rSUzUj8PGnl3F5eG +{ + "endpoint": "/rbac/*", + "created_at": 1531020744000, + "role_id": "9846b92c-6820-4741-ac31-425b3d6abc5b", + "actions": [ + "delete", + "create", + "update", + "read" + ], + "negative": true, + "workspace": "teamA" +} +``` + +``` +http :8001/teamA/rbac/roles/users/endpoints/ endpoint=/workspaces/* workspace=teamA actions=* Kong-Admin-Token:n5bhjgv0speXp4N7rSUzUj8PGnl3F5eG +{ + "endpoint": "/workspaces/*", + "created_at": 1531020778000, + "role_id": "9846b92c-6820-4741-ac31-425b3d6abc5b", + "actions": [ + "delete", + "create", + "update", + "read" + ], + "negative": true, + "workspace": "teamA" +} +``` + +**IMPORTANT**: as explained in the [Wildcards in Permissions](#wildcards-in-permissions) +section, the meaning of `*` is not the expected generic globbing one might +be used to. As such, `/rbac/*` or `/workspaces/*` do not match all of the +RBAC and Workspaces endpoints. For example, to cover all of the RBAC API, +one would have to define permissions for the following endpoints: + +- `/rbac/*` +- `/rbac/*/*` +- `/rbac/*/*/*` +- `/rbac/*/*/*/*` +- `/rbac/*/*/*/*/*` + +Team A just got 3 new members: foogineer, bargineer, and bazgineer. Admin A +will welcome them to the team by creating RBAC users for them and giving them +access to Kong! + +Create foogineer: + +``` +http :8001/teamA/rbac/users name=foogineer Kong-Admin-Token:n5bhjgv0speXp4N7rSUzUj8PGnl3F5eG +{ + "created_at": 1531019797000, + "id": "0b4111da-2827-4767-8651-a327f7a559e9", + "name": "foogineer", + "enabled": true, + "user_token": "dNeYvYAwvjOJdoReVJZXF8vLBXQioKkI" +} +``` + +Add foogineer to the `users` role: + +``` +http :8001/teamA/rbac/users/foogineer/roles roles=users Kong-Admin-Token:n5bhjgv0speXp4N7rSUzUj8PGnl3F5eG +{ + "roles": [ + { + "comment": "Default user role generated for foogineer", + "created_at": 1531019797000, + "id": "125c4212-b882-432d-a323-9cbe38b1d0df", + "name": "foogineer" + }, + { + "created_at": 1531020346000, + "id": "9846b92c-6820-4741-ac31-425b3d6abc5b", + "name": "users" + } + ], + "user": { + "created_at": 1531019797000, + "id": "0b4111da-2827-4767-8651-a327f7a559e9", + "name": "foogineer", + "enabled": true, + "user_token": "dNeYvYAwvjOJdoReVJZXF8vLBXQioKkI" + } +} +``` + +Create bargineer: + +``` +http :8001/teamA/rbac/users name=bargineer Kong-Admin-Token:n5bhjgv0speXp4N7rSUzUj8PGnl3F5eG +{ + "created_at": 1531019837000, + "id": "25dfa68e-32e8-48d8-815f-6fedfd2fb4a6", + "name": "bargineer", + "enabled": true, + "user_token": "eZj3WUc46wO3zEJbLP3Y4VGvNaUgGlyv" +} +``` + +Add bargineer to the `users` role: + +``` +http :8001/teamA/rbac/users/bargineer/roles roles=users Kong-Admin-Token:n5bhjgv0speXp4N7rSUzUj8PGnl3F5eG +{ + "roles": [ + { + "comment": "Default user role generated for bargineer", + "created_at": 1531019837000, + "id": "3edb00c2-9ae1-423d-ac81-bec702c29e37", + "name": "bargineer" + }, + { + "created_at": 1531020346000, + "id": "9846b92c-6820-4741-ac31-425b3d6abc5b", + "name": "users" + } + ], + "user": { + "created_at": 1531019837000, + "id": "25dfa68e-32e8-48d8-815f-6fedfd2fb4a6", + "name": "bargineer", + "enabled": true, + "user_token": "eZj3WUc46wO3zEJbLP3Y4VGvNaUgGlyv" + } +} +``` + +Create bazgineer: + +``` +http :8001/teamA/rbac/users name=bazgineer Kong-Admin-Token:n5bhjgv0speXp4N7rSUzUj8PGnl3F5eG +{ + "created_at": 1531019937000, + "id": "ea7207d7-0d69-427b-b288-ce696b7f4690", + "name": "bazgineer", + "enabled": true, + "user_token": "r8NhaT213Zm8o1woQF4ZyQyCVjFRgGp3" +} +``` + +Add bazgineer to the `users` role: + +``` +http :8001/teamA/rbac/users/bazgineer/roles roles=users Kong-Admin-Token:n5bhjgv0speXp4N7rSUzUj8PGnl3F5eG +{ + "roles": [ + { + "comment": "Default user role generated for bazgineer", + "created_at": 1531019937000, + "id": "fa409bb6-c86c-45d2-8a6b-ac8e71de2cc9", + "name": "bazgineer" + }, + { + "created_at": 1531020346000, + "name": "users", + "id": "9846b92c-6820-4741-ac31-425b3d6abc5b" + } + ], + "user": { + "created_at": 1531019937000, + "id": "ea7207d7-0d69-427b-b288-ce696b7f4690", + "name": "bazgineer", + "enabled": true, + "user_token": "r8NhaT213Zm8o1woQF4ZyQyCVjFRgGp3" + } +} +``` + +## Regular Team Users use their tokens + +foogineer, bargineer, and bazgineer all have gotten their RBAC user tokens +from their Team A admin, and are now allowed to explore Kong—within the +confines of their Team A workspace. Let's validate they can in fact do anything +they wish, except over RBAC and Workspaces. + +Try listing Workspaces: + +``` +http :8001/teamA/workspaces/ Kong-Admin-Token:dNeYvYAwvjOJdoReVJZXF8vLBXQioKkI +{ + "message": "foogineer, you do not have permissions to read this resource" +} +``` + +Enable some plugin—e.g., key-auth: + +``` +http :8001/teamA/plugins name=key-auth Kong-Admin-Token:dNeYvYAwvjOJdoReVJZXF8vLBXQioKkI +{ + "created_at": 1531021732000, + "config": { + "key_in_body": false, + "run_on_preflight": true, + "anonymous": "", + "hide_credentials": false, + "key_names": [ + "apikey" + ] + }, + "id": "cdc85ef0-804b-4f92-aafd-3ff58512e445", + "enabled": true, + "name": "key-auth" +} +``` + +List currently enabled plugins: + +``` +http :8001/teamA/plugins Kong-Admin-Token:dNeYvYAwvjOJdoReVJZXF8vLBXQioKkI +{ + "total": 1, + "data": [ + { + "created_at": 1531021732000, + "config": { + "key_in_body": false, + "run_on_preflight": true, + "anonymous": "", + "hide_credentials": false, + "key_names": [ + "apikey" + ] + }, + "id": "cdc85ef0-804b-4f92-aafd-3ff58512e445", + "name": "key-auth", + "enabled": true + } + ] +} +``` + +This ends our use case tutorial; it demonstrates the power of RBAC and +workspaces with a real-world scenario. Following, we will approach **Entity-Level +RBAC**, an extension of our powerful access control to entity-level granularity. + +## Entity-Level RBAC: a Primer + +{{site.base_gateway}}'s new RBAC implementation goes one step further in permissions +granularity: in addition to "endpoint" permissions, it supports entity-level +permissions, meaning that particular entities, identified by their unique ID, +can be allowed or disallowed access in a role. + +Refreshing our minds, RBAC is [enforced](#enforcing-rbac) with the `enforce_rbac` +configuration directive—or with its `KONG_ENFORCE_RBAC` environment variable +counterpart. Such directive is an enum, with 4 possible values: + +- `on`: similarly to the previous RBAC implementation, applies Endpoint-level +access control +- `entity`: applies **only** Entity-level access control +- `both`: applies **both Endpoint and Entity level access control** +- `off`: disables RBAC enforcement + +If one sets it to either `entity` or `both`, Kong will enforce entity-level +access control. However, as with endpoint-level access control, permissions +must be bootstrapped before enforcement is enabled. + +### Creating Entity-Level Permissions + +Team A just got one new, temporary, team member: qux. Admin A, the admin of +Team A, has already created his qux RBAC user; he needs, however, to limit +access that qux has over entities in Team A workspace, giving him read access +to only a couple of entities—say, a Service and a Route. For that, he will +use Entity-Level RBAC. + +**Admin A creates a role for the temporary user qux**: + +``` +http :8001/teamA/rbac/roles name=qux-role Kong-Admin-Token:n5bhjgv0speXp4N7rSUzUj8PGnl3F5eG +{ + "name": "qux-role", + "created_at": 1531065975000, + "id": "ffe93269-7993-4308-965e-0286d0bc87b9" +} +``` + +We will assume the following entities exist: + +A service: + +``` +http :8001/teamA/services Kong-Admin-Token:n5bhjgv0speXp4N7rSUzUj8PGnl3F5eG +{ + "next": null, + "data": [ + { + "host": "httpbin.org", + "created_at": 1531066074, + "connect_timeout": 60000, + "id": "3ed24101-19a7-4a0b-a10f-2f47bcd4ff43", + "protocol": "http", + "name": "service1", + "read_timeout": 60000, + "port": 80, + "path": null, + "updated_at": 1531066074, + "retries": 5, + "write_timeout": 60000 + } + ] +} +``` + +and a Route to that Service: + +``` +http :8001/teamA/routes Kong-Admin-Token:n5bhjgv0speXp4N7rSUzUj8PGnl3F5eG +{ + "next": null, + "data": [ + { + "created_at": 1531066253, + "id": "d25afc46-dc59-48b2-b04f-d3ebe19f6d4b", + "hosts": null, + "updated_at": 1531066253, + "preserve_host": false, + "regex_priority": 0, + "service": { + "id": "3ed24101-19a7-4a0b-a10f-2f47bcd4ff43" + }, + "paths": [ + "/anything" + ], + "methods": null, + "strip_path": false, + "protocols": [ + "http", + "https" + ] + } + ] +} +``` + +**Admin A creates entity permissions in qux-role**: + +Add service1—whose ID is 3ed24101-19a7-4a0b-a10f-2f47bcd4ff43: + +``` +http :8001/teamA/rbac/roles/qux-role/entities entity_id=3ed24101-19a7-4a0b-a10f-2f47bcd4ff43 actions=read Kong-Admin-Token:n5bhjgv0speXp4N7rSUzUj8PGnl3F5eG +{ + "created_at": 1531066684000, + "role_id": "ffe93269-7993-4308-965e-0286d0bc87b9", + "entity_id": "3ed24101-19a7-4a0b-a10f-2f47bcd4ff43", + "negative": false, + "entity_type": "services", + "actions": [ + "read" + ] +} +``` + +Add the route—whose ID is d25afc46-dc59-48b2-b04f-d3ebe19f6d4b: + +``` +http :8001/teamA/rbac/roles/qux-role/entities entity_id=d25afc46-dc59-48b2-b04f-d3ebe19f6d4b actions=read Kong-Admin-Token:n5bhjgv0speXp4N7rSUzUj8PGnl3F5eG +{ + "created_at": 1531066728000, + "role_id": "ffe93269-7993-4308-965e-0286d0bc87b9", + "entity_id": "d25afc46-dc59-48b2-b04f-d3ebe19f6d4b", + "negative": false, + "entity_type": "routes", + "actions": [ + "read" + ] +} +``` + +**Admin A adds qux to his role**: + +``` +http :8001/teamA/rbac/users/qux/roles roles=qux-role Kong-Admin-Token:n5bhjgv0speXp4N7rSUzUj8PGnl3F5eG +{ + "roles": [ + { + "comment": "Default user role generated for qux", + "created_at": 1531065373000, + "name": "qux", + "id": "31614171-4174-42b4-9fae-43c9ce14830f" + }, + { + "created_at": 1531065975000, + "name": "qux-role", + "id": "ffe93269-7993-4308-965e-0286d0bc87b9" + } + ], + "user": { + "created_at": 1531065373000, + "id": "4d87bf78-5824-4756-b0d0-ceaa9bd9b2d5", + "name": "qux", + "enabled": true, + "user_token": "sUnv6uBehM91amYRNWESsgX3HzqoBnR5" + } +} +``` + +Checking permissions appear listed: + +``` +http :8001/teamA/rbac/users/qux/permissions Kong-Admin-Token:n5bhjgv0speXp4N7rSUzUj8PGnl3F5eG +{ + "entities": { + "d25afc46-dc59-48b2-b04f-d3ebe19f6d4b": { + "actions": [ + "read" + ], + "negative": false + }, + "3ed24101-19a7-4a0b-a10f-2f47bcd4ff43": { + "actions": [ + "read" + ], + "negative": false + } + }, + "endpoints": {} +} +``` + +That is, 2 entities permissions and no endpoint permissions. + +Admin A is done setting up qux, and qux can now use his user token to read +his two entities over Kong's admin API. + +We will assume that Admin A [enabled entity-level enforcement](#enforcing-rbac). +Note that as qux has **no endpoint-level permissions**, if both endpoint and +entity-level enforcement is enabled, he will not be able to read his entities - +endpoint-level validation comes before entity-level. + +**qux tries listing all RBAC users** + +``` +http :8001/teamA/rbac/users/ Kong-Admin-Token:sUnv6uBehM91amYRNWESsgX3HzqoBnR5 +{ + "message": "qux, you do not have permissions to read this resource" +} +``` + +**qux tries listing all Workspaces** + +``` +http :8001/teamA/rbac/workspaces/ Kong-Admin-Token:sUnv6uBehM91amYRNWESsgX3HzqoBnR5 +{ + "message": "qux, you do not have permissions to read this resource" +} +``` + +**qux tries to access service1** + +``` +http :8001/teamA/services/service1 Kong-Admin-Token:sUnv6uBehM91amYRNWESsgX3HzqoBnR5 +{ + "host": "httpbin.org", + "created_at": 1531066074, + "connect_timeout": 60000, + "id": "3ed24101-19a7-4a0b-a10f-2f47bcd4ff43", + "protocol": "http", + "name": "service1", + "read_timeout": 60000, + "port": 80, + "path": null, + "updated_at": 1531066074, + "retries": 5, + "write_timeout": 60000 +} +``` + +Similarly, he can access his Route: + +``` +http :8001/teamA/routes/3ed24101-19a7-4a0b-a10f-2f47bcd4ff43 Kong-Admin-Token:sUnv6uBehM91amYRNWESsgX3HzqoBnR5 +{ + "created_at": 1531066253, + "strip_path": false, + "hosts": null, + "preserve_host": false, + "regex_priority": 0, + "updated_at": 1531066253, + "paths": [ + "/anything" + ], + "service": { + "id": "3ed24101-19a7-4a0b-a10f-2f47bcd4ff43" + }, + "methods": null, + "protocols": [ + "http", + "https" + ], + "id": "d25afc46-dc59-48b2-b04f-d3ebe19f6d4b" +} +``` + +## Closing Remarks + +We will end this chapter with a few closing remarks. + +### Wildcards in Permissions + +RBAC supports the use of wildcards—represented by the `*` character—in many +aspects of permissions: + +**Creating endpoint permissions—`/rbac/roles/:role/endpoints`** + +To create an endpoint permission, one must pass the parameters below, all of +which can be replaced by a * character: + +- `endpoint`: `*` matches **any endpoint** +- `workspace`: `*` matches **any workspace** +- `actions`: `*` evaluates to **all actions—read, update, create, delete** + +**Special case**: `endpoint`, in addition to a single `*`, also accepts `*` +within the endpoint itself, replacing a URL segment between `/`; for example, +all of the following are valid endpoints: + +- `/rbac/*`: where `*` replaces any possible segment—e.g., `/rbac/users`, +`/rbac/roles`, etc +- `/services/*/plugins`: `*` matches any Service name or ID + +Note, however, that `*` **is not** a generic, shell-like, glob pattern. + +If `workspace` is ommitted, it defaults to the current request's workspace. For +example, a role-endpoint permission created with `/teamA/roles/admin/endpoints` +is scoped to workspace `teamA`. + +**Creating entity permissions—`/rbac/roles/:role/entities`** + +Similarly, for entity permissions, the following parameters accept a `*` +character: + +- `entity_id`: `*` matches **any entity ID** + +### Entities Concealing in Entity-Level RBAC + +With Entity-Level RBAC enabled, endpoints that list all entities of a +particular collection will only list entities that the user has access to; +in the example above, if user qux listed all Routes, he would only get as +response the entities he has access to—even though there could be more: + +``` +http :8001/teamA/routes Kong-Admin-Token:sUnv6uBehM91amYRNWESsgX3HzqoBnR5 +{ + "next": null, + "data": [ + { + "created_at": 1531066253, + "id": "d25afc46-dc59-48b2-b04f-d3ebe19f6d4b", + "hosts": null, + "updated_at": 1531066253, + "preserve_host": false, + "regex_priority": 0, + "service": { + "id": "3ed24101-19a7-4a0b-a10f-2f47bcd4ff43" + }, + "paths": [ + "/anything" + ], + "methods": null, + "strip_path": false, + "protocols": [ + "http", + "https" + ] + } + ] +} +``` + +Some Kong endpoints carry a `total` field in responses; with Entity-Level RBAC +enabled, the global count of entities is displayed, but only entities the user +has access to are themselves shown; for example, if Team A has a number of +plugins configured, but qux only has access to one of them, the following +would be the expected output for a GET request to `/teamA/plugins`: + +``` +http :8001/teamA/plugins Kong-Admin-Token:sUnv6uBehM91amYRNWESsgX3HzqoBnR5 +{ + "total": 2, + "data": [ + { + "created_at": 1531070344000, + "config": { + "key_in_body": false, + "run_on_preflight": true, + "anonymous": "", + "hide_credentials": false, + "key_names": [ + "apikey" + ] + }, + "id": "8813dd0b-3e9d-4bcf-8a10-3112654f86e7", + "name": "key-auth", + "enabled": true + } + ] +} +``` + +Notice the `total` field is 2, but qux only got one entity in the response. + +### Creating Entities in Entity-Level RBAC + +As entity-level RBAC provides access control to individual existing entities, +it does not apply to creation of new entities; for that, endpoint-level +permissions must be configured and enforced. For example, if endpoint-level +permissions are not enforced, qux will be able to create new entities: + +``` +http :8001/teamA/routes paths[]=/anything service.id=3ed24101-19a7-4a0b-a10f-2f47bcd4ff43 strip_path=false Kong-Admin-Token:sUnv6uBehM91amYRNWESsgX3HzqoBnR5 +{ + "created_at": 1531070828, + "strip_path": false, + "hosts": null, + "preserve_host": false, + "regex_priority": 0, + "updated_at": 1531070828, + "paths": [ + "/anything" + ], + "service": { + "id": "3ed24101-19a7-4a0b-a10f-2f47bcd4ff43" + }, + "methods": null, + "protocols": [ + "http", + "https" + ], + "id": "6ee76f74-3c96-46a9-ae48-72df0717d244" +} +``` + +and qux will automatically have permissions to perform any actions to entities +he created. + +--- + +[workspaces-examples]: /gateway/{{page.kong_version}}/kong-enterprise/workspaces +[getting-started-guide]: /gateway/{{page.kong_version}}/get-started/ diff --git a/src/gateway/production/access-control/register-admin-api.md b/src/gateway/production/access-control/register-admin-api.md new file mode 100644 index 000000000000..2baf297fe948 --- /dev/null +++ b/src/gateway/production/access-control/register-admin-api.md @@ -0,0 +1,57 @@ +--- +title: Admins Examples +badge: enterprise +--- + +## How to Invite and Register an Admin + +### Introduction + +Can be used for automation + +### Prerequisites + +```bash +export USERNAME= +export EMAIL= +export WORKSPACE= +export HOST= +export TOKEN=Kong-Admin-Token: +``` + +for example: +```bash +export USERNAME=drogon +export EMAIL=test@test.com +export WORKSPACE=default +export HOST=127.0.0.1:8001 +export ADMIN_TOKEN=Kong-Admin-Token:hunter2 +``` + +May benefit from HTTPie and jq. + +## Step 1 +Extract and store the token from the registration URL, either by manually creating an environment variable or by echoing and piping with `jq`: + +#### Manual method example: + +1. Send a request to the registration URL +```bash +http $HOST/$WORKSPACE/admins/$USERNAME?generate_register_url=true $TOKEN +``` + +2. Copy the response and export as an environment variable, for example: +```bash +export REGISTER_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1NDUwNjc0NjUsImlkIjoiM2IyNzY3MzEtNjIxZC00ZjA3LTk3YTQtZjU1NTg0NmJkZjJjIn0.gujRDi2pX_E7u2zuhYBWD4MoPFKe3axMAq-AUcORg2g +``` + +#### Programmatic method (requires `jq`): +```bash +REGISTER_TOKEN=$(http $HOST/$WORKSPACE/admins/$USERNAME?generate_register_url=true $TOKEN | jq .token -r) +``` + +## Step 2 + +```bash +http $HOST/$WORKSPACE/admins/register token=$REGISTER_TOKEN username=$USERNAME email=$EMAIL password="" +``` diff --git a/src/gateway/production/access-control/start-securely.md b/src/gateway/production/access-control/start-securely.md new file mode 100644 index 000000000000..e43cf33f2295 --- /dev/null +++ b/src/gateway/production/access-control/start-securely.md @@ -0,0 +1,99 @@ +--- +title: Start Kong Gateway Securely +badge: enterprise +--- + +To secure the Admin API or Kong Manager, a Super Admin account is +required. + +The Super Admin has the ability to invite other Admins and +restrict their access based on Permissions of Roles within +Workspaces. + +The first Super Admin account is created during database migrations +following the guide below. It may only be added once. + +## Prerequisites + +After [installing {{site.base_gateway}}](/gateway/{{page.kong_version}}/install/), +either modify the configuration file or set environment variables for +the following properties: + +* `enforce_rbac` will force all Admin API requests to require a +`Kong-Admin-Token`. The Admin associated with the `Kong-Admin-Token` +must have adequate Permissions in order for the request to succeed. + +* If using Kong Manager, select the type of authentication that Admins +should use to log in. For the purpose of this guide, `admin_gui_auth` +may be set to `basic-auth`. See +[Securing Kong Manager](/gateway/{{page.kong_version}}/kong-manager/auth/) for other types +of authentication. + +For a simple configuration to use for the subsequent Getting +Started guides: + +{% include_cached /md/admin-listen.md desc='long' kong_version=page.kong_version %} + +``` +enforce_rbac = on +admin_gui_auth = basic-auth +admin_gui_session_conf = {"secret":"secret","storage":"kong","cookie_secure":false} +admin_listen = 0.0.0.0:8001, 0.0.0.0:8444 ssl +``` + +⚠️**Important:** the Sessions Plugin requires a secret and is configured securely by default. +* Under all circumstances, the `secret` must be manually set to a string. +* If using HTTP instead of HTTPS, `cookie_secure` must be manually set to `false`. +* If using different domains for the Admin API and Kong Manager, `cookie_samesite` must be set to `off`. +Learn more about these properties in [Session Security in Kong Manager](/gateway/{{page.kong_version}}/kong-manager/auth/sessions/#session-security), and see [example configurations](/gateway/{{page.kong_version}}/kong-manager/auth/sessions#example-configurations). + +## Step 1 + +Set a password for the Super Admin. This environment variable must +be present in the environment where database migrations will run. + +{:.important} +> **Important**: Setting your Kong password (`KONG_PASSWORD`) using a value containing four ticks (for example, `KONG_PASSWORD="a''a'a'a'a"`) causes a PostgreSQL syntax error on bootstrap. To work around this issue, do not use special characters in your password. + +``` +export KONG_PASSWORD= +``` + +This automatically creates a user, `kong_admin`, and a password that +can be used to log in to Kong Manager. This password may also be +used as a `Kong-Admin-Token` to make Admin API requests. + +**Note:** only one Super Admin may be created using this method, and only +on a fresh installation with an empty database. If one is not created during migrations, +follow [this guide](/gateway/{{page.kong_version}}/kong-manager/auth/rbac/add-admin/) to remediate. + +Future migrations will not update the password or create additional Super Admins. +To add additional Super Admins it is necessary to +[invite a new user as a Super Admin in Kong Manager](/gateway/{{page.kong_version}}/kong-manager/auth//super-admin/). + +## Step 2 + +Issue the following command to prepare your data store by running the Kong migrations: + +``` +kong migrations bootstrap [-c /path/to/kong.conf] +``` + +## Step 3 + +Start Kong: + +``` +kong start [-c /path/to/kong.conf] +``` + +**Note:** the CLI accepts a configuration option (`-c /path/to/kong.conf`) +allowing you to point to [your own configuration](/gateway/{{page.kong_version}}/reference/configuration/#configuration-loading). + +## Step 4 + +To test that {{site.base_gateway}} has successfully started with a Super Admin, +visit Kong Manager's URL. By default, it is on port `:8002`. + +The username is `kong_admin` and the password is the one set in +[Step 1](#step-1). diff --git a/src/gateway/production/blue-green.md b/src/gateway/production/blue-green.md new file mode 100644 index 000000000000..b5ab01498e24 --- /dev/null +++ b/src/gateway/production/blue-green.md @@ -0,0 +1,80 @@ +--- +title: Blue-green Deployments +content_type: tutorial +--- + +Using the [ring-balancer](/gateway/latest/how-kong-works/load-balancing/#ring-balancer), a blue-green deployment can be easily orchestrated for +a service. Switching target infrastructure only requires a `PATCH` request on a +service to change its `host` value. + +Set up the "blue" environment, running version one of the address service: + +1. Create an upstream: + ```bash + curl -X POST http://localhost:8001/upstreams \ + --data "name=address.v1.service" + ``` + +2. Add two targets to the upstream: + ```sh + curl -X POST http://localhost:8001/upstreams/address.v1.service/targets \ + --data "target=192.168.34.15:80" + --data "weight=100" + curl -X POST http://localhost:8001/upstreams/address.v1.service/targets \ + --data "target=192.168.34.16:80" + --data "weight=50" + ``` +3. Create a service targeting the Blue upstream: + ```sh + curl -X POST http://localhost:8001/services/ \ + --data "name=address-service" \ + --data "host=address.v1.service" \ + --data "path=/address" + ``` + +4. Finally, add a route as an entry-point into the service: + ```sh + curl -X POST http://localhost:8001/services/address-service/routes/ \ + --data "hosts[]=address.mydomain.com" + ``` + +Requests with host header set to `address.mydomain.com` will now be proxied +by {{site.base_gateway}} to the two defined targets. Two-thirds of the requests will go to +`http://192.168.34.15:80/address` (`weight=100`), and one-third will go to +`http://192.168.34.16:80/address` (`weight=50`). + +Before deploying version two of the address service, set up the "Green" +environment: + +1. Create a new Green upstream for address service v2: + ```sh + curl -X POST http://localhost:8001/upstreams \ + --data "name=address.v2.service" + ``` + +2. Add targets to the upstream: + ```sh + curl -X POST http://localhost:8001/upstreams/address.v2.service/targets \ + --data "target=192.168.34.17:80" + --data "weight=100" + curl -X POST http://localhost:8001/upstreams/address.v2.service/targets \ + --data "target=192.168.34.18:80" + --data "weight=100" + ``` + +3. To activate the blue/green switch, we now only need to update the service. +Switch the Service from Blue to Green upstream, v1 -> v2: + + ```bash + curl -X PATCH http://localhost:8001/services/address-service \ + --data "host=address.v2.service" + ``` + +Incoming requests with host header set to `address.mydomain.com` are now +proxied by Kong to the new targets. Half of the requests will go to +`http://192.168.34.17:80/address` (`weight=100`), and the other half will go to +`http://192.168.34.18:80/address` (`weight=100`). + +As always, the changes through the {{site.base_gateway}} Admin API are dynamic and take +effect immediately. No reload or restart is required, and no in-progress +requests are dropped. diff --git a/src/gateway/production/canary.md b/src/gateway/production/canary.md new file mode 100644 index 000000000000..4651b79b9402 --- /dev/null +++ b/src/gateway/production/canary.md @@ -0,0 +1,44 @@ +--- +title: Canary Deployments +content-type: reference +--- + +Using the [ring-balancer](/gateway/latest/how-kong-works/load-balancing/#ring-balancer), target weights can be adjusted granularly, allowing +for a smooth, controlled canary release. + +Using a very simple two target example: + +```bash +# first target at 1000 +curl -X POST http://localhost:8001/upstreams/address.v2.service/targets \ + --data "target=192.168.34.17:80" + --data "weight=1000" +``` + +```sh +# second target at 0 +curl -X POST http://localhost:8001/upstreams/address.v2.service/targets \ + --data "target=192.168.34.18:80" + --data "weight=0" +``` + +By repeating the requests, but altering the weights each time, traffic will +slowly be routed towards the other target. For example, set it at 10%: + +```bash +# first target at 900 +curl -X POST http://localhost:8001/upstreams/address.v2.service/targets \ + --data "target=192.168.34.17:80" + --data "weight=900" +``` + +```sh +# second target at 100 +curl -X POST http://localhost:8001/upstreams/address.v2.service/targets \ + --data "target=192.168.34.18:80" + --data "weight=100" +``` + +The changes through the {{site.base_gateway}} Admin API are dynamic and take +effect immediately. No reload or restart is required, and no in progress +requests are dropped. diff --git a/src/gateway/production/clustering.md b/src/gateway/production/clustering.md new file mode 100644 index 000000000000..a16eb6dea9d4 --- /dev/null +++ b/src/gateway/production/clustering.md @@ -0,0 +1,301 @@ +--- +title: Clustering Reference +--- + +A Kong cluster allows you to scale the system horizontally by adding more +machines to handle more incoming requests. They will all share the same +configuration since they point to the same database. Kong nodes pointing to the +**same datastore** will be part of the same Kong cluster. + +You need a load balancer in front of your Kong cluster to distribute traffic +across your available nodes. + +## What a Kong cluster does and doesn't do + +**Having a Kong cluster does not mean that your clients traffic will be +load-balanced across your Kong nodes out of the box.** You still need a +load-balancer in front of your Kong nodes to distribute your traffic. Instead, +a Kong cluster means that those nodes will share the same configuration. + +For performance reasons, Kong avoids database connections when proxying +requests, and caches the contents of your database in memory. The cached +entities include Services, Routes, Consumers, Plugins, Credentials, and so on. Since those +values are in memory, any change made via the Admin API of one of the nodes +needs to be propagated to the other nodes. + +This document describes how those cached entities are being invalidated and how +to configure your Kong nodes for your use case, which lies somewhere between +performance and consistency. + +## Single node Kong clusters + + +{% include_cached /md/enterprise/cassandra-deprecation.md %} + + +A single Kong node connected to a database (Cassandra or PostgreSQL) creates a +Kong cluster of one node. Any changes applied via the Admin API of this node +will instantly take effect. Example: + +Consider a single Kong node `A`. If we delete a previously registered Service: + +```bash +curl -X DELETE http://127.0.0.1:8001/services/test-service +``` + +Then any subsequent request to `A` would instantly return `404 Not Found`, as +the node purged it from its local cache: + +```bash +curl -i http://127.0.0.1:8000/test-service +``` + +## Multiple nodes Kong clusters + +In a cluster of multiple Kong nodes, other nodes connected to the same database +would not instantly be notified that the Service was deleted by node `A`. While +the Service is **not** in the database anymore (it was deleted by node `A`), it is +**still** in node `B`'s memory. + +All nodes perform a periodic background job to synchronize with changes that +may have been triggered by other nodes. The frequency of this job can be +configured via: + +* [db_update_frequency][db_update_frequency] (default: 5 seconds) + +Every `db_update_frequency` seconds, all running Kong nodes will poll the +database for any update, and will purge the relevant entities from their cache +if necessary. + +If we delete a Service from node `A`, this change will not be effective in node +`B` until node `B`s next database poll, which will occur up to +`db_update_frequency` seconds later (though it could happen sooner). + +This makes Kong clusters **eventually consistent**. + +### Use read-only replicas when deploying Kong clusters with Postgres + +When using Postgres as the backend storage, you can optionally enable +Kong to serve read queries from a separate database instance. + +Enabling the read-only connection support in Kong +greatly reduces the load on the main database instance since read-only +queries are no longer sent to it. + +To learn more about how to configure this feature, refer to the +[Datastore section](/gateway/{{page.kong_version}}/reference/configuration/#datastore-section) +of the Configuration reference. + +## What is being cached? + +All of the core entities such as Services, Routes, Plugins, Consumers, Credentials are +cached in memory by Kong and depend on their invalidation via the polling +mechanism to be updated. + +Additionally, Kong also caches **database misses**. This means that if you +configure a Service with no plugin, Kong will cache this information. Example: + +On node `A`, we add a Service and a Route: + +```bash +# node A +curl -X POST http://127.0.0.1:8001/services \ + --data "name=example-service" \ + --data "url=http://example.com" + +curl -X POST http://127.0.0.1:8001/services/example-service/routes \ + --data "paths[]=/example" +``` + +(Note that we used `/services/example-service/routes` as a shortcut: we +could have used the `/routes` endpoint instead, but then we would need to +pass `service_id` as an argument, with the UUID of the new Service.) + +A request to the Proxy port of both node `A` and `B` will cache this Service, and +the fact that no plugin is configured on it: + +```bash +# node A +curl http://127.0.0.1:8000/example +``` + +Response: +``` +HTTP 200 OK +... +``` + +```bash +# node B +curl http://127.0.0.2:8000/example +``` + +Response: +``` +HTTP 200 OK +... +``` + +Now, say we add a plugin to this Service via node `A`'s Admin API: + +```bash +# node A +curl -X POST http://127.0.0.1:8001/services/example-service/plugins \ + --data "name=example-plugin" +``` + +Because this request was issued via node `A`'s Admin API, node `A` will locally +invalidate its cache and on subsequent requests, it will detect that this API +has a plugin configured. + +However, node `B` hasn't run a database poll yet, and still caches that this +API has no plugin to run. It will be so until node `B` runs its database +polling job. + +**Conclusion**: All CRUD operations trigger cache invalidations. Creation +(`POST`, `PUT`) will invalidate cached database misses, and update/deletion +(`PATCH`, `DELETE`) will invalidate cached database hits. + +## How to configure database caching? + +You can configure three properties in the Kong configuration file, the most +important one being `db_update_frequency`, which determine where your Kong +nodes stand on the performance versus consistency trade-off. + +Kong comes with default values tuned for consistency so that you can +experiment with its clustering capabilities while avoiding surprises. As you +prepare a production setup, you should consider tuning those values to ensure +that your performance constraints are respected. + +### 1. [db_update_frequency][db_update_frequency] (default: 5s) + +This value determines the frequency at which your Kong nodes will be polling +the database for invalidation events. A lower value means that the polling +job will execute more frequently, but that your Kong nodes will keep up +with changes you apply. A higher value means that your Kong nodes will +spend less time running the polling jobs, and will focus on proxying your +traffic. + +**Note**: Changes propagate through the cluster in up to `db_update_frequency` +seconds. + +### 2. [db_update_propagation][db_update_propagation] (default: 0s) + +If your database itself is eventually consistent (that is, Cassandra), you **must** +configure this value. It is to ensure that the change has time to propagate +across your database nodes. When set, Kong nodes receiving invalidation events +from their polling jobs will delay the purging of their cache for +`db_update_propagation` seconds. + +If a Kong node connected to an eventually consistent database was not delaying +the event handling, it could purge its cache, only to cache the non-updated +value again (because the change hasn't propagated through the database yet)! + +You should set this value to an estimate of the amount of time your database +cluster takes to propagate changes. + +**Note**: When this value is set, changes propagate through the cluster in +up to `db_update_frequency + db_update_propagation` seconds. + +### 3. [db_cache_ttl][db_cache_ttl] (default: 0s) + +The time (in seconds) for which Kong will cache database entities (both hits +and misses). This Time-To-Live value acts as a safeguard in case a Kong node +misses an invalidation event, to avoid it from running on stale data for too +long. When the TTL is reached, the value will be purged from its cache, and the +next database result will be cached again. + +By default, no data is invalidated based on this TTL (the default value is `0`). +This is usually fine: Kong nodes rely on invalidation events, which are handled +at the db store level (Cassandra/PostgreSQL). If you are concerned that a Kong +node might miss invalidation event for any reason, you should set a TTL. Otherwise +the node might run with a stale value in its cache for an undefined amount of time +until the cache is manually purged, or the node is restarted. + +### 4. When using Cassandra + +If you use Cassandra as your Kong database, you **must** set +[db_update_propagation][db_update_propagation] to a non-zero value. Since +Cassandra is eventually consistent by nature, this will ensure that Kong nodes +do not prematurely invalidate their cache, only to fetch and catch a +not up-to-date entity again. Kong will present you a warning in logs if you did +not configure this value when using Cassandra. + +Additionally, you might want to configure `cassandra_consistency` to a value +like `QUORUM` or `LOCAL_QUORUM`, to ensure that values being cached by your +Kong nodes are up-to-date values from your database. + +Setting the `cassandra_refresh_frequency` option to `0` is not advised, as a Kong +restart will be required to discover any changes to the Cassandra cluster topology. + +## Interacting with the cache via the Admin API + +If for some reason, you want to investigate the cached values, or manually +invalidate a value cached by Kong (a cached hit or miss), you can do so via the +Admin API `/cache` endpoint. + +### Inspect a cached value + +**Endpoint** + +
      /cache/{cache_key}
      + +**Response** + +If a value with that key is cached: + +``` +HTTP 200 OK +... +{ + ... +} +``` + +Else: + +``` +HTTP 404 Not Found +``` + +**Note**: Retrieving the `cache_key` for each entity being cached by Kong is +currently an undocumented process. Future versions of the Admin API will make +this process easier. + +### Purge a cached value + +**Endpoint** + +
      /cache/{cache_key}
      + +**Response** + +``` +HTTP 204 No Content +... +``` + +**Note**: Retrieving the `cache_key` for each entity being cached by Kong is +currently an undocumented process. Future versions of the Admin API will make +this process easier. + +### Purge a node's cache + +**Endpoint** + +
      /cache
      + +**Response** + +``` +HTTP 204 No Content +``` + +**Note**: Be wary of using this endpoint on a node running in production with warm cache. +If the node is receiving a lot of traffic, purging its cache at the same time +will trigger many requests to your database, and could cause a +[dog-pile effect](https://en.wikipedia.org/wiki/Cache_stampede). + +[db_update_frequency]: /gateway/{{page.kong_version}}/reference/configuration/#db_update_frequency +[db_update_propagation]: /gateway/{{page.kong_version}}/reference/configuration/#db_update_propagation +[db_cache_ttl]: /gateway/{{page.kong_version}}/reference/configuration/#db_cache_ttl diff --git a/src/gateway/production/deployment-topologies/db-less-and-declarative-config.md b/src/gateway/production/deployment-topologies/db-less-and-declarative-config.md new file mode 100644 index 000000000000..e098dea07a6f --- /dev/null +++ b/src/gateway/production/deployment-topologies/db-less-and-declarative-config.md @@ -0,0 +1,294 @@ +--- +title: DB-less and Declarative Configuration +--- + + +{% include_cached /md/enterprise/cassandra-deprecation.md %} + + +Traditionally, Kong Gateway has always required a database, to store its configured entities such as Routes, +Services and Plugins. Kong uses its configuration file, `kong.conf`, to +specify the use of Postgres and Cassandra and its various settings. + +Kong Gateway can be run without a database using only in-memory storage for entities. We call this DB-less mode. When running Kong Gateway DB-less, the configuration of entities is done in a second configuration file, in YAML or JSON, using declarative configuration. + +The combination of DB-less mode and declarative configuration has a number +of benefits: + +* reduced number of dependencies: no need to manage a database installation + if the entire setup for your use-cases fits in memory +* it is a good fit for automation in CI/CD scenarios: configuration for + entities can be kept in a single source of truth managed via a Git + repository +* it enables more deployment options for Kong + +## Declarative configuration + +The key idea in declarative configuration is the notion +that it is *declarative*, as opposed to an *imperative* style of +configuration. "Imperative" means that a configuration is given as a series of +orders: "do this, then do that". "Declarative" means that the configuration is +given all at once: "I declare this to be the state of the world". + +The Kong Admin API is an example of an imperative configuration tool. The +final state of the configuration is attained through a sequence of API calls: +one call to create a Service, another call to create a Route, another call to +add a Plugin, and so on. + +Performing the configuration incrementally like this has the undesirable +side-effect that *intermediate states* happen. In the above example, there is +a window of time in between creating a Route and adding the Plugin in which +the Route did not have the Plugin applied. + +A declarative configuration file, on the other hand, will contain the settings +for all desired entities in a single file, and once that file is loaded into +Kong, it replaces the entire configuration. When incremental changes are +desired, they are made to the declarative configuration file, which is then +reloaded in its entirety. At all times, the configuration described in the +file loaded into Kong is the configured state of the system. + +## Set up Kong in DB-less mode + +To use Kong Gateway in DB-less mode, set the `database` directive of `kong.conf` to `off`. As usual, you can do this by editing `kong.conf` and setting +`database=off` or via environment variables. You can then start Kong +as usual: + +``` +export KONG_DATABASE=off +kong start -c kong.conf +``` + +Once Kong starts, access the `/` endpoint of the Admin API to verify that it +is running without a database. It will return the entire Kong configuration; +verify that `database` is set to `off`. + +Command: + +``` +http :8001/ +``` + +Sample response: + +``` +HTTP/1.1 200 OK +Access-Control-Allow-Origin: * +Connection: keep-alive +Content-Length: 6342 +Content-Type: application/json; charset=utf-8 +Date: Wed, 27 Mar 2019 15:24:58 GMT +Server: kong/2.1.0 +{ + "configuration:" { + ... + "database": "off", + ... + }, + ... + "version": "2.1.0" +} +``` + +Kong Gateway is running, but no declarative configuration was loaded yet. This +means that the configuration of this node is empty. There are no Routes, +Services or entities of any kind. + +Command: + +``` +http :8001/routes +``` + +Sample response: + +``` +HTTP/1.1 200 OK +Access-Control-Allow-Origin: * +Connection: keep-alive +Content-Length: 23 +Content-Type: application/json; charset=utf-8 +Date: Wed, 27 Mar 2019 15:30:02 GMT +Server: kong/2.1.0 + +{ + "data": [], + "next": null +} +``` + +## Creating a declarative configuration file + +{:.note} +> **Note:** We recommend using decK to manage your declarative configuration. +See the [decK documentation](/deck) for more information. + +To load entities into DB-less Kong, we need a declarative configuration +file. The following command will create a skeleton file to get you +started: + +``` +kong config -c kong.conf init +``` + +This command creates a `kong.yml` file in the current directory, +containing examples of the syntax for declaring entities and their +relationships. All examples in the generated file are commented-out +by default. You can experiment by uncommenting the examples +(removing the `#` markers) and modifying their values. + +## Declarative configuration format + +The Kong Gateway declarative configuration format consists of lists of +entities and their attributes. This is a small yet complete +example that illustrates a number of features: + +```yaml +_format_version: "3.0" +_transform: true + +services: +- name: my-service + url: https://example.com + plugins: + - name: key-auth + routes: + - name: my-route + paths: + - / + +consumers: +- username: my-user + keyauth_credentials: + - key: my-key +``` + +The only mandatory piece of metadata is `_format_version: "3.0"`, which +specifies the version number of the declarative configuration syntax format. +This also matches the minimum version of Kong required to parse the file. + +The `_transform` metadata is an optional boolean (defaults to `true`), which +controls whether schema transformations will occur while importing. The rule +of thumb for using this field is: if you are importing plain-text credentials +(i.e. passwords), you likely want to set it to `true`, so that Kong will +encrypt/hash them before storing them in the database. If you are importing +**already hashed/encrypted** credentials, set `_transform` to `false` so that +the encryption does not happen twice. + +At the top level, you can specify any Kong entity, be it a core entity such as +`services` and `consumers` as in the above example, or custom entities created +by Plugins, such as `keyauth_credentials`. This makes the declarative +configuration format inherently extensible, and it is the reason why `kong +config` commands that process declarative configuration require `kong.conf` to +be available, so that the `plugins` directive is taken into account. + +When entities have a relationship, such as a Route that points to a Service, +this relationship can be specified via nesting. + +Only one-to-one relationships can be specified by nesting: a Plugin that is +applied to a Service can have its relationship depicted via nesting, as in the +example above. Relationships involving more than two entities, such as a +Plugin that is applied to both a Service and a Consumer must be done via a +top-level entry, where the entities can be identified by their primary keys +or identifying names (the same identifiers that can be used to refer to them +in the Admin API). This is an example of a plugin applied to a Service and +a Consumer: + +```yml +plugins: +- name: syslog + consumer: my-user + service: my-service +``` + +## Check the file + +Once you are done editing the file, it is possible to check the syntax +for any errors before attempting to load it into Kong: + +``` +kong config -c kong.conf parse kong.yml +``` + +Response: +``` +parse successful +``` + +## Load the file + +There are two ways to load a declarative configuration file into Kong: using +`kong.conf` or the Admin API. + +To load a declarative configuration file at Kong start-up, use the +`declarative_config` directive in `kong.conf` (or, as usual to all `kong.conf` +entries, the equivalent `KONG_DECLARATIVE_CONFIG` environment variable). + +``` +export KONG_DATABASE=off \ +export KONG_DECLARATIVE_CONFIG=kong.yml \ +kong start -c kong.conf +``` + +You can also load a declarative configuration file into a running +Kong node with the Admin API, using the `/config` endpoint. The +following example loads `kong.yml` using HTTPie: + +``` +http :8001/config config=@kong.yml +``` + +{:.important} +The `/config` endpoint replaces the entire set of entities in memory +with the ones specified in the given file. + +Or another way you can start Kong in DB-less mode is with a +declarative configuration in a string using the `KONG_DECLARATIVE_CONFIG_STRING` +environment variable. + +``` +export KONG_DATABASE=off +export KONG_DECLARATIVE_CONFIG_STRING='{"_format_version":"1.1", "services":[{"host":"mockbin.com","port":443,"protocol":"https", "routes":[{"paths":["/"]}]}],"plugins":[{"name":"rate-limiting", "config":{"policy":"local","limit_by":"ip","minute":3}}]}' +kong start +``` + +## Using Kong in DB-less mode + +There are a number of things to be aware of when using Kong in DB-less +mode. + +### Memory cache requirements + +The entire configuration of entities must fit inside the Kong +cache. Make sure that the in-memory cache is configured appropriately: +see the `mem_cache_size` directive in `kong.conf`. + +### No central database coordination + +Since there is no central database, multiple Kong nodes have no +central coordination point and no cluster propagation of data: +nodes are completely independent of each other. + +This means that the declarative configuration should be loaded into each node +independently. Using the `/config` endpoint does not affect other Kong +nodes, since they have no knowledge of each other. + +### Read-only Admin API + +Since the only way to configure entities is via declarative configuration, +the endpoints for CRUD operations on entities are effectively read-only +in the Admin API when running Kong in DB-less mode. `GET` operations +for inspecting entities work as usual, but attempts to `POST`, `PATCH` +`PUT` or `DELETE` in endpoints such as `/services` or `/plugins` will return +`HTTP 405 Not Allowed`. + +This restriction is limited to what would be otherwise database operations. In +particular, using `POST` to set the health state of Targets is still enabled, +since this is a node-specific in-memory operation. + +#### Plugin compatibility + +Not all Kong plugins are compatible with DB-less mode since some of them +by design require a central database coordination or dynamic creation of +entities. + +For current plugin compatibility, see [Plugin compatibility](/konnect-platform/compatibility/plugins/). diff --git a/src/gateway/production/deployment-topologies/hybrid-mode/index.md b/src/gateway/production/deployment-topologies/hybrid-mode/index.md new file mode 100644 index 000000000000..e2e86f2101ae --- /dev/null +++ b/src/gateway/production/deployment-topologies/hybrid-mode/index.md @@ -0,0 +1,235 @@ +--- +title: Hybrid Mode Overview +--- + +Traditionally, Kong has always required a database, to store configured +entities such as Routes, Services, and Plugins. + +Starting with {{site.base_gateway}} 2.1, Kong can be deployed in +hybrid mode, also known as control plane / data plane separation (CP/DP). + +In this mode, Kong nodes in a cluster are split into two roles: control plane +(CP), where configuration is managed and the Admin API is served from; and data +plane (DP), which serves traffic for the proxy. Each DP node is connected to one +of the CP nodes. Instead of accessing the database contents directly in the +traditional deployment method, the DP nodes maintain connection with CP nodes, +and receive the latest configuration. + +![Hybrid mode topology](/assets/images/docs/ee/deployment/deployment-hybrid-2.png) + +When you create a new data plane node, it establishes a connection to the +control plane. The control plane listens on port 8005 for connections and +tracks any incoming data from its data planes. + +Once connected, every Admin API or Kong Manager action on the control plane +triggers an update to the data planes in the cluster. + +## Benefits + +Hybrid mode deployments have the following benefits: + +* **Deployment flexibility:** Users can deploy groups of data planes in +different data centers, geographies, or zones without needing a local clustered +database for each DP group. +* **Increased reliability:** The availability of the database does not affect +the availability of the data planes. Each DP caches the latest configuration it +received from the control plane on local disk storage, so if CP nodes are down, +the DP nodes keep functioning. + * While the CP is down, DP nodes constantly try to reestablish communication. + * DP nodes can be restarted while the CP is down, and still proxy traffic + normally. +* **Traffic reduction:** Drastically reduces the amount of traffic to and from +the database, since only CP nodes need a direct connection to the database. +* **Increased security:** If one of the DP nodes is compromised, an attacker +won’t be able to affect other nodes in the Kong cluster. +* **Ease of management:** Admins only need to interact with the CP nodes to +control and monitor the status of the entire Kong cluster. + +## Platform Compatibility + +You can run {{site.base_gateway}} in hybrid mode on any platform where +{{site.base_gateway}} is [supported](/gateway/{{page.kong_version}}/install/). + +### Kubernetes Support and Additional Documentation + +[{{site.base_gateway}} on Kubernetes](/gateway/{{page.kong_version}}/install/kubernetes/helm-quickstart) +fully supports hybrid mode deployments, with or without the Kong Ingress Controller. + +For the full Kubernetes hybrid mode documentation, see +[hybrid mode](https://github.com/Kong/charts/blob/main/charts/kong/README.md#hybrid-mode) +in the `kong/charts` repository. + +## Version Compatibility + +{{site.base_gateway}} control planes only allow connections from data planes with the +same major version. +Control planes won't allow connections from data planes with newer minor versions. + +For example, a {{site.base_gateway}} v2.5.2 control plane: + +- Accepts a {{site.base_gateway}} 2.5.0, 2.5.1 and 2.5.2 data plane. +- Accepts a {{site.base_gateway}} 2.3.8, 2.2.1 and 2.2.0 data plane. +- Accepts a {{site.base_gateway}} 2.5.3 data plane (newer patch version on the data plane is accepted). +- Rejects a {{site.base_gateway}} 1.0.0 data plane (major version differs). +- Rejects a {{site.base_gateway}} 2.6.0 data plane (minor version on data plane is newer). + +Furthermore, for every plugin that is configured on the {{site.base_gateway}} +control plane, new configs are only pushed to data planes that have those configured +plugins installed and loaded. The major version of those configured plugins must +be the same on both the control planes and data planes. Also, the minor versions +of the plugins on the data planes can not be newer than versions installed on the +control planes. Similar to {{site.base_gateway}} version checks, +plugin patch versions are also ignored when determining compatibility. + +{:.important} +> Configured plugins means any plugin that is either enabled globally or +configured by services, routes, or consumers. + +For example, if a {{site.base_gateway}} control plane has `plugin1` v1.1.1 +and `plugin2` v2.1.0 installed, and `plugin1` is configured by a `Route` object: + +- It accepts {{site.base_gateway}} data planes with `plugin1` v1.1.2, +`plugin2` not installed. +- It accepts {{site.base_gateway}} data planes with `plugin1` v1.1.2, +`plugin2` v2.1.0, and `plugin3` v9.8.1 installed. +- It accepts {{site.base_gateway}} data planes with `plugin1` v1.1.1 +and `plugin3` v9.8.1 installed. +- It rejects {{site.base_gateway}} data planes with `plugin1` v1.2.0, +`plugin2` v2.1.0 installed (minor version of plugin on data plane is newer). +- It rejects {{site.base_gateway}} data planes with `plugin1` not installed +(plugin configured on control plane but not installed on data plane). + +Version compatibility checks between the control plane and data plane +occur at configuration read time. As each data plane proxy receives +configuration updates, it checks to see if it can enable the requested +features. If the control plane has a newer version of {{site.base_gateway}} +than the data plane proxy, but the configuration doesn’t include any new features +from that newer version, the data plane proxy reads and applies it as expected. + +For instance, a new version of {{site.base_gateway}} includes a new +plugin offering, and you update your control plane with that version. You can +still send configurations to your data planes that are on a less recent version +as long as you have not added the new plugin offering to your configuration. +If you add the new plugin to your configuration, you will need to update your +data planes to the newer version for the data planes to continue to read from +the control plane. + +If the compatibility checks fail, the control plane stops +pushing out new config to the incompatible data planes to avoid breaking them. + +If a config can not be pushed to a data plane due to failure of the +compatibility checks, the control plane will contain `warn` level lines in the +`error.log` similar to the following: + +```bash +unable to send updated configuration to DP node with hostname: localhost.localdomain ip: 127.0.0.1 reason: version mismatches, CP version: 2.2 DP version: 2.1 +unable to send updated configuration to DP node with hostname: localhost.localdomain ip: 127.0.0.1 reason: CP and DP does not have same set of plugins installed or their versions might differ +``` + +In addition, the `/clustering/data-planes` Admin API endpoint returns +the version of the data plane node and the latest config hash the node is +using. This data helps detect version incompatibilities from the +control plane side. + +## Fault tolerance + +If control plane nodes are down, the data plane will keep functioning. Data plane caches +the latest configuration it received from the control plane on the local disk. +In case the control plane stops working, the data plane will keep serving requests using +cached configurations. It does so while constantly trying to reestablish communication +with the control plane. + +This means that the data plane nodes can be stopped even for extended periods +of time, and the data plane will still proxy traffic normally. Data plane +nodes can be restarted while in disconnected mode, and will load the last +configuration in the cache to start working. When the control plane is brought +up again, the data plane nodes will contact them and resume connected mode. + +### Disconnected Mode + +The viability of the data plane while disconnected means that control plane +updates or database restores can be done with peace of mind. First bring down +the control plane, perform all required downtime processes, and only bring up +the control plane after verifying the success and correctness of the procedure. +During that time, the data plane will keep working with the latest configuration. + +A new data plane node can be provisioned during control plane downtime. This +requires either copying the LMDB directory (`dbless.lmdb`) from another +data plane node, or using a declarative configuration. In either case, if it +has the role of `"data_plane"`, it will also keep trying to contact the control +plane until it's up again. + +To change a disconnected data plane node's configuration, you have to remove +the LMDB directory (`dbless.lmdb`), ensure the `declarative_config` +parameter or the `KONG_DECLARATIVE_CONFIG` environment variable is set, and set +the whole configuration in the referenced YAML file. + +### Data plane cache configuration +{:.badge .enterprise} + +By default, data planes store their configuration to the file system +in an unencrypted LMDB database, `dbless.lmdb`, in {{site.base_gateway}}'s +`prefix` path. <>. + +If encrypted, the data plane uses the cluster certificate key to decrypt the +LMDB database on startup. + +## Limitations + +### Configuration Inflexibility + +When a configuration change is made at the control plane level via the Admin +API, it immediately triggers a cluster-wide update of all data plane +configurations. This means that the same configuration is synced from the CP to +all DPs, and the update cannot be scheduled or batched. For different DPs to +have different configurations, they will need their own CP instances. + +### Plugin Incompatibility + +When plugins are running on a data plane in hybrid mode, there is no Admin API +exposed directly from that DP. Since the Admin API is only exposed from the +control plane, all plugin configuration has to occur from the CP. Due to this +setup, and the configuration sync format between the CP and the DP, some plugins +have limitations in hybrid mode: + +* [**Key Auth Encrypted:**](/hub/kong-inc/key-auth-enc) The time-to-live setting +(`ttl`), which determines the length of time a credential remains valid, does +not work in hybrid mode. +* [**Rate Limiting Advanced:**](/hub/kong-inc/rate-limiting-advanced) +This plugin does not support the `cluster` strategy in hybrid mode. The `redis` +strategy must be used instead. +* [**OAuth 2.0 Authentication:**](/hub/kong-inc/oauth2) This plugin is not +compatible with hybrid mode. For its regular workflow, the plugin needs to both +generate and delete tokens, and commit those changes to the database, which is +not possible with CP/DP separation. + +### Custom Plugins + +Custom plugins (either your own plugins or third-party plugins that are not +shipped with Kong) need to be installed on both the control plane and the data +plane in hybrid mode. + +### Load Balancing + +Currently, there is no automated load balancing for connections between the +control plane and the data plane. You can load balance manually by using +multiple control planes and redirecting the traffic using a TCP proxy. + +## Readonly Status API endpoints on data plane + +Several readonly endpoints from the [Admin API](/gateway/{{page.kong_version}}/admin-api) +are exposed to the [Status API](/gateway/{{page.kong_version}}/reference/configuration/#status_listen) on data planes, including the following: + +- [GET /upstreams/{upstream}/targets/](/gateway/{{page.kong_version}}/admin-api/#list-targets) +- [GET /upstreams/{upstream}/health/](/gateway/{{page.kong_version}}/admin-api/#show-upstream-health-for-node) +- [GET /upstreams/{upstream}/targets/all/](/gateway/{{page.kong_version}}/admin-api/#list-all-targets) +- GET /upstreams/{upstream}/targets/{target} + +Please refer to [Upstream objects](/gateway/{{page.kong_version}}/admin-api/#upstream-object) in the Admin API documentation for more information about the +endpoints. + +## Keyring encryption in hybrid mode + +Because the keyring module encrypts data in the database, it can't encrypt +data on data plane nodes, since these nodes run without a database and get +data from the control plane. diff --git a/src/gateway/production/deployment-topologies/hybrid-mode/setup.md b/src/gateway/production/deployment-topologies/hybrid-mode/setup.md new file mode 100644 index 000000000000..460d6ecbe6df --- /dev/null +++ b/src/gateway/production/deployment-topologies/hybrid-mode/setup.md @@ -0,0 +1,677 @@ +--- +title: Deploy Kong Gateway in Hybrid Mode +--- + +## Prerequisites + +To get started with a hybrid mode deployment, first install an instance of +{{site.base_gateway}} with TLS to be your control plane (CP) node. See the +[installation documentation](/gateway/{{page.kong_version}}/install/) +for details. + +We will bring up any subsequent data plane (DP) instances in this topic. + +{:.note} +> **Note:** For a hybrid mode deployment on Kubernetes, see [hybrid mode](https://github.com/Kong/charts/blob/main/charts/kong/README.md#hybrid-mode) +in the `kong/charts` repository. + +## Generate a certificate/key pair + +In hybrid mode, a mutual TLS handshake (mTLS) is used for authentication so the +actual private key is never transferred on the network, and communication +between CP and DP nodes is secure. + +Before using hybrid mode, you need a certificate/key pair. +{{site.base_gateway}} provides two modes for handling certificate/key pairs: + +* **Shared mode:** (Default) Use the Kong CLI to generate a certificate/key +pair, then distribute copies across nodes. The certificate/key pair is shared +by both CP and DP nodes. +* **PKI mode:** Provide certificates signed by a central certificate authority +(CA). Kong validates both sides by checking if they are from the same CA. This +eliminates the risks associated with transporting private keys. + +{:.warning} +> **Warning:** If you have a TLS-aware proxy between the DP and CP nodes, you +must use PKI mode and set `cluster_server_name` to the CP hostname in +`kong.conf`. Do not use shared mode, as it uses a non-standard value for TLS server name +indication, and this will confuse TLS-aware proxies that rely on SNI to route +traffic. + +For a breakdown of the properties used by these modes, see the +[configuration reference](#configuration-reference). + +{% navtabs %} +{% navtab Shared mode %} +{:.warning} + > **Warning:** Protect the Private Key. Ensure the private key file can only be accessed by + Kong nodes belonging to the cluster. If the key is compromised, you must + regenerate and replace certificates and keys on all CP and DP nodes. + +1. On an existing {{site.base_gateway}} instance, create a certificate/key pair: + ```bash + kong hybrid gen_cert + ``` + This will generate `cluster.crt` and `cluster.key` files and save them to + the current directory. By default, the certificate/key pair is valid for three + years, but can be adjusted with the `--days` option. See `kong hybrid --help` + for more usage information. + +2. Copy the `cluster.crt` and `cluster.key` files to the same directory +on all Kong CP and DP nodes; e.g., `/cluster/cluster`. + Set appropriate permissions on the key file so it can only be read by Kong. + +{% endnavtab %} +{% navtab PKI mode %} + +With PKI mode, the Hybrid cluster can use certificates signed by a central +certificate authority (CA). + +In this mode, the control plane and data plane don't need to use the same +`cluster_cert` and `cluster_cert_key`. Instead, Kong validates both sides by +checking if they are from the same CA. + +Prepare your CA certificates on the hosts where Kong will be running. + +{% navtabs %} +{% navtab CA Certificate Example %} +Typically, a CA certificate will look like this: + +``` +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 5d:29:73:bf:c3:da:5f:60:69:da:73:ed:0e:2e:97:6f:7f:4c:db:4b + Signature Algorithm: ecdsa-with-SHA256 + Issuer: O = Kong Inc., CN = Hybrid Root CA + Validity + Not Before: Jul 7 12:36:10 2020 GMT + Not After : Jul 7 12:36:40 2023 GMT + Subject: O = Kong Inc., CN = Hybrid Root CA + Subject Public Key Info: + Public Key Algorithm: id-ecPublicKey + Public-Key: (256 bit) + pub: + 04:df:49:9f:39:e6:2c:52:9f:46:7a:df:ae:7b:9b: + 87:1e:76:bb:2e:1d:9c:61:77:07:e5:8a:ba:34:53: + 3a:27:4c:1e:76:23:b4:a2:08:80:b4:1f:18:7a:0b: + 79:de:ea:8c:23:94:e6:2f:57:cf:27:b4:0a:52:59: + 90:2c:2b:86:03 + ASN1 OID: prime256v1 + NIST CURVE: P-256 + X509v3 extensions: + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Subject Key Identifier: + 8A:0F:07:61:1A:0F:F4:B4:5D:B7:F3:B7:28:D1:C5:4B:81:A2:B9:25 + X509v3 Authority Key Identifier: + keyid:8A:0F:07:61:1A:0F:F4:B4:5D:B7:F3:B7:28:D1:C5:4B:81:A2:B9:25 + + Signature Algorithm: ecdsa-with-SHA256 + 30:45:02:20:68:3c:d1:f3:63:a2:aa:b4:59:c9:52:af:33:b7: + 3f:ca:3a:2b:1c:9d:87:0c:c0:47:ff:a2:c4:af:3e:b0:36:29: + 02:21:00:86:ce:d0:fc:ba:92:e9:59:16:1c:c3:b2:11:11:ed: + 01:5d:16:49:d0:f9:0c:1d:35:0d:40:ba:19:98:31:76:57 +``` +{% endnavtab %} + +{% navtab CA Certificate on CP %} +Here is an example of a CA certificate on a control plane: + +``` +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 18:cc:a3:6b:aa:77:0a:69:c6:d5:ff:12:be:be:c0:ac:5c:ff:f1:1e + Signature Algorithm: ecdsa-with-SHA256 + Issuer: CN = Hybrid Intermediate CA + Validity + Not Before: Jul 31 00:59:29 2020 GMT + Not After : Oct 29 00:59:59 2020 GMT + Subject: CN = control-plane.kong.yourcorp.tld + Subject Public Key Info: + Public Key Algorithm: id-ecPublicKey + Public-Key: (256 bit) + pub: + 04:f8:3a:a9:d2:e2:79:19:19:f3:1c:58:a0:23:60: + 78:04:1f:7e:e2:bb:60:d2:29:50:ad:7c:9b:8e:22: + 1c:54:c2:ce:68:b8:6c:8a:f6:92:9d:0c:ce:08:d3: + aa:0c:20:67:41:32:18:63:c9:dd:50:31:60:d6:8b: + 8d:f9:7b:b5:37 + ASN1 OID: prime256v1 + NIST CURVE: P-256 + X509v3 extensions: + X509v3 Key Usage: critical + Digital Signature, Key Encipherment, Key Agreement + X509v3 Extended Key Usage: + TLS Web Server Authentication + X509v3 Subject Key Identifier: + 70:C7:F0:3B:CD:EB:8D:1B:FF:6A:7C:E0:A4:F0:C6:4C:4A:19:B8:7F + X509v3 Authority Key Identifier: + keyid:16:0D:CF:92:3B:31:B0:61:E5:AB:EE:91:42:B9:60:56:0A:88:92:82 + + X509v3 Subject Alternative Name: + DNS:control-plane.kong.yourcorp.tld, DNS:alternate-control-plane.kong.yourcorp.tld + X509v3 CRL Distribution Points: + + Full Name: + URI:https://crl-service.yourcorp.tld/v1/pki/crl + + Signature Algorithm: ecdsa-with-SHA256 + 30:44:02:20:5d:dd:ec:a8:4f:e7:5b:7d:2f:3f:ec:b5:40:d7: + de:5e:96:e1:db:b7:73:d6:84:2e:be:89:93:77:f1:05:07:f3: + 02:20:16:56:d9:90:06:cf:98:07:87:33:dc:ef:f4:cc:6b:d1: + 19:8f:64:ee:82:a6:e8:e6:de:57:a7:24:82:72:82:49 +``` +{% endnavtab %} + +{% navtab CA Certificate on DP %} +Here is an example of a CA certificate on a data plane: + +``` +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 4d:8b:eb:89:a2:ed:b5:29:80:94:31:e4:94:86:ce:4f:98:5a:ad:a0 + Signature Algorithm: ecdsa-with-SHA256 + Issuer: CN = Hybrid Intermediate CA + Validity + Not Before: Jul 31 00:57:01 2020 GMT + Not After : Oct 29 00:57:31 2020 GMT + Subject: CN = kong-dp-ce39edecp.service + Subject Public Key Info: + Public Key Algorithm: id-ecPublicKey + Public-Key: (256 bit) + pub: + 04:19:51:80:4c:6d:8c:a8:05:63:42:71:a2:9a:23: + 34:34:92:c6:2a:d3:e5:15:6e:36:44:85:64:0a:4c: + 12:16:82:3f:b7:4c:e1:a1:5a:49:5d:4c:5e:af:3c: + c1:37:e7:91:e2:b5:52:41:a0:51:ac:13:7b:cc:69: + 93:82:9b:2f:e2 + ASN1 OID: prime256v1 + NIST CURVE: P-256 + X509v3 extensions: + X509v3 Key Usage: critical + Digital Signature, Key Encipherment, Key Agreement + X509v3 Extended Key Usage: + TLS Web Client Authentication + X509v3 Subject Key Identifier: + 25:82:8C:93:85:35:C3:D6:34:CF:CB:7B:D6:14:97:46:84:B9:2B:87 + X509v3 Authority Key Identifier: + keyid:16:0D:CF:92:3B:31:B0:61:E5:AB:EE:91:42:B9:60:56:0A:88:92:82 + X509v3 CRL Distribution Points: + + Full Name: + URI:https://crl-service.yourcorp.tld/v1/pki/crl + + Signature Algorithm: ecdsa-with-SHA256 + 30:44:02:20:65:2f:5e:30:f7:a4:28:14:88:53:58:c5:85:24: + 35:50:25:c9:fe:db:2f:72:9f:ad:7d:a0:67:67:36:32:2b:d2: + 02:20:2a:27:7d:eb:75:a6:ee:65:8b:f1:66:a4:99:32:56:7c: + ad:ca:3a:d5:50:8f:cf:aa:6d:c2:1c:af:a4:ca:75:e8 +``` +{% endnavtab %} +{% endnavtabs %} + +> **Note:** Certificates on CP and DP must contain the `TLS Web Server Authentication` and +`TLS Web Client Authentication` as X509v3 Extended Key Usage extension, respectively. + +Kong doesn't validate the CommonName (CN) in the DP certificate; it can take an arbitrary value. + +{% endnavtab %} +{% endnavtabs %} + +## Set up the control plane +Next, give the control plane node the `control_plane` role, and set +certificate/key parameters to point at the location of your certificates and +keys. + +{% navtabs %} +{% navtab Using Docker %} + +1. In your Docker container, set the following environment variables: + + For `shared` certificate mode, use: + ```bash + KONG_ROLE=control_plane + KONG_CLUSTER_CERT=//cluster.crt + KONG_CLUSTER_CERT_KEY=//cluster.key + ``` + + For `pki` certificate mode, use: + ```bash + KONG_ROLE=control_plane + KONG_CLUSTER_MTLS=pki + KONG_CLUSTER_CA_CERT=//ca-cert.pem + KONG_CLUSTER_CERT=//control-plane.crt + KONG_CLUSTER_CERT_KEY=//control-plane.key + ``` + By setting the role of the node to `control_plane`, this node will listen on + port `0.0.0.0:8005` by default for data plane connections, and on port + `0.0.0.0:8006` for telemetry data. These ports on the + control plane will need to be accessible by all data planes it controls through + any firewalls you may have in place. + + For PKI mode, `KONG_CLUSTER_CA_CERT` specifies the root CA certificate for + `KONG_CLUSTER_CERT` and `KONG_CLUSTER_CERT_KEY`. This certificate must be + the root CA certificate and not any of an intermediate CA. Kong allows a + maximum of three levels of intermediate CAs to be used between the root CA + and the cluster certificate. + + If you need to change the ports that the control plane listens on, set: + ```bash + KONG_CLUSTER_LISTEN=0.0.0.0: + KONG_CLUSTER_TELEMETRY_LISTEN=0.0.0.0: + ``` + +2. Next, start Kong, or reload Kong if it's already running: + ```bash + kong start + ``` + ```bash + kong reload + ``` + +{% endnavtab %} +{% navtab Using kong.conf %} +1. In `kong.conf`, set the following configuration parameters: + + For `shared` certificate mode, use: + ```bash + role = control_plane + cluster_cert = //cluster.crt + cluster_cert_key = //cluster.key + ``` + + For `pki` certificate mode, use: + ```bash + role = control_plane + cluster_mtls = pki + cluster_ca_cert = //ca-cert.pem + cluster_cert = //control-plane.crt + cluster_cert_key = //control-plane.key + ``` + + By setting the role of the node to `control_plane`, this node will listen on + port `0.0.0.0:8005` by default for data plane connections, and on port + `0.0.0.0:8006` for telemetry data. These ports on the + control plane will need to be accessible by all data planes it controls through + any firewalls you may have in place. + + For PKI mode, `cluster_ca_cert` specifies the root CA certificate for + `cluster_cert` and `cluster_cert_key`. This certificate must be the root CA + certificate and not any of an intermediate CA. Kong allows a maximum of three + levels of intermediate CAs to be used between the root CA and the cluster + certificate. + + If you need to change the ports that the control plane listens on, set: + ```bash + cluster_listen=0.0.0.0: + cluster_telemetry_listen=0.0.0.0: + ``` + +2. Restart Kong for the settings to take effect: + ```bash + kong restart + ``` +{% endnavtab %} +{% endnavtabs %} + +Note that the control plane still needs a database to +store the central configurations, although the database never needs to +be accessed by data plane nodes. You may run multiple control plane nodes to +provide load balancing and redundancy, as long as they all point to the same +backend database. + +{:.note} +> **Note:** Control plane nodes cannot be used for proxying. + +### (Optional) Revocation checks of data plane certificates + +When Kong is running hybrid mode with PKI mode, the control plane can be configured to +optionally check for revocation status of the connecting data plane certificate. + +The supported method is through Online Certificate Status Protocol (OCSP) responders. +Issued data plane certificates must contain the Certificate Authority Information Access extension +that references the URI of OCSP responder that can be reached from the control plane. + +To enable OCSP checks, set the `cluster_ocsp` config on the control plane to one of the following values: + +* `on`: OCSP revocation check is enabled and the data plane must pass the revocation check +to establish connection with the control plane. This implies that certificates without the +OCSP extension or unreachable OCSP responder also prevents a connection from being established. +* `off`: OCSP revocation check is disabled (default). +* `optional`: OCSP revocation check will be attempted, however, if the OCSP responder URI is not +found inside the data plane-provided certificate or communication with the OCSP responder failed, +then data plane is still allowed through. + +Note that OCSP checks are only performed on the control plane against certificates provided by incoming data plane +nodes. The `cluster_ocsp` config has no effect on data plane nodes. +`cluster_oscp` affects all hybrid mode connections established from a data plane to its control plane. + +## Install and start data planes +Now that the control plane is running, you can attach data plane nodes to it to +start serving traffic. + +In this step, you will give all data plane nodes the `data_plane` role, +point them to the control plane, set certificate/key parameters to point at +the location of your certificates and keys, and ensure the database +is disabled. + +In addition, the certificate from `cluster_cert` (in `shared` mode) or `cluster_ca_cert` +(in `pki` mode) is automatically added to the trusted chain in +[`lua_ssl_trusted_certificate`](/gateway/{{page.kong_version}}/reference/configuration/#lua_ssl_trusted_certificate). + +{:.important} +> **Important:** Data plane nodes receive updates from the control plane via a format +similar to declarative config, therefore `database` has to be set to +`off` for Kong to start up properly. + +See the [DP node start sequence](#dp-node-start-sequence) for more information +on how data plane nodes process configuration. + + +{% navtabs %} +{% navtab Using Docker %} +1. Using the [Docker installation documentation](/gateway/{{page.kong_version}}/install/docker), +follow the instructions to: + 1. [Download {{site.base_gateway}}](/gateway/{{page.kong_version}}/install/docker). + 2. [Create a Docker network](/gateway/{{page.kong_version}}/install/docker/#install-gateway-in-db-less-mode). + + {:.warning} + > **Warning:** Do not start or create a database on this node. + + +1. Bring up your data plane container with the following settings: + + For `shared` certificate mode, use: + +{% capture shared-mode-cp %} +{% navtabs codeblock %} +{% navtab Kong Gateway %} +```bash +docker run -d --name kong-dp --network=kong-net \ +-e "KONG_ROLE=data_plane" \ +-e "KONG_DATABASE=off" \ +-e "KONG_PROXY_LISTEN=0.0.0.0:8000" \ +-e "KONG_CLUSTER_CONTROL_PLANE=control-plane..com:8005" \ +-e "KONG_CLUSTER_TELEMETRY_ENDPOINT=control-plane..com:8006" \ +-e "KONG_CLUSTER_CERT=//cluster.crt" \ +-e "KONG_CLUSTER_CERT_KEY=//cluster.key" \ +--mount type=bind,source="$(pwd)"/cluster,target=,readonly \ +-p 8000:8000 \ +kong/kong-gateway:{{page.kong_versions[page.version-index].ee-version}}-alpine +``` +{% endnavtab %} +{% navtab Kong Gateway (OSS) %} +```bash +docker run -d --name kong-dp --network=kong-net \ +-e "KONG_ROLE=data_plane" \ +-e "KONG_DATABASE=off" \ +-e "KONG_PROXY_LISTEN=0.0.0.0:8000" \ +-e "KONG_CLUSTER_CONTROL_PLANE=control-plane..com:8005" \ +-e "KONG_CLUSTER_TELEMETRY_ENDPOINT=control-plane..com:8006" \ +-e "KONG_CLUSTER_CERT=//cluster.crt" \ +-e "KONG_CLUSTER_CERT_KEY=//cluster.key" \ +--mount type=bind,source="$(pwd)"/cluster,target=,readonly \ +-p 8000:8000 \ +kong:{{page.kong_versions[page.version-index].ce-version}}-alpine +``` +{% endnavtab %} +{% endnavtabs %} +{% endcapture %} +{{ shared-mode-cp | indent | replace: " ", "" }} + + For `pki` certificate mode, use: + +{% capture pki-mode-cp %} +{% navtabs codeblock %} +{% navtab Kong Gateway %} +```bash +docker run -d --name kong-dp --network=kong-net \ +-e "KONG_ROLE=data_plane" \ +-e "KONG_DATABASE=off" \ +-e "KONG_PROXY_LISTEN=0.0.0.0:8000" \ +-e "KONG_CLUSTER_CONTROL_PLANE=control-plane..com:8005" \ +-e "KONG_CLUSTER_TELEMETRY_ENDPOINT=control-plane..com:8006" \ +-e "KONG_CLUSTER_MTLS=pki" \ +-e "KONG_CLUSTER_SERVER_NAME=control-plane.kong.yourcorp.tld" \ +-e "KONG_CLUSTER_CERT=data-plane.crt" \ +-e "KONG_CLUSTER_CERT_KEY=//data-plane.crt" \ +-e "KONG_CLUSTER_CA_CERT=//ca-cert.pem" \ +--mount type=bind,source="$(pwd)"/cluster,target=,readonly \ +-p 8000:8000 \ +kong/kong-gateway:{{page.kong_versions[page.version-index].ee-version}}-alpine +``` +{% endnavtab %} +{% navtab Kong Gateway (OSS) %} +```bash +docker run -d --name kong-dp --network=kong-net \ +-e "KONG_ROLE=data_plane" \ +-e "KONG_DATABASE=off" \ +-e "KONG_PROXY_LISTEN=0.0.0.0:8000" \ +-e "KONG_CLUSTER_CONTROL_PLANE=control-plane..com:8005" \ +-e "KONG_CLUSTER_TELEMETRY_ENDPOINT=control-plane..com:8006" \ +-e "KONG_CLUSTER_MTLS=pki" \ +-e "KONG_CLUSTER_SERVER_NAME=control-plane.kong.yourcorp.tld" \ +-e "KONG_CLUSTER_CERT=data-plane.crt" \ +-e "KONG_CLUSTER_CERT_KEY=//data-plane.crt" \ +-e "KONG_CLUSTER_CA_CERT=//ca-cert.pem" \ +--mount type=bind,source="$(pwd)"/cluster,target=,readonly \ +-p 8000:8000 \ +kong:{{page.kong_versions[page.version-index].ce-version}}-alpine +``` +{% endnavtab %} +{% endnavtabs %} +{% endcapture %} +{{ pki-mode-cp | indent | replace: " ", "" }} + + Where: + + `--name` and `--network` + : The tag of the {{site.base_gateway}} image that you're using, and the Docker network it communicates on. + + `KONG_CLUSTER_CONTROL_PLANE` + : Sets the address and port of the control plane (port `8005` by defaut). + + `KONG_DATABASE` + : Specifies whether this node connects directly to a database. + + `` and `target=` + : Are the same path, pointing to the location of the `cluster.key` and + `cluster.crt` files. + + `KONG_CLUSTER_SERVER_NAME` + : Specifies the SNI (Server Name Indication + extension) to use for data plane connections to the control plane through + TLS. When not set, data plane will use `kong_clustering` as the SNI. + + : You can also optionally use `KONG_CLUSTER_TELEMETRY_SERVER_NAME` + to set a custom SNI for telemetry data. If not set, it defaults to + `KONG_CLUSTER_SERVER_NAME`. + + `KONG_CLUSTER_TELEMETRY_ENDPOINT` + : Optional setting, needed for telemetry gathering. Not available in open-source deployments. + + You can also choose to encrypt or disable the data plane configuration + cache with some additional settings: + +1. If needed, bring up any subsequent data planes using the same settings. + +{% endnavtab %} +{% navtab Using kong.conf %} + +1. Find the documentation for [your platform](/gateway/{{page.kong_version}}/install), +and follow the instructions in Steps 1 and 2 **only** to download +{{site.base_gateway}} and install Kong. + + {:.note} + > **Note:** for Docker, see the **Docker** tab above. For Kubernetes, see the + [hybrid mode documentation](https://github.com/Kong/charts/blob/main/charts/kong/README.md#hybrid-mode) + in the `kong/charts` repository. + + {:.warning} + > Do not start or create a database on this node. + + +2. In `kong.conf`, set the following configuration parameters: + + For `shared` certificate mode, use: + ```bash + role = data_plane + database = off + proxy_listen = 0.0.0.0:8000 + cluster_control_plane = control-plane..com:8005 + cluster_telemetry_endpoint = control-plane..com:8006 + cluster_cert = //cluster.crt + cluster_cert_key = //cluster.key + ``` + + For `pki` certificate mode, use: + ```bash + role = data_plane + database = off + proxy_listen = 0.0.0.0:8000 + cluster_control_plane = control-plane..com:8005 + cluster_telemetry_endpoint = control-plane..com:8006 + cluster_mtls = pki + cluster_server_name = control-plane.kong.yourcorp.tld + cluster_cert = //data-plane.crt + cluster_cert_key = //data-plane.crt + cluster_ca_cert = //ca-cert.pem + ``` + + Where: + + `cluster_control_plane` + : Sets the address and port of the control plane (port `8005` by defaut). + + `database` + : Specifies whether this node connects directly to a database. + + `` + : Specifies the location of the `cluster.key` and `cluster.crt` files. + + `cluster_server_name` + : Specifies the SNI (Server Name Indication extension) + to use for data plane connections to the control plane through TLS. When + not set, data plane will use `kong_clustering` as the SNI. + + : You can also optionally use `cluster_telemetry_server_name` + to set a custom SNI for telemetry data. If not set, it defaults to + `cluster_server_name`. + + `cluster_telemetry_endpoint` + : Optional setting, needed for telemetry gathering. Not available in open-source deployments. + + You can also choose to encrypt or disable the data plane configuration + cache with some additional settings: + +3. Restart Kong for the settings to take effect: + ```bash + kong restart + ``` +{% endnavtab %} +{% endnavtabs %} + +## Verify that nodes are connected + +Use the control plane’s Cluster Status API to monitor your data planes. It +provides: +* The name of the node +* The last time the node synced with the control plane +* The version of the config currently running on each data plane + +To check whether the CP and DP nodes you just brought up are connected, run the +following on a control plane: +{% navtabs %} +{% navtab Using cURL %} +```bash +curl -i -X GET http://:8001/clustering/data-planes +``` +{% endnavtab %} +{% navtab Using HTTPie %} +```bash +http :8001/clustering/data-planes +``` +{% endnavtab %} +{% endnavtabs %} +The output shows all of the connected data plane instances in the cluster: + +```json +{ + "data": [ + { + "config_hash": "a9a166c59873245db8f1a747ba9a80a7", + "hostname": "data-plane-2", + "id": "ed58ac85-dba6-4946-999d-e8b5071607d4", + "ip": "192.168.10.3", + "last_seen": 1580623199, + "status": "connected" + }, + { + "config_hash": "a9a166c59873245db8f1a747ba9a80a7", + "hostname": "data-plane-1", + "id": "ed58ac85-dba6-4946-999d-e8b5071607d4", + "ip": "192.168.10.4", + "last_seen": 1580623200, + "status": "connected" + } + ], + "next": null +} +``` + +## References + +### DP node start sequence + +When set as a DP node, {{site.base_gateway}} processes configuration in the +following order: + +1. **Config cache**: If the file `config.json.gz` exists in the `kong_prefix` +path (`/usr/local/kong` by default), the DP node loads it as configuration. +2. **`declarative_config` exists**: If there is no config cache and the +`declarative_config` parameter is set, the DP node loads the specified file. +3. **Empty config**: If there is no config cache or declarative +configuration file available, the node starts with empty configuration. In this +state, it returns 404 to all requests. +4. **Contact CP Node**: In all cases, the DP node contacts the CP node to retrieve +the latest configuration. If successful, it gets stored in the local config +cache (`config.json.gz`). + +### Configuration reference + +Use the following configuration properties to configure {{site.base_gateway}} +in hybrid mode. + +Parameter | Description | CP or DP {:width=10%:} +--------- | ----------- | ---------------------- +[`role`](/gateway/{{page.kong_version}}/reference/configuration/#role)
      *Required* | Determines whether the {{site.base_gateway}} instance is a control plane or a data plane. Valid values are `control_plane` or `data_plane`. | Both +[`cluster_listen`](/gateway/{{page.kong_version}}/reference/configuration/#cluster_listen)
      *Optional*

      **Default:** `0.0.0.0:8005`| List of addresses and ports on which the control plane will listen for incoming data plane connections. This port is always protected with Mutual TLS (mTLS) encryption. Ignored on data plane nodes. | CP +[`proxy_listen`](/gateway/{{page.kong_version}}/reference/configuration/#proxy_listen)
      *Required* | Comma-separated list of addresses and ports on which the proxy server should listen for HTTP/HTTPS traffic. Ignored on control plane nodes. | DP +[`cluster_telemetry_listen`](/gateway/{{page.kong_version}}/reference/configuration/#cluster_telemetry_listen)
      *Optional*

      **Default:** `0.0.0.0:8006`| List of addresses and ports on which the control plane will listen for data plane telemetry data. This port is always protected with Mutual TLS (mTLS) encryption. Ignored on data plane nodes. | CP +[`cluster_telemetry_endpoint`](/gateway/{{page.kong_version}}/reference/configuration/#cluster_telemetry_endpoint)
      *Required for Enterprise deployments* | The port that the data plane uses to send telemetry data to the control plane. Ignored on control plane nodes. | DP +[`cluster_control_plane`](/gateway/{{page.kong_version}}/reference/configuration/#cluster_control_plane)
      *Required* | Address and port that the data plane nodes use to connect to the control plane. Must point to the port configured using the [`cluster_listen`](/gateway/{{page.kong_version}}/reference/configuration/#cluster_listen) property on the control plane node. Ignored on control plane nodes. | DP +[`cluster_mtls`](/gateway/{{page.kong_version}}/reference/configuration/#cluster_mtls)
      *Optional*

      **Default:** `shared` | One of `shared` or `pki`. Indicates whether hybrid mode will use a shared certificate/key pair for CP/DP mTLS or if PKI mode will be used. See below sections for differences in mTLS modes. | Both + +The following properties are used differently between `shared` and `pki` modes: + +Parameter | Description | Shared Mode {:width=12%:} | PKI Mode {:width=30%:} +--------- | ----------- | ------------------------- | ---------------------- +[`cluster_cert`](/gateway/{{page.kong_version}}/reference/configuration/#cluster_cert) and [`cluster_cert_key`](/gateway/{{page.kong_version}}/reference/configuration/#cluster_cert_key)
      *Required* | Certificate/key pair used for mTLS between CP/DP nodes. | Same between CP/DP nodes. | Unique certificate for each node, generated from the CA specified by `cluster_ca_cert`. +[`cluster_ca_cert`](/gateway/{{page.kong_version}}/reference/configuration/#cluster_ca_cert)
      *Required in PKI mode* | The trusted CA certificate file in PEM format used to verify the `cluster_cert`. | *Ignored* | CA certificate used to verify `cluster_cert`, same between CP/DP nodes. *Required* +[`cluster_server_name`](/gateway/{{page.kong_version}}/reference/configuration/#cluster_server_name)
      *Required in PKI mode* | The SNI presented by the DP node mTLS handshake. | *Ignored* | In PKI mode, the DP nodes will also verify that the Common Name (CN) or Subject Alternative Name (SAN) inside the certificate presented by CP matches the `cluster_server_name` value. +[`cluster_telemetry_server_name`](/gateway/{{page.kong_version}}/reference/configuration/#cluster_telemetry_server_name) | The telemetry SNI presented by the DP node mTLS handshake. If not specified, falls back on SNI set in `cluster_server_name`. | *Ignored* | In PKI mode, the DP nodes will also verify that the Common Name (CN) or Subject Alternative Name (SAN) inside the certificate presented by CP matches the `cluster_telemetry_server_name` value. + +## Next steps + +Now, you can start managing the cluster using the control plane. Once +all instances are set up, use the Admin API on the control plane as usual, and +these changes will be synced and updated on the data plane nodes automatically +within seconds. diff --git a/src/gateway/production/deployment-topologies/index.md b/src/gateway/production/deployment-topologies/index.md new file mode 100644 index 000000000000..c278550e33df --- /dev/null +++ b/src/gateway/production/deployment-topologies/index.md @@ -0,0 +1,83 @@ +--- +title: Overview +content_type: explanation +--- + +{{site.base_gateway}} can be deployed in four different modes: + +* {{site.konnect_short_name}} (hosted control plane) +* Hybrid +* Traditional (database) +* DB-less and declarative + +Each mode has benefits and limitations, so it is important to consider them carefully when deciding which mode to use to install {{site.base_gateway}} in production. + +The following sections briefly describe each mode. + +## {{ site.konnect_short_name }} + +{{ site.konnect_short_name }} is the fastest way to get started when using {{site.base_gateway}}. It allows you to deploy your own data planes (DP) to handle customer traffic without needing to deploy your own control plane (CP) or database. + +{{ site.konnect_short_name }} is a hybrid mode deployment, where Kong host the control plane for you. This means that you get all of the benefits of a hybrid mode deployment without needing to run multiple nodes yourself. + +Configuration changes can be made using the {{ site.konnect_short_name }} UI and configuration wizards, or applied in an automated way using [decK](/deck/latest/). + +As with hybrid mode, your data planes will continue to process traffic even if the control plane is offline. In addition, you no longer need to worry about securing the control plane because {{site.base_gateway}} does it for you. + +Finally, {{ site.konnect_short_name }} supports runtime groups, which allows you to segment your configuration in any way that you need. It could be by business unit, or environment. Achieving this using hybrid mode requires you to deploy one control plane per segment, while {{ site.konnect_short_name }} allows you to manage multiple configuration sets through the same UI and API. + +[Get started](https://cloud.konghq.com/register) with {{ site.konnect_short_name }} for free today. + +## Hybrid mode + +Starting with {{site.base_gateway}} 2.1, {{site.base_gateway}} can be deployed in +[hybrid mode](/gateway/{{page.kong_version}}/production/deployment-topologies/hybrid-mode/), which separates the control plane from the data plane. + +In this mode, {{site.base_gateway}} nodes in a cluster are split into two roles: control plane +(CP), where configuration is managed and the Admin API is served from, and data +plane (DP), which serves traffic for the proxy. Many DP nodes are connected to a single CP node. Instead of accessing the database contents directly like in the +traditional deployment method, the DP nodes maintain connection with CP nodes, +and receive the latest configuration in real-time. + +Hybrid mode deployments have the following benefits: + +* Users can deploy groups of data planes in different data centers, geographies, or zones without needing a local clustered database for each DP group. +* The availability of the database does not affect the availability of the data planes. If a control plane is offline, data planes will run using their last known configuration. +* Drastically reduces the amount of traffic to and from the database, since only CP nodes need a direct connection to the database. +* If one of the DP nodes is compromised, an attacker won’t be able to affect other nodes in the {{site.base_gateway}} cluster. + +## Traditional (database) mode + +In [traditional mode](/gateway/{{page.kong_version}}/production/deployment-topologies/traditional/), {{site.base_gateway}} requires a database to store configured entities such as routes, services, and plugins. {{site.base_gateway}} supports both PostgreSQL 10+ and Cassandra 3.11.x as its data store. + +Running {{ site.base_gateway }} in traditional mode is the simplest way to get started with Kong, and it is the only deployment topology that supports plugins that require a database, like rate-limiting with the cluster strategy, or OAuth2. However, there are some downsides too. + +When running in traditional mode, every {{ site.base_gateway }} node runs as both a Control Plane (CP) and Data Plane (DP). This means that if **any** of your nodes are compromised, the entire running gateway configuration is compromised. In contrast, hybrid mode (shown below) has distinct CP and DP nodes reducing the attack surface. + +In addition, if you're running Kong Enterprise with Kong Manager, request throughput may be reduced on nodes running Kong Manager due to expensive calculations being run to render analytics data and graphs. + +You can use the [Admin API](/gateway/{{page.kong_version}}/admin-api/) or declarative configuration files [(decK)](/deck/latest/) to configure the {{site.base_gateway}} in traditional mode. + +## DB-less and declarative mode + +Starting with {{site.base_gateway}} 1.1, you can enable [DB-less mode](/gateway/{{page.kong_version}}/production/deployment-topologies/db-less-and-declarative-config/) to reduce complexity of and create more flexible deployment patterns. In this mode, configured entities such as routes, services and plugins are stored in-memory on the node. + +When running in DB-less mode, configuration is provided to {{ site.base_gateway }} using a second file. This file contains your configuration in YAML or JSON format using Kong's declarative configuration syntax. + +DB-less mode is also used by the Kong Ingress Controller, where the Kubernetes API server uses Kong's `/config` endpoint to update the running configuration in memory any time a change is made. + +The combination of DB-less mode and declarative configuration has a number +of benefits: + +* Reduced number of dependencies: no need to manage a database installation + if the entire setup for your use-case fits in memory. +* Your configuration is always in a known state. There is no intermediate + state between creating a service and a route using the Admin API. +* It is a good fit for automation in CI/CD scenarios. Configuration for + entities can be kept in a single source of truth managed via a Git + repository. + +Here are a few limitations of this mode: + +* The [Admin API](/gateway/{{page.kong_version}}/admin-api/) is read only. +* Any plugin that stores information in the database, like rate limiting (cluster mode), do not fully function. \ No newline at end of file diff --git a/src/gateway/production/deployment-topologies/traditional/index.md b/src/gateway/production/deployment-topologies/traditional/index.md new file mode 100644 index 000000000000..d04941fb07a7 --- /dev/null +++ b/src/gateway/production/deployment-topologies/traditional/index.md @@ -0,0 +1,301 @@ +--- +title: Traditional Deployment +--- + +A Kong cluster allows you to scale the system horizontally by adding more +machines to handle more incoming requests. They will all share the same +configuration since they point to the same database. Kong nodes pointing to the +**same datastore** will be part of the same Kong cluster. + +You need a load balancer in front of your Kong cluster to distribute traffic +across your available nodes. + +## What a Kong cluster does and doesn't do + +**Having a Kong cluster does not mean that your clients traffic will be +load-balanced across your Kong nodes out of the box.** You still need a +load-balancer in front of your Kong nodes to distribute your traffic. Instead, +a Kong cluster means that those nodes will share the same configuration. + +For performance reasons, Kong avoids database connections when proxying +requests, and caches the contents of your database in memory. The cached +entities include Services, Routes, Consumers, Plugins, Credentials, and so on. Since those +values are in memory, any change made via the Admin API of one of the nodes +needs to be propagated to the other nodes. + +This document describes how those cached entities are being invalidated and how +to configure your Kong nodes for your use case, which lies somewhere between +performance and consistency. + +## Single node Kong clusters + + +{% include_cached /md/enterprise/cassandra-deprecation.md %} + + +A single Kong node connected to a database (Cassandra or PostgreSQL) creates a +Kong cluster of one node. Any changes applied via the Admin API of this node +will instantly take effect. Example: + +Consider a single Kong node `A`. If we delete a previously registered Service: + +```bash +curl -X DELETE http://127.0.0.1:8001/services/test-service +``` + +Then any subsequent request to `A` would instantly return `404 Not Found`, as +the node purged it from its local cache: + +```bash +curl -i http://127.0.0.1:8000/test-service +``` + +## Multiple nodes Kong clusters + +In a cluster of multiple Kong nodes, other nodes connected to the same database +would not instantly be notified that the Service was deleted by node `A`. While +the Service is **not** in the database anymore (it was deleted by node `A`), it is +**still** in node `B`'s memory. + +All nodes perform a periodic background job to synchronize with changes that +may have been triggered by other nodes. The frequency of this job can be +configured via: + +* [db_update_frequency][db_update_frequency] (default: 5 seconds) + +Every `db_update_frequency` seconds, all running Kong nodes will poll the +database for any update, and will purge the relevant entities from their cache +if necessary. + +If we delete a Service from node `A`, this change will not be effective in node +`B` until node `B`s next database poll, which will occur up to +`db_update_frequency` seconds later (though it could happen sooner). + +This makes Kong clusters **eventually consistent**. + +### Use read-only replicas when deploying Kong clusters with Postgres + +When using Postgres as the backend storage, you can optionally enable +Kong to serve read queries from a separate database instance. + +Enabling the read-only connection support in Kong +greatly reduces the load on the main database instance since read-only +queries are no longer sent to it. + +To learn more about how to configure this feature, refer to the +[Datastore section](/gateway/{{page.kong_version}}/reference/configuration/#datastore-section) +of the Configuration reference. + +## What is being cached? + +All of the core entities such as Services, Routes, Plugins, Consumers, Credentials are +cached in memory by Kong and depend on their invalidation via the polling +mechanism to be updated. + +Additionally, Kong also caches **database misses**. This means that if you +configure a Service with no plugin, Kong will cache this information. Example: + +On node `A`, we add a Service and a Route: + +```bash +# node A +curl -X POST http://127.0.0.1:8001/services \ + --data "name=example-service" \ + --data "url=http://example.com" + +curl -X POST http://127.0.0.1:8001/services/example-service/routes \ + --data "paths[]=/example" +``` + +(Note that we used `/services/example-service/routes` as a shortcut: we +could have used the `/routes` endpoint instead, but then we would need to +pass `service_id` as an argument, with the UUID of the new Service.) + +A request to the Proxy port of both node `A` and `B` will cache this Service, and +the fact that no plugin is configured on it: + +```bash +# node A +curl http://127.0.0.1:8000/example +``` + +Response: +``` +HTTP 200 OK +... +``` + +```bash +# node B +curl http://127.0.0.2:8000/example +``` + +Response: +``` +HTTP 200 OK +... +``` + +Now, say we add a plugin to this Service via node `A`'s Admin API: + +```bash +# node A +curl -X POST http://127.0.0.1:8001/services/example-service/plugins \ + --data "name=example-plugin" +``` + +Because this request was issued via node `A`'s Admin API, node `A` will locally +invalidate its cache and on subsequent requests, it will detect that this API +has a plugin configured. + +However, node `B` hasn't run a database poll yet, and still caches that this +API has no plugin to run. It will be so until node `B` runs its database +polling job. + +**Conclusion**: All CRUD operations trigger cache invalidations. Creation +(`POST`, `PUT`) will invalidate cached database misses, and update/deletion +(`PATCH`, `DELETE`) will invalidate cached database hits. + +## How to configure database caching? + +You can configure three properties in the Kong configuration file, the most +important one being `db_update_frequency`, which determine where your Kong +nodes stand on the performance versus consistency trade-off. + +Kong comes with default values tuned for consistency so that you can +experiment with its clustering capabilities while avoiding surprises. As you +prepare a production setup, you should consider tuning those values to ensure +that your performance constraints are respected. + +### 1. [db_update_frequency][db_update_frequency] (default: 5s) + +This value determines the frequency at which your Kong nodes will be polling +the database for invalidation events. A lower value means that the polling +job will execute more frequently, but that your Kong nodes will keep up +with changes you apply. A higher value means that your Kong nodes will +spend less time running the polling jobs, and will focus on proxying your +traffic. + +**Note**: Changes propagate through the cluster in up to `db_update_frequency` +seconds. + +### 2. [db_update_propagation][db_update_propagation] (default: 0s) + +If your database itself is eventually consistent (that is, Cassandra), you **must** +configure this value. It is to ensure that the change has time to propagate +across your database nodes. When set, Kong nodes receiving invalidation events +from their polling jobs will delay the purging of their cache for +`db_update_propagation` seconds. + +If a Kong node connected to an eventually consistent database was not delaying +the event handling, it could purge its cache, only to cache the non-updated +value again (because the change hasn't propagated through the database yet)! + +You should set this value to an estimate of the amount of time your database +cluster takes to propagate changes. + +**Note**: When this value is set, changes propagate through the cluster in +up to `db_update_frequency + db_update_propagation` seconds. + +### 3. [db_cache_ttl][db_cache_ttl] (default: 0s) + +The time (in seconds) for which Kong will cache database entities (both hits +and misses). This Time-To-Live value acts as a safeguard in case a Kong node +misses an invalidation event, to avoid it from running on stale data for too +long. When the TTL is reached, the value will be purged from its cache, and the +next database result will be cached again. + +By default, no data is invalidated based on this TTL (the default value is `0`). +This is usually fine: Kong nodes rely on invalidation events, which are handled +at the db store level (Cassandra/PostgreSQL). If you are concerned that a Kong +node might miss invalidation event for any reason, you should set a TTL. Otherwise +the node might run with a stale value in its cache for an undefined amount of time +until the cache is manually purged, or the node is restarted. + +### 4. When using Cassandra + +If you use Cassandra as your Kong database, you **must** set +[db_update_propagation][db_update_propagation] to a non-zero value. Since +Cassandra is eventually consistent by nature, this will ensure that Kong nodes +do not prematurely invalidate their cache, only to fetch and catch a +not up-to-date entity again. Kong will present you a warning in logs if you did +not configure this value when using Cassandra. + +Additionally, you might want to configure `cassandra_consistency` to a value +like `QUORUM` or `LOCAL_QUORUM`, to ensure that values being cached by your +Kong nodes are up-to-date values from your database. + +Setting the `cassandra_refresh_frequency` option to `0` is not advised, as a Kong +restart will be required to discover any changes to the Cassandra cluster topology. + +## Interacting with the cache via the Admin API + +If for some reason, you want to investigate the cached values, or manually +invalidate a value cached by Kong (a cached hit or miss), you can do so via the +Admin API `/cache` endpoint. + +### Inspect a cached value + +**Endpoint** + +
      /cache/{cache_key}
      + +**Response** + +If a value with that key is cached: + +``` +HTTP 200 OK +... +{ + ... +} +``` + +Else: + +``` +HTTP 404 Not Found +``` + +**Note**: Retrieving the `cache_key` for each entity being cached by Kong is +currently an undocumented process. Future versions of the Admin API will make +this process easier. + +### Purge a cached value + +**Endpoint** + +
      /cache/{cache_key}
      + +**Response** + +``` +HTTP 204 No Content +... +``` + +**Note**: Retrieving the `cache_key` for each entity being cached by Kong is +currently an undocumented process. Future versions of the Admin API will make +this process easier. + +### Purge a node's cache + +**Endpoint** + +
      /cache
      + +**Response** + +``` +HTTP 204 No Content +``` + +**Note**: Be wary of using this endpoint on a node running in production with warm cache. +If the node is receiving a lot of traffic, purging its cache at the same time +will trigger many requests to your database, and could cause a +[dog-pile effect](https://en.wikipedia.org/wiki/Cache_stampede). + +[db_update_frequency]: /gateway/{{page.kong_version}}/reference/configuration/#db_update_frequency +[db_update_propagation]: /gateway/{{page.kong_version}}/reference/configuration/#db_update_propagation +[db_cache_ttl]: /gateway/{{page.kong_version}}/reference/configuration/#db_cache_ttl diff --git a/src/gateway/production/environment-variables.md b/src/gateway/production/environment-variables.md new file mode 100644 index 000000000000..9e5586a46edf --- /dev/null +++ b/src/gateway/production/environment-variables.md @@ -0,0 +1,31 @@ +--- +title: Kong Gateway Environment Variables +content-type: how-to +--- + +## Environment variables + +{{site.base_gateway}} can be fully configured with environment variables. When loading properties from `kong.conf`, {{site.base_gateway}} will check existing +environment variables. + +To override a setting using an environment variable, declare an environment +variable with the name of the setting, prefixed with `KONG_`. + +To override the `log_level` parameter: + +``` +log_level = debug # in kong.conf +``` + +set `KONG_LOG_LEVEL` as an environment variable: + +```bash +export KONG_LOG_LEVEL=error +``` + + +## More Information + +* [Embedding Kong in OpenResty](/gateway/latest/production/kong-openresty) +* [How to use `kong.conf`](/gateway/latest/production/kong-conf) +* [How to serve an API and a website with Kong](/gateway/latest/production/website-api-serving) \ No newline at end of file diff --git a/src/gateway/production/kong-conf.md b/src/gateway/production/kong-conf.md new file mode 100644 index 000000000000..fb053509d045 --- /dev/null +++ b/src/gateway/production/kong-conf.md @@ -0,0 +1,102 @@ +--- +title: Kong Configuration File +content-type: how-to +--- + + +{{site.base_gateway}} comes with a default configuration file `kong.conf`. If you installed {{site.base_gateway}} using an official package, this file can be found at: +`/etc/kong/kong.conf.default`. The {{site.base_gateway}} configuration file is a YAML file that can be used to configure individual properties of your Kong instance. This guide will explain how to configure {{site.base_gateway}} using the `kong.conf` file. + + +## Configure {{site.base_gateway}} + +To configure {{site.base_gateway}}, make a copy of the default configuration file: + +```bash +cp /etc/kong/kong.conf.default /etc/kong/kong.conf +``` + +The file contains configuration properties and documentation: + +```bash +#upstream_keepalive_pool_size = 60 # Sets the default size of the upstream + # keepalive connection pools. + # Upstream keepalive connection pools + # are segmented by the `dst ip/dst + # port/SNI` attributes of a connection. + # A value of `0` will disable upstream + # keepalive connections by default, forcing + # each upstream request to open a new + # connection. +``` + +To configure a property, uncomment it and modify the value: + +```bash +upstream_keepalive_pool_size = 40 +``` + +Boolean values can be specified as `on`/`off` or `true`/`false`: + +```bash +#dns_no_sync = off # If enabled, then upon a cache-miss every + # request will trigger its own dns query. + # When disabled multiple requests for the + # same name/type will be synchronised to a + # single query. +``` + +{:.note} +> {{site.base_gateway}} will use the default settings for any value in `kong.conf` that is commented out. + +## Verify configuration +To verify that your configuration is usable, use the `check` command. The `check` command will evaluate the [environment variables](/gateway/latest/production/environment-variables) you have +currently set, and will output an error if your settings are invalid. + +```bash +kong check /etc/kong/kong.conf +``` +If your configuration is valid the shell will output: + +```bash +configuration at /etc/kong/kong.conf is valid +``` + +## Set custom path + +By default, {{site.base_gateway}} looks for `kong.conf` in two +default locations: + +``` +/etc/kong/kong.conf +/etc/kong.conf +``` + +You can override this behavior by specifying a custom path for your +configuration file using the `-c / --conf` argument in the CLI: + +```bash +kong start --conf /path/to/kong.conf +``` + +### Debug mode + +You can use the [{{site.base_gateway}} CLI](/gateway/latest/reference/cli/) in debug-mode to output configuration properties in the shell: + +```bash +kong start -c /etc/kong.conf --vv + +2016/08/11 14:53:36 [verbose] no config file found at /etc/kong.conf +2016/08/11 14:53:36 [verbose] no config file found at /etc/kong/kong.conf +2016/08/11 14:53:36 [debug] admin_listen = "0.0.0.0:8001" +2016/08/11 14:53:36 [debug] database = "postgres" +2016/08/11 14:53:36 [debug] log_level = "notice" +[...] +``` + + +## More Information + +* [Embedding Kong in OpenResty](/gateway/latest/production/kong-openresty) +* [Setting environment variables](/gateway/latest/production/environment-variables) +* [How to serve an API and a website with Kong](/gateway/latest/production/website-api-serving) \ No newline at end of file diff --git a/src/gateway/production/kong-openresty.md b/src/gateway/production/kong-openresty.md new file mode 100644 index 000000000000..b8811aab46f8 --- /dev/null +++ b/src/gateway/production/kong-openresty.md @@ -0,0 +1,37 @@ +--- +title: Embed Kong in OpenResty +content-type: how-to +--- + +If you are running your own OpenResty servers, you can embed {{site.base_gateway}} +by including the {{site.base_gateway}} Nginx sub-configuration using the `include` directive. +If you have an existing Nginx configuration, you can include the +{{site.base_gateway}}-specific portion of the configuration which is output by {{site.base_gateway}} in a separate +`nginx-kong.conf` file: + +``` +# my_nginx.conf + +# ...your nginx settings... + +http { + include 'nginx-kong.conf'; + + # ...your nginx settings... +} +``` + +Then start your Nginx instance: + +```bash +nginx -p /usr/local/openresty -c my_nginx.conf +``` + +Kong will be running in that instance as configured in `nginx-kong.conf`. + + +## More Information + +* [Setting environment variables](/gateway/latest/production/environment-variables) +* [How to use `kong.conf`](/gateway/latest/production/kong-conf) +* [How to serve an API and a website with Kong](/gateway/latest/production/website-api-serving) \ No newline at end of file diff --git a/src/gateway/production/logging.md b/src/gateway/production/logging.md new file mode 100644 index 000000000000..bc5931f4f544 --- /dev/null +++ b/src/gateway/production/logging.md @@ -0,0 +1,144 @@ +--- +title: Logging Reference +--- + +## Log Levels + +Log levels are set in [Kong's configuration](/gateway/{{page.kong_version}}/reference/configuration/#log_level). Following are the log levels in increasing order of their severity: `debug`, `info`, +`notice`, `warn`, `error` and `crit`. + +- *`debug`:* It provides debug information about the plugin's runloop and each individual plugin or other components. Only to be used during debugging since it is too chatty. +- *`info`/`notice`:* Kong does not make a big difference between both these levels. Provides information about normal behavior most of which can be ignored. +- *`warn`:* To log any abnormal behavior that doesn't result in dropped transactions but requires further investigation, `warn` level should be used. +- *`error`:* Used for logging errors that result in a request being dropped (for example getting an HTTP 500 error). The rate of such logs need to be monitored. +- *`crit`:* This level is used when Kong is working under critical conditions and not working properly thereby affecting several clients. Nginx also provides `alert` and `emerg` levels but currently Kong doesn't make use of these levels making `crit` the highest severity log level. + +`notice` is the default and recommended log level. However if the logs turn out to be too chatty, they can be bumped up to a higher level like `warn`. + +## Removing Certain Elements From Your Kong Logs + +With new regulations surrounding protecting private data like GDPR, there is a chance you may need to change your logging habits. If you use Kong as your API Gateway, this can be done in a single location to take effect on all of your Services. This guide will walk you through one approach to accomplishing this, but there are always different approaches for different needs. Please note, these changes will effect the output of the NGINX access logs. This will not have any effect on Kong's logging plugins. + +For this example, let’s say you want to remove any instances of an email address from your Kong logs. The emails addresses may come through in different ways, for example something like `/servicename/v2/verify/alice@example.com` or `/v3/verify?alice@example.com`. In order to keep these from being added to the logs, we will need to use a custom NGINX template. + +To start using a custom NGINX template, first get a copy of our template. This can be found in the [Configuration Property reference](/gateway/{{page.kong_version}}/reference/configuration/#custom-nginx-templates-embedding-kong) or copied from below + +``` +# --------------------- +# custom_nginx.template +# --------------------- + +worker_processes ${{NGINX_WORKER_PROCESSES}}; # can be set by kong.conf +daemon ${{NGINX_DAEMON}}; # can be set by kong.conf + +pid pids/nginx.pid; # this setting is mandatory +error_log logs/error.log ${{LOG_LEVEL}}; # can be set by kong.conf + +events { + use epoll; # custom setting + multi_accept on; +} + +http { + # include default Kong Nginx config + include 'nginx-kong.conf'; + + # custom server + server { + listen 8888; + server_name custom_server; + + location / { + ... # etc + } + } +} +``` + +In order to control what is placed in the logs, we will be using the NGINX map module in our template. For more detailed information abut the map directive, please see [this guide](http://nginx.org/en/docs/http/ngx_http_map_module.html). This will create a new variable whose value depends on values of one or more of the source variables specified in the first parameter. The format is: + +``` + +map $paramater_to_look_at $variable_name { + pattern_to_look_for 0; + second_pattern_to_look_for 0; + + default 1; +} +``` + +For this example, we will be mapping a new variable called `keeplog` which is dependent on certain values appearing in the `$request_uri`. We will be placing our map directive right at the start of the http block; this must be before `include 'nginx-kong.conf';`. For our example, we will add something along the lines of: + +``` +map $request_uri $keeplog { + ~.+\@.+\..+ 0; + ~/servicename/v2/verify 0; + ~/v3/verify 0; + + default 1; +} +``` + +You’ll probably notice that each of those lines start with a tilde. This is what tells NGINX to use RegEx when evaluating the line. We have three things to look for in this example: +- The first line uses regex to look for any email address in the `x@y.z` format +- The second line looks for any part of the URI which is `/servicename/v2/verify` +- The third line looks at any part of the URI which contains `/v3/verify` + +Because all of those have a value of something other than `0`, if a request has one of those elements, it will not be added to the log. + +Now, we need to set the log format for what we will keep in the logs. We will use the `log_format` module and assign our new logs a name of `show_everything`. The contents of the log can be customized for you needs, but for this example, I will simply change everything back to the Kong standards. To see the full list of options you can use, please refer to [this guide](https://nginx.org/en/docs/http/ngx_http_core_module.html#variables). + +``` +log_format show_everything '$remote_addr - $remote_user [$time_local] ' + '$request_uri $status $body_bytes_sent ' + '"$http_referer" "$http_user_agent"'; +``` + +Now, our custom NGINX template is all ready to be used. If you have been following along, your file should now be look like this: + +``` +# --------------------- +# custom_nginx.template +# --------------------- + +worker_processes ${{NGINX_WORKER_PROCESSES}}; # can be set by kong.conf +daemon ${{NGINX_DAEMON}}; # can be set by kong.conf + +pid pids/nginx.pid; # this setting is mandatory +error_log stderr ${{LOG_LEVEL}}; # can be set by kong.conf + + + +events { + use epoll; # custom setting + multi_accept on; +} + +http { + + + map $request_uri $keeplog { + ~.+\@.+\..+ 0; + ~/v1/invitation/ 0; + ~/reset/v1/customer/password/token 0; + ~/v2/verify 0; + + default 1; + } + log_format show_everything '$remote_addr - $remote_user [$time_local] ' + '$request_uri $status $body_bytes_sent ' + '"$http_referer" "$http_user_agent"'; + + include 'nginx-kong.conf'; +} +``` + +The last thing we need to do is tell Kong to use the newly created log, `show_everything`. To do this, we will be altering the Kong variable `proxy_access_log` by either editing `etc/kong/kong.conf` or using an environmental variable `KONG_PROXY_ACCESS_LOG`. You will want to mend the default location to show: + +``` +proxy_access_log=logs/access.log show_everything if=$keeplog +``` + +The final step in the process to make all the changes take effect is to restart Kong. You can use the `kong restart` command to do so. + +Now, any requests made with an email address in it will no longer be logged. Of course, we can use this logic to remove anything we want from the logs on a conditional manner. diff --git a/src/gateway/production/monitoring/datadog.md b/src/gateway/production/monitoring/datadog.md new file mode 100644 index 000000000000..f5e2e341b614 --- /dev/null +++ b/src/gateway/production/monitoring/datadog.md @@ -0,0 +1,29 @@ +--- +title: Collect Metrics with Datadog +content_type: how-to +--- + +You can use {{site.base_gateway}} and [the Prometheus plugin](/hub/kong-inc/prometheus/) to collect metrics in Datadog. + +## Prerequisites + +* [Datadog Agent v6 or later](https://docs.datadoghq.com/agent/) +* [Enable the Prometheus plugin in {{site.base_gateway}}](/hub/kong-inc/prometheus/#example-config) + +## Connect the Prometheus plugin to Datadog + +Using Datadog Agent 6, you can connect Datadog to the Prometheus endpoint to start collecting metrics. + +After enabling the Prometheus plugin for {{site.base_gateway}}, create a [Datadog Agent openmetrics.d](https://docs.datadoghq.com/integrations/openmetrics/) configuration at `/etc/datadog-agent/conf.d/openmetrics.d/conf.yaml`. This tells the agent to begin scraping metrics from {{site.base_gateway}}. + +The following is an example configuration for pulling all the `kong_` prefixed metrics: + +``` +instances: + - prometheus_url: http://localhost:8001/metrics + namespace: "kong" + metrics: + - kong_* +``` + +For more information about collecting metrics using Prometheus and the Datadog Agent, see [Prometheus and OpenMetrics metrics collection from a host](https://docs.datadoghq.com/integrations/guide/prometheus-host-collection/#pagetitle). diff --git a/src/gateway/production/monitoring/index.md b/src/gateway/production/monitoring/index.md new file mode 100644 index 000000000000..ec764b7d14a7 --- /dev/null +++ b/src/gateway/production/monitoring/index.md @@ -0,0 +1,26 @@ +--- +title: Monitoring Overview +content-type: reference +--- + +API gateways isolate your applications from the outside world and provide critical path +protection for your upstream services. Understanding the state of your API gateway +system is critical to providing reliable API-based systems. + +There are many monitoring and alerting systems available, and {{site.base_gateway}} integrates with +multiple solutions: + +* [Prometheus](https://prometheus.io/) is an open-source systems monitoring and alerting toolkit. + Prometheus provides a multi-demensional time series data model and query language. + The [Monitoring with Prometheus](/gateway/latest/production/monitoring/prometheus/) guide + shows how to install and configure the {{site.base_gateway}} [Prometheus plugin](/hub/kong-inc/prometheus/). +* [Datadog](https://www.datadoghq.com/) is a popular cloud based infrastructure and application monitoring service. + See the [Collect Metrics with Datadog guide](/gateway/latest/production/monitoring/datadog/) for information on + integrating {{site.base_gateway}} with Datadog. You can also integrate the [Datadog plugin](/hub/kong-inc/datadog/) with {{site.base_gateway}} for additional insights. +* [StatsD](https://github.com/statsd/statsd) is a lightweight network daemon that listens for application metrics on + UDP or TCP and sends aggregated values to one or more backend services. {{site.base_gateway}} directly supports StatsD + with the [StatsD plugin](/hub/kong-inc/statsd/). [Monitoring with StatsD](/gateway/latest/production/monitoring/statsd/) provides a + step-by-step guide to enabling StatsD. + +Closely related to monitoring is tracing. See the {{site.base_gateway}} [Tracing Reference](/gateway/latest/production/tracing/) +for details about instrumenting your API gateway. diff --git a/src/gateway/production/monitoring/prometheus.md b/src/gateway/production/monitoring/prometheus.md new file mode 100644 index 000000000000..d530ba24a600 --- /dev/null +++ b/src/gateway/production/monitoring/prometheus.md @@ -0,0 +1,149 @@ +--- +title: Monitoring with Prometheus +content_type: how-to +--- + +[Prometheus](https://prometheus.io/) is a popular systems monitoring and alerting toolkit. Prometheus +implements a multi-dimensional time series data model and distributed storage +system where metrics data is collected via a pull model over HTTP. + +{{site.base_gateway}} supports Prometheus with the [Prometheus Plugin](/hub/kong-inc/prometheus/) that exposes +{{site.base_gateway}} performance and proxied upstream service metrics on the `/metrics` endpoint. + +This guide will help you setup a test {{site.base_gateway}} and +Prometheus service. Then you will generate sample requests to {{site.base_gateway}} and +observe the collected monitoring data. + +### Prerequisites +This guide assumes the following tools are installed locally: +* [Docker](https://docs.docker.com/get-docker/) is used to run {{site.base_gateway}}, the supporting database, +and Prometheus locally. +* [curl](https://curl.se/) is used to send requests to {{site.base_gateway}}. `curl` is pre-installed on most systems. + +### Configure Prometheus monitoring + +1. Install {{site.base_gateway}}: + + {:.note} + > This step is optional if you wish to use an existing {{site.base_gateway}} installation. When using an existing + {{site.base_gateway}}, you will need to modify the commands to account for network + connectivity and installed {{site.base_gateway}} services and routes. + + ```sh + curl -Ls get.konghq.com/quickstart | sh -s -- -m + ``` + The `-m` flag instructs the script to install a mock service that is used in this guide to generate sample metrics. + + Once the {{site.base_gateway}} is ready, you will see the following message: + + ```text + ✔ Kong is ready! + ``` + +1. Install the Prometheus {{site.base_gateway}} plugin: + + ```sh + curl -s -X POST http://localhost:8001/plugins/ \ + --data "name=prometheus" + ``` + + You should receive a JSON response with the details of the installed plugin. + +1. Create a Prometheus configuration file named `prometheus.yml` +in the current directory, and copy the following values: + + ```text + scrape_configs: + - job_name: 'kong' + scrape_interval: 5s + static_configs: + - targets: ['kong-quickstart-gateway:8001'] + ``` + + See the Prometheus [Configuration Documentation](https://prometheus.io/docs/prometheus/latest/configuration/configuration/) + for details on these settings. + +1. Run a Prometheus server, and pass it the configuration file created in the previous step. Prometheus +will begin to scrape metrics data from {{site.base_gateway}}. + + ```sh + docker run -d --name kong-quickstart-prometheus \ + --network=kong-quickstart-net -p 9090:9090 \ + -v $(PWD)/prometheus.yml:/etc/prometheus/prometheus.yml \ + prom/prometheus:latest + ``` + +1. Generate sample traffic to the mock service. This allows you to observe + metrics generated from the StatsD plugin. The following command generates 60 + requests over one minute. Run the following in a new terminal: + + ```bash + for _ in {1..60}; do {curl -s localhost:8000/mock/request; sleep 1; } done + ``` + +1. You can view the metric data directly from {{site.base_gateway}} by querying the + `/metrics` endpoint on the [Admin API](/gateway/{{page.kong_version}}/admin-api/): + + ```sh + curl -s localhost:8001/metrics + ``` + + {{site.base_gateway}} will report system wide performance metrics by default. + When the Plugin has been installed and traffic is being proxied, it will record + additional metrics across service, route, and upstream dimensions. + + The response will look similar to the following snippet: + + ```text + # HELP kong_bandwidth Total bandwidth in bytes consumed per service/route in Kong + # TYPE kong_bandwidth counter + kong_bandwidth{service="mock",route="mock",type="egress"} 13579 + kong_bandwidth{service="mock",route="mock",type="ingress"} 540 + # HELP kong_datastore_reachable Datastore reachable from Kong, 0 is unreachable + # TYPE kong_datastore_reachable gauge + kong_datastore_reachable 1 + # HELP kong_http_status HTTP status codes per service/route in Kong + # TYPE kong_http_status counter + kong_http_status{service="mock",route="mock",code="200"} 6 + # HELP kong_latency Latency added by Kong, total request time and upstream latency for each service/route in Kong + # TYPE kong_latency histogram + kong_latency_bucket{service="mock",route="mock",type="kong",le="1"} 4 + kong_latency_bucket{service="mock",route="mock",type="kong",le="2"} 4 + ... + ``` + + See the [Kong Prometheus Plugin documentation](https://prometheus.io/docs/prometheus/latest/configuration/configuration://docs.konghq.com/hub/kong-inc/prometheus/) + for details on the available metrics and configurations. + +1. Prometheus provides multiple ways to query collected metric data. + + You can view the [Prometheus expression](https://prometheus.io/docs/prometheus/latest/querying/basics/) viewer + by opening a browser to [http://localhost:9090/graph](http://localhost:9090/graph). + + You can also query Prometheus directly using it's + [HTTP API](https://prometheus.io/docs/prometheus/latest/querying/api/): + + ```sh + curl -s 'localhost:9090/api/v1/query?query=kong_http_status' + ``` + + Prometheus also [provides documentation](https://prometheus.io/docs/visualization/grafana/) + for setting up [Grafana](https://grafana.com/) as a visualization tool for the collected time series data. + +### Cleanup + +Once you are done experimenting with Prometheus and {{site.base_gateway}}, you can use the following +commands to stop and remove the services created in this guide: + +```sh +docker stop kong-quickstart-prometheus +curl -Ls get.konghq.com/quickstart | sh -s -- -d +``` + +### More information +* [How to monitor with StatsD](/gateway/{{page.kong_version}}/production/monitoring/statsd/) +provides a guide to using [StatsD](https://github.com/statsd/statsd) for monitoring with the +[{{site.base_gateway}} Plugin](/hub/kong-inc/statsd/) +* See the [Tracing API Reference](/gateway/{{page.kong_version}}/production/tracing/api/) for information +on {{site.base_gateway}}'s tracing capabilities + diff --git a/src/gateway/production/monitoring/statsd.md b/src/gateway/production/monitoring/statsd.md new file mode 100644 index 000000000000..94e89537ab5c --- /dev/null +++ b/src/gateway/production/monitoring/statsd.md @@ -0,0 +1,106 @@ +--- +title: Monitoring with StatsD +content_type: how-to +--- + +[StatsD](https://github.com/statsd/statsd) is a network daemon that collects +and aggregates performance metrics by listening on the network for +text based statistics data, published by applications. + +This guide will help you setup a test {{site.base_gateway}} and +StatsD service. Then you will generate sample requests to {{site.base_gateway}} and +observe the collected monitoring data. + +### Prerequisites +* [Docker](https://docs.docker.com/get-docker/) is used to run StatsD and supporting services locally. +* [curl](https://curl.se/) is used to send requests to {{site.base_gateway}}. `curl` is pre-installed on most systems. +* [Netcat](http://netcat.sourceforge.net/) is installed as `nc` on the system `PATH`. `nc` is used to send requests + to the StatsD management interface. `nc` is pre-installed on many systems. + +### Configure StatsD monitoring + +1. Install {{site.base_gateway}}: + + {:.note} + > This step is optional if you wish to use an existing {{site.base_gateway}} installation. When using an existing + {{site.base_gateway}}, you will need to modify the commands to account for network + connectivity and installed {{site.base_gateway}} services and routes. + + ```sh + curl -Ls get.konghq.com/quickstart | sh -s -- -m + ``` + The `-m` flag instructs the script to install a mock service that is used in this guide to generate sample metrics. + + Once the {{site.base_gateway}} is ready, you will see the following message: + + ```text + ✔ Kong is ready! + ``` + +1. Run a StatsD container to capture monitoring data: + + ```sh + docker run -d --rm -p 8126:8126 \ + --name kong-quickstart-statsd --network=kong-quickstart-net \ + statsd/statsd:latest + ``` + +1. Install the [StatsD {{site.base_gateway}} plugin](/hub/kong-inc/statsd/), + configuring the hostname and port of the listening StatsD service: + + ```sh + curl -X POST http://localhost:8001/plugins/ \ + --data "name=statsd" \ + --data "config.host=kong-quickstart-statsd" \ + --data "config.port=8125" + ``` + + You should receive a JSON response with details about the installed plugin. + +1. Generate sample traffic to the mock service. This allows you to observe + metrics generated from the StatsD plugin. The following command generates 60 + requests over one minute. Run the following in a new terminal: + + ```sh + for _ in {1..60}; do {curl localhost:8000/mock/request; sleep 1; } done + ``` + +1. Query the StatsD management interface to see the collected metrics from {{site.base_gateway}}: + + ```sh + echo "counters" | nc localhost 8126 + ``` + + You should see a response similar to the following: + + ```text + { + 'statsd.bad_lines_seen': 0, + 'statsd.packets_received': 56, + 'statsd.metrics_received': 56, + 'kong.mock.request.count': 7, + 'kong.mock.request.status.200': 7, + 'kong.mock.request.status.total': 7 + } + END + ``` + +See the [StatsD plugin](/hub/kong-inc/statsd/) +documentation for more information about how to use and configure the plugin. + +### Clean up + +Once you are done experimenting with StatsD and {{site.base_gateway}}, you can use the following +commands to stop and remove the software ran in this guide: + +```sh +docker stop kong-quickstart-statsd +curl -Ls get.konghq.com/quickstart | sh -s -- -d +``` + +### More information +* [How to monitor with Prometheus](/gateway/{{page.kong_version}}/production/monitoring/prometheus/) +describes how to use [Prometheus](https://prometheus.io/docs/introduction/overview/) to monitor {{site.base_gateway}} using the +[Prometheus plugin](/hub/kong-inc/prometheus/). +* See the [Tracing API Reference](/gateway/{{page.kong_version}}/production/tracing/api/) for information +about {{site.base_gateway}}'s tracing capabilities. diff --git a/src/gateway/production/networking/default-ports.md b/src/gateway/production/networking/default-ports.md new file mode 100644 index 000000000000..8525dc488508 --- /dev/null +++ b/src/gateway/production/networking/default-ports.md @@ -0,0 +1,23 @@ +--- +title: Default Ports +--- +By default, {{site.base_gateway}} listens on the following ports: + +| Port | Protocol | Description | Gateway tier | +|:-----------------------------------------------------------------------------------|:---------|:------------|:----------------------| +| [`:8000`](/gateway/{{page.kong_version}}/reference/configuration/#proxy_listen) | HTTP | Takes incoming HTTP traffic from **Consumers**, and forwards it to upstream **Services**. | All tiers and modes | +| [`:8443`](/gateway/{{page.kong_version}}/reference/configuration/#proxy_listen) | HTTPS | Takes incoming HTTPS traffic from **Consumers**, and forwards it to upstream **Services**. | All tiers and modes | +| [`:8001`](/gateway/{{page.kong_version}}/reference/configuration/#admin_api_uri) | HTTP | Admin API. Listens for calls from the command line over HTTP. | All tiers and modes | +| [`:8444`](/gateway/{{page.kong_version}}/reference/configuration/#admin_api_uri) | HTTPS | Admin API. Listens for calls from the command line over HTTPS. | All tiers and modes | +| [`:8005`](/gateway/{{page.kong_version}}/production/deployment-topologies/hybrid-mode/setup/) | HTTP | Hybrid mode only. Control Plane listens for traffic from Data Planes. | All tiers and modes | +| [`:8006`](/gateway/{{page.kong_version}}/production/deployment-topologies/hybrid-mode/setup/) | HTTP | Hybrid mode only. Control Plane listens for Vitals telemetry data from Data Planes. | {{site.base_gateway}} Enterprise tier | +| [`:8002`](/gateway/{{page.kong_version}}/reference/configuration/#admin_gui_listen) | HTTP | Kong Manager (GUI). Listens for HTTP traffic. | {{site.base_gateway}} free mode | +| [`:8445`](/gateway/{{page.kong_version}}/reference/configuration/#admin_gui_listen) | HTTPS | Kong Manager (GUI). Listens for HTTPS traffic. | {{site.base_gateway}} free mode | +| [`:8003`](/gateway/{{page.kong_version}}/reference/configuration/#portal_gui_listen) | HTTP | Dev Portal. Listens for HTTP traffic, assuming Dev Portal is **enabled**. | {{site.base_gateway}} Enterprise tier | +| [`:8446`](/gateway/{{page.kong_version}}/reference/configuration/#portal_gui_listen) | HTTPS | Dev Portal. Listens for HTTPS traffic, assuming Dev Portal is **enabled**. | {{site.base_gateway}} Enterprise tier | +| [`:8004`](/gateway/{{page.kong_version}}/reference/configuration/#portal_api_listen) | HTTP | Dev Portal `/files` traffic over HTTP, assuming the Dev Portal is **enabled**. | {{site.base_gateway}} Enterprise tier | +| [`:8447`](/gateway/{{page.kong_version}}/reference/configuration/#portal_api_listen) | HTTPS | Dev Portal `/files` traffic over HTTPS, assuming the Dev Portal is **enabled**. | {{site.base_gateway}} Enterprise tier | + +{:.note} +> **Note:** Kong Gateway free mode and Enterprise tier are not available for +open-source Gateway packages. diff --git a/src/gateway/production/networking/dns-considerations.md b/src/gateway/production/networking/dns-considerations.md new file mode 100644 index 000000000000..3eb30bd252d4 --- /dev/null +++ b/src/gateway/production/networking/dns-considerations.md @@ -0,0 +1,257 @@ +--- +title: DNS Considerations for Kong Gateway +badge: enterprise +--- + +{{site.base_gateway}} provides web applications that must be able to interact with +other Kong services to function properly: Kong Manager must be able to +interact with the Admin API, and the Dev Portal must be able to interact with +the Portal API. These applications are subject to security restrictions +enforced by browsers, and Kong must send appropriate information to browsers in +order for them to function properly. + +These security restrictions use the applications' DNS hostnames to evaluate +whether the applications' metadata satisfies the security constraints. As such, +you must design your DNS structure to meet the requirements. + +## Quick guide + +It is recommended you read through this document to understand why these +requirements exist and how they function. In brief, your environment must meet +one of the two criteria below: + +* Kong Manager and the Admin API are served from the same hostname, typically + by placing the Admin API under an otherwise unused path, such as `/_adminapi/`. +* Kong Manager and the Admin API are served from different hostnames with a + shared suffix (e.g. `kong.example` for `api.admin.kong.example` and + `manager.admin.kong.example`). Admin session configuration sets + `cookie_domain` to the shared suffix. + +The same applies to the Portal API and Dev Portal. + +The first option simplifies configuration in `kong.conf`, but requires an HTTP +proxy in front of the applications (because it uses HTTP path-based routing). +The Kong proxy can be used for this. The second option requires more +configuration in kong.conf, but can be used without proxying the applications. + +## CORS + +### Understanding CORS + +[Cross-Origin Resource Sharing, or CORS][mdn-cors], is a set of rules for web +applications that make requests across origins, i.e. to URLs that do not share +the same scheme, hostname, and port as the page making the request. When making +a cross-origin request, browsers send an `Origin` request header, and servers +must respond with a matching `Access-Control-Allow-Origin` (ACAO) header. If +the two headers do not match, the browser will discard the response, and any +application components that require that response's data will not function +properly. + +For example, the following request/response pairs have matching CORS headers, +and will succeed: + +``` +GET / HTTP/1.1 +Host: example.com +Origin: http://example.net + +HTTP/1.1 200 OK +Access-Control-Allow-Origin: http://example.net +``` + +``` +GET / HTTP/1.1 +Host: example.com +Origin: http://example.net + +HTTP/1.1 200 OK +Access-Control-Allow-Origin: * +``` + +`*` indicates that any origin is allowed. + +These requests do not have a matching pair of CORS headers, and will fail: + +``` +GET / HTTP/1.1 +Host: example.com +Origin: http://example.net + +HTTP/1.1 200 OK +Access-Control-Allow-Origin: http://badbadcors.example +``` + +``` +GET / HTTP/1.1 +Host: example.com +Origin: http://example.net + +HTTP/1.1 200 OK +``` + +Missing CORS headers when CORS headers are expected results in failure. + +### CORS in the context of Kong Gateway + +Kong Manager and the Dev Portal operate by issuing requests to their respective +APIs using JavaScript. These requests may be cross-origin depending on your +environment. + +Kong's services determine what CORS headers to send based on various location +hint settings in `kong.conf`. The Admin API obtains its ACAO header value from +`admin_gui_url` and the Portal API obtains its header value from the +information in the `portal_gui_protocol`, `portal_gui_host`, and +`portal_gui_use_subdomains` settings. You may optionally specify additional +Portal API origins using `portal_cors_origins`. + +You can configure your environment such that these requests are not +cross-origin by accessing both the GUI and its associated API via the same +hostname, e.g. by accessing Kong Manager at `https://admin.kong.example/` and +the Admin API at `https://admin.kong.example/_api/`. This option requires +placing a proxy in front of both Kong Manager and the Admin API to handle +path-based routing; you can use Kong's proxy for this purpose. Note that the +GUIs must be served at the root of their domains; you cannot place the APIs at +the root and the GUI under a path. + +### Troubleshooting + +CORS errors are shown in the browser developer console (for example, see documentation for +[Firefox][firefox-dev-console] and [Chrome][chrome-dev-console]) with +explanations of the specific issue. ACAO/Origin mismatches are most common, but +other error conditions can appear as well. + +For example, if you have mistyped your `admin_api_uri`, you will see something +like the following: + +``` +Access to XMLHttpRequest at 'https://admin.kong.example' from origin 'https://manager.kong.example' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The 'Access-Control-Allow-Origin' header has a value 'https://typo.kong.example' that is not equal to the supplied origin. +``` + +These errors are generally self-explanatory, but if the issue is not clear, +check the Network developer tool, find the requests for the path in the error, +and compare its `Origin` request header and `Access-Control-Allow-Origin` +response header (it may be missing entirely). + +## Cookies + +### Understanding cookies + +[Cookies][mdn-cookies] are small pieces of data saved by browsers for use in +future requests. Servers include a [Set-Cookie header][mdn-set-cookie] in their +response headers to set cookies, and browsers include a [Cookie +header][mdn-cookie] when making subsequent requests. + +Cookies are used for a variety of purposes and offer many settings to tailor +when a browser will include them to fit a particular use case. Of particular +interest are the following directives: + +- Cookie scope, defined by the cookie's `Domain` and `Path` directives. Absent + these, cookies are sent only to the hostname that created them: a cookie + created by `example.com` will not be sent with a request to + `www.example.com`. When `Domain` is specified, cookies are sent to that + hostname and its subdomains, so a cookie from `example.com` with + `Domain=example.com` *will* be sent with requests to `www.example.com`. +- The `Secure` directive, which determines whether a cookie can be sent over an + unencrypted (HTTP rather than HTTPS) connection. A cookie with `Secure` + cannot be sent over HTTP, and must be set using HTTPS. +- The `SameSite` directive, which controls when a cookie can be sent with + cross-origin requests. Note that cookies have a different notion of + cross-origin than CORS and check against the domain suffix: while + `example.com` sending a request to `api.example.com` is cross-origin for the + purposes of CORS, a cookie with `Domain=example.com` is considered same-site + for requests to `api.example.com`. `SameSite=Strict` cookies are only sent + with same-site requests, `Lax` are sent when navigating to a link from + another site, and `None` are sent with all cross-origin requests. + +### Cookies in the context of Kong Gateway + +After you log in to Kong Manager or the Dev Portal, Kong stores session +information in a cookie to recognize your browser during future requests. These +cookies are created using the [session plugin][session-plugin] (via +`admin_gui_session_conf`) or [OpenID Connect plugin][oidc-plugin]. +Configuration is more or less the same between each--the OpenID Connect plugin +contains an embedded version of the session plugin, so while cookie handling +code is the same, it is configured directly in the OpenID Connect plugin +settings (`admin_gui_auth_conf`). + +- `cookie_name` does not affect where the cookie is used, but should be set to + a unique value to avoid collisions: some configurations may use the same + `cookie_domain` for both admin and Portal cookies, and using the same name + for both would then cause their cookies to collide and overwrite one another. +- `cookie_domain` should match the common hostname suffix shared by the GUI and + its API. For example, if you use `api.admin.kong.example` and + `manager.admin.kong.example` for the Admin API and Kong Manager, + `cookie_domain` should be `admin.kong.example`. +- `cookie_samesite` should typically be left at its default, `strict`. `none` + is not necessary if you have your DNS records and `cookie_domain` set + following the examples in this document. `off` is only needed if the GUI and + API are on entirely separate hostnames, e.g. `admin.kong.example` for the API + and `manager.example.com` for Kong Manager. This configuration is not + recommended because `off` opens a vector for cross-site request forgery + attacks. It may be needed in some development or testing environments, but + should not be used in production. +- `cookie_secure` controls whether cookies can be sent over unsecured + (plaintext HTTP) requests. By default, it is set to `true`, which does not + permit sending the cookie over unsecured connections. This setting should + also remain on the default, but may be disabled in some development or + testing environments where HTTPS is not used. + +OpenID Connect uses the same settings, but prefixed with `session_`, e.g. +`session_cookie_name` rather than `cookie_name`. + +Dev Portal configuration does not differ significantly from Kong Manager +configuration, but is configured per workspace under the Portal > Settings +section of Kong Manager, in the "Session Config (JSON)" field. + +As with CORS, the above is not necessary if both the GUI and API use the same +hostname, with both behind a proxy and the API under a specific path on the +hostname. + +### Troubleshooting + +Issues with session cookies broadly fall into cases where the cookie is not +sent and cases where the cookie is not set. The network (for example, see documentation for +[Firefox][firefox-dev-network] or [Chrome][chrome-dev-network]) and +application/storage (see documentation for [Firefox][firefox-dev-storage] or +[Chrome][chrome-dev-application]) developer tools can assist with investigating +these. + +In the network tool, selecting individual requests will show their request and +response headers. Successful authentication requests should see a `Set-Cookie` +response header including a cookie whose name matches `cookie_name` setting, +and subsequent requests should include the same cookie in the `Cookie` request +header. + +If `Set-Cookie` is not present, it may be being stripped by some intermediate +proxy, or may indicate that the authentication handler encountered an error. +There should typically be other evidence in the response status and body in the +event of an error, and possible additional information in Kong's error logs. + +If the cookie is set but not sent, it may have been deleted or may not match +requests that need it. The application/storage tool will show current cookies +and their parameters. Review these to see if your requests do not meet the +criteria to send the cookie (e.g. the cookie domain is not a suffix for a +request that requires the cookie, or is not present) and adjust your session +configuration accordingly. + +If cookies are *not* present in application/storage, but were previously set +with `Set-Cookie`, they may have since been deleted, or may have expired. +Review the `Set-Cookie` information to see when the cookie was set to expire +and subsequent requests to determine if any other response has issued a +`Set-Cookie` that deleted it (by setting expiration to a date in the past). + +This troubleshooting information may not immediately indicate the cause of the issue, but can +help Kong Support pinpoint the cause. Please provide it in tickets if possible. + +[chrome-dev-application]: https://developers.google.com/web/tools/chrome-devtools#application +[chrome-dev-console]: https://developers.google.com/web/tools/chrome-devtools/console/log +[chrome-dev-network]: https://developers.google.com/web/tools/chrome-devtools#network +[firefox-dev-console]: https://developer.mozilla.org/en-US/docs/Tools/Web_Console/Opening_the_Web_Console +[firefox-dev-network]: https://developer.mozilla.org/en-US/docs/Tools/Network_Monitor +[firefox-dev-storage]: https://developer.mozilla.org/en-US/docs/Tools/Storage_Inspector +[mdn-cookie]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cookie +[mdn-cookies]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies +[mdn-set-cookie]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie +[mdn-cors]: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS +[oidc-plugin]: https://docs.konghq.com/hub/kong-inc/openid-connect/ +[session-plugin]: https://docs.konghq.com/hub/kong-inc/session/ diff --git a/src/gateway/production/networking/firewall.md b/src/gateway/production/networking/firewall.md new file mode 100644 index 000000000000..4e9c4e348338 --- /dev/null +++ b/src/gateway/production/networking/firewall.md @@ -0,0 +1,72 @@ +--- +title: Network and Firewall +content_type: reference +--- + +In this section you will find a summary about the recommended network and firewall settings for Kong. + +## Ports + +Kong uses multiple connections for different purposes. + +* proxy +* admin api + +### Proxy + +The proxy ports is where Kong receives its incoming traffic. There are two ports with the following defaults: + +* `8000` for proxying HTTP traffic, and +* `8443` for proxying HTTPS traffic + +See [proxy_listen] for more details on HTTP/HTTPS proxy listen options. For production environment it is common +to change HTTP and HTTPS listen ports to `80` and `443`. + +Kong can also proxy TCP/TLS streams. The stream proxying is disabled by default. See [stream_listen] for +additional details on stream proxy listen options, and how to enable it (if you plan to proxy anything other than +HTTP/HTTPS traffic). + +In general the proxy ports are the **only ports** that should be made available to your clients. + +### Admin API + +This is the port where Kong exposes its management API. Hence in production this port should be firewalled to protect +it from unauthorized access. + +* `8001` provides Kong's **Admin API** that you can use to operate Kong with HTTP. See [admin_listen]. + +{% include_cached /md/admin-listen.md desc='short' kong_version=page.kong_version %} + +* `8444` provides the same Kong **Admin API** but using HTTPS. See [admin_listen] and the `ssl` suffix. + +## Firewall + +Below are the recommended firewall settings: + +* The upstream Services behind Kong will be available via the [proxy_listen] interface/port values. + Configure these values according to the access level you wish to grant to the upstream Services. +* If you are binding the Admin API to a public-facing interface (via [admin_listen]), then **protect** it to only + allow trusted clients to access the Admin API. See also [Securing the Admin API][secure_admin_api]. +* Your proxy will need have rules added for any HTTP/HTTPS and TCP/TLS stream listeners that you configure. + For example, if you want Kong to manage traffic on port `4242`, your firewall will need to allow traffic + on said port. + +#### Transparent Proxying + +It is worth mentioning that the `transparent` listen option may be applied to [proxy_listen] +and [stream_listen] configuration. With packet filtering such as `iptables` (Linux) or `pf` (macOS/BSDs) +or with hardware routers/switches, you can specify pre-routing or redirection rules for TCP packets that +allow you to mangle the original destination address and port. For example a HTTP request with a destination +address of `10.0.0.1`, and a destination port of `80` can be redirected to `127.0.0.1` at port `8000`. +To make this work, you need (with Linux) to add the `transparent` listen option to Kong proxy, +`proxy_listen=8000 transparent`. This allows Kong to see the original destination for the request +(`10.0.0.1:80`) even when Kong didn't actually listen to it directly. With this information, +Kong can route the request correctly. The `transparent` listen option should only be used with Linux. +macOS/BSDs allow transparent proxying without `transparent` listen option. With Linux you may also need +to start Kong as a `root` user or set the needed capabilities for the executable. + + +[proxy_listen]: /gateway/{{page.kong_version}}/reference/configuration/#proxy_listen +[stream_listen]: /gateway/{{page.kong_version}}/reference/configuration/#stream_listen +[admin_listen]: /gateway/{{page.kong_version}}/reference/configuration/#admin_listen +[secure_admin_api]: /gateway/{{page.kong_version}}/production/running-kong/secure-admin-api diff --git a/src/gateway/production/running-kong/kong-user.md b/src/gateway/production/running-kong/kong-user.md new file mode 100644 index 000000000000..23635ff9c1db --- /dev/null +++ b/src/gateway/production/running-kong/kong-user.md @@ -0,0 +1,59 @@ +--- +title: Running Kong as a Non-Root User +--- + +After installing {{site.base_gateway}} on a GNU/Linux system, you can +configure Kong to run as the built-in `kong` user and group instead of `root`. +This makes the Nginx master and worker processes run as the built-in `kong` +user and group, overriding any settings in the +[`nginx_user`](/gateway/{{page.kong_version}}/reference/configuration/#nginx_user) +configuration property. It is also possible to run Kong as a custom non-root user. + +{:.important} +> **Important:** The Nginx master process needs to run as `root` for +Nginx to execute certain actions (for example, to listen on the privileged +port 80). +

      +> Although running Kong as the `kong` user and group +does provide more security, we advise that a system and network +administration evaluation be performed before making this decision. Otherwise, +Kong nodes might become unavailable due to insufficient permissions to execute +privileged system calls in the operating system. + +## Prerequisites + +{{site.ee_product_name}} is installed on one of the following Linux distributions: +* [Amazon Linux 1 or 2](/gateway/{{page.kong_version}}/install/linux/amazon-linux) +* [RHEL](/gateway/{{page.kong_version}}/install/linux/rhel) +* [Ubuntu](/gateway/{{page.kong_version}}/install/linux/ubuntu) + +## Run {{site.base_gateway}} as the built-in kong user + +When {{site.base_gateway}} is installed with a package management system such as `APT` or `YUM`, a default `kong` user and a default `kong` group are created. All the files installed by the package are owned by the `kong` user and group. + +1. Switch to the built-in `kong` user: + + ```sh + su kong + ``` +2. Start Kong: + + ```sh + kong start + ``` + +## Run {{site.base_gateway}} as a custom non-root user + +It is also possible to run Kong as a custom non-root user. Since all the files installed by the {{site.base_gateway}} package are owned by the `kong` group, a user that belongs to that group should be permitted to perform the same operations as the `kong` user. + +1. Add the user to the `kong` group + + ```sh + sudo usermod -aG kong your-user + ``` + +2. Start Kong: + + ```sh + kong start + ``` diff --git a/src/gateway/production/running-kong/secure-admin-api.md b/src/gateway/production/running-kong/secure-admin-api.md new file mode 100644 index 000000000000..758ad83b48e1 --- /dev/null +++ b/src/gateway/production/running-kong/secure-admin-api.md @@ -0,0 +1,245 @@ +--- +title: Securing the Admin API +--- + +{{site.base_gateway}}'s Admin API provides a RESTful interface for administration and +configuration of Services, Routes, Plugins, Consumers, and Credentials. Because this +API allows full control of Kong, it is important to secure this API against +unwanted access. This document describes a few possible approaches to securing +the Admin API. + +## Network Layer Access Restrictions + +### Minimal Listening Footprint + +By default since its 0.12.0 release, Kong will only accept requests from the +local interface, as specified in its default `admin_listen` value: + +``` +admin_listen = 127.0.0.1:8001 +``` + +If you change this value, always ensure to keep the listening footprint to a +minimum, in order to avoid exposing your Admin API to third-parties, which +could seriously compromise the security of your Kong cluster as a whole. +For example, **avoid binding Kong to all of your interfaces**, by using +values such as `0.0.0.0:8001`. + +### Layer 3/4 Network Controls + +In cases where the Admin API must be exposed beyond a localhost interface, +network security best practices dictate that network-layer access be restricted +as much as possible. Consider an environment in which Kong listens on a private +network interface, but should only be accessed by a small subset of an IP range. +In such a case, host-based firewalls (e.g. iptables) are useful in limiting +input traffic ranges. For example: + + +```bash +# assume that Kong is listening on the address defined below, as defined as a +# /24 CIDR block, and only a select few hosts in this range should have access + +grep admin_listen /etc/kong/kong.conf +admin_listen 10.10.10.3:8001 + +# explicitly allow TCP packets on port 8001 from the Kong node itself +# this is not necessary if Admin API requests are not sent from the node +iptables -A INPUT -s 10.10.10.3 -m tcp -p tcp --dport 8001 -j ACCEPT + +# explicitly allow TCP packets on port 8001 from the following addresses +iptables -A INPUT -s 10.10.10.4 -m tcp -p tcp --dport 8001 -j ACCEPT +iptables -A INPUT -s 10.10.10.5 -m tcp -p tcp --dport 8001 -j ACCEPT + +# drop all TCP packets on port 8001 not in the above IP list +iptables -A INPUT -m tcp -p tcp --dport 8001 -j DROP + +``` + +Additional controls, such as similar ACLs applied at a network device level, are +encouraged, but fall outside the scope of this document. + +## Kong API Loopback + +Kong's routing design allows it to serve as a proxy for the Admin API itself. In +this manner, Kong itself can be used to provide fine-grained access control to +the Admin API. Such an environment requires bootstrapping a new Service that defines +the `admin_listen` address as the Service's `url`. + +For example, let's assume that Kong `admin_listen` is `127.0.0.1:8001`, so it is only +available from localhost. The port `8000` is serving proxy traffic, presumably exposed via +`myhost.dev:8000` + +We want to expose Admin API via the url `:8000/admin-api`, in a controlled way. We can do so by +creating a Service and Route for it from inside `127.0.0.1`: + +```bash +curl -X POST http://127.0.0.1:8001/services \ + --data name=admin-api \ + --data host=127.0.0.1 \ + --data port=8001 + +curl -X POST http://127.0.0.1:8001/services/admin-api/routes \ + --data paths[]=/admin-api +``` + +We can now transparently reach the Admin API through the proxy server, from outside `127.0.0.1`: + +```bash +curl myhost.dev:8000/admin-api/services +{ + "data":[ + { + "id": "653b21bd-4d81-4573-ba00-177cc0108dec", + "created_at": 1422386534, + "updated_at": 1422386534, + "name": "admin-api", + "retries": 5, + "protocol": "http", + "host": "127.0.0.1", + "port": 8001, + "path": "/admin-api", + "connect_timeout": 60000, + "write_timeout": 60000, + "read_timeout": 60000 + } + ], + "total":1 +} +``` + +From here, simply apply desired Kong-specific security controls (such as +[basic][basic-auth] or [key authentication][key-auth], +[IP restrictions][ip-restriction], or [access control lists][acl]) as you would +normally to any other Kong API. + +If you are using Docker to host {{site.ee_product_name}}, you can accomplish a similar task using a declarative configuration such as this one: + +``` yaml +_format_version: "3.0" + +services: +- name: admin-api + url: http://127.0.0.1:8001 + routes: + - paths: + - /admin-api + plugins: + - name: key-auth + +consumers: +- username: admin + keyauth_credentials: + - key: secret +``` + +Under this configuration, the Admin API will be available through the `/admin-api`, but only for requests accompanied with `?apikey=secret` query +parameters. + +Assuming that the file above is stored in `$(pwd)/kong.yml`, a DB-less {{site.ee_product_name}} can use it as it starts like this: + +``` bash +docker run -d --name kong-ee \ + -e "KONG_DATABASE=off" \ + -e "KONG_DECLARATIVE_CONFIG=/home/kong/kong.yml" + -e "KONG_PROXY_ACCESS_LOG=/dev/stdout" \ + -e "KONG_ADMIN_ACCESS_LOG=/dev/stdout" \ + -e "KONG_PROXY_ERROR_LOG=/dev/stderr" \ + -e "KONG_ADMIN_ERROR_LOG=/dev/stderr" \ + -e "KONG_ADMIN_LISTEN=0.0.0.0:8001, 0.0.0.0:8444 ssl" \ + -v $(pwd):/home/kong + kong-ee +``` + +With a PostgreSQL database, the initialization steps would be the following: + +``` bash +# Start PostgreSQL on a Docker container +# Notice that PG_PASSWORD needs to be set +docker run --name kong-ee-database \ + -p 5432:5432 \ + -e "POSTGRES_USER=kong" \ + -e "POSTGRES_DB=kong" \ + -e "POSTGRES_PASSWORD=$PG_PASSWORD" \ + -d postgres:9.6 + +# Run Kong migrations to initialize the database +docker run --rm \ + --link kong-ee-database:kong-ee-database \ + -e "KONG_DATABASE=postgres" \ + -e "KONG_PG_HOST=kong-ee-database" \ + -e "KONG_PG_PASSWORD=$PG_PASSWORD" \ + kong-ee kong migrations bootstrap + +# Load the configuration file which enables the Admin API loopback +# Notice that it is assumed that kong.yml is located in $(pwd)/kong.yml +docker run --rm \ + --link kong-ee-database:kong-ee-database \ + -e "KONG_DATABASE=postgres" \ + -e "KONG_PG_HOST=kong-ee-database" \ + -e "KONG_PG_PASSWORD=$PG_PASSWORD" \ + -v $(pwd):/home/kong \ + kong-ee kong config db_import /home/kong/kong.yml + +# Start Kong +docker run -d --name kong \ + --link kong-ee-database:kong-ee-database \ + -e "KONG_DATABASE=postgres" \ + -e "KONG_PG_HOST=kong-ee-database" \ + -e "KONG_PG_PASSWORD=$PG_PASSWORD" \ + -e "KONG_PROXY_ACCESS_LOG=/dev/stdout" \ + -e "KONG_ADMIN_ACCESS_LOG=/dev/stdout" \ + -e "KONG_PROXY_ERROR_LOG=/dev/stderr" \ + -e "KONG_ADMIN_ERROR_LOG=/dev/stderr" \ + -e "KONG_ADMIN_LISTEN=0.0.0.0:8001, 0.0.0.0:8444 ssl" \ + kong-ee +``` + +In both cases, once Kong is up and running, the Admin API would be available but protected: + +``` bash +curl myhost.dev:8000/admin-api/services +=> HTTP/1.1 401 Unauthorized + +curl myhost.dev:8000/admin-api/services?apikey=secret +=> HTTP/1.1 200 OK +{ + "data": [ + { + "ca_certificates": null, + "client_certificate": null, + "connect_timeout": 60000, + ... + } + ] +} +``` + +## Custom Nginx Configuration + +Kong is tightly coupled with Nginx as an HTTP daemon, and can thus be integrated +into environments with custom Nginx configurations. In this manner, use cases +with complex security/access control requirements can use the full power of +Nginx/OpenResty to build server/location blocks to house the Admin API as +necessary. This allows such environments to leverage native Nginx authorization +and authentication mechanisms, ACL modules, etc., in addition to providing the +OpenResty environment on which custom/complex security controls can be built. + +For more information on integrating Kong into custom Nginx configurations, see +[Custom Nginx configuration & embedding Kong][custom-configuration]. + +## Role Based Access Control +{:.badge .enterprise} + +{{site.base_gateway}} users can configure [role-based access control](/gateway/{{page.kong_version}}/production/access-control/enable-rbac) +to secure access to the Admin API. RBAC allows for fine-grained control over resource access +based on a model of user roles and permissions. Users are assigned to one or more roles, +which each in turn possess one or more permissions granting or denying access +to a particular resource. In this way, fine-grained control over specific Admin +API resources can be enforced, while scaling to allow complex, case-specific +uses. + +[acl]: /hub/kong-inc/acl +[basic-auth]: /hub/kong-inc/basic-auth +[custom-configuration]: /gateway/{{page.kong_version}}/reference/nginx-directives +[ip-restriction]: /hub/kong-inc/ip-restriction +[key-auth]: /hub/kong-inc/key-auth diff --git a/src/gateway/production/running-kong/systemd.md b/src/gateway/production/running-kong/systemd.md new file mode 100644 index 000000000000..8f8f3333ba3f --- /dev/null +++ b/src/gateway/production/running-kong/systemd.md @@ -0,0 +1,153 @@ +--- +title: Control Kong Gateway through systemd +--- + +This document includes instructions on how to integrate {{site.base_gateway}} +with systemd for Debian and RPM based packages. + +Note that some of the supported GNU/Linux distributions for {{site.base_gateway}} +may not have adopted systemd as their default init system +(for example, CentOS 6 and RHEL 6). For the following instructions, it is +assumed that {{site.base_gateway}} has already been +[installed and configured](/gateway/{{page.kong_version}}/install) on a +systemd-supported GNU/Linux distribution. + +## systemd commands for working with {{site.base_gateway}} + +### Start {{site.base_gateway}} + +```bash +# For {{site.base_gateway}} +sudo systemctl start kong-enterprise-edition + +# For {{site.ce_product_name}} +sudo systemctl start kong +``` + +### Stop {{site.base_gateway}} + +```bash +# For {{site.base_gateway}} +sudo systemctl stop kong-enterprise-edition + +# For {{site.ce_product_name}} +sudo systemctl stop kong +``` + +### Start {{site.base_gateway}} at system boot + +**Enable starting {{site.base_gateway}} automatically at system boot** + +```bash +# For {{site.base_gateway}} +sudo systemctl enable kong-enterprise-edition + +# For {{site.ce_product_name}} +sudo systemctl enable kong +``` + +**Disable starting {{site.base_gateway}} automatically at system boot** + +```bash +# For {{site.base_gateway}} +sudo systemctl disable kong-enterprise-edition + +# For {{site.ce_product_name}} +sudo systemctl disable kong +``` + +### Restart {{site.base_gateway}} + +```bash +# For {{site.base_gateway}} +sudo systemctl restart kong-enterprise-edition + +# For {{site.ce_product_name}} +sudo systemctl restart kong +``` + +### Query {{site.base_gateway}} status + +```bash +# For {{site.base_gateway}} +sudo systemctl status kong-enterprise-edition + +# For {{site.ce_product_name}} +sudo systemctl status kong +``` + +## Customize the {{site.base_gateway}} unit file + +The official systemd service is located at at `/lib/systemd/system/kong-enterprise-edition.service` for +{{site.base_gateway}}, or at `/lib/systemd/system/kong.service` for {{site.ce_product_name}}. + +For scenarios where customizations are needed (for example, configuring Kong +or modifying the service file behavior), we recommend creating another service +at `/etc/systemd/system/kong-enterprise-edition.service` for +{{site.base_gateway}}, or at `/etc/systemd/system/kong.service` for +{{site.ce_product_name}}, to avoid conflicts upon reinstalling or upgrading Kong. + +All environment variables prefixed with `KONG_` and capitalized will override the settings specified in the `/etc/kong/kong.conf.default` file. For example: `log_level = debug` in the .conf file translates to the `KONG_LOG_LEVEL=debug` environment variable. + +You can also choose use a configuration file instead of environment variables. In this case, modify the `ExecStartPre` systemd directive to execute `kong prepare` with the `-c` argument to point to your configuration file. For example, if you have a custom configuration file at `/etc/kong/kong.conf`, modify the `ExecStartPre` directive as follows: + +``` +ExecStartPre=/usr/local/bin/kong prepare -p /usr/local/kong -c /etc/kong/kong.conf +``` + +When linking non environment files using the `EnvironmentFile` systemd directive, note that the systemd parser will only recognize environment variables assignments. For example, if one of the Kong's default configuration files are linked (`/etc/kong/kong.conf.default` and `/etc/kong.conf`), non environment variables assignments in the file could lead to systemd errors. In this case, systemd will not allow the Kong service to be started. For this reason, we recommend specifying an `EnvironmentFile` other than the default ones: + +``` +EnvironmentFile=/etc/kong/kong_env.conf +``` + +### Logging to syslog and journald + +In this case, adding the below `Environment` systemd directives to your customized systemd service file at `/etc/systemd/system/kong-enterprise-edition.service` will do it: + +``` +Environment=KONG_PROXY_ACCESS_LOG=syslog:server=unix:/dev/log +Environment=KONG_PROXY_ERROR_LOG=syslog:server=unix:/dev/log +Environment=KONG_ADMIN_ACCESS_LOG=syslog:server=unix:/dev/log +Environment=KONG_ADMIN_ERROR_LOG=syslog:server=unix:/dev/log +``` + +To view the journald logs: + +```bash +# For {{site.base_gateway}} +journalctl -u kong-enterprise-edition + +# For {{site.ce_product_name}} +journalctl -u kong +``` + +To view the syslog logs: + +```bash +tail -F /var/log/syslog +``` + +### Customize Kong's Nginx instance using the Nginx directive injection system + +To use the [injection system](/gateway/{{page.kong_version}}/reference/configuration/#injecting-individual-nginx-directives) with environment variables, add the below `Environment` systemd directive to your custom service at `/etc/systemd/system/kong-enterprise-edition.service` ({{site.base_gateway}}) or `/etc/systemd/system/kong.service` ({{site.ce_product_name}}). Note the quoting rules defined by systemd to specify an environment variable containing spaces: + +``` +Environment="KONG_NGINX_HTTP_OUTPUT_BUFFERS=4 64k" +``` + +### Customize Kong's Nginx instance using ––nginx-conf + +To use the [`--nginx-conf`](/gateway/{{page.kong_version}}/reference/configuration/#custom-nginx-templates) argument, modify the `ExecStartPre` systemd directive to execute `kong prepare` with the `--nginx-conf` argument. For example, if you have a custom template at `/usr/local/kong/custom-nginx.template`, modify the `ExecStartPre` directive as follows: + +``` +ExecStartPre=/usr/local/bin/kong prepare -p /usr/local/kong --nginx-conf /usr/local/kong/custom-nginx.template +``` + +### Customize Kong's Nginx instance including files via the injected Nginx directives + +To [include files via the injected Nginx directives](/gateway/{{page.kong_version}}/reference/configuration/#including-files-via-injected-nginx-directives) with environment variables, add the below `Environment` systemd directive to your custom service at `/etc/systemd/system/kong-enterprise-edition.service` ({{site.base_gateway}}) or `/etc/systemd/system/kong.service` ({{site.ce_product_name}}): + +``` +Environment=KONG_NGINX_HTTP_INCLUDE=/path/to/your/my-server.kong.conf +``` diff --git a/src/gateway/production/security-update-process.md b/src/gateway/production/security-update-process.md new file mode 100644 index 000000000000..537a3b4f3604 --- /dev/null +++ b/src/gateway/production/security-update-process.md @@ -0,0 +1,19 @@ +--- +title: Kong Security Update Process +--- + +## Reporting a Vulnerability + +If you have found a vulnerability or a potential vulnerability in the Kong gateway or other Kong software, or know of a publicly disclosed security vulnerability, please immediately let us know by emailing [security@konghq.com](mailto:security@konghq.com). We'll send a confirmation email to acknowledge your report, and we'll send an additional email when we've identified the issue positively or negatively. + +Once a report is received, we will investigate the vulnerability and assign it a [CVSS](https://www.first.org/cvss/) score which will determine the timeline for the development of an appropriate fix. + +While the fix development is underway, we ask that you do not share or publicize an unresolved vulnerability with third parties. If you responsibly submitted a vulnerability report, we will do our best to acknowledge your report in a timely fashion and notify you of the estimated timeline for a fix. + +## Fix Development Process + +If a discovered vulnerability with a CVSS score above 4.0 (medium severity or higher) affects the latest major release of the Kong gateway or other Kong software, then we will work to develop a fix in the most timely fashion. The work and communication around the fix will happen in private channels, and a delivery estimate will be given to the vulnerability reporter. Once the fix is developed and verified, a new patch version will be released by Kong for each supported {{site.base_gateway}} release and for the current release of the open source gateway. We will disclose the vulnerability as appropriate. + +Discovered vulnerabilities with a CVSS score below 4.0 (low severity) will follow the same fix development and release process but with a less urgent timeline. + +Vulnerabilities affecting upstream projects (e.g. NGINX, OpenResty, OpenSSL...) will receive fixes as per the upstream project's disclosure timeline. diff --git a/src/gateway/production/sizing-guidelines.md b/src/gateway/production/sizing-guidelines.md new file mode 100644 index 000000000000..60195ba9d4d6 --- /dev/null +++ b/src/gateway/production/sizing-guidelines.md @@ -0,0 +1,190 @@ +--- +title: Resource Sizing Guidelines +--- + +This document discusses the performance characteristics of +{{site.base_gateway}}, and offers recommendations on sizing for +resource allocation based on expected {{site.base_gateway}} configuration and +traffic patterns. + +These recommendations are a baseline guide only. Specific tuning or +benchmarking efforts should be undertaken for performance-critical environments. + +## General resource guidelines + +### Kong Gateway resources + +{{site.base_gateway}} is designed to operate in a variety of deployment +environments. It has no minimum system requirements to operate. + +Resource requirements vary substantially based on configuration. The following +high-level matricies offer a guideline for determining system requirements +based on overall configuration and performance requirements. + +Consider the following simplified examples, where latency and throughput requirements are considered on a per-node basis. This table has rough usage requirement estimates: + +| Size | Number of Configured Entities | Latency Requirements | Throughput Requirements | Usage Pattern | +|---|---|---|---|---| +| Small | < 100 | < 100 ms | < 500 RPS | Dev/test environments; latency-insensitive gateways | +| Medium | < 1000 | < 20 ms | < 2500 RPS | Production clusters; greenfield traffic deployments | +| Large | < 10000 | < 10 ms | < 10000 RPS | Mission-critical clusters; legacy & greenfield traffic; central enterprise-grade gateways | + +### Database resources + +We do not provide any hard numbers for database sizing (DB sizing), as it +depends on your particular setup. Sizing varies based on: +* Traffic +* Number of nodes +* Enabled features: for example, Vitals, or if rate limiting uses a +database or Redis +* Number and rate of change of configured entities +* The rate at which {{site.base_gateway}} processes are started and restarted within the cluster +* The size of {{site.base_gateway}}'s [in-memory cache](#in-memory-caching) + +{{site.base_gateway}} intentionally relies on the database as little as +possible. To access configuration, {{site.base_gateway}} executes a spiky +access pattern to its backing database. This means that {{site.base_gateway}} +only reads configuration from the database when a node first starts, or +configuration for a given entity changes. + +Everything in the database is meant to be read infrequently and held in memory +as long as possible. Therefore, database resource requirements are lower than +those of compute environments running {{site.base_gateway}}. + +Query patterns are typically simple and follow schema indexes. Provision +sufficient database resources in order to handle spiky query patterns. + +There are [settings](/gateway/{{page.kong_version}}/reference/configuration/#datastore-section/) +that you can adjust to keep database access minimal (also see [in-memory caching](#in-memory-caching)), or +[keep {{site.base_gateway}} operational](https://support.konghq.com/support/s/article/Keeping-Kong-Functional-During-DB-Down-Times) +if the DB is down for maintenance. If you choose to keep the database +operational during downtimes, vitals data is not written to the +database during this time. + +### Cluster resource allocations + +Based on the expected size and demand of the cluster, we recommend +the following resource allocations as a starting point: + +| Size | CPU | RAM | Typical Cloud Instance Sizes | +|---|---|---|---|---| +| Small | 1-2 cores | 2-4 GB | **AWS**: t3.medium
      **GCP**: n1-standard-1
      **Azure**: Standard A1 v2 | +| Medium | 2-4 cores | 4-8 GB | **AWS**: m5.large
      **GCP**: n1-standard-4
      **Azure**: Standard A1 v4 | +| Large | 8-16 cores | 16-32 GB | **AWS**: c5.xlarge
      **GCP**: n1-highcpu-16
      **Azure**: F8s v2 | + +We strongly discourage the use of throttled cloud instance types (such as the +AWS `t2` or `t3` series of machines) in large clusters, as CPU throttling would +be detrimental to {{site.base_gateway}}'s performance. We also recommend +testing and verifying the bandwidth availability for a given instance class. +Bandwidth requirements for {{site.base_gateway}} depend on the shape and volume +of traffic flowing through the cluster. + +### In-memory caching +We recommend defining the `mem_cache_size` configuration as large as possible, +while still providing adequate resources to the operating system and any other +processes running adjacent to {{site.base_gateway}}. This configuration allows +{{site.base_gateway}} to take maximum advantage of the in-memory cache, and +reduce the number of trips to the database. + +Each {{site.base_gateway}} worker process maintains its own memory allocations, +and must be accounted for when provisioning memory. By default, one worker +process runs per number of available CPU cores. We recommend allowing for +around **500MB** of memory allocated per worker process. + +For example, on a machine with 4 CPU cores and 8 GB of RAM available, we recommend allocating between 4-6 GB to cache via the `mem_cache_size` directive, depending on what other processes are running alongside {{site.base_gateway}}. + +## Scaling dimensions + +{{site.base_gateway}} is designed to handle large volumes of request +traffic and proxying requests with minimal latency. Understanding how various +configuration scenarios impacts request traffic, and the {{site.base_gateway}} +cluster itself, is a crucial step in successfully deploying +{{site.base_gateway}}. + +{{site.base_gateway}} measures performance in the following dimensions: + +* **Latency** refers to the delay between the downstream client +sending a request and receiving a response. {{site.base_gateway}} measures +latency introduced into the request in terms of microseconds or milliseconds. +Increasing the number of Routes and Plugins in a {{site.base_gateway}} cluster +increases the amount of latency that's added to each request. +* **Throughput** refers to the number of +requests that {{site.base_gateway}} can process in a given time span, typically +measured in seconds or minutes. + +These dimensions have an inversely proportional relationship +when all other factors remain the same: decreasing the latency introduced into +each request allows the maximum throughput in {{site.base_gateway}} to +increase, as there is less CPU time spent handling each request, and more +CPU available for processing traffic as a whole. {{site.base_gateway}} is +designed to scale horizontally to be able to add more overall compute power for +configurations that add substantial latency into requests, while needing to +meet specific throughput requirements. + +{{site.base_gateway}}'s maximum throughput is a CPU-bound dimension, and minimum +latency is memory-bound. +* **Latency-sensitive workload**: making more memory available for database caching +is more beneficial than adding more compute power to the cluster. +* **Throughput-sensitive workload**: these workloads are dependant on both adequate +memory and CPU resources, but adding more +compute power by scaling {{site.base_gateway}} vertically or horizontally is +the better choice, as it provides near-unlimited throughput capacity. In this +scenario, adding more cache memory would not increase maximum throughput by +much. + +Performance benchmarking and optimization as a whole is a complex exercise that +must account for a variety of factors, including those external to +{{site.base_gateway}}, such as the behavior of upstream services, or the health +of the underlying hardware on which {{site.base_gateway}} is running. + +## Performance characteristics + +There are a number of factors that impact {{site.base_gateway}}'s performance, +including: + +* **Number of configured Routes and Services**: Increasing the count of Routes +and Services on the cluster requires more CPU to evaluate the request. +However, {{site.base_gateway}}'s request router can handle running at large +scale. We've seen clusters of {{site.base_gateway}} nodes serving tens of +thousands of Routes with minimal impact to latency as a result of request route +evaluation. + +* **Number of configured Consumers and Credentials**: Consumer and credential +data is stored in {{site.base_gateway}}'s datastore. {{site.base_gateway}} +caches this data in memory to reduce database load and +latency during request processing. Increasing the count of Consumers and +Credentials requires more memory available for {{site.base_gateway}} to hold +data in cache. If there is not enough memory available to cache all requested +database entities, request latency increases as {{site.base_gateway}} needs to +query the database more frequently to satisfy requests. + +* **Number of configured Plugins**: Increasing the count of Plugins on the +cluster requires more CPU to iterate through plugins during request +processing. Executing plugins comes with a varying cost depending on the nature +of the plugin. For example, a lightweight authentication plugin like `key-auth` +requires less resource availability than a plugin that performs complex +transformations of an HTTP request or response. + +* **Cardinality of configured Plugins**: _Cardinality_ is the number +of distinct plugin types that are configured on the cluster. For example, a +cluster with one each of `ip-restriction`, `key-auth`, `bot-detection`, +`rate-limiting`, and `http-log` plugins has a higher plugin cardinality than a +cluster with one thousand `rate-limiting` plugins applied at the route level. +With each additional plugin type added to the cluster, {{site.base_gateway}} +spends more time evaluating whether to execute a given plugin for a given +request. Increasing the cardinality of configured plugins requires more CPU +power, as the process to evaluate plugins is a CPU-constrained task. + +* **Request and response size**: Requests with large HTTP bodies, either in the +request or response, take longer to process, as {{site.base_gateway}} must +buffer the request to disk before proxying it. This allows +{{site.base_gateway}} to handle a large volume of traffic without running out +of memory, but the nature of buffered requests can result in increased latency. + +* **Number of configured Workspaces**: Increasing the count of Workspaces on the +cluster requires more CPU to evaluate each request, and more memory +available for the cache to hold Workspace configuration and metadata. The +impact of increasing the number of Workspaces on the cluster is also affected +by the cardinality of configured plugins on the cluster. There is an +exponential impact on request throughput capacity within the cluster +as the cardinality of plugins _and_ the number of Workspaces increases. diff --git a/src/gateway/production/tracing/api.md b/src/gateway/production/tracing/api.md new file mode 100644 index 000000000000..03e794896d0f --- /dev/null +++ b/src/gateway/production/tracing/api.md @@ -0,0 +1,206 @@ +--- +title: Tracing API Referenece +content-type: Reference +--- + +## Before you start + +In Gateway version 3.0.0, the tracing API became part of the Kong core application. +The API is in the `kong.tracing` namespace. + +The tracing API follows the [OpenTelemetry API specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md). +This specification defines how to use the API as an instrument to your module. +If you are familiar with the OpenTelemetry API, the tracing API will be familiar. + +With the tracing API, you can set the instrumentation of your module with the following operations: +- [Span](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#span) +- [Attributes](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/span-general.md) + +## Create a tracer + +Kong uses a global tracer internally to instrument the core modules and plugins. + +By default, the tracer is a [NoopTracer](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#get-a-tracer). The tracer is first initialized when `opentelemetry_tracing` configuration is enabled. + +You can create a new tracer manually, or use the global tracer instance: + +```lua +local tracer + +-- Create a new tracer +tracer = kong.tracing.new("custom-tracer") + +-- Use the global tracer +tracer = kong.tracing +``` + +### Sampling traces + +The sampling rate of a tracer can be configured: + +```lua +local tracer = kong.tracing.new("custom-tracer", { + -- Set the sampling rate to 0.1 + sampling_rate = 0.1, +}) +``` + +The default sampling rate is `1.0`, which samples all traces. + +## Create a span + +A span represents a single operation within a trace. Spans can be nested to form trace trees. Each trace contains a root span, which typically describes the entire operation and, optionally, one or more sub-spans for its sub-operations. + +```lua +local tracer = kong.tracing + +local span = tracer:start_span("my-span") +``` + +The span properties can be set by passing a table to the `start_span` method. + +```lua +local span = tracer:start_span("my-span", { + start_time_ns = ngx.now() * 1e9, -- override the start time + span_kind = 2, -- SPAN_KIND + -- UNSPECIFIED: 0 + -- INTERNAL: 1 + -- SERVER: 2 + -- CLIENT: 3 + -- PRODUCER: 4 + -- CONSUMER: 5 + should_sample = true, -- by setting it to `true` to ignore the sampling decision +}) +``` + +Make sure to ends the span when you are done: + +```lua +span:finish() -- ends the span +``` + +{:.Note} +>**Note:** The span table will be cleared and put into the table pool after the span is finished, +do not use it after the span is finished. + +## Get or set the active span + +The active span is the span that is currently being executed. + +To avoid overheads, the active span is manually set by calling the `set_active_span` method. +When you finish a span, the active span becomes the parent of the finished span. + + +To set or get the active span, you can use the following example code: + +```lua +local tracer = kong.tracing +local span = tracer:start_span("my-span") +tracer.set_active_span(span) + +local active_span = tracer.active_span() -- returns the active span +``` + +### Scope + +The tracers are scoped to a specific context by a namespace key. + +To get the active span for a specific namespace, you can use the following: + +```lua +-- get global tracer's active span, and set it as the parent of new created span +local global_tracer = kong.tracing +local tracer = kong.tracing.new("custom-tracer") + +local root_span = global_tracer.active_span() +local span = tracer.start_span("my-span", { + parent = root_span +}) +``` + +## Set the span attributes + +The attributes of a span are a map of key-value pairs +and can be set by passing a table to the `set_attributes` method. + +```lua +local span = tracer:start_span("my-span") +``` + +The OpenTelemetry specification defines the general semantic attributes, it can be used to describe the span. +It could also be meaningful to visualize the span in a UI. + +```lua +span:set_attribute("key", "value") +``` + +The following semantic conventions for spans are defined: + +* [General](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/span-general.md): General semantic attributes that may be used in describing different kinds of operations. +* [HTTP](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md): For HTTP client and server spans. +* [Database](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/database.md): For SQL and NoSQL client call spans. +* [RPC/RMI](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/rpc.md): For remote procedure call (e.g., gRPC) spans. +* [Messaging](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/messaging.md): For messaging systems (queues, publish/subscribe, etc.) spans. +* [FaaS](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/faas.md): For [Function as a Service](https://en.wikipedia.org/wiki/Function_as_a_service) (e.g., AWS Lambda) spans. +* [Exceptions](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/exceptions.md): For recording exceptions associated with a span. +* [Compatibility](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/compatibility.md): For spans generated by compatibility components, e.g. OpenTracing Shim layer. + +## Set the span events + +The events of a span are time-series events that can be set by passing a table to the `add_event` method. + +```lua +local span = kong.tracing:start_span("my-span") +span:add_event("my-event", { + -- attributes + ["key"] = "value", +}) +``` + +### Record error message + +The event could also be used to record error messages. + +```lua +local span = kong.tracing:start_span("my-span") +span:record_error("my-error-message") + +-- or (same as above) +span:add_event("exception", { + ["exception.message"] = "my-error-message", +}) +``` + +## Set the span status + +The status of a span is a status code and can be set by passing a table to the `set_status` method. + +```lua +local span = kong.tracing:start_span("my-span") +-- Status codes: +-- - `0` unset +-- - `1` ok +-- - `2` error +``` + +## Release the span (optional) + +The spans are stored in a pool, and can be released by calling the `release` method. + +```lua +local span = kong.tracing:start_span("my-span") +span:release() +``` + +By default, the span will be released after the Nginx request ends. + +## Visualize the trace + +Because of the compatibility with OpenTelemetry, the traces can be natively visualized through any OpenTelemetry UI. + +Please refer to the [OpenTelemetry plugin](/hub/kong-inc/opentelemetry) to see how to visualize the traces. + +## References + +- [Tracing PDK](/gateway/{{page.kong_version}}/plugin-development/pdk/kong.tracing) +- [OpenTelemetry plugin](/hub/kong-inc/opentelemetry) diff --git a/src/gateway/production/tracing/index.md b/src/gateway/production/tracing/index.md new file mode 100644 index 000000000000..00080d78593e --- /dev/null +++ b/src/gateway/production/tracing/index.md @@ -0,0 +1,39 @@ +--- +title: Tracing Reference +content-type: reference +--- + +In this section, we will describe the tracing capabilities of Kong. + +## Core instrumentations + +**Note** +Only works for the plugins that are built on top of Kong's tracing API. +e.g. OpenTelemetry plugin. + +Kong provides a set of core instrumentations for tracing, these can be configured in the `opentelemetry_tracing` configuration. + +- `off`: do not enable instrumentations. +- `request`: only enable request-level instrumentations. +- `all`: enable all the following instrumentations. +- `db_query`: trace database query, including PostgresSQL and Cassandra. +- `dns_query`: trace DNS query. +- `router`: trace router execution, including router rebuilding. +- `http_client`: trace OpenResty HTTP client requests. +- `balancer`: trace balancer retries. +- `plugin_rewrite`: trace plugins iterator execution with rewrite phase. +- `plugin_access`: trace plugins iterator execution with access phase. +- `plugin_header_filter`: trace plugins iterator execution with `header_filter` phase. + +## Propagation + +The tracing API support to propagate the following headers: +- `w3c` - [W3C trace context](https://www.w3.org/TR/trace-context/) +- `b3`, `b3-single` - [Zipkin headers](https://github.com/openzipkin/b3-propagation) +- `jaeger` - [Jaeger headers](https://www.jaegertracing.io/docs/client-libraries/#propagation-format) +- `ot` - [OpenTracing headers](https://github.com/opentracing/specification/blob/master/rfc/trace_identifiers.md) + +The tracing API will detect the propagation format from the headers, and will use the appropriate format to propagate the span context. +If no appropriate format is found, then will fallback to the default format, which can be specified. + +The propagation api works for both the OpenTelemetry plugin and the Zipkin plugin. diff --git a/src/gateway/production/tracing/write-custom-trace-exporter.md b/src/gateway/production/tracing/write-custom-trace-exporter.md new file mode 100644 index 000000000000..8f5481692671 --- /dev/null +++ b/src/gateway/production/tracing/write-custom-trace-exporter.md @@ -0,0 +1,32 @@ +--- +title: How to write a custom trace exporter +content-type: how-to +--- + +Kong bundled OpenTelemetry plugin in core with a implementation of [OTLP/HTTP](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/otlp.md#otlphttp), but you can still write your own exporter at scale. + + +## Gathering the spans + +The spans are stored in the tracer's buffer. +The buffer is a queue of spans that are awaiting to be sent to the backend. + +You can access the buffer and process the span using the `span_processor` function. + +```lua +-- Use the global tracer +local tracer = kong.tracing + +-- Process the span +local span_processor = function(span) + -- clone the span so it can be processed after the original one is cleared + local span_dup = table.clone(span) + -- you can transform the span, add tags, etc. to other specific data structures +end +``` + +The `span_processor` function should be called in the `log` phase of the plugin. + +## Full example + +Refer to [Github](https://github.com/Kong/kong/tree/master/spec/fixtures/custom_plugins/kong/plugins/tcp-trace-exporter) to see the example of a custom trace exporter. diff --git a/src/gateway/production/website-api-serving.md b/src/gateway/production/website-api-serving.md new file mode 100644 index 000000000000..32ab6106b1e4 --- /dev/null +++ b/src/gateway/production/website-api-serving.md @@ -0,0 +1,77 @@ +--- +title: Serving a website and API with Kong Gateway +content-type: how-to +--- + +## How to serve both a website and APIs using {{site.base_gateway}} + +A common use case for API providers is to make {{site.base_gateway}} serve both a website +and the APIs over port: `80` or `443` in +production. For example, `https://example.net` (Website) and +`https://example.net/api/v1` (API). + +You can do this using a custom +Nginx configuration template that calls `nginx_kong.lua` in-line, and adds a new +`location` block that serves website alongside the Kong proxy `location` +block: + +``` +# --------------------- +# custom_nginx.template +# --------------------- + +worker_processes ${{ "{{NGINX_WORKER_PROCESSES" }}}}; # can be set by kong.conf +daemon ${{ "{{NGINX_DAEMON" }}}}; # can be set by kong.conf + +pid pids/nginx.pid; # this setting is mandatory +error_log logs/error.log ${{ "{{LOG_LEVEL" }}}}; # can be set by kong.conf +events {} + +http { + # here, we inline the contents of nginx_kong.lua + charset UTF-8; + + # any contents until Kong's Proxy server block + ... + + # Kong's Proxy server block + server { + server_name kong; + + # any contents until the location / block + ... + + # here, we declare our custom location serving our website + # (or API portal) which we can optimize for serving static assets + location / { + root /var/www/example.net; + index index.htm index.html; + ... + } + + # Kong's Proxy location / has been changed to /api/v1 + location /api/v1 { + set $upstream_host nil; + set $upstream_scheme nil; + set $upstream_uri nil; + + # Any remaining configuration for the Proxy location + ... + } + } + + # Kong's Admin server block goes below + # ... +} +``` + +Then start Nginx: + +`nginx -p /usr/local/openresty -c my_nginx.conf` + + +## More Information + +* [Embedding Kong in OpenResty](/gateway/latest/production/kong-openresty) +* [Setting environment variables](/gateway/latest/production/environment-variables) +* [How to use `kong.conf`](/gateway/latest/production/kong-conf) \ No newline at end of file diff --git a/src/gateway/reference/cli.md b/src/gateway/reference/cli.md new file mode 100644 index 000000000000..130b8cf2c57c --- /dev/null +++ b/src/gateway/reference/cli.md @@ -0,0 +1,383 @@ +--- +# +# WARNING: this file was auto-generated by a script. +# DO NOT edit this file directly. Instead, send a pull request to change +# the files in https://github.com/Kong/kong/tree/master/autodoc/cli +# +title: CLI Reference +source_url: https://github.com/Kong/kong/tree/master/autodoc/cli +--- + +The provided CLI (*Command Line Interface*) allows you to start, stop, and +manage your Kong instances. The CLI manages your local node (as in, on the +current machine). + +If you haven't yet, we recommend you read the [configuration reference][configuration-reference]. + +## Global flags + +All commands take a set of special, optional flags as arguments: + +* `-h`, `--help`: print the command's help message +* `--v`: enable verbose mode +* `--vv`: enable debug mode (noisy) + +## Available commands + + +### kong check + +``` +Usage: kong check + +Check the validity of a given Kong configuration file. + + (default /etc/kong/kong.conf) configuration file + +``` + +--- + + +### kong config + +``` +Usage: kong config COMMAND [OPTIONS] + +Use declarative configuration files with Kong. + +The available commands are: + init [] Generate an example config file to + get you started. If a filename + is not given, ./kong.yml is used + by default. + + db_import Import a declarative config file into + the Kong database. + + db_export [] Export the Kong database into a + declarative config file. If a filename + is not given, ./kong.yml is used + by default. + + parse Parse a declarative config file (check + its syntax) but do not load it into Kong. + +Options: + -c,--conf (optional string) Configuration file. + -p,--prefix (optional string) Override prefix directory. + +``` + +{:.note} +> **Note:** `db_export` is only supported with open-source +{{site.base_gateway}} packages. + +--- + + +### kong health + +``` +Usage: kong health [OPTIONS] + +Check if the necessary services are running for this node. + +Options: + -p,--prefix (optional string) prefix at which Kong should be running + +``` + +--- + + +### kong hybrid + +``` +Usage: kong hybrid COMMAND [OPTIONS] + +Hybrid mode utilities for Kong. + +The available commands are: + gen_cert [ ] Generate a certificate/key pair that is suitable + for use in hybrid mode deployment. + Cert and key will be written to + './cluster.crt' and './cluster.key' inside + the current directory unless filenames are given. + +Options: + -d,--days (optional number) Override certificate validity duration. + Default: 1095 days (3 years) + +``` + +--- + + +### kong migrations + +``` +Usage: kong migrations COMMAND [OPTIONS] + +Manage database schema migrations. + +The available commands are: + bootstrap Bootstrap the database and run all + migrations. + + up Run any new migrations. + + finish Finish running any pending migrations after + 'up'. + + list List executed migrations. + + reset Reset the database. + The `reset` command erases all of the data + in Kong's database and deletes all of the schemas. + + migrate-community-to-enterprise Migrates Kong Community entities to + Kong Enterprise in the default + workspace. + + upgrade-workspace-table Outputs a script to be run on the db to + upgrade the entity for 2.x workspaces + implementation. + + reinitialize-workspace-entity-counters Resets the entity counters from the + database entities. + + status Dump the database migration status in JSON format. + +Options: + -y,--yes Assume "yes" to prompts and run + non-interactively. + + -q,--quiet Suppress all output. + + -f,--force Run migrations even if database reports + as already executed. + + With 'migrate-community-to-enterprise' it + disables the workspace entities check. + + --db-timeout (default 60) Timeout, in seconds, for all database + operations (including schema consensus for + Cassandra). + + --lock-timeout (default 60) Timeout, in seconds, for nodes waiting on + the leader node to finish running + migrations. + + -c,--conf (optional string) Configuration file. + + -p,--prefix (optional string) Override prefix directory. + + --v verbose + --vv debug + +``` + +--- + + +### kong prepare + +This command prepares the Kong prefix folder, with its sub-folders and files. + +``` +Usage: kong prepare [OPTIONS] + +Prepare the Kong prefix in the configured prefix directory. This command can +be used to start Kong from the nginx binary without using the 'kong start' +command. + +Example usage: + kong migrations up + kong prepare -p /usr/local/kong -c kong.conf + nginx -p /usr/local/kong -c /usr/local/kong/nginx.conf + +Options: + -c,--conf (optional string) configuration file + -p,--prefix (optional string) override prefix directory + --nginx-conf (optional string) custom Nginx configuration template + +``` + +--- + + +### kong quit + +``` +Usage: kong quit [OPTIONS] + +Gracefully quit a running Kong node (Nginx and other +configured services) in given prefix directory. + +This command sends a SIGQUIT signal to Nginx, meaning all +requests will finish processing before shutting down. +If the timeout delay is reached, the node will be forcefully +stopped (SIGTERM). + +Options: + -p,--prefix (optional string) prefix Kong is running at + -t,--timeout (default 10) timeout before forced shutdown + -w,--wait (default 0) wait time before initiating the shutdown + +``` + +--- + + +### kong reload + +``` +Usage: kong reload [OPTIONS] + +Reload a Kong node (and start other configured services +if necessary) in given prefix directory. + +This command sends a HUP signal to Nginx, which will spawn +new workers (taking configuration changes into account), +and stop the old ones when they have finished processing +current requests. + +Options: + -c,--conf (optional string) configuration file + -p,--prefix (optional string) prefix Kong is running at + --nginx-conf (optional string) custom Nginx configuration template + +``` + +--- + + +### kong restart + +``` +Usage: kong restart [OPTIONS] + +Restart a Kong node (and other configured services like Serf) +in the given prefix directory. + +This command is equivalent to doing both 'kong stop' and +'kong start'. + +Options: + -c,--conf (optional string) configuration file + -p,--prefix (optional string) prefix at which Kong should be running + --nginx-conf (optional string) custom Nginx configuration template + --run-migrations (optional boolean) optionally run migrations on the DB + --db-timeout (default 60) + --lock-timeout (default 60) + +``` + +--- + +### kong runner +{:.badge .enterprise} + +``` +Usage: kong runner [file] [args] + +Execute a lua file in a kong node. the `kong` variable is available to +reach the DAO, PDK, etc. The variable `args` can be used to access all +arguments (args[1] being the lua filename being run). + +Example usage: + kong runner file.lua arg1 arg2 + echo 'print("foo")' | kong runner +``` + +--- + + +### kong start + +``` +Usage: kong start [OPTIONS] + +Start Kong (Nginx and other configured services) in the configured +prefix directory. + +Options: + -c,--conf (optional string) Configuration file. + + -p,--prefix (optional string) Override prefix directory. + + --nginx-conf (optional string) Custom Nginx configuration template. + + --run-migrations (optional boolean) Run migrations before starting. + + --db-timeout (default 60) Timeout, in seconds, for all database + operations (including schema consensus for + Cassandra). + + --lock-timeout (default 60) When --run-migrations is enabled, timeout, + in seconds, for nodes waiting on the + leader node to finish running migrations. + +``` + +--- + + +### kong stop + +``` +Usage: kong stop [OPTIONS] + +Stop a running Kong node (Nginx and other configured services) in given +prefix directory. + +This command sends a SIGTERM signal to Nginx. + +Options: + -p,--prefix (optional string) prefix Kong is running at + +``` + +--- + + +### kong vault + +``` +Usage: kong vault COMMAND [OPTIONS] + +Vault utilities for Kong. + +Example usage: + TEST=hello kong vault get env/test + +The available commands are: + get Retrieves a value for + +Options: + -c,--conf (optional string) configuration file + -p,--prefix (optional string) override prefix directory + +``` + +--- + + +### kong version + +``` +Usage: kong version [OPTIONS] + +Print Kong's version. With the -a option, will print +the version of all underlying dependencies. + +Options: + -a,--all get version of all dependencies + +``` + +--- + + +[configuration-reference]: /gateway/{{page.kong_version}}/reference/configuration/ diff --git a/src/gateway/reference/configuration.md b/src/gateway/reference/configuration.md new file mode 100644 index 000000000000..108a1a81b8c4 --- /dev/null +++ b/src/gateway/reference/configuration.md @@ -0,0 +1,3673 @@ +--- +# +# WARNING: this file was auto-generated by a script. +# DO NOT edit this file directly. Instead, send a pull request to change +# the files in https://github.com/Kong/docs.konghq.com/tree/main/autodoc-conf-ee +# +title: Configuration Reference for Kong Gateway +source_url: https://github.com/Kong/kong-ee/blob/master/kong.conf.default +--- + + +Reference for {{site.base_gateway}} configuration parameters. Set these parameters in `kong.conf`. + +To learn more about the `kong.conf` file, see the guide on the [Kong Configuration File](/gateway/{{page.kong_version}}/production/kong-conf). + +--- + +## General section + +### prefix + +Working directory. Equivalent to Nginx's prefix path, containing temporary +files and logs. + +Each Kong process must have a separate working directory. + +**Default:** `/usr/local/kong/` + + + +### log_level + +Log level of the Nginx server. Logs are found at `/logs/error.log`. + +See http://nginx.org/en/docs/ngx_core_module.html#error_log for a list of +accepted values. + +**Default:** `notice` + + + +### proxy_access_log + +Path for proxy port request access logs. Set this value to `off` to disable +logging proxy requests. + +If this value is a relative path, it will be placed under the `prefix` +location. + +**Default:** `logs/access.log` + + + +### proxy_error_log + +Path for proxy port request error logs. The granularity of these logs is +adjusted by the `log_level` property. + +**Default:** `logs/error.log` + + + +### proxy_stream_access_log + +Path for tcp streams proxy port access logs. Set this value to `off` to disable +logging proxy requests. + +If this value is a relative path, it will be placed under the `prefix` +location. + +`basic` is defined as `'$remote_addr [$time_local] ' '$protocol $status +$bytes_sent $bytes_received ' '$session_time'` + +**Default:** `logs/access.log basic` + + + +### proxy_stream_error_log + +Path for tcp streams proxy port request error logs. The granularity of these +logs is adjusted by the `log_level` property. + +**Default:** `logs/error.log` + + + +### admin_access_log + +Path for Admin API request access logs. If Hybrid Mode is enabled and the +current node is set to be the Control Plane, then the connection requests from +Data Planes are also written to this file with server name +"kong_cluster_listener". + +Set this value to `off` to disable logging Admin API requests. + +If this value is a relative path, it will be placed under the `prefix` +location. + +**Default:** `logs/admin_access.log` + + + +### admin_error_log + +Path for Admin API request error logs. The granularity of these logs is +adjusted by the `log_level` property. + +**Default:** `logs/error.log` + + + +### status_access_log + +Path for Status API request access logs. The default value of `off` implies +that logging for this API is disabled by default. + +If this value is a relative path, it will be placed under the `prefix` +location. + +**Default:** `off` + + + +### status_error_log + +Path for Status API request error logs. The granularity of these logs is +adjusted by the `log_level` property. + +**Default:** `logs/status_error.log` + + + +### vaults + +Comma-separated list of vaults this node should load. By default, all the +bundled vaults are enabled. + +The specified name(s) will be substituted as such in the Lua namespace: +`kong.vaults.{name}.*`. + +**Default:** `bundled` + + + +### opentelemetry_tracing + +Comma-separated list of tracing instrumentations this node should load. By +default, no instrumentations are enabled. + +Valid values to this setting are: + +- `off`: do not enable instrumentations. +- `request`: only enable request-level instrumentations. +- `all`: enable all the following instrumentations. +- `db_query`: trace database query, including Postgres and Cassandra. +- `dns_query`: trace DNS query. +- `router`: trace router execution, including router rebuilding. +- `http_client`: trace OpenResty HTTP client requests. +- `balancer`: trace balancer retries. +- `plugin_rewrite`: trace plugins iterator execution with rewrite phase. +- `plugin_access`: trace plugins iterator execution with access phase. +- `plugin_header_filter`: trace plugins iterator execution with header_filter + phase. + +**Note:** In the current implementation, tracing instrumentations are not +enabled in stream mode. + +**Default:** `off` + + + +### opentelemetry_tracing_sampling_rate + +Tracing instrumentation sampling rate. + +Tracer samples a fixed percentage of all spans following the sampling rate. + +Example: `0.25`, this should account for 25% of all traces. + +**Default:** `1.0` + + + +### plugins + +Comma-separated list of plugins this node should load. By default, only plugins +bundled in official distributions are loaded via the `bundled` keyword. + +Loading a plugin does not enable it by default, but only instructs Kong to load +its source code, and allows to configure the plugin via the various related +Admin API endpoints. + +The specified name(s) will be substituted as such in the Lua namespace: +`kong.plugins.{name}.*`. + +When the `off` keyword is specified as the only value, no plugins will be +loaded. + +`bundled` and plugin names can be mixed together, as the following examples +suggest: + +- `plugins = bundled,custom-auth,custom-log` will include the bundled plugins + plus two custom ones +- `plugins = custom-auth,custom-log` will *only* include the `custom-auth` and + `custom-log` plugins. +- `plugins = off` will not include any plugins + +**Note:** Kong will not start if some plugins were previously configured (i.e. + +have rows in the database) and are not specified in this list. Before disabling +a plugin, ensure all instances of it are removed before restarting Kong. + +**Note:** Limiting the amount of available plugins can improve P99 latency when +experiencing LRU churning in the database cache (i.e. when the configured +`mem_cache_size`) is full. + +**Default:** `bundled` + + + +### pluginserver_names + +Comma-separated list of names for pluginserver processes. The actual names are +used for log messages and to relate the actual settings. + +**Default:** none + + + +### pluginserver_XXX_socket + +Path to the unix socket used by the pluginserver. + +**Default:** `/.socket` + + + +### pluginserver_XXX_start_cmd + +Full command (including any needed arguments) to start the pluginserver + +**Default:** `/usr/local/bin/` + + + +### pluginserver_XXX_query_cmd + +Full command to "query" the pluginserver. Should produce a JSON with the +dump info of all plugins it manages + +**Default:** `/usr/local/bin/query_` + + + +### port_maps + +With this configuration parameter, you can let the Kong to know about the port +from which the packets are forwarded to it. This is fairly common when running +Kong in a containerized or virtualized environment. + +For example, `port_maps=80:8000, 443:8443` instructs Kong that the port 80 is +mapped to 8000 (and the port 443 to 8443), where 8000 and 8443 are the ports +that Kong is listening to. + +This parameter helps Kong set a proper forwarded upstream HTTP request header +or to get the proper forwarded port with the Kong PDK (in case other means +determining it has failed). It changes routing by a destination port to route by +a port from which packets are forwarded to Kong, and similarly it changes the +default plugin log serializer to use the port according to this mapping instead +of reporting the port Kong is listening to. + +**Default:** none + + + +### anonymous_reports + +Send anonymous usage data such as error stack traces to help improve Kong. + +**Default:** `on` + + +--- + +## Hybrid Mode section + +### role + +Use this setting to enable Hybrid Mode, This allows running some Kong nodes in +a control plane role with a database and have them deliver configuration updates +to other nodes running to DB-less running in a Data Plane role. + +Valid values to this setting are: + +- `traditional`: do not use Hybrid Mode. +- `control_plane`: this node runs in a control plane role. It can use a + database and will deliver configuration updates to data plane nodes. +- `data_plane`: this is a data plane node. It runs DB-less and receives + configuration updates from a control plane node. + +**Default:** `traditional` + + + +### cluster_mtls + +Sets the verification between nodes of the cluster. + +Valid values to this setting are: + +- `shared`: use a shared certificate/key pair specified with the `cluster_cert` + and `cluster_cert_key` settings. Note that CP and DP nodes have to present the + same certificate to establish mTLS connections. +- `pki`: use `cluster_ca_cert`, `cluster_server_name` and `cluster_cert` for + verification. These are different certificates for each DP node, but issued by + a cluster-wide common CA certificate: `cluster_ca_cert`. +- `pki_check_cn` : similar to `pki`, but additionally + checks for the Common Name of the data plane certificate specified in + `cluster_allowed_common_names`. + +**Default:** `shared` + + + +### cluster_cert + +Filename of the cluster certificate to use when establishing secure +communication between control and data plane nodes. + +You can use the `kong hybrid` command to generate the certificate/key pair. + +Under `shared` mode, it must be the same for all nodes. Under `pki` mode it +should be a different certificate for each DP node. + +**Default:** none + + + +### cluster_cert_key + +Filename of the cluster certificate key to use when establishing secure +communication between control and data plane nodes. + +You can use the `kong hybrid` command to generate the certificate/key pair. + +Under `shared` mode, it must be the same for all nodes. Under `pki` mode it +should be a different certificate for each DP node. + +**Default:** none + + + +### cluster_ca_cert + +The trusted CA certificate file in PEM format used for Control Plane to verify +Data Plane's certificate and Data Plane to verify Control Plane's certificate. + +Required on data plane if `cluster_mtls` is set to `pki`. + +If Control Plane certificate is issued by a well known CA, user can set +`lua_ssl_trusted_certificate=system` on Data Plane and leave this field empty. + +This field is ignored if `cluster_mtls` is set to `shared`. + +**Default:** none + + + +### cluster_allowed_common_names + +The list of Common Names that are allowed to connect to the control plane. +Multiple entries may be supplied in a comma-separated string. When not +set, only data planes with the same parent domain as the +control plane cert are allowed to connect. + +This field is ignored if `cluster_mtls` is not set to `pki_check_cn`. + +**Default:** none + + +--- + +## Hybrid Mode Data Plane section + +### cluster_server_name + +The server name used in the SNI of the TLS connection from a DP node to a CP +node. + +Must match the Common Name (CN) or Subject Alternative Name (SAN) found in the +CP certificate. + +If `cluster_mtls` is set to `shared`, this setting is ignored and +`kong_clustering` is used. + +**Default:** none + + + +### cluster_control_plane + +To be used by data plane nodes only: address of the control plane node from +which configuration updates will be fetched, in `host:port` format. + +**Default:** none + + + +### cluster_telemetry_endpoint +{:.badge .enterprise} + +To be used by data plane nodes only: telemetry address of the control plane +node to which telemetry updates will be posted in `host:port` format. + +**Default:** none + + +--- + +## Hybrid Mode Control Plane section + +### cluster_listen + +Comma-separated list of addresses and ports on which the cluster control plane +server should listen for data plane connections. + +The cluster communication port of the control plane must be accessible by all +the data planes within the same cluster. This port is mTLS protected to ensure +end-to-end security and integrity. + +This setting has no effect if `role` is not set to `control_plane`. + +Connection made to this endpoint are logged to the same location as Admin API +access logs. + +See `admin_access_log` config description for more information. + +**Default:** `0.0.0.0:8005` + + + +### cluster_telemetry_listen +{:.badge .enterprise} + +Comma-separated list of addresses and ports on which the cluster control plane +server should listen for data plane telemetry connections. + +The cluster communication port of the control plane must be accessible by all +the data planes within the same cluster. + +This setting has no effect if `role` is not set to `control_plane`. + +**Default:** `0.0.0.0:8006` + + + +### cluster_data_plane_purge_delay + +How many seconds must pass from the time a DP node becomes offline to the time +its entry gets removed from the database, as returned by the +/clustering/data-planes Admin API endpoint. + +This is to prevent the cluster data plane table from growing indefinitely. The +default is set to 14 days. That is, if CP haven't heard from a DP for 14 days, +its entry will be removed. + +**Default:** `1209600` + + + +### cluster_ocsp + +Whether to check for revocation status of DP certificates using OCSP (Online +Certificate Status Protocol). + +If enabled, the DP certificate should contain the "Certificate Authority +Information Access" extension and the OCSP method with URI of which the OCSP +responder can be reached from CP. + +OCSP checks are only performed on CP nodes, it has no effect on DP nodes. + +Valid values to this setting are: + +- `on`: OCSP revocation check is enabled and DP must pass the check in order to + establish connection with CP. +- `off`: OCSP revocation check is disabled. +- `optional`: OCSP revocation check will be attempted, however, if the required + extension is not found inside DP provided certificate or communication with + the OCSP responder failed, then DP is still allowed through. + +**Default:** `off` + + + +### cluster_max_payload + +This sets the maximum payload size allowed to be sent across from CP to DP in +Hybrid mode. + +Default is 4Mb - 4 * 1024 * 1024 due to historical reasons. + +**Default:** `4194304` + + +--- + +## NGINX section + +### proxy_listen + +Comma-separated list of addresses and ports on which the proxy server should +listen for HTTP/HTTPS traffic. + +The proxy server is the public entry point of Kong, which proxies traffic from +your consumers to your backend services. This value accepts IPv4, IPv6, and +hostnames. + +Some suffixes can be specified for each pair: + +- `ssl` will require that all connections made through a particular + address/port be made with TLS enabled. +- `http2` will allow for clients to open HTTP/2 connections to Kong's proxy + server. +- `proxy_protocol` will enable usage of the PROXY protocol for a given + address/port. +- `deferred` instructs to use a deferred accept on Linux (the TCP_DEFER_ACCEPT + socket option). +- `bind` instructs to make a separate bind() call for a given address:port + pair. +- `reuseport` instructs to create an individual listening socket for each + worker process allowing the Kernel to better distribute incoming connections + between worker processes +- `backlog=N` sets the maximum length for the queue of pending TCP connections. + This number should not be too small in order to prevent clients seeing + "Connection refused" error connecting to a busy Kong instance. **Note:** on + Linux, this value is limited by the setting of `net.core.somaxconn` Kernel + parameter. In order for the larger `backlog` set here to take effect it is + necessary to raise `net.core.somaxconn` at the same time to match or exceed + the `backlog` number set. +- `ipv6only=on|off` whether an IPv6 socket listening on a wildcard address [::] + will accept only IPv6 connections or both IPv6 and IPv4 connections. +- `so_keepalive=on|off|[keepidle]:[keepintvl]:[keepcnt]` configures the + “TCP keepalive” behavior for the listening socket. If this parameter is + omitted then the operating system’s settings will be in effect for the socket. + If it is set to the value `on`, the `SO_KEEPALIVE` option is turned + on for the socket. If it is set to the value `off`, the `SO_KEEPALIVE` option + is turned off for the socket. Some operating systems support setting of + TCP keepalive parameters on a per-socket basis using the `TCP_KEEPIDLE`, + `TCP_KEEPINTVL`, and `TCP_KEEPCNT` socket options. + +This value can be set to `off`, thus disabling the HTTP/HTTPS proxy port for +this node. + +If stream_listen is also set to `off`, this enables 'control-plane' mode for +this node (in which all traffic proxying capabilities are disabled). This node +can then be used only to configure a cluster of Kong nodes connected to the same +datastore. + +Example: `proxy_listen = 0.0.0.0:443 ssl, 0.0.0.0:444 http2 ssl` + +See http://nginx.org/en/docs/http/ngx_http_core_module.html#listen for a +description of the accepted formats for this and other `*_listen` values. + +See https://www.nginx.com/resources/admin-guide/proxy-protocol/ for more +details about the `proxy_protocol` parameter. + +Not all `*_listen` values accept all formats specified in nginx's +documentation. + +**Default:** `0.0.0.0:8000 reuseport backlog=16384, 0.0.0.0:8443 http2 ssl reuseport backlog=16384` + + + +### proxy_url + +Kong Proxy URL + +The lookup, or balancer, address for your Kong Proxy nodes. + +This value is commonly used in a microservices or service-mesh oriented +architecture. + +Accepted format (parts in parentheses are optional): + +`://(:(/))` + +Examples: + +- `://:` -> `proxy_url = http://127.0.0.1:8000` +- `SSL ://` -> `proxy_url = https://proxy.domain.tld` +- `:///` -> `proxy_url = http://dev-machine/dev-285` + +By default, Kong Manager, and Kong Portal will use the window request host and +append the resolved listener port depending on the requested protocol. + +**Default:** none + + + +### stream_listen + +Comma-separated list of addresses and ports on which the stream mode should +listen. + +This value accepts IPv4, IPv6, and hostnames. + +Some suffixes can be specified for each pair: + +- `ssl` will require that all connections made through a particular + address/port be made with TLS enabled. +- `proxy_protocol` will enable usage of the PROXY protocol for a given + address/port. +- `bind` instructs to make a separate bind() call for a given address:port + pair. +- `reuseport` instructs to create an individual listening socket for each + worker process allowing the Kernel to better distribute incoming connections + between worker processes +- `backlog=N` sets the maximum length for the queue of pending TCP connections. + This number should not be too small in order to prevent clients seeing + "Connection refused" error connecting to a busy Kong instance. **Note:** on + Linux, this value is limited by the setting of `net.core.somaxconn` Kernel + parameter. In order for the larger `backlog` set here to take effect it is + necessary to raise `net.core.somaxconn` at the same time to match or exceed + the `backlog` number set. +- `ipv6only=on|off` whether an IPv6 socket listening on a wildcard address [::] + will accept only IPv6 connections or both IPv6 and IPv4 connections. +- `so_keepalive=on|off|[keepidle]:[keepintvl]:[keepcnt]` configures the + `TCP keepalive` behavior for the listening socket. If this parameter is + omitted then the operating system’s settings will be in effect for the socket. + If it is set to the value `on`, the `SO_KEEPALIVE` option is turned + on for the socket. If it is set to the value `off`, the `SO_KEEPALIVE` option + is turned off for the socket. Some operating systems support setting of + TCP keepalive parameters on a per-socket basis using the `TCP_KEEPIDLE`, + `TCP_KEEPINTVL`, and `TCP_KEEPCNT` socket options. + +Examples: + +``` +stream_listen = 127.0.0.1:7000 reuseport backlog=16384 +stream_listen = 0.0.0.0:989 reuseport backlog=65536, 0.0.0.0:20 +stream_listen = [::1]:1234 backlog=16384 +``` + +By default this value is set to `off`, thus disabling the stream proxy port for +this node. + +See http://nginx.org/en/docs/stream/ngx_stream_core_module.html#listen for a +description of the formats that Kong might accept in stream_listen. + +**Default:** `off` + + + +### admin_api_uri + +Hierarchical part of a URI which is composed optionally of a host, port, and +path at which the Admin API accepts HTTP or HTTPS traffic. When this config is +disabled, Kong Manager will use the window protocol + host and append the +resolved admin_listen HTTP/HTTPS port. + +**Default:** none + + + +### admin_listen + +Comma-separated list of addresses and ports on which the Admin interface should +listen. + +The Admin interface is the API allowing you to configure and manage Kong. + +Access to this interface should be *restricted* to Kong administrators *only*. +This value accepts IPv4, IPv6, and hostnames. + +Some suffixes can be specified for each pair: + +- `ssl` will require that all connections made through a particular + address/port be made with TLS enabled. +- `http2` will allow for clients to open HTTP/2 connections to Kong's proxy + server. +- `proxy_protocol` will enable usage of the PROXY protocol for a given + address/port. +- `deferred` instructs to use a deferred accept on Linux (the TCP_DEFER_ACCEPT + socket option). +- `bind` instructs to make a separate bind() call for a given address:port + pair. +- `reuseport` instructs to create an individual listening socket for each + worker process allowing the Kernel to better distribute incoming connections + between worker processes +- `backlog=N` sets the maximum length for the queue of pending TCP connections. + This number should not be too small in order to prevent clients seeing + "Connection refused" error connecting to a busy Kong instance. **Note:** on + Linux, this value is limited by the setting of `net.core.somaxconn` Kernel + parameter. In order for the larger `backlog` set here to take effect it is + necessary to raise `net.core.somaxconn` at the same time to match or exceed + the `backlog` number set. +- `ipv6only=on|off` whether an IPv6 socket listening on a wildcard address [::] + will accept only IPv6 connections or both IPv6 and IPv4 connections. +- `so_keepalive=on|off|[keepidle]:[keepintvl]:[keepcnt]` configures the + “TCP keepalive” behavior for the listening socket. If this parameter is + omitted then the operating system’s settings will be in effect for the socket. + If it is set to the value `on`, the `SO_KEEPALIVE` option is turned + on for the socket. If it is set to the value `off`, the `SO_KEEPALIVE` option + is turned off for the socket. Some operating systems support setting of + TCP keepalive parameters on a per-socket basis using the `TCP_KEEPIDLE`, + `TCP_KEEPINTVL`, and `TCP_KEEPCNT` socket options. + +This value can be set to `off`, thus disabling the Admin interface for this +node, enabling a 'data-plane' mode (without configuration capabilities) pulling +its configuration changes from the database. + +Example: `admin_listen = 127.0.0.1:8444 http2 ssl` + +**Default:** `127.0.0.1:8001 reuseport backlog=16384, 127.0.0.1:8444 http2 ssl reuseport backlog=16384` + + + +### status_listen + +Comma-separated list of addresses and ports on which the Status API should +listen. + +The Status API is a read-only endpoint allowing monitoring tools to retrieve +metrics, healthiness, and other non-sensitive information of the current Kong +node. + +The following suffix can be specified for each pair: + +- `ssl` will require that all connections made through a particular + address/port be made with TLS enabled. + +This value can be set to `off`, disabling the Status API for this node. + +Example: `status_listen = 0.0.0.0:8100` + +**Default:** `off` + + + +### nginx_user + +Defines user and group credentials used by worker processes. If group is +omitted, a group whose name equals that of user is used. + +Example: `nginx_user = nginx www` + +**Note**: If the `kong` user and the `kong` group are not available, the +default user and group credentials will be `nobody nobody`. + +**Default:** `kong kong` + + + +### nginx_worker_processes + +Determines the number of worker processes spawned by Nginx. + +See http://nginx.org/en/docs/ngx_core_module.html#worker_processes for detailed +usage of the equivalent Nginx directive and a description of accepted values. + +**Default:** `auto` + + + +### nginx_daemon + +Determines whether Nginx will run as a daemon or as a foreground process. +Mainly useful for development or when running Kong inside a Docker environment. + +See http://nginx.org/en/docs/ngx_core_module.html#daemon. + +**Default:** `on` + + + +### mem_cache_size + +Size of each of the two in-memory caches for database entities. The accepted +units are `k` and `m`, with a minimum recommended value of a few MBs. + +**Note**: As this option controls the size of two different cache entries, the +total memory Kong uses to cache entities might be double this value. + +**Default:** `128m` + + + +### ssl_cipher_suite + +Defines the TLS ciphers served by Nginx. + +Accepted values are `modern`, `intermediate`, `old`, or `custom`. + +See https://wiki.mozilla.org/Security/Server_Side_TLS for detailed descriptions +of each cipher suite. + +**Default:** `intermediate` + + + +### ssl_ciphers + +Defines a custom list of TLS ciphers to be served by Nginx. This list must +conform to the pattern defined by `openssl ciphers`. + +This value is ignored if `ssl_cipher_suite` is not `custom`. + +**Default:** none + + + +### ssl_protocols + +Enables the specified protocols for client-side connections. The set of +supported protocol versions also depends on the version of OpenSSL Kong was +built with. This value is ignored if `ssl_cipher_suite` is not `custom`. + +See http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_protocols + +**Default:** `TLSv1.1 TLSv1.2 TLSv1.3` + + + +### ssl_prefer_server_ciphers + +Specifies that server ciphers should be preferred over client ciphers when +using the SSLv3 and TLS protocols. This value is ignored if `ssl_cipher_suite` +is not `custom`. + +See +http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_prefer_server_ciphers + +**Default:** `on` + + + +### ssl_dhparam + +Defines DH parameters for DHE ciphers from the predefined groups: `ffdhe2048`, +`ffdhe3072`, `ffdhe4096`, `ffdhe6144`, `ffdhe8192`, or from the absolute path to +a parameters file. + +This value is ignored if `ssl_cipher_suite` is `modern` or `intermediate`. The +reason is that `modern` has no ciphers that needs this, and `intermediate` uses +`ffdhe2048`. + +See http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_dhparam + +**Default:** none + + + +### ssl_session_tickets + +Enables or disables session resumption through TLS session tickets. This has no +impact when used with TLSv1.3. + +Kong enables this by default for performance reasons, but it has security +implications: https://github.com/mozilla/server-side-tls/issues/135 + +See http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_session_tickets + +**Default:** `on` + + + +### ssl_session_timeout + +Specifies a time during which a client may reuse the session parameters. See +the rationale: https://github.com/mozilla/server-side-tls/issues/198 + +See http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_session_timeout + +**Default:** `1d` + + + +### ssl_cert + +Comma-separated list of the absolute path to the certificates for +`proxy_listen` values with TLS enabled. + +If more than one certificates are specified, it can be used to provide +alternate type of certificate (for example, ECC certificate) that will be served +to clients that supports them. Note to properly serve using ECC certificates, it +is recommended to also set `ssl_cipher_suite` to `modern` or `intermediate`. + +Unless this option is explicitly set, Kong will auto-generate a pair of default +certificates (RSA + ECC) first time it starts up and use it for serving TLS +requests. + +**Default:** none + + + +### ssl_cert_key + +Comma-separated list of the absolute path to the keys for `proxy_listen` values +with TLS enabled. + +If more than one certificate was specified for `ssl_cert`, then this option +should contain the corresponding key for all certificates provided in the same +order. + +Unless this option is explicitly set, Kong will auto-generate a pair of default +private keys (RSA + ECC) first time it starts up and use it for serving TLS +requests. + +**Default:** none + + + +### client_ssl + +Determines if Nginx should attempt to send client-side TLS certificates and +perform Mutual TLS Authentication with upstream service when proxying requests. + +**Default:** `off` + + + +### client_ssl_cert + +If `client_ssl` is enabled, the absolute path to the client certificate for the +`proxy_ssl_certificate` directive. + +This value can be overwritten dynamically with the `client_certificate` +attribute of the `Service` object. + +**Default:** none + + + +### client_ssl_cert_key + +If `client_ssl` is enabled, the absolute path to the client TLS key for the +`proxy_ssl_certificate_key` directive. + +This value can be overwritten dynamically with the `client_certificate` +attribute of the `Service` object. + +**Default:** none + + + +### admin_ssl_cert + +Comma-separated list of the absolute path to the certificates for +`admin_listen` values with TLS enabled. + +See docs for `ssl_cert` for detailed usage. + +**Default:** none + + + +### admin_ssl_cert_key + +Comma-separated list of the absolute path to the keys for `admin_listen` values +with TLS enabled. + +See docs for `ssl_cert_key` for detailed usage. + +**Default:** none + + + +### status_ssl_cert + +Comma-separated list of the absolute path to the certificates for +`status_listen` values with TLS enabled. + +See docs for `ssl_cert` for detailed usage. + +**Default:** none + + + +### status_ssl_cert_key + +Comma-separated list of the absolute path to the keys for `status_listen` +values with TLS enabled. + +See docs for `ssl_cert_key` for detailed usage. + +**Default:** none + + + +### headers + +Comma-separated list of headers Kong should inject in client responses. + +Accepted values are: + +- `Server`: Injects `Server: kong/x.y.z` on Kong-produced response (e.g. Admin + API, rejected requests from auth plugin). +- `Via`: Injects `Via: kong/x.y.z` for successfully proxied requests. +- `X-Kong-Proxy-Latency`: Time taken (in milliseconds) by Kong to process a + request and run all plugins before proxying the request upstream. +- `X-Kong-Response-Latency`: time taken (in millisecond) by Kong to produce a + response in case of e.g. plugin short-circuiting the request, or in in case of + an error. +- `X-Kong-Upstream-Latency`: Time taken (in milliseconds) by the upstream + service to send response headers. +- `X-Kong-Admin-Latency`: Time taken (in milliseconds) by Kong to process an + Admin API request. +- `X-Kong-Upstream-Status`: The HTTP status code returned by the upstream + service. This is particularly useful for clients to distinguish upstream + statuses if the response is rewritten by a plugin. +- `server_tokens`: Same as specifying both `Server` and `Via`. +- `latency_tokens`: Same as specifying `X-Kong-Proxy-Latency`, + `X-Kong-Response-Latency`, `X-Kong-Admin-Latency` and + `X-Kong-Upstream-Latency` + +In addition to those, this value can be set to `off`, which prevents Kong from +injecting any of the above headers. Note that this does not prevent plugins from +injecting headers of their own. + +Example: `headers = via, latency_tokens` + +**Default:** `server_tokens, latency_tokens` + + + +### trusted_ips + +Defines trusted IP addresses blocks that are known to send correct +`X-Forwarded-*` headers. + +Requests from trusted IPs make Kong forward their `X-Forwarded-*` headers +upstream. + +Non-trusted requests make Kong insert its own `X-Forwarded-*` headers. + +This property also sets the `set_real_ip_from` directive(s) in the Nginx +configuration. It accepts the same type of values (CIDR blocks) but as a +comma-separated list. + +To trust *all* /!\ IPs, set this value to `0.0.0.0/0,::/0`. + +If the special value `unix:` is specified, all UNIX-domain sockets will be +trusted. + +See http://nginx.org/en/docs/http/ngx_http_realip_module.html#set_real_ip_from +for examples of accepted values. + +**Default:** none + + + +### real_ip_header + +Defines the request header field whose value will be used to replace the client +address. + +This value sets the `ngx_http_realip_module` directive of the same name in the +Nginx configuration. + +If this value receives `proxy_protocol`: + +- at least one of the `proxy_listen` entries must have the `proxy_protocol` + flag enabled. +- the `proxy_protocol` parameter will be appended to the `listen` directive of + the Nginx template. + +See http://nginx.org/en/docs/http/ngx_http_realip_module.html#real_ip_header +for a description of this directive. + +**Default:** `X-Real-IP` + + + +### real_ip_recursive + +This value sets the `ngx_http_realip_module` directive of the same name in the +Nginx configuration. + +See http://nginx.org/en/docs/http/ngx_http_realip_module.html#real_ip_recursive +for a description of this directive. + +**Default:** `off` + + + +### error_default_type + +Default MIME type to use when the request `Accept` header is missing and Nginx +is returning an error for the request. + +Accepted values are `text/plain`, `text/html`, `application/json`, and +`application/xml`. + +**Default:** `text/plain` + + + +### upstream_keepalive_pool_size + +Sets the default size of the upstream keepalive connection pools. + +Upstream keepalive connection pools are segmented by the `dst ip/dst port/SNI` +attributes of a connection. + +A value of `0` will disable upstream keepalive connections by default, forcing +each upstream request to open a new connection. + +**Default:** `60` + + + +### upstream_keepalive_max_requests + +Sets the default maximum number of requests than can be proxied upstream +through one keepalive connection. + +After the maximum number of requests is reached, the connection will be closed. + +A value of `0` will disable this behavior, and a keepalive connection can be +used to proxy an indefinite number of requests. + +**Default:** `100` + + + +### upstream_keepalive_idle_timeout + +Sets the default timeout (in seconds) for which an upstream keepalive +connection should be kept open. When the timeout is reached while the connection +has not been reused, it will be closed. + +A value of `0` will disable this behavior, and an idle keepalive connection may +be kept open indefinitely. + +**Default:** `60` + + +--- + +## NGINX Injected Directives section + +Nginx directives can be dynamically injected in the runtime nginx.conf file +without requiring a custom Nginx configuration template. + +All configuration properties respecting the naming scheme +`nginx__` will result in `` being injected in +the Nginx configuration block corresponding to the property's ``. + +Example: `nginx_proxy_large_client_header_buffers = 8 24k` + +Will inject the following directive in Kong's proxy `server {}` block: + +`large_client_header_buffers 8 24k;` + +The following namespaces are supported: + +- `nginx_main_`: Injects `` in Kong's configuration + `main` context. +- `nginx_events_`: Injects `` in Kong's `events {}` + block. +- `nginx_http_`: Injects `` in Kong's `http {}` block. +- `nginx_proxy_`: Injects `` in Kong's proxy `server {}` + block. +- `nginx_upstream_`: Injects `` in Kong's proxy `upstream + {}` block. +- `nginx_admin_`: Injects `` in Kong's Admin API `server + {}` block. +- `nginx_status_`: Injects `` in Kong's Status API + `server {}` block (only effective if `status_listen` is enabled). +- `nginx_stream_`: Injects `` in Kong's stream module + `stream {}` block (only effective if `stream_listen` is enabled). +- `nginx_sproxy_`: Injects `` in Kong's stream module + `server {}` block (only effective if `stream_listen` is enabled). +- `nginx_supstream_`: Injects `` in Kong's stream module + `upstream {}` block. + +As with other configuration properties, Nginx directives can be injected via +environment variables when capitalized and prefixed with `KONG_`. + +Example: `KONG_NGINX_HTTP_SSL_PROTOCOLS` -> `nginx_http_ssl_protocols` + +Will inject the following directive in Kong's `http {}` block: + +`ssl_protocols ;` + +If different sets of protocols are desired between the proxy and Admin API +server, you may specify `nginx_proxy_ssl_protocols` and/or +`nginx_admin_ssl_protocols`, both of which taking precedence over the `http {}` +block. + + + +### nginx_main_worker_rlimit_nofile + +Changes the limit on the maximum number of open files for worker processes. + +The special and default value of `auto` sets this value to `ulimit -n` with the +upper bound limited to 16384 as a measure to protect against excess memory use, +and the lower bound of 1024 as a good default. + +See http://nginx.org/en/docs/ngx_core_module.html#worker_rlimit_nofile + +**Default:** `auto` + + + +### nginx_events_worker_connections + +Sets the maximum number of simultaneous connections that can be opened by a +worker process. + +The special and default value of `auto` sets this value to `ulimit -n` with the +upper bound limited to 16384 as a measure to protect against excess memory use, +and the lower bound of 1024 as a good default. + +See http://nginx.org/en/docs/ngx_core_module.html#worker_connections + +**Default:** `auto` + + + +### nginx_http_client_header_buffer_size + +Sets buffer size for reading the client request headers. + +See +http://nginx.org/en/docs/http/ngx_http_core_module.html#client_header_buffer_size + +**Default:** `1k` + + + +### nginx_http_large_client_header_buffers + +Sets the maximum number and size of buffers used for reading large clients +requests headers. + +See +http://nginx.org/en/docs/http/ngx_http_core_module.html#large_client_header_buffers + +**Default:** `4 8k` + + + +### nginx_http_client_max_body_size + +Defines the maximum request body size allowed by requests proxied by Kong, +specified in the Content-Length request header. If a request exceeds this limit, +Kong will respond with a 413 (Request Entity Too Large). Setting this value to 0 +disables checking the request body size. + +See +http://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size + +**Default:** `0` + + + +### nginx_admin_client_max_body_size + +Defines the maximum request body size for Admin API. + +**Default:** `10m` + + + +### nginx_http_client_body_buffer_size + +Defines the buffer size for reading the request body. If the client request +body is larger than this value, the body will be buffered to disk. Note that +when the body is buffered to disk, Kong plugins that access or manipulate the +request body may not work, so it is advisable to set this value as high as +possible (e.g., set it as high as `client_max_body_size` to force request bodies +to be kept in memory). Do note that high-concurrency environments will require +significant memory allocations to process many concurrent large request bodies. + +See +http://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_buffer_size + +**Default:** `8k` + + + +### nginx_admin_client_body_buffer_size + +Defines the buffer size for reading the request body on Admin API. + +**Default:** `10m` + + + +### nginx_http_lua_regex_match_limit + +Global `MATCH_LIMIT` for PCRE regex matching. The default of `100000` should +ensure at worst any regex Kong executes could finish within roughly 2 seconds. + +**Default:** `100000` + + +--- + +## Datastore section + +Kong can run with a database to store coordinated data between Kong nodes in a +cluster, or without a database, where each node stores its information +independently in memory. + +When using a database, Kong will store data for all its entities (such as +Routes, Services, Consumers, and Plugins) in a database, and +all Kong nodes belonging to the same cluster must connect themselves to the same +database. + +When not using a database, Kong is said to be in "DB-less mode": it will keep +its entities in memory, and each node needs to have this data entered via a +declarative configuration file, which can be specified through the +`declarative_config` property, or via the Admin API using the `/config` +endpoint. + +When using Postgres as the backend storage, you can optionally enable Kong to +serve read queries from a separate database instance. + +When the number of proxies is large, this can greatly reduce the load on the +main Postgres instance and achieve better scalability. It may also reduce the +latency jitter if the Kong proxy node's latency to the main Postgres instance is +high. + +The read-only Postgres instance only serves read queries and write queries +still goes to the main connection. The read-only Postgres instance can be +eventually consistent while replicating changes from the main instance. + +At least the `pg_ro_host` config is needed to enable this feature. + +By default, all other database config for the read-only connection are +inherited from the corresponding main connection config described above but may +be optionally overwritten explicitly using the `pg_ro_*` config below. + + + +### database + +Determines which of PostgreSQL or Cassandra this node will use as its +datastore. + +Accepted values are `postgres`, `cassandra`, and `off`. + +**Default:** `postgres` + + + + +### Postgres settings + +name | description | default +-|--|- +**pg_host** | Host of the Postgres server. | `127.0.0.1` +**pg_port** | Port of the Postgres server. | `5432` +**pg_timeout** | Defines the timeout (in ms), for connecting, reading and writing. | `5000` +**pg_user** | Postgres user. | `kong` +**pg_password** | Postgres user's password. | none +**pg_database** | The database name to connect to. | `kong` +**pg_schema** | The database schema to use. If unspecified, Kong will respect the `search_path` value of your PostgreSQL instance. | none +**pg_ssl** | Toggles client-server TLS connections between Kong and PostgreSQL. Because PostgreSQL uses the same port for TLS and non-TLS, this is only a hint. If the server does not support TLS, the established connection will be a plain one. | `off` +**pg_ssl_version** | When using ssl between Kong and PostgreSQL, the version of tls to use. Accepted values are `tlsv1`, `tlsv1_2`, or `tlsv1_3`. | `tlsv1` +**pg_ssl_required** | When `pg_ssl` is on this determines if TLS must be used between Kong and PostgreSQL. It aborts the connection if the server does not support SSL connections. | `off` +**pg_ssl_verify** | Toggles server certificate verification if `pg_ssl` is enabled. See the `lua_ssl_trusted_certificate` setting to specify a certificate authority. | `off` +**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. | none +**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. | none +**pg_max_concurrent_queries** | Sets the maximum number of concurrent queries that can be executing at any given time. This limit is enforced per worker process; the total number of concurrent queries for this node will be will be: `pg_max_concurrent_queries * nginx_worker_processes`. The default value of 0 removes this concurrency limitation. | `0` +**pg_semaphore_timeout** | Defines the timeout (in ms) after which PostgreSQL query semaphore resource acquisition attempts will fail. Such failures will generally result in the associated proxy or Admin API request failing with an HTTP 500 status code. Detailed discussion of this behavior is available in the online documentation. | `60000` +**pg_keepalive_timeout** | Defines the time in milliseconds that an idle connection to PostreSQL server will be kept alive. | `60000` +**pg_ro_host** | Same as `pg_host`, but for the read-only connection. **Note:** Refer to the documentation section above for detailed usage. | none +**pg_ro_port** | Same as `pg_port`, but for the read-only connection. | `` +**pg_ro_timeout** | Same as `pg_timeout`, but for the read-only connection. | `` +**pg_ro_user** | Same as `pg_user`, but for the read-only connection. | `` +**pg_ro_password** | Same as `pg_password`, but for the read-only connection. | `` +**pg_ro_database** | Same as `pg_database`, but for the read-only connection. | `` +**pg_ro_schema** | Same as `pg_schema`, but for the read-only connection. | `` +**pg_ro_ssl** | Same as `pg_ssl`, but for the read-only connection. | `` +**pg_ro_ssl_required** | Same as `pg_ssl_required`, but for the read-only connection. | `` +**pg_ro_ssl_verify** | Same as `pg_ssl_verify`, but for the read-only connection. | `` +**pg_ro_ssl_version** | Same as `pg_ssl_version`, but for the read-only connection. | `` +**pg_ro_max_concurrent_queries** | Same as `pg_max_concurrent_queries`, but for the read-only connection. Note: read-only concurrency is not shared with the main (read-write) connection. | `` +**pg_ro_semaphore_timeout** | Same as `pg_semaphore_timeout`, but for the read-only connection. | `` +**pg_ro_keepalive_timeout** | Same as `pg_keepalive_timeout`, but for the read-only connection. | `` + +### Cassandra settings + + +{% include_cached /md/enterprise/cassandra-deprecation.md %} + + +name | description | default +-|--|- +**cassandra_contact_points** | A comma-separated list of contact points to your cluster. You may specify IP addresses or hostnames. Note that the port component of SRV records will be ignored in favor of `cassandra_port`. When connecting to a multi-DC cluster, ensure that contact points from the local datacenter are specified first in this list. | `127.0.0.1` +**cassandra_port** | The port on which your nodes are listening on. All your nodes and contact points must listen on the same port. Will be created if it doesn't exist. | `9042` +**cassandra_keyspace** | The keyspace to use in your cluster. | `kong` +**cassandra_write_consistency** | Consistency setting to use when writing to the Cassandra cluster. | `ONE` +**cassandra_read_consistency** | Consistency setting to use when reading from the Cassandra cluster. | `ONE` +**cassandra_timeout** | Defines the timeout (in ms) for reading and writing. | `5000` +**cassandra_ssl** | Toggles client-to-node TLS connections between Kong and Cassandra. | `off` +**cassandra_ssl_verify** | Toggles server certificate verification if `cassandra_ssl` is enabled. See the `lua_ssl_trusted_certificate` setting to specify a certificate authority. | `off` +**cassandra_username** | Username when using the `PasswordAuthenticator` scheme. | `kong` +**cassandra_password** | Password when using the `PasswordAuthenticator` scheme. | none +**cassandra_lb_policy** | Load balancing policy to use when distributing queries across your Cassandra cluster. Accepted values are: `RoundRobin`, `RequestRoundRobin`, `DCAwareRoundRobin`, and `RequestDCAwareRoundRobin`. Policies prefixed with "Request" make efficient use of established connections throughout the same request. Prefer "DCAware" policies if and only if you are using a multi-datacenter cluster. | `RequestRoundRobin` +**cassandra_local_datacenter** | When using the `DCAwareRoundRobin` or `RequestDCAwareRoundRobin` load balancing policy, you must specify the name of the local (closest) datacenter for this Kong node. | none +**cassandra_refresh_frequency** | Frequency (in seconds) at which the cluster topology will be checked for new or decommissioned nodes. A value of `0` will disable this check, and the cluster topology will never be refreshed. | `60` +**cassandra_repl_strategy** | When migrating for the first time, Kong will use this setting to create your keyspace. Accepted values are `SimpleStrategy` and `NetworkTopologyStrategy`. | `SimpleStrategy` +**cassandra_repl_factor** | When migrating for the first time, Kong will create the keyspace with this replication factor when using the `SimpleStrategy`. | `1` +**cassandra_data_centers** | When migrating for the first time, will use this setting when using the `NetworkTopologyStrategy`. The format is a comma-separated list made of `:`. | `dc1:2,dc2:3` +**cassandra_schema_consensus_timeout** | Defines the timeout (in ms) for the waiting period to reach a schema consensus between your Cassandra nodes. This value is only used during migrations. | `10000` + +### declarative_config + +The path to the declarative configuration file which holds the specification of +all entities (Routes, Services, Consumers, etc.) to be used when the `database` +is set to `off`. + +Entities are stored in Kong's in-memory cache, so you must ensure that enough +memory is allocated to it via the `mem_cache_size` property. You must also +ensure that items in the cache never expire, which means that `db_cache_ttl` +should preserve its default value of 0. + +If the Hybrid mode `role` is set to `data_plane` and there's no configuration +cache file, this configuration is used before connecting to the Control Plane +node as a user-controlled fallback. + +**Default:** none + + + +### declarative_config_string + +The declarative configuration as a string + +**Default:** none + + + +### declarative_config_encryption_mode + +Set encryption of the declarative config mapped file on filesystem. + +`aes-256-gcm` = Use AES-256-GCM to encrypt `chacha20-poly1305` = Use +chacha20-poly1305 to encrypt `off` = does not encrypt + +**Default:** none + + +--- + +## Datastore Cache section + +In order to avoid unnecessary communication with the datastore, Kong caches +entities (such as APIs, Consumers, Credentials...) for a configurable period of +time. It also handles invalidations if such an entity is updated. + +This section allows for configuring the behavior of Kong regarding the caching +of such configuration entities. + + + +### db_update_frequency + +Frequency (in seconds) at which to check for updated entities with the +datastore. + +When a node creates, updates, or deletes an entity via the Admin API, other +nodes need to wait for the next poll (configured by this value) to eventually +purge the old cached entity and start using the new one. + +**Default:** `5` + + + +### db_update_propagation + +Time (in seconds) taken for an entity in the datastore to be propagated to +replica nodes of another datacenter. + +When in a distributed environment such as a multi-datacenter Cassandra cluster, +this value should be the maximum number of seconds taken by Cassandra to +propagate a row to other datacenters. + +When set, this property will increase the time taken by Kong to propagate the +change of an entity. + +Single-datacenter setups or PostgreSQL servers should suffer no such delays, +and this value can be safely set to 0. + +**Default:** `0` + + + +### db_cache_ttl + +Time-to-live (in seconds) of an entity from the datastore when cached by this +node. + +Database misses (no entity) are also cached according to this setting if you do +not configure `db_cache_neg_ttl`. + +If set to 0 (default), such cached entities or misses never expire. + +**Default:** `0` + + + +### db_cache_neg_ttl + +Time-to-live (in seconds) of a datastore miss (no entity). + +If not specified (default), `db_cache_ttl` value will be used instead. + +If set to 0, misses will never expire. + +**Default:** none + + + +### db_resurrect_ttl + +Time (in seconds) for which stale entities from the datastore should be +resurrected for when they cannot be refreshed (e.g., the datastore is +unreachable). When this TTL expires, a new attempt to refresh the stale entities +will be made. + +**Default:** `30` + + + +### db_cache_warmup_entities + +Entities to be pre-loaded from the datastore into the in-memory cache at Kong +start-up. + +This speeds up the first access of endpoints that use the given entities. + +When the `services` entity is configured for warmup, the DNS entries for values +in its `host` attribute are pre-resolved asynchronously as well. + +Cache size set in `mem_cache_size` should be set to a value large enough to +hold all instances of the specified entities. + +If the size is insufficient, Kong will log a warning. + +**Default:** `services` + + +--- + +## DNS Resolver section + +By default, the DNS resolver will use the standard configuration files +`/etc/hosts` and `/etc/resolv.conf`. The settings in the latter file will be +overridden by the environment variables `LOCALDOMAIN` and `RES_OPTIONS` if they +have been set. + +Kong will resolve hostnames as either `SRV` or `A` records (in that order, and +`CNAME` records will be dereferenced in the process). + +In case a name was resolved as an `SRV` record it will also override any given +port number by the `port` field contents received from the DNS server. + +The DNS options `SEARCH` and `NDOTS` (from the `/etc/resolv.conf` file) will be +used to expand short names to fully qualified ones. So it will first try the +entire `SEARCH` list for the `SRV` type, if that fails it will try the `SEARCH` +list for `A`, etc. + +For the duration of the `ttl`, the internal DNS resolver will loadbalance each +request it gets over the entries in the DNS record. For `SRV` records the +`weight` fields will be honored, but it will only use the lowest `priority` +field entries in the record. + + + +### dns_resolver + +Comma separated list of nameservers, each entry in `ip[:port]` format to be +used by Kong. If not specified the nameservers in the local `resolv.conf` file +will be used. + +Port defaults to 53 if omitted. Accepts both IPv4 and IPv6 addresses. + +**Default:** none + + + +### dns_hostsfile + +The hosts file to use. This file is read once and its content is static in +memory. + +To read the file again after modifying it, Kong must be reloaded. + +**Default:** `/etc/hosts` + + + +### dns_order + +The order in which to resolve different record types. The `LAST` type means the +type of the last successful lookup (for the specified name). The format is a +(case insensitive) comma separated list. + +**Default:** `LAST,SRV,A,CNAME` + + + +### dns_valid_ttl + +By default, DNS records are cached using the TTL value of a response. If this +property receives a value (in seconds), it will override the TTL for all +records. + +**Default:** none + + + +### dns_stale_ttl + +Defines, in seconds, how long a record will remain in cache past its TTL. This +value will be used while the new DNS record is fetched in the background. + +Stale data will be used from expiry of a record until either the refresh query +completes, or the `dns_stale_ttl` number of seconds have passed. + +**Default:** `4` + + + +### dns_cache_size + +Defines the maximum allowed number of DNS records stored in memory cache. + +Least recently used DNS records are discarded from cache if it is full. Both +errors and data are cached, therefore a single name query can easily take up +10-15 slots. + +**Default:** `10000` + + + +### dns_not_found_ttl + +TTL in seconds for empty DNS responses and "(3) name error" responses. + +**Default:** `30` + + + +### dns_error_ttl + +TTL in seconds for error responses. + +**Default:** `1` + + + +### dns_no_sync + +If enabled, then upon a cache-miss every request will trigger its own dns +query. + +When disabled multiple requests for the same name/type will be synchronised to +a single query. + +**Default:** `off` + + +--- + +## Tuning & Behavior section + +### worker_consistency + +Defines whether this node should rebuild its state synchronously or +asynchronously (the balancers and the router are rebuilt on updates that affects +them, e.g., updates to Routes, Services or Upstreams, via the Admin API or +loading a declarative configuration file). (This option is deprecated and will +be removed in future releases. The new default is `eventual`.) + +Accepted values are: + +- `strict`: the router will be rebuilt synchronously, causing incoming requests + to be delayed until the rebuild is finished. (This option is deprecated and + will be removed in future releases. The new default is `eventual`) +- `eventual`: the router will be rebuilt asynchronously via a recurring + background job running every second inside of each worker. + +Note that `strict` ensures that all workers of a given node will always proxy +requests with an identical router, but that increased long tail latency can be +observed if frequent Routes and Services updates are expected. + +Using `eventual` will help preventing long tail latency issues in such cases, +but may cause workers to route requests differently for a short period of time +after Routes and Services updates. + +**Default:** `eventual` + + + +### worker_state_update_frequency + +Defines how often the worker state changes are checked with a background job. +When a change is detected, a new router or balancer will be built, as needed. +Raising this value will decrease the load on database servers and result in less +jitter in proxy latency, but it might take more time to propagate changes to +each individual worker. + +**Default:** `5` + + +--- + +## Miscellaneous section + +Additional settings inherited from lua-nginx-module allowing for more +flexibility and advanced usage. + +See the lua-nginx-module documentation for more information: +https://github.com/openresty/lua-nginx-module + + + +### lua_ssl_trusted_certificate + +Comma-separated list of paths to certificate authority files for Lua cosockets +in PEM format. + +The special value `system` attempts to search for the "usual default" provided +by each distro, according to an arbitrary heuristic. In the current +implementation, The following pathnames will be tested in order, and the first +one found will be used: + +- /etc/ssl/certs/ca-certificates.crt (Debian/Ubuntu/Gentoo) +- /etc/pki/tls/certs/ca-bundle.crt (Fedora/RHEL 6) +- /etc/ssl/ca-bundle.pem (OpenSUSE) +- /etc/pki/tls/cacert.pem (OpenELEC) +- /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem (CentOS/RHEL 7) +- /etc/ssl/cert.pem (OpenBSD, Alpine) + +`system` can be used by itself or in conjunction with other CA filepaths. + +When `pg_ssl_verify` or `cassandra_ssl_verify` are enabled, these certificate +authority files will be used for verifying Kong's database connections. + +See https://github.com/openresty/lua-nginx-module#lua_ssl_trusted_certificate + +**Default:** `system` + + + +### lua_ssl_verify_depth + +Sets the verification depth in the server certificates chain used by Lua +cosockets, set by `lua_ssl_trusted_certificate`. + +This includes the certificates configured for Kong's database connections. + +If the maximum depth is reached before reaching the end of the chain, +verification will fail. This helps mitigate certificate based DoS attacks. + +See https://github.com/openresty/lua-nginx-module#lua_ssl_verify_depth + +**Default:** `1` + + + +### lua_ssl_protocols + +Defines the TLS versions supported when handshaking with OpenResty's TCP +cosocket APIs. + +This affects connections made by Lua code, such as connections to the database +Kong uses, or when sending logs using a logging plugin. It does *not* affect +connections made to the upstream Service or from downstream clients. + +**Default:** `TLSv1.1 TLSv1.2 TLSv1.3` + + + +### lua_package_path + +Sets the Lua module search path (LUA_PATH). Useful when developing or using +custom plugins not stored in the default search path. + +See https://github.com/openresty/lua-nginx-module#lua_package_path + +**Default:** `./?.lua;./?/init.lua;` + + + +### lua_package_cpath + +Sets the Lua C module search path (LUA_CPATH). + +See https://github.com/openresty/lua-nginx-module#lua_package_cpath + +**Default:** none + + + +### lua_socket_pool_size + +Specifies the size limit for every cosocket connection pool associated with +every remote server. + +See https://github.com/openresty/lua-nginx-module#lua_socket_pool_size + +**Default:** `30` + + + +### enforce_rbac +{:.badge .enterprise} + +Specifies whether Admin API RBAC is enforced. + +Accepts one of `entity`, `both`, `on`, or `off`. + +- `on`: only endpoint-level authorization is enforced. +- `entity`: entity-level authorization applies. +- `both`: enables both endpoint and entity-level authorization. +- `off`: disables both endpoint and entity-level authorization. + +When enabled, Kong will deny requests to the Admin API when a nonexistent or +invalid RBAC authorization token is passed, or the RBAC user with which the +token is associated does not have permissions to access/modify the requested +resource. + +**Default:** `off` + + + +### rbac_auth_header +{:.badge .enterprise} + +Defines the name of the HTTP request header from which the Admin API will +attempt to authenticate the RBAC user. + +**Default:** `Kong-Admin-Token` + + + +### event_hooks_enabled +{:.badge .enterprise} + +When enabled, event hook entities represent a relationship between an event +(source and event) and an action (handler). Similar to web hooks, event hooks +can be used to communicate Kong Gateway service events. When a particular event +happens on a service, the event hook calls a URL with information about that +event. Event hook configurations differ depending on the handler. The events +that are triggered send associated data. + +See: https://docs.konghq.com/gateway/latest/admin-api/event-hooks/reference/ + +**Default:** `on` + + +--- + +## Kong Manager section + +The Admin GUI for Kong Enterprise. + + + +### admin_gui_listen +{:.badge .free} + +Kong Manager Listeners + +Comma-separated list of addresses and ports on which Kong will expose Kong +Manager. This web application lets you configure and manage Kong, and therefore +should be kept secured. + +Suffixes can be specified for each pair, similarly to the `admin_listen` +directive. + +**Default:** `0.0.0.0:8002, 0.0.0.0:8445 ssl` + + + +### admin_gui_url +{:.badge .free} + +Kong Manager URL + +The lookup, or balancer, address for Kong Manager. + +Accepted format (items in parentheses are optional): + +`://(:(/))` + +Examples: + +- `http://127.0.0.1:8003` +- `https://kong-admin.test` +- `http://dev-machine/dev-285` + +By default, Kong Manager will use the window request host and append the +resolved listener port depending on the requested protocol. + +**Default:** none + + + +### admin_gui_ssl_cert +{:.badge .free} + +The absolute path to the SSL certificate for `admin_gui_listen` values with SSL +enabled. + +**Default:** none + + + +### admin_gui_ssl_cert_key +{:.badge .free} + +The absolute path to the SSL key for `admin_gui_listen` values with SSL +enabled. + +**Default:** none + + + +### admin_gui_flags +{:.badge .free} + +Alters the layout Admin GUI (JSON) The only supported value is `{ +"IMMUNITY_ENABLED": true }` to enable Kong Immunity in the Admin GUI. + +**Default:** `{}` + + + +### admin_gui_access_log +{:.badge .free} + +Kong Manager Access Logs + +Here you can set an absolute or relative path for Kong Manager access logs. +When the path is relative, logs are placed in the `prefix` location. + +Setting this value to `off` disables access logs for Kong Manager. + +**Default:** `logs/admin_gui_access.log` + + + +### admin_gui_error_log +{:.badge .free} + +Kong Manager Error Logs + +Here you can set an absolute or relative path for Kong Manager access logs. +When the path is relative, logs are placed in the `prefix` location. + +Setting this value to `off` disables error logs for Kong Manager. + +Granularity can be adjusted through the `log_level` directive. + +**Default:** `logs/admin_gui_error.log` + + + +### admin_gui_auth +{:.badge .enterprise} + +Kong Manager Authentication Plugin Name + +Secures access to Kong Manager by specifying an authentication plugin to use. + +Supported Plugins: + +- `basic-auth`: Basic Authentication plugin +- `ldap-auth-advanced`: LDAP Authentication plugin +- `openid-connect`: OpenID Connect Authentication plugin + +**Default:** none + + + +### admin_gui_auth_conf +{:.badge .enterprise} + +Kong Manager Authentication Plugin Config (JSON) + +Specifies the configuration for the authentication plugin specified in +`admin_gui_auth`. + +For information about Plugin Configuration consult the associated plugin +documentation. + +Example for `basic-auth`: + +`admin_gui_auth_conf = { "hide_credentials": true }` + +**Default:** none + + + +### admin_gui_auth_password_complexity +{:.badge .enterprise} + +Kong Manager Authentication Password Complexity (JSON) + +When `admin_gui_auth = basic-auth`, this property defines the rules required +for Kong Manager passwords. Choose from preset rules or write your own. + +Example using preset rules: + +`admin_gui_auth_password_complexity = { "kong-preset": "min_8" }` + +All values for kong-preset require the password to contain characters from at +least three of the following categories: + +1. Uppercase characters (A through Z) + +2. Lowercase characters (a through z) + +3. Base-10 digits (0 through 9) + +4. Special characters (for example, &, $, #, %) + +Supported preset rules: + +- `min_8`: minimum length of 8 +- `min_12`: minimum length of 12 +- `min_20`: minimum length of 20 + +To write your own rules, see +https://manpages.debian.org/jessie/passwdqc/passwdqc.conf.5.en.html. + +NOTE: Only keywords "min", "max" and "passphrase" are supported. + +Example: + +`admin_gui_auth_password_complexity = { "min": "disabled,24,11,9,8" }` + +**Default:** none + + + +### admin_gui_session_conf +{:.badge .enterprise} + +Kong Manager Session Config (JSON) + +Specifies the configuration for the Session plugin as used by Kong Manager. + +For information about plugin configuration, consult the Kong Session plugin +documentation. + +Example: + +``` +admin_gui_session_conf = { "cookie_name": "kookie", \ + "secret": "changeme" } +``` + +**Default:** none + + + +### admin_gui_auth_header +{:.badge .enterprise} + +Defines the name of the HTTP request header from which the Admin API will +attempt to identify the Kong Admin user. + +**Default:** `Kong-Admin-User` + + + +### admin_gui_auth_login_attempts +{:.badge .enterprise} + +Number of times a user can attempt to login to Kong Manager. 0 means infinite +attempts allowed. + +**Default:** `0` + + + +### admin_gui_header_txt +{:.badge .free} + +Kong Manager Header Text Sets text for Kong Manager Header Banner. Header +Banner is not shown if this config is empty. + +**Default:** none + + + +### admin_gui_header_bg_color +{:.badge .free} + +Kong Manager Header Background Color Sets background color for Kong Manager +Header Banner Accepts css color keyword, #-hexadecimal or rgb format. Invalid +values are ignored by Manager. + +**Default:** none + + + +### admin_gui_header_txt_color +{:.badge .free} + +Kong Manager Header Text Color Sets text color for Kong Manager Header Banner. + +Accepts css color keyword, #-hexadecimal or rgb format. Invalid values are +ignored by Kong Manager. + +**Default:** none + + + +### admin_gui_footer_txt +{:.badge .free} + +Kong Manager Footer Text Sets text for Kong Manager Footer Banner. Footer +Banner is not shown if this config is empty + +**Default:** none + + + +### admin_gui_footer_bg_color +{:.badge .free} + +Kong Manager Footer Background Color Sets background color for Kong Manager +Footer Banner. + +Accepts css color keyword, #-hexadecimal or rgb format. Invalid values are +ignored by Manager. + +**Default:** none + + + +### admin_gui_footer_txt_color +{:.badge .free} + +Kong Manager Footer Text Color Sets text color for Kong Manager Footer Banner. + +Accepts css color keyword, #-hexadecimal or rgb format. Invalid values are +ignored by Kong Manager. + +**Default:** none + + + +### admin_gui_login_banner_title +{:.badge .free} + +Kong Manager Login Banner Title Text Sets title text for Kong Manager Login +Banner. + +Login Banner is not shown if both `admin_gui_login_banner_title` and +`admin_gui_login_banner_body` are empty. + +**Default:** none + + + +### admin_gui_login_banner_body +{:.badge .free} + +Kong Manager Login Banner Body Text Sets body text for Kong Manager Login +Banner. + +Login Banner is not shown if both `admin_gui_login_banner_title` and +`admin_gui_login_banner_body` are empty. + +**Default:** none + + +--- + +## Vitals section + +### vitals +{:.badge .enterprise} + +When enabled, Kong will store and report metrics about its performance. + +When running Kong in a multi-node setup, `vitals` entails two separate meanings +depending on the node. + +On a Proxy-only node, `vitals` determines whether to collect data for Vitals. + +On an Admin-only node, `vitals` determines whether to display Vitals metrics +and visualizations on the dashboard. + +**Default:** `on` + + + +### vitals_strategy +{:.badge .enterprise} + +Determines whether to use the Kong database (either PostgreSQL or Cassandra, as +defined by the `database` config value above), or a separate storage engine, for +Vitals metrics. + +Accepted values are `database`, `prometheus`, or `influxdb`. + +**Default:** `database` + + + +### vitals_tsdb_address +{:.badge .enterprise} + +Defines the host and port of the TSDB server to which Vitals data is written +and read. + +This value is only applied when the `vitals_strategy` option is set to +`prometheus` or `influxdb`. This value accepts IPv4, IPv6, and hostname values. + +If the `vitals_strategy` is set to `prometheus`, this value determines the +address of the Prometheus server from which Vitals data will be read. For +`influxdb` strategies, this value controls both the read and write source for +Vitals data. + +**Default:** none + + + +### vitals_tsdb_user +{:.badge .enterprise} + +Influxdb user + +**Default:** none + + + +### vitals_tsdb_password +{:.badge .enterprise} + +Influxdb password + +**Default:** none + + + +### vitals_statsd_address +{:.badge .enterprise} + +Defines the host and port (and an optional protocol) of the StatsD server to +which Kong should write Vitals metics. This value is only applied when the +`vitals_strategy` is set to `prometheus`. This value accepts IPv4, IPv6, and, +hostnames. Additionally, the suffix `tcp` can be specified; doing so will result +in Kong sending StatsD metrics via TCP instead of the UDP (default). + +**Default:** none + + + +### vitals_statsd_prefix +{:.badge .enterprise} + +Defines the prefix value attached to all Vitals StatsD events. This prefix is +useful when writing metrics to a multi-tenant StatsD exporter or server. + +**Default:** `kong` + + + +### vitals_statsd_udp_packet_size +{:.badge .enterprise} + +Defines the maximum buffer size in which Vitals statsd metrics will be held and +sent in batches. + +This value is defined in bytes. + +**Default:** `1024` + + + +### vitals_prometheus_scrape_interval +{:.badge .enterprise} + +Defines the scrape_interval query parameter sent to the Prometheus server when +reading Vitals data. + +This should be same as the scrape interval (in seconds) of the Prometheus +server. + +**Default:** `5` + + +--- + +## Konnect section + +### konnect_mode + +When enabled, the dataplane is connected to Konnect + +**Default:** `off` + + +--- + +## Analytics For Konnect section + +### analytics_flush_interval + +Determine the frequency of flushing local data to Konnect in seconds. + +**Default:** `1` + + + +### analytics_buffer_size_limit + +Max number of messages can be buffered locally before dropping data in case +there is no network connection to Konnect. + +**Default:** `100000` + + +--- + +## Developer Portal section + +### portal +{:.badge .enterprise} + +Developer Portal Switch + +When enabled: + +Kong will expose the Dev Portal interface and read-only APIs on the +`portal_gui_listen` address, and endpoints on the Admin API to manage assets. + +When enabled along with `portal_auth`: + +Kong will expose management endpoints for developer accounts on the Admin API +and the Dev Portal API. + +**Default:** `off` + + + +### portal_gui_listen +{:.badge .enterprise} + +Developer Portal GUI Listeners + +Comma-separated list of addresses on which Kong will expose the Developer +Portal GUI. Suffixes can be specified for each pair, similarly to the +`admin_listen` directive. + +**Default:** `0.0.0.0:8003, 0.0.0.0:8446 ssl` + + + +### portal_gui_protocol +{:.badge .enterprise} + +Developer Portal GUI protocol + +The protocol used in conjunction with `portal_gui_host` to construct the +lookup, or balancer address for your Kong Proxy nodes. + +Examples: `http`,`https` + +**Default:** `http` + + + +### portal_gui_host +{:.badge .enterprise} + +Developer Portal GUI host + +The host used in conjunction with `portal_gui_protocol` to construct the +lookup, or balancer address for your Kong Proxy nodes. + +Examples: + +- `:` -> `portal_gui_host = 127.0.0.1:8003` +- `` -> `portal_gui_host = portal_api.domain.tld` +- `/` -> `portal_gui_host = dev-machine/dev-285` + +**Default:** `127.0.0.1:8003` + + + +### portal_cors_origins +{:.badge .enterprise} + +Developer Portal CORS Origins + +A comma separated list of allowed domains for `Access-Control-Allow-Origin` +header. This can be used to resolve CORS issues in custom networking +environments. + +Examples: + +- list of domains: `portal_cors_origins = http://localhost:8003, + https://localhost:8004` +- single domain: `portal_cors_origins = http://localhost:8003` +- all domains: `portal_cors_origins = *` + +NOTE: In most cases, the Developer Portal is able to derive valid CORS origins +by using `portal_gui_protocol`, `portal_gui_host`, and if applicable, +`portal_gui_use_subdomains`. In these cases, `portal_cors_origins` is not needed +and can remain unset. + +**Default:** none + + + +### portal_gui_use_subdomains +{:.badge .enterprise} + +Developer Portal GUI subdomain toggle + +By default Kong Portal uses the first namespace in the request path to +determine workspace. By turning `portal_gui_subdomains` on, Kong Portal will +expect workspace to be included in the request url as a subdomain. + +Example (off): - `:////` -> +`http://kong-portal.com/example-workspace/index` + +Example (on): - `://.` -> +`http://example-workspace.kong-portal.com/index` + +**Default:** `off` + + + +### portal_gui_ssl_cert +{:.badge .enterprise} + +Developer Portal GUI SSL Certificate + +The absolute path to the SSL certificate for `portal_gui_listen` values with +SSL enabled. + +**Default:** none + + + +### portal_gui_ssl_cert_key +{:.badge .enterprise} + +Developer Portal GUI SSL Certificate Key + +The absolute path to the SSL key for `portal_gui_listen` values with SSL +enabled. + +**Default:** none + + + +### portal_gui_access_log +{:.badge .enterprise} + +Developer Portal GUI Access Log location + +Here you can set an absolute or relative path for your Portal GUI access logs. + +Setting this value to `off` will disable logging Portal GUI access logs. + +When using relative pathing, logs will be placed under the `prefix` location. + +**Default:** `logs/portal_gui_access.log` + + + +### portal_gui_error_log +{:.badge .enterprise} + +Developer Portal GUI Error Log location + +Here you can set an absolute or relative path for your Portal GUI error logs. + +Setting this value to `off` will disable logging Portal GUI error logs. + +When using relative pathing, logs will be placed under the `prefix` location. + +Granularity can be adjusted through the `log_level` directive. + +**Default:** `logs/portal_gui_error.log` + + + +### portal_api_listen +{:.badge .enterprise} + +Developer Portal API Listeners + +Comma-separated list of addresses on which Kong will expose the Developer +Portal API. Suffixes can be specified for each pair, similarly to the +`admin_listen` directive. + +**Default:** `0.0.0.0:8004, 0.0.0.0:8447 ssl` + + + +### portal_api_url +{:.badge .enterprise} + +Developer Portal API URL + +The lookup, or balancer, address for your Developer Portal nodes. + +This value is commonly used in a microservices or service-mesh oriented +architecture. + +`portal_api_url` is the address on which your Kong Dev Portal API is accessible +by Kong. You should only set this value if your Kong Dev Portal API lives on a +different node than your Kong Proxy. + +Accepted format (parts in parenthesis are optional): + +`://(:(/))` + +Examples: + +- `://:` -> `portal_api_url = http://127.0.0.1:8003` +- `SSL ://` -> `portal_api_url = + https://portal_api.domain.tld` +- `:///` -> `portal_api_url = + http://dev-machine/dev-285` + +By default this value points to the local interface: + +- `http://0.0.0.0:8004` + +**Default:** none + + + +### portal_api_ssl_cert +{:.badge .enterprise} + +Developer Portal API SSL Certificate + +The absolute path to the SSL certificate for `portal_api_listen` values with +SSL enabled. + +**Default:** none + + + +### portal_api_ssl_cert_key +{:.badge .enterprise} + +Developer Portal API SSL Certificate Key + +The absolute path to the SSL key for `portal_api_listen` values with SSL +enabled. + +**Default:** none + + + +### portal_api_access_log +{:.badge .enterprise} + +Developer Portal API Access Log location + +Here you can set an absolute or relative path for your Portal API access logs. + +Setting this value to `off` will disable logging Portal API access logs. + +When using relative pathing, logs will be placed under the `prefix` location. + +**Default:** `logs/portal_api_access.log` + + + +### portal_api_error_log +{:.badge .enterprise} + +Developer Portal API Error Log location + +Here you can set an absolute or relative path for your Portal API error logs. + +Setting this value to `off` will disable logging Portal API error logs. + +When using relative pathing, logs will be placed under the `prefix` location. + +Granularity can be adjusted through the `log_level` directive. + +**Default:** `logs/portal_api_error.log` + + + +### portal_is_legacy +{:.badge .enterprise} + +Developer Portal legacy support + +Setting this value to `on` will cause all new portals to render using the +legacy rendering system by default. + +Setting this value to `off` will cause all new portals to render using the +current rendering system. + +**Default:** `off` + + + +### portal_app_auth +{:.badge .enterprise} + +Developer Portal application registration auth provider and strategy. Must be +set to enable application_registration plugin Currently accepts kong-oauth2 or +external-oauth2 + +**Default:** `kong-oauth2` + + +--- + +## Default Developer Portal Authentication section + +Referenced on workspace creation to set Dev Portal authentication defaults in +the database for that particular workspace. + + + +### portal_auth +{:.badge .enterprise} + +Developer Portal Authentication Plugin Name + +Specifies the authentication plugin to apply to your Developer Portal. +Developers will use the specified form of authentication to request access, +register, and login to your Developer Portal. + +Supported Plugins: + +- Basic Authentication: `portal_auth = basic-auth` +- OIDC Authentication: `portal_auth = openid-connect` + +**Default:** none + + + +### portal_auth_password_complexity +{:.badge .enterprise} + +Kong Portal Authentication Password Complexity (JSON) + +When portal_auth = basic-auth, this property defines the rules required for +Kong Portal passwords. Choose from preset rules or write your own. + +Example using preset rules: + +`portal_auth_password_complexity = { "kong-preset": "min_8" }` + +All values for kong-preset require the password to contain characters from at +least three of the following categories: + +1. Uppercase characters (A through Z) + +2. Lowercase characters (a through z) + +3. Base-10 digits (0 through 9) + +4. Special characters (for example, &, $, #, %) + +Supported preset rules: + +- `min_8`: minimum length of 8 +- `min_12`: minimum length of 12 +- `min_20`: minimum length of 20 + +To write your own rules, see +https://manpages.debian.org/jessie/passwdqc/passwdqc.conf.5.en.html. + +NOTE: Only keywords "min", "max" and "passphrase" are supported. + +Example: + +`portal_auth_password_complexity = { "min": "disabled,24,11,9,8" }` + +**Default:** none + + + +### portal_auth_conf +{:.badge .enterprise} + +Developer Portal Authentication Plugin Config (JSON) + +Specifies the plugin configuration object in JSON format to be applied to your +Developer Portal authentication. + +For information about Plugin Configuration consult the associated plugin +documentation. + +Example for `basic-auth`: + +`portal_auth_conf = { "hide_credentials": true }` + +**Default:** none + + + +### portal_auth_login_attempts +{:.badge .enterprise} + +Number of times a user can attempt to login to the Dev Portal before password +must be reset. + +0 (default) means infinite attempts allowed. + +Note: Any value greater than 0 will only affect Dev Portals secured with +basic-auth. + +**Default:** `0` + + + +### portal_session_conf +{:.badge .enterprise} + +Portal Session Config (JSON) + +Specifies the configuration for the Session plugin as used by Kong Portal. + +For information about Plugin Configuration consult the Kong Session Plugin +documentation. + +Example: + +``` +portal_session_conf = { "cookie_name": "portal_session", \ + "secret": "changeme", \ + "storage": "kong" } +``` + +**Default:** none + + + +### portal_auto_approve +{:.badge .enterprise} + +Developer Portal Auto Approve Access + +When set to `on`, a developer will automatically be marked as "approved" after +completing registration. Access can still be revoked through Kong Manager or the +Admin API. + +When set to `off`, a Kong admin will have to manually approve the Developer +using Kong Manager or the Admin API. + +**Default:** `off` + + + +### portal_token_exp +{:.badge .enterprise} + +Duration in seconds for the expiration of the Dev Portal reset password token. +Default is `21600` (six hours). + +**Default:** `21600` + + + +### portal_email_verification +{:.badge .enterprise} + +Portal Developer Email Verification. + +When enabled Developers will receive an email upon registration to verify their +account. Developers will not be able to use the Developer Portal until they +verify their account, even if auto-approve is enabled. + +Note: SMTP must be turned on in order to use this feature. + +**Default:** `off` + + +--- + +## Default Portal Smtp Configuration section + +Referenced on workspace creation to set SMTP defaults in the database for that +particular workspace. + + + +### portal_invite_email +{:.badge .enterprise} + +When enabled, Kong admins can invite developers to a Dev Portal by using the +Invite button in Kong Manager. + +The email looks like the following: + +``` +Subject: Invite to access Dev Portal + +Hello Developer! + +You have been invited to create a Dev Portal account at %s. + +Please visit `` to create your account. + +**Default:** `on` +``` + + + +### portal_access_request_email +{:.badge .enterprise} + +When enabled, Kong admins specified by `smtp_admin_emails` will receive an +email when a developer requests access to a Dev Portal. + +When disabled, Kong admins will have to manually check the Kong Manager to view +any requests. + +The email looks like the following: + +``` +Subject: Request to access Dev Portal + +Hello Admin! + + has requested Dev Portal access for . + +Please visit to review this request. + +**Default:** `on` +``` + + + +### portal_approved_email +{:.badge .enterprise} + +When enabled, developers will receive an email when access to a Dev Portal has +been approved. + +When disabled, developers will receive no indication that they have +beenapproved. It is suggested to only disable this feature if +`portal_auto_approve` is enabled. + +The email looks like the following: + +``` +Subject: Dev Portal access approved + + +Hello Developer! You have been approved to access . + +Please visit to login. +``` + +**Default:** `on` + + + +### portal_reset_email +{:.badge .enterprise} + +When enabled, developers will be able to use the Reset Password flow on a Dev +Portal and will receive an email with password reset instructions. + +When disabled, developers will *not* be able to reset their account passwords. +Kong Admins will have to manually create new credentials for the Developer in +the Kong Manager. + +The email looks like the following: + +``` +Subject: Password Reset Instructions for Dev Portal . + + +Hello Developer, + +Please click the link below to reset your Dev Portal password. + + + +This link will expire in + +If you didn't make this request, keep your account secure by clicking the link +above to change your password. +``` + +**Default:** `on` + + + +### portal_reset_success_email +{:.badge .enterprise} + +When enabled, developers will receive an email after successfully resetting +their Dev Portal account password. + +When disabled, developers will still be able to reset their account passwords, +but will not receive a confirmation email. + +The email looks like the following: + +``` +Subject: Dev Portal password change success + + +Hello Developer, We are emailing you to let you know that your Dev Portal +password at has been changed. + +Click the link below to sign in with your new credentials. + + +``` + +**Default:** `on` + + + +### portal_application_status_email +{:.badge .enterprise} + +When enabled, developers will receive an email when the status changes for +their appliciation service requests. + +When disabled, developers will still be able to view the status in their +developer portal application page. + +The email looks like the following: + +``` +Subject: Dev Portal application request () + + +Hello Developer, We are emailing you to let you know that your request for +application access from the Developer Portal account at is +. + +Application: Service: + +You will receive another email when your access has been approved. +``` + +**Default:** `off` + + + +### portal_application_request_email +{:.badge .enterprise} + +When enabled, Kong admins specified by `smtp_admin_emails` will receive an +email when a developer requests access to service through an application. + +When disabled, Kong admins will have to manually check the Kong Manager to view +any requests. + +By default, `smtp_admin_emails` will be the recipients. + +This can be overriden by `portal_smtp_admin_emails`, which can be set +dynamically per workspace through the Admin API. + +The email looks like the following: + +``` +Subject: Request to access Dev Portal () service from + + +Hello Admin, + + () has requested application access for +. + +Requested workspace: Requested application: +Requested service: + +Please visit + to +review this request. +``` + +**Default:** `off` + + + +### portal_emails_from +{:.badge .enterprise} + +The name and email address for the `From` header included in all Dev Portal +emails. + +Example: `portal_emails_from = Your Name ` + +Note: Some SMTP servers will not use this value, but instead insert the email +and name associated with the account. + +**Default:** none + + + +### portal_emails_reply_to +{:.badge .enterprise} + +Email address for the `Reply-To` header for portal emails + +Example: `portal_emails_reply_to = example@example.com` + +Note: Some SMTP servers will not use this value, but instead insert the email +associated with the account. + +**Default:** none + + + +### portal_smtp_admin_emails +{:.badge .enterprise} + +Comma separated list of admin emails to receive +portal notifications. Can be dynamically set per workspace through the Admin +API. + +If not set, `smtp_admin_emails` will be used. + +Example `admin1@example.com, admin2@example.com` + +**Default:** none + + +--- + +## Admin Smtp Configuration section + +### admin_emails_from +{:.badge .enterprise} + +The email address for the `From` header for admin emails. + +**Default:** `""` + + + +### admin_emails_reply_to +{:.badge .enterprise} + +Email address for the `Reply-To` header for admin emails. + +**Default:** none + + + +### admin_invitation_expiry +{:.badge .enterprise} + +Expiration time for the admin invitation link (in seconds). 0 means no +expiration. + +Example, 72 hours: `72 * 60 * 60 = 259200` + +**Default:** `259200` + + +--- + +## General Smtp Configuration section + +### smtp_mock +{:.badge .enterprise} + +This flag will mock the sending of emails. This can be used for testing before +the SMTP client is fully configured. + +**Default:** `on` + + + +### smtp_host +{:.badge .enterprise} + +The hostname of the SMTP server to connect to. + +**Default:** `localhost` + + + +### smtp_port +{:.badge .enterprise} + +The port number on the SMTP server to connect to. + +**Default:** `25` + + + +### smtp_starttls +{:.badge .enterprise} + +When set to `on`, STARTTLS is used to encrypt communication with the SMTP +server. This is normally used in conjunction with port 587. + +**Default:** `off` + + + +### smtp_username +{:.badge .enterprise} + +Username used for authentication with SMTP server + +**Default:** none + + + +### smtp_password +{:.badge .enterprise} + +Password used for authentication with SMTP server + +**Default:** none + + + +### smtp_ssl +{:.badge .enterprise} + +When set to `on`, SMTPS is used to encrypt communication with the SMTP server. +This is normally used in conjunction with port 465. + +**Default:** `off` + + + +### smtp_auth_type +{:.badge .enterprise} + +The method used to authenticate with the SMTP server Valid options are `plain`, +`login`, or `nil` + +**Default:** none + + + +### smtp_domain +{:.badge .enterprise} + +The domain used in the `EHLO` connection and part of the `Message-ID` header + +**Default:** `localhost.localdomain` + + + +### smtp_timeout_connect +{:.badge .enterprise} + +The timeout (in milliseconds) for connecting to the SMTP server. + +**Default:** `60000` + + + +### smtp_timeout_send +{:.badge .enterprise} + +The timeout (in milliseconds) for sending data to the SMTP server. + +**Default:** `60000` + + + +### smtp_timeout_read +{:.badge .enterprise} + +The timeout (in milliseconds) for reading data from the SMTP server. + +**Default:** `60000` + + + +### smtp_admin_emails +{:.badge .enterprise} + +Comma separated list of admin emails to receive notifications. + +Example `admin1@example.com, admin2@example.com` + +**Default:** none + + +--- + +## Data & Admin Audit section + +When enabled, Kong will store detailed audit data regarding Admin API and +database access. In most cases, updates to the database are associated with +Admin API requests. As such, database object audit log data is tied to a given +HTTP via a unique identifier, providing built-in association of Admin API and +database traffic. + + + +### audit_log + +When enabled, Kong will log information about Admin API access and database row +insertions, updates, and deletes. + +**Default:** `off` + + + +### audit_log_ignore_methods + +Comma-separated list of HTTP methods that will not generate audit log entries. +By default, all HTTP requests will be logged. + +**Default:** none + + + +### audit_log_ignore_paths + +Comma-separated list of request paths that will not generate audit log entries. +By default, all HTTP requests will be logged. + +**Default:** none + + + +### audit_log_ignore_tables + +Comma-separated list of database tables that will not generate audit log +entries. By default, updates to all database tables will be logged (the term +"updates" refers to the creation, update, or deletion of a row). + +**Default:** none + + + +### audit_log_payload_exclude + +Comma-separated list of keys that will be filtered out of the payload. Keys +that were filtered will be recorded in the audit log. + +**Default:** `token, secret, password` + + + +### audit_log_record_ttl + +Length, in seconds, of the TTL for audit log records. Records in the database +older than their TTL are automatically purged. + +Example, 30 days: `30 * 24 * 60 * 60 = 2592000` + +**Default:** `2592000` + + + +### audit_log_signing_key + +Defines the path to a private RSA signing key that can be used to insert a +signature of audit records, adjacent to the record. The corresponding public key +should be stored offline, and can be used the validate audit entries in the +future. If this value is undefined, no signature will be generated. + +**Default:** none + + +--- + +## Granular Tracing section + +{:.warning} +> **Deprecation warning**: Granular tracing is deprecated. This +means the feature will eventually be removed. +Our target for Granular tracing removal is the Kong Gateway 4.0 release. + +Granular tracing offers a mechanism to expose metrics and detailed debug data +about the lifecycle of Kong in a human- or machine-consumable format. + + + +### tracing +{:.badge .enterprise} + +When enabled, Kong will generate granular debug data about various portions of +the request lifecycle, such as DB or DNS queries, plugin execution, core handler +timing, etc. + +**Default:** `off` + + + +### tracing_write_strategy +{:.badge .enterprise} + +Defines how Kong will write tracing data at the conclusion of the request. The +default option, `file`, writes a human-readable depiction of tracing data to a +configurable location on the node's file system. Other strategies write tracing +data as a JSON document to the configured endpoint. Valid entries for this +option are `file`, `file_raw`, `http`, `tcp`, `tls`, and `udp`. + +**Default:** `file` + + + +### tracing_write_endpoint +{:.badge .enterprise} + +Defines the endpoint to which tracing data will be written. + +- For the `file` and `file_raw` tracing write strategies, this value must be a + valid location on the node's file system to which Kong must have write access. +- For the `tcp`, `tls`, and `udp` strategies, this value is defined as a string + in the form of: `:` +- For the `http` strategy, this value is defined in the form of: + `://(:(/))` + +Traces sent via HTTP are delivered via POST method with an `application/json` +Content-Type. + +**Default:** none + + + +### tracing_time_threshold +{:.badge .enterprise} + +The minimum time, in microseconds, over which a trace must execute in order to +write the trace data to the configured endpoint. This configuration can be used +to lower the noise present in trace data by removing trace objects that are not +interesting from a timing perspective. The default value of `0` removes this +limitation, causing traces of any duration to be written. + +**Default:** `0` + + + +### tracing_types +{:.badge .enterprise} + +Defines the types of traces that are written. + +Trace types not defined in this list are ignored, regardless of their lifetime. +The default special value of `all` results in all trace types being written, +regardless of type. + +The following trace types are included: + +- `query`: trace the database query +- `legacy_query`: (deprecated) trace the database query with legacy DAO +- `router`: trace Kong routing the request; internal routing time +- `balancer`: trace the execution of the overall balancer phase +- `balancer.getPeer`: trace Kong selecting an upstream peer from the + ring-balancer +- `balancer.toip`: trace balancer to resolve peer's host to IP +- `connect.toip`: trace cosocket to resolve target's host to IP +- `access.before`: trace the preprocessing of access phase, like parameter + parsing, route matching, and balance preparation +- `access.after`: trace the postprocess of access phase, like balancer + execution and internal variable assigning +- `cassandra_iterate`: trace Cassandra driver to paginate over results +- `plugin`: trace plugins phase handlers + +**Default:** `all` + + + +### tracing_debug_header +{:.badge .enterprise} + +Defines the name of the HTTP request header that must be present in order to +generate traces within a request. Setting this value provides a mechanism to +selectively generate request traces at the client's request. Note that the value +of the header does not matter, only that the header is present in the request. +When this value is not set and tracing is enabled, Kong will generate trace data +for all requests flowing through the proxy and Admin API. Note that data from +certificate handling phases is not logged when this setting is enabled. + +**Default:** none + + + +### generate_trace_details +{:.badge .enterprise} + +When enabled, Kong will write context- specific details into traces. Trace +details offer more data about the context of the trace. This can significantly +increase the size of trace reports. Note also that trace details may contain +potentially sensitive information, such as raw SQL queries; care should be taken +to store traces properly when this option is enabled. + +**Default:** `off` + + +--- + +## Route Collision Detection/Prevention section + +### route_validation_strategy +{:.badge .enterprise} + +The strategy used to validate routes when creating or updating them. + +Different strategies are available to tune how to enforce splitting traffic of +workspaces. + +- `smart` is the default option and uses the algorithm described in + https://docs.konghq.com/gateway/latest/kong-enterprise/workspaces/#important-note-conflicting-services-or-routes-in-workspaces +- `off` disables any check +- `path` enforces routes to comply with the pattern described in config + enforce_route_path_pattern + +**Default:** `smart` + + + +### enforce_route_path_pattern +{:.badge .enterprise} + +Specifies the Lua pattern which will be enforced on the `paths` attribute of a +Route object. You can also add a placeholder for the workspace in the pattern, +which will be rendered during runtime based on the workspace to which the +`route` belongs. + +This setting is only relevant if `route_validation_strategy` is set to `path`. + +Example For Pattern `/$(workspace)/v%d/.*` valid paths are: + +1. `/group1/v1/` if route belongs to workspace `group1`. + +2. `/group2/v1/some_path` if route belongs to workspace `group2`. + +**Default:** none + + +--- + +## Database Encryption & Keyring Management section + +When enabled, Kong will transparently encrypt sensitive fields, such as +Consumer credentials, TLS private keys, and RBAC user tokens, among others. A +full list of encrypted fields is available from the Kong Enterprise +documentation site. + +Encrypted data is transparently decrypted before being displayed to the Admin +API or made available to plugins or core routing logic. + +While this feature is GA, do note that we currently do not provide normal +semantic versioning compatibility guarantees on the keyring feature's APIs in +that Kong may make a breaking change to the feature in a minor version. Also +note that mis-management of keyring data may result in irrecoverable data loss. + + + +### keyring_enabled +{:.badge .enterprise} + +When enabled, Kong will encrypt sensitive field values before writing them to +the database, and subsuquently decrypt them when retrieving data for the Admin +API, Developer Portal, or proxy business logic. Symmetric encryption keys are +managed based on the strategy defined below. + +**Default:** `off` + + + +### keyring_strategy +{:.badge .enterprise} + +Defines the strategy implementation by which Kong nodes will manage symmetric +encryption keys. Please see the Kong Enterprise documentation for a detailed +description of each strategies. Acceptable values for this option are 'cluster' +and 'vault'. + +**Default:** `cluster` + + + +### keyring_public_key +{:.badge .enterprise} + +Defines the filesystem path at which the public key of an RSA keypair resides. +This keypair is used for symmetric keyring import/ export, e.g., for disaster +recovery and optional bootstrapping. + +**Default:** none + + + +### keyring_private_key +{:.badge .enterprise} + +Defines the filesystem path at which the private key of an RSA keypair resides. +This keypair is used for symmetric keyring import/ export, e.g., for disaster +recovery and optional bootstrapping. + +**Default:** none + + + +### keyring_recovery_public_key +{:.badge .enterprise} + +Defines the filesystem path at which the public +key to optionally encrypt all keyring materials and backup in the database. + +**Default:** none + + + +### keyring_blob_path +{:.badge .enterprise} + +Defines the filesystem path at which Kong will backup the initial keyring +material. + +This option is useful largely for development purposes. + +**Default:** none + + + +### keyring_vault_host +{:.badge .enterprise} + +Defines the Vault host at which Kong will fetch the encryption material. This +value should be defined in the format: + +`://:` + +**Default:** none + + + +### keyring_vault_mount +{:.badge .enterprise} + +Defines the name of the Vault v2 KV secrets engine at which symmetric keys are +found. + +**Default:** none + + + +### keyring_vault_path +{:.badge .enterprise} + +Defines the names of the Vault v2 KV path at which symmetric keys are found. + +**Default:** none + + + +### keyring_vault_token +{:.badge .enterprise} + +Defines the token value used to communicate with the v2 KV Vault HTTP(S) API. + +**Default:** none + + + +### untrusted_lua + +Controls loading of Lua functions from admin-supplied sources such as the Admin +API. LuaJIT bytecode loading is always disabled. + +**Warning:** LuaJIT is not designed as a secure runtime for running malicious +code, therefore you should properly protect your Admin API endpoint even with +sandboxing enabled. The sandbox only provides protection against trivial +attackers or unintentional modification of the Kong global environment. + +Accepted values are: `off`, `sandbox`, or `on`: + +* `off`: Disallow loading of any arbitrary Lua functions. The `off` option +disables any functionality that runs arbitrary Lua code, including the +Serverless Functions plugins and any transformation plugin that allows custom +Lua functions. + +* `sandbox`: Allow loading of Lua functions, but use a sandbox when executing +them. The sandboxed function has restricted access to the global environment and +only has access to standard Lua functions that will generally not cause harm to +the Kong Gateway node. + +* `on`: Functions have unrestricted access to the global environment and can +load any Lua modules. This is similar to the behavior in Kong Gateway prior to +2.3.0. + +The default `sandbox` environment does not allow importing other modules or +libraries, or executing anything at the OS level (for example, file read/write). +The global environment is also not accessible. + +Examples of `untrusted_lua = sandbox` behavior: + +* You can't access or change global values such as +`kong.configuration.pg_password` * You can run harmless lua: `local foo = 1 + +1`. However, OS level functions are not allowed, like: `os.execute('rm -rf +/*')`. + +For a full allowed/disallowed list, see: +https://github.com/kikito/sandbox.lua/blob/master/sandbox.lua + +To customize the sandbox environment, use the `untrusted_lua_sandbox_requires` +and `untrusted_lua_sandbox_environment` parameters below. + +**Default:** `sandbox` + + + +### untrusted_lua_sandbox_requires + +Comma-separated list of modules allowed to be loaded with `require` inside the +sandboxed environment. Ignored if `untrusted_lua` is not `sandbox`. + +For example, say you have configured the Serverless pre-function plugin and it +contains the following `requires`: + +``` +local template = require "resty.template" +local split = require "kong.tools.utils".split +``` + +To run the plugin, add the modules to the allowed list: + +``` +untrusted_lua_sandbox_requires = resty.template, kong.tools.utils +``` + +**Warning:** Allowing certain modules may create opportunities to escape the +sandbox. For example, allowing `os` or `luaposix` may be unsafe. + +**Default:** none + + + +### untrusted_lua_sandbox_environment + +Comma-separated list of global Lua variables that should be made available +inside the sandboxed environment. Ignored if `untrusted_lua` is not `sandbox`. + +**Warning**: Certain variables, when made available, may create opportunities +to escape the sandbox. + +**Default:** none + + + +### openresty_path + +Path to the OpenResty installation that Kong will use. When this is empty (the +default), Kong determines the OpenResty installation by searching for a +system-installed OpenResty and falling back to searching $PATH for the nginx +binary. + +Setting this attribute disables the search behavior and explicitly instructs +Kong which OpenResty installation to use. + +**Default:** none + + + + + +[Penlight]: http://stevedonovan.github.io/Penlight/api/index.html +[pl.template]: http://stevedonovan.github.io/Penlight/api/libraries/pl.template.html +[templates]: https://github.com/kong/kong/tree/master/kong/templates diff --git a/src/gateway/reference/faq.md b/src/gateway/reference/faq.md new file mode 100644 index 000000000000..317847f1f12f --- /dev/null +++ b/src/gateway/reference/faq.md @@ -0,0 +1,16 @@ +--- +title: FAQ +--- + +Can't find what you're looking for on this page? Let us know at team-docs@konghq.com. + +### Kong crashes on start (MDB_CORRUPTED) + +**Q:** I receive the following error when starting Kong: +``` +2022/04/11 12:01:07 [crit] 32790#0: *7 [lua] init.lua:648: init_worker(): worker initialization error: failed to create and open LMDB database: MDB_CORRUPTED: Located page was wrong type; this node must be restarted, context: init_worker_by_lua* +``` + +**A:** Your local configuration cache is corrupted. Remove your LMDB cache (located at `/dbless.lmdb`, which is usually `/usr/local/kong/dbless.lmdb`) and start Kong again. This will force your Kong node to pull configuration from the control plane rather than using the cache. + +--- \ No newline at end of file diff --git a/src/gateway/reference/nginx-directives.md b/src/gateway/reference/nginx-directives.md new file mode 100644 index 000000000000..404a70fbaaa4 --- /dev/null +++ b/src/gateway/reference/nginx-directives.md @@ -0,0 +1,199 @@ +--- +title: Nginx Directives +content-type: reference +--- + +### Injecting individual Nginx directives + +Entries in `kong.conf` that are prefixed with `nginx_http_`, +`nginx_proxy_` or `nginx_admin_` are converted to Nginx +directives. + +- Entries prefixed with `nginx_http_` will be injected into the overall `http` +block directive. + +- Entries prefixed with `nginx_proxy_` will be injected into the `server` block +directive handling {{site.base_gateway}}'s proxy ports. + +- Entries prefixed with `nginx_admin_` will be injected into the `server` block +directive handling {{site.base_gateway}}'s Admin API ports. + +For example, if you add the following line to your `kong.conf` file: + +``` +nginx_proxy_large_client_header_buffers=16 128k +``` + +It adds the following directive to the proxy `server` block of {{site.base_gateway}}'s +Nginx configuration: + +``` +large_client_header_buffers 16 128k; +``` + +These directives can also be specified +using [environment variables](/gateway/latest/production/environment-variables). For +example, if you declare an environment variable like this: + +```bash +export KONG_NGINX_HTTP_OUTPUT_BUFFERS="4 64k" +``` + +This results in the following Nginx directive being added to the `http` +block: + +``` +output_buffers 4 64k; +``` + +For more details on the Nginx configuration file structure and block +directives, see the [Nginx reference](https://nginx.org/en/docs/beginners_guide.html#conf_structure). + +For a list of Nginx directives, see the [Nginx directives index](https://nginx.org/en/docs/dirindex.html). + +### Including files via injected Nginx directives + +Complex configurations may require adding new `server` blocks to an Nginx configuration. +You can inject `include` directives into an Nginx configuration that point to Nginx settings files. + +For example, if you create a file called `my-server.kong.conf` with +the following contents: + +``` +# custom server +server { + listen 2112; + location / { + # ...more settings... + return 200; + } +} +``` + +You can make the {{site.base_gateway}} node serve this port by adding the following +entry to your `kong.conf` file: + +``` +nginx_http_include = /path/to/your/my-server.kong.conf +``` + +You can also use environment variables: + +```bash +export KONG_NGINX_HTTP_INCLUDE="/path/to/your/my-server.kong.conf" +``` + +When you start {{site.base_gateway}}, the `server` section from that file will be added to +that file, meaning that the custom server defined in it will be responding, +alongside the regular {{site.base_gateway}} ports: + +```bash +curl -I http://127.0.0.1:2112 +HTTP/1.1 200 OK +... +``` + +If you use a relative path in an `nginx_http_include` property, that +path will be interpreted relative to the value of the `prefix` property of +your `kong.conf` file (or the value of the `-p` flag of `kong start` if you +used it to override the prefix when starting {{site.base_gateway}}). + +## Custom Nginx templates and embedding {{site.base_gateway}} + +You can use custom Nginx +configuration templates directly in two cases: + +- You need to modify {{site.base_gateway}}'s default +Nginx configuration. Specifically values that are not adjustable in `kong.conf`, you can modify the template used by {{site.base_gateway}} for producing its +Nginx configuration and launch {{site.base_gateway}} using your customized template. + +- You need to embed {{site.base_gateway}} in an already running OpenResty instance, you +can reuse {{site.base_gateway}}'s generated configuration and include it in your existing +configuration. + +### Custom Nginx templates + +{{site.base_gateway}} can be started, reloaded and restarted with an `--nginx-conf` argument, +which must specify an Nginx configuration template. Such a template uses the +[Penlight][Penlight] [templating engine][pl.template], which is compiled using +the {{site.base_gateway}} configuration. + +The following Lua functions are available in the [templating engine][pl.template]: + +- `pairs`, `ipairs` +- `tostring` +- `os.getenv` + +The default template for +{{site.base_gateway}} can be found using this command on the system +running your {{site.base_gateway}} instance: +`find / -type d -name "templates" | grep kong`. +For open-source {{site.base_gateway}}, you can also see the +[templates directory][templates]. + +The template is split in two +Nginx configuration files: `nginx.lua` and `nginx_kong.lua`. The former is +minimal and includes the latter, which contains everything {{site.base_gateway}} requires +to run. When `kong start` runs, right before starting Nginx, it copies these +two files into the prefix directory, which looks like so: + +``` +/usr/local/kong +├── nginx-kong.conf +└── nginx.conf +``` + +If you must tweak global settings that are defined by {{site.base_gateway}} but not adjustable +via the {{site.base_gateway}} configuration in `kong.conf`, you can inline the contents of the +`nginx_kong.lua` configuration template into a custom template file (in this +example called `custom_nginx.template`) like this: + +``` +# --------------------- +# custom_nginx.template +# --------------------- + +worker_processes ${{ "{{NGINX_WORKER_PROCESSES" }}}}; # can be set by kong.conf +daemon ${{ "{{NGINX_DAEMON" }}}}; # can be set by kong.conf + +pid pids/nginx.pid; # this setting is mandatory +error_log logs/error.log ${{ "{{LOG_LEVEL" }}}}; # can be set by kong.conf + +events { + use epoll; # a custom setting + multi_accept on; +} + +http { + + # contents of the nginx_kong.lua template follow: + + resolver ${{ "{{DNS_RESOLVER" }}}} ipv6=off; + charset UTF-8; + error_log logs/error.log ${{ "{{LOG_LEVEL" }}}}; + access_log logs/access.log; + + ... # etc +} +``` + +You can then start {{site.base_gateway}} with: + +```bash +kong start -c kong.conf --nginx-conf custom_nginx.template +``` + + +## More information + +* [Embedding {{site.base_gateway}} in OpenResty](/gateway/latest/production/kong-openresty) +* [How to use `kong.conf`](/gateway/latest/production/kong-conf) +* [How to serve an API and a website with Kong](/gateway/latest/production/website-api-serving) + + +--- + + +[Penlight]: http://stevedonovan.github.io/Penlight/api/index.html +[pl.template]: http://stevedonovan.github.io/Penlight/api/libraries/pl.template.html +[templates]: https://github.com/kong/kong/tree/master/kong/templates diff --git a/src/gateway/reference/performance-testing-framework.md b/src/gateway/reference/performance-testing-framework.md new file mode 100644 index 000000000000..dc9385be0959 --- /dev/null +++ b/src/gateway/reference/performance-testing-framework.md @@ -0,0 +1,257 @@ +--- +title: Performance Testing Framework Reference +badge: oss +content_type: reference +--- + +### perf.use_defaults() + +*syntax: perf.use_defaults()* + +Use default parameters. This function sets the following: +- Looks up `PERF_TEST_DRIVER` environment variable and invokes `perf.use_driver`. +- Looks up `PERF_TEST_TERRAFORM_PROVIDER` if `PERF_TEST_DRIVER` is `terraform`; please see `perf.use_driver` for +environment variables that can be passed to each provider. +- Invokes `perf.set_log_level` and sets level to `"debug"`. +- Set retry count to 3. +- Looks up `PERF_TEST_USE_DAILY_IMAGE` environment variable and passes the variable to driver options. + +### perf.use_driver + +*syntax: perf.use_driver(name, options?)* + +Uses driver name, which must be one of "local", "docker" or "terraform". Additional +parameters for the driver can be specified in options as a Lua table. Throws error if any. + +The Docker and Terraform driver expect an options parameter to contain the following keys : + +- **use_daily_image**: a boolean to decide whether to use daily image or not; useful when testing +unreleased commits on master branch; downloading Enterprise daily images requires a valid Docker +login. + +The Terraform driver expects options to contain the following optional keys: + +- **provider** The service provider name, right now only "equinix-metal". +- **tfvars** Terraform variables as a Lua table as follows; environment variables are only used if `perf.use_defaults()` is called. + +|Provider | tfvars key | environment variable key | description | default | +|---|---|---|---|---| +|equinix-metal | `metal_project_id` | PERF_TEST_METAL_PROJECT_ID | The project ID that instances belong to. | | +|equinix-metal | `metal_auth_token` | PERF_TEST_METAL_AUTH_TOKEN | Equinix authentication token. | | +|equinix-metal | `metal_plan` | PERF_TEST_METAL_PLAN | Instance size. | `"c3.small.x86"` | +|equinix-metal | `metal_os` | PERF_TEST_METAL_OS | Operating system image name. | `"ubuntu_20_04"` | +| digitalocean | `do_project_name` | PERF_TEST_DIGITALOCEAN_PROJECT_NAME | The project name that instances belong to; will create one if not exist. | `"Benchmark"` | +|digitalocean | `do_token` | PERF_TEST_DIGITALOCEAN_TOKEN | DigitalOcean authentication token. | | +|digitalocean | `do_size` | PERF_TEST_DIGITALOCEAN_SIZE | Droplet size. | `"s-1vcpu-1gb"` | +|digitalocean | `do_region` | PERF_TEST_DIGITALOCEAN_REGION | Region to deploy droplet. | `"sfo3"` | +|digitalocean | `do_os` | PERF_TEST_DIGITALOCEAN_OS | Operation system image name. | `"ubuntu-20-04-x64"` | +|aws-ec2 | `aws_region` | PERF_TEST_AWS_REGION | AWS region to deploy EC2 instances. | `"us-east-2"` | +|aws-ec2 | `ec2_instance_type` | PERF_TEST_EC2_INSTANCE_TYPE | EC2 instance type. | `"c4.4xlarge"` | +|aws-ec2 | `ec2_os` | PERF_TEST_EC2_OS | Operation system image pattern. | `"ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"` | + +### perf.set_log_level + +*syntax: perf.set_log_level(level)* + +Sets the log level; expect one of `"debug"`, `"info"`, `"notice"`, `"warn"`, `"error"` and +`"crit"`. The default log level is `"info"` unless `perf.use_defaults` is called and set +to `"debug"`. + +### perf.set_retry_count + +*syntax: perf.set_retry_count(count)* + +Sets retry time for each “driver" operation. By default every operation is retried 3 times. + +### perf.setup + +*syntax: helpers = perf.setup()* + +Prepares base environment, except for {{site.base_gateway}}, and returns the `spec.helpers` module. Throws error, if any. + +The framework sets up some environment variables before importing `spec.helpers` modules. +The returned helper is just a normal `spec.helpers` module. Users can use the same pattern +in integration tests to setup entities in Kong. DB-less mode is currently not implemented. + +### perf.setup_kong + +*syntax: helpers = perf.setup_kong(version)* + +Prepares base environment and installs {{site.base_gateway}} with `version`, then returns the `spec.helpers` module. +Throws error, if any. Calling this function also invokes `perf.setup()`. + +To select a git hash or tag, use `"git:"` as the version. Otherwise, the framework +treats the `version` as a release version and downloads binary packages from +Kong's distribution website. + +The framework sets up some environment variables before importing `spec.helpers` modules. +The returned helper is just a normal `spec.helpers` module. Users can use the same pattern +in integration tests to setup entities in Kong. DB-less mode is currently not implemented. + +### perf.start_worker + +*syntax: `upstream_uri` = perf.start_worker(`nginx_conf_blob`, `port_count`?)* + +Starts upstream (Nginx/OpenResty) with given `nginx_conf_blob`. Returns the upstream +URI accessible from {{site.base_gateway}}'s view. Throws an error, if any. + +If `port_count` is set and larger than one, the framework starts upstreams with multiple ports +and returns them in a table. + +### perf.start_kong + +*syntax: perf.start_kong(`kong_configs`?, `driver_configs`?)* + +Starts {{site.base_gateway}} with the configurations in `kong_configs` as a Lua table. +Throws an error, if any. + +`driver_configs` is a Lua table that may contain following keys: +- `name`: A string that distinguishes different {{site.base_gateway}} instances. It's not required if only one {{site.base_gateway}} instance is started. It can be used as DNS name to access one {{site.base_gateway}} instance over another. +- `ports`: A table to setup exposed ports. This is only honored by the `docker` driver. + +### perf.stop_kong + +*syntax: perf.stop_kong()* + +Stops all Kong instances. Throws error if any. + +### perf.teardown + +*syntax: perf.teardown(full?)* + +Teardown. Throws error if any. With the terraform driver, setting full to true terminates +all infrastructure, while by default it does cleanup only to speed up successive runs. + +### perf.start_stapxx + +*syntax: perf.start_stapxx(`stapxx_file_name`, `arg`?, `driver_configs`?)* + +Starts the Stap++ script with `stapxx_file_name` exists in +[available stapxx scripts](https://github.com/Kong/stapxx/tree/kong/samples) +and additional CLI arguments. Throws error if any. + +This function blocks test execution until the `SystemTap` module is fully prepared and inserted into the +kernel. It should be called before `perf.start_load`. + +`driver_configs` is a Lua table that contains the following keys: +- `name`: A string to distinguish different {{site.base_gateway}} instances to probe one. + +### perf.start_load + +*syntax: perf.start_load(options?)* + +Starts to send load to Kong using `wrk`. Throws error if any. Options is a Lua table that may contain the following: + +- **path** String request path; defaults to `/ `. +- **uri** Base URI exception path; defaults to `http://kong-ip:kong-port/`. +- **connections** Connection count; defaults to 1000. +- **threads** Request thread count; defaults to 5. +- **duration** Number of performance tests duration in seconds; defaults to 10. +- **script** Content of `wrk` script as string; defaults to nil. +- **wrk2** Boolean to use `wrk2` instead of `wrk`. Defaults to false. +- **rate** Number of requests per second to send. This is required if using `wrk2` but invalid if using `wrk`. +- **kong_name** The `name` specified by `driver_confs` when starting {{site.base_gateway}} to send load to. When this is unspecified, the framework picks the first {{site.base_gateway}} instance that exposes the proxy port. + +### perf.get_admin_uri + +*syntax: perf.get_admin_uri(kong_name?)* + +Return the Admin API URL. The URL may only be accessible from +the load generator and not publicly available. The framework picks the first +{{site.base_gateway}} instance that exposes the admin port. `kong_name` must be set to choose the {{site.base_gateway}} +instance with matching `name` specified by `driver_confs` when starting {{site.base_gateway}}. +### perf.wait_result + +*syntax: result = perf.wait_result(options?)* + +Waits for the load test to finish and returns the result as a string. Throws error if any. + +Currently, this function waits indefinitely, or until both `wrk` and Stap++ processes exit. + +### perf.combine_results + +*syntax: `combined_result` = perf.combine_results(results, suite?)* + +Calculates multiple results returned by `perf.wait_result` and returns their average and min/max. +Throws an error, if any. The `suite` string identifies the test suite to display in the charts and +is used as the X-axis labels. If the suite is not specified, the framework will use the test name. + +If results in the same file are correlated, the user can set `suite` to a number and add the following options +to draw a line chart with a trend line: + +```lua +local charts = require "spec.helpers.perf.charts" +charts.options({ + suite_sequential = true, + xaxis_title = "Upstreams count", +}) +``` + +If this option is not set, the chart treats results in same test file as independent tests +and draws a bar chart. + +### perf.generate_flamegraph + +*syntax: perf.generate_flamegraph(path, title?)* + +Generates a FlameGraph with title and saves to path. Throws error if any. + +### perf.save_error_log + +*syntax: perf.save_error_log(path)* + +Saves Kong error log to path. Throws error if any. + +### perf.enable_charts + +*syntax: perf.enable_charts(on?)* + +Enable charts generation, throws error if any. + +Charts are enabled by default; the data of charts are fed by `perf.combine_results`. +The generated JSON results for creating charts are stored under the `output` directory. + +### perf.save_pgdump + +*syntax: perf.save_pgdump(path)* + +After setting up Kong using Blueprint, saves the PostgreSQL database dump to a path. Throws error if any. + +### perf.load_pgdump + +*syntax: perf.load_pgdump(path, `dont_patch_service`)* + +Loads the pgdump from the path and replaces the Kong database with the loaded data; this function +will also patch a services address to the upstream unless `dont_patch_service` is set to false, +it must be called after `perf.start_upstream`. Throws error if any. + +## Customization + +### Add new test suite + +All tests are stored in `spec/04-perf/01-rps` and `spec/04-perf/02-flamegraph` of the Kong repository. +Add a new file under one of the directories and put `#tags` in the test description. + +### Add new provider in Terraform + +Users can use the Terraform driver in most major service providers as long as +it's supported by Terraform. The following contracts are made between the framework and terraform module: + +The terraform files are stored in `spec/fixtures/perf/terraform/`. + +Three instances are provisioned, one for running Kong, one for running PostgreSQL +database and another for running an upstream and load (worker). +A firewall allows bidirectional traffic between the three instances +and from the public internet. Both instances run Ubuntu 20.04/focal. + +An SSH key to login into both instances exists or will be created in +`spec/fixtures/perf/terraform//id_rsa`. The logged-in user has root privilege or sudo privilege. + +The following are terraform output variables: + +- **kong-ip**: Kong node public IP. +- **kong-internal-ip**: Kong node internal IP (if unavailable, provide `kong-ip`). +- **worker-ip**: Worker node public IP. +- **worker-internal-ip**: Worker node internal IP (if unavailable, provide `worker-ip`). +- **db-ip**: Database node public IP. +- **db-internal-ip**: Database node internal IP (if unavailable, provide `db-ip`). diff --git a/src/gateway/reference/router-operators.md b/src/gateway/reference/router-operators.md new file mode 100644 index 000000000000..b3e21bae5315 --- /dev/null +++ b/src/gateway/reference/router-operators.md @@ -0,0 +1,100 @@ +--- +title: Router Operator Reference for Kong Gateway +content-type: reference +--- + +With the release of version 3.0, {{site.base_gateway}} now ships with a new router. The new router can describe routes using a domain-specific language called Expressions. Expressions can describe routes or paths as +combinations of logical operations called "predicates". This document serves as a reference for all of the available operators and fields. +If you want to learn how to configure routes using Expressions read [How to configure routes using Expressions](/gateway/{{ page.kong_version }}/key-concepts/routes/expressions). + + +## General design + +Kong router Expressions are designed as combinations of simple comparisons called "predicates". All predicates have one of the following form: + +``` +field op value +transformation(field) op value +``` + +Example: + +``` +http.path ^= "/prefix/" +lower(http.path) ^= "/prefix/" +``` + +Note: transformations only works on fields, it will not work on the value side of the predicate. This means you can **not** write: + +``` +http.path ^= lower("/preFIX/") +``` + +Predicates can be grouped with parenthesis `()` or logical operators `||`, `&&`: + +Example: + +``` +(http.path ^= "/prefix/" && net.port == 80) || http.method == "POST" +``` + +## Available fields + +| Field | Description | Type | +| --- | ----------- | -------| +| `net.protocol` | The protocol used to communicate with the upstream application. | String | +| `net.port` | Server end port number. | Int | +| `tls.sni` | Server name indication. | String | +| `http.method` | HTTP methods that match a route. | String | +| `http.host` | Lists of domains that match a route. | String | +| `http.path` | Normalized request path (without query parameters). | String | +| `http.headers.header_name` | Value of header `Header-Name`. Header names are converted to lower case, and `-` are replaced to `_`. | String | + +## String + +| Operator | Meaning | +| --- | ----------- | +| == | Equals | +| != | Not equals | +| ~ | Regex matching | +| ^= | Prefix matching | +| =^ | Suffix matching | +| in | Contains | +| not in | Does not contain | + +## String transformations + +| lower() | Lowercase | + +## Integer + +| Operator | Meaning | +| --- | ----------- | +| == | Equals | +| != | Not equals| +| > | Greater than | +| >= | Greater than or equal | +| < | Less than | +| <= | Less than or equal | + +## IP + +| Operator | Meaning | +| --- | ----------- | +| == | Equals | +| != | Not equals | +| in | Contains | + +## Boolean + +| Operator | Meaning | +| --- | ----------- | +| && | Logical And | +| `||` | Logical Or | + + + +## More information + +* [Expressions repository](https://github.com/Kong/atc-router#table-of-contents) +* [How to configure routes using Expressions](/gateway/{{ page.kong_version }}/key-concepts/routes/expressions) diff --git a/src/gateway/stability.md b/src/gateway/stability.md new file mode 100644 index 000000000000..29c582eadfcc --- /dev/null +++ b/src/gateway/stability.md @@ -0,0 +1,6 @@ +--- +title: Stages of software availability +content-type: reference +--- + +{% include_cached /md/availability-stages.md %} diff --git a/src/gateway/support-policy.md b/src/gateway/support-policy.md new file mode 100644 index 000000000000..d870f46109d1 --- /dev/null +++ b/src/gateway/support-policy.md @@ -0,0 +1,43 @@ +--- +title: Version Support Policy +badge: enterprise +content-type: reference +--- + +The support for {{site.ee_product_name}} software versions is explained in this topic. + +{% include_cached /md/support-policy.md %} + +## Version support for {{site.base_gateway}} (Enterprise) + +| Version | Released Date | End of Full Support | End of Sunset Support | +|:--------:|:-------------:|:-------------------:|:---------------------:| +| 3.0.x.x | 2022-08-31 | 2024-08-30 | 2025-08-30 | +| 2.8.x.x | 2022-03-02 | 2023-08-24 | 2024-08-24 | +| 2.7.x.x | 2021-12-16 | 2023-02-24 | 2023-08-24 | +| 2.6.x.x | 2021-10-14 | 2023-02-24 | 2023-08-24 | +| 2.5.x.x | 2021-08-03 | 2022-08-24 | 2023-08-24 | +| 2.4.x.x | 2021-05-18 | 2022-08-24 | 2023-08-24 | +| 2.3.x.x | 2021-02-11 | 2022-08-24 | 2023-08-24 | +| 2.2.x.x | 2020-11-17 | 2022-08-24 | 2023-08-24 | +| 2.1.x.x | 2020-08-25 | 2022-08-24 | 2023-08-24 | +| 1.5.x.x | 2020-04-10 | 2021-04-09 | 2022-04-09 | +| 1.3.x.x | 2019-11-05 | 2020-11-04 | 2021-11-04 | +| 0.36 | 2019-08-05 | 2020-08-04 | 2021-08-04 | +| 0.35 | 2019-05-16 | 2020-05-15 | 2020-11-15 | +| 0.34 | 2018-11-19 | 2019-11-18 | 2020-11-18 | +| 0.33 | 2018-07-11 | 2019-06-10 | 2020-06-10 | +| 0.32 | 2018-05-22 | 2019-05-21 | 2020-05-21 | +| 0.31 | 2018-03-13 | 2019-03-12 | 2020-03-12 | +| 0.30 | 2018-01-22 | 2019-01-21 | 2020-01-21 | + +> *Table 1: Version Support for {{site.ee_product_name}}* + +## Additional terms +- The above is a summary only and is qualified by Kong’s [Support and Maintenance Policy](https://konghq.com/supportandmaintenancepolicy). +- The above applies to Kong standard software builds only. + +## See also + +* [Version support policy for {{site.mesh_product_name}}](/mesh/latest/support-policy) +* [Version support policy for {{site.kic_product_name}}](/kubernetes-ingress-controller/latest/support-policy) diff --git a/src/gateway/upgrade.md b/src/gateway/upgrade.md new file mode 100644 index 000000000000..7f6a73f1258b --- /dev/null +++ b/src/gateway/upgrade.md @@ -0,0 +1,493 @@ +--- +title: Upgrade Kong Gateway +--- + +Upgrade to major, minor, and patch {{site.base_gateway}} +releases using the `kong migrations` commands. + +You can also use the commands to migrate all {{site.base_gateway}} open-source entities +to {{site.base_gateway}} (Enterprise). See +[Migrating from {{site.ce_product_name}} to {{site.base_gateway}}](/gateway/{{page.kong_version}}/migrate-ce-to-ke/). + +If you experience any issues when running migrations, contact +[Kong Support](https://support.konghq.com/support/s/) for assistance. + +## Upgrade path for {{site.base_gateway}} releases + +Kong adheres to [semantic versioning](https://semver.org/), which makes a +distinction between major, minor, and patch versions. + +The upgrade to 3.0.x is a **major** upgrade. +The lowest version that Kong 3.0.x supports migrating from is 2.1.x. + +{:.important} +> **Important**: Blue-green migration in traditional mode for versions below 2.8.2 to 3.0.x is not supported. +The upcoming 2.8.2 release will include blue-green migration support. If you want +to perform migrations for traditional mode with no downtime, please wait for the upcoming 2.8.2 patch release, +upgrade to 2.8.2, [then migrate to 3.0.x](#migrate-db). + +While you can upgrade directly to the latest version, be aware of any +breaking changes between the 2.x and 3.x series noted in this document +(both this version and prior versions) and in the +[open-source (OSS)](https://github.com/Kong/kong/blob/release/3.0.x/CHANGELOG.md#300) and +[Enterprise](/gateway/changelog/#3000) Gateway changelogs. Since {{site.base_gateway}} +is built on an open-source foundation, any breaking changes in OSS affect all {{site.base_gateway}} packages. + +{{site.base_gateway}} does not support directly upgrading from 1.x to 3.0.x. +If you are running 1.x, upgrade to 2.1.0 first at minimum, then upgrade to 3.0.x from there. + +In either case, you can review the [upgrade considerations](#upgrade-considerations-and-breaking-changes), +then follow the [database migration](#migrate-db) instructions. + +## Upgrade considerations and breaking changes + +Before upgrading, review this list for any configuration or breaking changes that +affect your current installation. + +### Deployment + +Amazon Linux 1 and Debian 8 (Jessie) containers and packages are deprecated and are no longer produced for new versions of {{site.base_gateway}}. + +#### Blue-green deployments + +**Traditional mode**: Blue-green upgrades from versions of 2.8.1 and below to 3.0.0 are not currently supported. +This is a known issue planned to be fixed in the next 2.8 release. When that version is released, 2.x users should upgrade to that version before beginning a blue-green upgrade to 3.0. + +**Hybrid mode**: See the [upgrade instructions](#migrate-db) below. + +### Dependencies + +If you are using the provided binary packages (except Debian and RHEL), all necessary dependencies +for the gateway are bundled and you can skip this section. + +As of {{ site.base_gateway }} 3.0, our Debian and RHEL images are built with minimal dependencies and run through automated security scanners before being published. +They only contain the bare minimum required to run {{site.base_gateway}}. +If you would like further customize the base image and any dependencies, you can +[build your own Docker images](/gateway/{{page.kong_version}}/install/docker/build-custom-images). + +If you are using Debian, RHEL, or building your dependencies by hand, there are changes since the +previous release, so you will need to rebuild them with the latest patches. + +The required OpenResty version for {{site.base_gateway}} 3.0.x is +[1.21.4.1](https://openresty.org/en/ann-1021004001.html). In addition to an upgraded +OpenResty, you need the correct [OpenResty patches](https://github.com/Kong/kong-build-tools/tree/master/openresty-build-tools/patches) +for this new version, including the latest release of [lua-kong-nginx-module](https://github.com/Kong/lua-kong-nginx-module). +The [kong-build-tools](https://github.com/Kong/kong-build-tools) +repository contains [openresty-build-tools](https://github.com/Kong/kong-build-tools/tree/master/openresty-build-tools), +which allows you to more easily build OpenResty with the necessary patches and modules. + +### Migrations + +The migration helper library (mostly used for Cassandra migrations) is no longer supplied with {{site.base_gateway}}. + +PostgreSQL migrations can now have an `up_f` part like Cassandra +migrations, designating a function to call. The `up_f` part is +invoked after the `up` part has been executed against the database +for both PostgreSQL and Cassandra. + +### Kong plugins + +If you are adding a new plugin to your installation, you need to run +`kong migrations up` with the plugin name specified. For example, +`KONG_PLUGINS=tls-handshake-modifier`. + +The 3.0 release includes the following new plugins: +* [OpenTelemetry](/hub/kong-inc/opentelemetry) (`opentelemetry`) +* [TLS Handshake Modifier](/hub/kong-inc/tls-handshake-modifier/) (`tls-handshake-modifier`) +* [TLS Metadata Headers](/hub/kong-inc/tls-metadata-headers/) (`tls-metadata-headers`) +* [WebSocket Size Limit](/hub/kong-inc/websocket-size-limit/) (`websocket-size-limit`) +* [WebSocket Validator](/hub/kong-inc/websocket-validator/) (`websocket-validator`) + +Kong plugins no longer support `CREDENTIAL_USERNAME` (`X-Credential-Username`). +Use the constant `CREDENTIAL_IDENTIFIER` (`X-Credential-Identifier`) when +setting the upstream headers for a credential. + +#### Deprecations and changed parameters + +The [StatsD Advanced](/hub/kong-inc/statsd-advanced/) plugin +has been deprecated and will be removed in 4.0. +All capabilities are now available in the [StatsD](/hub/kong-inc/statsd/) plugin. + +The following plugins have had configuration parameters changed or removed. You will need to carefully review and update your configuration as needed: + +**[ACL](/hub/kong-inc/acl/), [Bot Detection](/hub/kong-inc/bot-detection), and [IP Restriction](/hub/kong-inc/ip-restriction/)** +* Removed the deprecated `blacklist` and `whitelist` configuration parameters. Use `allow` or `deny` instead. + +**[ACME](/hub/kong-inc/ACME/)** +* The default value of the `auth_method` configuration parameter is now `token`. + +**[AWS Lambda](/hub/kong-inc/aws-lambda/)** +* The AWS region is now required. You can set it through the plugin configuration with the `aws_region` field parameter, or with environment variables. +* The plugin now allows `host` and `aws_region` fields to be set at the same time, and always applies the SigV4 signature. + +**[HTTP Log](/hub/kong-inc/http-log/)** +* The `headers` field now only takes a single string per header name, +where it previously took an array of values. + +**[JWT](/hub/kong-inc/jwt/)** +* The authenticated JWT is no longer put into the nginx +context (`ngx.ctx.authenticated_jwt_token`). Custom plugins which depend on that +value being set under that name must be updated to use Kong's shared context +instead (`kong.ctx.shared.authenticated_jwt_token`) before upgrading to 3.0. + +**[Prometheus](/hub/kong-inc/prometheus/)** +* High cardinality metrics are now disabled by default. + +* The following metric names were adjusted to add units to standardize where possible: + * `http_status` to `http_requests_total`. + * `latency` to `kong_request_latency_ms` (HTTP), `kong_upstream_latency_ms`, `kong_kong_latency_ms`, and `session_duration_ms` (stream). + Kong latency and upstream latency can operate at orders of different magnitudes. Separate these buckets to reduce memory overhead. + * `kong_bandwidth` to `kong_bandwidth_bytes`. + * `nginx_http_current_connections` and `nginx_stream_current_connections` were merged into `nginx_connections_total`. + * `request_count` and `consumer_status` were merged into `http_requests_total`. + If the `per_consumer` config is set to `false`, the `consumer` label will be empty. If the `per_consumer` config is `true`, the `consumer` label will be filled. + +* Other metric changes: + * Removed the following metric: `http_consumer_status`. + * `http_requests_total` has a new label, `source`. It can be set to `exit`, `error`, or `service`. + * All memory metrics have a new label: `node_id`. + * The plugin doesn't export status codes, latencies, bandwidth and upstream + health check metrics by default. They can still be turned on manually by setting `status_code_metrics`, + `lantency_metrics`, `bandwidth_metrics` and `upstream_health_metrics` respectively. + +**[Serverless Functions](/hub/kong-inc/serverless-functions/)** +* Removed the deprecated `config.functions` configuration parameter from the +Serverless Functions plugins' schemas (`post-fuction` and `pre-function`). +Use the `config.access` phase instead. + +**[StatsD](/hub/kong-inc/statsd/)** +* Any metric name that is related to a service now has a `service.` prefix: `kong.service..request.count`. + * The metric `kong..request.status.` has been renamed to `kong.service..status.`. + * The metric `kong..user..request.status.` has been renamed to `kong.service..user..status.`. + +* The metric `*.status..total` from metrics `status_count` and `status_count_per_user` has been removed. + +**[Proxy Cache](/hub/kong-inc/proxy-cache/), [Proxy Cache Advanced](/hub/kong-inc/proxy-cache-advanced/), and [GraphQL Proxy Cache Advanced](/hub/kong-inc/graphql-proxy-cache-advanced/)** +* These plugins don't store response data in `ngx.ctx.proxy_cache_hit` anymore. +* Logging plugins that need the response data must now read it from `kong.ctx.shared.proxy_cache_hit`. + +### Custom plugins and the PDK + +* DAOs in plugins must be listed in an array, so that their loading order is explicit. Loading them in a + hash-like table is no longer supported. +* Plugins MUST now have a valid `PRIORITY` (integer) and `VERSION` ("x.y.z" format) + field in their `handler.lua` file, otherwise the plugin will fail to load. +* The old `kong.plugins.log-serializers.basic` library was removed in favor of the PDK + function `kong.log.serialize`. Upgrade your plugins to use the PDK. +* The support for deprecated legacy plugin schemas was removed. If your custom plugins + still use the old (`0.x era`) schemas, you are now forced to upgrade them. + +* Updated the priority for some plugins. + + This is important for those who run custom plugins as it may affect the sequence in which your plugins are executed. + This does not change the order of execution for plugins in a standard {{site.base_gateway}} installation. + + Old and new plugin priority values: + - `acme` changed from `1007` to `1705` + - `basic-auth` changed from `1001` to `1100` + - `hmac-auth` changed from `1000` to `1030` + - `jwt` changed from `1005` to `1450` + - `key-auth` changed from `1003` to `1250` + - `ldap-auth` changed from `1002` to `1200` + - `oauth2` changed from `1004` to `1400` + - `rate-limiting` changed from `901` to `910` + - `pre-function` changed from `+inf` to `1000000`. + +* The `kong.request.get_path()` PDK function now performs path normalization + on the string that is returned to the caller. The raw, non-normalized version + of the request path can be fetched via `kong.request.get_raw_path()`. + +* `pdk.response.set_header()`, `pdk.response.set_headers()`, `pdk.response.exit()` now ignore and emit warnings for manually set `Transfer-Encoding` headers. + +* The PDK is no longer versioned. + +* The JavaScript PDK now returns `Uint8Array` for `kong.request.getRawBody`, + `kong.response.getRawBody`, and `kong.service.response.getRawBody`. + The Python PDK returns `bytes` for `kong.request.get_raw_body`, + `kong.response.get_raw_body`, and `kong.service.response.get_raw_body`. + Previously, these functions returned strings. + +* The `go_pluginserver_exe` and `go_plugins_dir` directives are no longer supported. +If you are using + [Go plugin server](https://github.com/Kong/go-pluginserver), migrate your plugins to use the + [Go PDK](https://github.com/Kong/go-pdk) before upgrading. + +* As of 3.0, {{site.base_gateway}}'s schema library's `process_auto_fields` function will not make deep + copies of data that is passed to it when the given context is `select`. This was + done to avoid excessive deep copying of tables where we believe the data most of + the time comes from a driver like `pgmoon` or `lmdb`. + + If a custom plugin relied on `process_auto_fields` not overriding the given table, it must make its own copy + before passing it to the function now. + +* The deprecated `shorthands` field in Kong plugin or DAO schemas was removed in favor + of the typed `shorthand_fields`. If your custom schemas still use `shorthands`, you + need to update them to use `shorthand_fields`. + +* The support for `legacy = true/false` attribute was removed from Kong schemas and + Kong field schemas. + +* The Kong singletons module `kong.singletons` was removed in favor of the PDK `kong.*`. + +### New router + +{{site.base_gateway}} no longer uses a heuristic to guess whether a `route.path` is a regex pattern. From 3.0 onward, +all regex paths must start with the `"~"` prefix, and all paths that don't start with `"~"` will be considered plain text. +The migration process should automatically convert the regex paths when upgrading from 2.x to 3.0. + +The normalization rules for `route.path` have changed. {{site.base_gateway}} now stores the unnormalized path, but +the regex path always pattern-matches with the normalized URI. Previously, {{site.base_gateway}} replaced percent-encoding +in the regex path pattern to ensure different forms of URI matches. +That is no longer supported. Except for the reserved characters defined in +[rfc3986](https://datatracker.ietf.org/doc/html/rfc3986#section-2.2), +write all other characters without percent-encoding. + +### Declarative and DB-less + +The version number (`_format_version`) of declarative configuration has been bumped to `3.0` for changes on `route.path`. +Declarative configurations with older versions will be upgraded to `3.0` during migrations. + +{:.important} +> **Do not sync (`deck sync`) declarative configuration files from 2.8 or earlier to 3.0.** +Old configuration files will overwrite the configuration and create compatibility issues. +To grab the updated configuration, `deck dump` the 3.0 file after migrations are completed. + +It is no longer possible to use the `.lua` format to import a declarative configuration file from the `kong` +CLI tool. Only JSON and YAML formats are supported. If your update procedure with {{site.base_gateway}} involves +executing `kong config db_import config.lua`, convert the `config.lua` file into a `config.json` or `config.yml` file +before upgrading. + +### Admin API + +The Admin API endpoint `/vitals/reports` has been removed. + +`POST` requests on `/targets` endpoints are no longer able to update +existing entities. They are only able to create new ones. +If you have scripts that use `POST` requests to modify `/targets`, change them to `PUT` +requests to the appropriate endpoints before updating to Kong 3.0. + +The list of reported plugins available on the server now returns a table of +metadata per plugin instead of a boolean `true`. + +### Configuration + +The Kong constant `CREDENTIAL_USERNAME` with the value of `X-Credential-Username` has been +removed. + +The default value of `lua_ssl_trusted_certificate` has changed to `system` to automatically load the trusted CA list from the system CA store. + +The data plane config cache mechanism and its related configuration options +(`data_plane_config_cache_mode` and `data_plane_config_cache_path`) have been removed in favor of LMDB. + +`ngx.ctx.balancer_address` was removed in favor of `ngx.ctx.balancer_data`. + +### Kong for Kubernetes considerations + +The Helm chart automates the upgrade migration process. When running `helm upgrade`, +the chart spawns an initial job to run `kong migrations up` and then spawns new +Kong pods with the updated version. Once these pods become ready, they begin processing +traffic and old pods are terminated. Once this is complete, the chart spawns another job +to run `kong migrations finish`. + +While the migrations themselves are automated, the chart does not automatically ensure +that you follow the recommended upgrade path. If you are upgrading from more than one minor +{{site.base_gateway}} version back, check the upgrade path recommendations. + +Although not required, users should upgrade their chart version and {{site.base_gateway}} version independently. +In the event of any issues, this will help clarify whether the issue stems from changes in +Kubernetes resources or changes in {{site.base_gateway}}. + +For specific Kong for Kubernetes version upgrade considerations, see +[Upgrade considerations](https://github.com/Kong/charts/blob/main/charts/kong/UPGRADE.md) + +#### Kong deployment split across multiple releases + +The standard chart upgrade automation process assumes that there is only a single {{site.base_gateway}} release +in the {{site.base_gateway}} cluster, and runs both `migrations up` and `migrations finish` jobs. + +If you split your {{site.base_gateway}} deployment across multiple Helm releases (to create proxy-only +and admin-only nodes, for example), you must set which migration jobs run based on your +upgrade order. + +To handle clusters split across multiple releases, you should: + +1. Upgrade one of the releases with: + + ```shell + helm upgrade RELEASENAME -f values.yaml \ + --set migrations.preUpgrade=true \ + --set migrations.postUpgrade=false + ``` +2. Upgrade all but one of the remaining releases with: + + ```shell + helm upgrade RELEASENAME -f values.yaml \ + --set migrations.preUpgrade=false \ + --set migrations.postUpgrade=false + ``` +3. Upgrade the final release with: + + ```shell + helm upgrade RELEASENAME -f values.yaml \ + --set migrations.preUpgrade=false \ + --set migrations.postUpgrade=true + ``` + +This ensures that all instances are using the new {{site.base_gateway}} package before running +`kong migrations finish`. + +### Hybrid mode considerations + +{:.important} +> **Important:** If you are currently running in [hybrid mode](/gateway/{{page.kong_version}}/production/deployment-topologies/hybrid-mode/), +upgrade the control plane first, and then the data planes. + +* If you are currently running 2.8.x in classic (traditional) + mode and want to run in hybrid mode instead, follow the hybrid mode + [installation instructions](/gateway/{{page.kong_version}}/production/deployment-topologies/hybrid-mode/setup/) + after running the migration. +* Custom plugins (either your own plugins or third-party plugins that are not shipped with {{site.base_gateway}}) + need to be installed on both the control plane and the data planes in hybrid mode. Install the + plugins on the control plane first, and then the data planes. +* The [Rate Limiting Advanced](/hub/kong-inc/rate-limiting-advanced) plugin does not + support the `cluster` strategy in hybrid mode. The `redis` strategy must be used instead. + +### Template changes + +There are changes in the Nginx configuration file between every minor and major +version of {{site.base_gateway}} starting with 2.0.x. + +In 3.0.x, the deprecated alias of `Kong.serve_admin_api` was removed. +If your custom Nginx templates still use it, change it to `Kong.admin_content`. + +{% navtabs %} +{% navtab OSS %} +To view all of the configuration changes between versions, clone the +[Kong repository](https://github.com/kong/kong) and run `git diff` +on the configuration templates, using `-w` for greater readability. + +Here's how to see the differences between previous versions and 3.0.x: + +``` +git clone https://github.com/kong/kong +cd kong +git diff -w 2.0.0 3.0.0 kong/templates/nginx_kong*.lua +``` + +Adjust the starting version number (2.0.0 in the example) to the version number you are currently using. + +To produce a patch file, use the following command: + +``` +git diff 2.0.0 3.0.0 kong/templates/nginx_kong*.lua > kong_config_changes.diff +``` + +Adjust the starting version number to the version number (2.0.0 in the example) you are currently using. + +{% endnavtab %} +{% navtab Enterprise %} + +The default template for {{site.base_gateway}} can be found using this command +on the system running your {{site.base_gateway}} instance: +`find / -type d -name "templates" | grep kong`. + +When upgrading, make sure to run this command on both the old and new clusters, +diff the files to identify any changes, and apply them as needed. + +{% endnavtab %} +{% endnavtabs %} + + +## Upgrade from 2.1.x - 2.8.x to 3.0.x {#migrate-db} + +Follow the instructions for your backing data store to migrate to the new version. +If you prefer to use a fresh data store and only migrate your `kong.conf` file, +see the instructions to +[install 3.0.x on a fresh data store](#install-30x-on-a-fresh-data-store). + +As with all upgrades make a backup of your data store before beginning the process. + +You should not make changes to configuration with the Admin API during migration, as it may lead to unexpected behavior and +break your configuration. + +**Version prerequisites for migrating to version 3.0.x** + +If you are migrating from 2.7.x or lower versions, first [migrate to 2.8.1](#upgrade-from-10x---22x-to-28x). + +Once you have migrated to 2.8.x, you can follow the instructions in the section +below to migrate to 3.0.x. + +### Upgrade from 2.8.x (x>=2) to 3.0.x for traditional mode + +{:.note} +> These instructions will only work once 2.8.2 is available. + +1. Clone your database. +2. Download 3.0.x, and configure it to point to the cloned data store + as your old (2.8.2 or beyond) cluster. Run `kong migrations up` and `kong migrations finish`. +3. Start 3.0.x cluster. +4. Now both the old (2.8.x) and new (3.0.x) + clusters can now run simultaneously. Start provisioning 3.0.x nodes. +3. Gradually divert traffic away from your old nodes, and into + your 3.0.x cluster. Monitor your traffic to make sure everything + is going smoothly. +4. When your traffic is fully migrated to the 3.0.x cluster, + decommission your old nodes. + +### Upgrade to 3.0.x for hybrid mode + +Data planes can serve traffic during the process of migration. + +1. Download 3.0.x. +2. Decommission your old control plane. +3. Configure the new control plane to point to the same data store + as your old control plane. Run `kong migrations up` and `kong migrations finish`. +4. Start the new control plane. It is expected that old data planes may complain +about connection failure to the control plane. +5. Start new data planes. +6. Gradually divert traffic away from your old data planes, and into + your 3.0.x data planes. Monitor your traffic to make sure everything + is going smoothly. +7. When your traffic is fully migrated to the 3.0.x cluster, + decommission your old nodes. + +## Install 3.0.x on a fresh data store + +For installing on a fresh data store, {{site.base_gateway}} 3.0.x has the +`kong migrations bootstrap` command. Run the following commands to +prepare a new 3.0.x cluster from a fresh data store. + +By default, the `kong` CLI tool +loads the configuration from `/etc/kong/kong.conf`, but you can optionally use +the `-c` flag to indicate the path to your configuration file: + +```bash +kong migrations bootstrap [-c /path/to/kong.conf] +kong start [-c /path/to/kong.conf] +``` + +Assuming that {{site.base_gateway}} is already running on your system, acquire the latest +version from any of the available [installation methods](/gateway/{{page.kong_version}}/install/) +and install it, overriding your previous installation. + +**If you are planning to make modifications to your configuration, this is a +good time to do so**. + +Then, run migrations to upgrade your database schema: + +```shell +kong migrations up [-c configuration_file] +``` + +If the command is successful, and no migration ran +(no output), then you only have to +[reload](/gateway/{{page.kong_version}}/reference/cli/#kong-reload) {{site.base_gateway}}: + +```shell +kong reload [-c configuration_file] +``` + +**Reminder**: `kong reload` leverages the Nginx `reload` signal that seamlessly +starts new workers, which take over from old workers before those old workers +are terminated. In this way, {{site.base_gateway}} will serve new requests via the new +configuration, without dropping existing in-flight connections. diff --git a/src/kubernetes-ingress-controller/availability-stages.md b/src/kubernetes-ingress-controller/availability-stages.md new file mode 100644 index 000000000000..29c582eadfcc --- /dev/null +++ b/src/kubernetes-ingress-controller/availability-stages.md @@ -0,0 +1,6 @@ +--- +title: Stages of software availability +content-type: reference +--- + +{% include_cached /md/availability-stages.md %} diff --git a/src/kubernetes-ingress-controller/concepts/design.md b/src/kubernetes-ingress-controller/concepts/design.md index cd220dba32da..063e20a27340 100644 --- a/src/kubernetes-ingress-controller/concepts/design.md +++ b/src/kubernetes-ingress-controller/concepts/design.md @@ -61,4 +61,4 @@ configuration: For more information on how Kong works with Routes, Services, and Upstreams, please see the [Proxy](/gateway/latest/reference/proxy/) -and [Load balancing](/gateway/latest/reference/loadbalancing/) references. +and [Load balancing](/gateway/latest/how-kong-works/load-balancing/) references. diff --git a/src/kubernetes-ingress-controller/concepts/k4k8s-with-kong-enterprise.md b/src/kubernetes-ingress-controller/concepts/k4k8s-with-kong-enterprise.md index 7c54f33d19f1..f4b094f2eccf 100644 --- a/src/kubernetes-ingress-controller/concepts/k4k8s-with-kong-enterprise.md +++ b/src/kubernetes-ingress-controller/concepts/k4k8s-with-kong-enterprise.md @@ -6,7 +6,7 @@ Kong for Kubernetes is a {{site.kic_product_name}} built on top of Open-Source {{site.base_gateway}}. If you are an Enterprise customer, you have an option of running the -[Enterprise version](/gateway/latest/install-and-run/kubernetes/) +[Enterprise version](/gateway/latest/install/kubernetes/helm-quickstart/) of the Ingress Controller, which includes all the Enterprise plugins but does not include Kong Manager or any other Enterprise features. This makes it possible to diff --git a/src/kubernetes-ingress-controller/guides/using-oidc-plugin.md b/src/kubernetes-ingress-controller/guides/using-oidc-plugin.md index 80b0cf821c32..d0c884190549 100644 --- a/src/kubernetes-ingress-controller/guides/using-oidc-plugin.md +++ b/src/kubernetes-ingress-controller/guides/using-oidc-plugin.md @@ -147,4 +147,4 @@ This basic configuration permits any user with a valid Google account to access the dummy service. For setting up more complicated authentication and authorization flows, please read -[plugin docs](/gateway/latest/configure/auth/oidc-google). +[plugin docs](/gateway/latest/kong-plugins/authentication/oidc/google). diff --git a/src/kubernetes-ingress-controller/references/plugin-compatibility.md b/src/kubernetes-ingress-controller/references/plugin-compatibility.md index 9908009c3642..cb8dfcc5fb49 100644 --- a/src/kubernetes-ingress-controller/references/plugin-compatibility.md +++ b/src/kubernetes-ingress-controller/references/plugin-compatibility.md @@ -9,7 +9,7 @@ database. Note that some DB-less compatible plugins have some limitations or require non-default configuration for -[compatibility](/gateway/latest/reference/db-less-and-declarative-config/#plugin-compatibility). +[compatibility](/gateway/latest/production/deployment-topologies/db-less-and-declarative-config/#plugin-compatibility). ## Kong diff --git a/src/kubernetes-ingress-controller/support-policy.md b/src/kubernetes-ingress-controller/support-policy.md new file mode 100644 index 000000000000..3a0f2f3f985e --- /dev/null +++ b/src/kubernetes-ingress-controller/support-policy.md @@ -0,0 +1,35 @@ +--- +title: Version Support Policy +badge: enterprise +content-type: reference +--- + +The support for {{site.kic_product_name}} software versions is explained in this topic. + +{% include_cached /md/support-policy.md %} + +## Version support for Kong Ingress Controller (Enterprise) + +| Version | Released Date | End of Full Support | End of Sunset Support | +|:--------:|:-------------:|:-------------------:|:---------------------:| +| 2.5.x | 2022-07-11 | 2023-07-11 | 2024-07-11 | +| 2.4.x | 2022-06-15 | 2023-06-15 | 2024-06-15 | +| 2.3.x | 2022-04-05 | 2023-04-05 | 2024-04-05 | +| 2.2.x | 2022-02-04 | 2023-02-04 | 2024-02-04 | +| 2.1.x | 2022-01-05 | 2023-01-05 | 2024-01-05 | +| 2.0.x | 2021-10-07 | 2022-10-07 | 2023-10-07 | +| 1.3.x | 2021-05-27 | 2022-05-27 | 2024-05-27 | +| 1.2.x | 2021-03-24 | 2022-03-24 | 2024-03-24 | +| 1.1.x | 2020-12-09 | 2021-12-09 | 2023-12-09 | +| 1.0.x | 2020-10-05 | 2021-10-05 | 2023-10-05 | +| 0.x.x | 2018-06-02 | 2019-06-02 | 2020-06-02 | + +> *Table 1: Version Support for Kong Ingress Controller* + +## Additional terms +- The above is a summary only and is qualified by Kong’s [Support and Maintenance Policy](https://konghq.com/supportandmaintenancepolicy). +- The above applies to Kong standard software builds only. + +## See also +* [Version support policy for {{site.base_gateway}}](/gateway/latest/support-policy) +* [Version support policy for {{site.mesh_product_name}}](/mesh/latest/support-policy) diff --git a/src/mesh/availability-stages.md b/src/mesh/availability-stages.md new file mode 100644 index 000000000000..29c582eadfcc --- /dev/null +++ b/src/mesh/availability-stages.md @@ -0,0 +1,6 @@ +--- +title: Stages of software availability +content-type: reference +--- + +{% include_cached /md/availability-stages.md %} diff --git a/src/mesh/index.md b/src/mesh/index.md index 19900478be54..d4a729209b5b 100644 --- a/src/mesh/index.md +++ b/src/mesh/index.md @@ -22,7 +22,7 @@ both Kubernetes and VMs on any cloud. Built on top of CNCF's {{site.mesh_product_name}} extends Kuma and Envoy with enterprise features and support, while providing native integration with -[{{site.ee_product_name}}](https://konghq.com/products/kong-enterprise) for a +[{{site.ee_product_name}}](https://konghq.com/products/api-gateway-platform) for a full-stack connectivity platform for all of your services and APIs, across every cloud and environment. @@ -38,299 +38,7 @@ every cloud and environment. enterprise-grade service mesh with unique features in the service mesh landscape, while still relying on a neutral foundation. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      -Kuma -Kuma -Start Free - -Kong Mesh -Kong Mesh -Contact Sales -
      Core Service Mesh Capabilities
      All Kuma Policies
      All Traffic Management Policies
      All Observability Policies
      Multi-Zone & Multi-Cluster
      Multi-Zone Security - -{% info_tooltip %} -Allows you to secure multi-zone deployments with a JWT-based authentication that ensures only approved zones can join the cluster. -{% endinfo_tooltip %} -
      Multi-Mesh Support
      Zero-Trust and mTLS
      Built-in CA
      Provided CA
      -HashiCorp Vault CA - -{% info_tooltip %} -Allows you to enable HashiCorp Vault as an additional third-party backend for mTLS CAs that are used to setup zero-trust security, without storing the CAs in Kong Mesh proper. -{% endinfo_tooltip %} -
      -AWS Certificate Manager CA -{% info_tooltip %} -Allows you to enable AWS Certificate Manager as an additional third-party backend for the mTLS CAs that are used to setup zero-trust security, without storing the CAs in Kong Mesh proper. -{% endinfo_tooltip %} -
      -Kubernetes cert-manager CA -{% info_tooltip %} -Allows you to enable Kubernetes cert-manager as an additional third-party backend for the mTLS CAs that are used to setup zero-trust security, without storing the CAs in Kong Mesh proper. -{% endinfo_tooltip %} -
      -GUI Dashboard for TLS and CA -{% info_tooltip %} -Provides you with additional visual reports that display the rotation status of the data plane proxy certificates and the rotation of the CAs themselves, in a zero-trust service mesh. -{% endinfo_tooltip %} -
      Data Plane Certificate Rotation
      -CA Automatic Rotation -{% info_tooltip %} -Provides automatic rotation across different CAs with no downtime in addition to providing automatic rotation and certificate lifecycle management to the data plane proxy mTLS certificates. This feature combined with the GUI Dashboard for TLS and CA provides a complete solution for managing the entire lifecycle of zero-trust service meshes. -{% endinfo_tooltip %} -
      Enterprise Application Security
      -FIPS-140 Encryption - -{% info_tooltip %} -By default, FIPS-140 compliant encryption is automatically enabled in Kong Mesh on the Envoy-based data plane proxies. This doesn't require any additional steps other than running Kong Mesh itself. -{% endinfo_tooltip %} -
      -Embedded OPA Agent -{% info_tooltip %} -Kong Mesh ships with an embedded OPA agent in the data plane proxy sidecars, without requiring the user to run an additional dedicated sidecar for the OPA agent. This simplifies the roll out of OPA across the entire organization and lowers operational costs. -{% endinfo_tooltip %} -
      -Native OPA Policy -{% info_tooltip %} -This exposes a native OPA policy resource that can be used to store and automatically propagate OPA policies across a multi-zone deployment natively with Kong Mesh. We also support the ability to connect to a third-party OPA store like Styra. -{% endinfo_tooltip %} -
      Enterprise Security and Governance
      -Roles and permissions (RBAC) -{% info_tooltip %} -Allows you to manage complex RBAC rules to allow or deny access to Kong Mesh policies and functions in a sophisticated and fine grained way. This works across multi-zone and multi-mesh natively. -{% endinfo_tooltip %} -
      -Audit Logs -{% info_tooltip %} -Allows you to store and fetch auditing logs for operations that were performed on the cluster. When used with RBAC, it allows us to have full visibility into how the system is being governed and configured by the users. -{% endinfo_tooltip %} -
      Universal Platform Distributions
      Containers, Kubernetes & OpenShift
      -Kubernetes Operator -{% info_tooltip %} -Allows you to simplify the operational cost of running Kong Mesh on Kubernetes by providing a native Kubernetes operator to fully manage the deployment, upgrades, and roll outs of a cluster on Kubernetes. -{% endinfo_tooltip %} -
      Virtual Machine Support
      Virtual Machine Transparent Proxying
      -Native AWS ECS Controller -{% info_tooltip %} -Allows you to natively support AWS ECS workloads with a built-in controller that automatically integrates ECS workloads within one or more service meshes powered by Kong Mesh. This simplifies the expansion of service mesh in the cloud. -{% endinfo_tooltip %} -
      -Windows Distributions -{% info_tooltip %} -Allows you to natively support Microsoft Windows workloads in service meshes, allowing you to further expand the reach of Kong Mesh across every workload in your organization. -{% endinfo_tooltip %} -
      -UBI Federal Distributions -{% info_tooltip %} -Provides officially supported distributions based on the Red Hat Universal Base Images (UBI). -{% endinfo_tooltip %} -
      Support and Customer Success
      -Enterprise Support and SLA -{% info_tooltip %} -With Kong Mesh, we provide 24/7/365 enterprise support with different SLAs, powered by Kong's global customer success and technical support team across all world regions. This also provides access to a vast network of partners for local language support as well. This is recommended for enterprise mission-critical deployments. -{% endinfo_tooltip %} -
      -Customer Success Packages -{% info_tooltip %} -With Kong Mesh, we provide access to our implementation and training programs to accelerate the roll out of a service mesh across every team, and to properly train and educate the organization on how to effectively drive business outcomes with the product. -{% endinfo_tooltip %} -
      -Envoy Support -{% info_tooltip %} -With Kong Mesh, we provide access to the Envoy contributors at Kong to further expand the capabilities of the underlying data plane proxy technology (Envoy) with features that are not currently available in upstream Envoy. This can be used to remove road blocks and cater to unique enterprise requirements and use-cases. -{% endinfo_tooltip %} -
      +{% include_cached feature-table.html config=site.data.tables.features.mesh %}
      @@ -430,3 +138,10 @@ hybrid Kubernetes/VMs:
      [Learn more](https://kuma.io/docs/latest/introduction/deployments/) about the standalone and multi-zone deployment modes in the Kuma documentation. + +## Support policy +Kong primarily follows a [semantic versioning](https://semver.org/) (SemVer) +model for its products. + +For the latest version support information for +{{site.mesh_product_name}}, see our [version support policy](/mesh/latest/support-policy). diff --git a/src/mesh/support-policy.md b/src/mesh/support-policy.md new file mode 100644 index 000000000000..1be9530bbcfd --- /dev/null +++ b/src/mesh/support-policy.md @@ -0,0 +1,29 @@ +--- +title: Version Support Policy +badge: enterprise +content-type: reference +--- + +The support for {{site.mesh_product_name}} software versions is explained in this topic. + +{% include_cached /md/support-policy.md %} + +## Version support for {{site.mesh_product_name}} + +| Version | Released Date | End of Full Support | +|:--------:|:-------------:|:-------------------:| +| 1.8.x | 2022-06-15 | 2023-06-14 | +| 1.7.x | 2022-04-11 | 2023-04-10 | +| 1.6.x | 2022-02-24 | 2023-02-23 | +| 1.5.x | 2021-11-23 | 2022-11-22 | + +> *Table 1: Version Support for {{site.mesh_product_name}}* + +## Additional terms +- The above is a summary only and is qualified by Kong’s [Support and Maintenance Policy](https://konghq.com/supportandmaintenancepolicy). +- The above applies to Kong standard software builds only. + +## See also + +* [Version support policy for {{site.base_gateway}}](/gateway/latest/support-policy) +* [Version support policy for {{site.kic_product_name}}](/kubernetes-ingress-controller/latest/support-policy) diff --git a/tests/breadcrumbs.test.js b/tests/breadcrumbs.test.js index 214cd9803f36..ae5c219374f0 100644 --- a/tests/breadcrumbs.test.js +++ b/tests/breadcrumbs.test.js @@ -7,10 +7,10 @@ describe("Gateway", () => { "Home" ); await expect($(".breadcrumb-item:nth-of-type(2)")).toHaveTextAllowingWhitespace( - "Kong Gateway" + "Kong Enterprise" ); await expect($(".breadcrumb-item:nth-of-type(3)")).toHaveTextAllowingWhitespace( - "Plugin development" + "Plugin Development" ); }); @@ -25,7 +25,7 @@ describe("Gateway", () => { "Kong Gateway (OSS)" ); await expect($(".breadcrumb-item:nth-of-type(3)")).toHaveTextAllowingWhitespace( - "Plugin development" + "Plugin Development" ); }); diff --git a/tests/edit_link.test.js b/tests/edit_link.test.js index 6f47e20e35d0..7f0e1cbc601b 100644 --- a/tests/edit_link.test.js +++ b/tests/edit_link.test.js @@ -17,7 +17,7 @@ describe("Edit this page link", () => { title: "/app/ page /latest/", src: "/gateway/latest/", expected: - "https://github.com/Kong/docs.konghq.com/edit/main/app/gateway/2.8.x/index.md", + "https://github.com/Kong/docs.konghq.com/edit/main/src/gateway/index.md", }, { title: "Single Sourced /latest/", diff --git a/tests/install.test.js b/tests/install.test.js index 04792a4dd118..688a2f8523c5 100644 --- a/tests/install.test.js +++ b/tests/install.test.js @@ -1,4 +1,4 @@ test("latest page contains a version", async () => { - const $ = await fetchPage("/gateway/latest/install-and-run/rhel/"); + const $ = await fetchPage("/gateway/latest/install/linux/rhel/"); await expect($(".codeblock")).not.toContainText("kong-enterprise-edition-.rpm"); }); diff --git a/tests/seo.test.js b/tests/seo.test.js index e92b8da7f0a8..8c6ff203db6e 100644 --- a/tests/seo.test.js +++ b/tests/seo.test.js @@ -14,13 +14,13 @@ describe("Canonical links", () => { { title: "contains a canonical link pointing to itself if it's the latest version", - src: "/gateway/latest/install-and-run/docker/", - href: "/gateway/latest/install-and-run/docker/", + src: "/gateway/latest/install/kubernetes/helm-quickstart/", + href: "/gateway/latest/install/kubernetes/helm-quickstart/", }, { title: "plugins contain a canonical link pointing to the latest version of a plugin", - src: "/hub/kong-inc/application-registration/1.0.x.html", + src: "/hub/kong-inc/application-registration/2.8.x.html", href: "/hub/kong-inc/application-registration/", }, { @@ -77,7 +77,7 @@ describe("noindex links", () => { }, { title: "contains a noindex tag for old plugin versions", - src: "/hub/kong-inc/application-registration/1.0.x.html", + src: "/hub/kong-inc/application-registration/2.8.x.html", }, ].forEach((t) => { test(t.title, async () => { @@ -115,10 +115,6 @@ describe("unversioned content", () => { title: "konnect", src: "/konnect/", }, - { - title: "konnect-platform", - src: "/konnect-platform/", - }, { title: "contributing", src: "/contributing/", @@ -137,12 +133,11 @@ describe("unversioned content", () => { describe("sitemap includes", () => { [ "/konnect/", - "/konnect-platform/", "/gateway/latest/", "/mesh/latest/", "/kubernetes-ingress-controller/latest/", "/deck/latest/", - "/gateway/latest/install-and-run/docker/", + "/gateway/latest/install/kubernetes/helm-quickstart/", "/mesh/latest/installation/ecs/", "/kubernetes-ingress-controller/latest/deployment/k4k8s/", "/deck/latest/installation/", @@ -164,7 +159,6 @@ describe("sitemap does not include", () => { "/gateway/2.6.x/configure/auth/kong-manager/oidc/", "/mesh/1.6.x/", "/mesh/1.1.x/overview/", - "/konnect-platform/compatibility/", "/deck/", "/gateway/", ].forEach((t) => { diff --git a/tests/sidebar.test.js b/tests/sidebar.test.js index 2c1ea6590d69..5516b66f2fb5 100644 --- a/tests/sidebar.test.js +++ b/tests/sidebar.test.js @@ -35,16 +35,16 @@ describe("Version Switcher", () => { [ { title: "links to the same page if it exists in previous versions", - page: "/enterprise/2.5.x/deployment/installation/docker/", - selector: 'a[data-version-id="2.1.x"]', - href: "/enterprise/2.1.x/deployment/installation/docker/", + page: "/gateway/2.8.x/install-and-run/docker/", + selector: 'a[data-version-id="2.6.x"]', + href: "/gateway/2.6.x/install-and-run/docker/", }, { title: "links to the root page if the page does not exist in previous versions", - page: "/enterprise/2.5.x/deployment/installation/docker/", - selector: 'a[data-version-id="0.34-x"]', - href: "/enterprise/0.34-x", + page: "/gateway/2.8.x/admin-api/consumer-groups/examples/", + selector: 'a[data-version-id="2.6.x"]', + href: "/gateway/2.6.x", }, ].forEach((t) => { test(t.title, async () => { @@ -63,7 +63,7 @@ describe("Outdated version documentation", () => { test("does not show on the latest version", async () => { const $ = await fetchPage( - `/gateway/${latestGatewayVersion}/install-and-run/rhel/` + `/gateway/${latestGatewayVersion}/install/linux/rhel/` ); await expect($(oldVersionSelector)).toHaveCount(0); }); @@ -73,16 +73,7 @@ describe("Outdated version documentation", () => { const s = $(oldVersionSelector); await expect(s).toHaveCount(1); await expect(s.attr("href")).toMatch( - new RegExp(`^/gateway/latest/install-and-run/rhel/$`) - ); - }); - - test("links to the root when the page no longer exists", async () => { - const $ = await fetchPage(`/enterprise/0.31-x/postgresql-redhat/`); - const s = $(oldVersionSelector); - await expect(s).toHaveCount(1); - await expect(s.attr("href")).toMatch( - new RegExp(`^/gateway/$`) + new RegExp(`^/gateway/latest/install/linux/rhel/$`) ); }); }); @@ -104,7 +95,7 @@ describe("Sidebar section count", () => { { title: "Gateway Single Sourced", path: "/gateway/latest/", - count: 8, + count: 9, }, { title: "decK", @@ -124,8 +115,8 @@ describe("sidenav versions", () => { { title: "Root page links to /latest/", src: "/gateway/latest/", - link_text: "Docker", - expected_url: "/gateway/latest/install-and-run/docker", + link_text: "Supported Distributions", + expected_url: "/gateway/latest/install/linux/os-support", }, { title: "Versioned root page links to the correct version", @@ -136,8 +127,8 @@ describe("sidenav versions", () => { { title: "Sub page links to latest", src: "/gateway/latest/admin-api/", - link_text: "Docker", - expected_url: "/gateway/latest/install-and-run/docker", + link_text: "Supported Distributions", + expected_url: "/gateway/latest/install/linux/os-support", }, { title: "Versioned sub page links to the correct version", diff --git a/tests/titles.test.js b/tests/titles.test.js index a20e0cde54d3..c082517c32d1 100644 --- a/tests/titles.test.js +++ b/tests/titles.test.js @@ -10,11 +10,6 @@ describe("Page titles", () => { src: "/hub/kong-inc/application-registration/", expected: "Portal Application Registration plugin | Kong Docs", }, - { - title: "Plugin Page (old style, file on disk)", - src: "/hub/kong-inc/application-registration/1.0.x.html", - expected: "Portal Application Registration plugin | Kong Docs", - }, ].forEach((t) => { test(t.title, async () => { const $ = await fetchPage(t.src); diff --git a/tools/moved-urls-checker/README.md b/tools/moved-urls-checker/README.md new file mode 100644 index 000000000000..ed1a95bf48f7 --- /dev/null +++ b/tools/moved-urls-checker/README.md @@ -0,0 +1,40 @@ +# Moved URLs checker + +The docs site calculates a canonical URL for any page using the following logic: + +1. Check if there's a page that exists with the exact same path, but a higher version number in the URL +1. Check if there's an entry in `moved_urls.yml` for the resolved path that points to a new URL + +`/gateway/2.7.x/install-and-run/` will resolve to `/gateway/2.8.x/install-and-run/` automatically. + +If there is an entry in `moved_urls.yml` that says `/gateway/VERSION/install-and-run/: /gateway/VERSION/install/` then the canonical URL for `/gateway/2.7.x/install-and-run/` will resolve to `/gateway/latest/install`. + +If there is no entry in `moved_urls.yml` **and** we're on the highest version available for a page, but it's not the latest version available, **this is an error**. The "latest version" URL will link to the same page that the user is on. In this instance, we need to add an entry to `moved_urls.yml` to direct them to the new, updated URL. + +## Running the tool + +To help prevent the error case where a page links to itself as the canonical URL, but isn't the latest version, we have a tool: + +```bash +make build +netlify dev +``` + +Then in another terminal, from the root of your clone of the docs repo: + +```bash +cd tools/moved-urls-checker +npm ci +node run.js --nav gateway_2.8.x +``` + +If there are errors, you'll get a list of URLs to resolve: + +``` +----------------------------------------------------------------- +Pages that link to themselves (no moved_urls.yml entry set): +----------------------------------------------------------------- +http://localhost:8888/gateway/2.8.x/availability-stages/ +http://localhost:8888/gateway/2.8.x/install-and-run/centos/ +http://localhost:8888/gateway/2.8.x/get-started/quickstart/configuring-a-service/ +``` \ No newline at end of file diff --git a/tools/moved-urls-checker/package-lock.json b/tools/moved-urls-checker/package-lock.json new file mode 100644 index 000000000000..612622b2fb9d --- /dev/null +++ b/tools/moved-urls-checker/package-lock.json @@ -0,0 +1,429 @@ +{ + "name": "moved-urls-checker", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "moved-urls-checker", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "cheerio": "^1.0.0-rc.12", + "js-yaml": "^4.1.0", + "minimist": "^1.2.6", + "node-fetch": "^2" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" + }, + "node_modules/cheerio": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", + "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "htmlparser2": "^8.0.1", + "parse5": "^7.0.0", + "parse5-htmlparser2-tree-adapter": "^7.0.0" + }, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/cheerio-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "dependencies": { + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz", + "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.1" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/entities": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", + "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/htmlparser2": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz", + "integrity": "sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "entities": "^4.3.0" + } + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" + }, + "node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/parse5": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.0.0.tgz", + "integrity": "sha512-y/t8IXSPWTuRZqXc0ajH/UwDj4mnqLEbSttNbThcFhGrZuOyoyvNBO85PBp2jQa55wY9d07PBNjsK8ZP3K5U6g==", + "dependencies": { + "entities": "^4.3.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", + "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", + "dependencies": { + "domhandler": "^5.0.2", + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + } + }, + "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" + }, + "cheerio": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", + "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", + "requires": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "htmlparser2": "^8.0.1", + "parse5": "^7.0.0", + "parse5-htmlparser2-tree-adapter": "^7.0.0" + } + }, + "cheerio-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "requires": { + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + } + }, + "css-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "requires": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + } + }, + "css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==" + }, + "dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "requires": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + } + }, + "domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==" + }, + "domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "requires": { + "domelementtype": "^2.3.0" + } + }, + "domutils": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz", + "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==", + "requires": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.1" + } + }, + "entities": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", + "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==" + }, + "htmlparser2": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz", + "integrity": "sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==", + "requires": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "entities": "^4.3.0" + } + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "requires": { + "argparse": "^2.0.1" + } + }, + "minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" + }, + "node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "requires": { + "whatwg-url": "^5.0.0" + } + }, + "nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "requires": { + "boolbase": "^1.0.0" + } + }, + "parse5": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.0.0.tgz", + "integrity": "sha512-y/t8IXSPWTuRZqXc0ajH/UwDj4mnqLEbSttNbThcFhGrZuOyoyvNBO85PBp2jQa55wY9d07PBNjsK8ZP3K5U6g==", + "requires": { + "entities": "^4.3.0" + } + }, + "parse5-htmlparser2-tree-adapter": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", + "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", + "requires": { + "domhandler": "^5.0.2", + "parse5": "^7.0.0" + } + }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + } + } +} diff --git a/tools/moved-urls-checker/package.json b/tools/moved-urls-checker/package.json new file mode 100644 index 000000000000..e17bb206c7da --- /dev/null +++ b/tools/moved-urls-checker/package.json @@ -0,0 +1,18 @@ +{ + "name": "moved-urls-checker", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "MIT", + "dependencies": { + "cheerio": "^1.0.0-rc.12", + "js-yaml": "^4.1.0", + "minimist": "^1.2.6", + "node-fetch": "^2" + } +} diff --git a/tools/moved-urls-checker/run.js b/tools/moved-urls-checker/run.js new file mode 100644 index 000000000000..4899bae2c659 --- /dev/null +++ b/tools/moved-urls-checker/run.js @@ -0,0 +1,124 @@ +const argv = require("minimist")(process.argv.slice(2)); + +const yaml = require("js-yaml"); +const fs = require("fs"); + +const fetch = require("node-fetch"); +const cheerio = require("cheerio"); + +(async function () { + let host = argv.host || "http://localhost:8888"; + if (host[host.length - 1] == "/") { + host = host.substring(0, host.length - 1); + } + + if ( + host.includes("https://docs.konghq.com") || + host.includes("http://docs.konghq.com") + ) { + console.log("This tool can not be run against production"); + process.exit(1); + } + + const defaultIndex = "/gateway/latest/"; + + const perPage = argv.perPage || 10; + const page = argv.page; + + const nav = argv.nav; + if (!nav) { + console.log("Provide a nav file e.g. 'gateway_3.0.x' using --nav"); + process.exit(1); + } + + let items = yaml.load( + fs.readFileSync(`../../app/_data/docs_nav_${nav}.yml`, "utf8") + ); + + // If it's a single sourced doc, extract the items directly + if (items.items) { + items = items.items; + } + + const prefix = `/${nav.replace("_", "/")}`; + let urls = extractNav(items, prefix); + + if (page !== undefined) { + const offset = page * perPage; + urls = urls.slice(offset, offset + perPage); + } + + urls = urls.map((u) => `${host}${u}`); + + if (urls.length) { + console.log(`Checking the following URLs:\n\n${urls.join("\n")}\n`); + + // Check all the URLs provided + const r = await checkUrls(urls, host); + + // Output report + if (r.length) { + console.log("-----------------------------------------------------------------") + console.log( + "Pages that link to themselves (no moved_urls.yml entry set):" + ); + console.log("-----------------------------------------------------------------") + console.log(r.join("\n")); + process.exit(1); + } + + console.log("No broken latest URLs detected"); + } else { + console.log("No URLs detected to test"); + } +})(); + +async function checkUrls(urls, host) { + const broken = []; + + for (let u of urls) { + u = normaliseUrl(u); + const response = await fetch(u); + const body = await response.text(); + const $ = cheerio.load(body); + const notice = $(".content-header+blockquote.important a"); + + // If the page doesn't contain a notice, skip it + if (!notice.length){ + continue; + } + + // Ensure both URLs are normalised + const href = normaliseUrl(notice.attr("href"), host); + + if (u == href) { + broken.push(u); + } + } + return broken; +} + +function extractNav(items, base) { + let urls = []; + for (let u of items) { + if (u.items) { + urls = urls.concat(extractNav(u.items, base)); + } else { + if (u.absolute_url) { + urls.push(u.url); + } else { + urls.push(`${base}${u.url}`); + } + } + } + return urls; +} + +function normaliseUrl(u, prefix) { + prefix = prefix || ""; + if (u[u.length - 1] == "/") { + u = u.substring(0, u.length - 1); + } + + return `${prefix}${u}/`; +}