Fortinet white logo
Fortinet white logo

Administration Guide

Azure DevOps

Azure DevOps

FortiCNAPP Code Security integration for Azure DevOps runs SCA and IaC scanning on your repositories, posting comparison results as Pull Request (PR) comments.

When code is pushed to a branch, the scanner runs SCA and IaC analysis and uploads results to the Lacework platform. When a PR is created or updated, the scanner:

  1. Scans the source branch (new code).

  2. Checks out and scans the target branch (existing code).

  3. Compares results to identify newly introduced issues.

  4. Posts (or updates) a PR comment thread with the findings.

The PR comment thread is updated in-place on subsequent pushes; no duplicate comments are created. See Pull request commenting.

Obtaining secret values

To integrate with Azure DevOps, you must first collect the values for LW_ACCOUNT, LW_API_KEY and LW_API_SECRET.

To collect the environment secrets:
  1. Log in to the console.

  2. Click Settings > API keys.

  3. Select or create an API key.

  4. Click the download icon.

  5. Open the downloaded .json file to view your API Key and Secret.

Adding variables to Azure DevOps

Once you have obtained the values for LW_ACCOUNT, LW_API_KEY and LW_API_SECRET, you must add and set up the environment to allow the scanning step to access them.

To add the variables in Azure DevOps:
  1. Go to Pipelines > Library in your Azure DevOps project

  2. Click + Variable group and enter a descriptive name, such as forticnapp-credentials.

  3. Add the LW_ACCOUNT, LW_API_KEY and LW_API_SECRET variables.

Adding the pipeline YAML file to your repository

To integrate the FortiCNAPP with an Azure DevOps repository, you need to edit the azure-pipelines.yml file that is located in the root of your repository. The file should contain the following:

trigger:
  - main

pr:
  - main

variables:
  - group: forticnapp-credentials

pool:
  vmImage: 'ubuntu-latest'

steps:
  - checkout: self
    fetchDepth: 0

  - script: |
      docker run \
        -v $(Build.SourcesDirectory):/app/src \
        -e WORKSPACE=src \
        -e LW_ACCOUNT="$(LW_ACCOUNT)" \
        -e LW_API_KEY="$(LW_API_KEY)" \
        -e LW_API_SECRET="$(LW_API_SECRET)" \
        -e TF_BUILD \
        -e BUILD_REASON \
        -e BUILD_SOURCEBRANCHNAME \
        -e BUILD_SOURCEBRANCH \
        -e BUILD_REPOSITORY_ID \
        -e BUILD_REPOSITORY_NAME \
        -e BUILD_BUILDID \
        -e BUILD_BUILDNUMBER \
        -e BUILD_DEFINITIONNAME \
        -e SYSTEM_COLLECTIONURI \
        -e SYSTEM_TEAMFOUNDATIONCOLLECTIONURI \
        -e SYSTEM_TEAMPROJECT \
        -e SYSTEM_DEFINITIONID \
        -e SYSTEM_PULLREQUEST_SOURCEBRANCH \
        -e SYSTEM_PULLREQUEST_TARGETBRANCH \
        -e SYSTEM_PULLREQUEST_PULLREQUESTID \
        -e SYSTEM_ACCESSTOKEN \
        lacework/code-security-azure:latest
    displayName: 'FortiCNAPP Code Security Scan'
    env:
      LW_API_KEY: $(LW_API_KEY)
      LW_API_SECRET: $(LW_API_SECRET)
      SYSTEM_ACCESSTOKEN: $(System.AccessToken)
  • fetchDepth: 0 is required so the scanner can fetch and check out the target branch during PR comparison scans.

  • Secret variables (LW_API_KEY, LW_API_SECRET, SYSTEM_ACCESSTOKEN) must be explicitly mapped in the env: block. Azure DevOps does not automatically pass secrets to scripts.

Creating the pipeline

Once the pipeline is configured in Azure DevOps, it will trigger automatically on pushes and PRs.

