Skip to content

Changes needed for Big Bang and Ironbank Images

The Big Bang team had to change some values from upstream because of how Big Bang makes use of Anchore from within Umbrella. We also made some additional modifications that were necessary because the Ironbank images our implementation of Anchore uses function slightly differently from the coresponding upstream Dockerhub images. This document outlines these changes so that you can verify that none of them have been overwritten by an update.

Big Bang Modifications

1) To support Istio optional network policies, automated license creation, monitoring, and SSO, the following changes should be present at the top of chart/values.yaml:

# Big Bang Values
# ---------------
domain: dev.bigbang.mil

istio:
  # Toggle istio integration
  enabled: false
  hardened:
    enabled: false
  injection: "disabled"

  ui:
    # Toggle vs creation
    enabled: true
    annotations: {}
    labels: {}
    gateways:
      - istio-system/main
    hosts:
      - "anchore.{{ .Values.domain }}"
  api:
    # Toggle vs creation
    enabled: true
    annotations: {}
    labels: {}
    gateways:
      - istio-system/main
    hosts:
      - "anchore-api.{{ .Values.domain }}"

   mtls:
    # -- STRICT = Allow only mutual TLS traffic,
    # PERMISSIVE = Allow both plain text and mutual TLS traffic
    mode: STRICT

networkPolicies:
  enabled: false
  ingressLabels:
    app: istio-ingressgateway
    istio: ingressgateway

# Enable Prometheus Monitoring
monitoring:
  enabled: false
  namespace: monitoring
  serviceMonitor:
    scheme: ""
    tlsConfig: {}

# Enterprise license: Specify your multiline license
# enterpriseLicenseYaml: |
#   License YAML
enterpriseLicenseYaml: "" # Full multiline license yaml

# Enable/disable Keycloak SSO integration
# If enabled, also enable OAuth - anchoreGlobal.oauthEnabled
sso:
  enabled: false
  name: "keycloak"
  acsHttpsPort: -1
  spEntityId: "platform1_a8604cc9-f5e9-4656-802d-d05624370245_bb8-anchore"
  acsUrl: "https://anchore.bigbang.dev/service/sso/auth/keycloak"
  defaultAccount: "user"
  defaultRole: "read-write" # If roleAttribute is passed, defaultRole will be ignored
  roleAttribute: "" # Optional, defines the Keycloak attribute to use to map roles/permissions
  requireSignedAssertions: false
  requireSignedResponse: true
  idpMetadataUrl: "https://login.dso.mil/auth/realms/baby-yoda/protocol/saml/descriptor"

# Default name override to upstream chart name
global:
  nameOverride: "anchore-enterprise"

2) All chart changes are located under the chart/templates/bigbang directory. These are currently:

  • Automated creation of the license secret
  • Creation of an SSO secret with the above SSO values
  • Automation of SSO configuration through a k8s job
  • Creation of secrets with database credentials from postgres and feeds.feeds-db values
  • Automated creation and synchronization of the Postgres databases, database users, and passwords through k8s jobs
  • Added analyzer-service.yaml to support metrics for analyzer
  • Added service monitors for all exposed metrics

Verify that these are present. As additional Big Bang changes are made, add them to this directory and update this document to reflect that.

Ironbank Modifications

3) Check chart/values.yaml and verify that all the following images are actually being pulled from registry1.dso.mil and not from the external upstream (note: the version numbers will be different from what is in this document):

image: registry1.dso.mil/ironbank/anchore/enterprise/enterprise:5.8.0
imagePullSecretName: private-registry

postgresql:
  image: registry1.dso.mil/ironbank/opensource/postgres/postgresql:16.2
  imagePullSecrets: private-registry

feeds:
  feeds-db:
    image: registry1.dso.mil/ironbank/opensource/postgres/postgresql:16.2
    imagePullSecrets: private-registry

gem-db:
  image: registry1.dso.mil/ironbank/opensource/postgres/postgresql:16.2
  imagePullSecrets: private-registry

ui:
  image: registry1.dso.mil/ironbank/anchore/enterprise/enterpriseui:5.8.0
  imagePullSecretName: private-registry

osaaMigrationJob:
  kubectlImage: registry1.dso.mil/ironbank/opensource/kubernetes/kubectl:v1.29.7

4) An image pull secret name should be specified so that Umbrella can pull the images above correctly. To check this, make sure you see this section in chart/values.yaml:

imagePullSecretName: private-registry

If you are pulling from public registry that don’t require credentials, you can set imagePullSecretName: ""

