Skip to main content

Chainloop Helm Chart

Chainloop is an open-source software supply chain control plane, a single source of truth for artifacts plus a declarative attestation crafting process.

Introduction

This chart bootstraps a Chainloop deployment on a Kubernetes cluster using the Helm package manager.

Prerequisites

  • Kubernetes 1.19+
  • Helm 3.2.0+
  • PV provisioner support in the underlying infrastructure (If built-in PostgreSQL is enabled)

Compatibility with the following Ingress Controllers has been verified, other controllers might or might not work.

TL;DR

Deploy Chainloop in development mode by running

helm install [RELEASE_NAME] oci://ghcr.io/chainloop-dev/charts/chainloop --set development=true

CAUTION: Do not use this mode in production, for that, use the standard mode instead.

Installing the Chart

This chart comes in two flavors, standard and development.

Standard (default)

The default deployment mode relies on external dependencies to be available in advance.

The Helm Chart in this mode includes

During installation, you'll need to provide

Instructions on how to create the ECDSA keypair can be found here.

Installation examples for standard mode

NOTE: We do not recommend passing nor storing sensitive data in plain text. For production, please consider having your overrides encrypted with tools such as Sops, Helm Secrets or Sealed Secrets.

Deploy Chainloop configured to talk to the bundled PostgreSQL an external OIDC IDp and a Vault instance.

helm install [RELEASE_NAME] oci://ghcr.io/chainloop-dev/charts/chainloop \
# Open ID Connect (OIDC)
--set controlplane.auth.oidc.url=[OIDC URL] \
--set controlplane.auth.oidc.clientID=[clientID] \
--set controlplane.auth.oidc.clientSecret=[clientSecret] \
# Secrets backend
--set secretsBackend.vault.address="https://[vault address]:8200" \
--set secretsBackend.vault.token=[token] \
# Server Auth KeyPair
--set casJWTPrivateKey="$(cat private.ec.key)" \
--set casJWTPublicKey="$(cat public.pem)"

Deploy using AWS Secrets Manager instead of Vault

helm install [RELEASE_NAME] oci://ghcr.io/chainloop-dev/charts/chainloop \
# Open ID Connect (OIDC)
# ...
# Secrets backend
--set secretsBackend.backend=awsSecretManager \
--set secretsBackend.awsSecretManager.accessKey=[AWS ACCESS KEY ID] \
--set secretsBackend.awsSecretManager.secretKey=[AWS SECRET KEY] \
--set secretsBackend.awsSecretManager.region=[AWS region]\
# Server Auth KeyPair
# ...

or using GCP Secret Manager

helm install [RELEASE_NAME] oci://ghcr.io/chainloop-dev/charts/chainloop \
# Open ID Connect (OIDC)
# ...
# Secrets backend
--set secretsBackend.backend=gcpSecretManager \
--set secretsBackend.gcpSecretManager.projectId=[GCP Project ID] \
--set secretsBackend.gcpSecretManager.serviceAccountKey=[GCP Auth KEY] \
# Server Auth KeyPair
# ...

or Azure KeyVault

helm install [RELEASE_NAME] oci://ghcr.io/chainloop-dev/charts/chainloop \
# Open ID Connect (OIDC)
# ...
# Secrets backend
--set secretsBackend.backend=azureKeyVault \
--set secretsBackend.azureKeyVault.tenantID=[AD tenant ID] \
--set secretsBackend.azureKeyVault.clientID=[Service Principal ID] \
--set secretsBackend.azureKeyVault.clientSecret=[Service Principal secret] \
--set secretsBackend.azureKeyVault.vaultURI=[Azure KeyVault URI]
# Server Auth KeyPair
# ...

Connect to an external PostgreSQL database instead

helm install [RELEASE_NAME] oci://ghcr.io/chainloop-dev/charts/chainloop \
# Open ID Connect (OIDC)
# ...
# Secrets backend
# ...
# Server Auth KeyPair
# ...
# External DB setup
--set postgresql.enabled=false \
--set controlplane.externalDatabase.host=[DB_HOST] \
--set controlplane.externalDatabase.user=[DB_USER] \
--set controlplane.externalDatabase.password=[DB_PASSWORD] \
--set controlplane.externalDatabase.database=[DB_NAME]

Development

To provide an easy way to give Chainloop a try, this Helm Chart has an opt-in development mode that can be enabled with the flag development=true

IMPORTANT: DO NOT USE THIS MODE IN PRODUCTION

The Helm Chart in this mode includes

  • Chainloop Controlplane
  • Chainloop Artifact proxy
  • A PostgreSQL dependency enabled by default
  • A pre-configured Hashicorp Vault instance running in development mode (unsealed, in-memory, insecure)
  • A pre-configured Dex OIDC instance.

The pre-setup users configuration on the Chart include two users, the information is as follows:

username: sarah@chainloop.local
password: password

username: john@chainloop.local
password: password

The overall OIDC configuration can be found at dex-values.yaml

CAUTION: Do not use this mode in production, for that, use the standard mode instead.

Installation examples for development mode

Deploy by leveraging built-in Vault and PostgreSQL instances

helm install [RELEASE_NAME] oci://ghcr.io/chainloop-dev/charts/chainloop --set development=true

AirGap and Relocation Support

This chart is compatible with relocation processes performed by the Helm Relocation Plugin

This is a two-step process (wrap -> unwrap)

  • Pull all the container images and Helm chart and wrap them in an intermediate tarball.
  • Unwrap the tarball and push container images, update the Helm Chart with new image references and push it to the target registry.

