Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions docs/en/DEPLOY_OPTION.md
Original file line number Diff line number Diff line change
Expand Up @@ -1810,6 +1810,48 @@ const envs: Record<string, Partial<StackInput>> = {
- samlCognitoDomainName: Specify the Cognito Domain name to be set in Cognito's App integration.
- samlCognitoFederatedIdentityProviderName: Specify the Identity Provider name to be set in Cognito's Sign-in experience.

### MFA (Multi-Factor Authentication)

You can enable email-based MFA for Cognito user pool authentication. When MFA is enabled, users must enter a verification code sent to their registered email address after entering their password.

> [!NOTE]
> MFA uses Amazon SES to send verification code emails. Before enabling MFA, you must verify the sender domain or email address in SES, and ensure SES is out of the sandbox (or that destination addresses are verified). Specify the verified sender address in `mfaFromEmail`.

> [!WARNING]
> When MFA is enabled, the "Forgot Password?" link on the sign-in screen is hidden. This is because Cognito cannot use the same email address for both MFA verification codes and password reset emails simultaneously. Password resets must be performed by an administrator via the Cognito service screen in the AWS Management Console.

Set `mfaEnabled` to `true` and specify the SES-verified sender address in `mfaFromEmail`. (Default is `false`)

- mfaEnabled: Set to `true` to require email MFA for all users. (Default: `false`)
- mfaFromEmail: Sender email address for MFA verification codes. Must be verified in Amazon SES.
- mfaReplyToEmail: Reply-to email address for MFA emails. (Default: `null`)

**Edit [parameter.ts](/packages/cdk/parameter.ts)**

```typescript
// parameter.ts
const envs: Record<string, Partial<StackInput>> = {
dev: {
mfaEnabled: true,
mfaFromEmail: 'no-reply@your-domain.com',
mfaReplyToEmail: null,
},
};
```

**Edit [packages/cdk/cdk.json](/packages/cdk/cdk.json)**

```json
// cdk.json
{
"context": {
"mfaEnabled": true,
"mfaFromEmail": "no-reply@your-domain.com",
"mfaReplyToEmail": null
}
}
```

### Guardrails

When using the Converse API (i.e., generative AI models that produce text output), guardrails can be applied. To configure this, change `guardrailEnabled` to `true` and redeploy.
Expand Down
42 changes: 42 additions & 0 deletions docs/ja/DEPLOY_OPTION.md
Original file line number Diff line number Diff line change
Expand Up @@ -1817,6 +1817,48 @@ const envs: Record<string, Partial<StackInput>> = {
- samlCognitoDomainName : Cognito の App integration で設定する Cognito Domain 名を指定します。
- samlCognitoFederatedIdentityProviderName : Cognito の Sign-in experience で設定する Identity Provider の名前を指定します。

### MFA(多要素認証)

Cognito ユーザープールにおける認証として、メールベースの MFA を有効化できます。MFA を有効にすると、ユーザーはパスワード入力後に登録済みのメールアドレスへ送信された認証コードの入力が求められます。

> [!NOTE]
> MFA の認証コードの送信には Amazon SES を使用します。MFA を有効化する前に、SES で送信元ドメインまたはメールアドレスを検証済みとする必要があります。検証済みの送信元メールアドレスを `mfaFromEmail` に指定してください。

> [!WARNING]
> MFA を有効にした場合、ログイン画面の「パスワードを忘れましたか?」リンクは非表示になります。これは Cognito が MFA 認証コードとパスワードリセットに同じメールアドレスを同時に使用できないためです。パスワードのリセットは管理者がAWSマネジメントコンソールの Cognito サービス画面から行う必要があります。

`mfaEnabled` を `true` に設定し、SES で検証済みの送信元メールアドレスを `mfaFromEmail` に指定します。(デフォルトは `false`)

- mfaEnabled : `true` にすることで、全ユーザーにメール MFA を必須化します。(デフォルト: `false`)
- mfaFromEmail : MFA 認証コードの送信元メールアドレス。Amazon SES で検証済みである必要があります。
- mfaReplyToEmail : MFA メールの Reply-To に設定するメールアドレス。(デフォルト: `null`)

**[parameter.ts](/packages/cdk/parameter.ts) を編集**

```typescript
// parameter.ts
const envs: Record<string, Partial<StackInput>> = {
dev: {
mfaEnabled: true,
mfaFromEmail: 'no-reply@your-domain.com',
mfaReplyToEmail: null,
},
};
```

**[packages/cdk/cdk.json](/packages/cdk/cdk.json) を編集**

```json
// cdk.json
{
"context": {
"mfaEnabled": true,
"mfaFromEmail": "no-reply@your-domain.com",
"mfaReplyToEmail": null
}
}
```

### ガードレール

Converse API を使う(=テキスト出力を行う生成 AI モデル)場合はガードレールを適用させることが可能です。設定するには `guardrailEnabled` を `true` に変更しデプロイしなおします。
Expand Down
42 changes: 42 additions & 0 deletions docs/ko/DEPLOY_OPTION.md
Original file line number Diff line number Diff line change
Expand Up @@ -1703,6 +1703,48 @@ const envs: Record<string, Partial<StackInput>> = {
- samlCognitoDomainName: Cognito의 App integration에 설정할 Cognito 도메인 이름을 지정합니다.
- samlCognitoFederatedIdentityProviderName: Cognito의 Sign-in experience에 설정할 Identity Provider 이름을 지정합니다.

### MFA (다단계 인증)

Cognito 사용자 풀 인증에 이메일 기반 MFA를 활성화할 수 있습니다. MFA를 활성화하면 사용자는 비밀번호 입력 후 등록된 이메일 주소로 전송된 인증 코드를 입력해야 합니다.

> [!NOTE]
> MFA는 인증 코드 이메일 발송에 Amazon SES를 사용합니다. MFA를 활성화하기 전에 SES에서 발신자 도메인 또는 이메일 주소를 검증하고, SES 샌드박스를 해제(또는 수신 주소를 검증)해야 합니다. 검증된 발신자 주소를 `mfaFromEmail`에 지정하세요.

> [!WARNING]
> MFA를 활성화하면 로그인 화면의 "비밀번호를 잊으셨나요?" 링크가 숨겨집니다. 이는 Cognito가 MFA 인증 코드와 비밀번호 재설정에 동일한 이메일 주소를 동시에 사용할 수 없기 때문입니다. 비밀번호 재설정은 관리자가 AWS Management Console의 Cognito 서비스 화면에서 수행해야 합니다.

`mfaEnabled`를 `true`로 설정하고 SES에서 검증된 발신자 주소를 `mfaFromEmail`에 지정합니다. (기본값: `false`)

- mfaEnabled: `true`로 설정하면 모든 사용자에게 이메일 MFA가 필수화됩니다. (기본값: `false`)
- mfaFromEmail: MFA 인증 코드의 발신자 이메일 주소. Amazon SES에서 검증되어야 합니다.
- mfaReplyToEmail: MFA 이메일의 Reply-To 주소. (기본값: `null`)

**[parameter.ts](/packages/cdk/parameter.ts) 편집**

```typescript
// parameter.ts
const envs: Record<string, Partial<StackInput>> = {
dev: {
mfaEnabled: true,
mfaFromEmail: 'no-reply@your-domain.com',
mfaReplyToEmail: null,
},
};
```

**[packages/cdk/cdk.json](/packages/cdk/cdk.json) 편집**

```json
// cdk.json
{
"context": {
"mfaEnabled": true,
"mfaFromEmail": "no-reply@your-domain.com",
"mfaReplyToEmail": null
}
}
```

### 가드레일

Converse API를 사용할 때 (즉, 텍스트 출력을 생성하는 생성형 AI 모델) 가드레일을 적용할 수 있습니다. 이를 구성하려면 `guardrailEnabled`를 `true`로 변경하고 재배포합니다.
Expand Down
3 changes: 3 additions & 0 deletions packages/cdk/cdk.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@
"samlAuthEnabled": false,
"samlCognitoDomainName": "",
"samlCognitoFederatedIdentityProviderName": "",
"mfaEnabled": false,
"mfaFromEmail": "no-reply@example.com",
"mfaReplyToEmail": null,
"hiddenUseCases": {},
"modelRegion": "us-east-1",
"modelIds": [
Expand Down
24 changes: 24 additions & 0 deletions packages/cdk/lib/construct/auth.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { Duration } from 'aws-cdk-lib';
import {
Mfa,
UserPool,
UserPoolClient,
UserPoolEmail,
UserPoolOperation,
} from 'aws-cdk-lib/aws-cognito';
import {
Expand All @@ -19,6 +21,9 @@ export interface AuthProps {
readonly allowedIpV6AddressRanges?: string[] | null;
readonly allowedSignUpEmailDomains?: string[] | null;
readonly samlAuthEnabled: boolean;
readonly mfaEnabled: boolean;
readonly mfaFromEmail: string;
readonly mfaReplyToEmail?: string | null;
}

export class Auth extends Construct {
Expand All @@ -29,6 +34,15 @@ export class Auth extends Construct {
constructor(scope: Construct, id: string, props: AuthProps) {
super(scope, id);

// Email configuration for MFA
const emailConfig = props.mfaEnabled
? UserPoolEmail.withSES({
fromEmail: props.mfaFromEmail,
replyTo: props.mfaReplyToEmail ?? undefined,
sesVerifiedDomain: props.mfaFromEmail?.split('@').pop(),
})
: undefined;

const userPool = new UserPool(this, 'UserPool', {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cognito の Feature Plan は Essentials 以上でないと Email MFA が使えません。

  • Feature Plan 概念が導入される前から存在するアカウントでは、新規作成 User Pool のデフォルトは LITE のまま
  • 概念導入後に作成されたアカウントでは新規 User Pool のデフォルトが ESSENTIALS

という挙動の差があり、今の実装ですと古い環境ではデプロイに失敗するようです。

以下のように明示的に MFA 有効化する際は Essential 指定することで古い環境でもデプロイできました。

featurePlan: props.mfaEnabled ? FeaturePlan.ESSENTIALS : undefined,

// If SAML authentication is enabled, do not use self-sign-up with UserPool. Be aware of security.
selfSignUpEnabled: props.samlAuthEnabled
Expand All @@ -44,6 +58,16 @@ export class Auth extends Construct {
requireDigits: true,
minLength: 8,
},
// MFA configuration
mfa: props.mfaEnabled ? Mfa.REQUIRED : Mfa.OFF,
mfaSecondFactor: props.mfaEnabled
? {
sms: false,
otp: false,
email: true,
}
: undefined,
email: emailConfig,
});

const client = userPool.addClient('client', {
Expand Down
2 changes: 2 additions & 0 deletions packages/cdk/lib/construct/web.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ export interface WebProps {
logoPath?: string;
title?: string;
};
readonly mfaEnabled: boolean;
}

export class Web extends Construct {
Expand Down Expand Up @@ -314,6 +315,7 @@ export class Web extends Construct {
),
VITE_APP_BRANDING_LOGO_PATH: props.brandingConfig?.logoPath ?? '',
VITE_APP_BRANDING_TITLE: props.brandingConfig?.title ?? '',
VITE_APP_MFA_ENABLED: props.mfaEnabled.toString(),
},
});
// Enhance computing resources
Expand Down
5 changes: 5 additions & 0 deletions packages/cdk/lib/generative-ai-use-cases-stack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,9 @@ export class GenerativeAiUseCasesStack extends Stack {
allowedIpV6AddressRanges: params.allowedIpV6AddressRanges,
allowedSignUpEmailDomains: params.allowedSignUpEmailDomains,
samlAuthEnabled: params.samlAuthEnabled,
mfaEnabled: params.mfaEnabled,
mfaFromEmail: params.mfaFromEmail,
mfaReplyToEmail: params.mfaReplyToEmail,
});

// Database
Expand Down Expand Up @@ -309,6 +312,8 @@ export class GenerativeAiUseCasesStack extends Stack {
cognitoIdentityPoolProxyEndpoint: props.cognitoIdentityPoolProxyEndpoint,
// Branding
brandingConfig: params.brandingConfig,
// MFA
mfaEnabled: params.mfaEnabled,
});

// RAG
Expand Down
3 changes: 3 additions & 0 deletions packages/cdk/lib/stack-input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ const baseStackInputSchema = z.object({
samlAuthEnabled: z.boolean().default(false),
samlCognitoDomainName: z.string().nullish(),
samlCognitoFederatedIdentityProviderName: z.string().nullish(),
mfaEnabled: z.boolean().default(false),
mfaFromEmail: z.string().email().default('no-reply@example.com'),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

すみません、こちら default 値指定したほうがいいかもしれないとコメントさせていただいたのですが、検証されたメールを設定しないとデプロイ時エラーになるため 「mfaEnabled の際は検証されたメールを明示的に入力する必要がある」を徹底するために、ここでは nullish にして refine でデプロイ前にエラーメッセージを表示する形にしたほうが良いかもしれません。

// 既存の refine に追加
.refine(
(data) => !data.mfaEnabled || !!data.mfaFromEmail,
{ message: 'mfaFromEmail is required when mfaEnabled is true', path: ['mfaFromEmail'] }
)

mfaReplyToEmail: z.string().nullish(),
// Frontend
hiddenUseCases: z
.object({
Expand Down
Loading