@prism-d1/cli 1.0.70 → 1.0.71
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/github-workflows/prism-eval-gate.yml +179 -59
- package/dist/assets/infra/lib/constructs/security-agent-construct.ts +124 -6
- package/dist/assets/infra/lib/metrics-pipeline-stack.ts +96 -1
- package/dist/src/commands/securityagent/setup.d.ts.map +1 -1
- package/dist/src/commands/securityagent/setup.js +79 -0
- package/dist/src/commands/securityagent/setup.js.map +1 -1
- package/package.json +1 -1
|
@@ -222,89 +222,209 @@ jobs:
|
|
|
222
222
|
\"EventBusName\":\"prism-d1-metrics\",
|
|
223
223
|
\"Detail\":$(echo "${EVAL_EVENT}" | jq -c '.' | jq -Rs '.')}]"
|
|
224
224
|
|
|
225
|
-
- name:
|
|
226
|
-
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
|
|
225
|
+
- name: AWS Continuum diff scan
|
|
227
226
|
id: security-gate
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
}
|
|
258
|
-
|
|
227
|
+
env:
|
|
228
|
+
AWS_REGION: us-west-2
|
|
229
|
+
run: |
|
|
230
|
+
# Pre-flight: verify AWS CLI has securityagent subcommand
|
|
231
|
+
if ! aws securityagent help > /dev/null 2>&1; then
|
|
232
|
+
echo "::warning::AWS CLI does not support 'securityagent' commands (upgrade to v2.35+). Skipping scan."
|
|
233
|
+
echo "findings=0" >> "$GITHUB_OUTPUT"
|
|
234
|
+
echo "skipped=true" >> "$GITHUB_OUTPUT"
|
|
235
|
+
exit 0
|
|
236
|
+
fi
|
|
237
|
+
|
|
238
|
+
echo "::group::Retrieve Continuum config from SSM"
|
|
239
|
+
AGENT_SPACE_ID=$(aws ssm get-parameter --name /prism/continuum/agent-space-id --query Parameter.Value --output text 2>/dev/null || echo "")
|
|
240
|
+
SCAN_BUCKET=$(aws ssm get-parameter --name /prism/continuum/scan-bucket --query Parameter.Value --output text 2>/dev/null || echo "")
|
|
241
|
+
SERVICE_ROLE=$(aws ssm get-parameter --name /prism/continuum/service-role-arn --query Parameter.Value --output text 2>/dev/null || echo "")
|
|
242
|
+
echo "::endgroup::"
|
|
243
|
+
|
|
244
|
+
# Skip if core infrastructure not deployed
|
|
245
|
+
if [[ -z "$AGENT_SPACE_ID" || -z "$SCAN_BUCKET" ]]; then
|
|
246
|
+
echo "⚠️ AWS Continuum not configured (agent-space-id or scan-bucket missing). Skipping security scan."
|
|
247
|
+
echo "findings=0" >> "$GITHUB_OUTPUT"
|
|
248
|
+
echo "skipped=true" >> "$GITHUB_OUTPUT"
|
|
249
|
+
exit 0
|
|
250
|
+
fi
|
|
251
|
+
|
|
252
|
+
# Fallback for service role if SSM param not yet deployed
|
|
253
|
+
if [[ -z "$SERVICE_ROLE" ]]; then
|
|
254
|
+
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
|
|
255
|
+
SERVICE_ROLE="arn:aws:iam::${ACCOUNT_ID}:role/prism-d1-security-agent-prism-d1-security"
|
|
256
|
+
echo "::notice::service-role-arn SSM param not found, using convention: ${SERVICE_ROLE}"
|
|
257
|
+
fi
|
|
258
|
+
|
|
259
|
+
# Derive repo slug for per-repo SSM key (org/repo → org-repo)
|
|
260
|
+
REPO_SLUG=$(echo "${{ github.repository }}" | tr '/' '-')
|
|
261
|
+
|
|
262
|
+
echo "::group::Resolve or bootstrap Code Review for ${REPO_SLUG}"
|
|
263
|
+
CODE_REVIEW_ID=$(aws ssm get-parameter --name "/prism/continuum/code-review-id/${REPO_SLUG}" --query Parameter.Value --output text 2>/dev/null || echo "")
|
|
264
|
+
|
|
265
|
+
if [[ -z "$CODE_REVIEW_ID" ]]; then
|
|
266
|
+
echo " No Code Review found for ${REPO_SLUG} — bootstrapping..."
|
|
267
|
+
|
|
268
|
+
# Upload repo ZIP as context for the diff scan
|
|
269
|
+
git archive HEAD --format=zip -o /tmp/repo.zip
|
|
270
|
+
aws s3 cp /tmp/repo.zip "s3://${SCAN_BUCKET}/repo/${REPO_SLUG}/latest.zip" --quiet
|
|
271
|
+
|
|
272
|
+
# Create Code Review resource
|
|
273
|
+
CR_RESPONSE=$(aws securityagent create-code-review \
|
|
274
|
+
--agent-space-id "${AGENT_SPACE_ID}" \
|
|
275
|
+
--title "${REPO_SLUG}-ci-diff-scan" \
|
|
276
|
+
--service-role "${SERVICE_ROLE}" \
|
|
277
|
+
--assets "{\"sourceCode\":[{\"s3Location\":\"s3://${SCAN_BUCKET}/repo/${REPO_SLUG}/latest.zip\"}]}" \
|
|
278
|
+
--output json 2>&1)
|
|
279
|
+
|
|
280
|
+
if echo "$CR_RESPONSE" | jq -e '.codeReviewId' > /dev/null 2>&1; then
|
|
281
|
+
CODE_REVIEW_ID=$(echo "$CR_RESPONSE" | jq -r '.codeReviewId')
|
|
282
|
+
echo " ✅ Code Review created: ${CODE_REVIEW_ID}"
|
|
283
|
+
|
|
284
|
+
# Persist for future runs
|
|
285
|
+
aws ssm put-parameter \
|
|
286
|
+
--name "/prism/continuum/code-review-id/${REPO_SLUG}" \
|
|
287
|
+
--value "${CODE_REVIEW_ID}" \
|
|
288
|
+
--type String --overwrite 2>/dev/null || true
|
|
289
|
+
else
|
|
290
|
+
echo " ⚠️ Failed to create Code Review: ${CR_RESPONSE}"
|
|
291
|
+
echo " Skipping scan (non-blocking)."
|
|
292
|
+
echo "findings=0" >> "$GITHUB_OUTPUT"
|
|
293
|
+
echo "skipped=true" >> "$GITHUB_OUTPUT"
|
|
294
|
+
exit 0
|
|
295
|
+
fi
|
|
296
|
+
else
|
|
297
|
+
echo " Using existing Code Review: ${CODE_REVIEW_ID}"
|
|
298
|
+
|
|
299
|
+
# Re-upload fresh repo ZIP (context for accurate cross-module analysis)
|
|
300
|
+
git archive HEAD --format=zip -o /tmp/repo.zip
|
|
301
|
+
aws s3 cp /tmp/repo.zip "s3://${SCAN_BUCKET}/repo/${REPO_SLUG}/latest.zip" --quiet
|
|
302
|
+
fi
|
|
303
|
+
echo "::endgroup::"
|
|
259
304
|
|
|
260
|
-
|
|
261
|
-
|
|
305
|
+
echo "::group::Generate and upload diff"
|
|
306
|
+
BASE_SHA="${{ github.event.pull_request.base.sha }}"
|
|
307
|
+
HEAD_SHA="${{ github.sha }}"
|
|
308
|
+
git diff "${BASE_SHA}..${HEAD_SHA}" > /tmp/changes.patch
|
|
309
|
+
|
|
310
|
+
DIFF_SIZE=$(wc -c < /tmp/changes.patch)
|
|
311
|
+
if [[ "$DIFF_SIZE" -eq 0 ]]; then
|
|
312
|
+
echo "No changes to scan."
|
|
313
|
+
echo "findings=0" >> "$GITHUB_OUTPUT"
|
|
314
|
+
exit 0
|
|
315
|
+
fi
|
|
316
|
+
|
|
317
|
+
DIFF_KEY="diffs/${REPO_SLUG}/${{ github.event.pull_request.number }}/${HEAD_SHA}.patch"
|
|
318
|
+
aws s3 cp /tmp/changes.patch "s3://${SCAN_BUCKET}/${DIFF_KEY}" --quiet
|
|
319
|
+
echo "::endgroup::"
|
|
320
|
+
|
|
321
|
+
echo "::group::Start Continuum diff scan"
|
|
322
|
+
JOB_RESPONSE=$(aws securityagent start-code-review-job \
|
|
323
|
+
--agent-space-id "${AGENT_SPACE_ID}" \
|
|
324
|
+
--code-review-id "${CODE_REVIEW_ID}" \
|
|
325
|
+
--diff-source "{\"s3Uri\":\"s3://${SCAN_BUCKET}/${DIFF_KEY}\"}" \
|
|
326
|
+
--output json)
|
|
327
|
+
|
|
328
|
+
JOB_ID=$(echo "$JOB_RESPONSE" | jq -r '.codeReviewJobId')
|
|
329
|
+
echo "Job started: ${JOB_ID}"
|
|
330
|
+
echo "::endgroup::"
|
|
331
|
+
|
|
332
|
+
echo "::group::Poll for completion (timeout: 15 min)"
|
|
333
|
+
for i in $(seq 1 30); do
|
|
334
|
+
sleep 30
|
|
335
|
+
STATUS=$(aws securityagent batch-get-code-review-jobs \
|
|
336
|
+
--agent-space-id "${AGENT_SPACE_ID}" \
|
|
337
|
+
--code-review-job-ids "${JOB_ID}" \
|
|
338
|
+
--query 'codeReviewJobs[0].status' --output text 2>/dev/null || echo "UNKNOWN")
|
|
339
|
+
|
|
340
|
+
echo " Poll ${i}/30: ${STATUS}"
|
|
341
|
+
if [[ "$STATUS" == "COMPLETED" || "$STATUS" == "FAILED" || "$STATUS" == "STOPPED" ]]; then
|
|
342
|
+
break
|
|
343
|
+
fi
|
|
344
|
+
done
|
|
345
|
+
echo "::endgroup::"
|
|
346
|
+
|
|
347
|
+
if [[ "$STATUS" == "FAILED" ]]; then
|
|
348
|
+
echo "::warning::Continuum scan failed — treating as 0 findings (non-blocking)"
|
|
349
|
+
echo "findings=0" >> "$GITHUB_OUTPUT"
|
|
350
|
+
exit 0
|
|
351
|
+
fi
|
|
352
|
+
|
|
353
|
+
if [[ "$STATUS" != "COMPLETED" ]]; then
|
|
354
|
+
echo "::warning::Continuum scan timed out (status: ${STATUS}) — treating as 0 findings"
|
|
355
|
+
echo "findings=0" >> "$GITHUB_OUTPUT"
|
|
356
|
+
exit 0
|
|
357
|
+
fi
|
|
358
|
+
|
|
359
|
+
echo "::group::Retrieve findings"
|
|
360
|
+
FINDINGS_JSON=$(aws securityagent list-findings \
|
|
361
|
+
--agent-space-id "${AGENT_SPACE_ID}" \
|
|
362
|
+
--code-review-job-id "${JOB_ID}" \
|
|
363
|
+
--output json 2>/dev/null || echo '{"findingsSummaries":[]}')
|
|
364
|
+
|
|
365
|
+
TOTAL=$(echo "$FINDINGS_JSON" | jq '.findingsSummaries | length')
|
|
366
|
+
CRITICAL=$(echo "$FINDINGS_JSON" | jq '[.findingsSummaries[] | select(.riskLevel == "CRITICAL")] | length')
|
|
367
|
+
HIGH=$(echo "$FINDINGS_JSON" | jq '[.findingsSummaries[] | select(.riskLevel == "HIGH")] | length')
|
|
368
|
+
MEDIUM=$(echo "$FINDINGS_JSON" | jq '[.findingsSummaries[] | select(.riskLevel == "MEDIUM")] | length')
|
|
369
|
+
|
|
370
|
+
echo "Findings: ${TOTAL} total (${CRITICAL} critical, ${HIGH} high, ${MEDIUM} medium)"
|
|
371
|
+
echo "findings=${TOTAL}" >> "$GITHUB_OUTPUT"
|
|
372
|
+
echo "critical=${CRITICAL}" >> "$GITHUB_OUTPUT"
|
|
373
|
+
echo "high=${HIGH}" >> "$GITHUB_OUTPUT"
|
|
374
|
+
echo "findings_json=$(echo "$FINDINGS_JSON" | jq -c '.findingsSummaries')" >> "$GITHUB_OUTPUT"
|
|
375
|
+
echo "::endgroup::"
|
|
376
|
+
|
|
377
|
+
# Print findings summary for PR annotations
|
|
378
|
+
if [[ "$TOTAL" -gt 0 ]]; then
|
|
379
|
+
echo "$FINDINGS_JSON" | jq -r '.findingsSummaries[] | "::error ::[\(.riskLevel)] \(.name | .[0:120])"'
|
|
380
|
+
fi
|
|
381
|
+
|
|
382
|
+
- name: Emit Continuum findings to EventBridge
|
|
383
|
+
if: steps.security-gate.outputs.findings != '0' && steps.security-gate.outputs.skipped != 'true'
|
|
262
384
|
env:
|
|
263
|
-
|
|
385
|
+
AWS_REGION: us-west-2
|
|
264
386
|
run: |
|
|
265
387
|
PR_NUMBER="${{ github.event.pull_request.number }}"
|
|
266
388
|
REPO="${{ github.repository }}"
|
|
267
389
|
TEAM_ID="${{ steps.prism-config.outputs.team_id }}"
|
|
268
|
-
|
|
269
|
-
HEAD_SHA="${{ github.sha }}"
|
|
390
|
+
FINDINGS='${{ steps.security-gate.outputs.findings_json }}'
|
|
270
391
|
|
|
271
392
|
AI_ORIGIN="human"
|
|
393
|
+
BASE_SHA="${{ github.event.pull_request.base.sha }}"
|
|
394
|
+
HEAD_SHA="${{ github.sha }}"
|
|
272
395
|
for SHA in $(git rev-list "${BASE_SHA}..${HEAD_SHA}"); do
|
|
273
396
|
if git log -1 --format='%B' "${SHA}" | grep -q 'AI-Origin: ai-generated\|AI-Origin: ai-assisted'; then
|
|
274
397
|
AI_ORIGIN="ai-assisted"; break
|
|
275
398
|
fi
|
|
276
399
|
done
|
|
277
400
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
ENTRIES=$(echo "${REVIEW_COMMENTS}" | jq --arg team_id "${TEAM_ID}" --arg repo "${REPO}" \
|
|
401
|
+
ENTRIES=$(echo "${FINDINGS}" | jq --arg team_id "${TEAM_ID}" --arg repo "${REPO}" \
|
|
281
402
|
--arg ai_origin "${AI_ORIGIN}" --argjson pr_number "${PR_NUMBER}" '
|
|
282
|
-
|
|
283
|
-
{"89":"CRITICAL","78":"CRITICAL","94":"CRITICAL","502":"CRITICAL","798":"CRITICAL",
|
|
284
|
-
"79":"HIGH","22":"HIGH","918":"HIGH","352":"HIGH","287":"HIGH","862":"HIGH",
|
|
285
|
-
"200":"MEDIUM","532":"MEDIUM","601":"MEDIUM"};
|
|
286
|
-
[.[] | select(.user.login == "aws-security-agent[bot]")] |
|
|
287
|
-
to_entries | map(.value as $c |
|
|
288
|
-
($c.body | capture("CWE-(?<id>[0-9]+)") // {id: null}).id as $cwe_id |
|
|
289
|
-
(if $cwe_id then (cwe_severity[$cwe_id] // "MEDIUM") else "MEDIUM" end) as $severity |
|
|
403
|
+
to_entries | map(.value as $f |
|
|
290
404
|
{Source:"prism.d1.velocity", DetailType:"prism.d1.security.code_review",
|
|
291
405
|
EventBusName:"prism-d1-metrics",
|
|
292
|
-
Detail:({team_id:$team_id, repo:$repo, timestamp
|
|
406
|
+
Detail:({team_id:$team_id, repo:$repo, timestamp:($f.createdAt // now | tostring), prism_level:3,
|
|
293
407
|
metric:{name:"security_finding",value:1,unit:"count"},
|
|
294
|
-
ai_context:{tool:"
|
|
295
|
-
|
|
296
|
-
severity
|
|
297
|
-
|
|
408
|
+
ai_context:{tool:"continuum",model:"aws-continuum",origin:$ai_origin},
|
|
409
|
+
continuum_finding:{finding_id:($f.findingId // "cf-pr\($pr_number)-\(.key)"), phase:"code_review",
|
|
410
|
+
severity:($f.riskLevel // "MEDIUM"),
|
|
411
|
+
cwe_id:($f.cweId // null),
|
|
412
|
+
ai_origin:$ai_origin, found_at:($f.createdAt // null)}
|
|
298
413
|
} | tostring)})' 2>/dev/null || echo "[]")
|
|
299
414
|
|
|
300
415
|
TOTAL=$(echo "${ENTRIES}" | jq 'length')
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
416
|
+
if [[ "$TOTAL" -gt 0 ]]; then
|
|
417
|
+
for i in $(seq 0 10 $((TOTAL - 1))); do
|
|
418
|
+
aws events put-events --entries "$(echo "${ENTRIES}" | jq ".[$i:$((i+10))]")"
|
|
419
|
+
done
|
|
420
|
+
echo "Emitted ${TOTAL} finding events to EventBridge"
|
|
421
|
+
fi
|
|
304
422
|
|
|
305
423
|
- name: Fail on eval or security issues
|
|
306
|
-
if: steps.eval.outputs.overall_result == 'FAIL' || steps.security-gate.outputs.findings != '0'
|
|
424
|
+
if: steps.eval.outputs.overall_result == 'FAIL' || (steps.security-gate.outputs.findings != '0' && steps.security-gate.outputs.skipped != 'true')
|
|
307
425
|
run: |
|
|
308
426
|
[[ "${{ steps.eval.outputs.overall_result }}" == "FAIL" ]] && echo "❌ Eval gate failed"
|
|
309
|
-
[[ "${{ steps.security-gate.outputs.findings }}" != "0"
|
|
427
|
+
if [[ "${{ steps.security-gate.outputs.findings }}" != "0" && "${{ steps.security-gate.outputs.skipped }}" != "true" ]]; then
|
|
428
|
+
echo "❌ AWS Continuum found ${{ steps.security-gate.outputs.findings }} security issues (${{ steps.security-gate.outputs.critical }} critical, ${{ steps.security-gate.outputs.high }} high)"
|
|
429
|
+
fi
|
|
310
430
|
exit 1
|
|
@@ -3,6 +3,8 @@ import * as securityagent from 'aws-cdk-lib/aws-securityagent';
|
|
|
3
3
|
import * as iam from 'aws-cdk-lib/aws-iam';
|
|
4
4
|
import * as kms from 'aws-cdk-lib/aws-kms';
|
|
5
5
|
import * as logs from 'aws-cdk-lib/aws-logs';
|
|
6
|
+
import * as s3 from 'aws-cdk-lib/aws-s3';
|
|
7
|
+
import * as ssm from 'aws-cdk-lib/aws-ssm';
|
|
6
8
|
import { Construct } from 'constructs';
|
|
7
9
|
import { NagSuppressions } from 'cdk-nag';
|
|
8
10
|
|
|
@@ -52,6 +54,13 @@ export interface SecurityAgentProps {
|
|
|
52
54
|
*/
|
|
53
55
|
codeRemediationStrategy?: 'AUTOMATIC' | 'DISABLED';
|
|
54
56
|
|
|
57
|
+
/**
|
|
58
|
+
* SSM Parameter Store prefix for CI/CD config retrieval.
|
|
59
|
+
* Stores agent space ID, code review ID, and scan bucket name.
|
|
60
|
+
* @default '/prism/continuum'
|
|
61
|
+
*/
|
|
62
|
+
ssmParameterPrefix?: string;
|
|
63
|
+
|
|
55
64
|
/**
|
|
56
65
|
* Tags applied to all Security Agent resources.
|
|
57
66
|
*/
|
|
@@ -71,6 +80,7 @@ export class SecurityAgentConstruct extends Construct {
|
|
|
71
80
|
public readonly agentSpaceId: string;
|
|
72
81
|
public readonly serviceRole: iam.Role;
|
|
73
82
|
public readonly targetDomainIds: string[];
|
|
83
|
+
public readonly scanBucket: s3.Bucket;
|
|
74
84
|
|
|
75
85
|
constructor(scope: Construct, id: string, props: SecurityAgentProps) {
|
|
76
86
|
super(scope, id);
|
|
@@ -93,9 +103,11 @@ export class SecurityAgentConstruct extends Construct {
|
|
|
93
103
|
}),
|
|
94
104
|
);
|
|
95
105
|
|
|
96
|
-
// Grant KMS permissions for encrypted agent spaces
|
|
106
|
+
// Grant KMS permissions for encrypted agent spaces + log groups
|
|
97
107
|
if (props.kmsKey) {
|
|
98
108
|
props.kmsKey.grantEncryptDecrypt(this.serviceRole);
|
|
109
|
+
// DescribeKey is required for CreateLogGroup with KMS encryption
|
|
110
|
+
props.kmsKey.grant(this.serviceRole, 'kms:DescribeKey', 'kms:CreateGrant');
|
|
99
111
|
}
|
|
100
112
|
|
|
101
113
|
// Grant CloudWatch Logs access for pen test logging
|
|
@@ -197,11 +209,12 @@ export class SecurityAgentConstruct extends Construct {
|
|
|
197
209
|
}
|
|
198
210
|
|
|
199
211
|
// Log group for pen test results (Security Agent writes to /aws/securityagent/<space>/pt-<id>)
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
212
|
+
// Note: we do NOT set logGroupName to avoid conflicts with pre-existing log groups
|
|
213
|
+
// created by prism-cli securityagent setup or the Security Agent service itself.
|
|
214
|
+
const pentestLogGroup = logs.LogGroup.fromLogGroupName(
|
|
215
|
+
this, 'PentestLogGroup',
|
|
216
|
+
`/aws/securityagent/${props.agentSpaceName}`,
|
|
217
|
+
);
|
|
205
218
|
|
|
206
219
|
// Outputs
|
|
207
220
|
new cdk.CfnOutput(this, 'AgentSpaceIdOutput', {
|
|
@@ -223,6 +236,111 @@ export class SecurityAgentConstruct extends Construct {
|
|
|
223
236
|
exportName: `PrismD1SecurityAgentDomainIds`,
|
|
224
237
|
});
|
|
225
238
|
}
|
|
239
|
+
|
|
240
|
+
// -------------------------------------------------------
|
|
241
|
+
// S3 Scan Bucket — stores repo ZIPs and diff files for
|
|
242
|
+
// API-triggered code reviews (diff scans from CI/CD).
|
|
243
|
+
// -------------------------------------------------------
|
|
244
|
+
this.scanBucket = new s3.Bucket(this, 'ScanBucket', {
|
|
245
|
+
bucketName: `security-agent-scans-${cdk.Aws.ACCOUNT_ID}-${cdk.Aws.REGION}`,
|
|
246
|
+
// SSE-S3 (not the customer-managed KMS key): the Continuum service reads
|
|
247
|
+
// this bucket when creating the code review and cannot access a CMK it
|
|
248
|
+
// has no grant on. Artifacts here are ephemeral diffs (30-day lifecycle),
|
|
249
|
+
// the bucket is private (BLOCK_ALL) and SSL-enforced.
|
|
250
|
+
encryption: s3.BucketEncryption.S3_MANAGED,
|
|
251
|
+
blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
|
|
252
|
+
enforceSSL: true,
|
|
253
|
+
versioned: false,
|
|
254
|
+
lifecycleRules: [
|
|
255
|
+
{
|
|
256
|
+
id: 'expire-scan-artifacts',
|
|
257
|
+
expiration: cdk.Duration.days(30),
|
|
258
|
+
enabled: true,
|
|
259
|
+
},
|
|
260
|
+
],
|
|
261
|
+
removalPolicy: cdk.RemovalPolicy.DESTROY,
|
|
262
|
+
autoDeleteObjects: true,
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
// Grant Security Agent service role read access to the scan bucket
|
|
266
|
+
this.scanBucket.grantRead(this.serviceRole);
|
|
267
|
+
|
|
268
|
+
// Suppress cdk-nag for S3 read grant wildcards (grantRead expands to s3:GetObject*, s3:GetBucket*, s3:List*)
|
|
269
|
+
NagSuppressions.addResourceSuppressions(
|
|
270
|
+
this.serviceRole,
|
|
271
|
+
[
|
|
272
|
+
{
|
|
273
|
+
id: 'AwsSolutions-IAM5',
|
|
274
|
+
reason: 'grantRead() generates s3:GetObject*, s3:GetBucket*, s3:List* — standard CDK pattern for bucket read access',
|
|
275
|
+
appliesTo: ['Action::s3:GetObject*', 'Action::s3:GetBucket*', 'Action::s3:List*'],
|
|
276
|
+
},
|
|
277
|
+
{
|
|
278
|
+
id: 'AwsSolutions-IAM5',
|
|
279
|
+
reason: 'Scan bucket objects are dynamic (SHA-named diffs); wildcard on objects required',
|
|
280
|
+
appliesTo: ['Resource::<SecurityAgentScanBucketB752F4A9.Arn>/*'],
|
|
281
|
+
},
|
|
282
|
+
],
|
|
283
|
+
true,
|
|
284
|
+
);
|
|
285
|
+
|
|
286
|
+
NagSuppressions.addResourceSuppressions(
|
|
287
|
+
this.scanBucket,
|
|
288
|
+
[
|
|
289
|
+
{
|
|
290
|
+
id: 'AwsSolutions-S1',
|
|
291
|
+
reason: 'Access logging not required for ephemeral scan artifacts (30-day lifecycle, auto-deleted)',
|
|
292
|
+
},
|
|
293
|
+
],
|
|
294
|
+
true,
|
|
295
|
+
);
|
|
296
|
+
|
|
297
|
+
// -------------------------------------------------------
|
|
298
|
+
// Code Review resource — NOT created here in CDK.
|
|
299
|
+
// CreateCodeReview requires assets.sourceCode pointing to
|
|
300
|
+
// an existing ZIP of the repo (chicken-and-egg at deploy).
|
|
301
|
+
// Instead, `prism-cli securityagent setup` handles:
|
|
302
|
+
// 1. git archive → upload repo.zip to scan bucket
|
|
303
|
+
// 2. CreateCodeReview API call
|
|
304
|
+
// 3. Write code-review-id to SSM
|
|
305
|
+
// The CDK only provisions the bucket + role + SSM scaffold.
|
|
306
|
+
// -------------------------------------------------------
|
|
307
|
+
|
|
308
|
+
new cdk.CfnOutput(this, 'ScanBucketOutput', {
|
|
309
|
+
value: this.scanBucket.bucketName,
|
|
310
|
+
description: 'S3 bucket for scan artifacts (repo ZIPs + diffs)',
|
|
311
|
+
exportName: 'PrismD1ContinuumScanBucket',
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
// -------------------------------------------------------
|
|
315
|
+
// SSM Parameter Store — non-sensitive CI/CD config.
|
|
316
|
+
// GitHub Actions workflows read these at runtime so no
|
|
317
|
+
// hardcoded IDs are needed in the repository.
|
|
318
|
+
// -------------------------------------------------------
|
|
319
|
+
const prefix = props.ssmParameterPrefix ?? '/prism/continuum';
|
|
320
|
+
|
|
321
|
+
new ssm.StringParameter(this, 'ParamAgentSpaceId', {
|
|
322
|
+
parameterName: `${prefix}/agent-space-id`,
|
|
323
|
+
stringValue: this.agentSpaceId,
|
|
324
|
+
description: 'AWS Continuum Agent Space ID for PRISM D1',
|
|
325
|
+
tier: ssm.ParameterTier.STANDARD,
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
// code-review-id is written by `prism-cli securityagent setup` (not CDK)
|
|
329
|
+
// because CreateCodeReview needs an existing repo ZIP in S3 first.
|
|
330
|
+
|
|
331
|
+
new ssm.StringParameter(this, 'ParamScanBucket', {
|
|
332
|
+
parameterName: `${prefix}/scan-bucket`,
|
|
333
|
+
stringValue: this.scanBucket.bucketName,
|
|
334
|
+
description: 'S3 bucket name for uploading repo/diff scan artifacts',
|
|
335
|
+
tier: ssm.ParameterTier.STANDARD,
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
new ssm.StringParameter(this, 'ParamServiceRoleArn', {
|
|
339
|
+
parameterName: `${prefix}/service-role-arn`,
|
|
340
|
+
stringValue: this.serviceRole.roleArn,
|
|
341
|
+
description: 'Service role ARN for Continuum CreateCodeReview (passed via --service-role)',
|
|
342
|
+
tier: ssm.ParameterTier.STANDARD,
|
|
343
|
+
});
|
|
226
344
|
}
|
|
227
345
|
|
|
228
346
|
/**
|
|
@@ -421,13 +421,108 @@ export class MetricsPipelineStack extends cdk.Stack {
|
|
|
421
421
|
if (enableSecurityAgent) {
|
|
422
422
|
this.securityAgent = new SecurityAgentConstruct(this, 'SecurityAgent', {
|
|
423
423
|
agentSpaceName: 'prism-d1-security',
|
|
424
|
-
description: 'PRISM D1
|
|
424
|
+
description: 'PRISM D1 Continuum space for design review, code review, and pen testing',
|
|
425
425
|
kmsKey: prismKmsKey,
|
|
426
426
|
codeRemediationStrategy: 'DISABLED',
|
|
427
427
|
tags: {
|
|
428
428
|
'prism:pillar': 'security',
|
|
429
429
|
},
|
|
430
430
|
});
|
|
431
|
+
|
|
432
|
+
// Grant GitHub OIDC roles access to scan bucket and Continuum APIs.
|
|
433
|
+
// The OIDC role is created by `prism-cli bootstrapper setup-github-oidc`
|
|
434
|
+
// with name pattern prism-d1-github-oidc-*.
|
|
435
|
+
this.securityAgent.scanBucket.addToResourcePolicy(
|
|
436
|
+
new iam.PolicyStatement({
|
|
437
|
+
effect: iam.Effect.ALLOW,
|
|
438
|
+
principals: [new iam.ArnPrincipal(`arn:aws:iam::${cdk.Aws.ACCOUNT_ID}:root`)],
|
|
439
|
+
actions: ['s3:PutObject', 's3:GetObject'],
|
|
440
|
+
resources: [this.securityAgent.scanBucket.arnForObjects('*')],
|
|
441
|
+
conditions: {
|
|
442
|
+
ArnLike: {
|
|
443
|
+
'aws:PrincipalArn': `arn:aws:iam::${cdk.Aws.ACCOUNT_ID}:role/prism-d1-github-oidc-*`,
|
|
444
|
+
},
|
|
445
|
+
},
|
|
446
|
+
}),
|
|
447
|
+
);
|
|
448
|
+
|
|
449
|
+
// Create a managed policy for Continuum scan API access.
|
|
450
|
+
// Attached to the OIDC role by the bootstrapper setup script.
|
|
451
|
+
const continuumCiPolicy = new iam.ManagedPolicy(this, 'ContinuumCiPolicy', {
|
|
452
|
+
managedPolicyName: 'prism-d1-continuum-ci-scan',
|
|
453
|
+
description: 'Grants GitHub Actions workflows access to Continuum diff scan APIs and SSM config',
|
|
454
|
+
statements: [
|
|
455
|
+
new iam.PolicyStatement({
|
|
456
|
+
sid: 'ContinuumScanAPIs',
|
|
457
|
+
effect: iam.Effect.ALLOW,
|
|
458
|
+
actions: [
|
|
459
|
+
'securityagent:StartCodeReviewJob',
|
|
460
|
+
'securityagent:BatchGetCodeReviewJobs',
|
|
461
|
+
'securityagent:BatchGetCodeReviewJobTasks',
|
|
462
|
+
'securityagent:ListFindings',
|
|
463
|
+
'securityagent:BatchGetFindings',
|
|
464
|
+
'securityagent:CreateCodeReview',
|
|
465
|
+
'securityagent:ListCodeReviews',
|
|
466
|
+
],
|
|
467
|
+
resources: [
|
|
468
|
+
`arn:aws:securityagent:${cdk.Aws.REGION}:${cdk.Aws.ACCOUNT_ID}:agent-space/*`,
|
|
469
|
+
],
|
|
470
|
+
}),
|
|
471
|
+
new iam.PolicyStatement({
|
|
472
|
+
sid: 'PassRoleForCodeReview',
|
|
473
|
+
effect: iam.Effect.ALLOW,
|
|
474
|
+
actions: ['iam:PassRole'],
|
|
475
|
+
resources: [this.securityAgent.serviceRole.roleArn],
|
|
476
|
+
conditions: {
|
|
477
|
+
StringEquals: { 'iam:PassedToService': 'securityagent.amazonaws.com' },
|
|
478
|
+
},
|
|
479
|
+
}),
|
|
480
|
+
new iam.PolicyStatement({
|
|
481
|
+
sid: 'ScanBucketWrite',
|
|
482
|
+
effect: iam.Effect.ALLOW,
|
|
483
|
+
actions: ['s3:PutObject', 's3:GetObject', 's3:ListBucket'],
|
|
484
|
+
resources: [
|
|
485
|
+
this.securityAgent.scanBucket.bucketArn,
|
|
486
|
+
this.securityAgent.scanBucket.arnForObjects('*'),
|
|
487
|
+
],
|
|
488
|
+
}),
|
|
489
|
+
new iam.PolicyStatement({
|
|
490
|
+
sid: 'SSMReadConfig',
|
|
491
|
+
effect: iam.Effect.ALLOW,
|
|
492
|
+
actions: ['ssm:GetParameter', 'ssm:GetParameters', 'ssm:PutParameter'],
|
|
493
|
+
resources: [
|
|
494
|
+
`arn:aws:ssm:${cdk.Aws.REGION}:${cdk.Aws.ACCOUNT_ID}:parameter/prism/continuum/*`,
|
|
495
|
+
],
|
|
496
|
+
}),
|
|
497
|
+
],
|
|
498
|
+
});
|
|
499
|
+
|
|
500
|
+
NagSuppressions.addResourceSuppressions(
|
|
501
|
+
continuumCiPolicy,
|
|
502
|
+
[
|
|
503
|
+
{
|
|
504
|
+
id: 'AwsSolutions-IAM5',
|
|
505
|
+
reason: 'Agent space ID is dynamic; wildcard scoped to securityagent service resources only',
|
|
506
|
+
appliesTo: [`Resource::arn:aws:securityagent:<AWS::Region>:<AWS::AccountId>:agent-space/*`],
|
|
507
|
+
},
|
|
508
|
+
{
|
|
509
|
+
id: 'AwsSolutions-IAM5',
|
|
510
|
+
reason: 'Scan bucket objects include dynamic diff filenames (SHA-based); wildcard on objects only',
|
|
511
|
+
appliesTo: ['Resource::<SecurityAgentScanBucketB752F4A9.Arn>/*'],
|
|
512
|
+
},
|
|
513
|
+
{
|
|
514
|
+
id: 'AwsSolutions-IAM5',
|
|
515
|
+
reason: 'SSM parameters under /prism/continuum/ are all non-sensitive config values (IDs and bucket names)',
|
|
516
|
+
appliesTo: ['Resource::arn:aws:ssm:<AWS::Region>:<AWS::AccountId>:parameter/prism/continuum/*'],
|
|
517
|
+
},
|
|
518
|
+
],
|
|
519
|
+
true,
|
|
520
|
+
);
|
|
521
|
+
|
|
522
|
+
new cdk.CfnOutput(this, 'ContinuumCiPolicyArn', {
|
|
523
|
+
value: continuumCiPolicy.managedPolicyArn,
|
|
524
|
+
description: 'Attach this policy to your GitHub OIDC role for Continuum CI scans',
|
|
525
|
+
});
|
|
431
526
|
}
|
|
432
527
|
|
|
433
528
|
// -------------------------------------------------------
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../../../src/commands/securityagent/setup.ts"],"names":[],"mappings":";;;;;;;oBAsCkB;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;;AANrD,
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../../../src/commands/securityagent/setup.ts"],"names":[],"mappings":";;;;;;;oBAsCkB;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;;AANrD,wBA+KE"}
|
|
@@ -109,6 +109,85 @@ export default {
|
|
|
109
109
|
console.log(` Application: ${applicationId}`);
|
|
110
110
|
console.log(` Web console: https://${region}.console.aws.amazon.com/securityagent/home?region=${region}`);
|
|
111
111
|
console.log(' Click "Admin access" to open the web app.');
|
|
112
|
+
// -------------------------------------------------------
|
|
113
|
+
// Create Code Review for CI diff scans
|
|
114
|
+
// Requires: repo ZIP uploaded to scan bucket first
|
|
115
|
+
// -------------------------------------------------------
|
|
116
|
+
console.log('\n📦 Setting up Code Review for CI/CD diff scans...');
|
|
117
|
+
// Get scan bucket from SSM (created by CDK)
|
|
118
|
+
const bucketParam = runCapture(`aws ssm get-parameter --name /prism/continuum/scan-bucket ${env} --query Parameter.Value --output text`);
|
|
119
|
+
if (!bucketParam.ok || !bucketParam.stdout) {
|
|
120
|
+
console.log(' ⚠️ Scan bucket SSM param not found. Deploy with --context enableSecurityAgent=true first.');
|
|
121
|
+
console.log(' Skipping Code Review creation.');
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
const scanBucket = bucketParam.stdout;
|
|
125
|
+
console.log(` Scan bucket: ${scanBucket}`);
|
|
126
|
+
// Zip the repo and upload
|
|
127
|
+
console.log(' Archiving repo...');
|
|
128
|
+
const repoRoot = process.cwd();
|
|
129
|
+
const zipResult = runCapture(`cd ${repoRoot} && git archive HEAD --format=zip -o /tmp/prism-repo.zip`);
|
|
130
|
+
if (!zipResult.ok) {
|
|
131
|
+
console.log(` ⚠️ git archive failed (not a git repo?): ${zipResult.stdout}`);
|
|
132
|
+
console.log(' Skipping Code Review creation. Run from a git repo root.');
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
const upload = runCapture(`aws s3 cp /tmp/prism-repo.zip s3://${scanBucket}/repo/latest.zip ${env}`);
|
|
136
|
+
if (!upload.ok) {
|
|
137
|
+
console.error(` Failed to upload repo ZIP: ${upload.stdout}`);
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
console.log(' ✅ Repo ZIP uploaded');
|
|
141
|
+
// Create Code Review (or find existing)
|
|
142
|
+
const codeReviewTitle = 'prism-d1-security-ci-diff-scan';
|
|
143
|
+
const createCr = runCapture(`aws securityagent create-code-review ` +
|
|
144
|
+
`--agent-space-id ${agentSpaceId} ` +
|
|
145
|
+
`--title ${codeReviewTitle} ` +
|
|
146
|
+
`--service-role ${roleArn} ` +
|
|
147
|
+
`--assets '{"sourceCode":[{"s3Location":"s3://${scanBucket}/repo/latest.zip"}]}' ` +
|
|
148
|
+
`${env} --output json`);
|
|
149
|
+
let codeReviewId;
|
|
150
|
+
if (createCr.ok) {
|
|
151
|
+
codeReviewId = JSON.parse(createCr.stdout).codeReviewId;
|
|
152
|
+
console.log(` ✅ Code Review created: ${codeReviewId}`);
|
|
153
|
+
}
|
|
154
|
+
else if (createCr.stdout.includes('Conflict') || createCr.stdout.includes('already exists')) {
|
|
155
|
+
// Already exists — find it
|
|
156
|
+
const listCr = runCapture(`aws securityagent list-code-reviews --agent-space-id ${agentSpaceId} ${env} --output json`);
|
|
157
|
+
if (listCr.ok) {
|
|
158
|
+
const reviews = JSON.parse(listCr.stdout).codeReviews || [];
|
|
159
|
+
const existing = reviews.find((r) => r.title === codeReviewTitle);
|
|
160
|
+
if (existing) {
|
|
161
|
+
codeReviewId = existing.codeReviewId;
|
|
162
|
+
console.log(` ✅ Code Review already exists: ${codeReviewId}`);
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
console.error(' ❌ Could not find existing Code Review');
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
console.error(` ❌ Failed to list code reviews: ${listCr.stdout}`);
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
console.error(` ❌ Failed to create Code Review: ${createCr.stdout}`);
|
|
176
|
+
console.log(' The CI workflow will skip Continuum scanning until this is resolved.');
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
// Write code-review-id to SSM
|
|
180
|
+
const ssmWrite = runCapture(`aws ssm put-parameter --name /prism/continuum/code-review-id ` +
|
|
181
|
+
`--value "${codeReviewId}" --type String --overwrite ${env}`);
|
|
182
|
+
if (ssmWrite.ok) {
|
|
183
|
+
console.log(' ✅ Code Review ID written to SSM: /prism/continuum/code-review-id');
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
console.log(` ⚠️ Failed to write SSM param: ${ssmWrite.stdout}`);
|
|
187
|
+
console.log(` Manually run: aws ssm put-parameter --name /prism/continuum/code-review-id --value "${codeReviewId}" --type String --overwrite ${env}`);
|
|
188
|
+
}
|
|
189
|
+
console.log('\n🎉 Continuum CI scanning ready!');
|
|
190
|
+
console.log(' The eval gate workflow will now run diff scans on every PR.');
|
|
112
191
|
},
|
|
113
192
|
};
|
|
114
193
|
//# sourceMappingURL=setup.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../../../src/commands/securityagent/setup.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../../../src/commands/securityagent/setup.ts"],"names":[],"mappings":"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"}
|