Deploying Fortify Software Security Center in Kubernetes

This document describes how to configure and use the helm-ssc Helm chart for complete Software Security Center container orchestration in Kubernetes. You can find the Software Security Center Helm chart at https://hub.docker.com/r/fortifydocker/helm-ssc.

Table of contents

Kubernetes versions

OpenText recommends running Fortify on the tested platforms described in the product system requirements documentation. However, customers running on other platforms or with untested configurations will be supported until the point OpenText determines that the root cause is the untested platform or configuration. Issues that can be reproduced on the tested platforms will be prioritized and fixed according to standard defect-handling policies.

These charts have been tested using the following Kubernetes versions:

Tool prerequisites

OpenText recommends that you use the same tool versions to avoid unpredictable results.

Installation

The following instructions are for example purposes and are based on a default Kubernetes environment running under Linux, using the default namespace. Windows systems might require different syntax for some commands and other Kubernetes Cluster providers might require additional/different configurations. Your Kubernetes administrator might require the use of specific namespaces and/or other configuration adjustments.

Installation prerequisites

Installation steps

  1. Preparing the Fortify license file
  2. Preparing HTTP certificate passwords
  3. Preparing the HTTP keystore file
  4. Preparing the Software Security Center autoconfig file
  5. Preparing the Software Security Center Kubernetes secrets
  6. Creating an image pull secret
  7. Installing the Software Security Center release
  8. Setting up port forwarding through kubectl
  9. Verifying that Software Security Center is available
  10. Testing the admin login
  11. Special considerations for testing environments

Preparing the Fortify license file

Preparing HTTP certificate passwords

Preparing the HTTP keystore file

Preparing the Software Security Center autoconfig file

  1. Create a file /tmp/ssc.autoconfig.tpl and copy the following content to it.

    appProperties:
      host.validation: false
      authentication.max.concurrent.logins: 1
    
    datasourceProperties:
      db.username: '<DB-USERNAME>'
      db.password: '<DB-PASSWORD>'
    
      jdbc.url: 'jdbc:sqlserver://<DB-HOST>;database=<DB-NAME>;sendStringParametersAsUnicode=false;trustServerCertificate=true'
    
    dbMigrationProperties:
      migration.enabled: true
      migration.username: '<DB-USERNAME>'
      migration.password: '<DB-PASSWORD>'

Preparing the Software Security Center Kubernetes secrets

Create separate secrets for each configuration item:

  1. Create the license secret:

    kubectl create secret generic ssc-license \
      --from-file=sscLicense=/tmp/fortify-license.txt
  2. Create the autoconfig secret:

    kubectl create secret generic ssc-autoconfig \
      --from-file=sscAutoconfig=/tmp/ssc.autoconfig.tpl
  3. Create the HTTP certificate keystore secret:

    kubectl create secret generic ssc-http-keystore \
      --from-file=httpCertificateKeystore=/tmp/httpKeystore.jks
  4. Create the HTTP certificate passwords secrets:

    kubectl create secret generic ssc-http-keystore-password \
      --from-literal=httpCertificateKeystorePassword="$HTTP_KEYSTORE_PWD"
      
    kubectl create secret generic ssc-http-key-password \
      --from-literal=httpCertificateKeyPassword="$HTTP_KEY_PWD"
  5. Clean up temporary files:

    rm /tmp/httpKeystore.jks /tmp/ssc.autoconfig.tpl /tmp/fortify-license.txt
    unset HTTP_KEYSTORE_PWD HTTP_KEY_PWD
  6. Optional: For SAML configuration, if you need SAML authentication, create an IDP certificate secret:

    kubectl create secret generic ssc-idp-certificate \
       --from-file=idpCertificate=/path/to/idp-certificate.crt

Creating an image pull secret

By default, the Software Security Center Helm chart references its images directly from DockerHub. For Kubernetes to properly install your images using the default configuration, you must create an image pull secret and store it in your installation namespace in Kubernetes. If you are replicating these images to a local repository, you can skip this task and update the relevant image values in the Helm chart to reference your local repository. To create an image pull secret:

