diff --git a/.secrets.baseline b/.secrets.baseline index a637da4a06..edc6da43aa 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -550,7 +550,7 @@ "hashed_secret": "effb7852555adce89885fb075fb43a77a1e0e77e", "is_secret": false, "is_verified": false, - "line_number": 1370, + "line_number": 1358, "type": "Secret Keyword", "verified_result": null } diff --git a/image/cli/mascli/functions/gitops_suite_app_config b/image/cli/mascli/functions/gitops_suite_app_config index 564f93840a..3da428a28b 100644 --- a/image/cli/mascli/functions/gitops_suite_app_config +++ b/image/cli/mascli/functions/gitops_suite_app_config @@ -425,7 +425,7 @@ function gitops_suite_app_config() { if [[ -n "${ICN}" ]]; then echo "✓ ICN successfully resolved: ${ICN}" echo " This ICN will be used for customer-level secrets:" - echo " - ibm-customer/${ICN}/facilities/manage-mref-keystore-password" + echo " - ibm-customer/${ICN}/facilities/{workspace_id}-facilities-vs--sn" echo " - ibm-customer/${ICN}//..." else echo "⚠ WARNING: ICN not available - customer-level secrets cannot be used" @@ -626,11 +626,10 @@ function gitops_suite_app_config() { # Set customer-level secret path (without trailing separator) export FACILITIES_VAULT_SECRET="ibm-customer${SECRETS_KEY_SEPERATOR}${ICN}${SECRETS_KEY_SEPERATOR}facilities" - export FACILITIES_LIBERTY_EXTENSIONS_SECRET="ibm-customer${SECRETS_KEY_SEPERATOR}${ICN}${SECRETS_KEY_SEPERATOR}facilities" + export FACILITIES_LIBERTY_EXTENSIONS_SECRET="${ACCOUNT_ID}${SECRETS_KEY_SEPERATOR}${CLUSTER_ID}${SECRETS_KEY_SEPERATOR}${MAS_INSTANCE_ID}${SECRETS_KEY_SEPERATOR}facilities" # Get user-provided secret name from app spec (if any) USER_PROVIDED_VAULT_SECRET=$(yq eval '.mas_appws_spec.settings.vaultSecret.secretName // ""' ${MAS_APPWS_SPEC_YAML_RESOLVED}) - USER_PROVIDED_LIBERTY_SECRET=$(yq eval '.mas_appws_spec.settings.libertyExtensionXML.secretName // ""' ${MAS_APPWS_SPEC_YAML_RESOLVED}) # Handle vault secret name if [[ -n "${USER_PROVIDED_VAULT_SECRET}" ]]; then @@ -640,11 +639,12 @@ function gitops_suite_app_config() { echo "- Verifying user-provided secret exists..." else # No user-provided name - use customer-level default - export FACILITIES_VAULT_SECRET_NAME="manage-mref-keystore-password" + export FACILITIES_VAULT_SECRET_NAME="${MAS_WORKSPACE_ID}-facilities-vs--sn" echo "- Using customer-level vault secret name: ${FACILITIES_VAULT_SECRET_NAME}" + local FACILITIES_AWS_SECRET_NAME="${MAS_WORKSPACE_ID}-facilities-vs--sn" # Ensure customer-level secret exists - manage_customer_mref_password "${ICN}" "${ACCOUNT_ID}" "${CLUSTER_ID}" "${MAS_INSTANCE_ID}" "${SECRETS_KEY_SEPERATOR}" + manage_customer_mref_password "${ICN}" "${ACCOUNT_ID}" "${CLUSTER_ID}" "${MAS_INSTANCE_ID}" "${MAS_WORKSPACE_ID}" "${SECRETS_KEY_SEPERATOR}" if [[ $? -ne 0 ]]; then echo "ERROR: Failed to create/retrieve customer-level MREF password" exit 1 @@ -652,13 +652,16 @@ function gitops_suite_app_config() { fi # Verify vault secret exists - sm_verify_secret_exists "${FACILITIES_VAULT_SECRET}${SECRETS_KEY_SEPERATOR}${FACILITIES_VAULT_SECRET_NAME}" "password" + sm_verify_secret_exists "${FACILITIES_VAULT_SECRET}${SECRETS_KEY_SEPERATOR}${FACILITIES_AWS_SECRET_NAME:-${FACILITIES_VAULT_SECRET_NAME}}" "pwd" # Handle liberty extensions secret name - if [[ -n "${USER_PROVIDED_LIBERTY_SECRET}" ]]; then - export FACILITIES_LIBERTY_EXTENSIONS_SECRET_NAME="${USER_PROVIDED_LIBERTY_SECRET}" - echo "- Using user-provided liberty extensions secret name: ${FACILITIES_LIBERTY_EXTENSIONS_SECRET_NAME}" - # Verify liberty secret exists + export FACILITIES_LIBERTY_EXTENSIONS_SECRET_NAME=$(yq eval '.mas_appws_spec.settings.libertyExtensionXML.secretName // ""' ${MAS_APPWS_SPEC_YAML_RESOLVED}) + if [[ -n "${FACILITIES_LIBERTY_EXTENSIONS_SECRET_NAME}" ]]; then + if [[ "${FACILITIES_LIBERTY_EXTENSIONS_SECRET_NAME}" != "${MAS_WORKSPACE_ID}-facilities-lexml--sn" ]]; then + echo "Error: Secret name ${FACILITIES_LIBERTY_EXTENSIONS_SECRET_NAME} does not match ${MAS_WORKSPACE_ID}-facilities-lexml--sn" + exit 1 + fi + echo "- Using liberty extensions secret name: ${FACILITIES_LIBERTY_EXTENSIONS_SECRET_NAME}" sm_verify_secret_exists "${FACILITIES_LIBERTY_EXTENSIONS_SECRET}${SECRETS_KEY_SEPERATOR}${FACILITIES_LIBERTY_EXTENSIONS_SECRET_NAME}" "b64_xml" fi fi # end if [[ "${MAS_APP_ID}" == "facilities" ]] diff --git a/image/cli/mascli/functions/gitops_utils b/image/cli/mascli/functions/gitops_utils index b625f3473d..5696a3cf74 100644 --- a/image/cli/mascli/functions/gitops_utils +++ b/image/cli/mascli/functions/gitops_utils @@ -524,17 +524,17 @@ function sm_get_secret_arn() { # This prevents backflow issues when moving data between prod/dev/test environments. # # The function: -# 1. Checks if customer-level password exists at ibm-customer/{ICN}/facilities/manage-mref-keystore-password -# 2. If not, checks for legacy instance-level password and migrates it -# 3. If neither exists, generates a new secure alphanumeric password -# 4. Stores password at customer level for reuse across all customer instances +# 1. Checks if customer-level password exists at ibm-customer/{ICN}/facilities/{MAS_WORKSPACE_ID}-facilities-vs--sn +# 2. If not, generates a new secure alphanumeric password +# 3. Stores password at customer level for reuse across all customer instances # # Args: # $1 - ICN (IBM Customer Number) # $2 - ACCOUNT_ID # $3 - CLUSTER_ID # $4 - MAS_INSTANCE_ID -# $5 - SECRETS_KEY_SEPERATOR +# $5 - MAS_WORKSPACE_ID +# $6 - SECRETS_KEY_SEPERATOR # # Returns: # 0 on success, 1 on failure @@ -544,7 +544,8 @@ function manage_customer_mref_password() { local ACCOUNT_ID="$2" local CLUSTER_ID="$3" local MAS_INSTANCE_ID="$4" - local SECRETS_KEY_SEPERATOR="$5" + local MAS_WORKSPACE_ID="$5" + local SECRETS_KEY_SEPERATOR="$6" if [[ -z "${ICN}" ]]; then echo "ERROR: ICN is required for customer-level MREF password management" @@ -555,51 +556,38 @@ function manage_customer_mref_password() { echo_h2 "Managing Customer-Level MREF AES Keystore Password" echo "- Customer ICN: ${ICN}" - # Define secret paths following customer-level secret pattern: ibm-customer/{ICN}/facilities/... - local CUSTOMER_SECRET_NAME="ibm-customer${SECRETS_KEY_SEPERATOR}${ICN}${SECRETS_KEY_SEPERATOR}facilities${SECRETS_KEY_SEPERATOR}manage-mref-keystore-password" - local LEGACY_SECRET_NAME="${ACCOUNT_ID}${SECRETS_KEY_SEPERATOR}${CLUSTER_ID}${SECRETS_KEY_SEPERATOR}${MAS_INSTANCE_ID}${SECRETS_KEY_SEPERATOR}facilities${SECRETS_KEY_SEPERATOR}manage-mref-keystore-password" - + # Define secret path following customer-level secret pattern: ibm-customer/{ICN}/facilities/... + local CUSTOMER_SECRET_NAME="ibm-customer${SECRETS_KEY_SEPERATOR}${ICN}${SECRETS_KEY_SEPERATOR}facilities${SECRETS_KEY_SEPERATOR}${MAS_WORKSPACE_ID}-facilities-vs--sn" + # Check if customer-level secret exists echo "- Checking for customer-level secret: ${CUSTOMER_SECRET_NAME}" set +o pipefail - local MREF_PASSWORD=$(sm_get_secret_value "${CUSTOMER_SECRET_NAME}" "password" 2>/dev/null) + local MREF_PASSWORD=$(sm_get_secret_value "${CUSTOMER_SECRET_NAME}" "pwd" 2>/dev/null) set -o pipefail - + if [[ -n "${MREF_PASSWORD}" ]] && [[ "${MREF_PASSWORD}" != "null" ]]; then echo "- Customer-level MREF password found, reusing existing password" return 0 fi - - # Customer-level secret doesn't exist, check for legacy instance-level secret - echo "- Customer-level secret not found, checking for legacy instance-level secret" - echo "- Checking: ${LEGACY_SECRET_NAME}" - set +o pipefail - local LEGACY_PASSWORD=$(sm_get_secret_value "${LEGACY_SECRET_NAME}" "password" 2>/dev/null) - set -o pipefail - - if [[ -n "${LEGACY_PASSWORD}" ]] && [[ "${LEGACY_PASSWORD}" != "null" ]]; then - echo "- Legacy instance-level password found, migrating to customer level" - MREF_PASSWORD="${LEGACY_PASSWORD}" - local MIGRATION_NOTE="Migrated from instance-level secret: ${LEGACY_SECRET_NAME}" - else - echo "- No existing password found, generating new secure password" - # Generate secure alphanumeric password (no special characters to avoid escaping issues) - # Use a loop to ensure we get exactly 32 characters after filtering - while true; do - MREF_PASSWORD=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | head -c 64) #pragma: allowlist secret - if [[ ${#MREF_PASSWORD} -ge 32 ]]; then - MREF_PASSWORD=${MREF_PASSWORD:0:32} #pragma: allowlist secret - break - fi - done - local MIGRATION_NOTE="Generated for first deployment" - fi + + # Secret not found, generate new secure password + echo "- No existing password found, generating new secure password" + # Generate secure alphanumeric password (no special characters to avoid escaping issues) + # Use a loop to ensure we get exactly 32 characters after filtering + while true; do + MREF_PASSWORD=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | head -c 64) #pragma: allowlist secret + if [[ ${#MREF_PASSWORD} -ge 32 ]]; then + MREF_PASSWORD=${MREF_PASSWORD:0:32} #pragma: allowlist secret + break + fi + done + local MIGRATION_NOTE="Generated for first deployment" # Store password at customer level echo "- Storing password at customer level: ${CUSTOMER_SECRET_NAME}" local TAGS="[{\"Key\": \"source\", \"Value\": \"gitops_suite_app_config\"}, {\"Key\": \"icn\", \"Value\": \"${ICN}\"}, {\"Key\": \"type\", \"Value\": \"customer-level\"}, {\"Key\": \"purpose\", \"Value\": \"mref-aes-keystore\"}, {\"Key\": \"note\", \"Value\": \"${MIGRATION_NOTE}\"}]" - sm_update_secret "${CUSTOMER_SECRET_NAME}" "{\"password\": \"${MREF_PASSWORD}\"}" "${TAGS}" + sm_update_secret "${CUSTOMER_SECRET_NAME}" "{\"pwd\": \"${MREF_PASSWORD}\"}" "${TAGS}" if [[ $? -eq 0 ]]; then echo "- Customer-level MREF password successfully stored" diff --git a/image/cli/mascli/templates/gitops/appset-configs/cluster/instance/masapp/ibm-mas-masapp-config.yaml.j2 b/image/cli/mascli/templates/gitops/appset-configs/cluster/instance/masapp/ibm-mas-masapp-config.yaml.j2 index 0b1c304544..d78c9a5d87 100644 --- a/image/cli/mascli/templates/gitops/appset-configs/cluster/instance/masapp/ibm-mas-masapp-config.yaml.j2 +++ b/image/cli/mascli/templates/gitops/appset-configs/cluster/instance/masapp/ibm-mas-masapp-config.yaml.j2 @@ -34,7 +34,7 @@ manage_update_schedule: {{ MANAGE_UPDATE_SCHEDULE }} {%- if FACILITIES_VAULT_SECRET_NAME is defined and FACILITIES_VAULT_SECRET_NAME !='' %} facilities_vault_secret_name: {{ FACILITIES_VAULT_SECRET_NAME }} -facilities_vault_secret_value: +facilities_vault_secret_value: {%- endif %} {%- if FACILITIES_LIBERTY_EXTENSIONS_SECRET_NAME is defined and FACILITIES_LIBERTY_EXTENSIONS_SECRET_NAME !='' %} facilities_liberty_extensions_secret_name: {{ FACILITIES_LIBERTY_EXTENSIONS_SECRET_NAME }}