Use the Prisma Cloud IaC Scan REST API

Use the Prisma Cloud REST API directly to scan IaC templates and test them against Prisma Cloud security policies.
Prisma Cloud makes the IaC scanning functionality available as a SaaS solution through a REST API. The Prisma Cloud IaC scan service supports Terraform templates, Terraform plan files in JSON format, CloudFormation templates, and Kubernetes app manifests. While you should take advantage of the IaC scan plugins that are available, you have the option to use the IaC scan API directly.
The Prisma Cloud IaC scan service API version 2 enables you to scan templates against policies and display scan results asynchronously for a better user experience. Version 1 of the IaC Scan API is deprecated and will continue to work until January 31, 2021. Make sure to update scripts or integrations that make requests to version 1 resources as soon as possible, to prevent any disruption.

Use the IaC Scan API Version 2

With version 2 of the IaC scan API, you can initiate IaC scans asynchronously and integrate your IaC scan results with Prisma Cloud. The new asynchronous IaC scan API solves timeout issues, increases the file size limit to 300MB, and supports Terraform v0.13. Also, this new API detects Terraform module structures and variable files automatically, in most cases.
To scan your templates, you identify your scan to the Prisma Cloud IaC scan service, upload the files to be scanned, and submit a job to perform the scan. After you submit your job, you make API requests to check the status of the job and to view the results.
Before you make your first IaC Scan v2 request, you must complete the following prerequisites:
  • Know the base API URL for your Prisma Cloud tenant, which will serve as the base URL of all your IaC scan API requests.
    Your Prisma Cloud API base URL depends on the region and cluster of your Prisma Cloud tenant. For example, if your Prisma Cloud admin console URL is
    https://app.prismacloud.io
    , then your Prisma Cloud API base URL is
    https://api.prismacloud.io
    . See the Prisma Cloud REST API Reference for a list of Prisma Cloud API URLs.
  • Get the Prisma Cloud JSON web token (JWT) token for authentication.
    Your Prisma Cloud administrator normally assigns an API access key, which you can use with a Prisma Cloud login API request to obtain a JWT token. You will include the JWT token in the header of your IaC scan API requests. See Access the Prisma Cloud REST API for details.
  • Know the
    Content-Type
    for your request header, which is in the table below.
