Skip to content

Secrets

This guide covers every Kubernetes Secret involved in a GitlabInstance: the ones you provide (referenced by the operator), the ones the operator creates, and the ones the upstream chart generates.

Secrets you provide

These Secrets must exist in the same namespace as the GitlabInstance before the operator can progress.

S3 object storage credentials (spec.objectStorage.credentialsSecret)

stringData:
  accessKey: <rgw-access-key>
  secretKey: <rgw-secret-key>
  endpoint: https://rgw.bnerd.com
  region: default
  bucket.registry:          <bucket-name>
  bucket.lfs:               <bucket-name>
  bucket.artifacts:         <bucket-name>
  bucket.uploads:           <bucket-name>
  bucket.packages:          <bucket-name>
  bucket.mr-diffs:          <bucket-name>
  bucket.terraform:         <bucket-name>
  bucket.ci-secure-files:   <bucket-name>
  bucket.dependency-proxy:  <bucket-name>
  bucket.backups:           <bucket-name>
  bucket.pages:             <bucket-name>

Required keys: accessKey, secretKey, endpoint, region, and one bucket.<class> key per storage class. See Object Storage for the full list.

BYO PostgreSQL credentials (spec.postgres.credentialsSecret)

Only when spec.postgres.managed: false:

stringData:
  host: pg.example.com   # required
  port: "5432"           # required, as a string
  password: <password>   # required

BYO Redis credentials (spec.redis.credentialsSecret)

Only when spec.redis.managed: false:

stringData:
  host: redis.example.com  # required
  port: "6379"             # required, as a string
  password: <password>     # required

EE license (spec.licenseSecret)

Only when spec.edition: ee:

stringData:
  license: |
    <base64-encoded GitLab EE license content>

The key must be named license. Create from a file:

kubectl create secret generic my-gitlab-ee-license \
  --from-file=license=/path/to/my.gitlab-license \
  -n my-gitlab-ee

SMTP password (spec.smtp.passwordSecret)

Optional. When spec.smtp.address is set, the operator reads the SMTP password from this Secret. All other SMTP parameters (address, port, userName, domain, authentication, startTLS, emailFrom, emailDisplayName) are declared inline on the GitlabInstance spec.

stringData:
  password: <smtp-password>

The key must be named password. The operator wires this to global.smtp.password in the chart.

Example GitlabInstance SMTP block:

spec:
  smtp:
    address: smtp.example.com
    port: 587
    userName: gitlab@example.com
    passwordSecret: my-gitlab-smtp-password
    domain: example.com
    emailFrom: gitlab@example.com
    emailDisplayName: "GitLab"

Backup object storage config (spec.backups.objectStorage.credentialsSecret)

Optional. The Secret must contain an s3cmd-format config under key config. This is wired to gitlab.toolbox.backups.objectStorage.config in the chart. On chart 10+, the Toolbox is only enabled when this field is set.

stringData:
  config: |
    [default]
    host_base = rgw.bnerd.com
    host_bucket = rgw.bnerd.com/%(bucket)s
    access_key = <rgw-access-key>
    secret_key = <rgw-secret-key>
    bucket_location = default
    use_https = True

This Secret uses a different format from the main spec.objectStorage.credentialsSecret — it cannot be the same object.


Secrets the operator creates

The operator creates and tracks these Secrets in status.secrets. They are garbage-collected by the finalizer when the GitlabInstance is deleted.

Secret name Contents When created
{instance}-gitlab-registry-storage docker-registry S3 driver config (key: config) When spec.objectStorage.credentialsSecret is set

Operator-owned Secrets are named with the pattern {instance-name}-gitlab-{section}.


Secrets the upstream GitLab chart creates

These Secrets are created by the GitLab Helm chart (via Flux) and are not managed by the operator.

Secret name Contents Notes
{release}-gitlab-initial-root-password password — the initial root password Created on first chart install only
{release}-gitlab-gitlab-shell-secret GitLab Shell auth token Managed by the chart
{release}-gitlab-gitaly-secret Gitaly internal token Managed by the chart
Various other chart-internal Secrets Rails secret key, Workhorse token, etc. Managed by the chart

Retrieving the initial root password

kubectl get secret {release}-gitlab-initial-root-password \
  -n {namespace} \
  -o jsonpath='{.data.password}' | base64 -d; echo

For an instance named my-gitlab in namespace my-gitlab:

kubectl get secret my-gitlab-gitlab-initial-root-password \
  -n my-gitlab \
  -o jsonpath='{.data.password}' | base64 -d; echo

Change the root password after first login

The initial root password is randomly generated by the chart and stored in plain base64 in a Kubernetes Secret. Copy it, log in as root, and set a strong password immediately.


Secret lifecycle and cleanup

  • Operator-owned Secrets (in status.secrets) are deleted by the finalizer when the GitlabInstance is deleted.
  • Secrets you provide (S3, PG, Redis, license, SMTP) are never touched or deleted by the operator.
  • Chart-created Secrets are owned by the HelmRelease and deleted when the HelmRelease is deleted (which happens when the GitlabInstance is deleted, since the HelmRelease is owned by the instance).
  • Managed backend credential Secrets (e.g. {instance}-pg-pguser-gitlab from Percona) are owned by Percona and are retained when the GitlabInstance is deleted — they go with their respective backend clusters.

See Deletion & Retention for the full cleanup sequence.