export async function evaluateSecurityHubTaggingCoverage()

in packages/obligatron/src/obligations/tagging.ts [152:215]


export async function evaluateSecurityHubTaggingCoverage(
	db: PrismaClient,
): Promise<ObligationResult[]> {
	const findings = await db.aws_securityhub_findings.findMany({
		where: {
			product_fields: {
				path: ['StandardsArn'],
				string_starts_with:
					'arn:aws:securityhub:::standards/aws-resource-tagging-standard',
			},
			compliance: {
				path: ['Status'],
				equals: 'FAILED',
			},
		},
	});

	logger.log({
		message: 'Received findings from security hub',
		total: findings.length,
	});

	const results: ObligationResult[] = [];

	for (const finding of findings) {
		const resources = finding.resources?.valueOf();

		if (!Array.isArray(resources)) {
			logger.error({
				message: `Skipping invalid SecurityHub finding, invalid 'resources' field`,
				finding_id: finding.id,
			});
			continue;
		}

		// The Security Hub spec indicates that a finding can have multiple resources,
		// I don't think this will happen for the Tagging rules, but lets be safe by
		// handling this situation and raising a warning.
		if (resources.length !== 1) {
			logger.warn({
				message: `Finding had more (or less) that 1 resource: ${resources.length}`,
				finding_id: finding.id,
			});
		}

		const validResources = resources.filter(isFindingResource);
		const invalidResources = resources.filter((f) => !isFindingResource(f));

		// This in theory should not happen as long as AWS don't change their schema.
		// if they do change the schema its unlikely to be just this one finding failing,
		// so lets make sure that we crash the lambda and get a humans attention!
		if (invalidResources.length > 0) {
			throw new Error(`Invalid resource in finding ${finding.id}`);
		}

		const newResults: ObligationResult[] = validResources
			.map((resource) => createResult(resource, finding))
			.filter((_) => _ !== undefined);

		results.push(...newResults);
	}

	return results;
}