diff --git a/README.md b/README.md index 8c49fbfa..1bdb63d3 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,7 @@ CloudGraph AWS Provider will ask you what regions you would like to crawl and wi | apiGatewayRestApi | apiGatewayResource, apiGatewayStage, route53Record | | apiGatewayStage | apiGatewayRestApi | | apiGatewayResource | apiGatewayRestApi | -| appSync | cognitoUserPool, dynamodb, lambda, rdsCluster | +| appSync | cognitoUserPool, dynamodb, iamRole, lambda, rdsCluster, wafV2WebAcl | | asg | ebs, ec2, securityGroup, subnet | | athenaDataCatalog | | | clientVpnEndpoint | securityGroup | @@ -122,7 +122,7 @@ CloudGraph AWS Provider will ask you what regions you would like to crawl and wi | iamServerCertificate | | | iamUser | iamGroup | | iamPolicy | iamRole, iamGroup | -| iamRole | codebuild, configurationRecorder, ec2, iamInstanceProfile, iamPolicy, eksCluster, ecsService, flowLog, glueJob, managedAirflow, sageMakerNotebookInstance, systemsManagerInstance guardDutyDetector | +| iamRole | appSync, codebuild, configurationRecorder, ec2, iamInstanceProfile, iamPolicy, eksCluster, ecsService, flowLog, glueJob, managedAirflow, sageMakerNotebookInstance, systemsManagerInstance guardDutyDetector | | iamGroup | iamUser, iamPolicy | | igw | vpc | | iot | | @@ -159,5 +159,5 @@ CloudGraph AWS Provider will ask you what regions you would like to crawl and wi | vpc | alb, codebuild, dmsReplicationInstance, ec2, eip, elb, ecsService, efsMountTarget, eksCluster igw, elastiCacheCluster, elasticSearchDomain, lambda, nacl, natGateway, networkInterface, rdsClusterSnapshot, rdsDbInstance, redshiftCluster, route53HostedZone, routeTable, subnet, flowLog, vpnGateway, transitGatewayAttachment | | vpnConnection | customerGateway, transitGateway, transitGatewayAttachment, vpnGateway | | vpnGateway | vpc, vpnConnection | -| wafV2WebAcl | | +| wafV2WebAcl | appSync | diff --git a/src/services/appSync/connections.ts b/src/services/appSync/connections.ts index 401252b6..095a689c 100644 --- a/src/services/appSync/connections.ts +++ b/src/services/appSync/connections.ts @@ -10,6 +10,9 @@ import { RawAwsDynamoDbTable } from '../dynamodb/data' import { RawAwsLambdaFunction } from '../lambda/data' import { RawAwsCognitoUserPool } from '../cognitoUserPool/data' import { RawAwsRdsCluster } from '../rdsCluster/data' +import { RawAwsIamRole } from '../iamRole/data' +import { globalRegionName } from '../../enums/regions' +import { RawAwsWafV2WebAcl } from '../wafV2WebAcl/data' /** * AppSync @@ -27,7 +30,7 @@ export default ({ region: string }): { [key: string]: ServiceConnection[] } => { const connections: ServiceConnection[] = [] - const { apiId: id, awsDataSources, userPoolConfig } = appSync + const { apiId: id, awsDataSources, userPoolConfig, wafWebAclArn } = appSync /** * Find cognito user pools @@ -153,6 +156,60 @@ export default ({ } } + /** + * Find related IAM Roles + */ + const roles: { name: string; data: { [property: string]: any[] } } = + data.find(({ name }) => name === services.iamRole) + + const roleArns = awsDataSources?.map( + ({ serviceRoleArn }) => serviceRoleArn + ) + + if (roles?.data?.[globalRegionName]) { + const dataAtRegion: RawAwsIamRole[] = roles.data[globalRegionName].filter( + role => roleArns.includes(role.Arn) + ) + if (!isEmpty(dataAtRegion)) { + for (const instance of dataAtRegion) { + const { Arn: arn }: RawAwsIamRole = instance + + connections.push({ + id: arn, + resourceType: services.iamRole, + relation: 'child', + field: 'iamRoles', + }) + } + } + } + + /** + * Find wafV2WebAcls + */ + const acls: { + name: string + data: { [property: string]: RawAwsWafV2WebAcl[] } + } = data.find(({ name }) => name === services.wafV2WebAcl) + + if (acls?.data) { + const allAcls = Object.values(acls.data).flat() + const dataInRegion: RawAwsWafV2WebAcl[] = allAcls.filter( + ({ ARN }: RawAwsWafV2WebAcl) => ARN === wafWebAclArn + ) + + if (!isEmpty(dataInRegion)) { + for (const acl of dataInRegion) { + connections.push({ + id: acl.Id, + resourceType: services.wafV2WebAcl, + relation: 'child', + field: 'webAcl', + }) + } + } + } + const appSyncResult = { [id]: connections, } diff --git a/src/services/appSync/schema.graphql b/src/services/appSync/schema.graphql index e5d67743..48bd5a6d 100644 --- a/src/services/appSync/schema.graphql +++ b/src/services/appSync/schema.graphql @@ -124,9 +124,7 @@ type awsAdditionalAuthenticationProvider userPoolAwsRegion: String @search(by: [hash, regexp]) userPoolAppIdClientRegex: String @search(by: [hash, regexp]) } -# TODO: add iam role connection -# TODO: waf web acl connection -# TODO: add cloudwatchLog connection + type awsAppSync implements awsBaseService @key(fields: "arn") { name: String @search(by: [hash, regexp]) authenticationType: String @search(by: [hash, regexp]) @@ -158,4 +156,6 @@ type awsAppSync implements awsBaseService @key(fields: "arn") { dynamodb: [awsDynamoDbTable] @hasInverse(field: appSync) lambda: [awsLambda] @hasInverse(field: appSync) rdsCluster: [awsRdsCluster] @hasInverse(field: appSync) + iamRoles: [awsIamRole] @hasInverse(field: appSync) + webAcl: [awsWafV2WebAcl] @hasInverse(field: appSync) } diff --git a/src/services/iamRole/schema.graphql b/src/services/iamRole/schema.graphql index 806a6f42..757653bf 100644 --- a/src/services/iamRole/schema.graphql +++ b/src/services/iamRole/schema.graphql @@ -24,4 +24,5 @@ type awsIamRole implements awsBaseService @key(fields: "id") { iamInstanceProfiles: [awsIamInstanceProfile] @hasInverse(field: iamRole) ec2Instances: [awsEc2] @hasInverse(field: iamRole) cognitoUserPools: [awsCognitoUserPool] @hasInverse(field: iamRole) + appSync: [awsAppSync] @hasInverse(field: iamRoles) } diff --git a/src/services/wafV2WebAcl/schema.graphql b/src/services/wafV2WebAcl/schema.graphql index d497de74..b60de8d6 100644 --- a/src/services/wafV2WebAcl/schema.graphql +++ b/src/services/wafV2WebAcl/schema.graphql @@ -12,6 +12,7 @@ type awsWafV2WebAcl implements awsBaseService @key(fields: "arn") { customResponseBodies: [awsWafV2CustomResponseBody] loggingConfiguration: awsWafV2LoggingConfig cloudfront: [awsCloudfront] @hasInverse(field: webAcl) + appSync: [awsAppSync] @hasInverse(field: webAcl) } type awsWafV2Rule { diff --git a/src/types/generated.ts b/src/types/generated.ts index e38557fe..9a5f7347 100644 --- a/src/types/generated.ts +++ b/src/types/generated.ts @@ -354,6 +354,7 @@ export type AwsAppSync = AwsBaseService & { dataSources?: Maybe>>; dynamodb?: Maybe>>; functions?: Maybe>>; + iamRoles?: Maybe>>; lambda?: Maybe>>; lambdaAuthorizerIdentityValidationExpression?: Maybe; lambdaAuthorizerResultTtlInSeconds?: Maybe; @@ -375,6 +376,7 @@ export type AwsAppSync = AwsBaseService & { userPoolDefaultAction?: Maybe; userPoolId?: Maybe; wafWebAclArn?: Maybe; + webAcl?: Maybe>>; xrayEnabled?: Maybe; }; @@ -3017,6 +3019,7 @@ export type AwsIamPolicy = AwsBaseService & { }; export type AwsIamRole = AwsBaseService & { + appSync?: Maybe>>; assumeRolePolicy?: Maybe; cloudFormationStack?: Maybe>>; codebuilds?: Maybe>>; @@ -4418,6 +4421,7 @@ export type AwsWafV2VisibilityConfig = { export type AwsWafV2WebAcl = AwsBaseService & { ManagedByFirewallManager?: Maybe; + appSync?: Maybe>>; capacity?: Maybe; cloudfront?: Maybe>>; customResponseBodies?: Maybe>>;