@prism-d1/cli 1.2.0 → 1.3.0

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.
Files changed (127) hide show
  1. package/dist/assets/github-workflows/prism-eval-gate-kiro.yml +2 -2
  2. package/dist/assets/infra/bin/app.ts +61 -37
  3. package/dist/assets/infra/lib/constructs/security-agent-construct.ts +35 -30
  4. package/dist/assets/infra/lib/metrics-pipeline-stack.ts +2 -110
  5. package/dist/assets/infra/lib/security-agent-resources.ts +136 -0
  6. package/dist/assets/infra/lib/security-agent-stack.ts +69 -0
  7. package/dist/assets/pentest-cdk/bin/app.ts +12 -0
  8. package/dist/assets/pentest-cdk/cdk.json +7 -0
  9. package/dist/assets/pentest-cdk/lib/pentest-target-stack.ts +206 -0
  10. package/dist/assets/pentest-cdk/package.json +18 -0
  11. package/dist/assets/pentest-cdk/tsconfig.json +12 -0
  12. package/dist/src/codewatch/results.d.ts +124 -4
  13. package/dist/src/codewatch/results.d.ts.map +1 -1
  14. package/dist/src/codewatch/results.js +8 -2
  15. package/dist/src/codewatch/results.js.map +1 -1
  16. package/dist/src/commands/_top/version.d.ts +62 -0
  17. package/dist/src/commands/_top/version.d.ts.map +1 -0
  18. package/dist/src/commands/_top/version.js +175 -0
  19. package/dist/src/commands/_top/version.js.map +1 -0
  20. package/dist/src/commands/bootstrapper/setup-otel-sync.d.ts +12 -6
  21. package/dist/src/commands/bootstrapper/setup-otel-sync.d.ts.map +1 -1
  22. package/dist/src/commands/bootstrapper/setup-otel-sync.js +18 -409
  23. package/dist/src/commands/bootstrapper/setup-otel-sync.js.map +1 -1
  24. package/dist/src/commands/enable/codeburn.d.ts +59 -0
  25. package/dist/src/commands/enable/codeburn.d.ts.map +1 -0
  26. package/dist/src/commands/enable/codeburn.js +531 -0
  27. package/dist/src/commands/enable/codeburn.js.map +1 -0
  28. package/dist/src/commands/enable/security.d.ts +41 -0
  29. package/dist/src/commands/enable/security.d.ts.map +1 -0
  30. package/dist/src/commands/enable/security.js +130 -0
  31. package/dist/src/commands/enable/security.js.map +1 -0
  32. package/dist/src/commands/export/otel.d.ts +31 -0
  33. package/dist/src/commands/export/otel.d.ts.map +1 -0
  34. package/dist/src/commands/export/otel.js +52 -0
  35. package/dist/src/commands/export/otel.js.map +1 -0
  36. package/dist/src/commands/security/code-review.d.ts +22 -0
  37. package/dist/src/commands/security/code-review.d.ts.map +1 -0
  38. package/dist/src/commands/security/code-review.js +43 -0
  39. package/dist/src/commands/security/code-review.js.map +1 -0
  40. package/dist/src/commands/security/findings.d.ts +15 -0
  41. package/dist/src/commands/security/findings.d.ts.map +1 -0
  42. package/dist/src/commands/security/findings.js +31 -0
  43. package/dist/src/commands/security/findings.js.map +1 -0
  44. package/dist/src/commands/security/pentest.d.ts +18 -0
  45. package/dist/src/commands/security/pentest.d.ts.map +1 -0
  46. package/dist/src/commands/security/pentest.js +32 -0
  47. package/dist/src/commands/security/pentest.js.map +1 -0
  48. package/dist/src/commands/security/threat-model.d.ts +16 -0
  49. package/dist/src/commands/security/threat-model.d.ts.map +1 -0
  50. package/dist/src/commands/security/threat-model.js +24 -0
  51. package/dist/src/commands/security/threat-model.js.map +1 -0
  52. package/dist/src/commands/security/threats.d.ts +12 -0
  53. package/dist/src/commands/security/threats.d.ts.map +1 -0
  54. package/dist/src/commands/security/threats.js +23 -0
  55. package/dist/src/commands/security/threats.js.map +1 -0
  56. package/dist/src/commands/securityagent/setup.d.ts +19 -5
  57. package/dist/src/commands/securityagent/setup.d.ts.map +1 -1
  58. package/dist/src/commands/securityagent/setup.js +25 -189
  59. package/dist/src/commands/securityagent/setup.js.map +1 -1
  60. package/dist/src/dashboard/codewatch.d.ts.map +1 -1
  61. package/dist/src/dashboard/codewatch.js +2 -1
  62. package/dist/src/dashboard/codewatch.js.map +1 -1
  63. package/dist/src/dashboard/page.d.ts.map +1 -1
  64. package/dist/src/dashboard/page.js +159 -4
  65. package/dist/src/dashboard/page.js.map +1 -1
  66. package/dist/src/dashboard/payload.d.ts +8 -5
  67. package/dist/src/dashboard/payload.d.ts.map +1 -1
  68. package/dist/src/dashboard/payload.js +5 -2
  69. package/dist/src/dashboard/payload.js.map +1 -1
  70. package/dist/src/dashboard/security.d.ts +130 -0
  71. package/dist/src/dashboard/security.d.ts.map +1 -0
  72. package/dist/src/dashboard/security.js +144 -0
  73. package/dist/src/dashboard/security.js.map +1 -0
  74. package/dist/src/dashboard/setup.d.ts +15 -0
  75. package/dist/src/dashboard/setup.d.ts.map +1 -1
  76. package/dist/src/dashboard/setup.js +20 -3
  77. package/dist/src/dashboard/setup.js.map +1 -1
  78. package/dist/src/dashboard/usage.js +1 -1
  79. package/dist/src/dashboard/usage.js.map +1 -1
  80. package/dist/src/index.d.ts.map +1 -1
  81. package/dist/src/index.js +9 -2
  82. package/dist/src/index.js.map +1 -1
  83. package/dist/src/security/cfn-diff.d.ts +57 -0
  84. package/dist/src/security/cfn-diff.d.ts.map +1 -0
  85. package/dist/src/security/cfn-diff.js +112 -0
  86. package/dist/src/security/cfn-diff.js.map +1 -0
  87. package/dist/src/security/errors.d.ts +45 -0
  88. package/dist/src/security/errors.d.ts.map +1 -0
  89. package/dist/src/security/errors.js +116 -0
  90. package/dist/src/security/errors.js.map +1 -0
  91. package/dist/src/security/marker.d.ts +46 -0
  92. package/dist/src/security/marker.d.ts.map +1 -0
  93. package/dist/src/security/marker.js +120 -0
  94. package/dist/src/security/marker.js.map +1 -0
  95. package/dist/src/security/pentest-dockerfile.d.ts +8 -0
  96. package/dist/src/security/pentest-dockerfile.d.ts.map +1 -0
  97. package/dist/src/security/pentest-dockerfile.js +163 -0
  98. package/dist/src/security/pentest-dockerfile.js.map +1 -0
  99. package/dist/src/security/pentest.d.ts +233 -0
  100. package/dist/src/security/pentest.d.ts.map +1 -0
  101. package/dist/src/security/pentest.js +1057 -0
  102. package/dist/src/security/pentest.js.map +1 -0
  103. package/dist/src/security/repo.d.ts +25 -0
  104. package/dist/src/security/repo.d.ts.map +1 -0
  105. package/dist/src/security/repo.js +38 -0
  106. package/dist/src/security/repo.js.map +1 -0
  107. package/dist/src/security/review.d.ts +202 -0
  108. package/dist/src/security/review.d.ts.map +1 -0
  109. package/dist/src/security/review.js +706 -0
  110. package/dist/src/security/review.js.map +1 -0
  111. package/dist/src/security/setup.d.ts +193 -0
  112. package/dist/src/security/setup.d.ts.map +1 -0
  113. package/dist/src/security/setup.js +728 -0
  114. package/dist/src/security/setup.js.map +1 -0
  115. package/dist/src/security/threat-model.d.ts +133 -0
  116. package/dist/src/security/threat-model.d.ts.map +1 -0
  117. package/dist/src/security/threat-model.js +653 -0
  118. package/dist/src/security/threat-model.js.map +1 -0
  119. package/dist/src/utils/exec.d.ts +6 -0
  120. package/dist/src/utils/exec.d.ts.map +1 -1
  121. package/dist/src/utils/exec.js +12 -1
  122. package/dist/src/utils/exec.js.map +1 -1
  123. package/dist/src/utils/otel-sync-schedule.d.ts +19 -0
  124. package/dist/src/utils/otel-sync-schedule.d.ts.map +1 -1
  125. package/dist/src/utils/otel-sync-schedule.js +24 -2
  126. package/dist/src/utils/otel-sync-schedule.js.map +1 -1
  127. package/package.json +3 -3