To create the pipeline:
  1. Go to Pipelines.

  2. Click New pipeline.

  3. Select Azure Repos Git and pick your repository.

  4. Choose Existing Azure Pipelines YAML file and select /azure-pipelines.yml.

  5. Click Save.

  6. Click Run.

Granting PR comment permissions

For the integration to post PR comments, the build service account needs write access to pull requests. Without this permission, scanning will work but PR comments will fail with a TF401027 error.

To grant permissions:
  1. Go to Project Settings > Repos > Repositories.

  2. Select your repository.

  3. Click the Security tab.

  4. Find the build service account; it will be named in the format of <Project Name> Build Service (<Org Name>).

  5. Set Contribute to pull requests to Allow.

Configuring PR build validation

Azure DevOps YAML pr: triggers may not fire in all configurations. For reliable PR scanning, set up a branch policy. This ensures the scan runs automatically whenever a PR targets that branch.

To configure PR build validation:
  1. Go to Repos > Branches.

  2. Click the ... menu on your target branch (such as main) and select Branch policies.

  3. Under Build Validation, click + Add build policy.

  4. Select your pipeline, leave the defaults, and save.

Troubleshooting

Review the following table for common troubleshooting scenarios:

Symptom Cause Fix
TF401027: You need the Git 'PullRequestContribute' permission Build service lacks PR write access. See Granting PR comment permissions.
PR scan doesn't trigger automatically YAML PR triggers are not active or the branch policy missing. See Configuring PR build validation.
fatal: could not read Passworderrors in scan logs Scanner tries git remote show origin inside the container. Tthis is expected and non-fatal. No action needed; the scanner continues successfully.
ERROR unknown command "sca" for "lacework" Container running with wrong HOME directory. Ensure you're using lacework/code-security-azure:latest, not the base lacework/codesec image directly.
Scan exits with code 160 Violations were found that exceed the severity threshold. This is expected behavior; the scan completed successfully and found issues.

Azure DevOps

Azure DevOps

FortiCNAPP Code Security integration for Azure DevOps runs SCA and IaC scanning on your repositories, posting comparison results as Pull Request (PR) comments.

When code is pushed to a branch, the scanner runs SCA and IaC analysis and uploads results to the Lacework platform. When a PR is created or updated, the scanner:

  1. Scans the source branch (new code).

  2. Checks out and scans the target branch (existing code).

  3. Compares results to identify newly introduced issues.

  4. Posts (or updates) a PR comment thread with the findings.

The PR comment thread is updated in-place on subsequent pushes; no duplicate comments are created. See Pull request commenting.

Obtaining secret values

To integrate with Azure DevOps, you must first collect the values for LW_ACCOUNT, LW_API_KEY and LW_API_SECRET.

To collect the environment secrets:
  1. Log in to the console.

  2. Click Settings > API keys.

  3. Select or create an API key.

  4. Click the download icon.

  5. Open the downloaded .json file to view your API Key and Secret.

Adding variables to Azure DevOps

Once you have obtained the values for LW_ACCOUNT, LW_API_KEY and LW_API_SECRET, you must add and set up the environment to allow the scanning step to access them.

To add the variables in Azure DevOps:
  1. Go to Pipelines > Library in your Azure DevOps project

  2. Click + Variable group and enter a descriptive name, such as forticnapp-credentials.

  3. Add the LW_ACCOUNT, LW_API_KEY and LW_API_SECRET variables.

Adding the pipeline YAML file to your repository

To integrate the FortiCNAPP with an Azure DevOps repository, you need to edit the azure-pipelines.yml file that is located in the root of your repository. The file should contain the following:

trigger:
  - main

pr:
  - main

variables:
  - group: forticnapp-credentials

pool:
  vmImage: 'ubuntu-latest'

