@prism-d1/cli 1.0.95 → 1.0.96

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.
@@ -1 +1 @@
1
- {"version":3,"file":"scan-account.d.ts","sourceRoot":"","sources":["../../../../src/commands/bedrock-protection/scan-account.ts"],"names":[],"mappings":"AAUA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;;;;;;;iBAckB;QACjB,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAC;QAC3E,OAAO,CAAC,EAAE,OAAO,CAAC;QAAC,WAAW,CAAC,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;KAC3E;;AAfH,wBA8EE"}
1
+ {"version":3,"file":"scan-account.d.ts","sourceRoot":"","sources":["../../../../src/commands/bedrock-protection/scan-account.ts"],"names":[],"mappings":"AAUA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;;;;;;;iBAckB;QACjB,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAC;QAC3E,OAAO,CAAC,EAAE,OAAO,CAAC;QAAC,WAAW,CAAC,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;KAC3E;;AAfH,wBAgFE"}
@@ -54,7 +54,9 @@ export default {
54
54
  throw new Error('--max-key-age must be a positive integer');
55
55
  if (!Number.isFinite(unusedDays) || unusedDays < 1)
56
56
  throw new Error('--unused-days must be a positive integer');
57
- const accountId = resolveAccount(opts.profile);
57
+ // One target for every check; scan-org supplies assumed-role creds instead.
58
+ const target = { profile: opts.profile };
59
+ const accountId = resolveAccount(target);
58
60
  if (!accountId) {
59
61
  process.exitCode = 2;
60
62
  return;
@@ -63,20 +65,20 @@ export default {
63
65
  const runBedrock = !opts.iamOnly;
64
66
  // auditBudgets returns the covering budget names so the alerting check can
65
67
  // scope its per-notification calls to them rather than every budget.
66
- const budgets = runBedrock ? auditBudgets(opts.profile, accountId) : null;
68
+ const budgets = runBedrock ? auditBudgets(target, accountId) : null;
67
69
  const findings = [
68
70
  ...(runIam ? [
69
- ...auditRoot(opts.profile),
70
- auditPasswordPolicy(opts.profile),
71
- ...auditUsers(opts.profile, maxKeyAge, unusedDays),
72
- auditUserPolicies(opts.profile),
71
+ ...auditRoot(target),
72
+ auditPasswordPolicy(target),
73
+ ...auditUsers(target, maxKeyAge, unusedDays),
74
+ auditUserPolicies(target),
73
75
  ] : []),
74
76
  ...(runBedrock && budgets ? [
75
77
  ...budgets.findings,
76
- auditBudgetAlerting(opts.profile, accountId, budgets.coveringBudgets),
77
- ...auditDetection(opts.profile, region),
78
- auditCommitments(opts.profile, region),
79
- auditForensics(opts.profile, region),
78
+ auditBudgetAlerting(target, accountId, budgets.coveringBudgets),
79
+ ...auditDetection(target, region),
80
+ auditCommitments(target, region),
81
+ auditForensics(target, region),
80
82
  ] : []),
81
83
  ];
82
84
  const scope = runIam && runBedrock ? '' : runIam ? ' Scope: IAM only' : ' Scope: Bedrock only';
@@ -1 +1 @@
1
- {"version":3,"file":"scan-account.js","sourceRoot":"","sources":["../../../../src/commands/bedrock-protection/scan-account.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scan-account.js","sourceRoot":"","sources":["../../../../src/commands/bedrock-protection/scan-account.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ declare const _default: {
2
+ description: string;
3
+ options: {
4
+ flags: string;
5
+ description: string;
6
+ }[];
7
+ action(opts: {
8
+ ou?: string;
9
+ roleName?: string;
10
+ region?: string;
11
+ profile?: string;
12
+ maxAccounts?: string;
13
+ sessionDuration?: string;
14
+ maxKeyAge?: string;
15
+ unusedDays?: string;
16
+ skipBedrock?: boolean;
17
+ skipGuardrails?: boolean;
18
+ json?: boolean;
19
+ failOn?: string;
20
+ }): Promise<void>;
21
+ };
22
+ export default _default;
23
+ //# sourceMappingURL=scan-org.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan-org.d.ts","sourceRoot":"","sources":["../../../../src/commands/bedrock-protection/scan-org.ts"],"names":[],"mappings":";;;;;;iBA0JqB;QACjB,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAClE,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,eAAe,CAAC,EAAE,MAAM,CAAC;QAC/C,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,OAAO,CAAC;QAAC,cAAc,CAAC,EAAE,OAAO,CAAC;QACzF,IAAI,CAAC,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;KACjC;;AArBH,wBAiRE"}
@@ -0,0 +1,328 @@
1
+ import { aws, assumeRole, resolveAccount, PROFILE_OPTION } from '../../utils/aws.js';
2
+ import { DEFAULT_REGION } from '../../utils/region.js';
3
+ import { validateAwsRegion } from '../../utils/validate.js';
4
+ import { severityRank, parseFailOn, applyFailOn, FAIL_ON_OPTION, JSON_OPTION, } from '../../utils/audit.js';
5
+ import { auditRoot, auditPasswordPolicy, auditUsers, auditUserPolicies } from '../../utils/audit-iam.js';
6
+ import { auditBudgets, auditBudgetAlerting, auditDetection, auditCommitments, auditForensics } from '../../utils/audit-bedrock.js';
7
+ import { auditServiceControlPolicies, auditConfigRules } from '../../utils/audit-org.js';
8
+ /**
9
+ * Walk a parent (root or OU) collecting ACTIVE accounts.
10
+ *
11
+ * Always recurses into nested OUs. `list-accounts-for-parent` returns only
12
+ * direct children, so a non-recursive walk of an OU containing sub-OUs would
13
+ * silently report on a fraction of it and look complete -- the dangerous
14
+ * direction for an audit, so recursion is not optional.
15
+ */
16
+ function collectAccounts(parentId, parentName, target, seen, out, errors) {
17
+ const accts = aws(['organizations', 'list-accounts-for-parent', '--parent-id', parentId], target);
18
+ if (!accts.ok) {
19
+ errors.push(`${parentId}: could not list accounts (${accts.errorCode || 'unknown error'})`);
20
+ }
21
+ else {
22
+ for (const a of accts.json?.Accounts ?? []) {
23
+ if (seen.has(a.Id))
24
+ continue;
25
+ seen.add(a.Id);
26
+ out.push({ id: a.Id, name: a.Name ?? '(unnamed)', status: a.Status ?? 'UNKNOWN', parent: parentName });
27
+ }
28
+ }
29
+ const ous = aws(['organizations', 'list-organizational-units-for-parent', '--parent-id', parentId], target);
30
+ if (!ous.ok) {
31
+ errors.push(`${parentId}: could not list child OUs (${ous.errorCode || 'unknown error'})`);
32
+ return;
33
+ }
34
+ for (const ou of ous.json?.OrganizationalUnits ?? []) {
35
+ collectAccounts(ou.Id, `${parentName}/${ou.Name ?? ou.Id}`, target, seen, out, errors);
36
+ }
37
+ }
38
+ function orgScopeAccounts(target, ous) {
39
+ const errors = [];
40
+ const seen = new Set();
41
+ const accounts = [];
42
+ if (ous.length === 0) {
43
+ const roots = aws(['organizations', 'list-roots'], target);
44
+ if (!roots.ok) {
45
+ return { accounts, errors: [`list-roots failed (${roots.errorCode || 'unknown error'})`], scopeLabel: 'org' };
46
+ }
47
+ for (const r of roots.json?.Roots ?? []) {
48
+ collectAccounts(r.Id, r.Name ?? r.Id, target, seen, accounts, errors);
49
+ }
50
+ return { accounts, errors, scopeLabel: 'entire organization' };
51
+ }
52
+ for (const ou of ous) {
53
+ // Resolve the name for readable output; fall back to the id.
54
+ const desc = aws(['organizations', 'describe-organizational-unit', '--organizational-unit-id', ou], target);
55
+ const name = desc.ok ? (desc.json?.OrganizationalUnit?.Name ?? ou) : ou;
56
+ if (!desc.ok)
57
+ errors.push(`${ou}: could not describe OU (${desc.errorCode || 'unknown error'})`);
58
+ collectAccounts(ou, name, target, seen, accounts, errors);
59
+ }
60
+ return { accounts, errors, scopeLabel: `OU(s) ${ous.join(', ')}` };
61
+ }
62
+ /** Mark every IAM check for an account we could not get into. */
63
+ function unreachableFindings(reason) {
64
+ return [
65
+ ['root-mfa', 'Root account MFA', 'CRITICAL'],
66
+ ['root-access-keys', 'Root access keys', 'CRITICAL'],
67
+ ['password-policy', 'Account password policy', 'MEDIUM'],
68
+ ['access-key-age', 'Long-lived access keys', 'HIGH'],
69
+ ['console-user-no-mfa', 'Console users without MFA', 'HIGH'],
70
+ ['unused-credentials', 'Unused credentials', 'MEDIUM'],
71
+ ['user-admin-policy', 'AdministratorAccess on IAM users', 'HIGH'],
72
+ ].map(([id, title, severity]) => ({
73
+ id, category: 'iam', title,
74
+ status: 'INDETERMINATE', severity: severity,
75
+ detail: `Account could not be audited: ${reason}.`,
76
+ remediation: 'Ensure the audit role exists in this account and is assumable from the management account, then re-run.',
77
+ }));
78
+ }
79
+ export default {
80
+ description: 'Audit an AWS Organization or specific OUs: per-account IAM credential hygiene plus org-wide Bedrock spend guardrails',
81
+ options: [
82
+ { flags: '--ou <ids>', description: 'Comma-separated OU ids to scope to (default: the entire organization, recursing from every root)' },
83
+ { flags: '--role-name <name>', description: 'Role to assume in each member account', default: 'OrganizationAccountAccessRole' },
84
+ { flags: '--region <region>', description: 'Region for Bedrock, CloudWatch and Provisioned Throughput checks', default: DEFAULT_REGION },
85
+ PROFILE_OPTION,
86
+ { flags: '--max-accounts <n>', description: 'Stop after this many accounts (each costs ~10 AWS API calls)', default: '50' },
87
+ { flags: '--session-duration <seconds>', description: 'AssumeRole session length', default: '3600' },
88
+ { flags: '--max-key-age <days>', description: 'Flag active access keys older than this', default: '90' },
89
+ { flags: '--unused-days <days>', description: 'Flag credentials idle longer than this', default: '90' },
90
+ { flags: '--skip-bedrock', description: 'Skip the org-wide Bedrock spend guardrail checks' },
91
+ { flags: '--skip-guardrails', description: 'Skip the SCP and AWS Config organization guardrail checks' },
92
+ JSON_OPTION,
93
+ FAIL_ON_OPTION,
94
+ ],
95
+ async action(opts) {
96
+ const region = validateAwsRegion(opts.region || DEFAULT_REGION);
97
+ const failOn = parseFailOn(opts.failOn);
98
+ const roleName = opts.roleName || 'OrganizationAccountAccessRole';
99
+ if (!/^[\w+=,.@-]{1,64}$/.test(roleName)) {
100
+ throw new Error(`--role-name must be a valid IAM role name (got "${roleName}")`);
101
+ }
102
+ const maxAccounts = Number.parseInt(opts.maxAccounts ?? '50', 10);
103
+ const sessionDuration = Number.parseInt(opts.sessionDuration ?? '3600', 10);
104
+ const maxKeyAge = Number.parseInt(opts.maxKeyAge ?? '90', 10);
105
+ const unusedDays = Number.parseInt(opts.unusedDays ?? '90', 10);
106
+ for (const [name, v, min] of [['--max-accounts', maxAccounts, 1], ['--session-duration', sessionDuration, 900], ['--max-key-age', maxKeyAge, 1], ['--unused-days', unusedDays, 1]]) {
107
+ if (!Number.isFinite(v) || v < min)
108
+ throw new Error(`${name} must be an integer >= ${min}`);
109
+ }
110
+ const ous = (opts.ou ?? '').split(',').map((s) => s.trim()).filter(Boolean);
111
+ for (const ou of ous) {
112
+ if (!/^ou-[0-9a-z]{4,32}-[a-z0-9]{8,32}$/.test(ou)) {
113
+ throw new Error(`"${ou}" is not a valid OU id (expected ou-xxxx-xxxxxxxx)`);
114
+ }
115
+ }
116
+ const mgmt = { profile: opts.profile };
117
+ const callerAccount = resolveAccount(mgmt);
118
+ if (!callerAccount) {
119
+ process.exitCode = 2;
120
+ return;
121
+ }
122
+ // Confirm we are actually in the management account (or a delegated admin).
123
+ // Running from a member account silently returns only that account, which
124
+ // would look like a one-account org rather than a permissions problem.
125
+ const org = aws(['organizations', 'describe-organization'], mgmt);
126
+ if (!org.ok) {
127
+ console.error(`\n❌ Cannot read the organization (${org.errorCode || 'unknown error'}).`);
128
+ console.error(` Run this from the management account or a delegated admin, with organizations:Describe*/List* granted.\n`);
129
+ process.exitCode = 2;
130
+ return;
131
+ }
132
+ const orgId = org.json?.Organization?.Id ?? 'unknown';
133
+ const payerId = org.json?.Organization?.MasterAccountId ?? '';
134
+ if (payerId && payerId !== callerAccount) {
135
+ console.log(`\n⚠️ Running from ${callerAccount}, which is not the management account (${payerId}).`);
136
+ console.log(` Org-wide Bedrock guardrails are evaluated against the CALLER, so budget findings may not reflect the payer.\n`);
137
+ }
138
+ const { accounts, errors, scopeLabel } = orgScopeAccounts(mgmt, ous);
139
+ // Attachment is judged against the audited scope, not the org at large: an
140
+ // SCP attached to an unrelated OU does not constrain these accounts.
141
+ const scopeTargetIds = ous.length
142
+ ? ous
143
+ : (aws(['organizations', 'list-roots'], mgmt).json?.Roots ?? []).map((r) => r.Id);
144
+ const active = accounts.filter((a) => a.status === 'ACTIVE');
145
+ const suspended = accounts.filter((a) => a.status !== 'ACTIVE');
146
+ const selected = active.slice(0, maxAccounts);
147
+ const truncated = active.length - selected.length;
148
+ if (!opts.json) {
149
+ console.log(`\n🏛️ Bedrock protection — organization audit`);
150
+ console.log(` Org: ${orgId} Scope: ${scopeLabel} Region: ${region}`);
151
+ console.log(` ${active.length} active account(s)${suspended.length ? `, ${suspended.length} non-active skipped` : ''}${truncated > 0 ? `, ${truncated} beyond --max-accounts` : ''}`);
152
+ console.log(` Audit only — this command makes no changes.\n`);
153
+ for (const e of errors)
154
+ console.log(` ⚠️ ${e}`);
155
+ if (errors.length)
156
+ console.log('');
157
+ }
158
+ // ---- per-account IAM hygiene ----
159
+ const results = [];
160
+ for (const acct of selected) {
161
+ let target;
162
+ if (acct.id === callerAccount) {
163
+ // Cannot assume into ourselves via the org role; use ambient creds.
164
+ target = mgmt;
165
+ }
166
+ else {
167
+ const assumed = assumeRole(acct.id, roleName, 'prism-bedrock-protection', sessionDuration, mgmt, region);
168
+ if ('error' in assumed) {
169
+ results.push({ account: acct, findings: unreachableFindings(`${roleName} not assumable (${assumed.error})`), unreachable: assumed.error });
170
+ if (!opts.json)
171
+ console.log(` ❓ ${acct.id} ${acct.name} — unreachable: ${assumed.error}`);
172
+ continue;
173
+ }
174
+ target = { env: assumed.env };
175
+ // Confirm the session really landed in the intended account before
176
+ // attributing any finding to it. Misattribution is the worst failure
177
+ // available here -- a stale AWS_PROFILE or a mis-set env var would
178
+ // report the caller's own posture under a member account's name, and
179
+ // every number would be wrong in a way no reader could detect. Cheap
180
+ // insurance: one extra GetCallerIdentity per account.
181
+ const landed = aws(['sts', 'get-caller-identity'], target);
182
+ const landedId = landed.ok ? landed.json?.Account : null;
183
+ if (landedId !== acct.id) {
184
+ const why = landed.ok
185
+ ? `session resolved to ${landedId ?? 'unknown'}, not ${acct.id}`
186
+ : `could not confirm identity after assuming (${landed.errorCode || 'unknown error'})`;
187
+ results.push({ account: acct, findings: unreachableFindings(why), unreachable: why });
188
+ if (!opts.json)
189
+ console.log(` ❓ ${acct.id} ${acct.name} — ${why}`);
190
+ continue;
191
+ }
192
+ }
193
+ const findings = [
194
+ ...auditRoot(target),
195
+ auditPasswordPolicy(target),
196
+ ...auditUsers(target, maxKeyAge, unusedDays),
197
+ auditUserPolicies(target),
198
+ ];
199
+ results.push({ account: acct, findings });
200
+ if (!opts.json) {
201
+ const f = findings.filter((x) => x.status === 'FAIL');
202
+ const i = findings.filter((x) => x.status === 'INDETERMINATE');
203
+ const pass = findings.length - f.length - i.length;
204
+ const worst = f.length ? f.reduce((a, b) => (severityRank(b.severity) > severityRank(a.severity) ? b : a)).severity : '—';
205
+ // Absence of failures is NOT a pass. An account where every check came
206
+ // back indeterminate established nothing, and a green tick there is the
207
+ // same laundering this audit exists to prevent.
208
+ const icon = f.some((x) => x.severity === 'CRITICAL') ? '❌'
209
+ : f.length ? '⚠️ '
210
+ : pass === 0 ? '❓'
211
+ : i.length ? '⚠️ '
212
+ : '✅';
213
+ console.log(` ${icon} ${acct.id} ${acct.name.padEnd(24).slice(0, 24)} ${pass}/${findings.length} pass, ${f.length} fail (worst ${worst})${i.length ? `, ${i.length} INDETERMINATE` : ''}`);
214
+ }
215
+ }
216
+ // ---- org-wide Bedrock guardrails, evaluated once at the payer ----
217
+ const orgFindings = [];
218
+ if (!opts.skipBedrock) {
219
+ const budgets = auditBudgets(mgmt, callerAccount);
220
+ orgFindings.push(...budgets.findings, auditBudgetAlerting(mgmt, callerAccount, budgets.coveringBudgets), ...auditDetection(mgmt, region), auditCommitments(mgmt, region), auditForensics(mgmt, region));
221
+ }
222
+ if (!opts.skipGuardrails) {
223
+ orgFindings.push(...auditServiceControlPolicies(mgmt, scopeTargetIds), ...auditConfigRules(mgmt));
224
+ }
225
+ const allFindings = [...results.flatMap((r) => r.findings), ...orgFindings];
226
+ if (opts.json) {
227
+ console.log(JSON.stringify({
228
+ organization: orgId,
229
+ scope: scopeLabel,
230
+ region,
231
+ caller_account: callerAccount,
232
+ management_account: payerId || null,
233
+ role_name: roleName,
234
+ accounts_active: active.length,
235
+ accounts_audited: selected.length,
236
+ accounts_truncated: truncated,
237
+ enumeration_errors: errors,
238
+ generated_at: new Date().toISOString(),
239
+ per_account: results.map((r) => ({
240
+ account_id: r.account.id,
241
+ account_name: r.account.name,
242
+ ou_path: r.account.parent,
243
+ unreachable: r.unreachable ?? null,
244
+ findings: r.findings,
245
+ })),
246
+ org_wide_findings: orgFindings,
247
+ }, null, 2));
248
+ applyFailOn(allFindings, failOn, true);
249
+ return;
250
+ }
251
+ // ---- org-wide section ----
252
+ const printGroup = (heading, note, cats) => {
253
+ const rows = orgFindings.filter((f) => cats.includes(f.category));
254
+ if (!rows.length)
255
+ return;
256
+ console.log(`\n── ${heading} ──\n`);
257
+ for (const n of note)
258
+ console.log(` ${n}`);
259
+ if (note.length)
260
+ console.log('');
261
+ for (const f of rows.slice().sort((a, b) => severityRank(b.severity) - severityRank(a.severity))) {
262
+ const icon = f.status === 'PASS' ? '✅' : f.status === 'FAIL' ? '❌' : '❓';
263
+ console.log(` ${icon} [${f.severity}] ${f.title}`);
264
+ console.log(` ${f.detail}`);
265
+ if (f.status !== 'PASS' && f.remediation)
266
+ console.log(` → ${f.remediation}`);
267
+ console.log('');
268
+ }
269
+ };
270
+ printGroup(`Org-wide Bedrock guardrails (evaluated once at ${callerAccount})`, [
271
+ 'Under consolidated billing these bound every linked account, so they are',
272
+ 'reported once rather than per account. A member account may still hold its',
273
+ 'own budget, so a FAIL here does not prove no ceiling exists anywhere.',
274
+ ], ['budget', 'detection', 'commitment', 'forensics']);
275
+ printGroup('Preventive guardrails — Service Control Policies', [
276
+ 'SCPs refuse the action rather than reporting it, and bind even a compromised',
277
+ 'admin. Detected structurally: presence and attachment, NOT enforcement.',
278
+ ], ['preventive']);
279
+ printGroup('Detective guardrails — AWS Config organization rules', [
280
+ 'This audit is a point-in-time sample. Config rules evaluate on every',
281
+ 'configuration change, which is what catches drift between runs.',
282
+ ], ['detective']);
283
+ // ---- rollup ----
284
+ const fail = allFindings.filter((f) => f.status === 'FAIL');
285
+ const indet = allFindings.filter((f) => f.status === 'INDETERMINATE');
286
+ const bySev = (s) => fail.filter((f) => f.severity === s).length;
287
+ const unreachableAccounts = results.filter((r) => r.unreachable);
288
+ console.log('── Organization rollup ──\n');
289
+ console.log(` ${selected.length} account(s) audited, ${allFindings.length} checks: ${allFindings.length - fail.length - indet.length} pass, ${fail.length} fail, ${indet.length} indeterminate`);
290
+ console.log(` Findings by severity: CRITICAL ${bySev('CRITICAL')}, HIGH ${bySev('HIGH')}, MEDIUM ${bySev('MEDIUM')}, LOW ${bySev('LOW')}\n`);
291
+ // Rank accounts so the worst is actionable first rather than buried.
292
+ const ranked = results
293
+ .map((r) => ({
294
+ r,
295
+ crit: r.findings.filter((f) => f.status === 'FAIL' && f.severity === 'CRITICAL').length,
296
+ high: r.findings.filter((f) => f.status === 'FAIL' && f.severity === 'HIGH').length,
297
+ }))
298
+ .filter((x) => x.crit + x.high > 0)
299
+ .sort((a, b) => b.crit - a.crit || b.high - a.high);
300
+ if (ranked.length) {
301
+ console.log(` Accounts with CRITICAL or HIGH findings, worst first:`);
302
+ for (const x of ranked) {
303
+ console.log(` ${x.r.account.id} ${x.r.account.name} [${x.r.account.parent}] CRITICAL ${x.crit}, HIGH ${x.high}`);
304
+ }
305
+ console.log('');
306
+ }
307
+ const establishedNothing = results.filter((r) => !r.unreachable
308
+ && r.findings.every((f) => f.status === 'INDETERMINATE'));
309
+ if (establishedNothing.length) {
310
+ console.log(` ❓ ${establishedNothing.length} reachable account(s) produced NO usable checks (every result indeterminate):`);
311
+ for (const r of establishedNothing)
312
+ console.log(` ${r.account.id} ${r.account.name} — likely missing IAM read permissions on the assumed role`);
313
+ console.log('');
314
+ }
315
+ if (unreachableAccounts.length) {
316
+ console.log(` ❓ ${unreachableAccounts.length} account(s) could not be audited and are NOT passes:`);
317
+ for (const r of unreachableAccounts)
318
+ console.log(` ${r.account.id} ${r.account.name} — ${r.unreachable}`);
319
+ console.log(` Their IAM posture is unknown. Org coverage is ${selected.length - unreachableAccounts.length}/${selected.length}.\n`);
320
+ }
321
+ if (truncated > 0) {
322
+ console.log(` ⚠️ ${truncated} active account(s) were not audited because of --max-accounts ${maxAccounts}.`);
323
+ console.log(` Raise it to cover the whole scope; the result is a floor until you do.\n`);
324
+ }
325
+ applyFailOn(allFindings, failOn, false);
326
+ },
327
+ };
328
+ //# sourceMappingURL=scan-org.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan-org.js","sourceRoot":"","sources":["../../../../src/commands/bedrock-protection/scan-org.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
+ import { AwsTarget } from './aws.js';
1
2
  import { Finding } from './audit.js';
2
- export declare function auditBudgets(profile: string | undefined, accountId: string): {
3
+ export declare function auditBudgets(target: AwsTarget | undefined, accountId: string): {
3
4
  findings: Finding[];
4
5
  coveringBudgets: string[];
5
6
  };
@@ -17,8 +18,8 @@ export declare function auditBudgets(profile: string | undefined, accountId: str
17
18
  * in ONE call. Subscribers need a call per notification, which is why this is
18
19
  * scoped to the budgets that actually cover Bedrock rather than all of them.
19
20
  */
20
- export declare function auditBudgetAlerting(profile: string | undefined, accountId: string, coveringBudgets: string[]): Finding;
21
- export declare function auditDetection(profile: string | undefined, region: string): Finding[];
22
- export declare function auditCommitments(profile: string | undefined, region: string): Finding;
23
- export declare function auditForensics(profile: string | undefined, region: string): Finding;
21
+ export declare function auditBudgetAlerting(target: AwsTarget | undefined, accountId: string, coveringBudgets: string[]): Finding;
22
+ export declare function auditDetection(target: AwsTarget | undefined, region: string): Finding[];
23
+ export declare function auditCommitments(target: AwsTarget | undefined, region: string): Finding;
24
+ export declare function auditForensics(target: AwsTarget | undefined, region: string): Finding;
24
25
  //# sourceMappingURL=audit-bedrock.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"audit-bedrock.d.ts","sourceRoot":"","sources":["../../../src/utils/audit-bedrock.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAiErC,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,SAAS,EAAE,MAAM,GAAG;IAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;IAAC,eAAe,EAAE,MAAM,EAAE,CAAA;CAAE,CA2D/H;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,MAAM,EAAE,GACxB,OAAO,CA8DT;AAWD,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,EAAE,CA+FrF;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAmBrF;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAoBnF"}
1
+ {"version":3,"file":"audit-bedrock.d.ts","sourceRoot":"","sources":["../../../src/utils/audit-bedrock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,SAAS,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAiErC,wBAAgB,YAAY,CAAC,MAAM,EAAE,SAAS,GAAG,SAAS,EAAE,SAAS,EAAE,MAAM,GAAG;IAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;IAAC,eAAe,EAAE,MAAM,EAAE,CAAA;CAAE,CA2DjI;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,SAAS,GAAG,SAAS,EAC7B,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,MAAM,EAAE,GACxB,OAAO,CA8DT;AAWD,wBAAgB,cAAc,CAAC,MAAM,EAAE,SAAS,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,EAAE,CA+FvF;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAmBvF;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,SAAS,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAoBrF"}
@@ -58,10 +58,10 @@ function budgetCovers(budget, hints) {
58
58
  function isCostBudget(budget) {
59
59
  return budget?.BudgetType === 'COST';
60
60
  }
61
- export function auditBudgets(profile, accountId) {
61
+ export function auditBudgets(target, accountId) {
62
62
  // describe-budgets requires an explicit account id, and returns an EMPTY body
63
63
  // -- not {"Budgets": []} -- when no budgets exist.
64
- const bud = aws(['budgets', 'describe-budgets', '--account-id', accountId], profile);
64
+ const bud = aws(['budgets', 'describe-budgets', '--account-id', accountId], target);
65
65
  if (!bud.ok) {
66
66
  return { coveringBudgets: [], findings: [
67
67
  ['bedrock-budget', 'Budget covering Bedrock services'],
@@ -125,7 +125,7 @@ export function auditBudgets(profile, accountId) {
125
125
  * in ONE call. Subscribers need a call per notification, which is why this is
126
126
  * scoped to the budgets that actually cover Bedrock rather than all of them.
127
127
  */
128
- export function auditBudgetAlerting(profile, accountId, coveringBudgets) {
128
+ export function auditBudgetAlerting(target, accountId, coveringBudgets) {
129
129
  const id = 'budget-alerting';
130
130
  const title = 'Bedrock budgets actually notify someone';
131
131
  if (coveringBudgets.length === 0) {
@@ -138,7 +138,7 @@ export function auditBudgetAlerting(profile, accountId, coveringBudgets) {
138
138
  detail: 'No COST budget covers Bedrock or Marketplace, so there is no budget whose alerting could be checked (see bedrock-budget and marketplace-budget above).',
139
139
  };
140
140
  }
141
- const all = aws(['budgets', 'describe-budget-notifications-for-account', '--account-id', accountId], profile);
141
+ const all = aws(['budgets', 'describe-budget-notifications-for-account', '--account-id', accountId], target);
142
142
  if (!all.ok) {
143
143
  return {
144
144
  id, category: 'budget', title,
@@ -164,7 +164,7 @@ export function auditBudgetAlerting(profile, accountId, coveringBudgets) {
164
164
  'budgets', 'describe-subscribers-for-notification',
165
165
  '--account-id', accountId, '--budget-name', name,
166
166
  '--notification', JSON.stringify(n),
167
- ], profile);
167
+ ], target);
168
168
  if (subs.ok)
169
169
  subscribers += (subs.json?.Subscribers ?? []).length;
170
170
  }
@@ -197,14 +197,14 @@ export function auditBudgetAlerting(profile, accountId, coveringBudgets) {
197
197
  * depending on account state, which is unstable in --json output.
198
198
  */
199
199
  const ANOMALY_TITLE = 'Cost anomaly monitor covering Bedrock, with an alert subscription';
200
- export function auditDetection(profile, region) {
200
+ export function auditDetection(target, region) {
201
201
  const out = [];
202
202
  // Cost Explorer is an account-level opt-in that stays OFF until someone
203
203
  // enables it -- measured error: AccessDeniedException "User not enabled for
204
204
  // cost explorer access". Every CE-backed check must be gated on this, or the
205
205
  // audit reports "no anomaly monitor configured" when the truth is that it
206
206
  // could not look.
207
- const ce = aws(['ce', 'get-anomaly-monitors'], profile);
207
+ const ce = aws(['ce', 'get-anomaly-monitors'], target);
208
208
  const ceDisabled = !ce.ok && /not enabled for cost explorer/i.test(ce.raw);
209
209
  out.push({
210
210
  id: 'cost-explorer-enabled', category: 'detection', title: 'Cost Explorer enabled',
@@ -240,7 +240,7 @@ export function auditDetection(profile, region) {
240
240
  // then auto-creates a "Default-Services-Monitor" (SERVICE dimension) WITH a
241
241
  // subscription -- observed live. So this check often passes as a side effect
242
242
  // of setting up budgets rather than deliberately.
243
- const subs = aws(['ce', 'get-anomaly-subscriptions'], profile);
243
+ const subs = aws(['ce', 'get-anomaly-subscriptions'], target);
244
244
  const coveringArns = new Set(covering.map((m) => m.MonitorArn));
245
245
  const subscribed = subs.ok
246
246
  ? (subs.json?.AnomalySubscriptions ?? []).some((s) => (s.MonitorArnList ?? []).some((arn) => coveringArns.has(arn)))
@@ -266,7 +266,7 @@ export function auditDetection(profile, region) {
266
266
  }
267
267
  // CloudWatch is the only fast signal. Cost data lags 12-24h, so a cost-only
268
268
  // posture lets a stolen key run for up to a day before anything fires.
269
- const alarms = aws(['cloudwatch', 'describe-alarms', '--region', region], profile);
269
+ const alarms = aws(['cloudwatch', 'describe-alarms', '--region', region], target);
270
270
  if (!alarms.ok) {
271
271
  out.push({
272
272
  id: 'bedrock-invocation-alarm', category: 'detection', title: 'CloudWatch alarm on Bedrock invocation volume',
@@ -287,8 +287,8 @@ export function auditDetection(profile, region) {
287
287
  }
288
288
  return out;
289
289
  }
290
- export function auditCommitments(profile, region) {
291
- const pt = aws(['bedrock', 'list-provisioned-model-throughputs', '--region', region], profile);
290
+ export function auditCommitments(target, region) {
291
+ const pt = aws(['bedrock', 'list-provisioned-model-throughputs', '--region', region], target);
292
292
  if (!pt.ok) {
293
293
  return {
294
294
  id: 'provisioned-throughput', category: 'commitment', title: 'Provisioned Throughput commitments',
@@ -307,9 +307,9 @@ export function auditCommitments(profile, region) {
307
307
  remediation: pts.length ? 'Confirm each commitment is intentional and still in use; an abandoned one bills indefinitely.' : undefined,
308
308
  };
309
309
  }
310
- export function auditForensics(profile, region) {
310
+ export function auditForensics(target, region) {
311
311
  // Returns an EMPTY body when logging is off -- same trap as describe-budgets.
312
- const log = aws(['bedrock', 'get-model-invocation-logging-configuration', '--region', region], profile);
312
+ const log = aws(['bedrock', 'get-model-invocation-logging-configuration', '--region', region], target);
313
313
  if (!log.ok) {
314
314
  return {
315
315
  id: 'model-invocation-logging', category: 'forensics', title: 'Bedrock model invocation logging',