The following table shows the required request-header fields for all the IaC scan V2 API requests.
Request-Header Field
Value
x-redlock-auth
Your JWT token as described above
Content-Type
application/vnd.api+json
If you want to scan Terraform plan files, an additional prerequisite is to use the Terraform plan and Terraform show commands to convert your Terraform modules to JSON-formatted plan files.
Version 2 of the IaC scan API is JSON API compliant.
The examples below illustrate the API requests you need to run and manage an asynchronous IaC scan job in Prisma Cloud.
  1. Create an IaC scan asset in Prisma Cloud.
    The following API enables you to create an IaC scan asset. An IaC scan asset represents a collection of one or more templates whose contents have been scanned or will be scanned by the Prisma Cloud scan service to check against Prisma Cloud IaC policies.The Prisma Cloud scan service performs this scan asynchonously.
    Method
    Endpoint URL
    POST
    https://<Prisma Cloud API base URL>/iac/v2/scans
    The following is an example of a cURL request to create an IaC scan asset.
    curl -X POST 'https:/<Prisma Cloud API URL>/iac/v2/scans' \ --header 'x-redlock-auth: <JWT Token>' \ --header 'Content-Type: application/vnd.api+json' \ --data-raw ' { "data": { "type": "async-scan", "attributes": { "assetName": "my-asset", "assetType": "IaC-API", "tags": { "env": "dev" }, "scanAttributes": { "projectName": "my-project" }, "failureCriteria": { "high": 1, "medium": 10, "low": 30, "operator": "or" } } } }'
    The request body parameters both provide metadata about your scan and define failure criteria for an IaC scan job. The required
    data.type
    value must currently be
    async-scan
    . The parameters in this example includes the following attributes:
    • assetName
      : Can be a project name or any identifier you want to attach to the scan. Some examples are a CI/CD project name or a Git repository name.
    • assetType
      : Identifies where the IaC scan is being done. For the IaC scan API the standard value is IaC-API. You are allowed to use other values as well. For example, if you are requesting a scan through a GitHub action and using the IaC scan API, you can set the
      assetType
      to
      GitHub
      . See the Async Scan API in the Prisma Cloud API Reference for a list of supported asset types.
    • tags
      : Prisma Cloud tags are different from cloud tags that you might have included in your IaC templates. Prisma Cloud tags will facilitate use of upcoming Prisma Cloud features like role-based access control and policy selection. An example tag list is
      owner:johndoe, team:creditapp, env:dev
      .
    • scanAttributes
      : Can be any additional details that you want to send as key/value pairs with each scan. Some examples are Git pull request numbers or specific build numbers inside a CI/CD project.
    • failureCriteria
      : Enables you to evaluate scan results against set failure criteria to obtain failed or passed verdicts. You can set the count for high, medium, and low severity issues and use
      and
      or
      or
      operators to refine your criteria. The IaC scan API checks each severity violation number separately against scan results and applies the operator to each evaluation. The scan triggers a failure if the number of violations is greater than or equal to the
      failureCriteria
      values. For example, if you want a scan to fail when it detects any type of issue, you can set the failure criteria to
      “high”: 1
      ,
      “medium”: 1
      ,
      “low”: 1
      and
      ”operator”: “or”
      . With this
      failureCriteria
      setting, if the scan finds any type of issue, the job will fail. An example of
      failureCriteria
      that causes the IaC scan API to run checks in warning mode is
      “high”: 1000
      ,
      “medium”: 1000
      ,
      “low”: 1000
      ,
      “operator”: and
      .
    Details about all the body parameters for this request are in Async Scan API in the Prisma Cloud API Reference.
    The following example shows the response of a successful request. In this example, the
    data.id
    value is a scan id that you will use in subsequent requests to manage your scan job. The
    data.url
    value is a presigned URL you will use to upload the files you want scanned to Prisma Cloud.
    { "data": { "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "links": { "url": "https://s3.amazonaws.com/s3sign2-bucket-hchq3nwuo8ns/s3-sign-demo.json?X-Amz-Security-Token=FQ…&X-Amz-Credential=ASIAJF3BXG…&X-Amz-Date=20170125T044127Z&X-Amz-Expires=60&X-Amz-Signature=24db0" } } }
  2. Use the presigned URL from the scan asset creation to upload the templates to be scanned.
    Prisma Cloud uses a presigned URL that gives you temporary access to upload an object. In the example above, the presigned URL is the value of the key
    data.url
    . The following is an example of a cURL request to upload a file to the presigned URL.
    curl -v -X PUT '<presigned URL>' -T <path and file name of file to be uploaded>
    You can upload a single file or multiple files as a zip archive to the presigned URL.
    Some example templates and plan files are available at Prisma Cloud IaC samples on GitHub; you can use one of these files to experiment with an upload request.
  3. Start a job to perform a scan of your uploaded templates.
    The following API enables you start an asynchronous job to perform a scan of your uploaded file. The path parameter is the scan ID from the response of your earlier request to create a scan asset.
    Method
    Endpoint URL
    POST
    https://<Prisma Cloud API base URL>/iac/v2/scans/{scanID}
    The path parameter
    scanID
    is the scan ID from the response of your earlier request to create a scan asset.
    The following is an example of a cURL request to start a job that scans the file you’ve already uploaded.
    curl -X POST 'https://<Prisma Cloud API URL>/iac/v2/scans/3fa85f64-5717-4562-b3fc-2c963f66afa6' \ --header 'x-redlock-auth: <JWT Token>' \ --header 'Content-Type: application/vnd.api+json' \ --data-raw ' { "data": { "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "attributes": { "templateType": "tf" } } }'
    The
    data.id
    in the request body parameter is the same as the path parameter
    scanID
    and is optional.
    Optional request parameters are available to handle more complex scenarios, including specification of the following:
    • Runtime variables for templates.
    • Variable files if the IaC scan API cannot automatically detect the files.
    • A list of files to which the scan will be limited.
    • A list of folders to which the scan will be limited. With this specification, the IaC scan service will scan the content of the listed folders, including files and sub-folders.
    Details about the API request are in the Initiate Scan Job API in the Prisma Cloud API Reference
    A successful request will return an HTTP code of 200.
  4. Query your job status.
    The following API enables you to query the status of your asynchronous IaC scan job.
    Method
    Endpoint URL
    GET
    https://<Prisma Cloud API base URL>/iac/v2/{scanID}/status
    The
    scanID
    path parameter is the id you received in the response object from the request to create a scan asset and which you also used as a path parameter to start the scan job. The following is an example cURL request to request the job status.
    curl -X GET 'https://<Prisma Cloud API URL>/iac/v2/scans/3fa85f64-5717-4562-b3fc-2c963f66afa6/status' \ --header 'x-redlock-auth: <JWT Token>' \ --header 'Content-Type: application/vnd.api+json'
    The following example shows the response of a successful request.
    { "data": { "id": 12345678-5717-4562-b3fc-2c963f66afa6", "attributes": { "status": "processing" } } }
  5. Request IaC scan results.
    The following API enables you to request your IaC scan results after the scan job is done.
    Method
    Endpoint URL
    GET
    https://<Prisma Cloud API base URL>/iac/v2/scans/{scanID}/results
    The
    scanID
    path parameter is the id you received in the response object from the request to create a scan asset and which you also used as a path parameter to start the scan job. The following is an example cURL request to request the job status.
    curl -X GET 'https://<Prisma Cloud API URL>/iac/v2/scans/12345678-5717-4562-b3fc-2c963f66afa6/results' \ --header 'x-redlock-auth: <JWT Token>' \ --header 'Content-Type: application/vnd.api+json'
    The following example shows the response of a successful request.
    { "meta": { "matchedPoliciesSummary": { "high": 1, "medium": 0, "low": 0 }, "errorDetails": [] }, "data": [ { "id": "12345678-5717-4562-b3fc-2c963f66afa6", "attributes": { "severity": "high", "name": "AWS Security Groups allow internet traffic to SSH port (22)", "rule": "$.resource[*].aws_security_group exists and ($.resource.aws_security_group[*].ingress[?(@.protocol == 'tcp'&& @.from_port<23 && @.to_port>21 )].cidr_blocks contains 0.0.0.0/0", "desc": "This policy identifies AWS Security Groups which do allow inbound traffic on SSH port (22) from public internet", "files": [ "./main.tf" ], "policyId": "617b9138-584b-4e8e-ad15-7fbabafbed1a", "docUrl": "https://docs.paloaltonetworks.com/prisma/prisma-cloud/prisma-cloud-policy-reference/configuration-policies/configuration-policies-build-phase/amazon-web-services-configuration-policies/policy_617b9138-584b-4e8e-ad15-7fbabafbed1a.html" } } ] }

Scan API Version 1 for Terraform Files (Deprecated)

Method
Endpoint URL
POST
https://<Prisma Cloud API base URL>/iac/tf/v1/scan
This REST API request scans a Terraform file or a zip archive that contains multiple Terraform files for comparison against Prisma Cloud security policies. The body of the API request contains the file or zip archive to be scanned.The module you scan can have either Terraform 0.12 or prior version templates.The request-header fields differ, depending on the type of Terraform module you want to scan.
The IaC scan service cannot scan any files that are not valid Terraform files, either in the incorrect or invalid .tf format.

Terraform 0.12

The following table shows request-header fields required to request a scan of Terraform 0.12 modules.
Request-Header Field
Value
Notes
x-redlock-auth
Your JWT token
Required
content-type
To scan single files:
text/plain
. To scan zip archives:
multipart/form-data
Required
terraform-version
0.12
Required
terraform-012-parameters
An array of key/value pairs that describe the variables in your module. See details below.
Required
The value of
terraform-012-parameters
differs, depending on whether your Terraform 0.12 module has (1) standard variables or (2) custom variable file names and/or external variables.
  • If the Terraform module has variable files but no external variables, then the array elements that make up the value of
    terraform-012-parameters
    is as follows.
    Key
    Value
    root-module
    Terraform 0.12 root module
    The following example shows a cURL request to scan a Terraform 0.12 module that has standard variables.
    curl -X POST ’https://<Prisma Cloud API URL>/iac/tf/v1/scan' \ --header 'x-redlock-auth: <JWT token>' \ --header 'Content-Type: multipart/form-data' \ --header 'terraform-version: 0.12' \ --header 'terraform-012-parameters: [{"root-module":"/scan/rich-value-types/"},{"root-module":"/scan/rich-value-types/network/"}]' \ --form 'templateFile=@<path and file name of single Terraform file or zip archive>'
    The following example shows the response of a successful request.
    { "result": { "is_successful": true, "rules_matched": [ { "severity": "medium", "name": "AWS S3 Object Versioning is disabled", "rule": " $.resource[*].aws_s3_bucket exists and ($.resource[*].aws_s3_bucket.*[*].*.versioning[*].enabled does not exist or $.resource[*].aws_s3_bucket.*[*].*.versioning[*].enabled anyFalse)", "description":"Thispolicy identifies the S3 buckets which have Object Versioning disabled. S3 Object Versioning is an important capability in protecting your data within a bucket. Once you enable Object Versioning, you cannot remove it; you can suspend Object Versioning at any time on a bucket if you do not wish for it to persist. It is recommended to enable Object Versioning on S3.", "files": [ "/scan/for-expressions" ], "id": "89ea62c1-3845-4134-b337-cc82203b8ff9" } ], "severity_stats": { "high": 0, "low": 0, "medium": 1 } }, "response_id": "bb3ba05a-2e31-4fc3-9a8e-91b31f673500" }
  • You can set the value of
    terraform-012-parameters
    to enable a scan of Terraform variable files with custom names or Terraform external variables. If your Terraform module has either of these variable uses, then the value of
    terraform-012-parameters
    is an array of key/value pairs where the key/value pairs can be one or more of the following.
    Key
    Value
    root-module
    Terraform 0.12 root module
    variable-files
    An array of custom variable file names. The path of each file is relative to your root module.
    variables
    An array of key/value pairs. Each array element has a name and value that together identify an input variable (e.g. [{“name”:”varName1”,”value”:”varValue1},{“name”:”varName2”,”value”:”varValue2”}]
    The following example shows a cURL request to scan a Terraform 0.12 zip archive that has custom variable file names.
    curl -X POST 'https://<Prisma Cloud API URL>/iac/tf/v1/scan' \ --header 'x-redlock-auth: <JWT token>' \ --header 'Content-Type: multipart/form-data' \ --header 'terraform-version: 0.12' \ --header 'terraform-012-parameters: [{"root-module":"/scan/rich-value-types/"},{"root-module":"/scan/rich-value-types/network/","variable-files":["/scan/rich-value-types/network/variables.tf"]},{"root-module":"/scan/for-expressions/"}]' \ --form 'templateFile=@<absolute file path of template or zip>'
    The following example shows a cURL request to scan a Terraform 0.12 zip archive that has external variables.
    curl -X POST 'https://<Prisma Cloud API URL>/iac/tf/v1/scan' \ --header 'x-redlock-auth: <JWT token>' \ --header 'Content-Type: multipart/form-data' \ --header 'terraform-version: 0.12' \ --header 'terraform-012-parameters: [{"root-module":"/", "variables": [ {"name": "region", "value": "us-west-1" }, { "name" : "bucket", "value": "testbucket"}] } ]' \ --form 'templateFile=@<absolute file path of template or zip>'
  • The following example shows a cURL request to scan a Terraform 0.12 plan file that is in JSON format.
    curl --location --request POST 'https://api.prismacloud.io/iac/tf/v1/scan' \ --header 'x-redlock-auth: <JWT token>' \ --form 'templateFile=@<absolute file path of plan JSON file>'
    Note that, as the request above shows, the only required header is
    x-redlock-auth
    . The following is an example of successful response to this request.
    { "result": { "is_successful": true, "rules_matched": [ { "severity": "medium", "name": "AWS S3 Object Versioning is disabled", "rule": " $.resource[*].aws_s3_bucket exists and ($.resource[*].aws_s3_bucket.*[*].*.versioning[*].enabled does not exist or $.resource[*].aws_s3_bucket.*[*].*.versioning[*].enabled anyFalse)", "description": "This policy identifies the S3 buckets which have Object Versioning disabled. S3 Object Versioning is an important capability in protecting your data within a bucket. Once you enable Object Versioning, you cannot remove it; you can suspend Object Versioning at any time on a bucket if you do not wish for it to persist. It is recommended to enable Object Versioning on S3.", "id":"89ea62c1-3845-4134-b337-cc82203b8ff9" } ], "severity_stats": { "high": 0, "low": 0, "medium": 1 } }, "response_id": "35760530-70d3-4652-b4d2-2a06a9eb776e" }

Terraform 0.11

The following table shows request-header fields required to request a scan of Terraform 0.11 modules that have only standard variables.
Request-header Field
Value
Notes
x-redlock-auth
Your JWT token
Required
content-type
To scan single files:
text/plain
. To scan zip archives:
multipart/form-data
Required
The following is an example of a cURL request to scan a Terraform 0.11 module that has only standard variable file names.
curl -X POST 'https://<Prisma Cloud API URL>/iac/tf/v1/scan' \ --header 'x-redlock-auth: <JWT token>' \ --header 'Content-Type: multipart/form-data' \ --form 'templateFile=@<absolute file path of template or zip>'
The following table shows request-header fields required to request a scan of Terraform 0.11 modules that have custom variable file names or external variables.
Request-header Field
Value
Notes
x-redlock-auth
Your JWT token
Required
content-type
To scan single files:
text/plain
. To scan zip archives:
multipart/form-data
Required
rl-parameters
An array of key/value pairs. Each array element has a name and value that together identify an input variable (e.g. [{“name”:”varName1”,”value”:”varValue1}, {“name”:”varName2”,”value”:”varValue2”}])
Required for input variables
rl-variable-file-names
An array of variable file names. The path of each file is relative to your repository branch root directory
Required for variable files
The following is an example of a cURL request to scan a Terraform 0.11 module that has custom file names and external variables.
curl -X POST 'https://<Prisma Cloud API URL>/iac/tf/v1/scan' \ --header 'x-redlock-auth: <JWT token>' \ --header 'Content-Type: multipart/form-data' \ --header ‘rl-parameters: “[{"name":"varName1","value":"varValue1"},{"name":"varName2","value":"varValue2"}]”’ \ --header 'rl-variable-file-names: ["vars.tf.json", "file1.tf"]' \ --form 'templateFile=@<absolute file path of template or zip>'
The following is an example of a successful response to the request above.
{ "result": { "is_successful": true, "rules_matched": [ { "severity": "high", "name": "AWS Security Groups allow internet traffic to SSH port (22)", "rule": "$.resource[*].aws_security_group exists and ($.resource[*].aws_security_group[*].*[*].ingress[?( @.protocol == 'tcp'&& @.from_port<23 && @.to_port>21 )].cidr_blocks[*] contains 0.0.0.0/0 or $.resource[*].aws_security_group[*].*[*].ingress[?( @.protocol == 'tcp' && @.from_port<23 && @.to_port>21 )].ipv6_cidr_blocks[*] contains ::/0)", "description": "This policy identifies AWS Security Groups which do allow inbound traffic on SSH port (22) from public internet. Doing so, may allow a bad actor to brute force their way into the system and potentially get access to the entire network.", "files": [ "demo/securitygroup22.tf" ], "id": "617b9138-584b-4e8e-ad15-7fbabafbed1a" }, "severity_stats": { "high": 0, "low": 0, "medium": 1 } }, "response_id": "bb3ba05a-2e31-4fc3-9a8e-91b31f673500" }

Scan API Version 1 for AWS CloudFormation Templates (Deprecated)

Method
Endpoint URL
POST
https://<Prisma Cloud API base URL>/iac/cft/v1/scan
This REST API request scans AWS CloudFormation template files for comparison against Prisma Cloud security policies. Support exists for both JSON and YAML formats. Prisma Cloud IaC API also supports parameters for CloudFormation templates. You can also scan either a single template or a zip archive of template files with a single API request. Note that scan support does not currently exist for nested references, macros, or intrinsic functions in CloudFormation templates.
The following table shows the request-header fields. The body of the API request contains the file or zip archive to be scanned.
Request-header Field
Value
Notes
x-redlock-auth
Your JWT token
Required
content-type
To scan single files:
text/plain
. To scan zip archives:
multipart/form-data
Required
rl-parameters
An array of key/value pairs. Each array element has a name and value that together identify a parameter (e.g. [{“name”:”varName1”,”value”:”varValue1}, {“name”:”varName2”,”value”:”varValue2”}])
Required for parameters
The following example shows a cURL request to scan an AWS CloudFormation template with external variables.
curl-X POST ’https://<Prisma Cloud API URL>/iac/cft/v1/scan' \ --header 'x-redlock-auth: <JWT token>' \ --header 'Content-Type: multipart/form-data' \ --header ‘rl-parameters: “[{"name":"varName1","value":"varValue1"},{"name":"varName2","value":"varValue2"}]”’ \ --form 'templateFile=@<absolute file path of template or zip>'
The following is an example of a successful response to this request.
{ "result": { "is_successful": true, "rules_matched": [ { "severity": "high", "name": "AWS Security Groups allow internet traffic to SSH port (22)", "rule": "$.resource[*].aws_security_group exists and ($.resource[*].aws_security_group[*].*[*].ingress[?( @.protocol == 'tcp'&& @.from_port<23 && @.to_port>21 )].cidr_blocks[*] contains 0.0.0.0/0 or $.resource[*].aws_security_group[*].*[*].ingress[?( @.protocol == 'tcp' && @.from_port<23 && @.to_port>21 )].ipv6_cidr_blocks[*] contains ::/0)", "description": "This policy identifies AWS Security Groups which do allow inbound traffic on SSH port (22) from public internet. Doing so, may allow a bad actor to brute force their way into the system and potentially get access to the entire network.", "files": [ "cftdemo/cft_sg.json" ], "id": "617b9138-584b-4e8e-ad15-7fbabafbed1a" }, "severity_stats": { "high": 0, "low": 0, "medium": 1 } }, "response_id": "bb3ba05a-2e31-4fc3-9a8e-91b31f673500" }

Scan API Version 1 for Kubernetes Templates (Deprecated)

Method
Endpoint URL
POST
https://<Prisma Cloud API base URL>/iac/k8s/v1/scan
This REST API request scans Kubernetes manifests to compare against Prisma Cloud security policies, including manifests that you generate from Helm charts. You can scan either a single manifest or a zip archive of manifest files with a single API request.
The following table shows the request-header fields. The body of the API request contains the file or zip archive to be scanned.
Request-header Field
Value
Notes
x-redlock-auth
Your JWT token
Required
content-type
To scan single files:
text/plain
. To scan zip archives:
multipart/form-data
Required
The following example shows a cURL request to scan a single Kubernetes manifest file.
curl --location --request POST 'https://<Prisma Cloud API URL>/iac/k8s/v1/scan' \ --header 'x-redlock-auth: <JWT token>' \ --header 'Content-Type: multipart/form-data' \ --form 'templateFile=@<absolute file path of template or zip>'
The following is an example of a successful response object.
{ "result": { "is_successful": true, "rules_matched": [ { "severity": "high", "name": "All capabilities should be dropped", "rule": "$.spec.template.spec.containers[*].securityContext.capabilities.drop exists and not $.spec.templates.spec.containers[*].securityContext.capabilities.drop[*] contains ALL", "description": "Ensure that all capabilities are dropped.", "id": "4682a6f1-2a1b-4f5a-938c-cdd3fa421a63" }, { "severity": "medium", "name": "Do not run containers with dangerous capabilities", "rule": "$.spec.template.spec.containers[*].securityContext.capabilities exists and $.spec.template.spec.containers[*].securityContext.capabilities.add[*] is member of (FSETID, SETUID, SETGID,SYS_CHROOT,SYS_PTRACE,CHOWN,NET_RAW,NET_ADMIN,SYS_ADMIN,NET_BIND_SERVICE)", "description": "Ensure not running containers with dangerous capabilities.", "id": "135420a6-3206-4c29-b944-846f65cea43e" } ], "severity_stats": { "high": 1, "low": 0, "medium": 1 } }, "response_id": "ddd6d597-e560-4e67-abd1-4bc2cedee062" }

Recommended For You