5) To support the Ironbank Postgres image, additional configuration has to be set in chart/values.yaml:

postgresql:
  persistence:
    resourcePolicy: keep
    size: 20Gi
    subPath: "data/pgdata"
    mountPath: /var/lib/postgresql
  # Set the configs to allow listening and connecting from other pods
  postgresConfiguration: {"listen_addresses": "*"}
  pgHbaConfiguration: |-
    local all all scram-sha-256
    host all all all scram-sha-256
  postgresqlDataDir: /var/lib/postgresql/data

feeds:
  feeds-db:
    primary:
      persistence:
        resourcePolicy: keep
        size: 20Gi
        subPath: "pgdata"
        mountPath: /var/lib/postgresql
    # Set the configs to allow listening and connecting from other pods
    postgresConfiguration: {"listen_addresses": "*"}
    pgHbaConfiguration: |-
      local all all scram-sha-256
      host all all all scram-sha-256

Obsolete as of chart 4.1.2-bb.0. The bundled PostgreSQL configuration shown above no longer applies. This package does not ship a database anymore, so none of those postgresql.* values exist. The block is retained only to describe how earlier releases were configured. See below for the current requirement.

Starting with chart 4.1.2-bb.0, Big Bang no longer bundles a PostgreSQL subchart with this package. Three things drove that: the upstream chart dropped its own Bitnami PostgreSQL dependency in 4.x, Bitnami’s public catalog is deprecated, and Big Bang does not support in-cluster persistence for production workloads. Consumers must supply their own database.

Anchore Enterprise 6.x additionally requires PostgreSQL 17 or above with the pg_cron extension installed and enabled - shared_preload_libraries must include pg_cron and cron.database_name must name the Anchore database. Neither the upstream chart nor this package creates the extension.

CREATE EXTENSION pg_cron must be run by a superuser, which leaves the cron schema owned by that superuser. The Anchore application role therefore has no access to it by default and the services fail with permission denied for schema cron. The role must be granted access explicitly. Against a database named anchore with an application role of the same name:

-- as a superuser, in the Anchore database
CREATE EXTENSION IF NOT EXISTS pg_cron;
GRANT USAGE ON SCHEMA cron TO anchore;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA cron TO anchore;
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA cron TO anchore;

On managed services the shared_preload_libraries and cron.database_name settings are not in postgresql.conf: on RDS they go in the parameter group and require a reboot, and Cloud SQL and Azure Database each have their own flag mechanism. Setting cron.use_background_workers to on is also recommended.

For a Big Bang deployment, configure the database through the umbrella values. host, username, password, and database are required; port defaults to 5432.

addons:
  anchoreEnterprise:
    database:
      host: "postgresql.example.svc.cluster.local"
      port: 5432
      username: ""
      password: ""
      database: ""

The Big Bang umbrella maps these values to upstream.postgresql.*. Direct installations of this package chart use those upstream.postgresql.* values instead.

Set the admin password explicitly when the database is external

upstream.anchoreConfig.default_admin_password should be set, or useExistingSecrets used to supply the secret yourself. Leaving it unset is viable with a bundled database but is a hazard with an external one.

Unset, the chart generates the admin password with randAlphaNum 32, and anchore_secret.yaml only carries the previous value over from the existing secret when .Release.IsUpgrade is true. Any reinstall therefore mints a new password. When the database was part of the same release that was harmless, because the database was recreated alongside it. An external database outlives the release, so it keeps the admin account that the earlier install bootstrapped with the old password, and the new one does not match it.

The result is a deployment that looks entirely healthy - every service running, every /health returning 200 - while every authenticated request answers 401 Unauthorized and nothing indicates why. It is not self-correcting: reinstalling produces another new password, and the database keeps the original. Recovery means either resetting the password in the database or setting default_admin_password to the value the database already holds.

Flux makes this easy to hit, because a failed install can be remediated by uninstalling the release, which deletes the secret before reinstalling. Setting the password explicitly removes the failure mode regardless of how the release is reconciled. upstream.anchoreConfig.keys.secret is worth pinning for the same reason - it defaults to randAlphaNum 32 as well, and a value that changes on each render makes the services redeploy on every reconcile.

The upstream pre-install hook is disabled via upstream.preInstallJob.enabled: false. It loops on anchore-enterprise-manager db pre-upgrade-check and gates the install on whether that command produced anything on stderr. On Anchore Enterprise 6.x the command logs entirely to stdout, so the test always passes and the hook reports the database ready even when it cannot reach it, and its exit code is 2 both for a healthy empty database and for a connection failure. The gate provides no protection while its unbounded loop can block an install indefinitely with the error discarded. upstream.preInstallJob.resources and upstream.preInstallJob.containerSecurityContext are still set so the job is compliant if a consumer re-enables it.

