├── GitHub-Enterprise-App
├── Readme.md
└── prisma-cloud-github-webhook.zip
├── README.md
└── aws-codepipeline
├── PrismaCloudCompute
└── buildspec.yml
├── PrismaCloudIacScan
├── Bash
│ ├── PrismaCloudIaCAction.json
│ └── poll.sh
└── Lambda
│ └── PrismaCloudIaCScan.zip
└── README.md
/GitHub-Enterprise-App/Readme.md:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/GitHub-Enterprise-App/prisma-cloud-github-webhook.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaloAltoNetworks/Prisma-Cloud-DevOps-Security/f36756e3fc0fb2a76ffe3daf139291276e35e80c/GitHub-Enterprise-App/prisma-cloud-github-webhook.zip
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
Prisma Cloud DevOps Security
2 |
3 | The Prisma Cloud devOps security capabilities are geared to meet the common goal of delivering releases faster and preventing security lapses by applying a consistent set of checks through the build-to-release process that keep your applications and infrastructure secure.
4 |
5 | Prisma Cloud devOps security enables devOps and security teams to identify insecure configurations in Infrastructure-as-Code (IaC) templates and vulnerabilities in container images so that security issues are identified before actual resources are deployed in runtime environments.
6 | To identify potential issues you can scan the content in your templates and files in AWS CloudFormation Templates (JSON or YAML format), HashiCorp Terraform templates (HCL format), and Kubernetes App manifests (JSON or YAML format) against a list of IaC policies policies. Currently, these policies provide good coverage of AWS and GCP CIS standards.
7 |
8 | 
9 |
--------------------------------------------------------------------------------
/aws-codepipeline/PrismaCloudCompute/buildspec.yml:
--------------------------------------------------------------------------------
1 | version: 0.2
2 |
3 | # In this example, we're using environment variables
4 | # to store the username & password of our Prisma Cloud Compute CI user account
5 | # and the URL to our console
6 |
7 | # Username: The Prisma Cloud Compute user with the CI User role
8 | # Password: The password for this user account
9 | # Prisma_Cloud_Compute_Console_URL: The base URL for the console -- http://console..com:8083 -- without a trailing /
10 |
11 | phases:
12 | install:
13 | runtime-versions:
14 | docker: 18
15 | build:
16 | commands:
17 | - echo Build started on `date`
18 | - echo Building the Docker image...
19 | - docker build -t $IMAGE_NAME:$IMAGE_TAG .
20 | post_build:
21 | commands:
22 | - echo Build completed on `date`
23 | - echo Downloading twistcli
24 | - curl -k -u $Username:$Password --output ./twistcli $Prisma_Cloud_Compute_Console_URL/api/v1/util/twistcli
25 | - chmod +x ./twistcli
26 | - echo Scanning with twistcli
27 |
28 | # Run the scan with twistcli, providing detailed results in CodeBuild and
29 | # pushing the results to the Twistlock console.
30 | # --details returns all vulnerabilities & compliance issues rather than just summaries.
31 | # -address points to our Twistlock console
32 | # -u and -p provide credentials for the console. These creds only need the CI User role.
33 | # Finally, we provide the name of the image we built with 'docker build', above.
34 |
35 | - ./twistcli images scan --details -address $Prisma_Cloud_Compute_Console_URL -u $Username -p $Password $IMAGE_NAME:$IMAGE_TAG
36 |
37 | # Add --vulnerability-threshold and/or --compliance-threshold to this command to
38 | # fail builds based on the thresholds.
39 | # See twistcli documentation for more details.
40 |
41 |
--------------------------------------------------------------------------------
/aws-codepipeline/PrismaCloudIacScan/Bash/PrismaCloudIaCAction.json:
--------------------------------------------------------------------------------
1 | {
2 | "category": "Test",
3 | "provider": "Prisma-Cloud-IaC-Scan",
4 | "version": "1",
5 | "settings": {
6 | "entityUrlTemplate": "https://s3.console.aws.amazon.com/s3/buckets/{Config:S3BucketName}/?region={Config:S3BucketRegion}&tab=overview",
7 | "executionUrlTemplate": "https://s3.console.aws.amazon.com/s3/buckets/{Config:S3BucketName}/?region={Config:S3BucketRegion}&tab=overview"
8 | },
9 |
10 | "configurationProperties": [
11 | {
12 | "name": "S3BucketName",
13 | "required": true,
14 | "key": true,
15 | "secret": false,
16 | "queryable": false,
17 | "description": "The S3 bucket name.",
18 | "type": "String"
19 | },
20 | {
21 | "name": "S3BucketRegion",
22 | "required": true,
23 | "key": true,
24 | "secret": false,
25 | "queryable": false,
26 | "description": "The region where the S3 bucket specified",
27 | "type": "String"
28 | },
29 | {
30 | "name": "Prisma_Cloud_API_URL",
31 | "required": true,
32 | "key": true,
33 | "secret": false,
34 | "queryable": false,
35 | "description": "Prisma Cloud server URL",
36 | "type": "String"
37 |
38 | },
39 | {
40 | "name": "Access_Key",
41 | "required": true,
42 | "key": true,
43 | "secret": false,
44 | "queryable": false,
45 | "description": "Prisma Cloud access key",
46 | "type": "String"
47 |
48 | },
49 | {
50 | "name": "Secret_Key",
51 | "required": true,
52 | "key": true,
53 | "secret": true,
54 | "queryable": false,
55 | "description": "Prisma Cloud secret key",
56 | "type": "String"
57 |
58 | },
59 | {
60 | "name": "Failure_Criteria_High_Severity",
61 | "required": true,
62 | "key": true,
63 | "secret": false,
64 | "queryable": false,
65 | "description": "Provide failure threshold for high severity security issues",
66 | "type": "Number"
67 | },
68 | {
69 | "name": "Failure_Criteria_Medium_Severity",
70 | "required": true,
71 | "key": true,
72 | "secret": false,
73 | "queryable": false,
74 | "description": "Provide failure threshold for medium severity security issues.",
75 | "type": "Number"
76 | },
77 | {
78 | "name": "Failure_Criteria_Low_Severity",
79 | "required": true,
80 | "key": true,
81 | "secret": false,
82 | "queryable": false,
83 | "description": "Provide failure threshold for low severity security issues.",
84 | "type": "Number"
85 | },
86 | {
87 | "name": "Failure_Criteria_Operator",
88 | "required": true,
89 | "key": true,
90 | "secret": false,
91 | "queryable": false,
92 | "description": "Provide operator for high, medium, low severity failure thresholds.",
93 | "type": "String"
94 | }
95 | ],
96 | "inputArtifactDetails": {
97 | "maximumCount": 1,
98 | "minimumCount": 0
99 | },
100 | "outputArtifactDetails": {
101 | "maximumCount": 1,
102 | "minimumCount": 0
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/aws-codepipeline/PrismaCloudIacScan/Bash/poll.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -u
4 | set -e
5 | trap "echo ERR; exit" ERR
6 |
7 | # exec &> >(while read line; do echo "$(date +'%h %d %H:%M:%S') $line" >> cmds.log; done;)
8 |
9 | #set -x
10 |
11 | if [[ -z "${1:-}" ]]; then
12 | echo "Usage: ./poll.sh " >&2
13 | echo -e "Example:\n ./poll.sh \"category=Test,owner=Custom,version=1,provider=Prisma-Cloud-IaC-Scan\"" >&2
14 | exit 1
15 | fi
16 |
17 | echo_ts() {
18 |
19 | echo -e "\n" >> Prisma_Cloud_IaC_Scan.log
20 | echo "$1" >> Prisma_Cloud_IaC_Scan.log
21 |
22 | }
23 |
24 | run() {
25 |
26 | local action_type_id="$1"
27 | echo_ts "actiontypeid: $action_type_id"
28 |
29 | #while :
30 | #do
31 | local job_json="$(fetch_job "$action_type_id")"
32 |
33 | if [[ "$job_json" != "null" && "$job_json" != "None" && "$job_json" != "" ]]; then
34 |
35 | local job_id="$(echo "$job_json" | jq -r '.id')"
36 | echo "job_id: $job_id"
37 | mkdir $job_id
38 | chmod +x $job_id
39 | cd $job_id || update_job_status "$job_json" "job id not found"
40 |
41 | acknowledge_job "$job_json"
42 | local build_json=$(create_build "$job_json")
43 | else
44 | sleep 10
45 | fi
46 | #done
47 | }
48 | acknowledge_job() {
49 |
50 | local job_json="$1"
51 | local job_id="$(echo "$job_json" | jq -r '.id')"
52 | local nonce="$(echo "$job_json" | jq -r '.nonce')"
53 |
54 | echo_ts "Acknowledging CodePipeline job (id: $job_id nonce: $nonce)" >&2
55 |
56 | aws codepipeline acknowledge-job --job-id "$job_id" --nonce "$nonce" > /dev/null 2>&1
57 | }
58 |
59 | fetch_job() {
60 |
61 | local action_type_id="$1"
62 |
63 | aws codepipeline poll-for-jobs --max-batch-size 1 \
64 | --action-type-id "$action_type_id" \
65 | --query 'jobs[0]'
66 | }
67 |
68 | action_configuration_value() {
69 |
70 | local job_json="$1"
71 | local configuration_key="$2"
72 |
73 | echo "$job_json" | jq -r ".data.actionConfiguration.configuration | .[\"$configuration_key\"]"
74 |
75 | }
76 |
77 | update_job_status() {
78 | local job_json="$1"
79 | local build_state="$2"
80 |
81 | local job_id="$(echo "$job_json" | jq -r '.id')"
82 |
83 | echo_ts "Updating CodePipeline job with '$build_state' and job_id '$job_id'result" >&2
84 |
85 | if [[ "$build_state" == "success" ]]; then
86 | aws codepipeline put-job-success-result \
87 | --job-id "$job_id" \
88 | --execution-details "summary=Build succeeded,externalExecutionId=$job_id,percentComplete=100"
89 | else
90 | aws codepipeline put-job-failure-result \
91 | --job-id "$job_id" \
92 | --failure-details "type=JobFailed,message=Build $build_state,externalExecutionId=$job_id"
93 | fi
94 | }
95 |
96 |
97 | decide_job_status(){
98 | local job_json="$1"
99 | local stats="$2"
100 | local in_high="$(echo "$job_json" | jq -r ".data.actionConfiguration.configuration.Failure_Criteria_High_Severity")"
101 | local in_med="$(echo "$job_json" | jq -r ".data.actionConfiguration.configuration.Failure_Criteria_Medium_Severity")"
102 | local in_low="$(echo "$job_json" | jq -r ".data.actionConfiguration.configuration.Failure_Criteria_Low_Severity")"
103 | local in_oper="$(echo "$job_json" | jq -r ".data.actionConfiguration.configuration.Failure_Criteria_Operator")"
104 |
105 | local resp_high="$(echo "$stats" | jq -r '.high')"
106 | local resp_med="$(echo "$stats" | jq -r '.medium')"
107 | local resp_low="$(echo "$stats" | jq -r '.low')"
108 |
109 |
110 | if [[ $in_oper == null ]];then
111 | in_oper="or"
112 | fi
113 | if [[ $in_high == null ]];then
114 | in_high=0
115 | fi
116 | if [[ $in_med == null ]];then
117 | in_med=0
118 | fi
119 | if [[ $in_low == null ]];then
120 | in_low=0
121 | fi
122 |
123 | if [[ $stats != null ]] ;then
124 | if [[ "$in_oper" == "or" && ( "$resp_high" -ge "$in_high" || "$resp_med" -ge "$in_med" || "$resp_low" -ge "$in_low" ) ]] ;then
125 | echo_ts "Prisma Cloud IaC scan failed with issues as security issues count (High: $resp_high, Medium: $resp_med, Low: $resp_low) meets or exceeds failure criteria (High: $in_high, Medium: $in_med, Low: $in_low)"
126 | update_job_status "$job_json" "failure"
127 |
128 | elif [[ "$in_oper" == "and" && ( "$resp_high" -ge "$in_high" && "$resp_med" -ge "$in_med" && "$resp_low" -ge "$in_low" ) ]]; then
129 | echo_ts "Prisma Cloud IaC scan failed with issues as security issues count (High: $resp_high, Medium: $resp_med, Low: $resp_low) meets or exceeds failure criteria (High: $in_high, Medium: $in_med, Low: $in_low)"
130 | update_job_status "$job_json" "failure"
131 |
132 | else
133 | echo_ts "Prisma Cloud IaC scan succeeded with issues as security issues count (High: $resp_high, Medium: $resp_med, Low: $resp_low) does not exceed failure criteria (High: $in_high, Medium: $in_med, Low: $in_low)"
134 | update_job_status "$job_json" "success"
135 | fi
136 |
137 | else
138 | update_job_status "$job_json" "success"
139 | fi
140 |
141 | }
142 |
143 | create_build() {
144 |
145 | local job_json="$1"
146 | local job_id="$(echo "$job_json" | jq -r '.id')"
147 | local s3_bucket=$(action_configuration_value "$job_json" "S3BucketName")
148 | local bucketName="$(echo "$job_json" | jq -r ".data.inputArtifacts[0].location.s3Location | .[\"bucketName\"]")"
149 | local object_key="$(echo "$job_json" | jq -r ".data.inputArtifacts[0].location.s3Location | .[\"objectKey\"]")"
150 | local output_object="$(echo "$job_json" | jq -r ".data.outputArtifacts[0].location.s3Location | .[\"objectKey\"]")"
151 |
152 | local console_url="$(echo "$job_json" | jq -r ".data.actionConfiguration.configuration.Prisma_Cloud_API_URL")"
153 | local access_key="$(echo "$job_json" | jq -r ".data.actionConfiguration.configuration.Access_Key")"
154 | local secret_key="$(echo "$job_json" | jq -r ".data.actionConfiguration.configuration.Secret_Key")"
155 |
156 |
157 | if [ -z "$console_url" ]; then
158 | echo_ts "Please enter valid Prisma Cloud API URL in plugin in Input param. For details refer to :plugin link"
159 | update_job_status "$job_json" "Please enter valid Prisma Cloud API URL in plugin in Input param. For details refer to plugin link"
160 | exit 1;
161 | fi
162 |
163 | local login_url="${console_url}/login"
164 |
165 | local req_cmd=$(curl -k -i -o -X POST $login_url -H "Content-Type:application/json" -d "{\"username\":\"${access_key}\",\"password\":\"${secret_key}\"}" ) || update_job_status "$job_json" "$err_500"
166 |
167 | local err_400="Invalid credentials please verify that API URL, Access Key and Secret Key in Prisma Cloud plugin settings are valid For details refer to Extension link https://docs.paloaltonetworks.com/prisma/prisma-cloud/prisma-cloud-admin/prisma-cloud-devops-security/use-the-prisma-cloud-extension-for-aws-codepipeline.html"
168 | local err_500="Oops! Something went wrong, please try again or refer to documentation on https://docs.paloaltonetworks.com/prisma/prisma-cloud/prisma-cloud-admin/prisma-cloud-devops-security/use-the-prisma-cloud-extension-for-aws-codepipeline.html"
169 |
170 | http_status=$(echo "$req_cmd" | grep HTTP | awk '{print $2}')
171 |
172 | if [ -z "$http_status" ]; then
173 | echo_ts '$err_500' >&2
174 | update_job_status "$job_json" "error"
175 | exit 1;
176 | fi
177 |
178 | if [[ "$http_status" == 400 || "$http_status" == 401 ]] ; then
179 | echo_ts '$err_400' >&2
180 | update_job_status "$job_json" "error"
181 | exit 1
182 |
183 | fi
184 |
185 | if [[ $http_status -ge 500 ]] ; then
186 | echo_ts '$err_500' >&2
187 | update_job_status "$job_json" "error"
188 | exit 1
189 | fi
190 |
191 | output_response=$(echo "$req_cmd" | grep token)
192 |
193 | local token="$(echo "$output_response" | jq .token | tr -d '"')"
194 |
195 |
196 | local scan_location="$(echo $bucketName/$object_key)"
197 |
198 | aws s3 cp s3://$scan_location . || update_job_status "$job_json" "Copy Object from S3 bucket failed"
199 |
200 |
201 | local file=( *.zip )
202 |
203 | mv $file artifact.zip
204 |
205 | iacAPI=${console_url}/iac_scan
206 |
207 | while :
208 | do
209 |
210 | local response="$(curl -k -X POST $iacAPI -H "x-redlock-auth:${token}" -F templateFile=@artifact.zip)" || update_job_status "$job_json" "Call from API failed"
211 |
212 | local result="$(echo "$response" | jq -r '.result.is_successful')"
213 |
214 | if [[ $result ]]
215 | then
216 | local matched="$(echo "$response" | jq -r '.result.rules_matched')"
217 |
218 | if [[ $matched != null ]] ;then
219 |
220 | local stats="$(echo "$response" | jq -r '.result.severity_stats')"
221 |
222 | display="$(echo "$matched" | jq -r 'sort_by(.severity) | (["SEVERITY" ,"NAME" ,"FILES"] | (., map(length*"-")) ), (.[] | [.severity , .name, .files[0] ]) | join(",")' | column -t -s ",")" || update_job_status "$job_json" "Unknown Error "
223 |
224 | else
225 | echo_ts "Good job! Prisma Cloud did not detect any issues."
226 |
227 | fi
228 | fi
229 |
230 | if [[ "$result" != "null" ]]; then
231 |
232 | if [[ $result == "true" ]] ;then
233 | decide_job_status "$job_json" "$stats"
234 |
235 | fi
236 | break
237 | else
238 | echo_ts "Build is running"
239 | sleep 3
240 | fi
241 | done
242 |
243 | echo_ts "$display" >&2
244 |
245 | aws s3 cp Prisma_Cloud_IaC_Scan.log s3://$s3_bucket/Prisma_Cloud_IaC_Scan_$job_id.log || update_job_status "$job_json" "upload results to S3 bucket failed"
246 |
247 | cd ..
248 | rm -fr $job_id
249 |
250 | }
251 |
252 | run "$1"
253 |
--------------------------------------------------------------------------------
/aws-codepipeline/PrismaCloudIacScan/Lambda/PrismaCloudIaCScan.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaloAltoNetworks/Prisma-Cloud-DevOps-Security/f36756e3fc0fb2a76ffe3daf139291276e35e80c/aws-codepipeline/PrismaCloudIacScan/Lambda/PrismaCloudIaCScan.zip
--------------------------------------------------------------------------------
/aws-codepipeline/README.md:
--------------------------------------------------------------------------------
1 | Overview
2 |
3 |
4 | This extension enables Prisma Cloud Infrastructure-as-Code (IaC) scan and container image / serverless zip scan functionality from Palo Alto Networks Inc. in AWS Code Pipelines. Prisma Cloud IaC Scan identifies insecure configurations in common Infrastructure-as-Code (IaC) templates - for example, AWS Cloud Formation Templates, HashiCorp Terraform templates, Kubernetes App Deployment YAML files. More details about the functionality can be found here: https://docs.paloaltonetworks.com/prisma/prisma-cloud/prisma-cloud-admin/prisma-cloud-devops-security.html
5 |
6 |
7 | Prisma Cloud IaC Scan
8 |
9 | User can us this feature in 2 ways :
10 | 1. Using AWS Lambda
11 | OR
12 | 2. Creating Custom action to run poll jobs (bash script) either in local enviornment or EC2 instance with AWS account.
13 |
14 | More Details on how to use it can be found in the documentation link:
15 | https://docs.paloaltonetworks.com/prisma/prisma-cloud/prisma-cloud-admin/prisma-cloud-devops-security/use-the-prisma-cloud-extension-for-aws-codepipeline.html
16 |
17 |
18 | Prisma Cloud Compute Image Scanning
19 | /buildspec.yml includes details on how to use twistcli when using AWS CodeBuild
20 |
--------------------------------------------------------------------------------