For example: to relocate to an Azure Container Registry

helm dt wrap oci://ghcr.io/chainloop-dev/charts/chainloop
# 🎉 Helm chart wrapped into "chainloop-1.77.0.wrap.tgz"

# Now you can take the tarball to an air-gapped environment and unwrap it like this
helm dt unwrap chainloop-1.77.0.wrap.tgz oci://chainloop.azurecr.io --yes
# Unwrapping Helm chart "chainloop-1.77.0.wrap.tgz"
# ✔ All images pushed successfully
# ✔ Helm chart successfully pushed
#
# 🎉 Helm chart unwrapped successfully: You can use it now by running "helm install oci://chainloop.azurecr.io/chart/chainloop --generate-name"

How to guides

CAS upload speeds are slow, what can I do?

Chainloop uses gRPC streaming to perform artifact uploads. This method is susceptible to being very slow on high latency scenarios. #375

To improve upload speeds, you need to increase http2 flow control buffer. This can be done in NGINX by setting the following annotation in the ingress resource.

# Improve upload speed by adding client buffering used by http2 control-flows
nginx.ingress.kubernetes.io/client-body-buffer-size: "3M"

Note: For other reverse proxies, you'll need to find the equivalent configuration.

Generate a ECDSA key-pair

An ECDSA key-pair is required to perform authentication between the control-plane and the Artifact CAS

You can generate both the private and public keys by running

# Private Key (private.ec.key)
openssl ecparam -name secp521r1 -genkey -noout -out private.ec.key
# Public Key (public.pem)
openssl ec -in private.ec.key -pubout -out public.pem

Then, you can either provide it in a custom values.yaml file override

casJWTPrivateKey: |-
-----BEGIN EC PRIVATE KEY-----
REDACTED
-----END EC PRIVATE KEY-----
casJWTPublicKey: |
-----BEGIN PUBLIC KEY-----
REDACTED
-----END PUBLIC KEY-----

or as shown before, provide them as imperative inputs during Helm Install/Upgrade --set casJWTPrivateKey="$(cat private.ec.key)"--set casJWTPublicKey="$(cat public.pem)"

Enable a custom domain with TLS

Chainloop uses three endpoints so we'll need to enable the ingress resource for each one of them.

See below an example of a values.yaml override

controlplane:
ingress:
enabled: true
hostname: cp.chainloop.dev

ingressAPI:
enabled: true
hostname: api.cp.chainloop.dev

cas:
ingressAPI:
enabled: true
hostname: api.cas.chainloop.dev

A complete setup that uses

would look like

controlplane:
ingress:
enabled: true
tls: true
ingressClassName: nginx
hostname: cp.chainloop.dev
annotations:
# This depends on your configured issuer
cert-manager.io/cluster-issuer: "letsencrypt-prod"

ingressAPI:
enabled: true
tls: true
ingressClassName: nginx
hostname: api.cp.chainloop.dev
annotations:
nginx.ingress.kubernetes.io/backend-protocol: "GRPC"
cert-manager.io/cluster-issuer: "letsencrypt-prod"

cas:
ingressAPI:
enabled: true
tls: true
ingressClassName: nginx
hostname: api.cas.chainloop.dev
annotations:
nginx.ingress.kubernetes.io/backend-protocol: "GRPC"
cert-manager.io/cluster-issuer: "letsencrypt-prod"
# limit the size of the files that go through the proxy
# 0 means to not check the size of the request so we do not get 413 error.
# For now we are going to set a limit on 100MB files
# Even though we send data in chunks of 1MB, this size refers to all the data sent in the streaming connection
nginx.ingress.kubernetes.io/proxy-body-size: "100m"

Remember, once you have set up your domain, make sure you use the CLI pointing to it instead of the defaults.

Connect to an external PostgreSQL database

# Disable built-in DB
postgresql:
enabled: false

# Provide with external connection
controlplane:
externalDatabase:
host: 1.2.3.4
port: 5432
user: chainloop
password: [REDACTED]
database: chainloop-controlplane-prod

Alternatively, if you are using Google Cloud SQL and you are running Chainloop in Google Kubernetes Engine. You can connect instead via a proxy

This method can also be easily enabled in this chart by doing

# Disable built-in DB
postgresql:
enabled: false

# Provide with external connection
controlplane:
sqlProxy:
# Inject the proxy sidecar
enabled: true
## @param controlplane.sqlProxy.connectionName Google Cloud SQL connection name
connectionName: "my-sql-instance"
# Then you'll need to configure your DB settings to use the proxy IP address
externalDatabase:
host: [proxy-sidecar-ip-address]
port: 5432
user: chainloop
password: [REDACTED]
database: chainloop-controlplane-prod

Use AWS secrets manager

Instead of using Hashicorp Vault (default), you can use AWS Secrets Manager by adding these settings in your values.yaml file

secretsBackend:
backend: awsSecretManager
awsSecretManager:
accessKey: [KEY]
secretKey: [SECRET]
region: [REGION]

Use GCP secret manager

Or Google Cloud Secret Manager with the following settings

secretsBackend:
backend: gcpSecretManager
gcpSecretManager:
projectId: [PROJECT_ID]
serviceAccountKey: [KEY]

Use Azure KeyVault

Azure KeyVault is also supported