The postgresqlSuperUser and ensureDbJobs values were removed at the same time. They only ever configured the chart/templates/bigbang/db/ jobs, which were dropped when the package replaced its vendored PostgreSQL copy under chart/deps/ with the upstream Bitnami chart as a dependency, and had no effect after that point. That bundled dependency has since been removed as well, so this package no longer ships a database in any form.

6) To support SSO:

sso:
  enabled: true

7) To support Istio:

istio:
  enabled: true
  hardened:
    enabled: true

Migrating from the bundled PostgreSQL

Neither the upstream chart nor this package performs any database management. Upstream’s position is that you point Anchore at a database that already contains what it needs, so moving data off the PostgreSQL that earlier releases bundled happens outside Helm entirely. Upgrading a release that used the bundled subchart is therefore a data migration you perform yourself, before the chart upgrade - not something the upgrade does for you.

Read this through before starting. The ordering matters: the restore has to happen before Anchore 6.x starts against the new database. If you upgrade first and let Anchore bootstrap an empty database, it creates a fresh 6.x schema, and restoring 5.x data over that afterwards will conflict.

What is and is not in the database

By default Anchore’s object store and analysis archive use the database driver, so image analysis, SBOMs, policies, and archived data all live in PostgreSQL and a dump covers them. If you configured the S3 object store or analysis archive driver, that data lives outside the database, is unaffected by this migration, and should keep pointing at the same bucket.

1. Provision the external database

Stand up PostgreSQL 17 or above with pg_cron, and grant the Anchore role access to the cron schema as described earlier in this document. Do this first, and leave the database empty.

2. Quiesce Anchore

A dump taken while the services are writing is not consistent. Scale the deployments down and confirm nothing is still running:

NS=anchore   # the namespace holding the release
kubectl -n "$NS" scale deployment --all --replicas=0
kubectl -n "$NS" get pods

Leave the bundled PostgreSQL pod itself running - it is the source of the dump.

3. Dump the existing database

Find the bundled database service and confirm the name rather than assuming it; it follows the release name, so it is usually <release>-postgresql:

kubectl -n "$NS" get svc | grep postgres

The credentials are the ones the old release was configured with, under the now-removed postgresql.global.postgresql.auth values - by default user anchore and database anchore. Take the dump using a pg_dump at least as new as the source server:

kubectl -n "$NS" exec <postgres-pod> -- \
  pg_dump --format=custom --no-owner --no-acl \
    --username=anchore --dbname=anchore > anchore.dump

--no-owner and --no-acl matter if the role name on the new database differs from the old one; without them the restore tries to reassign ownership to a role that may not exist.

Confirm the dump is non-empty and that pg_dump exited cleanly before continuing.

4. Restore into the external database

pg_restore --no-owner --no-acl \
  --host=<endpoint> --port=5432 \
  --username=<user> --dbname=<database> anchore.dump

The dump does not carry pg_cron across, so the extension and the cron schema grants from step 1 must still be in place afterwards.

5. Upgrade the release

Set the connection values and upgrade:

addons:
  anchoreEnterprise:
    database:
      host: "<endpoint>"
      port: 5432
      username: "<user>"
      password: "<password>"
      database: "<database>"

Anchore performs its own 5.x to 6.x schema migration on first start against the restored data. Do not attempt that part by hand. Allow more time than a normal upgrade: the chart scales the services down in a pre-upgrade hook, runs the database upgrade, then scales them back up, and upstream advises raising the Helm timeout accordingly.

6. Verify, then clean up

Confirm the system is healthy and the data is present - accounts, policies, and previously analysed images should all be there - before discarding anything. Removing the bundled subchart does not delete its PersistentVolumeClaim, so the old data survives the upgrade and remains the rollback path. Delete it only once you are satisfied:

kubectl -n "$NS" get pvc              # identify the old bundled postgres claim
kubectl -n "$NS" delete pvc <claim>   # only after verifying the migration

A note on this package’s CI

The upgrade test jobs deploy the previous release, then upgrade to the new one against a freshly created database. They validate the chart upgrade itself: that the release upgrades in place, that the removed PostgreSQL subchart’s resources are pruned cleanly, and that the services come up and pass their smoke tests. They deliberately do not exercise the data migration above, because the chart makes no data-continuity guarantee to test. A green upgrade job is not evidence that a production migration will preserve data.

