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 ishttps://app.prismacloud.io, then your Prisma Cloud API base URL ishttps://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 theContent-Typefor 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.
- 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.MethodEndpoint URLPOSThttps://<Prisma Cloud API base URL>/iac/v2/scansThe 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 requireddata.typevalue must currently beasync-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 theassetTypetoGitHub. 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 isowner: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 useandororoperators 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 thefailureCriteriavalues. 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”: 1and”operator”: “or”. With thisfailureCriteriasetting, if the scan finds any type of issue, the job will fail. An example offailureCriteriathat 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, thedata.idvalue is a scan id that you will use in subsequent requests to manage your scan job. Thedata.urlvalue 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" } } } - 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 keydata.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.
- 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.MethodEndpoint URLPOSThttps://<Prisma Cloud API base URL>/iac/v2/scans/{scanID}The path parameterscanIDis 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" } } }'Thedata.idin the request body parameter is the same as the path parameterscanIDand 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 ReferenceA successful request will return an HTTP code of 200. - Query your job status.The following API enables you to query the status of your asynchronous IaC scan job.MethodEndpoint URLGEThttps://<Prisma Cloud API base URL>/iac/v2/{scanID}/statusThescanIDpath 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" } } }
- Request IaC scan results.The following API enables you to request your IaC scan results after the scan job is done.MethodEndpoint URLGEThttps://<Prisma Cloud API base URL>/iac/v2/scans/{scanID}/resultsThescanIDpath 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 ofterraform-012-parametersis as follows.KeyValueroot-moduleTerraform 0.12 root moduleThe 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 ofterraform-012-parametersto 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 ofterraform-012-parametersis an array of key/value pairs where the key/value pairs can be one or more of the following.KeyValueroot-moduleTerraform 0.12 root modulevariable-filesAn array of custom variable file names. The path of each file is relative to your root module.variablesAn 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 isx-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
Recommended Videos
Recommended videos not found.