Skip to main content

Cluster Level Configuration

This document is a guide to Kargo configuration options that are available to operators at runtime. These are generally analogs to Project level configuration options available to developers.

info

Not what you were looking for?

Most system level configuration options are exercised by operators at the time of installation or upgrade. For details, refer to Common Configurations and the Kargo Helm Chart's README.md.

Triggering Artifact Discovery Using Webhooks

If your cluster contains many Warehouse resources, which periodically poll artifact repositories, or if developers have configured any of those Warehouses poorly, you may have elected to reduce the frequency with which all Warehouses execute their artifact discovery processes (i.e. You may have elected to increase the minimum polling interval. See Common Configurations. )

If you have done this, it may have relieved degraded performance and helped to avoid encountering rate limits, but it will have been accompanied by the undesired side effect of increasing the average time required for every Warehouse to notice new artifacts. This can be overcome by configuring repositories to alert Kargo to the presence of new artifacts via webhooks.

Developers are able to configure Kargo to listen for inbound webhook requests from various sources at the Project level, however, in an organization with many separate repositories in one (or a few) Git hosting providers or container image registries, it may make more sense for an operator to configure Kargo to listen for inbound webhook requests at the cluster level.

To illustrate, consider a GitHub organization having many repositories belonging to different teams within the organization. Each team may have their own Kargo Project(s) for self-managing their promotion pipelines. Instead of every team configuring Project level GitHub webhook receivers that may trigger artifact discovery only for their own applicable Warehouses, you, as the operator, can configure one cluster-level GitHub webhook receiver to trigger the artifact discovery process of every applicable Warehouse across all Projects.

This can be accomplished easily by updating your ClusterConfig resource's spec.webhookReceivers field. If your cluster does not already have a ClusterConfig resource, you can create one.

note

Every cluster hosting a Kargo control plane is permitted to have at most one ClusterConfig resource. This limit is enforced by requiring all ClusterConfig resources to be named cluster.

A ClusterConfig resource's spec.webhookReceivers field may define one or more webhook receivers. A webhook receiver is an endpoint on a (typically) internet-facing HTTP server that is configured to receive and process requests from specific sources, and in response, trigger the discovery process of any Warehouse across all Projects that subscribes to a repository URL referenced by the request payload.

Most types of webhook receivers require you only to specify a unique name and a reference to a Secret. The expected keys and values for each kind of webhook receiver vary, and are documented on each receiver type's own page.

note

Because ClusterConfig resources are cluster-scoped resources and Kubernetes has no such thing as a "ClusterSecret" resource type (i.e. a cluster-scoped analog to Secret), Kargo will look for the referenced Secret in a designated namespace. By default, that namespace is kargo-cluster-secrets, but can be changed by the operator at the time of installation. (Refer to the Kargo Helm Chart's README.md. )

info

Secrets referenced by a webhook receiver typically serve two purposes.

  1. Often, some value(s) from the Secret's data map are shared with the webhook sender (GitHub, for instance) and used to help authenticate requests. Some senders may use such "shared secrets" as bearer tokens. Others may use them as keys for signing requests. In such cases, the corresponding webhook receiver knows exactly what to do with this information in order to authenticate inbound requests.

  2. Always, some value(s) from the Secret's data map are used as a seed in deterministically constructing a complex, hard-to-guess URL where the receiver will listen for inbound requests.

    Some webhook senders (Docker Hub, for instance), do not natively implement any sort of authentication mechanism. No secret value(s) need to be shared with such a sender and requests from the sender contain no bearer token, nor are they signed. For cases such as these, a hard-to-guess URL is, itself, a de facto shared secret and authentication mechanism.

    Note that if a Secret's value(s) are rotated, the URL where the receiver listens for inbound requests will also change. This is by design.

    Kargo does not watch Secrets for changes because it lacks the permissions to do so, so it can be some time after its Secret's value(s) are rotated that a webhook receiver's URL will be updated. To expedite that update, your ClusterConfig resource can be manually "refreshed" using the kargo CLI:

    kargo refresh clusterconfig

The following example ClusterConfig configures two webhook receivers:

apiVersion: kargo.akuity.io/v1alpha1
kind: Cluster
metadata:
name: cluster
spec:
webhookReceivers:
- name: my-first-receiver
github:
secretRef:
name: my-first-secret
- name: my-second-receiver
gitlab:
secretRef:
name: my-second-secret
---
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: my-first-secret
namespace: kargo-cluster-secrets
labels:
kargo.akuity.io/cred-type: generic
data:
secret: c295bGVudCBncmVlbiBpcyBwZW9wbGUK
---
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: my-second-secret
namespace: kargo-cluster-secrets
labels:
kargo.akuity.io/cred-type: generic
data:
secret-token: cm9zZWJ1ZCB3YXMgYSBzbGVkCg==
note

The kargo.akuity.io/cred-type: generic label on Secrets referenced by webhook receivers is not strictly required, but we strongly recommend including it.

For each properly configured webhook receiver, Kargo will update the ClusterConfig resource's status to reflect the URLs that can be registered as endpoints with the senders.

For instance, the ClusterConfig and Secrets above result in the following:

apiVersion: kargo.akuity.io/v1alpha1
kind: ClusterConfig
metadata:
name: cluster
spec:
# ... omitted for brevity ...
status:
conditions:
- lastTransitionTime: "2025-06-11T22:53:21Z"
message: ProjectConfig is synced and ready for use
observedGeneration: 1
reason: Synced
status: "True"
type: Ready
webhookReceivers:
- name: my-first-receiver
path: /webhook/github/804b6f6bb40eb1f0e371f971d71dd95549be4bc9cbf868046941115f44073c67
url: https://kargo.example.com/webhook/github/804b6f6bb40eb1f0e371f971d71dd95549be4bc9cbf868046941115f44073c67
- name: my-second-receiver
path: /webhook/gitlab/0eba9ff2a91f04f7787404b8f8f0edaf8cf8c39add34082651a474803cc99015
url: https://kargo.example.com/webhook/gitlab/0eba9ff2a91f04f7787404b8f8f0edaf8cf8c39add34082651a474803cc99015

Above, you can see the URLs that can be registered with GitHub and GitLab as endpoints to receive webhook requests from those platforms.

info

For more information about registering these endpoints with specific senders, refer to each receiver type's own page.

Receivers in Action

Once a webhook receiver has been assigned a URL and that URL has been registered with a compatible sender, the receiver will begin receiving webhook requests in response to events in your repositories. The payload (body) of such a request contains structured information (usually JSON) the sender wishes to share about some event. Invariably, among this information, is the URL of the repository from which the event originated.

A webhook receiver's only job is to extract a repository URL from the webhook request's payload, query for all Warehouse resources across all Projects having subscriptions to that repository, and request each to execute their artifact discovery process.