Installing the Software Security Center release

The following command installs the Software Security Center using the recommended defaults. In some cases, you might need to customize these values using the Helm --set parameter or by creating a values.yaml override file and passing it to the command line with the Helm -f flag. For more information about the values you can override, see the Helm Chart Values table.

Tip: To find the available Software Security Center Helm chart version, go to https://hub.docker.com/r/fortifydocker/helm-ssc/tags.

Setting up port forwarding through kubectl

  1. Verify that your Software Security Center pod (ssc-webapp-0) is running successfully. It might take a few minutes before your pod gets to a proper 1/1 Running configuration. You can run the command above multiple times or use the flag -w to watch for any changes.

    kubectl get pods
  2. Open a new terminal shell.

  3. Set up port forwarding through kubectl to access your Software Security Center endpoint.

    For example, to forward the localhost port 8081:

    kubectl port-forward  svc/<ssc-service-name> 8081:443

    ssc-service-name can be determined by listing the Kubernetes services using the following command:

    kubectl get services

Verifying that Software Security Center is available

  1. Follow the steps in Setting up port forwarding through kubectl.

  2. You should now be able to access the Software Security Center web endpoint from your browser.

    https://localhost:8081

Testing the admin login

  1. Follow the steps in Setting up port forwarding through kubectl.

  2. Access the login endpoint from your browser:

    https://localhost:8081
  3. Log in to Software Security Center with the default admin credentials. The default username is admin and the password is admin. You must change the admin password the first time you login.

Special considerations for testing environments

By default, the Helm chart defines the container resource/requests based on recommended best-practice values intended to prevent performance issues and unexpected Kubernetes evictions of containers and pods. These values are often too large for a small test environment that does not require the same level of resources. You can override the resource requests by passing additional value --set resources=null in the helm install command above.

WARNING: Using the above option in production is not supported and will lead to unstable behavior.

Upgrade

This section explains how to upgrade Software Security Center from a previous release to version 26.2.

Upgrade prerequisites

Upgrading from previous version

Important: Version 25.4 introduced a breaking change in secret management architecture. If you are upgrading from a previous version, you must migrate from the monolithic secret approach to discrete secrets before proceeding with the upgrade.

Important: Refer to SSC User Guide for Upgrade of SSC from 25.4 to 26.2 for the support of MYSQL8.4

Upgrade steps
  1. Migrating from monolithic secret to discrete secrets
  2. Preparing the values file
  3. Upgrading the Software Security Center release
  4. Verifying Software Security Center after the upgrade

Migrating from monolithic secret to discrete secrets

