Skip to content

Commit

Permalink
Consume Security Hub tagging data in Obligatron
Browse files Browse the repository at this point in the history
  • Loading branch information
AshCorr committed Jun 12, 2024
1 parent 1819a57 commit 0b9556e
Show file tree
Hide file tree
Showing 3 changed files with 164 additions and 159 deletions.
2 changes: 1 addition & 1 deletion packages/obligatron/src/obligations/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@ export type ObligationResult = {
/**
* Key-value pairs to link failing obligations to the responsible teams.
*/
contacts?: Record<string, string>;
contacts?: Record<string, unknown>;
};
202 changes: 86 additions & 116 deletions packages/obligatron/src/obligations/tagging.test.ts
Original file line number Diff line number Diff line change
@@ -1,166 +1,136 @@
import type { PrismaClient } from '@prisma/client';
import type { AwsResource } from './tagging';
import { evaluateTaggingObligation } from './tagging';

const createPrismaClientWithMockedResponse = (response: AwsResource[]) => {
const createPrismaClientWithMockedResponse = (response: unknown[]) => {
const aws_securityhub_findings = {
findMany: () => Promise.resolve(response),
};

const test = {
$queryRaw: () => Promise.resolve(response),
aws_securityhub_findings,
} as unknown as PrismaClient;

return test;
};

describe('The tagging obligation', () => {
it('passes correct resource', async () => {
it('catches failed securityhub findings', async () => {
const client = createPrismaClientWithMockedResponse([
{
account_id: '123456789012',
arn: 'arn:aws:s3:::mybucket',
service: 's3',
resource_type: 'bucket',
taggable: 'true',
tags: {
Stack: 'my-stack',
Stage: 'prod',
App: 'myapp',
'gu:repo': 'myrepo',
},
id: '123456789012',
title: 'failed tagging',
region: 'mars-north-1',
aws_account_id: '123456789012',
resources: [
{
Id: 'arn:aws:s3:::mybucket',
Tags: {
Stack: 'my-stack',
Stage: 'prod',
App: 'myapp',
'gu:repo': 'myrepo',
},
},
],
},
]);

const results = await evaluateTaggingObligation(client);

expect(results).toHaveLength(0);
});

it('catches missing Stack tags', async () => {
const client = createPrismaClientWithMockedResponse([
{
account_id: '123456789012',
arn: 'arn:aws:s3:::mybucket',
service: 's3',
resource_type: 'bucket',
taggable: 'true',
tags: {
Stage: 'prod',
App: 'myapp',
'gu:repo': 'myrepo',
},
id: '123456789012',
title: 'failed tagging',
region: 'mars-north-1',
aws_account_id: '123456789012',
resources: [
{
Id: 'arn:aws:s3:::mybucket',
Tags: {
Stack: 'my-stack',
Stage: 'prod',
App: 'myapp',
},
},
],
},
]);

const results = await evaluateTaggingObligation(client);

expect(results).toHaveLength(1);
expect(results).toHaveLength(2);
expect(results[0]).toEqual({
resource: 'arn:aws:s3:::mybucket',
reason: "Resource missing 'Stack' tag.",
contacts: { aws_account: '123456789012' },
});
});

it('catches missing Stage tags', async () => {
const client = createPrismaClientWithMockedResponse([
{
account_id: '123456789012',
arn: 'arn:aws:s3:::mybucket',
service: 's3',
resource_type: 'bucket',
taggable: 'true',
tags: {
Stack: 'my-stack',
App: 'myapp',
'gu:repo': 'myrepo',
},
reason: 'failed tagging',
contacts: {
aws_account_id: '123456789012',
Stack: 'my-stack',
Stage: 'prod',
App: 'myapp',
},
]);

const results = await evaluateTaggingObligation(client);

expect(results).toHaveLength(1);
expect(results[0]).toEqual({
resource: 'arn:aws:s3:::mybucket',
reason: "Resource missing 'Stage' tag.",
contacts: { aws_account: '123456789012' },
url: 'https://mars-north-1.console.aws.amazon.com/securityhub/home?region=mars-north-1#/findings?search=RecordState%3D%255Coperator%255C%253AEQUALS%255C%253AACTIVE%26Id%3D%255Coperator%255C%253AEQUALS%255C%253A123456789012',
});
});

it('catches missing App tags', async () => {
it('handles findings with no resources', async () => {
const client = createPrismaClientWithMockedResponse([
{
account_id: '123456789012',
arn: 'arn:aws:s3:::mybucket',
service: 's3',
resource_type: 'bucket',
taggable: 'true',
tags: {
Stack: 'my-stack',
Stage: 'prod',
'gu:repo': 'myrepo',
},
id: '123456789012',
title: 'failed tagging',
region: 'mars-north-1',
aws_account_id: '123456789012',
resources: [],
},
]);

const results = await evaluateTaggingObligation(client);

expect(results).toHaveLength(1);
expect(results[0]).toEqual({
resource: 'arn:aws:s3:::mybucket',
reason: "Resource missing 'App' tag.",
contacts: { aws_account: '123456789012' },
});
expect(results).toHaveLength(0);
});

it('catches missing Repo tags', async () => {
it('handles findings with incorrect amount of resources', async () => {
const client = createPrismaClientWithMockedResponse([
{
account_id: '123456789012',
arn: 'arn:aws:s3:::mybucket',
service: 's3',
resource_type: 'bucket',
taggable: 'true',
tags: {
Stack: 'my-stack',
Stage: 'prod',
App: 'myapp',
},
id: '123456789012',
title: 'failed tagging',
region: 'mars-north-1',
aws_account_id: '123456789012',
resources: [
{
Id: 'arn:aws:s3:::mybucket',
Tags: {
Stack: 'my-stack',
Stage: 'prod',
App: 'myapp',
'gu:repo': 'myrepo',
},
},
{
Id: 'arn:aws:s3:::mybucket',
Tags: {
Stack: 'my-stack',
Stage: 'prod',
App: 'myapp',
'gu:repo': 'myrepo',
},
},
],
},
]);

const results = await evaluateTaggingObligation(client);

expect(results).toHaveLength(1);
expect(results[0]).toEqual({
resource: 'arn:aws:s3:::mybucket',
reason: "Resource missing 'gu:repo' tag.",
contacts: { aws_account: '123456789012' },
});
expect(results).toHaveLength(2);
});

it('catches empty tags', async () => {
it('crashes on findings with an invalid Resource schema', async () => {
const client = createPrismaClientWithMockedResponse([
{
account_id: '123456789012',
arn: 'arn:aws:s3:::mybucket',
service: 's3',
resource_type: 'bucket',
taggable: 'true',
tags: {
Stack: '',
Stage: '',
App: '',
'gu:repo': '',
},
id: '123456789012',
title: 'failed tagging',
region: 'mars-north-1',
aws_account_id: '123456789012',
resources: [{}],
},
]);

const results = await evaluateTaggingObligation(client);

expect(results).toHaveLength(4);
expect(results[0]).toEqual({
resource: 'arn:aws:s3:::mybucket',
reason: "Resource missing 'Stack' tag.",
contacts: { aws_account: '123456789012' },
});
await expect(evaluateTaggingObligation(client)).rejects.toEqual(
new Error('Invalid resource in finding 123456789012 at index 0'),
);
});
});
Loading

0 comments on commit 0b9556e

Please sign in to comment.