secretsBackend:
backend: azureKeyVault
azureKeyVault:
tenantID: [TENANT_ID] # Active Directory Tenant ID
clientID: [CLIENT_ID] # Registered application / service principal client ID
clientSecret: [CLIENT_SECRET] # Service principal client secret
vaultURI: [VAULT URI] # Azure Key Vault URL

Deploy in keyless mode with file-based CA

This feature is experimental, as it doesn't yet support verification.

You can enable keyless signing mode by providing a custom Certificate Authority. For example, these commands generate a self-signed certificate with an RSA private key of length 4096 and AES256 encryption with a validity of 365 days:

> openssl genrsa -aes256 -out ca.key 4096
...
> openssl req -new -x509 -sha256 -key ca.key -out ca.crt -days 365
...

Then you can configure your deployment values with:

controlplane:
keylessSigning:
enabled: true
backend: fileCA
fileCA:
cert: |
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
key: |
-----BEGIN ENCRYPTED PRIVATE KEY-----
...
-----END ENCRYPTED PRIVATE KEY-----
keyPass: "REDACTED"

Insert custom Certificate Authorities (CAs)

In some scenarios, you might want to add custom Certificate Authorities to the Chainloop deployment. Like in the instance where your OIDC provider uses a self-signed certificate. To do so, add the PEM-encoded CA certificate to the customCAs list in either controlplane or cas sections, in your values.yaml file like in the example below.

  customCAs:
- |-
-----BEGIN CERTIFICATE-----
MIIFmDCCA4CgAwIBAgIQU9C87nMpOIFKYpfvOHFHFDANBgkqhkiG9w0BAQsFADBm
BhMCVVMxMzAxBgNVBAoTKihTVEFHSU5HKSBJbnRlcm5ldCBTZWN1cml0eSBSZXNl
REDACTED
5CunuvCXmEQJHo7kGcViT7sETn6Jz9KOhvYcXkJ7po6d93A/jy4GKPIPnsKKNEmR
7DiA+/9Qdp9RBWJpTS9i/mDnJg1xvo8Xz49mrrgfmcAXTCJqXi24NatI3Oc=
-----END CERTIFICATE-----

Send exceptions to Sentry

You can configure different sentry projects for both the controlplane and the artifact CAS

# for controlplane
controlplane:
...
sentry:
enabled: true
dsn: [your secret sentry project DSN URL]
environment: production
# Artifact CAS
cas:
...
sentry:
enabled: true
dsn: [your secret sentry project DSN URL]
environment: production

Enable Prometheus Monitoring in GKE

Chainloop exposes Prometheus compatible /metrics endpoints that can be easily scraped by a Prometheus data collector Server.

Google Cloud has a managed Prometheus offering that could be easily enabled by setting --set GKEMonitoring.enabled=true. This will inject the required PodMonitoring custom resources.

Configure Chainloop CLI to point to your instance

Once you have your instance of Chainloop deployed, you need to configure the CLI to point to both the CAS and the Control plane gRPC APIs like this.

chainloop config save \
--control-plane my-controlplane.acme.com:443 \
--artifact-cas cas.acme.com:443

Parameters

Global parameters

NameDescriptionValue
global.imageRegistryGlobal Docker image registry""
global.imagePullSecretsGlobal Docker registry secret names as an array[]
global.compatibility.openshift.adaptSecurityContextAdapt the securityContext sections of the deployment to make them compatible with Openshift restricted-v2 SCC: remove runAsUser, runAsGroup and fsGroup and let the platform use their allowed default IDs. Possible values: auto (apply if the detected running cluster is Openshift), force (perform the adaptation always), disabled (do not perform adaptation)auto
developmentDeploys Chainloop pre-configured FOR DEVELOPMENT ONLY. It includes a Vault instance in development mode and pre-configured authentication certificates and passphrasesfalse

Common parameters

NameDescriptionValue
kubeVersionOverride Kubernetes version""
commonAnnotationsAnnotations to add to all deployed objects{}
commonLabelsLabels to add to all deployed objects{}
extraDeployArray of extra objects to deploy with the release[]

Secrets Backend

NameDescriptionValue
secretsBackend.backendSecrets backend type ("vault", "awsSecretManager" or "gcpSecretManager", "azureKeyVault")vault
secretsBackend.secretPrefixPrefix that will be pre-pended to all secrets in the storage backendchainloop
secretsBackend.vault.addressVault address
secretsBackend.vault.tokenVault authentication token
secretsBackend.awsSecretManager.accessKeyAWS Access KEY ID
secretsBackend.awsSecretManager.secretKeyAWS Secret Key
secretsBackend.awsSecretManager.regionAWS Secrets Manager Region
secretsBackend.gcpSecretManager.projectIdGCP Project ID
secretsBackend.gcpSecretManager.serviceAccountKeyGCP Auth Key
secretsBackend.azureKeyVault.tenantIDActive Directory Tenant ID
secretsBackend.azureKeyVault.clientIDRegistered application / service principal client ID
secretsBackend.azureKeyVault.clientSecretService principal client secret
secretsBackend.azureKeyVault.vaultURIAzure Key Vault URL

Authentication

NameDescriptionValue
casJWTPrivateKeyECDSA (ES512) private key used for Controlplane to CAS Authentication""
casJWTPublicKeyECDSA (ES512) public key""

Control Plane

