AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified Apache-2.0 Self-run

Kb Demo App Auth

skill-minorun365-agent-builder-skills-kb-demo-app-auth · by minorun365

デモアプリ・Webアプリの Cognito 認証のおすすめ構成。「Googleで続ける」か「メール+パスキー(パスワードも併用可)」の2経路をCDKとフロントでどう組むか、パスキーが動かない設定の罠、Google client secret の置き場、ログイン画面のUX規約、Googleの同意画面に出るアプリ名の扱い。新しくデモアプリを作るとき、既存アプリの認証を作り直すとき、パスキーやGoogleログインが動かないときに読む。

— No reviews yet
0 installs
0 views
— view→install

Install

$ agentstack add skill-minorun365-agent-builder-skills-kb-demo-app-auth

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • ✓ Prompt-injection patterns
  • ✓ Secret / credential exfiltration
  • ✓ Dangerous shell & filesystem operations
  • ✓ Untrusted network calls
  • ✓ Known-malicious package signatures

What it can access

  • ● Network access Used
  • ✓ Filesystem access No
  • ✓ Shell / process execution No
  • ✓ Environment & secrets No
  • ✓ Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-minorun365-agent-builder-skills-kb-demo-app-auth)

Reliability & compatibility

✓ Security review passed
0 installs to date
— no reviews yet
● 5d ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Kb Demo App Auth? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

デモアプリの Cognito 認証(おすすめ構成)

デモアプリ・Webアプリの認証は、特に指定がなければこの構成にする:「Googleで続ける」か「メール+パスキー」。

動く実物は minorun365/marp-agent。 迷ったら実物を読む。設計の背景は同リポジトリの docs/authentication-options.md。

| ファイル | 中身 | |---|---| | infra/lib/auth-stack.ts | User Pool / App Client / Google IdP / Cognito ドメイン | | src/components/Auth/AuthScreen.tsx | ログイン画面(326行。移植元) | | src/components/Auth/AuthScreen.css | 同スタイル | | infra/lambda/auth/google-idp-manager/handler.ts | Google IdP を作るカスタムリソース | | infra/lambda/auth/google-link/handler.ts | preSignUp。既存メールユーザーへGoogleを連携 |


1. 利用者から見た形

| 経路 | 初回 | 2回目以降 | |---|---|---| | Google | 「Googleで続ける」で登録とログインが同時に終わる | Google | | メール | メールアドレス+パスワードで登録し、確認コードでメールを確認 | パスキー(顔・指紋)。パスワードも使える |

  • メールのワンタイムコードログインは採用しない。 SES の本番利用申請を認証の前提にしない。Cognito 標準メールは新規登録の確認とパスワード再設定だけに使う(AWSアカウントあたり1日50通)。
  • パスキーはパスワードの置き換えではない。 登録しなくても期限なくパスワードで使える。
  • Google 利用者へパスキー登録を案内しない。 本人確認は Google 側が担当している。

2. ログイン画面のUX規約

1画面目は 2択だけに絞る。「Googleで続ける」と、メールアドレス入力+「メールで続ける」。

メールを入れた次の画面では、パスキーとパスワードを常に並べて出す。

> ⚠️ パスキー登録の有無で画面を出し分けない。 出し分けると「そのメールアドレスが登録済みか」を第三者へ教えることになる。同じ理由で、存在しないアドレスも認証失敗も表示は「メールアドレスまたは認証情報を確認してください。」に統一し、Cognito 側も preventUserExistenceErrors: true にする。

パスワードでログインした利用者には、成功後に一度だけパスキー登録を案内する。

  • 「パスキーを登録」と「あとで」の2つだけ
  • 「あとで」を押されたら 30日間は再案内しない(localStorage に押した時刻を持つ)
  • 専用の設定画面は作らない。ログイン後のメイン画面も変えない

3. CDK(User Pool)

パスキーは設定が1つでも欠けるとエラーにならず、ただ使えない形で失敗する。次の5点をまとめて入れる。

this.userPool = new cognito.UserPool(this, 'UserPool', {
  featurePlan: cognito.FeaturePlan.ESSENTIALS,   // ① LITE ではパスキーを使えない
  mfa: cognito.Mfa.OFF,                          // ② 明示しないとOPTIONALへ補完されることがある
  selfSignUpEnabled: true,
  signInAliases: { email: true },
  signInCaseSensitive: false,
  autoVerify: { email: true },
  standardAttributes: { email: { required: true, mutable: true } },
  accountRecovery: cognito.AccountRecovery.EMAIL_ONLY,
  signInPolicy: {
    allowedFirstAuthFactors: { password: true, passkey: true },   // ③ パスキーを第1認証要素に
  },
  passkeyRelyingPartyId: props.appDomain,                          // ④ 配信ドメインと完全一致させる
  passkeyUserVerification: cognito.PasskeyUserVerification.PREFERRED,
  passwordPolicy: { minLength: 8, requireDigits: false, requireLowercase: false, requireSymbols: false, requireUppercase: false },
});

