Skip to content

Configuring the s3gw

The following configuration options are for the s3gw and can be configured within the values.yaml file.

Access credentials

We strongly advise customizing the initial access credentials. These can be used to access the admin UI, as well as the S3 endpoint. Additional credentials can be created using the admin UI.

Initial credentials for the default user can be provided in different ways:

  • Explicit values

This is the default mode. You provide explicit values for both the S3 Access Key and the S3 Secret Key.

accessKey: admin
secretKey: foobar
  • Random values

If you set accessKey and/or secretKey as the empty string:


The chart then computes a random alphanumeric string of 32 characters for the field(s). The generated values are printed to the console after the installation completes successfully. They can also be retrieved later.

To obtain the access key:

kubectl --namespace $S3GW_NAMESPACE get secret \
  $(yq .defaultUserCredentialSecret values.yaml) \
  -o yaml | yq .data.RGW_DEFAULT_USER_ACCESS_KEY | base64 -d

To obtain the secret key:

kubectl --namespace $S3GW_NAMESPACE get secret \
  $(yq .defaultUserCredentialSecret values.yaml) \
  -o yaml | yq .data.RGW_DEFAULT_USER_SECRET_KEY | base64 -d
  • Existing secret

You can provide an existing secret containing the S3 credentials for the default user. This secret must contain 2 keys:

  • RGW_DEFAULT_USER_ACCESS_KEY: the S3 Access Key for the default user.
  • RGW_DEFAULT_USER_SECRET_KEY: the S3 Secret Key for the default user.

To use this configuration, you have to enable the flag:

useExistingSecret: true

You can set the name of the existing secret with:

defaultUserCredentialsSecret: "my-secret"

Ingress options

If you want to expose the S3 service outside the cluster (for example, to a host static content for a website) you need an ingress for the outside traffic to reach the s3gw. Set ingress.enabled to true:

  enabled: true

If you only want cluster-internal access, set to false:

  enabled: false

Certification manager

If you want to have secure connections to the s3gw using TLS and do not want to manage certificates by hand set useCertManager to true. This does require you to have jetstack certmanager installed from

As cert-manager will be installed in its own namespace, you can give a namespace where the chart can communicate with the cert manager using certManagerNamespace.

TLS issuer

The tlsIssuer property controls how certificates are issued with the cert-manager. Either use s3gw-letsencrypt-issuer when you want certificates that are issued by letsencrypt or use the s3gw-issuer for a self-signed certificate.


If you are not using the cert-manager, you have to manually specify the TLS certificates in the values.yaml file to enable TLS at the various Ingresses and ClusterIP resources. Note that the connection between the Ingress and the s3gw's ClusterIP within the cluster will not be TLS protected.


The certificates must be provided as base64 encoded PEM in one long string without line breaks. You can create them from a PEM file.

s3gw user interface

ui.enabled is by default set to true, but can be set to false to use the s3gw standalone.

ui.serviceName and ui.publicDomain are the hostname and domain name which the ingress will listed on for access to the UI. If the UI is set as such:

  serviceName: object-browser

The UI can be accessed under http(s)://

S3 service

useExistingSecret can be used to tell the chart that you want to provide a secret where the access credentials for the first account can be found. defaultUserCredentialsSecret can be used to tell helm which secret that will be.

If accessKey and secretKey are left empty, credentials will be generated automatically.

Service name

There are two possible ways to access the s3gw: from inside the Kubernetes cluster and from the outside. For both, the s3gw must be configured with the correct service and domain name. Use the publicDomain and the ui.publicDomain setting to configure the domain under which the s3gw and the UI respectively be available to the outside of the Kubernetes cluster. Use the privateDomain setting to set the cluster's internal domain and make the s3gw available inside the cluster to other deployments.

serviceName: s3gw
publicDomain: ""
privateDomain: "s3gw-namespace.svc.cluster.local"
  serviceName: s3gw-ui
  publicDomain: ""


The s3gw is best deployed on top of a Longhorn volume. If you have Longhorn installed in your cluster, all appropriate resources are automatically deployed for you.

The size of the volume can be controlled with storageSize:

storageSize: 10Gi

If you want to reuse an existing storage class or otherwise need more control over storage settings, set storageClass.create to false and to the name of your preferred storage class.

  name: my-custom-storageclass
  create: false

Local storage

You can use the storageClass.local and storageClass.localPath variables to set up a node-local volume for testing if you do not have Longhorn.

Note: This is an experimental feature for development use only.

Log settings

The log verbosity can also be configured for the s3gw pod. Set the logLevel property to one of none, low, medium, or high:

logLevel: "none"

Generally speaking, none or low should be fine for most deployments, unless there is reason to believe it's misbehaving. In that case, the highest logLevel we recommend is medium. Higher log levels should be used only in case the system is misbehaving significantly and there's a suspicion more verbose debugging might be necessary. Please note that at high the system may be impacted.

Developer options

In some cases, custom image settings are needed, for example in an air-gapped environment or for developers. In that case, you can modify the registry and image settings:

imageRegistry: ""
imageName: "s3gw"
imageTag: "latest"
imagePullPolicy: "Always"

To configure the image and registry for the user interface, use:

ui.imageRegistry: ""
ui.imageName: "s3gw-ui"
ui.imagePullPolicy: "Always"
ui.imageTag: "latest"

Container Object Storage Interface (COSI)

WARNING: Be advised that COSI standard is currently in alpha state. The COSI implementation provided by s3gw is considered an experimental feature and changes to the COSI standard are expected in this phase. The s3gw team does not control the upstream development of COSI.


If you are going to use COSI, ensure some resources are pre-deployed on the cluster.

COSI requirements:


To deploy COSI CRDs, run:

kubectl create -k
  • COSI Controller

To deploy the COSI Controller, run:

kubectl create -k

Check if the controller pod is in the default namespace:

NAME                                        READY   STATUS    RESTARTS   AGE
objectstorage-controller-6fc5f89444-4ws72   1/1     Running   0          2d6h


COSI support is disabled by default in s3gw. To enable it, set:

cosi.enabled: true

Normally, you do not need to change the chart's defaults for the COSI related fields.

However, the following fields can be customized:

cosi.driver.imageName: # It specifies a custom image name for the COSI driver.
                       # Default: s3gw-cosi-driver

cosi.driver.imageTag: # It specifies a custom image tag for the COSI driver.
                      # Default: the current chart version.

cosi.driver.imageRegistry: #It specifies a custom image registry for the COSI driver.

cosi.driver.imagePullPolicy: # It specifies the pull policy for the COSI driver.
                             # Default: IfNotPresent # It specifies the name of the COSI driver.
                  # Default: {Release.Name}.{Release.Namespace}

cosi.sidecar.imageName: # It specifies a custom image name for the COSI sidecar.
                        # Default: s3gw-cosi-sidecar

cosi.sidecar.imageTag: # It specifies a custom image tag for the COSI sidecar.
                       # Default: the current chart version.

cosi.sidecar.imageRegistry: # It specifies a custom image registry for the COSI sidecar.
                            # Default:

cosi.sidecar.imagePullPolicy: # It specifies the pull policy for the COSI sidecar.
                              # Default: IfNotPresent

cosi.sidecar.logLevel: # It specifies the log verbosity of the COSI sidecar.
                       # Higher values are more verbose.
                       # Default: 5