NameDescriptionValue
controlplane.replicaCountNumber of replicas2
controlplane.image.registryImage registryREGISTRY_NAME
controlplane.image.repositoryImage repositoryREPOSITORY_NAME
controlplane.containerPorts.httpcontrolplane HTTP container port8000
controlplane.containerPorts.grpccontrolplane gRPC container port9000
controlplane.containerPorts.metricscontrolplane prometheus metrics container port5000
controlplane.tls.existingSecretExisting secret name containing TLS certificate to be used by the controlplane grpc server""
controlplane.pluginsDirDirectory where to look for plugins/plugins
controlplane.referrerSharedIndexConfigure the shared, public index API endpoint that can be used to discover metadata referrers
controlplane.referrerSharedIndex.enabledEnable index API endpointfalse
controlplane.referrerSharedIndex.allowedOrgsList of UUIDs of organizations that are allowed to publish to the shared index[]
controlplane.onboarding.nameName of the organization to onboard
controlplane.onboarding.roleRole of the organization to onboard
controlplane.prometheus_org_metricsList of organizations to expose metrics for using Prometheus
controlplane.policy_providersList of endpoints providing external policies
controlplane.migration.image.registryImage registryREGISTRY_NAME
controlplane.migration.image.repositoryImage repositoryREPOSITORY_NAME
controlplane.migration.sslConnect to the database using SSL (required fro AWS RDS, etc)false

Control Plane Database

NameDescriptionValue
controlplane.externalDatabaseExternal PostgreSQL configuration. These values are only used when postgresql.enabled is set to false
controlplane.externalDatabase.hostDatabase host""
controlplane.externalDatabase.portDatabase port number5432
controlplane.externalDatabase.userNon-root username""
controlplane.externalDatabase.databaseDatabase name""
controlplane.externalDatabase.passwordPassword for the non-root username""

Control Plane Authentication

NameDescriptionValue
controlplane.auth.passphrasePassphrase used to sign the Auth Tokens generated by the controlplane. Leave empty for auto-generation""
controlplane.auth.oidc.urlFull authentication path, it should match the issuer URL of the Identity provider (IDp)""
controlplane.auth.oidc.clientIDOIDC IDp clientID""
controlplane.auth.oidc.clientSecretOIDC IDp clientSecret""
controlplane.auth.oidc.loginURLOverrideOptional OIDC login URL override, useful to point to custom login pages
controlplane.auth.oidc.externalURLOptional External URL for the controlplane to the outside world
controlplane.auth.allowList.rulesList of domains or emails to allow
controlplane.auth.allowList.selectedRoutesList of selected routes to allow. If not set it applies to all routes
controlplane.auth.allowList.customMessageCustom message to display when a user is not allowed

Control Plane Networking

NameDescriptionValue
controlplane.service.typeService typeClusterIP
controlplane.service.ports.httpcontrolplane service HTTP port80
controlplane.service.ports.httpscontrolplane service HTTPS port443
controlplane.service.nodePorts.httpNode port for HTTP""
controlplane.service.nodePorts.httpsNode port for HTTPS""
controlplane.service.clusterIPcontrolplane service Cluster IP""
controlplane.service.loadBalancerIPcontrolplane service Load Balancer IP""
controlplane.service.loadBalancerSourceRangescontrolplane service Load Balancer sources[]
controlplane.service.externalTrafficPolicycontrolplane service external traffic policyCluster
controlplane.service.annotationsAdditional custom annotations for controlplane service{}
controlplane.service.extraPortsExtra ports to expose in controlplane service (normally used with the sidecars value)[]
controlplane.service.sessionAffinityControl where client requests go, to the same pod or round-robinNone
controlplane.service.sessionAffinityConfigAdditional settings for the sessionAffinity{}
controlplane.serviceAPI.typeService typeClusterIP
controlplane.serviceAPI.ports.httpcontrolplane service HTTP port80
controlplane.serviceAPI.ports.httpscontrolplane service HTTPS port443
controlplane.serviceAPI.nodePorts.httpNode port for HTTP""
controlplane.serviceAPI.nodePorts.httpsNode port for HTTPS""
controlplane.serviceAPI.clusterIPcontrolplane service Cluster IP""
controlplane.serviceAPI.loadBalancerIPcontrolplane service Load Balancer IP""
controlplane.serviceAPI.loadBalancerSourceRangescontrolplane service Load Balancer sources[]
controlplane.serviceAPI.externalTrafficPolicycontrolplane service external traffic policyCluster
controlplane.serviceAPI.annotationsAdditional custom annotations for controlplane service
controlplane.serviceAPI.extraPortsExtra ports to expose in controlplane service (normally used with the sidecars value)[]
controlplane.serviceAPI.sessionAffinityControl where client requests go, to the same pod or round-robinNone
controlplane.serviceAPI.sessionAffinityConfigAdditional settings for the sessionAffinity{}
controlplane.ingress.enabledEnable ingress record generation for controlplanefalse
controlplane.ingress.pathTypeIngress path typeImplementationSpecific
controlplane.ingress.hostnameDefault host for the ingress recordcp.dev.local
controlplane.ingress.ingressClassNameIngressClass that will be be used to implement the Ingress (Kubernetes 1.18+)""
controlplane.ingress.pathDefault path for the ingress record/
controlplane.ingress.annotationsAdditional annotations for the Ingress resource. To enable certificate autogeneration, place here your cert-manager annotations.{}
controlplane.ingress.tlsEnable TLS configuration for the host defined at controlplane.ingress.hostname parameterfalse
controlplane.ingress.selfSignedCreate a TLS secret for this ingress record using self-signed certificates generated by Helmfalse
controlplane.ingress.extraHostsAn array with additional hostname(s) to be covered with the ingress record[]
controlplane.ingress.extraPathsAn array with additional arbitrary paths that may need to be added to the ingress under the main host[]
controlplane.ingress.extraTlsTLS configuration for additional hostname(s) to be covered with this ingress record[]
controlplane.ingress.secretsCustom TLS certificates as secrets[]
controlplane.ingress.extraRulesAdditional rules to be covered with this ingress record[]
controlplane.ingressAPI.enabledEnable ingress record generation for controlplanefalse
controlplane.ingressAPI.pathTypeIngress path typeImplementationSpecific
controlplane.ingressAPI.hostnameDefault host for the ingress recordapi.cp.dev.local
controlplane.ingressAPI.ingressClassNameIngressClass that will be be used to implement the Ingress (Kubernetes 1.18+)""
controlplane.ingressAPI.pathDefault path for the ingress record/
controlplane.ingressAPI.annotationsAdditional annotations for the Ingress resource. To enable certificate autogeneration, place here your cert-manager annotations.
controlplane.ingressAPI.tlsEnable TLS configuration for the host defined at controlplane.ingress.hostname parameterfalse
controlplane.ingressAPI.selfSignedCreate a TLS secret for this ingress record using self-signed certificates generated by Helmfalse
controlplane.ingressAPI.extraHostsAn array with additional hostname(s) to be covered with the ingress record[]
controlplane.ingressAPI.extraPathsAn array with additional arbitrary paths that may need to be added to the ingress under the main host[]
controlplane.ingressAPI.extraTlsTLS configuration for additional hostname(s) to be covered with this ingress record[]
controlplane.ingressAPI.secretsCustom TLS certificates as secrets[]
controlplane.ingressAPI.extraRulesAdditional rules to be covered with this ingress record[]