Version 25.4 replaced the single monolithic secret architecture with discrete secrets. This new approach provides: If you are upgrading from a previous version that used the secretRef configuration with a single secret (typically named ssc-secret), follow these migration steps.

  1. Export the important environment variables for secrets migration.

    export SSC_HELM_RELEASE=<SSC_HELM_RELEASE>   # Replace with your SSC release name
    export SSC_NAMESPACE=<SSC_NAMESPACE>  # Replace with the namespace in which SSC is deployed
    export SSC_SECRET_NAME=$(helm -n $SSC_NAMESPACE get values $SSC_HELM_RELEASE  | yq .secretRef.name)
  2. Create the ssc-license secret from the existing secret

    SSC_LICENSE_KEY=$(helm -n $SSC_NAMESPACE get values $SSC_HELM_RELEASE | yq -r '.secretRef.keys.sscLicenseEntry')
    kubectl -n $SSC_NAMESPACE get secret $SSC_SECRET_NAME -o yaml | yq eval -r ".data[\"$SSC_LICENSE_KEY\"]" | base64 -d > /tmp/fortify-license.txt
    kubectl -n $SSC_NAMESPACE create secret generic ssc-license --from-file=sscLicense=/tmp/fortify-license.txt
  3. Create the ssc-autoconfig secret from the existing secret

    SSC_AUTOCONFIG_KEY=$(helm -n $SSC_NAMESPACE get values $SSC_HELM_RELEASE  | yq -r '.secretRef.keys.sscAutoconfigEntry')
    kubectl -n $SSC_NAMESPACE get secret $SSC_SECRET_NAME -o yaml | yq eval -r ".data[\"$SSC_AUTOCONFIG_KEY\"]" | base64 -d > /tmp/ssc-autoconfig.tpl
    kubectl -n $SSC_NAMESPACE create secret generic ssc-autoconfig --from-file=sscAutoconfig=/tmp/ssc-autoconfig.tpl
  4. Create the ssc-http-keystore secret from the existing secret

    HTTP_KEYSTORE_FILE_KEY=$(helm -n $SSC_NAMESPACE get values $SSC_HELM_RELEASE  | yq -r '.secretRef.keys.httpCertificateKeystoreFileEntry')
    kubectl -n $SSC_NAMESPACE get secret $SSC_SECRET_NAME -o yaml | yq eval -r ".data[\"$HTTP_KEYSTORE_FILE_KEY\"]" | base64 -d > /tmp/httpKeystore.jks
    kubectl -n $SSC_NAMESPACE create secret generic ssc-http-keystore --from-file=httpCertificateKeystore=/tmp/httpKeystore.jks
  5. Create the ssc-http-keystore-password secret from the existing secret

    HTTP_KEYSTORE_PWD_KEY=$(helm -n $SSC_NAMESPACE get values $SSC_HELM_RELEASE  | yq -r '.secretRef.keys.httpCertificateKeystorePasswordEntry')
    HTTP_KEYSTORE_PWD=$(kubectl -n $SSC_NAMESPACE get secret $SSC_SECRET_NAME -o yaml | yq eval -r ".data[\"$HTTP_KEYSTORE_PWD_KEY\"]" | base64 -d)
    kubectl -n $SSC_NAMESPACE create secret generic ssc-http-keystore-password --from-literal=httpCertificateKeystorePassword="$HTTP_KEYSTORE_PWD"
  6. Create the ssc-http-key-password secret from the existing secret

    HTTP_KEY_PWD_KEY=$(helm -n $SSC_NAMESPACE get values $SSC_HELM_RELEASE  | yq -r '.secretRef.keys.httpCertificateKeyPasswordEntry')
    HTTP_KEY_PWD=$(kubectl -n $SSC_NAMESPACE get secret $SSC_SECRET_NAME -o yaml | yq eval -r ".data[\"$HTTP_KEY_PWD_KEY\"]" | base64 -d)
    kubectl -n $SSC_NAMESPACE create secret generic ssc-http-key-password --from-literal=httpCertificateKeyPassword="$HTTP_KEY_PWD"
  7. If present, optionally migrate additional secret keys such as the HTTP truststore, JVM truststore, SAML IDP certificate, etc. For each key, execute the corresponding command and replace all placeholder values with the appropriate configuration details.

    SECRET_KEY_ENTRY_NAME="<PLACEHOLDER_OLD_SECRET_KEY_NAME>"  # e.g., sscSecretKeyEntry, idpCertificateEntry, httpTruststoreFileEntry
    NEW_SECRET_NAME="<PLACEHOLDER_NEW_SECRET_NAME>"             # e.g., ssc-secret-key, idp-certificate, http-truststore
    NEW_SECRET_KEY="<PLACEHOLDER_NEW_SECRET_KEY>"               # e.g., sscSecretKey, idpCertificate, httpTruststore
    TEMP_FILE_PATH="<PLACEHOLDER_TEMP_FILE_PATH>"               # e.g., /tmp/secret.txt, /tmp/cert.pem
    
    # Extract and migrate the secret
    SECRET_VALUE=$(helm -n $SSC_NAMESPACE get values $SSC_HELM_RELEASE | yq -r ".secretRef.keys.$SECRET_KEY_ENTRY_NAME")
    kubectl -n $SSC_NAMESPACE get secret $SSC_SECRET_NAME -o yaml | yq eval -r ".data[\"$SECRET_VALUE\"]" | base64 -d > "$TEMP_FILE_PATH"
    kubectl -n $SSC_NAMESPACE create secret generic "$NEW_SECRET_NAME" --from-file="$NEW_SECRET_KEY=$TEMP_FILE_PATH"
    rm -f "$TEMP_FILE_PATH"
  8. Remove temporary files and clear environment variables to maintain security:

    # Remove all temporary files
    rm -f /tmp/fortify-license.txt /tmp/ssc-autoconfig.tpl /tmp/httpKeystore.jks
    rm -f /tmp/httpTruststore.jks /tmp/jvmTruststore.jks /tmp/idpCertificate.crt
    
    # Clear environment variables
    unset HTTP_KEYSTORE_PWD HTTP_KEY_PWD HTTP_TRUSTSTORE_PWD JVM_TRUSTSTORE_PWD EXISTING_SECRET_NAME

