From e85099813e5ae44cf5e7ab37ad232976ded4d00d Mon Sep 17 00:00:00 2001 From: Kota8102 <52307008+Kota8102@users.noreply.github.com> Date: Sun, 24 Mar 2024 15:52:02 +0900 Subject: [PATCH 1/4] Feature/#36 (#48) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cdk-nagによるセキュリティチェック導入 #36 --- .github/workflows/backend.yml | 11 +++- src/backend/bin/backend.ts | 21 +++++-- src/backend/lib/backend-stack.ts | 101 +++++++++++++++++++++++++++++-- src/backend/package-lock.json | 10 +++ src/backend/package.json | 5 +- 5 files changed, 134 insertions(+), 14 deletions(-) diff --git a/.github/workflows/backend.yml b/.github/workflows/backend.yml index 6cd7cdb..6d3ce9f 100644 --- a/.github/workflows/backend.yml +++ b/.github/workflows/backend.yml @@ -50,14 +50,19 @@ jobs: - name: Build run: npm run build working-directory: src/backend + - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v1 with: aws-region: "${{ secrets.AWS_REGION }}" role-to-assume: "arn:aws:iam::${{ secrets.AWS_ACCOUNT }}:role/${{ secrets.ACTIONS_ROLE }}" + - name: CDK Synth + if: startsWith(github.ref, 'refs/heads/feature/') + run: npm run cdk synth + working-directory: src/backend + - name: CDK Deploy - env: - ENVIRONMENT: ${{ needs.set-environment.outputs.environment }} - run: npm run cdk deploy BackendStack --require-approval never --context environment=$ENVIRONMENT + if: github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/main' + run: npm run cdk deploy BackendStack --require-approval never working-directory: src/backend diff --git a/src/backend/bin/backend.ts b/src/backend/bin/backend.ts index 2ee2ef4..071ca00 100644 --- a/src/backend/bin/backend.ts +++ b/src/backend/bin/backend.ts @@ -1,9 +1,22 @@ #!/usr/bin/env node import * as cdk from "aws-cdk-lib"; import { BackendStack } from "../lib/backend-stack"; +import { AwsSolutionsChecks, NagSuppressions } from 'cdk-nag'; +import { Aspects } from 'aws-cdk-lib'; const app = new cdk.App(); -const environment = app.node.tryGetContext("environment"); -new BackendStack(app, "BackendStack", { - environment, -}); + +Aspects.of(app).add(new AwsSolutionsChecks()); + +const backendStack = new BackendStack(app, "BackendStack", {}); + +NagSuppressions.addStackSuppressions(backendStack, [ + { + id: 'AwsSolutions-COG3', + reason: 'このプロジェクトではAdvancedSecurityModeをENFORCEDに設定する必要はないと判断した。', + }, + { + id: 'AwsSolutions-IAM5', + reason: '暫定的にオフにしているが、本番環境では適切なIAMポリシーを設定すること。', + } +]); \ No newline at end of file diff --git a/src/backend/lib/backend-stack.ts b/src/backend/lib/backend-stack.ts index 1a4f33f..841f46c 100644 --- a/src/backend/lib/backend-stack.ts +++ b/src/backend/lib/backend-stack.ts @@ -1,17 +1,108 @@ import * as cdk from "aws-cdk-lib"; import { Construct } from "constructs"; import * as s3 from "aws-cdk-lib/aws-s3"; +import * as cognito from "aws-cdk-lib/aws-cognito"; +import * as dynamodb from "aws-cdk-lib/aws-dynamodb"; -interface BackendStackProps extends cdk.StackProps { - environment: string; -} +interface BackendStackProps extends cdk.StackProps { } export class BackendStack extends cdk.Stack { constructor(scope: Construct, id: string, props: BackendStackProps) { super(scope, id, props); - new s3.Bucket(this, `diary-${props.environment}-bucket`, { + const logBucket = new s3.Bucket(this, `LogBucket`, { removalPolicy: cdk.RemovalPolicy.DESTROY, + enforceSSL: true, + serverAccessLogsPrefix: "log/", + }); + + new s3.Bucket(this, `DiaryBucket`, { + removalPolicy: cdk.RemovalPolicy.DESTROY, + enforceSSL: true, + serverAccessLogsBucket: logBucket, + serverAccessLogsPrefix: "DiaryLog/", + }); + + new dynamodb.Table(this, `DiaryContentsTable`, { + partitionKey: { + name: "user_id", + type: dynamodb.AttributeType.STRING, + }, + sortKey: { + name: "date", + type: dynamodb.AttributeType.STRING, + }, + removalPolicy: cdk.RemovalPolicy.DESTROY, + pointInTimeRecovery: true, + }); + + const userPool = new cognito.UserPool(this, `DiaryUserPool`, { + userPoolName: `diary-user-pool`, + signInAliases: { + email: true, + }, + selfSignUpEnabled: true, + autoVerify: { + email: true, + }, + userVerification: { + emailSubject: 'メールアドレスを認証してください。', + emailBody: 'ご登録ありがとうございます。 あなたの認証コードは {####} です。', + emailStyle: cognito.VerificationEmailStyle.CODE, + }, + standardAttributes: { + familyName: { + mutable: false, + required: true, + }, + givenName: { + mutable: false, + required: true, + }, + address: { + mutable: true, + required: false, + }, + gender: { + mutable: true, + required: true, + }, + email: { + mutable: false, + required: true, + }, + }, + passwordPolicy: { + minLength: 8, + requireLowercase: true, + requireUppercase: true, + requireDigits: true, + requireSymbols: true, + }, + accountRecovery: cognito.AccountRecovery.EMAIL_ONLY, + mfa: cognito.Mfa.REQUIRED, + mfaSecondFactor: { + sms: true, + otp: true, + }, + removalPolicy: cdk.RemovalPolicy.DESTROY, + }); + + const userPoolClient = new cognito.UserPoolClient(this, "DiaryUserPoolClient", { + userPool, + userPoolClientName: "diary-userpool-client", + authFlows: { + adminUserPassword: true, + custom: true, + userSrp: true, + }, + supportedIdentityProviders: [ + cognito.UserPoolClientIdentityProvider.COGNITO, + ], + }); + + userPool.addDomain('UserPoolDomain', { + cognitoDomain: { domainPrefix: 'dairy-851725642854' }, }); } -} +} \ No newline at end of file diff --git a/src/backend/package-lock.json b/src/backend/package-lock.json index a331b32..08e7805 100644 --- a/src/backend/package-lock.json +++ b/src/backend/package-lock.json @@ -9,6 +9,7 @@ "version": "0.1.0", "dependencies": { "aws-cdk-lib": "2.122.0", + "cdk-nag": "^2.28.72", "constructs": "^10.0.0", "source-map-support": "^0.5.21" }, @@ -1884,6 +1885,15 @@ } ] }, + "node_modules/cdk-nag": { + "version": "2.28.72", + "resolved": "https://registry.npmjs.org/cdk-nag/-/cdk-nag-2.28.72.tgz", + "integrity": "sha512-vcTg643b+hlnA4ZUq6KU/Sv5inapJuKogZ/5jmThZ7MhhBCpxmIEyWI/CNEX+zQhwuyvORtxQB4fDmU9kHKK5w==", + "peerDependencies": { + "aws-cdk-lib": "^2.116.0", + "constructs": "^10.0.5" + } + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", diff --git a/src/backend/package.json b/src/backend/package.json index 9807382..e8c514b 100644 --- a/src/backend/package.json +++ b/src/backend/package.json @@ -13,15 +13,16 @@ "devDependencies": { "@types/jest": "^29.5.11", "@types/node": "20.11.5", + "aws-cdk": "2.122.0", "jest": "^29.7.0", "ts-jest": "^29.1.1", - "aws-cdk": "2.122.0", "ts-node": "^10.9.2", "typescript": "~5.3.3" }, "dependencies": { "aws-cdk-lib": "2.122.0", + "cdk-nag": "^2.28.72", "constructs": "^10.0.0", "source-map-support": "^0.5.21" } -} \ No newline at end of file +} From ab5dafbcf63b1c030d6950d6b01f0460e7d3abaa Mon Sep 17 00:00:00 2001 From: Kota8102 <52307008+Kota8102@users.noreply.github.com> Date: Sun, 24 Mar 2024 15:54:01 +0900 Subject: [PATCH 2/4] Develop (#49) Develop (#49) From bcba1668e10328a9aa2b859b93b7c7ffd950f848 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=93=E3=82=93=E3=81=9F?= Date: Sun, 24 Mar 2024 15:56:23 +0900 Subject: [PATCH 3/4] rm .DS_Store --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index d9f5e51..16e4ed7 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,5 @@ src/frontend/*.ntvs* src/frontend/*.njsproj src/frontend/*.sln src/frontend/*.sw? + +.DS_Store \ No newline at end of file From b6b8af0e445ce939a78e6b56fdca8a9b01debf2a Mon Sep 17 00:00:00 2001 From: Kota8102 <52307008+Kota8102@users.noreply.github.com> Date: Sun, 24 Mar 2024 15:56:48 +0900 Subject: [PATCH 4/4] Delete .DS_Store --- .DS_Store | Bin 6148 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 78872d165674085c6f251377fd46f9406d784a7e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHK!AiqG5Z!H~O(;SR3Oz1(E!b2PikA@U4;aydN==%g!I+gMwTDv3S%1hc@q3)v z-4>+^oO$YAwvCPXT%|~NZkR~HYxw=U6L{0-a$&*6WhI+tuY-ixMX0!dC*A|}V z&D&zu>vr1W;IKQNJNC}*-qGpcK6}XJvnG+l_oiga-~wL2S*|B3hFJ{Hhl9)DQ#j5u zncqTeF$s>75Cg;jF|bAqnC;JQuF;xlsl)&=@G}N*e-NOEzQIbP+B(3f768zKuoCdG zm%tif&^K6Vgb@&~O96E$H!TL&bS!-~X#5GQL`X> eJc?VON+2%K0rU-48X*EgKLUydGQ_~IGVl&}EKf`T