Controlplane Misc

NameDescriptionValue
controlplane.resourcesPresetSet init container resources according to one common preset (allowed values: none, nano, small, medium, large, xlarge, 2xlarge). This is ignored if volumePermissions.resources is set (volumePermissions.resources is recommended for production).micro
controlplane.resourcesSet controlplane container requests and limits for different resources like CPU or memory (essential for production workloads){}
controlplane.podSecurityContext.enabledEnable controlplane pods' Security Contexttrue
controlplane.podSecurityContext.fsGroupChangePolicySet filesystem group change policy for controlplane podsAlways
controlplane.podSecurityContext.sysctlsSet kernel settings using the sysctl interface for controlplane pods[]
controlplane.podSecurityContext.supplementalGroupsSet filesystem extra groups for controlplane pods[]
controlplane.podSecurityContext.fsGroupSet fsGroup in controlplane pods' Security Context1001
controlplane.containerSecurityContext.enabledEnabled controlplane container' Security Contexttrue
controlplane.containerSecurityContext.seLinuxOptionsSet SELinux options in controlplane container{}
controlplane.containerSecurityContext.runAsUserSet runAsUser in controlplane container' Security Context1001
controlplane.containerSecurityContext.runAsGroupSet runAsGroup in controlplane container' Security Context1001
controlplane.containerSecurityContext.runAsNonRootSet runAsNonRoot in controlplane container' Security Contexttrue
controlplane.containerSecurityContext.readOnlyRootFilesystemSet readOnlyRootFilesystem in controlplane container' Security Contexttrue
controlplane.containerSecurityContext.privilegedSet privileged in controlplane container' Security Contextfalse
controlplane.containerSecurityContext.allowPrivilegeEscalationSet allowPrivilegeEscalation in controlplane container' Security Contextfalse
controlplane.containerSecurityContext.capabilities.dropList of capabilities to be dropped in controlplane container["ALL"]
controlplane.containerSecurityContext.seccompProfile.typeSet seccomp profile in controlplane containerRuntimeDefault
controlplane.sentry.enabledEnable sentry.io alertingfalse
controlplane.sentry.dsnDSN endpoint""
controlplane.sentry.environmentEnvironment tagproduction

Keyless signing configuration