Other Modifications

8) Required environment variables should be set in chart/templates/envvars_configmap.yaml:

data:
  ANCHORE_ENABLE_METRICS: "{{ .Values.upstream.anchoreConfig.metrics.enabled }}"
  ANCHORE_DISABLE_METRICS_AUTH: "{{ .Values.upstream.anchoreConfig.metrics.auth_disabled }}"

11) Legacy Istio sidecar shutdown curl logic should not be added to package job resources. Native sidecars and Ambient mode do not require manual proxy termination calls. Package job commands should remain focused on the package work they perform rather than waiting for or shutting down an Istio sidecar:

          {{- if not .Values.upstream.anchoreConfig.database.ssl }}
            - |
              {{ print (include "enterprise.doSourceFile" .) }} anchore-enterprise-manager db --db-connect postgresql://"${ANCHORE_DB_USER}":"${ANCHORE_DB_PASSWORD}"@"${ANCHORE_DB_HOST}":"${ANCHORE_DB_PORT}"/"${ANCHORE_DB_NAME}" upgrade --dontask;
          {{- else if eq .Values.upstream.anchoreConfig.database.sslMode "require" }}
            - |
              {{ print (include "enterprise.doSourceFile" .) }} anchore-enterprise-manager db --db-use-ssl --db-connect postgresql://"${ANCHORE_DB_USER}":"${ANCHORE_DB_PASSWORD}"@"${ANCHORE_DB_HOST}":"${ANCHORE_DB_PORT}"/"${ANCHORE_DB_NAME}"?sslmode={{- .Values.upstream.anchoreConfig.database.sslMode }} upgrade --dontask;
          {{- else }}
            - |
              {{ print (include "enterprise.doSourceFile" .) }} anchore-enterprise-manager db --db-use-ssl --db-connect postgresql://"${ANCHORE_DB_USER}":"${ANCHORE_DB_PASSWORD}"@"${ANCHORE_DB_HOST}":"${ANCHORE_DB_PORT}"/"${ANCHORE_DB_NAME}"?sslmode={{- .Values.upstream.anchoreConfig.database.sslMode -}}\&sslrootcert=/home/anchore/certs/{{- .Values.upstream.anchoreConfig.datab>
          {{- end }}

12) To resolve OPA Gatekeeper violations around container resources and ratios, a field should have been added to chart/templates/bigbang/db/ensure-feeds-db.yaml, and chart/templates/bigbang/db/ensure-anchore-db.yaml to allow users to specify container resource requests and limits for the jobs:

resources: {{ toYaml .Values.ensureDbJobs.resources | nindent 12 }}

13) To resolve an issue where Anchore would redeploy after every update, chart/templates/anchore_secret.yaml and chart/deps/feeds/templates/secret.yaml should be modified to set ANCHORE_SAML_SECRET to a randomly generated value if not set and the previous secret does not exist:

{{- if not .Values.useExistingSecrets -}}
{{- /*
  If release is being upgraded, don't recreate the defaultAdminPassword or samlSecret, instead get it from the corresponding existing
  secret.
*/ -}}
{{- $anchoreSamlSecret := (include "enterprise.samlSecret" . | quote) -}}
{{- if .Release.IsUpgrade -}}
  {{- $anchoreSecret := (lookup "v1" "Secret" .Release.Namespace (include "enterprise.fullname" .)) -}}
  {{- if $anchoreSecret -}}
    {{- $anchoreSamlSecret = (index $anchoreSecret.data "ANCHORE_SAML_SECRET" | b64dec) | quote -}}
  {{- end -}}
{{- end -}}

  ANCHORE_SAML_SECRET: {{ $anchoreSamlSecret }}

14) To support metrics mTLS added appPotocol: http to the Service port spec found in chart/templates/bigbang/analyzer-service.yaml

Container Security Context Additions

9) To set all containers to run without additional capabilities, and instead to add explicit drops, several containerSecurityContext sections have been added to chart/values.yaml. Each of these sections look like the following and are referenced in the template files:

  containerSecurityContext:
    capabilities:
      drop:
        - ALL

Note that other sections with additional securityContext settings may have been modified to include explicit drops, but these were already part of the chart.

List of files that are frequently modified from upstream

warning: these are non exhaustive and should always be manually checked You will likely want to select “ours” when merging in upstream changes

  • chart/templates/ui_secret.yaml
  • chart/templates/migrate_pod.yaml
  • chart/templates/ui_secret.yaml