this.userPoolClient = this.userPool.addClient('WebClient', {
  generateSecret: false,
  preventUserExistenceErrors: true,
  authFlows: { user: true, userPassword: true, userSrp: true },    // ⑤ user:true = USER_AUTH。無いとパスキーを選べない
  accessTokenValidity: cdk.Duration.minutes(60),
  idTokenValidity: cdk.Duration.minutes(60),
  refreshTokenValidity: cdk.Duration.days(30),
});
  • ④ の RP ID は「利用者がアクセスするドメイン」。dxxxx.cloudfront.net のような配信基盤の既定ドメインでもよいが、後からカスタムドメインへ移すと登録済みのパスキーは全部使えなくなる(RP ID が変わるため)。カスタムドメインを付ける予定があるなら、パスキーを入れる前に先に付ける。
  • パスワードポリシーを厳しくしない。 パスキーを入れる目的は入力を減らすこと。記号必須・12文字のような設定はデモの初回登録を重くするだけ。
  • featurePlan: ESSENTIALS は MAU 課金が発生する。デモ規模なら無視できるが、LITE からの変更なので認識しておく。

フロント側(aws-amplify v6)

// パスキーでログイン
await signIn({ username: email, options: { authFlowType: 'USER_AUTH', preferredChallenge: 'WEB_AUTHN' } });

// パスワードでログイン
await signIn({ username: email, password, options: { authFlowType: 'USER_PASSWORD_AUTH' } });

// ログイン後にパスキーを登録
await associateWebAuthnCredential();

Amplify.configure の Auth.Cognito に userPoolId / userPoolClientId を渡すだけでよい。Google を使うときだけ loginWith.oauth を足す(次節)。

4. Google ログイン

OAuth クライアントはデモごとに作らず、共通の1つを使い回す

同意画面のアプリ名は GCP プロジェクト単位で1つなので、デモごとにクライアントを作っても名前は分けられない。 デモ用の中立な名前でプロジェクトとクライアントを1つ用意し、以後のデモは全部これを使い回す。

| 項目 | 決め方 | |---|---| | GCP プロジェクト | デモ専用に1つ作る | | 同意画面のアプリ名 | 利用者に見えるのはこれ。特定のデモ名にせず、中立な名前にする | | 公開ステータス | 本番環境(テストユーザーの登録なしで誰でもログインできる) | | Client ID | CDK のコンテキストで渡す(秘密ではない) | | Client Secret | デプロイ先の AWS アカウントへ置く(下の「client secret の置き場」) |

新しいデモを足すときの作業は2つだけ。

  1. Google Cloud Console でそのクライアントを開き、承認済みリダイレクト URI に新しい Cognito ドメインの /oauth2/idpresponse を1行足す
  2. そのデモの AWS アカウントへ Secret を入れ、CDK に googleClientId を渡す