NameDescriptionValue
controlplane.keylessSigning.enabledActivates or deactivates the featurefalse
controlplane.keylessSigning.backendThe backend to use. Currently only "fileCA" and "ejbcaCA" are supportedfileCA
controlplane.keylessSigning.fileCA.certThe PEM-encoded certificate of the file based CA""
controlplane.keylessSigning.fileCA.keyThe PEM-encoded private key of the file based CA""
controlplane.keylessSigning.fileCA.keyPassThe secret key pass""
controlplane.keylessSigning.ejbcaCA.serverURLThe url of the EJBCA service ("https://host/ejbca")""
controlplane.keylessSigning.ejbcaCA.clientKeyPEM-encoded the private key for EJBCA cert authentication""
controlplane.keylessSigning.ejbcaCA.clientCertPEM-encoded certificate for EJBCA cert authentication""
controlplane.keylessSigning.ejbcaCA.certProfileNameName of the certificate profile to use in EJBCA""
controlplane.keylessSigning.ejbcaCA.endEntityProfileNameName of the Entity Profile to use in EJBCA""
controlplane.keylessSigning.ejbcaCA.caNameName of the CA issuer to use in EJBCA""
controlplane.customCAsList of custom CA certificates content[]
controlplane.automountServiceAccountTokenMount Service Account token in controlplane podsfalse
controlplane.hostAliasescontrolplane pods host aliases[]
controlplane.deploymentAnnotationsAnnotations for controlplane deployment{}
controlplane.podLabelsExtra labels for controlplane pods{}
controlplane.podAffinityPresetPod affinity preset. Ignored if controlplane.affinity is set. Allowed values: soft or hard""
controlplane.podAntiAffinityPresetPod anti-affinity preset. Ignored if controlplane.affinity is set. Allowed values: soft or hardsoft
controlplane.nodeAffinityPreset.typeNode affinity preset type. Ignored if controlplane.affinity is set. Allowed values: soft or hard""
controlplane.nodeAffinityPreset.keyNode label key to match. Ignored if controlplane.affinity is set""
controlplane.nodeAffinityPreset.valuesNode label values to match. Ignored if controlplane.affinity is set[]
controlplane.affinityAffinity for controlplane pods assignment{}
controlplane.nodeSelectorNode labels for controlplane pods assignment{}
controlplane.tolerationsTolerations for controlplane pods assignment[]
controlplane.updateStrategy.typecontrolplane deployment strategy typeRollingUpdate
controlplane.priorityClassNamecontrolplane pods' priorityClassName""
controlplane.topologySpreadConstraintsTopology Spread Constraints for controlplane pod assignment spread across your cluster among failure-domains[]
controlplane.schedulerNameName of the k8s scheduler (other than default) for controlplane pods""
controlplane.terminationGracePeriodSecondsSeconds controlplane pods need to terminate gracefully""
controlplane.lifecycleHooksfor controlplane containers to automate configuration before or after startup{}
controlplane.extraEnvVarsArray with extra environment variables to add to controlplane containers[]
controlplane.extraEnvVarsCMName of existing ConfigMap containing extra env vars for controlplane containers""
controlplane.extraEnvVarsSecretName of existing Secret containing extra env vars for controlplane containers""
controlplane.extraVolumesOptionally specify extra list of additional volumes for the controlplane pods[]
controlplane.extraVolumeMountsOptionally specify extra list of additional volumeMounts for the controlplane containers[]
controlplane.sidecarsAdd additional sidecar containers to the controlplane pods[]
controlplane.initContainersAdd additional init containers to the controlplane pods[]
controlplane.pdb.createEnable/disable a Pod Disruption Budget creationtrue
controlplane.pdb.minAvailableMinimum number/percentage of pods that should remain scheduled""
controlplane.pdb.maxUnavailableMaximum number/percentage of pods that may be made unavailable. Defaults to 1 if both controlplane.pdb.minAvailable and controlplane.pdb.maxUnavailable are empty.""
controlplane.autoscaling.vpa.enabledEnable VPA for controlplane podsfalse
controlplane.autoscaling.vpa.annotationsAnnotations for VPA resource{}
controlplane.autoscaling.vpa.controlledResourcesVPA List of resources that the vertical pod autoscaler can control. Defaults to cpu and memory[]
controlplane.autoscaling.vpa.maxAllowedVPA Max allowed resources for the pod{}
controlplane.autoscaling.vpa.minAllowedVPA Min allowed resources for the pod{}
controlplane.autoscaling.vpa.updatePolicy.updateModeAutoscaling update policyAuto
controlplane.autoscaling.hpa.enabledEnable HPA for controlplane podsfalse
controlplane.autoscaling.hpa.minReplicasMinimum number of replicas""
controlplane.autoscaling.hpa.maxReplicasMaximum number of replicas""
controlplane.autoscaling.hpa.targetCPUTarget CPU utilization percentage""
controlplane.autoscaling.hpa.targetMemoryTarget Memory utilization percentage""
controlplane.networkPolicy.enabledSpecifies whether a NetworkPolicy should be createdtrue
controlplane.networkPolicy.allowExternalDon't require client label for connectionstrue
controlplane.networkPolicy.allowExternalEgressAllow the pod to access any range of port and all destinations.true
controlplane.networkPolicy.extraIngressAdd extra ingress rules to the NetworkPolicy[]
controlplane.networkPolicy.extraEgressAdd extra ingress rules to the NetworkPolicy[]
controlplane.networkPolicy.ingressNSMatchLabelsLabels to match to allow traffic from other namespaces{}
controlplane.networkPolicy.ingressNSPodMatchLabelsPod labels to match to allow traffic from other namespaces{}

Artifact Content Addressable (CAS) API

NameDescriptionValue
cas.replicaCountNumber of replicas2
cas.image.registryImage registryREGISTRY_NAME
cas.image.repositoryImage repositoryREPOSITORY_NAME
cas.containerPorts.httpcontrolplane HTTP container port8000
cas.containerPorts.grpccontrolplane gRPC container port9000
cas.containerPorts.metricscontrolplane prometheus metrics container port5000
cas.tls.existingSecretExisting secret name containing TLS certificate to be used by the cas grpc server""

CAS Networking