Preparing the values file

Update your values.yaml file to reference the new discrete secrets instead of the monolithic secret structure.

Previous configuration (monolithic secret):

secretRef:
  name: ssc-secret
keys:
  sscLicenseEntry: fortify-license.txt
  sscAutoconfigEntry: ssc.autoconfig.tpl
  httpCertificateKeystoreFileEntry: httpKeystore.jks
  httpCertificateKeyPasswordEntry: httpCertificateKeyPassword
  httpCertificateKeystorePasswordEntry: httpCertificateKeystorePassword

New configuration (discrete secrets):

# Required secrets - these must be configured
sscLicenseSecret: ssc-license
sscLicenseKey: sscLicense
httpCertificateKeystoreSecret: ssc-http-keystore
httpCertificateKeystoreKey: httpCertificateKeystore
httpCertificateKeystorePasswordSecret: ssc-http-keystore-password
httpCertificateKeystorePasswordKey: httpCertificateKeystorePassword
httpCertificateKeyPasswordSecret: ssc-http-key-password
httpCertificateKeyPasswordKey: httpCertificateKeyPassword

# Optional secrets - uncomment and configure if you have these configuration in your environment
# sscAutoconfigSecret: ssc-autoconfig
# sscAutoconfigKey: sscAutoconfig
# sscSecretKeySecret: ssc-secret-key
# sscSecretKeyKey: sscSecretKey
# httpTruststoreSecret: ssc-http-truststore
# httpTruststoreKey: httpTruststore
# httpTruststorePasswordSecret: ssc-http-truststore-password
# httpTruststorePasswordKey: httpTruststorePassword
# jvmTruststoreSecret: ssc-jvm-truststore
# jvmTruststoreKey: jvmTruststore
# jvmTruststorePasswordSecret: ssc-jvm-truststore-password
# jvmTruststorePasswordKey: jvmTruststorePassword
# idpCertificateSecret: ssc-idp-certificate
# idpCertificateKey: idpCertificate

Note: The sscAutoconfigSecret and sscAutoconfigKey parameters are optional. When omitted (or left as empty strings), SSC will start in manual installation wizard mode, allowing you to configure the database and other settings through the web interface.

After updating the secret references, review and merge any other configuration changes from the current release. See the complete values reference for all available configuration options.

Upgrading the Software Security Center release

Execute the Helm upgrade command to apply the new configuration:

helm -n $SSC_NAMESPACE upgrade $SSC_HELM_RELEASE oci://registry-1.docker.io/fortifydocker/helm-ssc \
  --version <ssc-helm-chart-version> \
  -f values.yaml \
  --reuse-values

Replace:

Verifying Software Security Center after the upgrade

After completing the upgrade, verify that Software Security Center is functioning correctly:

  1. Check that the pod is running:

    kubectl -n $SSC_NAMESPACE get pods -l app.kubernetes.io/name=ssc
  2. Verify Software Security Center is accessible by following the steps in Setting up port forwarding through kubectl and confirming you can access the web interface at https://localhost:8081.

  3. Test the admin login following the steps in Testing the admin login.

  4. Verify your existing applications and scan results are intact.