@@ -0,0 +1,206 @@
1
+ /**
2
+ * The temporary pentest TARGET environment, deployed per run by
3
+ * `prism-cli security pentest` (dockerfile adapter). Generalized from the
4
+ * hand-run spike stack (removed once this replaced it); see
5
+ * docs/DESIGN-prism-cli-pentest.md. Test target: cli/test/fixtures/pentest-sample.
6
+ *
7
+ * Private VPC only: private isolated subnets, no public subnet, no internet
8
+ * gateway, no NAT, no 0.0.0.0/0 ingress anywhere. The app runs on Fargate
9
+ * behind an INTERNAL ALB; the pentest agent's ENI reaches it over local VPC
10
+ * routing. VPC endpoints (ECR api+dkr, S3 gateway, CloudWatch Logs) let Fargate
11
+ * run with no internet path.
12
+ *
13
+ * Context (all from `cdk -c key=value`, set by the adapter):
14
+ * slug run id; names the stack's resources and the private zone
15
+ * appDir absolute path to the Docker build context -> image asset
16
+ * dockerfile Dockerfile path relative to appDir (default: Dockerfile)
17
+ * port container port the app listens on
18
+ * healthPath ALB health-check path
19
+ * zoneName private hosted-zone name (host is app.<zoneName>)
20
+ * ttlHours hours from synth for the prism:expires-at tag
21
+ */
22
+ import * as cdk from 'aws-cdk-lib';
23
+ import * as ec2 from 'aws-cdk-lib/aws-ec2';
24
+ import * as ecs from 'aws-cdk-lib/aws-ecs';
25
+ import * as ecrAssets from 'aws-cdk-lib/aws-ecr-assets';
26
+ import * as elbv2 from 'aws-cdk-lib/aws-elasticloadbalancingv2';
27
+ import * as iam from 'aws-cdk-lib/aws-iam';
28
+ import * as logs from 'aws-cdk-lib/aws-logs';
29
+ import * as route53 from 'aws-cdk-lib/aws-route53';
30
+ import * as targets from 'aws-cdk-lib/aws-route53-targets';
31
+ import * as s3 from 'aws-cdk-lib/aws-s3';
32
+ import * as secretsmanager from 'aws-cdk-lib/aws-secretsmanager';
33
+ import { Construct } from 'constructs';
34
+
35
+ const ALB_PORT = 80;
36
+
37
+ /** A JSON context value (the adapter passes env, secrets and actor ARNs this way); absent = fallback. */
38
+ function ctxJson<T>(scope: Construct, key: string, fallback: T): T {
39
+ const v = scope.node.tryGetContext(key);
40
+ if (v === undefined || v === null || v === '') return fallback;
41
+ return (typeof v === 'string' ? JSON.parse(v) : v) as T;
42
+ }
43
+
44
+ /** A Secrets Manager ARN with its random 6-character suffix is complete; without it, partial. */
45
+ const isCompleteSecretArn = (arn: string) => /-[A-Za-z0-9]{6}$/.test(arn);
46
+
47
+ function ctxStr(scope: Construct, key: string, fallback?: string): string {
48
+ const v = scope.node.tryGetContext(key);
49
+ if (v === undefined || v === null || v === '') {
50
+ if (fallback !== undefined) return fallback;
51
+ throw new Error(`pentest-cdk: required context "${key}" is not set`);
52
+ }
53
+ return String(v);
54
+ }
55
+
56
+ export class PentestTargetStack extends cdk.Stack {
57
+ constructor(scope: Construct, id: string, props: cdk.StackProps) {
58
+ super(scope, id, props);
59
+
60
+ const slug = ctxStr(this, 'slug');
61
+ const appDir = ctxStr(this, 'appDir');
62
+ const port = Number(ctxStr(this, 'port', '8080'));
63
+ const healthPath = ctxStr(this, 'healthPath', '/health');
64
+ const zoneName = ctxStr(this, 'zoneName', `${slug}.prism.internal`);
65
+ const ttlHours = Number(ctxStr(this, 'ttlHours', '24'));
66
+ const logGroupName = `/aws/securityagent/prism-pentest-${slug}`;
67
+
68
+ cdk.Tags.of(this).add('prism:purpose', 'pentest');
69
+ cdk.Tags.of(this).add('prism:pentest-run', slug);
70
+ cdk.Tags.of(this).add('prism:expires-at', new Date(Date.now() + ttlHours * 3_600_000).toISOString());
71
+
72
+ // --- Network: private isolated subnets only (no IGW, no NAT) ---------
73
+ const vpc = new ec2.Vpc(this, 'Vpc', {
74
+ ipAddresses: ec2.IpAddresses.cidr('10.80.0.0/16'),
75
+ maxAzs: 2,
76
+ natGateways: 0,
77
+ subnetConfiguration: [{ name: 'private', subnetType: ec2.SubnetType.PRIVATE_ISOLATED, cidrMask: 24 }],
78
+ restrictDefaultSecurityGroup: true,
79
+ });
80
+ const privateSubnets = { subnetType: ec2.SubnetType.PRIVATE_ISOLATED };
81
+
82
+ const sg = (name: string, description: string) => new ec2.SecurityGroup(this, name, { vpc, description, allowAllOutbound: false });
83
+ const agentSg = sg('AgentSg', 'Pentest agent ENI: may reach the internal ALB on 80 only');
84
+ const albSg = sg('AlbSg', 'Internal ALB: accepts the pentest agent only');
85
+ const appSg = sg('AppSg', 'App tasks: accept the ALB only');
86
+ const endpointSg = sg('EndpointSg', 'VPC interface endpoints: accept the app tasks only');
87
+
88
+ agentSg.addEgressRule(albSg, ec2.Port.tcp(ALB_PORT), 'to the internal ALB');
89
+ albSg.addIngressRule(agentSg, ec2.Port.tcp(ALB_PORT), 'from the pentest agent');
90
+ appSg.addEgressRule(endpointSg, ec2.Port.tcp(443), 'to VPC interface endpoints');
91
+ endpointSg.addIngressRule(appSg, ec2.Port.tcp(443), 'from the app tasks');
92
+
93
+ vpc.addGatewayEndpoint('S3', { service: ec2.GatewayVpcEndpointAwsService.S3, subnets: [privateSubnets] });
94
+ const s3PrefixList = ec2.PrefixList.fromLookup(this, 'S3PrefixList', { prefixListName: `com.amazonaws.${this.region}.s3` });
95
+ appSg.addEgressRule(ec2.Peer.prefixList(s3PrefixList.prefixListId), ec2.Port.tcp(443), 'to S3 (ECR image layers)');
96
+
97
+ const appEnv = ctxJson<Record<string, string>>(this, 'env', {});
98
+ const appSecrets = ctxJson<Record<string, string>>(this, 'secrets', {});
99
+ const actorSecrets = ctxJson<string[]>(this, 'actorSecrets', []);
100
+ const actorLambdas = ctxJson<string[]>(this, 'actorLambdas', []);
101
+
102
+ const endpoints: [string, ec2.InterfaceVpcEndpointAwsService][] = [
103
+ ['EcrApi', ec2.InterfaceVpcEndpointAwsService.ECR],
104
+ ['EcrDkr', ec2.InterfaceVpcEndpointAwsService.ECR_DOCKER],
105
+ ['Logs', ec2.InterfaceVpcEndpointAwsService.CLOUDWATCH_LOGS],
106
+ ];
107
+ // With no internet path, a task reads its secrets at start through this endpoint.
108
+ if (Object.keys(appSecrets).length) endpoints.push(['SecretsManager', ec2.InterfaceVpcEndpointAwsService.SECRETS_MANAGER]);
109
+ for (const [cid, service] of endpoints) {
110
+ vpc.addInterfaceEndpoint(cid, { service, subnets: privateSubnets, securityGroups: [endpointSg], open: false, privateDnsEnabled: true });
111
+ }
112
+
113
+ // --- App: Fargate behind an internal ALB -----------------------------
114
+ // dockerfile: path relative to appDir (the build context); may be in a subfolder.
115
+ const dockerfile = ctxStr(this, 'dockerfile', 'Dockerfile');
116
+ const image = new ecrAssets.DockerImageAsset(this, 'Image', { directory: appDir, file: dockerfile, platform: ecrAssets.Platform.LINUX_AMD64 });
117
+ const appLogs = new logs.LogGroup(this, 'AppLogs', { retention: logs.RetentionDays.ONE_WEEK, removalPolicy: cdk.RemovalPolicy.DESTROY });
118
+ const cluster = new ecs.Cluster(this, 'Cluster', { vpc });
119
+ const task = new ecs.FargateTaskDefinition(this, 'Task', {
120
+ cpu: 256, memoryLimitMiB: 512,
121
+ runtimePlatform: { cpuArchitecture: ecs.CpuArchitecture.X86_64, operatingSystemFamily: ecs.OperatingSystemFamily.LINUX },
122
+ });
123
+ task.addContainer('app', {
124
+ image: ecs.ContainerImage.fromDockerImageAsset(image),
125
+ portMappings: [{ containerPort: port }],
126
+ environment: { ...appEnv, PORT: String(port) },
127
+ // Injected by ECS at task start; the execution role is granted read on exactly these secrets.
128
+ secrets: Object.fromEntries(Object.entries(appSecrets).map(([name, arn], i) => [name, ecs.Secret.fromSecretsManager(
129
+ isCompleteSecretArn(arn) ? secretsmanager.Secret.fromSecretCompleteArn(this, `AppSecret${i}`, arn) : secretsmanager.Secret.fromSecretPartialArn(this, `AppSecret${i}`, arn),
130
+ )])),
131
+ logging: ecs.LogDrivers.awsLogs({ logGroup: appLogs, streamPrefix: 'app' }),
132
+ });
133
+ const service = new ecs.FargateService(this, 'Service', {
134
+ cluster, taskDefinition: task, desiredCount: 1, minHealthyPercent: 100,
135
+ assignPublicIp: false, vpcSubnets: privateSubnets, securityGroups: [appSg], circuitBreaker: { rollback: true },
136
+ });
137
+
138
+ const alb = new elbv2.ApplicationLoadBalancer(this, 'Alb', {
139
+ vpc, internetFacing: false, vpcSubnets: privateSubnets, securityGroup: albSg, dropInvalidHeaderFields: true,
140
+ });
141
+ const listener = alb.addListener('Http', { port: ALB_PORT, protocol: elbv2.ApplicationProtocol.HTTP, open: false });
142
+ // Faster than the 5 x 30s default, so a new task turns healthy in ~20s; the
143
+ // command waits for a healthy target before starting the pentest.
144
+ const targetGroup = listener.addTargets('App', {
145
+ port, protocol: elbv2.ApplicationProtocol.HTTP, targets: [service],
146
+ healthCheck: { path: healthPath, interval: cdk.Duration.seconds(10), timeout: cdk.Duration.seconds(5), healthyThresholdCount: 2, unhealthyThresholdCount: 3 },
147
+ deregistrationDelay: cdk.Duration.seconds(10),
148
+ });
149
+
150
+ // --- Private hostname -------------------------------------------------
151
+ const zone = new route53.PrivateHostedZone(this, 'Zone', { zoneName, vpc });
152
+ new route53.ARecord(this, 'AppRecord', { zone, recordName: 'app', target: route53.RecordTarget.fromAlias(new targets.LoadBalancerTarget(alb)) });
153
+
154
+ // --- Source zip bucket and agent log group ---------------------------
155
+ const source = new s3.Bucket(this, 'Source', {
156
+ blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL, encryption: s3.BucketEncryption.S3_MANAGED,
157
+ enforceSSL: true, removalPolicy: cdk.RemovalPolicy.DESTROY, autoDeleteObjects: true,
158
+ });
159
+ const agentLogs = new logs.LogGroup(this, 'AgentLogs', { logGroupName, retention: logs.RetentionDays.ONE_WEEK, removalPolicy: cdk.RemovalPolicy.DESTROY });
160
+
161
+ // --- Pentest service role (scoped ENI permissions; spike-confirmed) ---
162
+ const subnetArns = vpc.isolatedSubnets.map((s) => this.formatArn({ service: 'ec2', resource: 'subnet', resourceName: s.subnetId }));
163
+ const agentSgArn = this.formatArn({ service: 'ec2', resource: 'security-group', resourceName: agentSg.securityGroupId });
164
+ const eniArn = this.formatArn({ service: 'ec2', resource: 'network-interface', resourceName: '*' });
165
+
166
+ const role = new iam.Role(this, 'ServiceRole', {
167
+ assumedBy: new iam.ServicePrincipal('securityagent.amazonaws.com', { conditions: { StringEquals: { 'aws:SourceAccount': this.account } } }),
168
+ description: 'prism-cli security pentest: Security Agent service role for one private VPC pentest',
169
+ });
170
+ role.addToPolicy(new iam.PolicyStatement({
171
+ sid: 'DescribeNetwork',
172
+ actions: ['ec2:DescribeDhcpOptions', 'ec2:DescribeNetworkInterfaces', 'ec2:DescribeNetworkInterfaceAttribute', 'ec2:DescribeSubnets', 'ec2:DescribeSecurityGroups', 'ec2:DescribeVpcs'],
173
+ resources: ['*'],
174
+ }));
175
+ role.addToPolicy(new iam.PolicyStatement({ sid: 'EniCreateScoped', actions: ['ec2:CreateNetworkInterface'], resources: [eniArn, agentSgArn, ...subnetArns] }));
176
+ role.addToPolicy(new iam.PolicyStatement({ sid: 'EniManageScoped', actions: ['ec2:ModifyNetworkInterfaceAttribute', 'ec2:DeleteNetworkInterface'], resources: [eniArn, agentSgArn], conditions: { StringEquals: { 'ec2:Vpc': vpc.vpcArn } } }));
177
+ role.addToPolicy(new iam.PolicyStatement({ sid: 'EniPermission', actions: ['ec2:CreateNetworkInterfacePermission'], resources: [eniArn], conditions: { ArnEquals: { 'ec2:Subnet': subnetArns } } }));
178
+ // Logs: create/describe the configured group (spike: PREFLIGHT fails CLIENT_ERROR without CreateLogGroup on the group ARN).
179
+ role.addToPolicy(new iam.PolicyStatement({ sid: 'LogsGroup', actions: ['logs:CreateLogGroup', 'logs:CreateLogStream', 'logs:PutLogEvents', 'logs:DescribeLogStreams'], resources: [
180
+ // logGroupArn already ends in ':*', which does NOT match the bare group ARN
181
+ // CreateLogGroup is authorized against (the spike's second PREFLIGHT failure).
182
+ this.formatArn({ service: 'logs', resource: 'log-group', resourceName: logGroupName, arnFormat: cdk.ArnFormat.COLON_RESOURCE_NAME }),
183
+ agentLogs.logGroupArn,
184
+ ] }));
185
+ role.addToPolicy(new iam.PolicyStatement({ sid: 'LogsDescribe', actions: ['logs:DescribeLogGroups'], resources: ['*'] }));
186
+ source.grantRead(role);
187
+ // Test actors (.prism/pentest.json "actors"): the agent reads their credentials with this role.
188
+ actorSecrets.forEach((arn, i) => (isCompleteSecretArn(arn)
189
+ ? secretsmanager.Secret.fromSecretCompleteArn(this, `ActorSecret${i}`, arn)
190
+ : secretsmanager.Secret.fromSecretPartialArn(this, `ActorSecret${i}`, arn)).grantRead(role));
191
+ if (actorLambdas.length) role.addToPolicy(new iam.PolicyStatement({ sid: 'ActorCredentials', actions: ['lambda:InvokeFunction'], resources: actorLambdas }));
192
+
193
+ const out = (oid: string, value: string) => new cdk.CfnOutput(this, oid, { value });
194
+ out('VpcArn', vpc.vpcArn);
195
+ out('SubnetArns', cdk.Fn.join(',', subnetArns));
196
+ out('AgentSecurityGroupArn', agentSgArn);
197
+ out('AlbDnsName', alb.loadBalancerDnsName);
198
+ out('PrivateHost', `app.${zoneName}`);
199
+ out('ServiceRoleArn', role.roleArn);
200
+ out('SourceBucket', source.bucketName);
201
+ out('AgentLogGroup', agentLogs.logGroupName);
202
+ out('TargetGroupArn', targetGroup.targetGroupArn);
203
+ out('AppLogGroup', appLogs.logGroupName);
204
+ out('ExpiresAt', new Date(Date.now() + ttlHours * 3_600_000).toISOString());
205
+ }
206
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "prism-pentest-target-cdk",
3
+ "version": "1.0.0",
4
+ "private": true,
5
+ "scripts": {
6
+ "cdk": "cdk"
7
+ },
8
+ "dependencies": {
9
+ "aws-cdk-lib": "^2.265.0",
10
+ "constructs": "^10.4.2"
11
+ },
12
+ "devDependencies": {
13
+ "@types/node": "^20.17.0",
14
+ "aws-cdk": "^2.1000.0",
15
+ "ts-node": "^10.9.2",
16
+ "typescript": "~5.6.0"
17
+ }
18
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "commonjs",
5
+ "moduleResolution": "node",
6
+ "strict": true,
7
+ "esModuleInterop": true,
8
+ "skipLibCheck": true,
9
+ "noEmit": true
10
+ },
11
+ "include": ["bin/**/*.ts", "lib/**/*.ts"]
12
+ }
@@ -12,17 +12,127 @@ export interface Finding {
12
12
  file: string;
13
13
  line: number | null;
14
14
  message: string;
15
+ /** security-review / security-pentest: the Security Agent risk level (CRITICAL ... UNKNOWN), finding title, CWE and id. */
16
+ risk_level?: string;
17
+ title?: string;
18
+ cwe?: string | null;
19
+ finding_id?: string;
20
+ /** security-review only: the path exactly as the service reported it (file is repo-relative). */
21
+ raw_file?: string;
22
+ /** security-threat-model only: the threat's id, STRIDE categories, mitigation and every evidence path (repo-relative). */
23
+ threat_id?: string;
24
+ stride?: string[];
25
+ recommendation?: string;
26
+ evidence?: string[];
27
+ /** security-pentest only: the agent's confidence (HIGH | MEDIUM | LOW | FALSE_POSITIVE). */
28
+ confidence?: string;
29
+ }
30
+ /**
31
+ * `secrets` = gitleaks; `review` = the reviewer (kiro-cli / Claude Code);
32
+ * `security-review` = an AWS Security Agent code review job;
33
+ * `security-threat-model` = an AWS Security Agent threat model job;
34
+ * `security-pentest` = an AWS Security Agent penetration test job.
35
+ */
36
+ export type ResultKind = 'secrets' | 'review' | 'security-review' | 'security-threat-model' | 'security-pentest';
37
+ /** security-threat-model only: the job behind the result. */
38
+ export interface ThreatModelInfo {
39
+ job_id: string;
40
+ threat_model_id: string;
41
+ agent_space_id: string;
42
+ region: string;
43
+ account?: string;
44
+ job_status: string;
45
+ /** Threats per severity (CRITICAL ... INFO). */
46
+ counts: Record<string, number>;
47
+ /** Threats per STRIDE category. */
48
+ stride_counts: Record<string, number>;
49
+ /** Repo paths of the scope docs, as read from the commit. */
50
+ scope_docs: string[];
51
+ /** The agent's system overview, in full; null until the job completes. */
52
+ system_overview: string | null;
53
+ service_created_at?: string | null;
54
+ service_updated_at?: string | null;
55
+ }
56
+ /** security-review only: the job behind the result. */
57
+ export interface SecurityReviewInfo {
58
+ job_id: string;
59
+ code_review_id: string;
60
+ agent_space_id: string;
61
+ region: string;
62
+ /** The AWS account the job ran in, so `security findings` only completes its own account's pending records. */
63
+ account?: string;
64
+ /** diff: the branch diff base...tip. full: the whole repo at tip. unknown: fetched later by `security findings`. */
65
+ scope: 'diff' | 'full' | 'unknown';
66
+ /**
67
+ * The commit the code review's source asset (repo/<slug>/latest.zip) held
68
+ * when the job started: the code a diff job reads around the patch. null
69
+ * when unknown (a job `security findings` fetched with no pending record).
70
+ */
71
+ context_commit?: string | null;
72
+ job_status: string;
73
+ /** Findings per Security Agent risk level. */
74
+ counts: Record<string, number>;
75
+ /** The service's job timestamps, and updatedAt - createdAt (queue plus run time), when it reported them. */
76
+ service_created_at?: string | null;
77
+ service_updated_at?: string | null;
78
+ service_duration_s?: number | null;
79
+ /** Our wall time from starting the job to seeing it finish (code-review only; includes polling). */
80
+ wall_s?: number | null;
81
+ }
82
+ /**
83
+ * security-pentest only: the penetration-test job behind the result, and the
84
+ * temporary environment it ran against. Mirrors SecurityReviewInfo; a pentest
85
+ * finding has no file/line, carries a `confidence`, and the environment handle
86
+ * is what `security pentest --cleanup` tears down.
87
+ */
88
+ export interface PentestInfo {
89
+ job_id: string;
90
+ pentest_id: string;
91
+ agent_space_id: string;
92
+ /** True when this run created a dedicated agent space (teardown deletes it); false when it reused a shared one. */
93
+ agent_space_dedicated: boolean;
94
+ region: string;
95
+ /** The AWS account the job ran in, so findings only completes its own account's pending records. */
96
+ account?: string;
97
+ /** The verified target domain the pentest ran against (app.<zone>). */
98
+ target_host: string;
99
+ job_status: string;
100
+ /** Findings per Security Agent risk level, after dropping FALSE_POSITIVE confidence (unless --include-false-positives). */
101
+ counts: Record<string, number>;
102
+ /** First paragraph of the job's `overview` text, when the service reported one. */
103
+ overview?: string | null;
104
+ /** The CloudFormation stack and run slug of the temporary environment, for --cleanup. */
105
+ stack?: string | null;
106
+ slug?: string | null;
107
+ /** When the environment is set to auto-expire (the prism:expires-at tag), ISO. */
108
+ expires_at?: string | null;
109
+ /** The agent ENIs' security group id: teardown waits for its ENIs to drain before destroying the stack. */
110
+ agent_security_group_id?: string | null;
111
+ /** The app container's log group, for debugging hints. */
112
+ app_log_group?: string | null;
113
+ /** The PRIVATE_VPC target domain this run created; teardown deletes it. */
114
+ target_domain_id?: string | null;
115
+ /** Set when the last teardown left the stack up (destroy failed twice); --cleanup retries it. */
116
+ teardown_failed?: {
117
+ at: string;
118
+ reason: string;
119
+ } | null;
120
+ service_created_at?: string | null;
121
+ service_updated_at?: string | null;
122
+ service_duration_s?: number | null;
123
+ wall_s?: number | null;
15
124
  }