NameDescriptionValue
cas.service.typeService typeClusterIP
cas.service.ports.httpcas service HTTP port80
cas.service.ports.httpscas service HTTPS port443
cas.service.nodePorts.httpNode port for HTTP""
cas.service.nodePorts.httpsNode port for HTTPS""
cas.service.clusterIPcas service Cluster IP""
cas.service.loadBalancerIPcas service Load Balancer IP""
cas.service.loadBalancerSourceRangescas service Load Balancer sources[]
cas.service.externalTrafficPolicycas service external traffic policyCluster
cas.service.annotationsAdditional custom annotations for cas service{}
cas.service.extraPortsExtra ports to expose in cas service (normally used with the sidecars value)[]
cas.service.sessionAffinityControl where client requests go, to the same pod or round-robinNone
cas.service.sessionAffinityConfigAdditional settings for the sessionAffinity{}
cas.serviceAPI.typeService typeClusterIP
cas.serviceAPI.ports.httpcas service HTTP port80
cas.serviceAPI.ports.httpscas service HTTPS port443
cas.serviceAPI.nodePorts.httpNode port for HTTP""
cas.serviceAPI.nodePorts.httpsNode port for HTTPS""
cas.serviceAPI.clusterIPcas service Cluster IP""
cas.serviceAPI.loadBalancerIPcas service Load Balancer IP""
cas.serviceAPI.loadBalancerSourceRangescas service Load Balancer sources[]
cas.serviceAPI.externalTrafficPolicycas service external traffic policyCluster
cas.serviceAPI.annotationsAdditional custom annotations for cas service
cas.serviceAPI.extraPortsExtra ports to expose in cas service (normally used with the sidecars value)[]
cas.serviceAPI.sessionAffinityControl where client requests go, to the same pod or round-robinNone
cas.serviceAPI.sessionAffinityConfigAdditional settings for the sessionAffinity{}
cas.ingress.enabledEnable ingress record generation for controlplanefalse
cas.ingress.pathTypeIngress path typeImplementationSpecific
cas.ingress.hostnameDefault host for the ingress recordcas.dev.local
cas.ingress.ingressClassNameIngressClass that will be be used to implement the Ingress (Kubernetes 1.18+)""
cas.ingress.pathDefault path for the ingress record/
cas.ingress.annotationsAdditional annotations for the Ingress resource. To enable certificate autogeneration, place here your cert-manager annotations.{}
cas.ingress.tlsEnable TLS configuration for the host defined at controlplane.ingress.hostname parameterfalse
cas.ingress.selfSignedCreate a TLS secret for this ingress record using self-signed certificates generated by Helmfalse
cas.ingress.extraHostsAn array with additional hostname(s) to be covered with the ingress record[]
cas.ingress.extraPathsAn array with additional arbitrary paths that may need to be added to the ingress under the main host[]
cas.ingress.extraTlsTLS configuration for additional hostname(s) to be covered with this ingress record[]
cas.ingress.secretsCustom TLS certificates as secrets[]
cas.ingress.extraRulesAdditional rules to be covered with this ingress record[]
cas.ingressAPI.enabledEnable ingress record generation for controlplanefalse
cas.ingressAPI.pathTypeIngress path typeImplementationSpecific
cas.ingressAPI.hostnameDefault host for the ingress recordapi.cas.dev.local
cas.ingressAPI.ingressClassNameIngressClass that will be be used to implement the Ingress (Kubernetes 1.18+)""
cas.ingressAPI.pathDefault path for the ingress record/
cas.ingressAPI.annotationsAdditional annotations for the Ingress resource. To enable certificate autogeneration, place here your cert-manager annotations.
cas.ingressAPI.tlsEnable TLS configuration for the host defined at controlplane.ingress.hostname parameterfalse
cas.ingressAPI.selfSignedCreate a TLS secret for this ingress record using self-signed certificates generated by Helmfalse
cas.ingressAPI.extraHostsAn array with additional hostname(s) to be covered with the ingress record[]
cas.ingressAPI.extraPathsAn array with additional arbitrary paths that may need to be added to the ingress under the main host[]
cas.ingressAPI.extraTlsTLS configuration for additional hostname(s) to be covered with this ingress record[]
cas.ingressAPI.secretsCustom TLS certificates as secrets[]
cas.ingressAPI.extraRulesAdditional rules to be covered with this ingress record[]

CAS Misc

NameDescriptionValue
cas.sentry.enabledEnable sentry.io alertingfalse
cas.sentry.dsnDSN endpoint""
cas.sentry.environmentEnvironment tagproduction
cas.customCAsList of custom CA certificates content[]

CAS Misc

