@prism-d1/cli 1.2.0 → 1.4.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.
- package/dist/assets/github-workflows/prism-eval-gate-kiro.yml +2 -2
- package/dist/assets/infra/bin/app.ts +61 -37
- package/dist/assets/infra/lib/constructs/security-agent-construct.ts +35 -30
- package/dist/assets/infra/lib/metrics-pipeline-stack.ts +2 -110
- package/dist/assets/infra/lib/security-agent-resources.ts +136 -0
- package/dist/assets/infra/lib/security-agent-stack.ts +69 -0
- package/dist/assets/pentest-cdk/bin/app.ts +12 -0
- package/dist/assets/pentest-cdk/cdk.json +7 -0
- package/dist/assets/pentest-cdk/lib/pentest-target-stack.ts +206 -0
- package/dist/assets/pentest-cdk/package.json +18 -0
- package/dist/assets/pentest-cdk/tsconfig.json +12 -0
- package/dist/src/aws/advice.d.ts +33 -0
- package/dist/src/aws/advice.d.ts.map +1 -0
- package/dist/src/aws/advice.js +174 -0
- package/dist/src/aws/advice.js.map +1 -0
- package/dist/src/aws/check.d.ts +64 -0
- package/dist/src/aws/check.d.ts.map +1 -0
- package/dist/src/aws/check.js +269 -0
- package/dist/src/aws/check.js.map +1 -0
- package/dist/src/aws/connect.d.ts +65 -0
- package/dist/src/aws/connect.d.ts.map +1 -0
- package/dist/src/aws/connect.js +250 -0
- package/dist/src/aws/connect.js.map +1 -0
- package/dist/src/aws/connection.d.ts +67 -0
- package/dist/src/aws/connection.d.ts.map +1 -0
- package/dist/src/aws/connection.js +137 -0
- package/dist/src/aws/connection.js.map +1 -0
- package/dist/src/aws/recommend.d.ts +70 -0
- package/dist/src/aws/recommend.d.ts.map +1 -0
- package/dist/src/aws/recommend.js +244 -0
- package/dist/src/aws/recommend.js.map +1 -0
- package/dist/src/aws/run-check.d.ts +31 -0
- package/dist/src/aws/run-check.d.ts.map +1 -0
- package/dist/src/aws/run-check.js +91 -0
- package/dist/src/aws/run-check.js.map +1 -0
- package/dist/src/codewatch/results.d.ts +155 -4
- package/dist/src/codewatch/results.d.ts.map +1 -1
- package/dist/src/codewatch/results.js +12 -2
- package/dist/src/codewatch/results.js.map +1 -1
- package/dist/src/commands/_top/version.d.ts +62 -0
- package/dist/src/commands/_top/version.d.ts.map +1 -0
- package/dist/src/commands/_top/version.js +175 -0
- package/dist/src/commands/_top/version.js.map +1 -0
- package/dist/src/commands/aws/check.d.ts +25 -0
- package/dist/src/commands/aws/check.d.ts.map +1 -0
- package/dist/src/commands/aws/check.js +42 -0
- package/dist/src/commands/aws/check.js.map +1 -0
- package/dist/src/commands/aws/connect.d.ts +16 -0
- package/dist/src/commands/aws/connect.d.ts.map +1 -0
- package/dist/src/commands/aws/connect.js +39 -0
- package/dist/src/commands/aws/connect.js.map +1 -0
- package/dist/src/commands/aws/recommend.d.ts +12 -0
- package/dist/src/commands/aws/recommend.d.ts.map +1 -0
- package/dist/src/commands/aws/recommend.js +21 -0
- package/dist/src/commands/aws/recommend.js.map +1 -0
- package/dist/src/commands/bedrock-protection/scan-account.d.ts.map +1 -1
- package/dist/src/commands/bedrock-protection/scan-account.js +14 -35
- package/dist/src/commands/bedrock-protection/scan-account.js.map +1 -1
- package/dist/src/commands/bedrock-protection/scan-org.d.ts.map +1 -1
- package/dist/src/commands/bedrock-protection/scan-org.js +12 -5
- package/dist/src/commands/bedrock-protection/scan-org.js.map +1 -1
- package/dist/src/commands/bootstrapper/setup-otel-sync.d.ts +12 -6
- package/dist/src/commands/bootstrapper/setup-otel-sync.d.ts.map +1 -1
- package/dist/src/commands/bootstrapper/setup-otel-sync.js +18 -409
- package/dist/src/commands/bootstrapper/setup-otel-sync.js.map +1 -1
- package/dist/src/commands/enable/codeburn.d.ts +59 -0
- package/dist/src/commands/enable/codeburn.d.ts.map +1 -0
- package/dist/src/commands/enable/codeburn.js +531 -0
- package/dist/src/commands/enable/codeburn.js.map +1 -0
- package/dist/src/commands/enable/security.d.ts +41 -0
- package/dist/src/commands/enable/security.d.ts.map +1 -0
- package/dist/src/commands/enable/security.js +128 -0
- package/dist/src/commands/enable/security.js.map +1 -0
- package/dist/src/commands/export/otel.d.ts +31 -0
- package/dist/src/commands/export/otel.d.ts.map +1 -0
- package/dist/src/commands/export/otel.js +52 -0
- package/dist/src/commands/export/otel.js.map +1 -0
- package/dist/src/commands/security/code-review.d.ts +22 -0
- package/dist/src/commands/security/code-review.d.ts.map +1 -0
- package/dist/src/commands/security/code-review.js +44 -0
- package/dist/src/commands/security/code-review.js.map +1 -0
- package/dist/src/commands/security/findings.d.ts +15 -0
- package/dist/src/commands/security/findings.d.ts.map +1 -0
- package/dist/src/commands/security/findings.js +33 -0
- package/dist/src/commands/security/findings.js.map +1 -0
- package/dist/src/commands/security/pentest.d.ts +18 -0
- package/dist/src/commands/security/pentest.d.ts.map +1 -0
- package/dist/src/commands/security/pentest.js +33 -0
- package/dist/src/commands/security/pentest.js.map +1 -0
- package/dist/src/commands/security/threat-model.d.ts +16 -0
- package/dist/src/commands/security/threat-model.d.ts.map +1 -0
- package/dist/src/commands/security/threat-model.js +25 -0
- package/dist/src/commands/security/threat-model.js.map +1 -0
- package/dist/src/commands/security/threats.d.ts +12 -0
- package/dist/src/commands/security/threats.d.ts.map +1 -0
- package/dist/src/commands/security/threats.js +24 -0
- package/dist/src/commands/security/threats.js.map +1 -0
- package/dist/src/commands/securityagent/setup.d.ts +19 -5
- package/dist/src/commands/securityagent/setup.d.ts.map +1 -1
- package/dist/src/commands/securityagent/setup.js +25 -189
- package/dist/src/commands/securityagent/setup.js.map +1 -1
- package/dist/src/dashboard/aws.d.ts +39 -0
- package/dist/src/dashboard/aws.d.ts.map +1 -0
- package/dist/src/dashboard/aws.js +35 -0
- package/dist/src/dashboard/aws.js.map +1 -0
- package/dist/src/dashboard/codewatch.d.ts.map +1 -1
- package/dist/src/dashboard/codewatch.js +2 -1
- package/dist/src/dashboard/codewatch.js.map +1 -1
- package/dist/src/dashboard/page.d.ts.map +1 -1
- package/dist/src/dashboard/page.js +193 -5
- package/dist/src/dashboard/page.js.map +1 -1
- package/dist/src/dashboard/payload.d.ts +11 -5
- package/dist/src/dashboard/payload.d.ts.map +1 -1
- package/dist/src/dashboard/payload.js +7 -2
- package/dist/src/dashboard/payload.js.map +1 -1
- package/dist/src/dashboard/security.d.ts +130 -0
- package/dist/src/dashboard/security.d.ts.map +1 -0
- package/dist/src/dashboard/security.js +144 -0
- package/dist/src/dashboard/security.js.map +1 -0
- package/dist/src/dashboard/setup.d.ts +15 -0
- package/dist/src/dashboard/setup.d.ts.map +1 -1
- package/dist/src/dashboard/setup.js +20 -3
- package/dist/src/dashboard/setup.js.map +1 -1
- package/dist/src/dashboard/usage.js +1 -1
- package/dist/src/dashboard/usage.js.map +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +9 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/security/cfn-diff.d.ts +57 -0
- package/dist/src/security/cfn-diff.d.ts.map +1 -0
- package/dist/src/security/cfn-diff.js +112 -0
- package/dist/src/security/cfn-diff.js.map +1 -0
- package/dist/src/security/errors.d.ts +45 -0
- package/dist/src/security/errors.d.ts.map +1 -0
- package/dist/src/security/errors.js +116 -0
- package/dist/src/security/errors.js.map +1 -0
- package/dist/src/security/marker.d.ts +46 -0
- package/dist/src/security/marker.d.ts.map +1 -0
- package/dist/src/security/marker.js +120 -0
- package/dist/src/security/marker.js.map +1 -0
- package/dist/src/security/pentest-dockerfile.d.ts +8 -0
- package/dist/src/security/pentest-dockerfile.d.ts.map +1 -0
- package/dist/src/security/pentest-dockerfile.js +163 -0
- package/dist/src/security/pentest-dockerfile.js.map +1 -0
- package/dist/src/security/pentest.d.ts +233 -0
- package/dist/src/security/pentest.d.ts.map +1 -0
- package/dist/src/security/pentest.js +1057 -0
- package/dist/src/security/pentest.js.map +1 -0
- package/dist/src/security/repo.d.ts +25 -0
- package/dist/src/security/repo.d.ts.map +1 -0
- package/dist/src/security/repo.js +38 -0
- package/dist/src/security/repo.js.map +1 -0
- package/dist/src/security/review.d.ts +202 -0
- package/dist/src/security/review.d.ts.map +1 -0
- package/dist/src/security/review.js +706 -0
- package/dist/src/security/review.js.map +1 -0
- package/dist/src/security/setup.d.ts +209 -0
- package/dist/src/security/setup.d.ts.map +1 -0
- package/dist/src/security/setup.js +742 -0
- package/dist/src/security/setup.js.map +1 -0
- package/dist/src/security/threat-model.d.ts +133 -0
- package/dist/src/security/threat-model.d.ts.map +1 -0
- package/dist/src/security/threat-model.js +653 -0
- package/dist/src/security/threat-model.js.map +1 -0
- package/dist/src/utils/audit-account.d.ts +50 -0
- package/dist/src/utils/audit-account.d.ts.map +1 -0
- package/dist/src/utils/audit-account.js +69 -0
- package/dist/src/utils/audit-account.js.map +1 -0
- package/dist/src/utils/audit-iam.d.ts +1 -1
- package/dist/src/utils/audit-iam.d.ts.map +1 -1
- package/dist/src/utils/audit-iam.js +11 -7
- package/dist/src/utils/audit-iam.js.map +1 -1
- package/dist/src/utils/exec.d.ts +6 -0
- package/dist/src/utils/exec.d.ts.map +1 -1
- package/dist/src/utils/exec.js +12 -1
- package/dist/src/utils/exec.js.map +1 -1
- package/dist/src/utils/otel-sync-schedule.d.ts +19 -0
- package/dist/src/utils/otel-sync-schedule.d.ts.map +1 -1
- package/dist/src/utils/otel-sync-schedule.js +24 -2
- package/dist/src/utils/otel-sync-schedule.js.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/security/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,6GAA6G;AAC7G,eAAO,MAAM,WAAW,kBAAmB,CAAC;AAC5C,eAAO,MAAM,gBAAgB,QAA8B,CAAC;AAE5D,eAAO,MAAM,sBAAsB,0DAA0D,CAAC;AAM9F,qFAAqF;AACrF,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAK3C;AAUD,qFAAqF;AACrF,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAIpD;AAED,MAAM,MAAM,YAAY,GAAG,gBAAgB,GAAG,eAAe,GAAG,SAAS,GAAG,OAAO,CAAC;AAEpF,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,YAAY,CAAC;IACnB,2CAA2C;IAC3C,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,cAAc,CAyB1G;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,EAAE,CAqBlG;AAED,+FAA+F;AAC/F,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAMhG"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Turns AWS CLI failures into messages a developer can act on.
|
|
3
|
+
*
|
|
4
|
+
* Three cases get their own wording because the raw CLI output does not say
|
|
5
|
+
* what to do: no usable credentials, an AWS CLI too old to know the
|
|
6
|
+
* `securityagent` commands, and an AccessDenied (which API, and which IAM
|
|
7
|
+
* action it needed). Everything printed goes through redact() first, so a
|
|
8
|
+
* credential that ends up in an error string is never echoed.
|
|
9
|
+
*/
|
|
10
|
+
/** First AWS CLI release with the Security Agent code review commands (matches the CI eval gate's check). */
|
|
11
|
+
export const MIN_AWS_CLI = [2, 36];
|
|
12
|
+
export const MIN_AWS_CLI_TEXT = `v${MIN_AWS_CLI.join('.')}`;
|
|
13
|
+
export const NO_CREDENTIALS_MESSAGE = 'Failed to get account ID. Check your AWS credentials.';
|
|
14
|
+
const CREDENTIAL_ERRORS = /Unable to locate credentials|could not be found|ExpiredToken|InvalidClientTokenId|SignatureDoesNotMatch|Token has expired|The SSO session|NoCredentialProviders|Error loading SSO Token|security token included in the request is (invalid|expired)/i;
|
|
15
|
+
const ACCESS_DENIED = /AccessDenied|UnauthorizedOperation|not authorized to perform|UnauthorizedException/i;
|
|
16
|
+
const UNKNOWN_COMMAND = /invalid choice/i;
|
|
17
|
+
/** Removes anything shaped like an AWS credential from text before it is printed. */
|
|
18
|
+
export function redact(text) {
|
|
19
|
+
return text
|
|
20
|
+
.replace(/\b(AKIA|ASIA)[A-Z0-9]{16}\b/g, '[redacted access key]')
|
|
21
|
+
.replace(/(aws_secret_access_key|aws_session_token|SecretAccessKey|SessionToken)(["']?\s*[:=]\s*["']?)[^\s"',}]+/gi, '$1$2[redacted]')
|
|
22
|
+
.replace(/(X-Amz-Security-Token|X-Amz-Signature|X-Amz-Credential)=[^&\s"']+/gi, '$1=[redacted]');
|
|
23
|
+
}
|
|
24
|
+
/** `list-agent-spaces` -> `ListAgentSpaces`. */
|
|
25
|
+
function pascal(cmd) {
|
|
26
|
+
return cmd.split('-').map((p) => p.charAt(0).toUpperCase() + p.slice(1)).join('');
|
|
27
|
+
}
|
|
28
|
+
const SERVICE_PREFIX = { s3api: 's3', s3: 's3' };
|
|
29
|
+
const S3_ACTIONS = { 'head-object': 's3:GetObject', 'put-object': 's3:PutObject', cp: 's3:PutObject' };
|
|
30
|
+
/** The IAM action an `aws <service> <command>` call needs, derived from the argv. */
|
|
31
|
+
export function permissionFor(args) {
|
|
32
|
+
const [service = '', command = ''] = args;
|
|
33
|
+
if (service === 's3api' || service === 's3')
|
|
34
|
+
return S3_ACTIONS[command] ?? `s3:${pascal(command)}`;
|
|
35
|
+
return `${SERVICE_PREFIX[service] ?? service}:${pascal(command)}`;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Explains a failed `aws` call. `args` is the argv that failed (without
|
|
39
|
+
* --region/--profile), `stderr` what the CLI printed, `cliVersion` the
|
|
40
|
+
* `aws --version` output when known.
|
|
41
|
+
*/
|
|
42
|
+
export function explainAwsError(args, stderr, cliVersion) {
|
|
43
|
+
const raw = redact((stderr || '').trim());
|
|
44
|
+
const lastLine = raw.split('\n').map((l) => l.trim()).filter(Boolean).pop() || 'unknown error';
|
|
45
|
+
if (UNKNOWN_COMMAND.test(raw)) {
|
|
46
|
+
return {
|
|
47
|
+
kind: 'old-cli',
|
|
48
|
+
message: `This AWS CLI does not have "aws ${args.slice(0, 2).join(' ')}". prism-cli enable security needs AWS CLI ${MIN_AWS_CLI_TEXT} or later`
|
|
49
|
+
+ `${cliVersion ? ` (found ${cliVersion.split(/\s+/)[0]})` : ''}. Install it from https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html`,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
if (CREDENTIAL_ERRORS.test(raw)) {
|
|
53
|
+
return {
|
|
54
|
+
kind: 'no-credentials',
|
|
55
|
+
message: `${NO_CREDENTIALS_MESSAGE}\n ${lastLine}\n Configure them with "aws configure" or "aws sso login", or pass --profile <name>.`,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
if (ACCESS_DENIED.test(raw)) {
|
|
59
|
+
const op = /when calling the (\w+) operation/.exec(raw)?.[1] ?? pascal(args[1] || '');
|
|
60
|
+
const action = /not authorized to perform:?\s+([\w-]+:[\w*]+)/.exec(raw)?.[1] ?? permissionFor(args);
|
|
61
|
+
return {
|
|
62
|
+
kind: 'access-denied',
|
|
63
|
+
message: `AccessDenied: ${op} (aws ${args.slice(0, 2).join(' ')}) was refused. The caller needs the IAM permission ${action}.\n ${lastLine}`,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
return { kind: 'other', message: `aws ${args.slice(0, 2).join(' ')} failed: ${lastLine}` };
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Lines for an error that is not one of ours (not an Abort): a failed npm or
|
|
70
|
+
* cdk run, a JSON parse, a git or file-system error. One redacted `Error:`
|
|
71
|
+
* line, at most one hint, and the redacted stack only with PRISM_DEBUG=1.
|
|
72
|
+
*
|
|
73
|
+
* Only `message`, `code`, `syscall` and `stack` are read. A child-process
|
|
74
|
+
* error also carries `cmd`, `spawnargs`, `envPairs`, `stdout` and `stderr`,
|
|
75
|
+
* which can hold full command lines and the environment; those are never read.
|
|
76
|
+
*/
|
|
77
|
+
export function describeUnexpectedError(e, env = process.env) {
|
|
78
|
+
const err = e instanceof Error ? e : new Error(String(e));
|
|
79
|
+
const extra = err;
|
|
80
|
+
const code = typeof extra.code === 'string' ? extra.code : '';
|
|
81
|
+
const syscall = typeof extra.syscall === 'string' ? extra.syscall : '';
|
|
82
|
+
const firstLine = redact(err.message || String(e)).split('\n').map((l) => l.trim()).find(Boolean) || 'unknown error';
|
|
83
|
+
const lines = [`Error: ${firstLine}`];
|
|
84
|
+
const msg = err.message || '';
|
|
85
|
+
let hint = '';
|
|
86
|
+
// Most specific first: a parse or fs error whose message merely contains a
|
|
87
|
+
// path like cdk.out/... or .git/... must not get the cdk or git hint.
|
|
88
|
+
const spawned = syscall.startsWith('spawn');
|
|
89
|
+
if (/Command failed: npm\b|\bnpm (ERR|error)\b/.test(msg))
|
|
90
|
+
hint = 'Installing the CDK app dependencies failed: check network access to the npm registry and that Node.js 22 is installed, then re-run.';
|
|
91
|
+
else if (err instanceof SyntaxError || /\bJSON\b/.test(msg))
|
|
92
|
+
hint = 'A CDK template or an AWS response was not valid JSON; re-run, and report it if it repeats.';
|
|
93
|
+
else if (syscall && code && !spawned)
|
|
94
|
+
hint = `File system error (${code} during ${syscall}): check the path exists and is writable.`;
|
|
95
|
+
else if (/(^|[\s:'"])cdk\b(?![.-])/.test(msg))
|
|
96
|
+
hint = 'The CDK step failed: re-run with --dry-run to see the synth output, and check that the account is CDK-bootstrapped.';
|
|
97
|
+
else if (/(^|[\s:'"])git\b(?![.-])/.test(msg))
|
|
98
|
+
hint = 'A git command failed: run prism-cli enable security from inside the repository.';
|
|
99
|
+
else if (syscall && code)
|
|
100
|
+
hint = `Could not start a program (${code} during ${syscall}): check it is installed and on PATH.`;
|
|
101
|
+
if (hint)
|
|
102
|
+
lines.push(` ${hint}`);
|
|
103
|
+
if (env.PRISM_DEBUG === '1' && err.stack)
|
|
104
|
+
lines.push(redact(err.stack));
|
|
105
|
+
return lines;
|
|
106
|
+
}
|
|
107
|
+
/** Parses `aws --version` ("aws-cli/2.36.19 Python/...") and checks it against MIN_AWS_CLI. */
|
|
108
|
+
export function cliVersionOk(versionText) {
|
|
109
|
+
const m = /aws-cli\/(\d+)\.(\d+)\.(\d+)/.exec(versionText || '');
|
|
110
|
+
if (!m)
|
|
111
|
+
return { ok: true, version: null }; // unknown: let the first securityagent call decide
|
|
112
|
+
const [maj, min] = [Number(m[1]), Number(m[2])];
|
|
113
|
+
const ok = maj > MIN_AWS_CLI[0] || (maj === MIN_AWS_CLI[0] && min >= MIN_AWS_CLI[1]);
|
|
114
|
+
return { ok, version: `${m[1]}.${m[2]}.${m[3]}` };
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/security/errors.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { RunResult } from '../utils/exec.js';
|
|
2
|
+
export declare const MARKER_PATH = ".prism/security.local.json";
|
|
3
|
+
export interface SecurityMarker {
|
|
4
|
+
agentSpaceId: string;
|
|
5
|
+
applicationId: string;
|
|
6
|
+
codeReviewId: string;
|
|
7
|
+
region: string;
|
|
8
|
+
account: string;
|
|
9
|
+
setupAt: string;
|
|
10
|
+
}
|
|
11
|
+
/** Only `.prism/security.local.json`, never the legacy config.json block. */
|
|
12
|
+
export declare function readLocalMarker(repoRoot: string): SecurityMarker | null;
|
|
13
|
+
/** The marker and where it came from: the local file first, else the legacy `security` block. */
|
|
14
|
+
export declare function readSecurityMarkerWithSource(repoRoot: string): {
|
|
15
|
+
marker: SecurityMarker;
|
|
16
|
+
source: 'local' | 'legacy';
|
|
17
|
+
} | null;
|
|
18
|
+
/** The marker, or null when it is absent or incomplete. */
|
|
19
|
+
export declare function readSecurityMarker(repoRoot: string): SecurityMarker | null;
|
|
20
|
+
/**
|
|
21
|
+
* Removes only the `security` key from `.prism/config.json`, keeping every
|
|
22
|
+
* other key, its order, the indent and the trailing newline. Returns true when
|
|
23
|
+
* the key was there.
|
|
24
|
+
*/
|
|
25
|
+
export declare function removeLegacyBlock(repoRoot: string): boolean;
|
|
26
|
+
export interface MarkerWrite {
|
|
27
|
+
path: string;
|
|
28
|
+
/** False when the file already held the same ids (setupAt is then kept). */
|
|
29
|
+
wrote: boolean;
|
|
30
|
+
/** A legacy `security` block was removed from `.prism/config.json`. */
|
|
31
|
+
migrated: boolean;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Writes `.prism/security.local.json`. setupAt is kept when nothing else
|
|
35
|
+
* changed, so a re-run that changes nothing leaves the file as it was. A
|
|
36
|
+
* legacy block in `.prism/config.json` is removed after the new file is written.
|
|
37
|
+
*/
|
|
38
|
+
export declare function writeSecurityMarker(repoRoot: string, m: Omit<SecurityMarker, 'setupAt'>, now: Date): MarkerWrite;
|
|
39
|
+
/**
|
|
40
|
+
* Makes sure git ignores the marker in this clone, without touching the repo's
|
|
41
|
+
* .gitignore: when `git check-ignore` says it is not ignored, the path is added
|
|
42
|
+
* to `info/exclude` (resolved with `git rev-parse --git-path`, so linked
|
|
43
|
+
* worktrees use the right file). Returns the exclude file when it was changed.
|
|
44
|
+
*/
|
|
45
|
+
export declare function ensureMarkerIgnored(repoRoot: string, git: (args: string[]) => RunResult, path?: string, by?: string): string | null;
|
|
46
|
+
//# sourceMappingURL=marker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"marker.d.ts","sourceRoot":"","sources":["../../../src/security/marker.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAGlD,eAAO,MAAM,WAAW,+BAA+B,CAAC;AAExD,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAcD,6EAA6E;AAC7E,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAEvE;AAMD,iGAAiG;AACjG,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,cAAc,CAAC;IAAC,MAAM,EAAE,OAAO,GAAG,QAAQ,CAAA;CAAE,GAAG,IAAI,CAK5H;AAED,2DAA2D;AAC3D,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAE1E;AAQD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAS3D;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,KAAK,EAAE,OAAO,CAAC;IACf,uEAAuE;IACvE,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,CAAC,cAAc,EAAE,SAAS,CAAC,EAAE,GAAG,EAAE,IAAI,GAAG,WAAW,CAchH;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,SAAS,EAAE,IAAI,SAAc,EAAE,EAAE,SAA8B,GAAG,MAAM,GAAG,IAAI,CAU7J"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The local record that `prism-cli enable security` finished in this repo:
|
|
3
|
+
* `.prism/security.local.json`. Ids, account and region only, never a secret.
|
|
4
|
+
* It is per developer and never committed (`.prism/config.json` stays safe to
|
|
5
|
+
* commit for the team reviewer). The dashboard's Security Agent row reads it,
|
|
6
|
+
* so the dashboard stays credential-free.
|
|
7
|
+
*
|
|
8
|
+
* Earlier versions wrote the same block as `security` inside
|
|
9
|
+
* `.prism/config.json`. Readers fall back to it, and the next successful
|
|
10
|
+
* `enable security` run moves it here.
|
|
11
|
+
*/
|
|
12
|
+
import { appendFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
13
|
+
import { dirname, resolve } from 'node:path';
|
|
14
|
+
import { CONFIG_PATH, readPrismConfig } from '../codewatch/config.js';
|
|
15
|
+
export const MARKER_PATH = '.prism/security.local.json';
|
|
16
|
+
const REQUIRED = ['agentSpaceId', 'codeReviewId', 'region', 'account'];
|
|
17
|
+
function parseMarker(s) {
|
|
18
|
+
if (!s || typeof s !== 'object')
|
|
19
|
+
return null;
|
|
20
|
+
for (const k of REQUIRED)
|
|
21
|
+
if (typeof s[k] !== 'string' || !s[k])
|
|
22
|
+
return null;
|
|
23
|
+
return {
|
|
24
|
+
agentSpaceId: s.agentSpaceId, applicationId: typeof s.applicationId === 'string' ? s.applicationId : '',
|
|
25
|
+
codeReviewId: s.codeReviewId, region: s.region, account: s.account,
|
|
26
|
+
setupAt: typeof s.setupAt === 'string' ? s.setupAt : '',
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/** Only `.prism/security.local.json`, never the legacy config.json block. */
|
|
30
|
+
export function readLocalMarker(repoRoot) {
|
|
31
|
+
return readLocal(repoRoot);
|
|
32
|
+
}
|
|
33
|
+
function readLocal(repoRoot) {
|
|
34
|
+
try {
|
|
35
|
+
return parseMarker(JSON.parse(readFileSync(resolve(repoRoot, MARKER_PATH), 'utf8')));
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/** The marker and where it came from: the local file first, else the legacy `security` block. */
|
|
42
|
+
export function readSecurityMarkerWithSource(repoRoot) {
|
|
43
|
+
const local = readLocal(repoRoot);
|
|
44
|
+
if (local)
|
|
45
|
+
return { marker: local, source: 'local' };
|
|
46
|
+
const legacy = parseMarker(readPrismConfig(repoRoot).security);
|
|
47
|
+
return legacy ? { marker: legacy, source: 'legacy' } : null;
|
|
48
|
+
}
|
|
49
|
+
/** The marker, or null when it is absent or incomplete. */
|
|
50
|
+
export function readSecurityMarker(repoRoot) {
|
|
51
|
+
return readSecurityMarkerWithSource(repoRoot)?.marker ?? null;
|
|
52
|
+
}
|
|
53
|
+
/** The indent a JSON file uses (its first indented line), so a rewrite keeps the look. */
|
|
54
|
+
function detectIndent(text) {
|
|
55
|
+
const m = /\n([ \t]+)"/.exec(text);
|
|
56
|
+
return m ? m[1] : 2;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Removes only the `security` key from `.prism/config.json`, keeping every
|
|
60
|
+
* other key, its order, the indent and the trailing newline. Returns true when
|
|
61
|
+
* the key was there.
|
|
62
|
+
*/
|
|
63
|
+
export function removeLegacyBlock(repoRoot) {
|
|
64
|
+
const p = resolve(repoRoot, CONFIG_PATH);
|
|
65
|
+
let text;
|
|
66
|
+
let cfg;
|
|
67
|
+
try {
|
|
68
|
+
text = readFileSync(p, 'utf8');
|
|
69
|
+
cfg = JSON.parse(text);
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
if (!cfg || typeof cfg !== 'object' || Array.isArray(cfg) || !('security' in cfg))
|
|
75
|
+
return false;
|
|
76
|
+
delete cfg.security;
|
|
77
|
+
writeFileSync(p, JSON.stringify(cfg, null, detectIndent(text)) + (text.endsWith('\n') ? '\n' : ''));
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Writes `.prism/security.local.json`. setupAt is kept when nothing else
|
|
82
|
+
* changed, so a re-run that changes nothing leaves the file as it was. A
|
|
83
|
+
* legacy block in `.prism/config.json` is removed after the new file is written.
|
|
84
|
+
*/
|
|
85
|
+
export function writeSecurityMarker(repoRoot, m, now) {
|
|
86
|
+
const p = resolve(repoRoot, MARKER_PATH);
|
|
87
|
+
const prev = readSecurityMarkerWithSource(repoRoot);
|
|
88
|
+
const pm = prev?.marker;
|
|
89
|
+
const same = !!pm && pm.agentSpaceId === m.agentSpaceId && pm.applicationId === m.applicationId
|
|
90
|
+
&& pm.codeReviewId === m.codeReviewId && pm.region === m.region && pm.account === m.account && !!pm.setupAt;
|
|
91
|
+
let wrote = false;
|
|
92
|
+
if (!(same && prev.source === 'local')) {
|
|
93
|
+
mkdirSync(dirname(p), { recursive: true });
|
|
94
|
+
writeFileSync(p, JSON.stringify({ ...m, setupAt: same ? pm.setupAt : now.toISOString() }, null, 2) + '\n');
|
|
95
|
+
wrote = !same;
|
|
96
|
+
}
|
|
97
|
+
const migrated = removeLegacyBlock(repoRoot);
|
|
98
|
+
return { path: p, wrote, migrated };
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Makes sure git ignores the marker in this clone, without touching the repo's
|
|
102
|
+
* .gitignore: when `git check-ignore` says it is not ignored, the path is added
|
|
103
|
+
* to `info/exclude` (resolved with `git rev-parse --git-path`, so linked
|
|
104
|
+
* worktrees use the right file). Returns the exclude file when it was changed.
|
|
105
|
+
*/
|
|
106
|
+
export function ensureMarkerIgnored(repoRoot, git, path = MARKER_PATH, by = 'prism-cli enable security') {
|
|
107
|
+
if (git(['-C', repoRoot, 'check-ignore', '-q', path]).ok)
|
|
108
|
+
return null;
|
|
109
|
+
const r = git(['-C', repoRoot, 'rev-parse', '--path-format=absolute', '--git-path', 'info/exclude']);
|
|
110
|
+
if (!r.ok || !r.stdout)
|
|
111
|
+
return null;
|
|
112
|
+
const exclude = r.stdout.trim();
|
|
113
|
+
const text = existsSync(exclude) ? readFileSync(exclude, 'utf8') : '';
|
|
114
|
+
if (text.split('\n').some((l) => l.trim() === path || l.trim() === `/${path}`))
|
|
115
|
+
return null;
|
|
116
|
+
mkdirSync(dirname(exclude), { recursive: true });
|
|
117
|
+
appendFileSync(exclude, `${text && !text.endsWith('\n') ? '\n' : ''}# ${by}: per-developer record, never committed\n${path}\n`);
|
|
118
|
+
return exclude;
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=marker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"marker.js","sourceRoot":"","sources":["../../../src/security/marker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type RepoCtx } from './setup.js';
|
|
2
|
+
import type { PentestApp } from './pentest.js';
|
|
3
|
+
/** Short, CFN-safe run id from the repo name plus a base36 timestamp. */
|
|
4
|
+
export declare function runSlug(repo: RepoCtx, now: number): string;
|
|
5
|
+
export declare function dockerfileApp(opts: {
|
|
6
|
+
profile?: string;
|
|
7
|
+
}): PentestApp;
|
|
8
|
+
//# sourceMappingURL=pentest-dockerfile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pentest-dockerfile.d.ts","sourceRoot":"","sources":["../../../src/security/pentest-dockerfile.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAyB,KAAK,OAAO,EAAE,MAAM,YAAY,CAAC;AAGjE,OAAO,KAAK,EAAE,UAAU,EAAyC,MAAM,cAAc,CAAC;AAwBtF,yEAAyE;AACzE,wBAAgB,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAG1D;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,UAAU,CAkGpE"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `dockerfile` app-type adapter for `prism-cli security pentest`.
|
|
3
|
+
*
|
|
4
|
+
* Builds the app image from the repo's Dockerfile and runs it on Fargate behind
|
|
5
|
+
* an internal ALB in a fresh private VPC, by synth/deploy of the shipped CDK
|
|
6
|
+
* app in commands/security/pentest-cdk (generalized from the proven spike).
|
|
7
|
+
* `plan` synths + diffs (no writes); `apply` deploys, reads the stack outputs,
|
|
8
|
+
* and uploads the repo-at-HEAD source zip for white-box testing. Teardown is
|
|
9
|
+
* not here: pentest.ts deletes the recorded stack with CloudFormation.
|
|
10
|
+
*
|
|
11
|
+
* Everything AWS/cdk runs through child processes here, so this file is only
|
|
12
|
+
* exercised on the real command path; the orchestration in pentest.ts is tested
|
|
13
|
+
* against a fake adapter.
|
|
14
|
+
*/
|
|
15
|
+
import { execFileSync, spawnSync } from 'node:child_process';
|
|
16
|
+
import { existsSync, statSync } from 'node:fs';
|
|
17
|
+
import { join, relative, resolve, dirname } from 'node:path';
|
|
18
|
+
import { fileURLToPath } from 'node:url';
|
|
19
|
+
import { Abort, call } from './setup.js';
|
|
20
|
+
import { repoZipKey } from './repo.js';
|
|
21
|
+
import { getAssetPath } from '../utils/root.js';
|
|
22
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
23
|
+
const CDK_MAX_BUFFER = 64 * 1024 * 1024;
|
|
24
|
+
/** Hours until the environment's prism:expires-at tag; the env is disposable. */
|
|
25
|
+
const TTL_HOURS = 24;
|
|
26
|
+
/** The shipped CDK app dir: the built asset when present, else the source tree (dev/tsx). */
|
|
27
|
+
function assetDir() {
|
|
28
|
+
// Built: dist/assets/pentest-cdk, found the same way enable security finds
|
|
29
|
+
// its infra asset (walks up from this file). Dev/tsx: the source tree.
|
|
30
|
+
let built = null;
|
|
31
|
+
try {
|
|
32
|
+
built = getAssetPath(import.meta.url, 'pentest-cdk');
|
|
33
|
+
}
|
|
34
|
+
catch { /* not built */ }
|
|
35
|
+
const source = resolve(__dirname, '..', 'commands', 'security', 'pentest-cdk');
|
|
36
|
+
for (const d of [built, source])
|
|
37
|
+
if (d && existsSync(join(d, 'bin', 'app.ts')))
|
|
38
|
+
return d;
|
|
39
|
+
throw new Abort(`pentest CDK app not found (looked for dist/assets/pentest-cdk and ${source}); run npm run build`);
|
|
40
|
+
}
|
|
41
|
+
function cleanEnv(extra) {
|
|
42
|
+
const env = { ...process.env, ...extra };
|
|
43
|
+
for (const k of Object.keys(env))
|
|
44
|
+
if (k.startsWith('npm_'))
|
|
45
|
+
delete env[k];
|
|
46
|
+
return env;
|
|
47
|
+
}
|
|
48
|
+
/** Short, CFN-safe run id from the repo name plus a base36 timestamp. */
|
|
49
|
+
export function runSlug(repo, now) {
|
|
50
|
+
const name = (repo.id.split('/').pop() || 'app').toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '').slice(0, 24) || 'app';
|
|
51
|
+
return `${name}-${now.toString(36)}`;
|
|
52
|
+
}
|
|
53
|
+
export function dockerfileApp(opts) {
|
|
54
|
+
const dir = () => assetDir();
|
|
55
|
+
const profileArgs = opts.profile ? ['--profile', opts.profile] : [];
|
|
56
|
+
function ensureDeps(d) {
|
|
57
|
+
if (existsSync(join(d, 'node_modules', '.bin', 'cdk')))
|
|
58
|
+
return;
|
|
59
|
+
execFileSync('npm', ['install', '--no-audit', '--no-fund'], { cwd: d, stdio: 'inherit', env: cleanEnv({}) });
|
|
60
|
+
}
|
|
61
|
+
function cdkEnv(ctx) {
|
|
62
|
+
const acct = call(ctx, ['sts', 'get-caller-identity']).json?.Account;
|
|
63
|
+
return cleanEnv({ CDK_DEFAULT_ACCOUNT: String(acct || ''), CDK_DEFAULT_REGION: ctx.opts.region, AWS_DEFAULT_REGION: ctx.opts.region, AWS_REGION: ctx.opts.region, AWS_PAGER: '' });
|
|
64
|
+
}
|
|
65
|
+
const ctxArgs = (c) => Object.entries(c).flatMap(([k, v]) => ['-c', `${k}=${v}`]);
|
|
66
|
+
function context(repo, cfg, slug) {
|
|
67
|
+
const appDir = join(repo.root, cfg.path);
|
|
68
|
+
// DockerImageAsset takes the Dockerfile relative to the build context.
|
|
69
|
+
const dockerfile = relative(appDir, join(repo.root, cfg.dockerfile)) || 'Dockerfile';
|
|
70
|
+
const byType = (t) => cfg.actors.filter((a) => a.auth.providerType === t).map((a) => a.auth.value);
|
|
71
|
+
return {
|
|
72
|
+
slug, appDir, dockerfile, port: String(cfg.port), healthPath: cfg.healthPath, zoneName: `${slug}.prism.internal`, ttlHours: String(TTL_HOURS),
|
|
73
|
+
// JSON in context values: spawnSync passes argv without a shell, so no quoting is involved.
|
|
74
|
+
env: JSON.stringify(Object.fromEntries(cfg.env.map((e) => [e.name, e.value]))),
|
|
75
|
+
secrets: JSON.stringify(Object.fromEntries(cfg.secretEnv.map((e) => [e.name, e.secret]))),
|
|
76
|
+
actorSecrets: JSON.stringify(byType('SECRETS_MANAGER')),
|
|
77
|
+
actorLambdas: JSON.stringify(byType('AWS_LAMBDA')),
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
function plan(ctx, repo, cfg) {
|
|
81
|
+
const slug = runSlug(repo, ctx.deps.now().getTime());
|
|
82
|
+
const stack = `PrismPentest-${slug}`;
|
|
83
|
+
const host = `app.${slug}.prism.internal`;
|
|
84
|
+
const d = dir();
|
|
85
|
+
ensureDeps(d);
|
|
86
|
+
const env = cdkEnv(ctx);
|
|
87
|
+
const bin = join(d, 'node_modules', '.bin', 'cdk');
|
|
88
|
+
const ctxA = ctxArgs(context(repo, cfg, slug));
|
|
89
|
+
const synth = spawnSync(bin, ['synth', '--quiet', ...ctxA, ...profileArgs], { cwd: d, env, encoding: 'utf8', maxBuffer: CDK_MAX_BUFFER });
|
|
90
|
+
if (synth.status !== 0)
|
|
91
|
+
throw new Abort(`cdk synth of the pentest target failed:\n${(synth.stderr || '').split('\n').slice(-15).join('\n')}`);
|
|
92
|
+
const diff = spawnSync(bin, ['diff', stack, '--no-color', '--method=template', ...ctxA, ...profileArgs], { cwd: d, env, encoding: 'utf8', maxBuffer: CDK_MAX_BUFFER });
|
|
93
|
+
const diffText = `${diff.stdout || ''}${diff.stderr || ''}`.trim() || 'A private VPC (isolated subnets only), ECR/S3/Logs VPC endpoints, a Fargate service, an internal ALB, four security groups, a scoped service role, a source bucket and a log group.';
|
|
94
|
+
return { diffText, targetHost: host, stack, slug };
|
|
95
|
+
}
|
|
96
|
+
function apply(ctx, repo, cfg, p, approveAll) {
|
|
97
|
+
const d = dir();
|
|
98
|
+
ensureDeps(d);
|
|
99
|
+
const env = cdkEnv(ctx);
|
|
100
|
+
const bin = join(d, 'node_modules', '.bin', 'cdk');
|
|
101
|
+
const ctxA = ctxArgs(context(repo, cfg, p.slug));
|
|
102
|
+
const approval = approveAll ? ['--require-approval', 'never'] : [];
|
|
103
|
+
const deploy = spawnSync(bin, ['deploy', p.stack, ...approval, ...ctxA, ...profileArgs], { cwd: d, env, stdio: 'inherit' });
|
|
104
|
+
if (deploy.status !== 0)
|
|
105
|
+
throw new Abort(`cdk deploy of the pentest target (${p.stack}) failed; check the output above and CloudFormation.`);
|
|
106
|
+
const outputs = readStackOutputs(ctx, p.stack);
|
|
107
|
+
const subnetArns = (outputs.SubnetArns || '').split(',').filter(Boolean);
|
|
108
|
+
if (!outputs.VpcArn || !subnetArns.length || !outputs.AgentSecurityGroupArn || !outputs.ServiceRoleArn || !outputs.AgentLogGroup || !outputs.PrivateHost || !outputs.SourceBucket || !outputs.TargetGroupArn) {
|
|
109
|
+
throw new Abort(`the pentest stack ${p.stack} did not report the expected outputs; cannot configure the pentest.`);
|
|
110
|
+
}
|
|
111
|
+
const sourceZipS3 = uploadSourceZip(ctx, repo, outputs.SourceBucket);
|
|
112
|
+
return {
|
|
113
|
+
targetHost: outputs.PrivateHost, targetUrl: `http://${outputs.PrivateHost}`,
|
|
114
|
+
vpcArn: outputs.VpcArn, subnetArns, pentestSubnetArn: subnetArns[0],
|
|
115
|
+
agentSecurityGroupArn: outputs.AgentSecurityGroupArn, serviceRoleArn: outputs.ServiceRoleArn,
|
|
116
|
+
logGroup: outputs.AgentLogGroup, sourceZipS3, expiresAt: outputs.ExpiresAt || '',
|
|
117
|
+
stack: p.stack, slug: p.slug,
|
|
118
|
+
targetGroupArn: outputs.TargetGroupArn, appLogGroup: outputs.AppLogGroup || '',
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
function readStackOutputs(ctx, stack) {
|
|
122
|
+
const r = call(ctx, ['cloudformation', 'describe-stacks', '--stack-name', stack]);
|
|
123
|
+
const outs = r.json?.Stacks?.[0]?.Outputs || [];
|
|
124
|
+
const map = {};
|
|
125
|
+
for (const o of outs)
|
|
126
|
+
if (o?.OutputKey)
|
|
127
|
+
map[String(o.OutputKey)] = String(o.OutputValue ?? '');
|
|
128
|
+
return map;
|
|
129
|
+
}
|
|
130
|
+
function uploadSourceZip(ctx, repo, bucket) {
|
|
131
|
+
const dirTmp = ctx.deps.makeTempDir();
|
|
132
|
+
const zip = join(dirTmp, 'source.zip');
|
|
133
|
+
const archived = ctx.deps.git(['-C', repo.root, 'archive', 'HEAD', '--format=zip', '-o', zip]);
|
|
134
|
+
if (!archived.ok || !existsSync(zip)) {
|
|
135
|
+
ctx.deps.log('Warning: git archive HEAD failed; the pentest runs without white-box source.');
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
const key = repoZipKey(repo.slug);
|
|
139
|
+
call(ctx, ['s3api', 'put-object', '--bucket', bucket, '--key', key, '--body', zip]);
|
|
140
|
+
return `s3://${bucket}/${key}`;
|
|
141
|
+
}
|
|
142
|
+
return {
|
|
143
|
+
type: 'dockerfile',
|
|
144
|
+
detect: (appDir, dockerfile) => {
|
|
145
|
+
try {
|
|
146
|
+
if (!statSync(appDir).isDirectory())
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
const f = dockerfile ?? join(appDir, 'Dockerfile');
|
|
153
|
+
try {
|
|
154
|
+
return statSync(f).isFile();
|
|
155
|
+
}
|
|
156
|
+
catch {
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
plan, apply,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=pentest-dockerfile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pentest-dockerfile.js","sourceRoot":"","sources":["../../../src/security/pentest-dockerfile.ts"],"names":[],"mappings":"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"}
|