Automated SIGN+ Package Installation and Configuration
Configure your Azure DevOps pipeline to install and configure SIGN+ automatically on every run, without manual agent setup.
Overview
Previously, you had to manually install and configure the SIGN+ package on each build agent before any signing job could run. This manual setup created extra work whenever you added new agents, scaled your infrastructure, or moved pipelines to a new pool.
Starting with version 2026.3.0, you can configure your Azure DevOps pipeline to install and configure SIGN+ automatically every time it runs without touching the agent manually. The pipeline detects whether SIGN+ is already installed; if it is, installation is skipped and the signing step starts immediately.
This topic covers three approaches for getting the SIGN+ package onto your build agent. Choose the approach that best fits your team's setup.
jarsigner on a Linux agent. Use the generated JSON configuration
file (described in Understanding the JSON Configuration File) to retrieve the correct
commands for other file types such as Android APK, Windows PE, XML, or container
images.Prerequisites
- An active AppViewX account with a configured code-signing policy.
- Your OAuth client ID and client secret (or username and password for basic authentication). Store these as Secret variables in Azure DevOps never put credentials directly in pipeline files.
- The name of your SIGN+ signing policy. Your AppViewX administrator can provide this.
- The Linux utilities
jqandunzipavailable on your build agent, or permission to install them during the pipeline run.
How automated installation works
The automated installation follows the same steps every time. Understanding these steps helps you troubleshoot issues and customize the process for your team.
- Get the SIGN+ package. The pipeline either reads the package from the repository, downloads it from the AppViewX API, or downloads it using a secure OAuth token. The exact method depends on the approach you choose.
- Check whether SIGN+ is already installed. If the package is already extracted and installed at the configured work directory, the pipeline skips extraction and installation. This saves time on repeated pipeline runs.
- Install SIGN+. If this is the first run, the pipeline extracts the package, sets the correct file permissions, and runs the SIGN+ Installer.
- Read the signing commands. After installation, SIGN+ generates a JSON configuration file that contains the exact signing and verification commands for your policy. The pipeline reads this file to get the correct command to run.
- Sign and verify your artifact. The pipeline runs the signing command, then verifies that the signature was applied correctly.
Approach 1: Store the SIGN+ package in your repository (Recommended)
In this approach, you commit the SIGN+ package file directly to your Git repository. The pipeline reads it from there no internet connection to the AppViewX server is needed at pipeline run time.
This is the recommended approach for most teams because it:
- Keeps pipeline run times short no large file download happens on every build.
- Removes the runtime dependency on the AppViewX server being reachable.
- Works reliably even during network disruptions.
SIGN_PLUS_ZIP variable to point to that location.Repository structure
Your repository must contain these files:
your-repository/
├── azure-pipelines.yml
├── scripts/
│ └── sign-with-signplus.sh
└── <YourPolicyName>_SIGN+_Package.zip ← SIGN+ package committed here
Step-by-step setup
- Download the SIGN+ package for Linux from the AppViewX portal.
- Commit the downloaded .zip file to the root of your repository (or a known path).
- Create scripts/sign-with-signplus.sh in your repository with the script content shown in The Signing Script.
- Copy the pipeline YAML below into your azure-pipelines.yml file.
Replace
<YourPolicyName>_SIGN+_Package.zipwith your actual zip file name, and updateSIGNPLUS_POLICYinside the signing script to match your policy name. - In Azure DevOps, create two pipeline variables:
SIGNPLUS_CLIENTIDyour OAuth client ID.SIGNPLUS_CLIENTSECRETyour OAuth client secret. Mark this variable as Secret so its value is hidden in logs.
- Push to
mainormasterto start a build.
Pipeline configuration azure-pipelines.yml
trigger:
- main
- master
pr:
- main
- master
stages:
# Stage 1: Build
- stage: Build
displayName: Build Java
jobs:
- job: MavenBuild
displayName: Maven package
pool:
name: Default
steps:
- checkout: self
displayName: Checkout source
- script: mvn -B clean test package
displayName: Maven clean test package
workingDirectory: sample-java-app
- task: PublishPipelineArtifact@1
displayName: Publish unsigned JAR
inputs:
targetPath: sample-java-app/target/sample-java-app-1.0.0.jar
artifact: unsigned-jar
publishLocation: pipeline
# Stage 2: Sign
- stage: Sign
displayName: Sign JAR with SIGN+
dependsOn: Build
jobs:
- job: SignJar
displayName: Install SIGN+ and sign
pool:
name: Default
steps:
- checkout: self
displayName: Checkout source and SIGN+ package
- task: DownloadPipelineArtifact@2
displayName: Download unsigned JAR
inputs:
buildType: current
artifactName: unsigned-jar
targetPath: $(Pipeline.Workspace)/unsigned-jar
- script: |
set -e
if ! command -v jq >/dev/null 2>&1; then
sudo apt-get update -qq
sudo apt-get install -y -qq jq unzip
fi
displayName: Ensure jq and unzip
- script: |
set -euo pipefail
chmod +x scripts/sign-with-signplus.sh
export SIGN_PLUS_ZIP="$(Build.SourcesDirectory)/<YourPolicyName>_SIGN+_Package.zip"
export INPUT_JAR="$(Pipeline.Workspace)/unsigned-jar/sample-java-app-1.0.0.jar"
export OUTPUT_JAR="$(Pipeline.Workspace)/signed/sample-java-app-1.0.0_signed.jar"
export SIGN_PLUS_WORK_DIR="$(Agent.TempDirectory)/signplus"
mkdir -p "$(Pipeline.Workspace)/signed"
scripts/sign-with-signplus.sh
displayName: SIGN+ install, sign, verify
env:
SIGNPLUS_CLIENTID: $(SIGNPLUS_CLIENTID)
SIGNPLUS_CLIENTSECRET: $(SIGNPLUS_CLIENTSECRET)
- task: PublishPipelineArtifact@1
displayName: Publish signed JAR
inputs:
targetPath: $(Pipeline.Workspace)/signed/sample-java-app-1.0.0_signed.jar
artifact: signed-jar
publishLocation: pipeline
The signing script
Create scripts/sign-with-signplus.sh in your repository. This script installs SIGN+ (if not already installed) and runs the signing and verification commands. The script reads the correct commands directly from the JSON configuration file that SIGN+ generates after installation.
Required environment variables
| Variable | Description |
|---|---|
SIGNPLUS_CLIENTID |
Your OAuth client ID from AppViewX. |
SIGNPLUS_CLIENTSECRET |
Your OAuth client secret. Mark as Secret in Azure DevOps. |
SIGN_PLUS_ZIP |
Full path to the SIGN+ package .zip file. |
INPUT_JAR |
Full path to the unsigned artifact to sign. |
OUTPUT_JAR |
Full path where the signed artifact is saved. |
SIGN_PLUS_WORK_DIR |
(Optional) Directory where SIGN+ is installed and cached between pipeline runs.
Defaults to ~/signplus-package. Reusing the same directory avoids
reinstalling SIGN+ on every run. |
#!/usr/bin/env bash
# Installs SIGN+ (idempotent) and signs/verifies a single JAR using jarsigner.
set -euo pipefail
# Validate required variables
if [[ "${SIGNPLUS_CLIENTID:-}" == '$(SIGNPLUS_CLIENTID)' || \
"${SIGNPLUS_CLIENTSECRET:-}" == '$(SIGNPLUS_CLIENTSECRET)' ]]; then
echo "[ERROR] Pipeline variables were not expanded."
echo " Define SIGNPLUS_CLIENTID and SIGNPLUS_CLIENTSECRET in Azure DevOps."
exit 1
fi
: "${SIGNPLUS_CLIENTID:?SIGNPLUS_CLIENTID is required}"
: "${SIGNPLUS_CLIENTSECRET:?SIGNPLUS_CLIENTSECRET is required}"
: "${SIGN_PLUS_ZIP:?SIGN_PLUS_ZIP is required}"
: "${INPUT_JAR:?INPUT_JAR is required}"
: "${OUTPUT_JAR:?OUTPUT_JAR is required}"
SIGNPLUS_AUTHTYPE="oAuth"
SIGNPLUS_POLICY="AzurePolicy" # Update to match your policy name
WORK_DIR="${SIGN_PLUS_WORK_DIR:-$HOME/signplus-package}"
SIGN_PLUS_PACKAGE_DIR="$WORK_DIR/$(basename "$SIGN_PLUS_ZIP" .zip)"
mkdir -p "$WORK_DIR"
# Install SIGN+ (skipped if already installed)
if [[ -f "$SIGN_PLUS_PACKAGE_DIR/SIGN+_Installer" ]]; then
echo "[INFO] SIGN+ already installed — skipping."
else
echo "[STEP 1] Extracting SIGN+ package..."
unzip -o "$SIGN_PLUS_ZIP" -d "$SIGN_PLUS_PACKAGE_DIR"
echo "[STEP 2] Setting installer permissions..."
chmod +x "$SIGN_PLUS_PACKAGE_DIR/SIGN+_Installer"
echo "[STEP 3] Installing SIGN+..."
cd "$SIGN_PLUS_PACKAGE_DIR"
./SIGN+_Installer Install \
--authtype "$SIGNPLUS_AUTHTYPE" \
--username "$SIGNPLUS_CLIENTID" \
--password "$SIGNPLUS_CLIENTSECRET" \
--overwriteInstallation
fi
cd "$SIGN_PLUS_PACKAGE_DIR"
echo "[STEP 4] Current SIGN+ configuration:"
./SIGN+_Installer Print
# Read signing commands from the generated JSON file
JSON_FILE="$SIGN_PLUS_PACKAGE_DIR/README_${SIGNPLUS_POLICY}.json"
if [[ ! -f "$JSON_FILE" ]]; then
echo "[ERROR] JSON config not found: $JSON_FILE"
exit 1
fi
echo "[STEP 5] Reading signing commands from $JSON_FILE..."
RAW_SIGN_CMD=$(jq -r '.pkcs11.sign.jarsigner' "$JSON_FILE")
RAW_VERIFY_CMD=$(jq -r '.pkcs11.verify.jarsigner' "$JSON_FILE")
if [[ "$RAW_SIGN_CMD" == "null" || -z "$RAW_SIGN_CMD" ]]; then
echo "[ERROR] jarsigner sign command not found in JSON"
exit 1
fi
mkdir -p "$(dirname "$OUTPUT_JAR")"
FINAL_SIGN_CMD="${RAW_SIGN_CMD//<input_file_path>/$INPUT_JAR}"
FINAL_SIGN_CMD="${FINAL_SIGN_CMD//<output_file_path>/$OUTPUT_JAR}"
FINAL_VERIFY_CMD="${RAW_VERIFY_CMD//<signed_file_path>/$OUTPUT_JAR}"
echo "[STEP 6] Signing artifact..."
eval "$FINAL_SIGN_CMD"
echo "[STEP 7] Verifying signature..."
eval "$FINAL_VERIFY_CMD"
echo "Signed artifact ready: $OUTPUT_JAR"
Approach 2: Download the SIGN+ package at runtime
The download script caches the package after the first download. Subsequent runs on the same agent reuse the cached file and skip the download.
Two variants are available:
- Variant A Basic download: Downloads the default SIGN+ package for your operating system. Use this when your signing policy does not require a specific certificate thumbprint at download time.
- Variant B Policy-specific download: Downloads a package pre-configured for a specific signing policy and certificate. Use this when your AppViewX environment has multiple policies and you need to target a specific one.
Variant A Basic package download script
#!/usr/bin/env bash
# Downloads the SIGN+ package from the AppViewX API (basic, no policy filter).
set -euo pipefail
: "${SIGNPLUS_USERNAME:?SIGNPLUS_USERNAME is required}"
: "${SIGNPLUS_PASSWORD:?SIGNPLUS_PASSWORD is required}"
: "${SIGNPLUS_API_HOST:?SIGNPLUS_API_HOST is required}"
: "${SIGNPLUS_API_PORT:?SIGNPLUS_API_PORT is required}"
: "${OUTPUT_FILE:?OUTPUT_FILE is required}"
PACKAGE_TYPE="${SIGNPLUS_PACKAGE_TYPE:-Linux}"
API_URL="https://${SIGNPLUS_API_HOST}:${SIGNPLUS_API_PORT}/avxapi/code-signing-download-csp-pkcs11-dll-sign?gwsource=external"
# Skip if package is already cached and valid
if [[ -f "$OUTPUT_FILE" ]] && unzip -t "$OUTPUT_FILE" >/dev/null 2>&1; then
echo "[INFO] SIGN+ package already cached — skipping download."
exit 0
fi
mkdir -p "$(dirname "$OUTPUT_FILE")"
JSON_PAYLOAD="{\"payload\":{\"packageType\":\"${PACKAGE_TYPE}\"}}"
TMPFILE=$(mktemp)
trap 'rm -f "$TMPFILE"' EXIT
HTTP_STATUS=$(curl -k --location "${API_URL}" \
--header "Content-Type: application/json" \
--header "username: ${SIGNPLUS_USERNAME}" \
--header "password: ${SIGNPLUS_PASSWORD}" \
--data "${JSON_PAYLOAD}" \
--output "${TMPFILE}" \
-w '%{http_code}')
if [[ "${HTTP_STATUS}" -eq 200 ]]; then
FILE_CONTENT=$(jq -r '.response.fileContent // empty' "${TMPFILE}")
if [[ -z "${FILE_CONTENT}" ]]; then
echo "[ERROR] Response did not contain .response.fileContent"
exit 1
fi
echo "${FILE_CONTENT}" | base64 -d > "${OUTPUT_FILE}"
unzip -t "${OUTPUT_FILE}" >/dev/null
echo "[INFO] Package downloaded and verified: ${OUTPUT_FILE}"
else
echo "[ERROR] HTTP ${HTTP_STATUS} — download failed."
exit 1
fi
Variant B Policy-specific download script
Use this variant when you need a package pre-configured for a specific signing policy and certificate thumbprint. Ask your AppViewX administrator for the certificate thumbprint value for your policy.
#!/usr/bin/env bash
# Downloads the SIGN+ package for a specific signing policy.
set -euo pipefail
: "${SIGNPLUS_USERNAME:?}"
: "${SIGNPLUS_PASSWORD:?}"
: "${SIGNPLUS_API_HOST:?}"
: "${SIGNPLUS_API_PORT:?}"
: "${SIGNPLUS_POLICY_NAME:?}"
: "${SIGNPLUS_POLICY_VALUE:?}"
: "${OUTPUT_FILE:?}"
PAYLOAD_USER_NAME="${SIGNPLUS_PAYLOAD_USER_NAME:-$SIGNPLUS_USERNAME}"
PACKAGE_TYPE="${SIGNPLUS_PACKAGE_TYPE:-Linux}"
AUTH_TYPE="${SIGNPLUS_AUTH_TYPE:-basicAuth}"
API_URL="https://${SIGNPLUS_API_HOST}:${SIGNPLUS_API_PORT}/avxapi/code-signing-download-csp-pkcs11-dll-sign?gwsource=external"
if [[ -f "$OUTPUT_FILE" ]] && unzip -t "$OUTPUT_FILE" >/dev/null 2>&1; then
echo "[INFO] Package cached at $OUTPUT_FILE — skipping download."
exit 0
fi
mkdir -p "$(dirname "$OUTPUT_FILE")"
JSON_PAYLOAD=$(cat <<EOF
{
"payload": {
"userName": "${PAYLOAD_USER_NAME}",
"packageType": "${PACKAGE_TYPE}",
"authType": "${AUTH_TYPE}",
"signingPolicy": {
"${SIGNPLUS_POLICY_NAME}": "${SIGNPLUS_POLICY_VALUE}"
}
}
}
EOF
)
TMPFILE=$(mktemp)
trap 'rm -f "$TMPFILE"' EXIT
HTTP_STATUS=$(curl -k --location "${API_URL}" \
--header "Content-Type: application/json" \
--header "username: ${SIGNPLUS_USERNAME}" \
--header "password: ${SIGNPLUS_PASSWORD}" \
--data "${JSON_PAYLOAD}" \
--output "${TMPFILE}" \
-w '%{http_code}')
if [[ "${HTTP_STATUS}" -eq 200 ]]; then
FILE_CONTENT=$(jq -r '.response.fileContent // empty' "${TMPFILE}")
if [[ -z "${FILE_CONTENT}" ]]; then
echo "[ERROR] Response body missing .response.fileContent"; exit 1
fi
echo "${FILE_CONTENT}" | base64 -d > "${OUTPUT_FILE}"
unzip -t "${OUTPUT_FILE}" >/dev/null
echo "[INFO] Package downloaded and verified: ${OUTPUT_FILE}"
else
echo "[ERROR] HTTP ${HTTP_STATUS}"; exit 1
fi
API request payload reference
| Field | Required | Description |
|---|---|---|
packageType |
Yes | The operating system of your build agent. Accepted values:
Linux or Windows. |
userName |
No | The AppViewX username to associate with the package. Defaults to
SIGNPLUS_USERNAME if omitted. |
authType |
Variant B only | The authentication type configured in AppViewX. Accepted values:
basicAuth or oAuth. |
signingPolicy |
Variant B only | A key-value pair that identifies the signing policy and certificate:
{ "<PolicyName>": "<username>=<certificateThumbprint>"
}. Ask your AppViewX administrator for the certificate
thumbprint. |
connectionType |
No | Set to Custom if signing requests must go through a load
balancer or custom URL rather than the default AppViewX server address. |
loadBalancerURL |
No | The full URL of your load balancer, for example
https://example.com:443. Include this when
connectionType is Custom. |
Pipeline configuration azure-pipelines.yml (Approach 2)
trigger: - main variables: SIGNPLUS_API_HOST: "<your-appviewx-server>" SIGNPLUS_API_PORT: "<api-port>" SIGNPLUS_PACKAGE_TYPE: Linux SIGNPLUS_AUTH_TYPE: "oAuth" SIGNPLUS_POLICY_NAME: "<your-policy-name>" stages: # Stage 1: Build - stage: Build displayName: Build Java jobs: - job: MavenBuild pool: name: Default steps: - checkout: self - script: mvn -B clean test package workingDirectory: sample-java-app - task: PublishPipelineArtifact@1 inputs: targetPath: sample-java-app/target/sample-java-app-1.0.0.jar artifact: unsigned-jar publishLocation: pipeline # Stage 2: Sign - stage: Sign displayName: Sign JAR (API download) dependsOn: Build jobs: - job: SignJar pool: name: Default steps: - checkout: self - task: DownloadPipelineArtifact@2 inputs: buildType: current artifactName: unsigned-jar targetPath: $(Pipeline.Workspace)/unsigned-jar - script: | set -e if ! command -v jq >/dev/null 2>&1; then sudo apt-get update -qq && sudo apt-get install -y -qq jq unzip curl fi displayName: Ensure jq, unzip, curl - script: | set -euo pipefail chmod +x scripts/download-signplus-api.sh scripts/sign-with-signplus.sh export OUTPUT_FILE="$(Agent.TempDirectory)/signplus_package.zip" scripts/download-signplus-api.sh echo "##vso[task.setvariable variable=SIGN_PLUS_ZIP]${OUTPUT_FILE}" displayName: Download SIGN+ package env: SIGNPLUS_USERNAME: $(SIGNPLUS_USERNAME) SIGNPLUS_PASSWORD: $(SIGNPLUS_PASSWORD) SIGNPLUS_API_HOST: $(SIGNPLUS_API_HOST) SIGNPLUS_API_PORT: $(SIGNPLUS_API_PORT) SIGNPLUS_PACKAGE_TYPE: $(SIGNPLUS_PACKAGE_TYPE) - script: | set -euo pipefail export INPUT_JAR="$(Pipeline.Workspace)/unsigned-jar/sample-java-app-1.0.0.jar" export OUTPUT_JAR="$(Pipeline.Workspace)/signed/sample-java-app-1.0.0_signed.jar" export SIGN_PLUS_WORK_DIR="$(Agent.TempDirectory)/signplus" mkdir -p "$(Pipeline.Workspace)/signed" scripts/sign-with-signplus.sh displayName: Install SIGN+, sign and verify env: SIGNPLUS_CLIENTID: $(SIGNPLUS_USERNAME) SIGNPLUS_CLIENTSECRET: $(SIGNPLUS_PASSWORD) SIGN_PLUS_ZIP: $(SIGN_PLUS_ZIP) - task: PublishPipelineArtifact@1 inputs: targetPath: $(Pipeline.Workspace)/signed/sample-java-app-1.0.0_signed.jar artifact: signed-jar publishLocation: pipeline
Step-by-step setup (Approach 2)
- Create scripts/download-signplus-api.sh using Variant A or Variant B.
- Create scripts/sign-with-signplus.sh using the content in The Signing Script.
- Copy the pipeline YAML above and update:
SIGNPLUS_API_HOSTyour AppViewX server hostname or IP.SIGNPLUS_API_PORTthe API port (typically 31443).SIGNPLUS_POLICY_NAMEyour signing policy name.
- Create Secret pipeline variables in Azure DevOps:
SIGNPLUS_USERNAMEyour AppViewX username.SIGNPLUS_PASSWORDyour AppViewX password. Mark as Secret.
- Push to trigger the pipeline.
Approach 3: Use an OAuth service account token
Use this approach when your organization authenticates with AppViewX using OAuth service accounts. The pipeline first retrieves a short-lived access token from AppViewX, then uses that token to download the SIGN+ package.
Step 1 Get a bearer token
A bearer token is a temporary access credential. Call the
acctmgmt_get_service_token API with your service account credentials to
receive one:
TOKEN_RESPONSE=$(curl -k --location \
"https://<your-appviewx-server>:<port>/avxapi/acctmgmt_get_service_token" \
--header "Content-Type: application/json" \
--data '{
"payload": {
"clientId": "<service-account-client-id>",
"clientSecret": "<service-account-client-secret>"
}
}')
BEARER_TOKEN=$(echo "$TOKEN_RESPONSE" | jq -r '.response.token')
Step 2 Download the SIGN+ package using the token
Pass the token in the Authorization header when calling the download
API:
HTTP_STATUS=$(curl -k --location \
"https://<your-appviewx-server>:<port>/avxapi/code-signing-download-csp-pkcs11-dll-sign?gwsource=external" \
--header "Content-Type: application/json" \
--header "Authorization: Bearer ${BEARER_TOKEN}" \
--data '{
"payload": {
"packageType": "Linux"
}
}' \
--output "${TMPFILE}" \
-w '%{http_code}')
if [[ "${HTTP_STATUS}" -eq 200 ]]; then
FILE_CONTENT=$(jq -r '.response.fileContent // empty' "${TMPFILE}")
echo "${FILE_CONTENT}" | base64 -d > "${OUTPUT_FILE}"
unzip -t "${OUTPUT_FILE}" >/dev/null
echo "[INFO] Package downloaded and verified."
fi
After you download the package, run the signing script described in The Signing Script.
Understanding the JSON configuration file
When SIGN+ installs, it generates a file named README_<PolicyName>.json in the installation directory. This file contains all the signing and verification commands for your policy pre-configured and ready to run.
Each command contains placeholder tokens that the signing script replaces at runtime:
| Placeholder | Replaced with |
|---|---|
<input_file_path> |
Path to the unsigned artifact. |
<output_file_path> |
Destination path for the signed artifact. |
<signed_file_path> |
Path to the signed artifact (used in verification commands). |
Supported signing tools
| Tool | JSON path | Typical use |
|---|---|---|
| jarsigner | .pkcs11.sign.jarsigner |
Java JAR files. |
| jsign | .pkcs11.sign.jsign |
Windows PE, MSI, JAR, and other formats. |
| apksigner | .pkcs11.sign.apksigner |
Android APK files. |
| xmlsectool | .pkcs11.sign.xmlsectool |
XML documents. |
| OpenSSL (dgst) | .pkcs11.sign.openssl_dgst |
Raw file signing. |
| OpenSSL (CMS) | .pkcs11.sign.openssl_cms |
CMS / PKCS#7 detached signatures. |
| osslsigncode | .pkcs11.sign.osslsigncode |
Windows Authenticode signing from a Linux agent. |
| cosign | .pkcs11.sign.cosign |
OCI container images and blobs. |
| Maven | .pkcs11.sign.maven_pom_snippet |
Maven build integration. |
| Gradle | .pkcs11.sign.gradle_snippet |
Gradle build integration. |
Choose the right approach
| Approach | Best for | Requires |
|---|---|---|
| 1 Bundle in repository | Most teams. Fastest, most reliable, no network dependency. | Permission to commit a binary file to Git (or access to an artifact store). |
| 2 Download via API | Teams that cannot store binaries in Git. First download is cached for future runs. | Network access to the AppViewX server from the build agent. |
| 3 OAuth service token | Organizations that use OAuth service accounts for AppViewX authentication. | Network access to the AppViewX server and an OAuth service account with download permissions. |
Important notes and customization
The pipeline files, scripts, and commands in this topic are reference implementations. Review and adapt them before using them in a production environment:
- Policy name: Update
SIGNPLUS_POLICYin the signing script to match the exact policy name configured in AppViewX for your environment. - Authentication type: Select
oAuthorbasicAuthbased on how your AppViewX environment is configured. - Signing tool: The examples use jarsigner for Java JAR files. For other artifact types such as Android APK files, Windows executables, or container images, read the corresponding key from the generated JSON file and use the same placeholder substitution pattern.
- Platform: The scripts in this topic run on Linux using Bash. For Windows agents,
use PowerShell with
ConvertFrom-Jsonto read the JSON file and apply the same placeholder substitution. - TLS certificate verification: The download scripts use the
-kflag in curl to skip TLS verification. This is acceptable for internal lab environments with self-signed certificates. For production environments, replace-kwith--cacert /path/to/your/ca-bundle.crtto verify the AppViewX server certificate. - Secret management: Always mark credentials
(
SIGNPLUS_CLIENTSECRET,SIGNPLUS_PASSWORD) as Secret variables in Azure DevOps so their values are masked in pipeline logs and not accessible to other jobs.