NameDescriptionValue
cas.resourcesPresetSet init container resources according to one common preset (allowed values: none, nano, small, medium, large, xlarge, 2xlarge). This is ignored if volumePermissions.resources is set (volumePermissions.resources is recommended for production).micro
cas.resourcesSet cas container requests and limits for different resources like CPU or memory (essential for production workloads){}
cas.podSecurityContext.enabledEnable cas pods' Security Contexttrue
cas.podSecurityContext.fsGroupChangePolicySet filesystem group change policy for cas podsAlways
cas.podSecurityContext.sysctlsSet kernel settings using the sysctl interface for cas pods[]
cas.podSecurityContext.supplementalGroupsSet filesystem extra groups for cas pods[]
cas.podSecurityContext.fsGroupSet fsGroup in cas pods' Security Context1001
cas.containerSecurityContext.enabledEnabled cas container' Security Contexttrue
cas.containerSecurityContext.seLinuxOptionsSet SELinux options in cas container{}
cas.containerSecurityContext.runAsUserSet runAsUser in cas container' Security Context1001
cas.containerSecurityContext.runAsGroupSet runAsGroup in cas container' Security Context1001
cas.containerSecurityContext.runAsNonRootSet runAsNonRoot in cas container' Security Contexttrue
cas.containerSecurityContext.readOnlyRootFilesystemSet readOnlyRootFilesystem in cas container' Security Contexttrue
cas.containerSecurityContext.privilegedSet privileged in cas container' Security Contextfalse
cas.containerSecurityContext.allowPrivilegeEscalationSet allowPrivilegeEscalation in cas container' Security Contextfalse
cas.containerSecurityContext.capabilities.dropList of capabilities to be dropped in cas container["ALL"]
cas.containerSecurityContext.seccompProfile.typeSet seccomp profile in cas containerRuntimeDefault
cas.automountServiceAccountTokenMount Service Account token in cas podsfalse
cas.hostAliasescas pods host aliases[]
cas.deploymentAnnotationsAnnotations for cas deployment{}
cas.podLabelsExtra labels for cas pods{}
cas.podAffinityPresetPod affinity preset. Ignored if cas.affinity is set. Allowed values: soft or hard""
cas.podAntiAffinityPresetPod anti-affinity preset. Ignored if cas.affinity is set. Allowed values: soft or hardsoft
cas.nodeAffinityPreset.typeNode affinity preset type. Ignored if cas.affinity is set. Allowed values: soft or hard""
cas.nodeAffinityPreset.keyNode label key to match. Ignored if cas.affinity is set""
cas.nodeAffinityPreset.valuesNode label values to match. Ignored if cas.affinity is set[]
cas.affinityAffinity for cas pods assignment{}
cas.nodeSelectorNode labels for cas pods assignment{}
cas.tolerationsTolerations for cas pods assignment[]
cas.updateStrategy.typecas deployment strategy typeRollingUpdate
cas.priorityClassNamecas pods' priorityClassName""
cas.topologySpreadConstraintsTopology Spread Constraints for cas pod assignment spread across your cluster among failure-domains[]
cas.schedulerNameName of the k8s scheduler (other than default) for cas pods""
cas.terminationGracePeriodSecondsSeconds cas pods need to terminate gracefully""
cas.lifecycleHooksfor cas containers to automate configuration before or after startup{}
cas.extraEnvVarsArray with extra environment variables to add to cas containers[]
cas.extraEnvVarsCMName of existing ConfigMap containing extra env vars for cas containers""
cas.extraEnvVarsSecretName of existing Secret containing extra env vars for cas containers""
cas.extraVolumesOptionally specify extra list of additional volumes for the cas pods[]
cas.extraVolumeMountsOptionally specify extra list of additional volumeMounts for the cas containers[]
cas.sidecarsAdd additional sidecar containers to the cas pods[]
cas.initContainersAdd additional init containers to the cas pods[]
cas.pdb.createEnable/disable a Pod Disruption Budget creationtrue
cas.pdb.minAvailableMinimum number/percentage of pods that should remain scheduled""
cas.pdb.maxUnavailableMaximum number/percentage of pods that may be made unavailable. Defaults to 1 if both cas.pdb.minAvailable and cas.pdb.maxUnavailable are empty.""
cas.autoscaling.vpa.enabledEnable VPA for cas podsfalse
cas.autoscaling.vpa.annotationsAnnotations for VPA resource{}
cas.autoscaling.vpa.controlledResourcesVPA List of resources that the vertical pod autoscaler can control. Defaults to cpu and memory[]
cas.autoscaling.vpa.maxAllowedVPA Max allowed resources for the pod{}
cas.autoscaling.vpa.minAllowedVPA Min allowed resources for the pod{}
cas.autoscaling.vpa.updatePolicy.updateModeAutoscaling update policyAuto
cas.autoscaling.hpa.enabledEnable HPA for cas podsfalse
cas.autoscaling.hpa.minReplicasMinimum number of replicas""
cas.autoscaling.hpa.maxReplicasMaximum number of replicas""
cas.autoscaling.hpa.targetCPUTarget CPU utilization percentage""
cas.autoscaling.hpa.targetMemoryTarget Memory utilization percentagenil
cas.networkPolicy.enabledSpecifies whether a NetworkPolicy should be createdtrue
cas.networkPolicy.allowExternalDon't require client label for connectionstrue
cas.networkPolicy.allowExternalEgressAllow the pod to access any range of port and all destinations.true
cas.networkPolicy.extraIngressAdd extra ingress rules to the NetworkPolicy[]
cas.networkPolicy.extraEgressAdd extra ingress rules to the NetworkPolicy[]
cas.networkPolicy.ingressNSMatchLabelsLabels to match to allow traffic from other namespaces{}
cas.networkPolicy.ingressNSPodMatchLabelsPod labels to match to allow traffic from other namespaces{}

Dependencies

NameDescriptionValue
postgresql.enabledSwitch to enable or disable the PostgreSQL helm charttrue
postgresql.auth.enablePostgresUserAssign a password to the "postgres" admin user. Otherwise, remote access will be blocked for this userfalse
postgresql.auth.usernameName for a custom user to createchainloop
postgresql.auth.passwordPassword for the custom user to createchainlooppwd
postgresql.auth.databaseName for a custom database to createchainloop-cp
postgresql.auth.existingSecretName of existing secret to use for PostgreSQL credentials""
vault.server.argsArguments to pass to the vault server. This is useful for setting the server in development mode["server","-dev"]
vault.server.configConfiguration for the vault server. Small override of default Bitnami configuration`storage "inmem"
disable_mlock = true
ui = true
service_registration "kubernetes" `
vault.server.extraEnvVars[0].nameRoot token for the vault serverVAULT_DEV_ROOT_TOKEN_ID
vault.server.extraEnvVars[0].valueThe value of the root token. Default: notasecretnotasecret
vault.server.extraEnvVars[1].nameAddress to listen on development modeVAULT_DEV_LISTEN_ADDRESS
vault.server.extraEnvVars[1].valueThe address to listen on. Default: [::]:8200[::]:8200

License

Copyright © 2023 The Chainloop Authors

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.