steps:
  - checkout: self
    fetchDepth: 0

  - script: |
      docker run \
        -v $(Build.SourcesDirectory):/app/src \
        -e WORKSPACE=src \
        -e LW_ACCOUNT="$(LW_ACCOUNT)" \
        -e LW_API_KEY="$(LW_API_KEY)" \
        -e LW_API_SECRET="$(LW_API_SECRET)" \
        -e TF_BUILD \
        -e BUILD_REASON \
        -e BUILD_SOURCEBRANCHNAME \
        -e BUILD_SOURCEBRANCH \
        -e BUILD_REPOSITORY_ID \
        -e BUILD_REPOSITORY_NAME \
        -e BUILD_BUILDID \
        -e BUILD_BUILDNUMBER \
        -e BUILD_DEFINITIONNAME \
        -e SYSTEM_COLLECTIONURI \
        -e SYSTEM_TEAMFOUNDATIONCOLLECTIONURI \
        -e SYSTEM_TEAMPROJECT \
        -e SYSTEM_DEFINITIONID \
        -e SYSTEM_PULLREQUEST_SOURCEBRANCH \
        -e SYSTEM_PULLREQUEST_TARGETBRANCH \
        -e SYSTEM_PULLREQUEST_PULLREQUESTID \
        -e SYSTEM_ACCESSTOKEN \
        lacework/code-security-azure:latest
    displayName: 'FortiCNAPP Code Security Scan'
    env:
      LW_API_KEY: $(LW_API_KEY)
      LW_API_SECRET: $(LW_API_SECRET)
      SYSTEM_ACCESSTOKEN: $(System.AccessToken)
  • fetchDepth: 0 is required so the scanner can fetch and check out the target branch during PR comparison scans.

  • Secret variables (LW_API_KEY, LW_API_SECRET, SYSTEM_ACCESSTOKEN) must be explicitly mapped in the env: block. Azure DevOps does not automatically pass secrets to scripts.

Creating the pipeline

Once the pipeline is configured in Azure DevOps, it will trigger automatically on pushes and PRs.

To create the pipeline:
  1. Go to Pipelines.

  2. Click New pipeline.

  3. Select Azure Repos Git and pick your repository.

  4. Choose Existing Azure Pipelines YAML file and select /azure-pipelines.yml.

  5. Click Save.

  6. Click Run.

Granting PR comment permissions

For the integration to post PR comments, the build service account needs write access to pull requests. Without this permission, scanning will work but PR comments will fail with a TF401027 error.

To grant permissions:
  1. Go to Project Settings > Repos > Repositories.

  2. Select your repository.

  3. Click the Security tab.

  4. Find the build service account; it will be named in the format of <Project Name> Build Service (<Org Name>).

  5. Set Contribute to pull requests to Allow.

Configuring PR build validation

Azure DevOps YAML pr: triggers may not fire in all configurations. For reliable PR scanning, set up a branch policy. This ensures the scan runs automatically whenever a PR targets that branch.

To configure PR build validation:
  1. Go to Repos > Branches.

  2. Click the ... menu on your target branch (such as main) and select Branch policies.

  3. Under Build Validation, click + Add build policy.

  4. Select your pipeline, leave the defaults, and save.

Troubleshooting

Review the following table for common troubleshooting scenarios:

Symptom Cause Fix
TF401027: You need the Git 'PullRequestContribute' permission Build service lacks PR write access. See Granting PR comment permissions.
PR scan doesn't trigger automatically YAML PR triggers are not active or the branch policy missing. See Configuring PR build validation.
fatal: could not read Passworderrors in scan logs Scanner tries git remote show origin inside the container. Tthis is expected and non-fatal. No action needed; the scanner continues successfully.
ERROR unknown command "sca" for "lacework" Container running with wrong HOME directory. Ensure you're using lacework/code-security-azure:latest, not the base lacework/codesec image directly.
Scan exits with code 160 Violations were found that exceed the severity threshold. This is expected behavior; the scan completed successfully and found issues.