Post-upgrade cleanup (optional)

After thoroughly testing the upgraded deployment and confirming everything works correctly, you can safely remove the old monolithic secret:

# Only execute this command after verifying the upgrade was successful
kubectl -n $SSC_NAMESPACE delete secret $SSC_SECRET_NAME

Warning: Do not delete the old secret until you have verified that:

Note: Ensure to temporarily retain the old secret in case you want to rollback the deployment.

Values

The following values are exposed by the Helm Chart. Unless specified as Required, only override values as required for your specific environment.

Required

Key Type Default Description
httpCertificateKeyPasswordKey string "" Specifies the key in the Kubernetes secret for the key password
httpCertificateKeyPasswordSecret string "" Specifies the Kubernetes secret to store the password for the HTTP certificate key
httpCertificateKeystoreKey string "" Specifies the key in the Kubernetes secret for the keystore file
httpCertificateKeystorePasswordKey string "" Specifies the key in the Kubernetes secret for the keystore password
httpCertificateKeystorePasswordSecret string "" Specifies the Kubernetes secret to store the password for the HTTP keystore
httpCertificateKeystoreSecret string "" Specifies the Kubernetes secret to store the HTTP certificate keystore
persistentVolumeClaim.size string "4Gi" Specifies the size of the persistent volume created for Software Security Center pod.
sscLicenseKey string "" Specifies the key in the Kubernetes secret for the license file
sscLicenseSecret string "" Specifies the Kubernetes secret to store the Fortify license file
urlHost string "" Specifies the fully qualified DNS name to access the application externally.

Other Values