16
- /** `secrets` = gitleaks; `review` = the reviewer (kiro-cli / Claude Code). */
17
- export type ResultKind = 'secrets' | 'review';
18
125
  export type ResultHook = 'pre-commit' | 'pre-push' | 'ci' | 'manual';
19
126
  /**
20
127
  * ok ran, nothing found
21
128
  * findings ran, found something
22
129
  * error could not produce a verdict (tool missing, crashed, unparseable output)
23
130
  * skipped did not run: no changes to review, or the hook was bypassed (`--no-verify`)
131
+ * pending security-review / security-pentest: the job was started and has no
132
+ * verdict yet. finished_at equals started_at until the record is
133
+ * completed in place.
24
134
  */
25
- export type ResultStatus = 'ok' | 'findings' | 'error' | 'skipped';
135
+ export type ResultStatus = 'ok' | 'findings' | 'error' | 'skipped' | 'pending';
26
136
  export interface PrismResult {
27
137
  schema_version: typeof RESULT_SCHEMA_VERSION;
28
138
  kind: ResultKind;
@@ -55,6 +165,12 @@ export interface PrismResult {
55
165
  * consumers (the dashboard, CI) match on exactly: see REASON_*.
56
166
  */
57
167
  reason: string | null;
168
+ /** Present on kind security-review. */
169
+ security?: SecurityReviewInfo;
170
+ /** Present on kind security-threat-model. */
171
+ threat_model?: ThreatModelInfo;
172
+ /** Present on kind security-pentest. */
173
+ pentest?: PentestInfo;
58
174
  }
59
175
  export type ResultInit = Omit<PrismResult, 'schema_version' | 'tool_version' | 'model' | 'commit' | 'tree' | 'branch' | 'upstream' | 'base' | 'summary' | 'score' | 'reason' | 'findings'> & Partial<Pick<PrismResult, 'tool_version' | 'model' | 'commit' | 'tree' | 'branch' | 'upstream' | 'base' | 'summary' | 'score' | 'reason' | 'findings'>>;
60
176
  export declare function makeResult(init: ResultInit): PrismResult;
@@ -76,7 +192,11 @@ export declare function resultFileName(r: PrismResult): string;
76
192
  * clean without touching any tracked file. Outside a git repo it does nothing.
77
193
  */
78
194
  export declare function ensureResultsExcluded(repoRoot: string): boolean;
79
- export declare function writeResult(repoRoot: string, r: PrismResult): string;
195
+ /**
196
+ * `id` (a ResultEntry id) rewrites that existing file in place instead of
197
+ * naming a new one: how a pending security-review record is completed.
198
+ */
199
+ export declare function writeResult(repoRoot: string, r: PrismResult, id?: string): string;
80
200
  export interface ResultEntry {
81
201
  /** File name without `.json`: the result's stable id (used by report links). */
82
202
  id: string;
@@ -1 +1 @@
1
- {"version":3,"file":"results.d.ts","sourceRoot":"","sources":["../../../src/codewatch/results.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,qBAAqB,IAAI,CAAC;AACvC,eAAO,MAAM,WAAW,mBAAmB,CAAC;AAE5C,8FAA8F;AAC9F,eAAO,MAAM,uBAAuB,qBAAqB,CAAC;AAE1D,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;AACjD,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,UAAU,CAAC;AAErD,MAAM,WAAW,OAAO;IACtB,QAAQ,EAAE,QAAQ,CAAC;IACnB,QAAQ,EAAE,eAAe,CAAC;IAC1B,iFAAiF;IACjF,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,8EAA8E;AAC9E,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,QAAQ,CAAC;AAC9C,MAAM,MAAM,UAAU,GAAG,YAAY,GAAG,UAAU,GAAG,IAAI,GAAG,QAAQ,CAAC;AACrE;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,UAAU,GAAG,OAAO,GAAG,SAAS,CAAC;AAEnE,MAAM,WAAW,WAAW;IAC1B,cAAc,EAAE,OAAO,qBAAqB,CAAC;IAC7C,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,UAAU,CAAC;IACjB,MAAM,EAAE,YAAY,CAAC;IACrB,+EAA+E;IAC/E,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,gGAAgG;IAChG,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,iFAAiF;IACjF,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB;;;;OAIG;IACH,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,oDAAoD;IACpD,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB;;;OAGG;IACH,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,MAAM,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,EAAE,gBAAgB,GAAG,cAAc,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,UAAU,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,QAAQ,GAAG,UAAU,CAAC,GACtL,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,UAAU,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,QAAQ,GAAG,UAAU,CAAC,CAAC,CAAC;AAE5J,wBAAgB,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,WAAW,CAgBxD;AAOD,qDAAqD;AACrD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,WAAW,GAAG,MAAM,CAGrD;AAED;;;GAGG;AACH;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAS/D;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC,EAAE,WAAW,GAAG,MAAM,CAWpE;AAED,MAAM,WAAW,WAAW;IAC1B,gFAAgF;IAChF,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,iGAAiG;AACjG,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,EAAE,CAgBjE;AAED,mFAAmF;AACnF,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,EAAE,CAE3D;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAI7E"}
1
+ {"version":3,"file":"results.d.ts","sourceRoot":"","sources":["../../../src/codewatch/results.ts"],"names":[],"mappings":"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"}
@@ -72,7 +72,13 @@ export function ensureResultsExcluded(repoRoot) {
72
72
  appendFileSync(p.stdout, `${prefix}# prism-cli codewatch results (local)\n/${RESULTS_DIR}/\n`);
73
73
  return true;
74
74
  }
75
- export function writeResult(repoRoot, r) {
75
+ /**
76
+ * `id` (a ResultEntry id) rewrites that existing file in place instead of
77
+ * naming a new one: how a pending security-review record is completed.
78
+ */
79
+ export function writeResult(repoRoot, r, id) {
80
+ if (id !== undefined && !/^[A-Za-z0-9_-]{1,200}$/.test(id))
81
+ throw new Error(`invalid result id: ${id}`);
76
82
  const dir = resolve(repoRoot, RESULTS_DIR);
77
83
  if (!fileExists(dir)) {
78
84
  try {
@@ -81,7 +87,7 @@ export function writeResult(repoRoot, r) {
81
87
  catch { /* never fail a write over this */ }
82
88
  }
83
89
  mkdirSync(dir, { recursive: true });
84
- const dest = join(dir, resultFileName(r));
90
+ const dest = join(dir, id !== undefined ? `${id}.json` : resultFileName(r));
85
91
  const tmp = `${dest}.${process.pid}.tmp`;
86
92
  writeFileSync(tmp, JSON.stringify(r, null, 2) + '\n', { mode: 0o600 });
87
93
  renameSync(tmp, dest);
@@ -1 +1 @@
1
- {"version":3,"file":"results.js","sourceRoot":"","sources":["../../../src/codewatch/results.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"results.js","sourceRoot":"","sources":["../../../src/codewatch/results.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ export declare const PACKAGE_NAME = "@prism-d1/cli";
2
+ export interface Install {
3
+ /** The PATH entry. */
4
+ path: string;
5
+ /** Where it resolves after symlinks. */
6
+ realpath: string;
7
+ /** From the package.json next to it; null when it cannot be found. */
8
+ version: string | null;
9
+ /** True when it is this running CLI. */
10
+ isThis: boolean;
11
+ }
12
+ export interface VersionReport {
13
+ schema: 'prism.version.v1';
14
+ version: string;
15
+ node: string;
16
+ latest: string | null;
17
+ updateAvailable: boolean | null;
18
+ /** Why latest is null: 'offline', or the npm failure. */
19
+ latestNote: string | null;
20
+ onPath: Install[];
21
+ warnings: string[];
22
+ }
23
+ export interface VersionDeps {
24
+ /** The directory holding this CLI's package.json. */
25
+ ownPackageDir: string;
26
+ pathEnv: string;
27
+ /** `npm view @prism-d1/cli version`: the version, or an error message. */
28
+ npmLatest: () => {
29
+ version: string | null;
30
+ error?: string;
31
+ };
32
+ }
33
+ /** Walks up from `start` to the package.json of @prism-d1/cli, at most 6 levels. */
34
+ export declare function findPackageDir(start: string): string | null;
35
+ /** -1, 0 or 1, comparing dotted numeric versions; pre-release tags are ignored. */
36
+ export declare function compareVersions(a: string, b: string): number;
37
+ /**
38
+ * Every prism-cli on PATH, in PATH order, deduplicated by real path (e.g.
39
+ * /bin -> /usr/bin).
40
+ *
41
+ * shortcut: on Windows, npm's .cmd shims do not resolve to their package, so
42
+ * other installs there show version unknown; parse the shim if that matters.
43
+ */
44
+ export declare function installsOnPath(pathEnv: string, ownPackageDir: string): Install[];
45
+ export declare function buildReport(opts: {
46
+ offline?: boolean;
47
+ }, d: VersionDeps): VersionReport;
48
+ export declare function defaultDeps(): VersionDeps;
49
+ export declare function printReport(r: VersionReport, log?: (l: string) => void): void;
50
+ declare const _default: {
51
+ description: string;
52
+ options: {
53
+ flags: string;
54
+ description: string;
55
+ }[];
56
+ action(opts: {
57
+ json?: boolean;
58
+ offline?: boolean;
59
+ }): Promise<void>;
60
+ };
61
+ export default _default;
62
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../../../src/commands/_top/version.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,YAAY,kBAAkB,CAAC;AAK5C,MAAM,WAAW,OAAO;IACtB,sBAAsB;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,wCAAwC;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,sEAAsE;IACtE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,wCAAwC;IACxC,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,kBAAkB,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,eAAe,EAAE,OAAO,GAAG,IAAI,CAAC;IAChC,yDAAyD;IACzD,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,EAAE,OAAO,EAAE,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,qDAAqD;IACrD,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,0EAA0E;IAC1E,SAAS,EAAE,MAAM;QAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC7D;AAED,oFAAoF;AACpF,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAc3D;AAWD,mFAAmF;AACnF,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAK5D;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,EAAE,CAoBhF;AAMD,wBAAgB,WAAW,CAAC,IAAI,EAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,EAAE,CAAC,EAAE,WAAW,GAAG,aAAa,CA4BtF;AAeD,wBAAgB,WAAW,IAAI,WAAW,CAMzC;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,aAAa,EAAE,GAAG,GAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAkB,GAAG,IAAI,CAO1F;;;;;;;iBAQoB;QAAE,IAAI,CAAC,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE;;AAN1D,wBAWE"}