UNPKG

@cloud-copilot/iam-collect

Version:

Collect IAM information from AWS Accounts

239 lines 10.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.AwsConfigS3Client = void 0; const client_s3_1 = require("@aws-sdk/client-s3"); const AbstractClient_js_1 = require("../../customClients/AbstractClient.js"); const ResourceNotFoundException_js_1 = require("../../customClients/ResourceNotFoundException.js"); const json_js_1 = require("../../utils/json.js"); const AwsConfigClientContext_js_1 = require("../AwsConfigClientContext.js"); const awsConfigUtils_js_1 = require("../awsConfigUtils.js"); /** * AWS Config-based S3 client implementation */ class AwsConfigS3Client extends AbstractClient_js_1.AbstractClient { static clientName = client_s3_1.S3Client.name; constructor(options, customContext) { super(options, customContext); } registerCommands() { this.registerCommand(AwsConfigGetBucketPolicyCommand); this.registerCommand(AwsConfigGetBucketEncryptionCommand); this.registerCommand(AwsConfigGetBucketTaggingCommand); this.registerCommand(AwsConfigGetPublicAccessBlockCommand); this.registerCommand(AwsConfigListBucketsCommand); this.registerCommand(AwsConfigListDirectoryBucketsCommand); } } exports.AwsConfigS3Client = AwsConfigS3Client; /** * Config-based implementation of S3 ListBucketsCommand * Returns bucket listing from AWS Config inventory data */ const AwsConfigListBucketsCommand = (0, AwsConfigClientContext_js_1.awsConfigCommand)({ command: client_s3_1.ListBucketsCommand, execute: async (input, context) => { // Query Config for S3 buckets const query = ` SELECT arn, resourceName, configuration.name, configuration.creationDate, supplementaryConfiguration.BucketPolicy, supplementaryConfiguration.ServerSideEncryptionConfiguration, supplementaryConfiguration.PublicAccessBlockConfiguration, tags WHERE resourceType = 'AWS::S3::Bucket' AND awsRegion = '${input.BucketRegion}' AND accountId = '${context.accountId}' AND ${awsConfigUtils_js_1.resourceStatusWhereClause} `; const configResults = await (0, awsConfigUtils_js_1.executeConfigQuery)(query, context); const buckets = configResults.map((resultString) => { const { configItem, configuration, supplementaryConfiguration, tags } = (0, awsConfigUtils_js_1.parseConfigItem)(resultString); context.putCache(configItem.resourceName, 'policy', supplementaryConfiguration?.BucketPolicy.policyText); context.putCache(configItem.resourceName, 'encryption', supplementaryConfiguration?.ServerSideEncryptionConfiguration); context.putCache(configItem.resourceName, 'tags', tags); context.putCache(configItem.resourceName, 'publicAccessBlock', supplementaryConfiguration?.PublicAccessBlockConfiguration); return { Name: configuration?.name || configItem.resourceName, CreationDate: configuration?.creationDate ? new Date(configuration.creationDate) : undefined }; }); return { Buckets: buckets }; } }); /** * Config-based implementation of S3 ListDirectoryBucketsCommand * Uses AWS::S3Express::DirectoryBucket resource type */ const AwsConfigListDirectoryBucketsCommand = (0, AwsConfigClientContext_js_1.awsConfigCommand)({ command: client_s3_1.ListDirectoryBucketsCommand, execute: async (input, context) => { const query = ` SELECT arn, resourceId, resourceName, configuration.BucketEncryption, tags WHERE resourceType = 'AWS::S3Express::DirectoryBucket' AND awsRegion = '${context.region}' AND accountId = '${context.accountId}' AND ${awsConfigUtils_js_1.resourceStatusWhereClause} `; const results = await (0, awsConfigUtils_js_1.executeConfigQuery)(query, context); const buckets = results?.map((resultString) => { const { configItem, configuration } = (0, awsConfigUtils_js_1.parseConfigItem)(resultString); context.putCache(configItem.resourceName, 'policy', configuration?.PolicyDocument); context.putCache(configItem.resourceName, 'encryption', configuration?.BucketEncryption); return { Name: configItem.resourceName }; }) || []; return { Buckets: buckets }; } }); /** * Config-based implementation of S3 GetBucketPolicyCommand * Returns bucket policy from AWS Config supplementary data */ const AwsConfigGetBucketPolicyCommand = (0, AwsConfigClientContext_js_1.awsConfigCommand)({ command: client_s3_1.GetBucketPolicyCommand, execute: async (input, context) => { const { Bucket } = input; if (!Bucket) { throw new Error('Bucket parameter is required'); } if (isDirectoryBucket(Bucket)) { const query = ` SELECT resourceName, configuration.PolicyDocument WHERE resourceType = 'AWS::S3Express::BucketPolicy' AND resourceName = '${Bucket}' AND accountId = '${context.accountId}' AND awsRegion = '${context.region}' AND ${awsConfigUtils_js_1.resourceStatusWhereClause} `; const configResults = await (0, awsConfigUtils_js_1.executeConfigQuery)(query, context); if (configResults.length === 0) { throw new ResourceNotFoundException_js_1.ResourceNotFoundException(`Bucket '${Bucket}' not found`); } const { configuration } = (0, awsConfigUtils_js_1.parseConfigItem)(configResults[0]); return { Policy: JSON.stringify(configuration?.PolicyDocument) }; } const cachedPolicy = context.getCache(Bucket, 'policy'); return { Policy: (0, json_js_1.stringifyIfPresent)(cachedPolicy) }; } }); /** * Config-based implementation of S3 GetBucketEncryptionCommand * Returns bucket encryption configuration from AWS Config supplementary data */ const AwsConfigGetBucketEncryptionCommand = (0, AwsConfigClientContext_js_1.awsConfigCommand)({ command: client_s3_1.GetBucketEncryptionCommand, execute: async (input, context) => { const { Bucket } = input; if (!Bucket) { throw new Error('Bucket parameter is required'); } if (isDirectoryBucket(Bucket)) { const encryptionConfig = context.getCache(Bucket, 'encryption'); const seeConfig = encryptionConfig?.ServerSideEncryptionConfiguration?.at(0); if (!seeConfig) { // Return an empty result to indicate no encryption configuration is set return {}; } return { ServerSideEncryptionConfiguration: { Rules: [ { ApplyServerSideEncryptionByDefault: { SSEAlgorithm: seeConfig.ServerSideEncryptionByDefault?.SSEAlgorithm, KMSMasterKeyID: seeConfig.ServerSideEncryptionByDefault?.KMSMasterKeyID }, BucketKeyEnabled: seeConfig.BucketKeyEnabled } ] } }; } const serverSideEncryption = context.getCache(Bucket, 'encryption'); if (!serverSideEncryption) { // Return undefined to indicate no encryption configuration is set return undefined; } // Convert Config encryption format to S3 ServerSideEncryptionConfiguration format const rules = serverSideEncryption.rules?.map((rule) => ({ ApplyServerSideEncryptionByDefault: { SSEAlgorithm: rule.applyServerSideEncryptionByDefault?.sseAlgorithm, KMSMasterKeyID: rule.applyServerSideEncryptionByDefault?.kmsMasterKeyID }, BucketKeyEnabled: rule.bucketKeyEnabled })) || []; return { ServerSideEncryptionConfiguration: { Rules: rules } }; } }); /** * Config-based implementation of S3 GetBucketTaggingCommand * Returns bucket tags from AWS Config tags data */ const AwsConfigGetBucketTaggingCommand = (0, AwsConfigClientContext_js_1.awsConfigCommand)({ command: client_s3_1.GetBucketTaggingCommand, execute: async (input, context) => { const { Bucket } = input; if (!Bucket) { throw new Error('Bucket parameter is required'); } const tags = context.getCache(Bucket, 'tags'); return { TagSet: tags }; } }); /** * Config-based implementation of S3 GetPublicAccessBlockCommand * Returns public access block configuration from AWS Config supplementary data */ const AwsConfigGetPublicAccessBlockCommand = (0, AwsConfigClientContext_js_1.awsConfigCommand)({ command: client_s3_1.GetPublicAccessBlockCommand, execute: async (input, context) => { const { Bucket } = input; if (!Bucket) { throw new Error('Bucket parameter is required'); } const publicAccessBlock = context.getCache(Bucket, 'publicAccessBlock'); if (!publicAccessBlock) { // Return undefined to indicate no public access block configuration is set return undefined; } return { PublicAccessBlockConfiguration: { BlockPublicAcls: publicAccessBlock.blockPublicAcls, BlockPublicPolicy: publicAccessBlock.blockPublicPolicy, IgnorePublicAcls: publicAccessBlock.ignorePublicAcls, RestrictPublicBuckets: publicAccessBlock.restrictPublicBuckets } }; } }); function isDirectoryBucket(bucketName) { return bucketName.endsWith('-x-s3'); } //# sourceMappingURL=AwsConfigS3Client.js.map