Key Type Default Description
affinity pod.affinity {} Defines Node Affinity configurations to add to pods.
customResources object {"enabled":false,"resources":{}} Defines Kubernetes resources to be installed and configured as part of the Helm chart. If you provide any resources, you must provide them as quoted, using single quotation marks '.
customResources.enabled bool false Indicates whether to enable custom resource creation.
customResources.resources Kubernetes YAML {} Specifies the custom resources to generate.
environment list [] Specifies any additional environment variables to add to the pods.
fullnameOverride string {deployment_name}-{service_name} Overrides the fully qualified app name of the release.
httpClientCertificateVerification string "none" Specifies the configuring HTTPS client certificate verification, supported values: "none", "optional", "required".
httpTruststoreKey string "" Specifies the key in the Kubernetes secret for the truststore file
httpTruststorePasswordKey string "" Specifies the key in the Kubernetes secret for the truststore password
httpTruststorePasswordSecret string "" Specifies the Kubernetes secret to store the password for the HTTP truststore (optional)
httpTruststoreSecret string "" Specifies the Kubernetes secret to store the HTTP truststore (optional)
idpCertificateKey string "" Specifies the key in the Kubernetes secret for the IDP certificate file
idpCertificateSecret string "" Specifies the Kubernetes secret to store the IDP certificate (required if SAML enabled)
image.pullPolicy string "IfNotPresent" Specifies the image pull behavior.
image.repository string "fortifydocker/ssc-webapp" Specifies the Docker repository from which to pull the Software Security Center Docker image.
image.tag string "26.2.0.0183"
imagePullSecrets list [] Specifies a list of references to secrets in the same namespace to use for pulling any of the images used by the current release.
ingress.annotations object {} Specifies annotations to add to the resource.
ingress.className string "" Identifies the Ingress resource class name.
ingress.enabled bool false Indicates whether to enable Ingress.
ingress.hosts[0] object {"host":"ssc.local","paths":[{"path":"/","pathType":"Prefix"}]} Specifies the hostname through which to accept requests.
ingress.hosts[0].paths[0] object {"path":"/","pathType":"Prefix"} Specifies the path through which to accept requests.
ingress.hosts[0].paths[0].pathType string "Prefix" Specifies the path type.
ingress.tls list [] Defines TLS configurations. The setting is expressed in the following format: [{"hosts":["some-host"], "secretName":"some-name"}]
ingressScim.annotations object {} Specifies annotations to add to the resource.
ingressScim.className string "" Identifies the ingress resource class name.
ingressScim.enabled bool false Indicates whether to enable IngressScim.
ingressScim.hosts[0] object {"host":"ssc-scim.local","paths":[{"path":"/api/scim/v2","pathType":"Exact"}]} Specifies the hostname through which to accept requests.
ingressScim.hosts[0].paths[0] object {"path":"/api/scim/v2","pathType":"Exact"} Specifies the path through which to accept requests.
ingressScim.hosts[0].paths[0].pathType string "Exact" Specifies the path type.
ingressScim.tls list [] Defines TLS configurations. The setting is expressed in the following format: [{"hosts":["some-host"], "secretName":"some-name"}]
jvmExtraOptions string "" Specifies a set of additional options passed to the Java process.
jvmMaxRAMPercentage int 86 Specifies percentage of memory limit to be used for JVM heap.
jvmTruststoreKey string "" Specifies the key in the Kubernetes secret for the JVM truststore file
jvmTruststorePasswordKey string "" Specifies the key in the Kubernetes secret for the JVM truststore password
jvmTruststorePasswordSecret string "" Specifies the Kubernetes secret to store the password for the JVM truststore (optional)
jvmTruststoreSecret string "" Specifies the Kubernetes secret to store the JVM truststore (optional)
nameOverride string ssc Overrides the name of this chart.
nodeSelector pod.nodeSelector {"kubernetes.io/arch":"amd64","kubernetes.io/os":"linux"} Defines Node selection constraint configurations to add to the pods.
persistentVolumeClaim.annotations object {} Persistent Volume Claim annotations. Used when 'existingClaim' is not defined.
persistentVolumeClaim.existingClaim string nil Specifies the use of a pre-existing PersistentVolumeClaim. Supercedes all other PersistentVolumeClaim values.
persistentVolumeClaim.selector object {} Specifies the Kubernetes PersistentVolumeClaim selector.
persistentVolumeClaim.storageClassName string "" Specifies the storage class name used for the persistent volume.
podAnnotations pod.annotations {} Defines annotations to add to the pods.
priorityClassName string "" Specifies a priority class for the pod to run as. Requires an existing PriorityClass to be defined in Kubernetes prior to use.
resources.limits.cpu int 8 Defines the limits of CPU resources granted to the pod.
resources.limits.memory string "28Gi" Defines the limits of memory resources granted to the pod.
resources.requests.cpu int 1 Defines the initial request of cpu resources granted to the pod.
resources.requests.memory string "7Gi" Defines the initial request of memory resources granted to the pod.
saml.enable bool false Indicates whether to enable external SAML.
service.annotations object {} Specifies the map of annotations applied to the service.
service.clusterIP string "" Specifies the fixed service cluster IP address, if empty, Kubernetes assigns a value.
service.httpPort int 80 Specifies the port to expose for HTTP calls.
service.httpsPort int 443 Specifies the port to expose for HTTPS calls.
service.loadBalancerIP string "" Specifies the fixed load balancer IP address. If empty, the Kubernetes cloud provider assigns a value.
service.type string "ClusterIP" Specifies the type of Service to use.
sscAutoconfigKey string "" Specifies the key in the Kubernetes secret for the autoconfig file. Required when sscAutoconfigSecret is set.
sscAutoconfigSecret string "" Specifies the Kubernetes secret to store the SSC autoconfig file. When left empty, SSC starts in manual installation wizard mode.
sscPathPrefix string "/" Specifies the URL path prefix where the Software Security Center application is accessed.
sscSecretKeyKey string "" Specifies the key in the Kubernetes secret for the secret.key file
sscSecretKeySecret string "" Specifies the Kubernetes secret to store the SSC secret.key file (optional)
tolerations pod.tolerations [] Defines Toleration configurations to add to the pod(s).
urlPort int 0 Specifies the HTTPS port for externally accessing the application. If zero, a value of service.httpsPort is used instead.
user pod.securityContext {"gid":0,"uid":1111} Defines security context configurations to add to the pods.