> ⚠️ 組織の Google Workspace 配下の GCP プロジェクトは、同意画面が「内部」(orgInternalOnly)になっていることがある。 > その場合は組織のアカウントしかログインできず、外部の人が触るデモでは機能しない。プロジェクトを選ぶ前に同意画面のユーザータイプを確かめる。 > > ⚠️ gcloud でも API でも、クライアントの作成も編集もできない。リダイレクトURIの追記も含めて Console のブラウザ操作が唯一の手段(2026-08 時点)。根拠は3つ: > - gcloud alpha iap oauth-clients は IAP 専用で、ヘルプ自身が「プロジェクト内の全 OAuth クライアントの管理 API としては使えない」と明記。加えて IAP OAuth Admin API は 2026-03-19 に完全停止 > - iap v1 の discovery を見ると projects.brands.identityAwareProxyClients の method は create/get/list/delete/resetSecret だけで、更新系が無い。停止していなくてもURIは足せない > - Google の公開 API 一覧(https://www.googleapis.com/discovery/v1/apis)に、OAuth クライアントを管理する API 自体が存在しない > > 人に操作を頼むときは、クライアントの編集画面まで開けるURLを渡す。 URLはこの形: > https://console.cloud.google.com/auth/clients/?project=

実装に必要なもの

Cognito ドメイン(Hosted UI 用)、Google の OAuth クライアント ID / Secret、IdP 登録、App Client の OAuth 設定。

supportedIdentityProviders: [cognito.UserPoolClientIdentityProvider.COGNITO, cognito.UserPoolClientIdentityProvider.GOOGLE],
oAuth: {
  flows: { authorizationCodeGrant: true },
  scopes: [cognito.OAuthScope.OPENID, cognito.OAuthScope.EMAIL, cognito.OAuthScope.PROFILE],
  callbackUrls: [`https://${appDomain}/`, 'http://localhost:5173/'],
  logoutUrls:   [`https://${appDomain}/`, 'http://localhost:5173/'],
},

フロントは signInWithRedirect({ provider: 'Google' }) を呼ぶだけ。

⚠️ Amplify Gen2 の defineAuth では「スコープ」が2か所にあり、書き方が逆になる。 ここを取り違えると デプロイも構成検査も通ったうえで、Googleのログイン画面が invalid_scope で開かない。

| 場所 | 何のスコープか | 書き方 | |---|---|---| | externalProviders.scopes | Cognito のアプリクライアントが出すトークンの範囲 | 大文字の列挙(['EMAIL','PROFILE','OPENID']) | | externalProviders.google.scopes | Google へそのまま渡る生の文字列 | 小文字(['openid','email','profile']) |

後者に大文字を書くと authorize_scopes が "EMAIL PROFILE OPENID" として IdP に入り、Google が invalid=[OPENID] を返す(EMAIL / PROFILE は通ってしまうので、症状が OPENID だけに出て気づきにくい)。

この種の失敗は AWS 側をいくら見ても分からない。 デプロイ後に Cognito の認可エンドポイントへ リクエストを投げ、accounts.google.com のログイン画面へ着地するかを確かめる(サインインは不要)。 エラー時は authError クエリが base64 で理由を持っている:

curl -s -o /dev/null -L -w '%{url_effective}\n' \
  "https://.auth..amazoncognito.com/oauth2/authorize?identity_provider=Google&client_id=&response_type=code&scope=openid+email+profile&redirect_uri=https%3A%2F%2F%2F"

.../signin/oauth/error?authError=... へ着地したら失敗。authError を base64url デコードすると invalid_scope / redirect_uri_mismatch などの理由が平文で読める。

client secret の置き場

cognito.UserPoolIdentityProviderGoogle の L2 は secret を CloudFormation テンプレートへ平文で残す。marp-agent は、秘密値を state に残さないカスタムリソース(google-idp-manager)で IdP を作る形にしている。

> ⚠️ 組織の管理下にある AWS アカウントでは、SCP で secretsmanager:CreateSecret が拒否されていることがある。 marp-agent の handler は Secrets Manager から読む実装なので、その場合は SSM Parameter Store の SecureString に置き換える。Lambda 実行ロールに ssm:GetParameter と、SecureString を復号する kms:Decrypt を付ける。

段階的に入れてよい

Google は GCP 側の作業(OAuth クライアント作成、承認済みリダイレクトURIの追加)が要るので、「クライアントIDが渡されたときだけ Google を有効にする」実装にしておくと、パスキーだけ先にリリースできる。marp-agent は this.node.tryGetContext('googleClientId') の有無で分岐している。

同じメールアドレスの重複プロフィール

Cognito は、メールアドレスが同じでもローカルユーザーと Google ユーザーを自動で統合しない。放置すると同じ人に2つのプロフィールができる。marp-agent は preSignUp トリガー(google-link)で、確認済みメールアドレスが一致する既存プロフィールへ AdminLinkProviderForUser でリンクしている。デモアプリで既存利用者がいないなら、初期は省いてよい。

5. デモアプリでの判断(外部の人が触る場合)

  • Google の同意画面に出るアプリ名は GCP プロジェクトのブランディングで決まる。クライアントIDを別に作っても、同じプロジェクトなら名前は同じ。外部の人に見せるデモで、無関係な別アプリの名前が出る状態にしない。
  • 管理を楽にするなら、デモ共通の中立な名前でプロジェクトとクライアントを1つ用意し、以後のデモはリダイレクトURIを1行足すだけにする。デモごとに作らない。
  • セキュリティ要件の厳しい組織の利用者は、業務用 Google アカウントを外部アプリへ繋ぐことに抵抗がある。Google を出しても、メール経路を同格で並べる(片方だけにしない)。

6. 検証(実装完了と言う前に)

パスキーは「画面が出た」では動作確認にならない。次を実操作で通す。

  1. メールで新規登録 → 確認コード → ログイン
  2. パスキー登録 → いったんサインアウト → パスキーでログイン
  3. パスキー未登録の状態でパスキーを押し、共通エラーが出てパスワードへ戻れる
  4. Google ログイン(有効にした場合)
  5. PC と iPhone の両方(iOS Simulator か実機の Safari)

localhost は RP ID が localhost になるため、本番ドメインで登録したパスキーはローカルでは使えない。ローカルではパスワード経路で確認する。

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.